3 Commits
Author SHA1 Message Date
orrisroot 4ccf1b37e1 fix: append px only to bare numbers in CosmoDB image sizes
The check was written /^d+/, which matches a literal d, so a unitless
width or height in an {Image} tag never got its px and was dropped as
invalid CSS. Anchor it at both ends so the 160px and 90% values the
current templates use are left as they are.
2026-09-15 12:58:30 +09:00
orrisroot 79e0e2295f feat: migrate from Create React App to Vite
react-scripts 4 on React 17 no longer builds on a current toolchain.
Move to Vite 8 with React 19 and TypeScript 7, and take the same shape
as the other converted sites.

- react-router-dom v5 -> react-router v8: Switch/Redirect become
  Routes/Navigate, and withRouter gives way to useLocation and
  useNavigate; the original /modules/... addresses are kept
- swap the unmaintained dependencies: axios -> ky, react-html-parser
  -> @orrisroot/react-html-parser, react-ga -> react-ga4,
  react-helmet -> @dr.pogodin/react-helmet, moment -> date-fns,
  react-spinner-material -> a CSS spinner, and a local HashLink in
  place of react-router-hash-link
- drop react-app-polyfill, the jest setup, xregexp and the unused
  async-lock, rc-tree, react-overlays and react-image-lightbox
- replace ESLint with Biome, yarn with npm, and match the other sites'
  tsconfigs and sanitize.css base stylesheet
- serve static-contents/ next to the repository with sirv in the dev
  and preview servers, keeping it out of dist/
- convert the page components to function components; each module
  loads its index once, sharing the request under StrictMode
- resolve relative links in page bodies the way a browser does, since
  react-router 8 resolves them against the route hierarchy
- fix the glossary search restricted to a category, whose query
  matched nothing
- set the GA4 measurement ID replacing the shut-down UA property
- correct the keywords meta tag copied from dynamicbrain
- write down the data layout and the deployment procedure
2026-09-15 12:56:11 +09:00
orrisroot 480c1aeed8 chore: move XOOPS conversion tools to xoops-static-exporter
The dump scripts are site-specific but belong with the other sites'
tools rather than inside the front-end repository. They now live in
xoops-static-exporter under sites/invbrain.neuroinf.jp/.
2026-09-15 12:43:16 +09:00
106 changed files with 5539 additions and 18605 deletions
+21 -26
View File
@@ -1,30 +1,25 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
.eslintcache
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
# database contents
/public/static
/public/modules
/public/uploads
/dl-limit-items.csv
node_modules
dist
dist-ssr
coverage
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
+6
View File
@@ -0,0 +1,6 @@
// Keep @types/node on the 24.x line to match the deployment target. Its
// "latest" dist-tag points at the 22.x line, so the default target would
// report no updates at all instead of offering 24.x patches.
export default {
target: (name) => (name === '@types/node' ? 'minor' : 'latest'),
};
+130 -25
View File
@@ -1,44 +1,149 @@
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
# Invertebrate Brain Platform
## Available Scripts
Static front-end for the archived [Invertebrate Brain Platform](https://invbrain.neuroinf.jp/) site,
built with [Vite](https://vite.dev/), React and TypeScript.
In the project directory, you can run:
## Requirements
### `yarn start`
- Node.js 20.19+ / 22.12+ (Vite 8)
- npm
Runs the app in the development mode.<br />
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
## Setup
The page will reload if you make edits.<br />
You will also see any lint errors in the console.
```sh
npm install
```
### `yarn test`
## Site data
Launches the test runner in the interactive watch mode.<br />
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
The pages are rendered from JSON dumped out of the original XOOPS installation
by [xoops-static-exporter](https://git.ni.riken.jp/niu/xoops-static-exporter)
(`sites/invbrain.neuroinf.jp/`).
### `yarn build`
All of it lives in `static-contents/`, which sits next to the repository rather
than inside it:
Builds the app for production to the `build` folder.<br />
It correctly bundles React in production mode and optimizes the build for the best performance.
```
invbrain.neuroinf.jp/
├── invbrain.neuroinf.jp/ this repository
├── deploy.sh
└── static-contents/
├── modules/ one directory per source XOOPS module
│ ├── credits/ index.json, <page id>.json
│ ├── documents/ pico: index.json, <content id>.json, images/
│ ├── htmldocs/ pico: index.json, <content id>.json, IVBPF/
│ ├── newdb*/ CosmoDB: index.json, <item id>.json, extract/, images/
│ ├── PubMedPDF/ index.json
│ ├── xfileuploader/ files linked from the pages
│ └── xwords/ index.json
├── static/ static HTML trees linked from the pages
├── uploads/ files linked from the pages
├── common/ files linked from the pages
└── rss.xml
```
The build is minified and the filenames include the hashes.<br />
Your app is ready to be deployed!
The app keeps the original XOOPS addresses (`/modules/<module>/...`), so its
routes share `modules/` with the data. That works because the data files are
all `index.json`, `<id>.json` and linked assets, none of which is a page URL, and
a real file always wins over the SPA fallback.
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
Each module fetches its own `index.json` the first time one of its pages is
shown, rather than all of them at start up.
### `yarn eject`
The dev and preview servers mount `static-contents/` at the site root. It is
deliberately kept out of `dist/`: it runs to about 68 GB, and the web server
maps it in directly. It is generated content and is not tracked in git.
**Note: this is a one-way operation. Once you `eject`, you cant go back!**
## Scripts
If you arent satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
| Command | Description |
| --- | --- |
| `npm run dev` | Start the dev server on http://localhost:5173 |
| `npm run build` | Type-check and build into `dist/` |
| `npm run preview` | Serve the production build on http://localhost:4173 |
| `npm run lint` | Lint with [Biome](https://biomejs.dev/) |
| `npm run format` | Format with Biome |
| `npm run check` | Lint, format and organize imports, applying the safe fixes |
Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point youre on your own.
`@types/node` is pinned to the major that matches the Node runtime in use (24);
`.ncurc.js` keeps `npm-check-updates` from bumping it past that.
You dont have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldnt feel obligated to use this feature. However we understand that this tool wouldnt be useful if you couldnt customize it when you are ready for it.
There is currently no test suite.
## Learn More
## Deployment
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
Build locally, then run `../deploy.sh`, which does steps 2 to 4 below against
the `archive` host. The server does not need a toolchain.
To learn React, check out the [React documentation](https://reactjs.org/).
### 1. Build and check
```sh
npm ci
npm run check # biome, writes fixes
npm run build # runs tsc -b, then vite build
npm run preview # localhost:4173 , serves dist/ + static-contents/
```
### 2. Send up the site data
About 68 GB, most of it under `modules/newdb5/extract/`. The server mirrors the
local layout: `static-contents/` sits next to the document root.
```
/data/www/invbrain.neuroinf.jp/
├── html/ document root
└── static-contents/
```
```sh
rsync -a --delete static-contents/ \
user@server:/data/www/invbrain.neuroinf.jp/static-contents/
```
### 3. Push the build
```sh
rsync -a --delete dist/ user@server:/data/www/invbrain.neuroinf.jp/html/
```
`--delete` clears out the previous build, and with it the data symlinks from
step 4; they are recreated right after.
### 4. Link the site data into the document root
```sh
cd /data/www/invbrain.neuroinf.jp/html
ln -sfn ../static-contents/* .
```
That links every top-level entry of `static-contents/` — currently `modules/`,
`static/`, `uploads/`, `common/` and `rss.xml`. The links are relative, so the
whole tree can be moved without rewriting them.
Apache needs `Options FollowSymLinks`, `AllowOverride All` and
`Require all granted` on the document root, and `Options FollowSymLinks` with
`Require all granted` on `static-contents/`. Use symlinks rather than `Alias`:
an aliased `/modules` is outside the document root, so `.htaccess` no longer
sends the page URLs under it to `index.html`.
### 5. Check the deployed site
```sh
curl -I https://invbrain.neuroinf.jp/rss.xml # 200
curl -I https://invbrain.neuroinf.jp/modules/htmldocs/index.json # 200
```
Then load `/`, a CosmoDB list and detail page (`/modules/newdb5/list.php?id=2`),
`/modules/PubMedPDF/`, `/modules/xwords/` and `/modules/credits/` in a browser
and confirm the images resolve.
### Upgrading from v1.0.0
v1.0.0 already served the data from the same paths, so the data layout is
unchanged and step 2 only has to transfer what differs.
## Google Analytics
`GOOGLE_ANALYTICS_TRACKING_ID` in `src/config.ts` carries the GA4 measurement
ID that replaced the Universal Analytics property shut down in 2023. Emptying
it disables tracking.
+39
View File
@@ -0,0 +1,39 @@
{
"$schema": "https://biomejs.dev/schemas/2.5.13/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"includes": ["**", "!**/dist", "!src/*/assets"]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 4,
"lineWidth": 120
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"jsxQuoteStyle": "double",
"semicolons": "always",
"trailingCommas": "es5",
"arrowParentheses": "always"
}
},
"linter": {
"enabled": true,
"rules": {
"preset": "recommended"
}
},
"assist": {
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}
-316
View File
@@ -1,316 +0,0 @@
<?php
require_once __DIR__.'/config.inc.php';
define('PROTECTOR_SKIP_DOS_CHECK', 1);
define('PROTECTOR_SKIP_FILESCHECKER', 1);
// disable query logger
define('XOOPS_LOGGER_ADDQUERY_DISABLED', true);
// ----
if (!file_exists($mainfile)) {
echo 'ERROR : mainfile.php not found'.PHP_EOL;
exit(1);
}
$xoops_path = '';
$xoops_url = '';
foreach (file($mainfile) as $line) {
if (preg_match('/^\s*define\s*\(\s*[\'"]XOOPS_ROOT_PATH[\'"]\s*,\s*[\'"](.+)[\'"]\)\s*;\s*$/', $line, $matches)) {
$xoops_path = $matches[1];
}
if (preg_match('/^\s*define\s*\(\s*[\'"]XOOPS_URL[\'"]\s*,\s*[\'"](.+)[\'"]\)\s*;\s*$/', $line, $matches)) {
$xoops_url = $matches[1];
}
}
if (isset($method) && 'POST' == strtoupper($method)) {
$method = 'POST';
} else {
$method = 'GET';
}
$_SERVER['HTTP_USER_AGENT'] = 'php-cli';
$_SERVER['REQUEST_METHOD'] = $method;
$_ENV['HTTP_REFERER'] = $xoops_url.'/index.php';
$_SERVER['QUERY_STRING'] = '/index.php';
$_SERVER['REMOTE_ADDR'] = '192.168.0.1';
if (file_exists($xoops_path.'/modules/xoonips/include/common.inc.php')) {
require_once $xoops_path.'/modules/xoonips/include/common.inc.php';
} else {
require_once $xoops_path.'/mainfile.php';
require_once $xoops_path.'/modules/xoonips/condefs.php';
require_once $xoops_path.'/modules/xoonips/include/functions.php';
}
if (defined('XOOPS_DB_PROXY') && XOOPS_DB_PROXY == 1 && 'POST' == $method) {
die('Error: not accept POST request'."\n");
}
error_reporting(E_ALL);
// remove ob fileters
while (ob_get_level()) {
ob_end_clean();
}
define('MYDUMPTOOL_OUTPUTDIR', __DIR__.'/data');
MyDumpTool::makeDirectory('');
MyDumpTool::makeDirectory('src');
MyDumpTool::makeDirectory('public');
class MyDumpTool
{
public static function decode(&$data)
{
$textutil = xoonips_getutility('text');
foreach ($data as $k => $v) {
if (is_string($v)) {
$v = $textutil->html_numeric_entities($v);
$v = mb_decode_numericentity($v, [0x0, 0x10000, 0, 0xfffff], 'UTF-8');
$data[$k] = \Normalizer::normalize(trim($v), \Normalizer::FORM_C);
} elseif (null === $v) {
$data[$k] = '';
}
}
}
public static function convertToInt(&$data, $keys, $zerofill = false)
{
foreach ($keys as $key) {
if (isset($data[$key])) {
$data[$key] = '' === $data[$key] ? ($zerofill ? 0 : null) : (int) $data[$key];
}
}
}
public static function dropColumn(&$data, $keys)
{
foreach ($keys as $key) {
if (isset($data[$key])) {
unset($data[$key]);
}
}
}
public static function fileCopy($from, $to)
{
system('rsync -aq '.escapeshellarg($from).' '.escapeshellarg($to), $ret);
return 0 === $ret;
}
public static function fixHtml($text)
{
static $config = [
//'clean' => true,
'hide-comments' => true,
'indent' => true,
'output-xhtml' => true,
'preserve-entities' => true,
'show-body-only' => true,
'drop-proprietary-attributes' => true,
'logical-emphasis' => true,
'wrap' => 0,
'input-encoding' => 'utf8',
'output-encoding' => 'utf8',
'output-bom' => false,
];
$text = tidy_repair_string($text, $config);
$text = preg_replace('/<table([^>]*)>((?:\s*<caption[^>]*>.*<\/caption>)?\s*)<tr([^>]*)>/Us', '<table\1>\2<tbody><tr\3>', $text);
$text = preg_replace('/<\/tr>(\s*)<\/table>/s', '</tr></tbody>\1</table>', $text);
$text = tidy_repair_string($text, $config);
return $text;
}
public static function tableExists($name)
{
global $xoopsDB;
$prefix = $xoopsDB->prefix();
$sql = <<< SQL
SELECT 1
FROM `${prefix}_${name}`
LIMIT 1
SQL;
if (!($res = $xoopsDB->query($sql))) {
return false;
}
$xoopsDB->freeRecordSet($res);
return true;
}
public static function makeDirectory($dirname)
{
$path = MYDUMPTOOL_OUTPUTDIR.('' !== $dirname ? '/'.$dirname : '');
if (!is_dir($path)) {
if (!@mkdir($path, 0755, true)) {
exit('Failed to create directory: '.$path.PHP_EOL);
}
}
}
public static function saveJson($fname, $data)
{
$path = MYDUMPTOOL_OUTPUTDIR.'/'.$fname;
if (false === file_put_contents($path, json_encode($data, JSON_UNESCAPED_UNICODE))) {
exit('Failed to save json file: '.$path.PHP_EOL);
}
}
public static function fileDownload($url, $fpath)
{
$fp = fopen($fpath, 'w');
if (false === $fp) {
exit('Failed to open file: '.$fpath.PHP_EOL);
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FAILONERROR, true);
curl_setopt($curl, CURLOPT_FILE, $fp);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
$ret = curl_exec($curl);
fclose($fp);
if (false === $ret) {
unlink($fpath);
exit('Failed to download file, unexpected error: '.$url.PHP_EOL);
}
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if (200 !== $code) {
unlink($fpath);
exit('Failed to download file, invalid status code('.$code.'): '.$url.PHP_EOL);
}
curl_close($curl);
return true;
}
public static function getMimeType($fpath)
{
$finfo = finfo_open(FILEINFO_MIME);
$mime = finfo_file($finfo, $fpath);
finfo_close($finfo);
$mime = preg_replace('/(;.*)$/', '', $mime);
return $mime;
}
public static function getModule($dirname)
{
$moduleHandler = xoops_gethandler('module');
$moduleObj = $moduleHandler->getByDirname($dirname);
return [
'id' => (int) $moduleObj->get('mid'),
'name' => $moduleObj->get('name'),
'dirname' => $moduleObj->get('dirname'),
'version' => (int) $moduleObj->get('version'),
'lastupdate' => (int) $moduleObj->get('last_update'),
];
}
public static function canModuleRead($dirname, $uid)
{
$moduleHandler = xoops_gethandler('module');
$moduleObj = $moduleHandler->getByDirname($dirname);
$moduleId = (int) $moduleObj->get('mid');
$memberHandler = xoops_gethandler('member');
$groupIds = 0 === $uid ? [XOOPS_GROUP_ANONYMOUS] : $memberHandler->getGroupsByUser($uid);
$groupPermHandler = xoops_gethandler('groupperm');
$ret = $groupPermHandler->checkRight('module_read', $moduleId, $groupIds);
return $ret;
}
public static function mlang($s, $url, $lang)
{
if (!defined('CUBE_UTILS_ML_LANGS')) {
exit('Error: cubeUtils is not loaded'.PHP_EOL);
}
$mLanguage = $lang;
$mLanguages = explode(',', CUBE_UTILS_ML_LANGS);
$mLanguageNames = explode(',', CUBE_UTILS_ML_LANGNAMES);
// escape brackets inside of <input type="text" value="...">
$s = preg_replace_callback('/(\<input)([^>]*)(\>)/isU', 'self::mlang_escapeBracketTextBox', $s);
// escape brackets inside of <textarea></textarea>
$s = preg_replace_callback('/(\<textarea[^>]*\>)(.*)(<\/textarea\>)/isU', 'self::mlang_escapeBracket', $s);
// multilanguage image tag
$langimages = explode(',', CUBE_UTILS_ML_LANGIMAGES);
$langnames = explode(',', CUBE_UTILS_ML_LANGNAMES);
@list($url, $query) = explode('?', $url);
if (empty($query)) {
$link_base = '?'.CUBE_UTILS_ML_PARAM_NAME.'=';
} elseif (false === ($pos = strpos($query, CUBE_UTILS_ML_PARAM_NAME.'='))) {
$link_base = '?'.htmlspecialchars($query, ENT_QUOTES).'&amp;'.CUBE_UTILS_ML_PARAM_NAME.'=';
} elseif ($pos < 2) {
$link_base = '?'.CUBE_UTILS_ML_PARAM_NAME.'=';
} else {
$link_base = '?'.htmlspecialchars(substr($query, 0, $pos - 1), ENT_QUOTES).'&amp;'.CUBE_UTILS_ML_PARAM_NAME.'=';
}
$link_base = $url.$link_base;
$langimage_html = '';
foreach ($mLanguages as $l => $lang) {
$langimage_html .= '<a rel="nofollow" href="'.$link_base.$lang.'"><img src="'.XOOPS_URL.'/'.$langimages[$l].'" alt="flag" title="'.$langnames[$l].'" /></a>';
}
$s = preg_replace('/\['.CUBE_UTILS_ML_IMAGETAG.'\]/', $langimage_html, $s);
$s = preg_replace('/\['.CUBE_UTILS_ML_URLTAG.':([^\]]*?)\]/', $link_base.'$1', $s);
// simple pattern to strip selected lang_tags
$s = preg_replace('/\[(\/)?([^\]]+\|)?'.preg_quote($mLanguage).'(\|[^\]]+)?\](\<br \/\>)?/i', '', $s);
// eliminate description between the other language tags.
foreach ($mLanguages as $lang) {
if ($mLanguage == $lang) {
continue;
}
$s = preg_replace_callback('/\[(?:^\/[^\]]+\|)?'.preg_quote($lang).'(?:\|[^\]]+)?\].*\[\/(?:^\/[^\]]+\|)?'.preg_quote($lang).'(?:\|[^\]]+)?(?:\]\<br \/\>|\])/isU', 'self::mlang_checkNeverCross', $s);
}
// escape brackets inside of <input type="text" value="...">
$s = preg_replace_callback('/(\<input)([^>]*)(\>)/isU', 'self::mlang_unEscapeBracketTextBox', $s);
// escape brackets inside of <textarea></textarea>
$s = preg_replace_callback('/(\<textarea[^>]*\>)(.*)(<\/textarea\>)/isU', 'self::unEscapeBracket', $s);
return $s;
}
public static function mlang_escapeBracketTextBox($matches)
{
if (preg_match('/type=["\']?(?=text|hidden)["\']?/i', $matches[2])) {
return $matches[1].str_replace('[', '__ml[ml__', $matches[2]).$matches[3];
} else {
return $matches[1].$matches[2].$matches[3];
}
}
public static function mlang_escapeBracket($matches)
{
return $matches[1].str_replace('[', '__ml[ml__', $matches[2]).$matches[3];
}
public static function mlang_unEscapeBracketTextBox($matches)
{
if (preg_match('/type=["\']?(?=text|hidden)["\']?/i', $matches[2])) {
return $matches[1].str_replace('__ml[ml__', '[', $matches[2]).$matches[3];
} else {
return $matches[1].$matches[2].$matches[3];
}
}
public static function mlang_unEscapeBracket($matches)
{
return $matches[1].str_replace('__ml[ml__', '[', $matches[2]).$matches[3];
}
public static function mlang_checkNeverCross($matches)
{
return preg_match(CUBE_UTILS_ML_NEVERCROSSREGEX, $matches[0]) ? $matches[0] : '';
}
}
-7
View File
@@ -1,7 +0,0 @@
<?php
$mainfile = '/data/www/html/mainfile.php';
//$XOOPS_MODULE_D3FORUM = ['forum'];
$XOOPS_MODULE_PICO = ['documents', 'htmldocs'];
$XOOPS_MODULE_COSMODB = ['newdb', 'newdb1', 'newdb2', 'newdb3', 'newdb4', 'newdb5', 'newdb6', 'newdb7', 'newdb8', 'newdb9', 'newdb10', 'newdb112', 'newdb12', 'newdb13'];
-27
View File
@@ -1,27 +0,0 @@
#!/bin/sh
DESTDIR=$(dirname $0)/static-contents
XOOPS_ROOT_PATH=/data/www/html
XOOPS_MODULE_PATH=${XOOPS_ROOT_PATH}/modules
COSMODBS="
newdb1
newdb2
newdb3
newdb5
newdb7
newdb8
newdb9
newdb10
newdb112
newdb12
newdb13"
for i in ${COSMODBS}; do
SRC=${XOOPS_MODULE_PATH}/${i}/extract
DEST=${DESTDIR}/modules/${i}/extract
if test ! -d ${DEST}; then
mkdir -p ${DEST}
fi
rsync -av --delete ${SRC}/ ${DEST}/
done
-5
View File
@@ -1,5 +0,0 @@
#!/bin/sh
DESTDIR=$(dirname $0)/static-contents
rsync -av --delete /data/www/static/ $DESTDIR/static/
-193
View File
@@ -1,193 +0,0 @@
<?php
require_once __DIR__.'/common.inc.php';
if (!isset($XOOPS_MODULE_COSMODB) || empty($XOOPS_MODULE_COSMODB)) {
exit('Not configured for cosmodb module'.PHP_EOL);
}
foreach ($XOOPS_MODULE_COSMODB as $dirname) {
dumpCosmoDB($dirname);
}
function dumpCosmoDB($dirname)
{
global $xoopsDB;
$config = [];
if (!MyDumpTool::canModuleRead($dirname, 0)) {
echo 'No read permission for Guest user: '.$dirname.PHP_EOL;
return false;
}
echo $dirname.PHP_EOL;
MyDumpTool::makeDirectory('public/modules/'.$dirname);
// copy noimage
MyDumpTool::makeDirectory('public/modules/'.$dirname.'/images');
$spath = XOOPS_ROOT_PATH.'/modules/'.$dirname.'/images/noimage.gif';
$dpath = MYDUMPTOOL_OUTPUTDIR.'/public/modules/'.$dirname.'/images/noimage.gif';
MyDumpTool::fileCopy($spath, $dpath);
// component_master table
$sql = sprintf('SELECT * FROM `%s` ORDER BY `sort`,`comp_id`', $xoopsDB->prefix($dirname.'_component_master'));
$modKeys = ['comp_id' => 'i', 'type' => 'i', 'onoff' => 'i', 'sort' => 'i', 'nonull' => 'i', 'textmax' => 'i', 'onoff_refine' => 'i'];
// onoff: use for sort, onoff_refine: use for refine search, 0: means yes, 1: means no
$config['component'] = queryDatabase($sql, $modKeys);
// keyword table
$sql = sprintf('SELECT * FROM `%s` ORDER BY `kw_id`', $xoopsDB->prefix($dirname.'_keyword'));
$modKeys = ['kw_id' => 'i', 'sort' => 'i'];
$res = queryDatabase($sql, $modKeys);
foreach ($res as $idx => $row) {
$path = explode('/', trim($row['path'], '/'));
$parent = array_pop($path);
$res[$idx]['pid'] = ($parent == '') ? 0 : intval($parent);
unset($res[$idx]['path']);
}
$config['keyword'] = $res;
// detail table
$sql = sprintf('SELECT * FROM `%s` WHERE `detail_id`=1', $xoopsDB->prefix($dirname.'_detail'));
$modKeys = ['detail_id' => 'd', 'template' => 'h'];
$res = queryDatabase($sql, $modKeys);
$config['detail'] = $res[0]['template'];
// list table
$sql = sprintf('SELECT * FROM `%s` WHERE `onoff`=0 ORDER BY `sort`,`list_id`', $xoopsDB->prefix($dirname.'_list'));
$modKeys = ['list_id' => 'i', 'type' => 'i', 'onoff' => 'd', 'sort' => 'i'];
$config['list'] = queryDatabase($sql, $modKeys);
//var_dump($config);
$dHandler = Cosmoapi_Utils::getTrustModuleHandler('data', 'cosmoapi');
$dHandler->setDirname($dirname);
$ids = $dHandler->getIds();
foreach ($ids as $id => $label) {
$obj = $dHandler->get($id);
$keywords = [];
foreach ($obj->mKeywords as $kObj) {
$keywords[] = intval($kObj->mKeywordId);
}
$components = [];
foreach ($obj->mComponents as $cObj) {
$components[] = [
'name' => $cObj->mName,
'value' => $cObj->mValue,
];
}
$items = [];
foreach ($obj->mItems as $iObj) {
$items[] = [
'type' => $iObj->mType,
'name' => $iObj->mName,
'path' => $iObj->mPath,
'reg_date' => intval($iObj->mRegDate),
'reg_user' => getUserInfo($iObj->mRegUserId),
];
}
$thumbnails = [];
foreach ($obj->mThumbnails as $thumbnail) {
$thumbnails[] = [
'url' => preg_replace('/^'.preg_quote(XOOPS_URL.'/modules/'.$dirname.'/extract/'.$id.'/thumbnail/','/').'/', '', $thumbnail['url']),
'caption' => $thumbnail['caption'],
];
}
$commentTopics = [];
foreach ($obj->mComments as $ctObj) {
$comment = [
'subject' => $ctObj->mComment->mSubject,
'message' => $ctObj->mComment->mMessage,
'reg_date' => intval($ctObj->mComment->mRegDate),
'reg_user' => getUserInfo($ctObj->mComment->mRegUser),
];
$replies = [];
foreach ($ctObj->mReplies as $cObj) {
$replies[] = [
'subject' => $cObj->mSubject,
'message' => $cObj->mMessage,
'reg_date' => intval($cObj->mRegDate),
'reg_user' => getUserInfo($cObj->mRegUser),
];
}
$commentTopics[] = [
'topic_id' => intval($ctObj->mTopicId),
'com_id' => intval($ctObj->mComId),
'type' => $ctObj->mType,
'comment' => $comment,
'replies' => $replies,
];
}
$links = [];
foreach ($obj->mLinks as $lObj) {
$href = preg_replace(preg_replace('/https/', 'https?', '/'.preg_quote(XOOPS_URL, '/').'/'), '', $lObj->mHref);
if (strpos($href, 'invbrain') !== false) {
var_dump($href);
}
$links[] = [
'type' => (int) $lObj->mType,
'user' => getUserInfo($lObj->mUid),
'name' => $lObj->mName,
'href' => $href,
'note' => $lObj->mNote,
];
}
$basic = [
'id' => $id,
'label' => $obj->mLabel,
'reg_date' => intval($obj->mRegDate),
'author' => getUserInfo($obj->mAuthor),
'views' => intval($obj->mViews),
'components' => $components,
'thumbnails' => $thumbnails,
'items' => $items,
];
$detail = [
'id' => $id,
'users' => array_map('getUserInfo', $obj->mUserIds),
'keywords' => $keywords,
'comment_topics' => $commentTopics,
'links' => $links,
];
MyDumpTool::saveJson('public/modules/'.$dirname.'/'.$id.'.json', $detail);
$config['data'][] = $basic;
}
MyDumpTool::saveJson('public/modules/'.$dirname.'/index.json', $config);
}
function getUserInfo($uid) {
static $users = [];
if (!isset($users[$uid])) {
$memberHandler = xoops_gethandler('member');
$userObj = $memberHandler->getUser($uid);
if (is_object($userObj)) {
$name = trim($userObj->get('name'));
$uname = trim($userObj->get('uname'));
$users[$uid] = $uname; // $name !== '' ? $name.' ('.$uname.')' : $uname;
} else {
$users[$uid] = 'unknown';
}
}
return $users[$uid];
}
function queryDatabase($sql, $modKeys = []) {
global $xoopsDB;
$ret = [];
if (!($res = $xoopsDB->query($sql))) {
var_dump($xoopsDB);
exit();
}
while ($row = $xoopsDB->fetchArray($res)) {
MyDumpTool::decode($row);
foreach ($modKeys as $key => $type) {
switch ($type) {
case 'i':
$row[$key] = intval($row[$key]);
break;
case 'd':
unset($row[$key]);
break;
case 'h':
$row[$key] = preg_replace('/\s+([a-z]+)=\'([^\']*)\'/U', ' \1="\2"', MyDumpTool::fixHtml($row[$key]));
break;
}
}
$ret[] = $row;
}
$xoopsDB->freeRecordSet($res);
return $ret;
}
-181
View File
@@ -1,181 +0,0 @@
<?php
require_once __DIR__.'/common.inc.php';
$prefix = $xoopsDB->prefix();
$table = 'nipfcredits_organization';
if (!MyDumpTool::tableExists($table)) {
exit('credits module not found'.PHP_EOL);
}
MyDumpTool::makeDirectory('public/modules/credits');
// module
$module = MyDumpTool::getModule('credits');
// organization
$organization = [];
$sql = <<< SQL
SELECT
`o`.*
FROM `${prefix}_nipfcredits_organization` AS `o`
SQL;
if (!($res = $xoopsDB->query($sql))) {
var_dump($xoopsDB);
exit();
}
while ($row = $xoopsDB->fetchArray($res)) {
MyDumpTool::decode($row);
$organization = $row;
}
$xoopsDB->freeRecordSet($res);
$organization['com_email'] = str_replace('@', ' (at) ', $organization['com_email']);
$organization['com_url'] = XOOPS_URL;
$organization['institute'] = '[en]Neuroinformatics Unit, RIKEN Center for Brain Science[/en][ja]理化学研究所 脳神経科学研究センター 神経情報基盤ユニット[/ja]';
$organization['url'] = 'https://www.ni.riken.jp/';
$organization['email'] = 'office (at) ni.riken.jp';
$organization['address'] = '[en]Hirosawa 2-1, Wako, Saitama, 351-0198 Japan[/en][ja]埼玉県和光市広沢 2-1[/ja]';
$organization['tel'] = '+81 48 (462) 1111';
// member
$member = [];
$sql = <<< SQL
SELECT
`m`.*
FROM `${prefix}_nipfcredits_member` AS `m`
ORDER BY `m`.`weight`
SQL;
if (!($res = $xoopsDB->query($sql))) {
var_dump($xoopsDB);
exit();
}
while ($row = $xoopsDB->fetchArray($res)) {
MyDumpTool::decode($row);
$member[] = $row;
}
$xoopsDB->freeRecordSet($res);
$opage = getOrganizationPage($organization, $member, $module);
MyDumpTool::saveJson('public/modules/credits/0.json', $opage);
//var_dump($opage);
// pages
$pages = [];
$sql = <<< SQL
SELECT
`p`.*
FROM `${prefix}_nipfcredits_page` AS `p`
ORDER BY `p`.`weight`
SQL;
if (!($res = $xoopsDB->query($sql))) {
var_dump($xoopsDB);
exit();
}
while ($row = $xoopsDB->fetchArray($res)) {
MyDumpTool::decode($row);
myDumpTool::convertToInt($row, ['pid', 'weight', 'lastupdate']);
$content = replaceOrganization($row['content'], $organization);
$content = MyDumpTool::fixHtml($content);
$content = preg_replace('/href="(?:\.\/|'.preg_quote(XOOPS_URL, '/').'\/modules\/credits\/)?index\.php\?id=(\d+)"/', 'href="/credits/\1"', $content);
$imageUrl = [];
$content = preg_replace_callback('/<img ([^>]*)src="([^"]+)"([^>]*)\/>/Usi', function ($matches) use (&$imageUrl, $row) {
$url = $matches[2];
if (preg_match('/^(.+)\/([^\/]+\.(:?png|jpg|gif|svg))(\?.+)?$/i', $url, $m)) {
if (!isset($imageUrl[$m[1]])) {
$imageUrl[$m[1]] = count($imageUrl) + 1;
}
$id = $imageUrl[$m[1]];
$fname = '/modules/credits/images/'.$row['pid'].'/'.$id.'/'.urldecode($m[2]);
$fpath = MYDUMPTOOL_OUTPUTDIR.'/public'.$fname;
if (!file_exists($fpath)) {
MyDumpTool::makeDirectory('public/modules/credits/images');
MyDumpTool::makeDirectory('public/modules/credits/images/'.$row['pid']);
MyDumpTool::makeDirectory('public/modules/credits/images/'.$row['pid'].'/'.$id);
if (preg_match('/^\//', $url)) {
$url = XOOPS_URL.$url;
}
MyDumpTool::fileDownload($url, $fpath);
}
$url = 'images/'.$row['pid'].'/'.$id.'/'.$m[2];
}
return '<img '.$matches[1].'src="'.$url.'"'.$matches[3].'/>';
}, $content);
$content = preg_replace('/<a (?:[^>]*)href="(?:'.preg_quote(XOOPS_URL, '/').')?\/modules\/xoonips\/(?:register|edit|user)[^"]*"(?:[^>]*)>(.*)<\/a>/Usi', '<s>\1</s>(closed)', $content);
$row['content'] = $content;
MyDumpTool::dropColumn($row, ['weight']);
$pages[] = [
'id' => $row['pid'],
'title' => $row['title'],
];
MyDumpTool::saveJson('public/modules/credits/'.$row['pid'].'.json', $row);
}
$xoopsDB->freeRecordSet($res);
//var_dump($pages);
$pages[] = [
'id' => $opage['id'],
'title' => $opage['title'],
];
$data = [
'name' => $module['name'],
'pages' => $pages,
];
MyDumpTool::saveJson('public/modules/credits/index.json', $data);
function replaceOrganization($text, $org)
{
$textutil = xoonips_getutility('text');
$map = [
'{COMMITTEE_NAME}' => $textutil->html_special_chars($org['committee']),
'{COMMITTEE_EMAIL}' => '<s>'.$textutil->html_special_chars($org['com_email']).'</s>(committee email has been closed)',
'{INSTITUTE_NAME}' => $textutil->html_special_chars($org['institute']),
'{INSTITUTE_URL}' => $textutil->html_special_chars($org['url']),
'{INSTITUTE_EMAIL}' => $textutil->html_special_chars($org['email']),
'{INSTITUTE_ADDRESS}' => $textutil->html_special_chars($org['address']),
'{INSTITUTE_TEL}' => $textutil->html_special_chars($org['tel']),
'{PLATFORM_URL}' => XOOPS_URL,
];
return str_replace(array_keys($map), $map, $text);
}
function getOrganizationPage($org, $member, $module)
{
$textutil = xoonips_getutility('text');
$members = [];
if (!empty($member)) {
$members[] = ' <li>[en]Members[/en][ja]委員一覧[/ja]';
$members[] = ' <ul>';
foreach ($member as $m) {
$members[] = ' <li>'.$textutil->html_special_chars($m['name'].' : '.$m['division']).'</li>';
}
$members[] = ' </ul>';
$members[] = ' </li>';
}
$members = implode("\n", $members);
$committee = $textutil->html_special_chars($org['committee']);
$institute = $textutil->html_special_chars($org['institute']);
$address = $textutil->html_special_chars($org['address']);
$url = $textutil->html_special_chars($org['url']);
$email = $textutil->html_special_chars($org['com_email']);
$html = <<< HTML
<h4>${committee}</h4>
<ul>
<li>E-Mail: <strike>${email}</strike></li>
${members}
</ul>
<h4>${institute}</h4>
<ul>
<li>[en]Address[/en][ja]所在地[/ja]: ${address}</li>
<li>URL: <a href="${url}" target="_blank" rel=”noopener noreferrer”>${url}</a></li>
</ul>
HTML;
return [
'id' => 0,
'title' => '[en]Organization[/en][ja]運用母体[/ja]',
'content' => $html,
'lastupdate' => 0,
];
}
-186
View File
@@ -1,186 +0,0 @@
<?php
require_once __DIR__.'/common.inc.php';
if (!isset($XOOPS_MODULE_PICO) || empty($XOOPS_MODULE_PICO)) {
exit('Not configured for pico module'.PHP_EOL);
}
error_reporting(0);
require_once XOOPS_TRUST_PATH.'/modules/pico/include/main_functions.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/include/common_functions.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/pico.textsanitizer.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/PicoUriMapper.class.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/PicoPermission.class.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/PicoModelCategory.class.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/PicoModelContent.class.php';
require_once XOOPS_TRUST_PATH.'/libs/altsys/class/AltsysBreadcrumbs.class.php';
error_reporting(E_ALL);
foreach ($XOOPS_MODULE_PICO as $pico) {
dumpPico($pico);
}
function dumpPico($pico)
{
global $xoopsDB;
$prefix = $xoopsDB->prefix();
$table = $pico.'_contents';
if (!MyDumpTool::tableExists($table)) {
exit('pico('.$pico.') module not found'.PHP_EOL);
}
MyDumpTool::makeDirectory('public/modules/'.$pico);
$moduleHandler = xoops_gethandler('module');
$module = $moduleHandler->getByDirname($pico);
$moduleConfigHandler = xoops_gethandler('config');
$moduleConfig = $moduleConfigHandler->getConfigsByDirname($pico);
$permObj = PicoPermission::getInstance();
$perms = $permObj->getPermissions($pico);
$categoryHandler = new PicoCategoryHandler($pico, $perms);
$contentHandler = new PicoContentHandler($pico);
$cats = $categoryHandler->getAllCategories();
$confContents = [];
$confCategories = [];
$dataMap = [];
$dataSeq = 1;
foreach ($cats as $cat) {
$catData = $cat->getData();
$modConfig = $cat->getOverriddenModConfig();
$link = pico_common_make_category_link4html($modConfig, $catData, $pico);
MyDumpTool::decode($catData);
$confCategories[] = [
'id' => $catData['id'],
'title' => $catData['cat_title'],
'desc' => (string) $catData['cat_desc'],
'pid' => (int) $catData['pid'],
'weight' => (int) $catData['cat_weight'],
'link' => $link,
];
$contents = $contentHandler->getCategoryContents($cat);
foreach ($contents as $content) {
$data = $content->getData();
$link = pico_common_make_content_link4html($modConfig, $data);
MyDumpTool::decode($data);
$url = XOOPS_URL.'/modules/'.$pico.'/'.$link;
$content_en = normalizeHtml(MyDumpTool::mlang($data['body_cached'], $url, 'en'), $url);
$content_ja = normalizeHtml(MyDumpTool::mlang($data['body_cached'], $url, 'ja'), $url);
$item = [
'id' => $data['id'],
'title' => $data['subject_raw'],
'content' => [
'en' => $content_en,
'ja' => $content_ja,
],
];
MyDumpTool::saveJson('public/modules/'.$pico.'/'.$data['id'].'.json', $item);
$confContents[] = [
'id' => $item['id'],
'title' => $data['subject_raw'],
'cat_id' => (int) $data['cat_id'],
'weight' => (int) $data['weight'],
'link' => $link,
];
}
}
$moduleinfo = [
'name' => $module->get('name'),
'dirname' => $pico,
'message' => $moduleConfig['top_message'],
'show_menuinmoduletop' => (int) $moduleConfig['show_menuinmoduletop'],
'show_listasindex' => (int) $moduleConfig['show_listasindex'],
'show_breadcrumbs' => (int) $moduleConfig['show_breadcrumbs'],
'show_pagenavi' => (int) $moduleConfig['show_pagenavi'],
];
MyDumpTool::decode($moduleinfo);
$config = [
'module' => $moduleinfo,
'categories' => $confCategories,
'contents' => $confContents,
];
MyDumpTool::saveJson('public/modules/'.$pico.'/index.json', $config);
}
function normalizeUrl($url, $base)
{
$localpath = function ($url) {
$purl1 = parse_url($url);
$purl2 = parse_url(XOOPS_URL);
if ($purl1['host'] === $purl2['host']) {
$url = preg_replace('/^http:/', 'https:', $url);
}
return $url;
};
if ('' === $url) {
return $localpath($base);
}
$purl = parse_url($url);
if (isset($purl['scheme'])) {
return $localpath($url);
}
$pburl = parse_url($base);
$path = $pburl['path'];
if ('/' == $url[0]) {
$path = '';
} elseif ('#' !== $url[0] && '?' !== $url[0]) {
$path = preg_replace('#/[^/]*$#', '', $path).'/';
}
$path .= $url;
$pattern = ['#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#'];
do {
$path = preg_replace($pattern, '/', $path, -1, $count);
} while (0 < $count);
return $localpath($pburl['scheme'].'://'.$pburl['host'].$path);
}
function downloadLocalFile($url)
{
$url2 = preg_replace('/'.preg_quote(XOOPS_URL, '/').'/', '', $url);
if (preg_match('/^\//', $url2)) {
if (preg_match('/\/[^\/]+\.(zip|pdf|doc|docx|xls|xlsx|ppt|pptx|txt|gif|jpg|jpeg|png|wmv|tar\.gz|mpg|obj|mtl|tif|avi)(\?.+)?$/i', $url2)) {
$spath = urldecode($url2);
$opath = MYDUMPTOOL_OUTPUTDIR.'/public'.$spath;
if (!file_exists($opath)) {
$odir = dirname($opath);
mkdir($odir, 0755, true);
MyDumpTool::fileDownload($url, $opath);
}
} elseif (!preg_match('/\/([^\/]+\.(php|html))?(\?.+)?(#.+)?$/i', $url2)) {
var_dump($url2);
}
$url = $url2;
}
return $url;
}
function normalizeHtml($text, $path)
{
$text = MyDumpTool::fixHtml($text);
$text = preg_replace_callback('/<img ([^>]*)src="(.*)"([^>]*)\/>/Us', function ($matches) use ($path) {
$url = htmlspecialchars_decode($matches[2], ENT_QUOTES);
$url = normalizeUrl($url, $path);
$url = downloadLocalFile($url);
return '<img '.$matches[1].'src="'.htmlspecialchars($url, ENT_QUOTES).'"'.$matches[3].'/>';
}, $text);
$text = preg_replace_callback('/<a ([^>]*)href="([^"]+)"([^>]*)>/Us', function ($matches) use ($path) {
$url = htmlspecialchars_decode($matches[2], ENT_QUOTES);
$url = normalizeUrl($url, $path);
$url = downloadLocalFile($url);
return '<a '.$matches[1].'href="'.htmlspecialchars($url, ENT_QUOTES).'"'.$matches[3].'>';
}, $text);
$text = preg_replace_callback('/<embed ([^>]*)src="(.*)"([^>]*)\/>/Us', function ($matches) use ($path) {
$url = htmlspecialchars_decode($matches[2], ENT_QUOTES);
$url = normalizeUrl($url, $path);
$url = downloadLocalFile($url);
return '<embed '.$matches[1].'src="'.htmlspecialchars($url, ENT_QUOTES).'"'.$matches[3].'/>';
}, $text);
$text = preg_replace('/ lang="([^"]+)"/Us', '', $text);
$text = preg_replace('/ xml:lang="([^"]+)"/Us', '', $text);
return $text;
}
-117
View File
@@ -1,117 +0,0 @@
<?php
require_once __DIR__.'/common.inc.php';
MyDumpTool::makeDirectory('public/modules');
MyDumpTool::makeDirectory('public/modules/PubMedPDF');
// MyDumpTool::makeDirectory('public/modules/PubMedPDF/detail');
dumpPubMedPDF();
function dumpPubMedPDF()
{
global $xoopsDB;
$prefix = $xoopsDB->prefix();
// module
$module = MyDumpTool::getModule('PubMedPDF');
// paper
$paper = [];
$authorIdMap = [];
$journalIdMap = [];
$sql = <<< SQL
SELECT
*
FROM `${prefix}_pmid_id`
ORDER BY `id` ASC
SQL;
if (!($res = $xoopsDB->query($sql))) {
var_dump($xoopsDB);
exit();
}
while ($row = $xoopsDB->fetchArray($res)) {
MyDumpTool::decode($row);
MyDumpTool::convertToInt($row, ['id', 'PMID', 'Journal', 'Year']);
$authors = array_map('trim', explode(',', rtrim(trim($row['Author']), ',')));
$authorIds = [];
foreach ($authors as $_author) {
$authorId = (int) substr($_author, 1, -1);
$authorIds[] = $authorId;
$authorIdMap[$authorId][] = $row['id'];
}
$journalIdMap[$row['Journal']][] = $row['id'];
$paper[] = [
'id' => $row['id'],
'pmid' => $row['PMID'],
'journal_id' => $row['Journal'],
'year' => $row['Year'],
'volume' => $row['Volume'],
'page' => $row['Page'],
'author_ids' => $authorIds,
'title' => $row['Title'],
];
$paperDetail = [
'id' => $row['id'],
'abstract' => $row['Abstract'],
'reg_user' => $row['R_usr'],
'reg_date' => $row['R_date'],
];
//MyDumpTool::saveJson('public/modules/PubMedPDF/detail/'.$row['id'].'.json', $paperDetail);
}
$xoopsDB->freeRecordSet($res);
// author
$author = [];
$sql = <<< SQL
SELECT
*
FROM `${prefix}_pmid_author`
ORDER BY `Author` ASC
SQL;
if (!($res = $xoopsDB->query($sql))) {
var_dump($xoopsDB);
exit();
}
while ($row = $xoopsDB->fetchArray($res)) {
MyDumpTool::decode($row);
MyDumpTool::convertToInt($row, ['id']);
$author[] = [
'id' => $row['id'],
'name' => $row['Author'],
'count' => count($authorIdMap[$row['id']]),
];
}
$xoopsDB->freeRecordSet($res);
// journal
$journal = [];
$sql = <<< SQL
SELECT
*
FROM `${prefix}_pmid_journal`
ORDER BY `Journal` ASC
SQL;
if (!($res = $xoopsDB->query($sql))) {
var_dump($xoopsDB);
exit();
}
while ($row = $xoopsDB->fetchArray($res)) {
MyDumpTool::decode($row);
MyDumpTool::convertToInt($row, ['id']);
$journal[] = [
'id' => $row['id'],
'name' => $row['Journal'],
'count' => count($journalIdMap[$row['id']]),
];
}
$xoopsDB->freeRecordSet($res);
$data = [
'name' => $module['name'],
'author' => $author,
'journal' => $journal,
'paper' => $paper,
];
MyDumpTool::saveJson('public/modules/PubMedPDF/index.json', $data);
}
-1176
View File
File diff suppressed because it is too large Load Diff
-106
View File
@@ -1,106 +0,0 @@
<?php
require_once __DIR__.'/common.inc.php';
$data = dumpXwords();
MyDumpTool::makeDirectory('public/modules/xwords');
MyDumpTool::saveJson('public/modules/xwords/index.json', $data);
function dumpXwords()
{
global $xoopsDB;
$prefix = $xoopsDB->prefix();
// module
$module = MyDumpTool::getModule('xwords');
// category
$category = [];
$sql = <<< SQL
SELECT
*
FROM `${prefix}_xwords_cat`
ORDER BY `weight` ASC
SQL;
if (!($res = $xoopsDB->query($sql))) {
var_dump($xoopsDB);
exit();
}
while ($row = $xoopsDB->fetchArray($res)) {
MyDumpTool::decode($row);
MyDumpTool::convertToInt($row, ['categoryID', 'total', 'weight']);
$category[] = [
'id' => $row['categoryID'],
'name' => $row['name'],
'total' => $row['total'],
];
}
$xoopsDB->freeRecordSet($res);
// entry
$entry = [];
$sql = <<< SQL
SELECT
*
FROM `${prefix}_xwords_ent`
WHERE `offline` = 0
SQL;
if (!($res = $xoopsDB->query($sql))) {
var_dump($xoopsDB);
exit();
}
while ($row = $xoopsDB->fetchArray($res)) {
MyDumpTool::decode($row);
MyDumpTool::convertToInt($row, ['entryID', 'categoryID', 'datesub', 'counter']);
$procs = explode(',', $row['proc']);
$term = $row['term'];
$yomi = $procs[1];
$initTerm = mb_substr($term, 0, 1, 'UTF-8');
$initTerm = mb_convert_kana($initTerm, 'asHc', 'UTF-8');
$initTerm = strtoupper($initTerm);
$initYomi = mb_substr($yomi, 0, 1, 'UTF-8');
$initYomi = mb_convert_kana($initYomi, 'asHc', 'UTF-8');
$initYomi = strtoupper($initYomi);
$kana = [
'01' => '[あ-お]',
'02' => '[か-こが-ご]',
'03' => '[さ-そざ-ぞ]',
'04' => '[た-とだ-ど]',
'05' => '[な-の]',
'06' => '[は-ほば-ぼぱ-ぽ]',
'07' => '[ま-も]',
'08' => '[や-よ]',
'09' => '[ら-ろ]',
'10' => '[わ-ん]',
'11' => '.*',
];
if (preg_match('/^[A-Z]$/', $initTerm)) {
$init = $initTerm;
} else {
foreach ($kana as $index => $pattern) {
if (preg_match('/^'.$pattern.'/u', $initYomi)) {
$init = $index;
break;
}
}
}
$entry[] = [
'id' => $row['entryID'],
'cat_id' => $row['categoryID'],
'term' => $row['term'],
'yomi' => $yomi,
'initial' => $init,
'definition' => $row['definition'],
'timestamp' => $row['datesub'],
'counter' => $row['counter'],
];
}
$xoopsDB->freeRecordSet($res);
return [
'name' => $module['name'],
'category' => $category,
'entry' => $entry,
];
}
-36
View File
@@ -1,36 +0,0 @@
<?php
if ($argc !== 2 || !preg_match('/\.html?$/', $argv[1]) || !file_exists($argv[1])) {
exit('Error: html file not found.'.PHP_EOL);
}
$fpath = $argv[1];
$timestamp = filemtime($fpath);
$text = file_get_contents($fpath);
$encoding = mb_detect_encoding($text);
if (!in_array($encoding, ['UTF-8', 'ASCII'])) {
if (in_array($encoding, ['SJIS'])) {
$encoding = 'CP932';
}
$text = mb_convert_encoding($text, 'UTF-8', $encoding);
$text = preg_replace('/(<meta\s+http-equiv=(?:"|\')content-type(?:"|\')\s+content=(?:"|\')text\/html;\s*charset=)(?:[^"\']+)((?:"|\')\s*>)/is', '\1UTF-8\2', $text);
}
$text = \Normalizer::normalize(trim($text), \Normalizer::FORM_C);
static $config = [
//'clean' => true,
'hide-comments' => true,
'indent' => true,
'output-xhtml' => true,
'preserve-entities' => true,
//'show-body-only' => true,
'wrap' => 0,
'input-encoding' => 'utf8',
'output-encoding' => 'utf8',
'output-bom' => false,
];
$text = tidy_repair_string($text, $config);
$text = preg_replace('/<table([^>]*)>((?:\s*<caption[^>]*>.*<\/caption>)?\s*)<tr([^>]*)>/Us', '<table\1>\2<tbody><tr\3>', $text);
$text = preg_replace('/<\/tr>(\s*)<\/table>/s', '</tr></tbody>\1</table>', $text);
file_put_contents($fpath, $text);
touch($fpath, $timestamp);
-311
View File
@@ -1,311 +0,0 @@
<?php
require_once __DIR__.'/common.inc.php';
if (!isset($XOOPS_MODULE_PICO) || empty($XOOPS_MODULE_PICO)) {
exit('Not configured for pico module'.PHP_EOL);
}
error_reporting(0);
require_once XOOPS_TRUST_PATH.'/modules/pico/include/main_functions.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/include/common_functions.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/include/transact_functions.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/pico.textsanitizer.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/PicoUriMapper.class.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/PicoPermission.class.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/PicoModelCategory.class.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/PicoModelContent.class.php';
require_once XOOPS_TRUST_PATH.'/libs/altsys/class/AltsysBreadcrumbs.class.php';
error_reporting(E_ALL);
foreach ($XOOPS_MODULE_PICO as $dirname) {
$pico = new FixPicoWraps($dirname);
if ($pico->isWrapsMode()) {
$pico->fixCategories();
$pico->fixContents();
}
}
class FixPicoWraps
{
private $mDirname;
private $mModule;
private $mModuleConfig;
private $mWrapsPath;
public function __construct($dirname)
{
$this->mDirname = $dirname;
$moduleHandler = xoops_gethandler('module');
$this->mModule = $moduleHandler->getByDirname($dirname);
$moduleConfigHandler = xoops_gethandler('config');
$this->mModuleConfig = $moduleConfigHandler->getConfigsByDirname($dirname);
$this->mWrapsPath = XOOPS_TRUST_PATH.'/wraps/'.$dirname;
}
public function isWrapsMode()
{
$key = 'use_wraps_mode';
return isset($this->mModuleConfig[$key]) && '1' === $this->mModuleConfig[$key];
}
public function getWrapsFiles()
{
exec(sprintf('find "%s" -type f -name "*.html" -o -name "*.htm"', $this->mWrapsPath), $fpaths);
$ret = [];
foreach ($fpaths as $fpath) {
$ret[] = preg_replace('/^'.preg_quote($this->mWrapsPath, '/').'/', '', $fpath);
}
return $ret;
}
public function getWrapsFilesDirectory()
{
$files = $this->getWrapsFiles();
$dirs = array_map('dirname', $files);
$ret = array_unique($dirs);
sort($ret);
return $ret;
}
public function fixCategories()
{
$catVpaths = $this->getWrapsFilesDirectory();
$registeredCatVpaths = ['/' => 0];
$categories = $this->getAllCategories();
foreach ($categories as $category) {
$contents = $category->getContents(true);
$data = $category->getData();
if (empty($contents)) {
// remove empty category.
echo "empty category found. deleting...\n";
$this->deleteCategory($category);
continue;
}
if (null !== $data['cat_vpath']) {
if (!in_array($data['cat_vpath'], $catVpaths)) {
echo 'category vpath not found. '.$data['cat_vpath'].' need to confirm by manual.'."\n";
} else {
$registeredCatVpaths[$data['cat_vpath']] = intval($data['cat_id']);
}
}
}
// register not registered wraps directory.
$notRegisteredCatVpaths = array_diff($catVpaths, array_keys($registeredCatVpaths));
foreach ($notRegisteredCatVpaths as $catVpath) {
$title = basename($catVpath);
$this->createCategory($title, '', 0, $catVpath, 0);
}
// update parent directory
$categories = $this->getAllCategories();
$cmap = ['/' => ['cat_id' => '0', 'cat_vpath' => '/']];
foreach ($categories as $category) {
$data = $category->getData();
if (null !== $data['cat_vpath']) {
$cmap[$data['cat_vpath']] = $data;
}
}
foreach ($cmap as $cvpath => $data) {
if ('0' === $data['cat_id']) {
continue;
}
$pcvpath = dirname($cvpath);
if (!isset($cmap[$pcvpath])) {
echo 'parent category vpath not found: '.$pcvpath.PHP_EOL;
} else {
$pdata = $cmap[$pcvpath];
if ($data['pid'] !== $pdata['cat_id']) {
echo 'parent category id mismatched: '.$data['cat_vpath'].' need to confirm by manual.'."\n";
}
}
}
}
public function fixContents()
{
$wrapFiles = $this->getWrapsFiles();
$foundFiles = [];
foreach ($this->getAllCategories() as $category) {
$cdata = $category->getData();
$cvpath = null === $cdata['cat_vpath'] ? '/' : $cdata['cat_vpath'];
$contents = $category->getContents(true);
foreach ($contents as $content) {
$data = $content->getData4Html();
$vpath = $data['vpath'];
if ($cvpath !== dirname($vpath)) {
echo 'vpath and cat_vpath is not matched..:'.$vpath."\n";
}
$filters = array_map('trim', explode('|', $data['filters']));
if (in_array('wraps', $filters)) {
$fpath = $this->mWrapsPath.$data['vpath'];
if (!file_exists($fpath)) {
echo 'wraps file not found: '.$data['vpath'].PHP_EOL;
}
}
$html = trim($data['body_cached']);
if (0 === strlen($html)) {
echo 'Empty file found: '.$data['vpath'].PHP_EOL;
}
if (in_array($data['vpath'], $wrapFiles)) {
$foundFiles[] = $data['vpath'];
} else {
echo 'Real wraps file not found: '.$data['vpath'].PHP_EOL;
}
if (preg_match('/<script/', $html)) {
echo 'Javascript found : '.$data['vpath'].PHP_EOL;
var_dump($html);
exit();
}
if (preg_match('/onclick=/', $html)) {
echo 'Javascript found : '.$data['vpath'].PHP_EOL;
var_dump($html);
exit();
}
$hasError = false;
$html = $this->checkMlang($html, $hasError);
if ($hasError) {
echo 'mlang error detected: '.$data['vpath'].PHP_EOL;
var_dump($html);
exit();
}
}
}
sort($foundFiles);
$missingFiles = array_diff($wrapFiles, $foundFiles);
if (!empty($missingFiles)) {
echo 'Missing file found: '.implode(', ', $missingFiles).PHP_EOL;
}
}
private function getAllCategories()
{
$permObj = PicoPermission::getInstance();
$perms = $permObj->getPermissions($this->mDirname);
$categoryHandler = new PicoCategoryHandler($this->mDirname, $perms);
return $categoryHandler->getAllCategories(true);
}
private function createCategory($title, $desc, $weight, $vpath, $pid)
{
$db = XoopsDatabaseFactory::getDatabaseConnection();
list($cid) = $db->fetchRow($db->query('SELECT MAX(cat_id)+1 FROM '.$db->prefix($this->mDirname.'_categories')));
list($permId) = $db->fetchRow($db->query('SELECT cat_permission_id FROM '.$db->prefix($this->mDirname.'_categories').' WHERE cat_id='.intval($pid)));
$vars = [
'cat_id' => intval($cid),
'cat_permission_id' => intval($permId),
'cat_vpath' => ('' === $vpath ? 'NULL' : $db->quoteString($vpath)),
'pid' => intval($pid),
'cat_title' => $db->quoteString($title),
'cat_desc' => $db->quoteString($desc),
'cat_path_in_tree' => $db->quoteString(''),
'cat_unique_path' => $db->quoteString(''),
'cat_weight' => intval($weight),
'cat_options' => $db->quoteString(pico_common_serialize([])),
];
$set = [];
foreach ($vars as $key => $value) {
$set[] = sprintf('`%s`=%s', $key, $value);
}
$sql = sprintf('INSERT INTO `%s` SET %s', $db->prefix($this->mDirname.'_categories'), implode(', ', $set));
if (!$db->queryF($sql)) {
var_dump($db);
die(_MD_PICO_ERR_DUPLICATEDVPATH.' or '._MD_PICO_ERR_SQL.__LINE__);
}
pico_sync_cattree($this->mDirname);
echo 'category created: '.$title."\n";
return true;
}
private function deleteCategory($category)
{
global $xoopsModule;
$data = $category->getData();
if (0 == $data['id']) {
echo "cannot delete root(Top) category\n";
return false;
}
if (!empty($data['redundants']['subcattree_raw'])) {
echo "child categories exist\n";
return false;
}
var_dump($data['cat_id'], $data['cat_vpath']);
$backupModule = $xoopsModule;
$xoopsModule = $this->mModule;
pico_delete_category($this->mDirname, $data['cat_id']);
$xoopsModule = $backupModule;
return true;
}
private function checkMlang($text, &$hasError)
{
$hasError = false;
if (!isset($GLOBALS['cubeUtilMlang'])) {
return $text;
}
$errtags = [];
$hls = '<span style="font-weight:bold; color:red">';
$hle = '</span>';
foreach ($GLOBALS['cubeUtilMlang']->mLanguages as $lang) {
$tags = '['.$lang.']';
$tage = '[/'.$lang.']';
$pos = 0;
$is_error = false;
while ($pos < strlen($text)) {
$poss = strpos($text, $tags, $pos);
$pose = strpos($text, $tage, $pos);
if (false === $poss && false === $pose) {
// finished
break;
} elseif (false === $poss && false !== $pose) {
// end tag only found.
$text = substr($text, 0, $pose).$hls.$tage.$hle.substr($text, $pose + strlen($tage));
$is_error = true;
break;
} elseif (false !== $poss && false === $pose) {
// end tag not found.
$text = substr($text, 0, $poss).$hls.$tags.$hle.substr($text, $poss + strlen($tags));
$is_error = true;
break;
}
if ($poss > $pose) {
// end tag found before start tag.
$text = substr($text, 0, $pose).$hls.$tage.$hle.substr($text, $pose + strlen($tage));
$is_error = true;
break;
}
$poss2 = strpos($text, $tags, $poss + strlen($tags));
if (false === $poss2) {
// finished
break;
}
if ($pose > $poss2) {
// next start tag found before end tag
$text = substr($text, 0, $poss2).$hls.$tags.$hle.substr($text, $poss2 + strlen($tags));
$is_error = true;
break;
}
$pos = $pose + strlen($tage);
}
if ($is_error) {
$errtags[] = $lang;
$text = $error.$text;
$text = str_replace([$tags, $tage], ['&lsqb;'.$lang.'&rsqb;', '&lsqb;/'.$lang.'&rsqb;'], $text);
}
}
if (!empty($errtags)) {
$text = '<div class="error">'.$hls.'Unmatched ml tag(s) found: '.implode(', ', $errtags).$hle.'</div>'.$text;
$hasError = true;
}
return $text;
}
}
-68
View File
@@ -1,68 +0,0 @@
<?php
$SITENAME = 'Invertebrate Brain Platform';
$HOSTNAME = 'invbrain';
$FQDN = $HOSTNAME.'.neuroinf.jp';
$URL = 'https://'.$FQDN;
$XOOPS_URL = $URL;
$JSONS = glob(__DIR__.'/../../static-contents/modules/newdb*/index.json');
$items = [];
foreach ($JSONS as $JSON) {
$data = json_decode(file_get_contents($JSON), true);
$mydirname = basename(dirname($JSON));
foreach ($data['data'] as $item) {
$items[] = [
'title' => mlang($item['label']),
'url' => $XOOPS_URL.'/modules/'.$mydirname.'/detail.php?id='.$item['id'],
'date' => $item['reg_date'],
'category' => $mydirname,
];
}
usort($items, function ($a, $b) { return $a['date'] === $b['date'] ? 0 : ($a['date'] > $b['date'] ? -1 : 1);});
$items = array_slice($items, 0, 10);
}
function mlang($text) {
$text = preg_replace('/\[ja\].*\[\/ja\]/Us', '', $text);
$text = preg_replace('/\[\/?en\]/', '', $text);
return $text;
}
//var_dump($items);
$xml = <<< HEAD
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<atom:link href="${XOOPS_URL}/rss.xml" rel="self" type="application/rss+xml" />
<title>${SITENAME}</title>
<link>${URL}</link>
<description>${SITENAME}</description>
<language>en</language>
HEAD;
foreach($items as $item) {
$title = htmlspecialchars($item['title'], ENT_QUOTES);
$url = htmlspecialchars($item['url'], ENT_QUOTES);
$pubDate = gmdate(DATE_RSS, $item['date']);
$category = htmlspecialchars($item['category'], ENT_QUOTES);
$xml .= <<< ITEM
<item>
<title>$title</title>
<link>$url</link>
<pubDate>$pubDate</pubDate>
<guid>$url</guid>
<description></description>
<category>$category</category>
</item>
ITEM;
}
$xml .= <<< FOOTER
</channel>
</rss>
FOOTER;
file_put_contents(__DIR__.'/rss.xml', $xml);
-465
View File
@@ -1,465 +0,0 @@
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=6045,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=25
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=909,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=27
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=1648,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=28
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=913,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=29
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=1623,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=30
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=1620,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=32
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=896,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=33
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=2434,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=34
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=2441,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=35
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=5307,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=37
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?id=943,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=38
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=403,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=39
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=398,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=40
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=350,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=41
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=366,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=43
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=370,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=44
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=361,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=45
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=4449054b,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=46
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=6110,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=47
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=7252867b,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=48
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=6105,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=49
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=2861,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=50
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=16625198b,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=51
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=6422,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=52
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=19281836b,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=53
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=7941380b,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=54
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=6448,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=55
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=6106,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=56
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1027,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=57
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1030,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=58
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1031,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=59
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1033,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=61
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1034,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=62
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1035,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=63
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1036,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=64
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1037,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=65
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1038,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=66
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1041,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=67
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1042,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=68
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1043,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=69
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1044,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=70
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1045,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=71
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1046,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=72
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1047,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=73
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1048,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=74
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1051,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=76
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1052,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=77
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1054,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=78
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1056,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=79
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1057,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=80
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1059,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=81
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1060,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=82
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1061,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=83
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1062,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=84
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1064,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=85
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1065,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=86
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1066,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=87
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1067,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=114
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1068,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=116
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1069,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=117
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1071,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=119
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1073,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=121
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1076,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=124
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1077,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=125
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1078,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=126
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1079,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=127
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=296,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=128
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=5586,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=129
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=297,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=130
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1080,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=131
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1081,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=132
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1082,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=133
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1084,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=134
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1085,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=135
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1086,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=136
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1087,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=137
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1088,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=138
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1089,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=139
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1098,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=140
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1099,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=141
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1100,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=142
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1101,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=143
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1102,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=144
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1103,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=145
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1105,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=146
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1106,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=147
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1107,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=148
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1108,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=149
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1109,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=150
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1110,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=151
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1111,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=152
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1112,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=153
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1113,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=154
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1114,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=155
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1115,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=156
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1119,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=159
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1120,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=160
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1121,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=161
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1122,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=162
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1123,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=163
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1124,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=164
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1125,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=165
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1127,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=167
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1128,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=168
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1129,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=169
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1130,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=170
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1131,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=171
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1132,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=172
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1134,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=174
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1135,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=175
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1136,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=176
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1137,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=177
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1138,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=178
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1139,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=179
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1140,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=180
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1141,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=181
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1142,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=182
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1143,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=183
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1144,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=184
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1146,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=186
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1147,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=187
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1148,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=188
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1149,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=189
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1150,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=190
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1152,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=192
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1153,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=193
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1154,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=194
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1156,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=195
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1157,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=196
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1159,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=198
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1160,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=199
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1161,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=200
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1162,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=201
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1163,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=202
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1164,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=203
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1165,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=204
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1166,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=205
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1167,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=206
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1168,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=207
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1169,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=208
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1170,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=209
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1171,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=210
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1173,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=212
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1174,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=213
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1175,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=214
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1176,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=215
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1177,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=216
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1178,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=217
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1179,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=218
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1180,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=219
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1181,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=220
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1182,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=221
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1183,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=222
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1184,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=223
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1185,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=224
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1186,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=225
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1187,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=226
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1188,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=227
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1189,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=228
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1190,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=229
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1191,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=230
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1192,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=231
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1193,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=232
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=15929656d,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=233
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=376,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=234
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=298,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=235
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=1629,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=236
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=1647,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=237
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1209,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=239
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1210,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=240
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1211,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=241
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1212,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=242
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1213,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=243
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1214,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=244
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1215,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=245
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1216,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=246
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1218,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=248
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1219,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=249
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1220,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=250
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1222,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=251
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1223,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=252
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1224,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=253
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1225,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=254
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1226,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=255
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1227,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=256
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1228,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=257
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1230,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=258
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1231,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=259
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1232,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=260
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1233,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=261
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1234,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=262
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1235,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=263
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1236,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=264
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1237,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=265
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1238,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=266
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1239,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=267
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1240,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=268
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1241,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=269
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1242,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=270
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1243,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=271
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1244,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=272
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1245,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=273
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1246,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=274
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1247,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=275
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1248,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=276
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1251,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=279
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1252,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=280
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1255,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=281
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1256,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=282
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1257,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=283
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1258,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=284
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1262,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=286
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1263,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=287
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1264,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=288
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1265,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=289
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1266,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=290
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1268,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=292
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1269,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=293
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1270,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=294
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1271,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=295
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1272,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=296
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1273,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=297
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1278,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=302
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1279,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=303
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1280,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=304
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1281,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=305
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1282,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=306
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1283,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=307
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1284,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=308
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1285,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=309
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1286,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=310
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1287,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=311
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1288,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=312
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1289,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=313
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1291,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=315
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1292,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=316
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1293,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=317
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1294,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=318
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1295,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=319
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1296,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=320
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1298,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=322
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1299,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=323
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1300,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=324
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1302,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=326
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1306,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=330
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1312,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=336
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1313,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=337
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1314,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=338
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1315,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=339
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=162,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=341
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=5936,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=342
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/558/weaverWearne06.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=360
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=4449054c,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=367
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1039,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=416
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1040,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=417
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=7051,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=444
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1427,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=485
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1425,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=486
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1424,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=487
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1423,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=488
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1422,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=489
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1421,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=490
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1420,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=491
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1419,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=492
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1418,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=493
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1417,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=494
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1416,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=496
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1415,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=497
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1362,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=498
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1414,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=499
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1363,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=500
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1413,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=501
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1411,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=502
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1409,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=503
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1365,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=504
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1369,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=505
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1408,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=506
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1406,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=507
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1362,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=511
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1364,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=514
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1367,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=515
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1366,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=516
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1405,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=517
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1364,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=518
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1401,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=519
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1415,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=520
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1368,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=521
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1399,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=523
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1370,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=524
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1398,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=525
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1371,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=526
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1397,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=527
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1396,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=528
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1372,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=529
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1373,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=530
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1374,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=531
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1375,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=532
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1376,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=533
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1380,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=534
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1395,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=535
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1394,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=536
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1393,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=537
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1392,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=538
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1391,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=539
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1390,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=540
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1389,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=541
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1387,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=542
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1386,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=543
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1385,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=544
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1384,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=545
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1382,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=546
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1381,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=547
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1362,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=550
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1363,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=551
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1364,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=552
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1365,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=553
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1366,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=554
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1367,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=555
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1368,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=556
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1369,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=557
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1370,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=558
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1371,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=559
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1372,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=560
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1374,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=562
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1375,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=563
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1376,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=564
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1379,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=565
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1380,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=566
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1381,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=567
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1382,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=568
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1384,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=569
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1385,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=571
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1386,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=572
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1387,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=573
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1045,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=574
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1389,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=575
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1390,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=576
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1391,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=577
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1392,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=578
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1393,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=579
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1394,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=580
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1395,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=581
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1396,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=582
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1397,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=583
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1398,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=584
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1399,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=585
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1400,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=586
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1401,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=587
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1402,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=588
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1405,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=589
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1409,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=590
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1409,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=591
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1411,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=592
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1413,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=593
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1414,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=594
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1415,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=595
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1416,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=596
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1418,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=598
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1419,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=599
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1420,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=600
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1421,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=601
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1422,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=602
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1423,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=603
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1424,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=604
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1425,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=605
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1427,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=606
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1428,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=607
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1429,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=608
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1430,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=609
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1431,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=610
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1432,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=611
visiome,https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=7252,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=612
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1434,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=613
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1435,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=614
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1450,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=615
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1452,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=616
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1453,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=617
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1454,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=618
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1455,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=619
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1458,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=620
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1460,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=621
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1461,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=622
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1462,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=623
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1463,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=624
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1466,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=625
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1465,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=626
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1467,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=627
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1470,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=628
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1471,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=629
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1472,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=630
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1473,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=631
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1474,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=632
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1476,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=633
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1477,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=634
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1479,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=635
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1481,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=636
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1482,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=637
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1483,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=638
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1486,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=639
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1487,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=640
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1488,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=641
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1489,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=642
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1490,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=643
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1493,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=644
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1496,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=645
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1497,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=646
cerebellum,https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1498,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=647
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/533/SundtEtAl2015.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=656
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/536/baker_etal_JCNS_2010.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=657
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/538/CS56PyModelDB.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=659
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/539/TCconvergenceModel.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=660
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/540/BahlEtAl2012.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=661
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/541/ACh_ModelDB.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=662
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/543/OLMmodel_r3.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=664
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/548/GentilettiEtAl2016.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=668
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/556/FUS_model.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=677
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/560/ShepherdBrayton1979.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=680
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/561/gc-1.1_r2.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=681
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/564/VladimirovTuTraub2012.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=683
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/565/xiaoshenli.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=684
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/566/kv72-R213QW-mutations_r2.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=685
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/567/Ih_current.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=686
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/569/Schizophr.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=687
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/570/SaudargieneEtAl2015.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=688
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/571/bpap.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=689
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/572/magical7.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=691
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/575/HyunEtAl2015.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=696
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/576/MasurkarChen2011_r1.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=697
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/577/Nakano_FICN_model_r1.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=698
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/582/AshhadNarayanan2013.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=699
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/583/DiFrancescoNoble1985.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=700
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/584/DGC.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=701
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/586/DG_BC.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=703
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/587/DRG_Devor.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=704
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/588/Kv72_ModelDB.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=705
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/589/SousaEtAl2014.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=706
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/590/MiglioreEtAl2015.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=707
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/592/Chloride_Model.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=708
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/593/MiglioreEJN2016_r2.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=709
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/595/Moore2015.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=711
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/597/FFI_CA1_r3.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=713
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/598/stadler2014_layerV_r1.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=714
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/600/2VN.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=716
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/602/Branch_Point_Tapering.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=718
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/604/MenonEtAl2009_r1.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=720
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/606/CA3Atrophy.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=722
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/607/Gorin_et_al_2016.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=723
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/608/Poleg-PolskyDiamond2011.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=724
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/613/Demo.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=728
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/614/ShortEtAl2016.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=729
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/618/Casaleggio2014.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=733
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/623/MiglioreMcTavish2013.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=736
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/624/KimEtAl2017.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=737
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/626/fig1b.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=738
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/627/cortex_r1.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=739
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/629/oltedal.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=741
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/632/ka_rgc.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=744
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/634/na_rgc.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=745
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/636/V1_PFC_ModelDB.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=747
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/640/moore83.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=751
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/642/SpaceClampDemo.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=753
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/644/anderson.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=755
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/645/VNO.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=756
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/645/VNO.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=757
cns,https://cns.neuroinf.jp/modules/fmanager/index.php/view/647/Watanabe-et-al_2017_r1.zip,http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=758
1 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=6045 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=25
2 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=909 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=27
3 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=1648 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=28
4 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=913 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=29
5 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=1623 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=30
6 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=1620 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=32
7 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=896 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=33
8 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=2434 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=34
9 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=2441 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=35
10 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=5307 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=37
11 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?id=943 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=38
12 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=403 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=39
13 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=398 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=40
14 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=350 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=41
15 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=366 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=43
16 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=370 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=44
17 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=361 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=45
18 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=4449054b http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=46
19 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=6110 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=47
20 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=7252867b http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=48
21 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=6105 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=49
22 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=2861 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=50
23 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=16625198b http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=51
24 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=6422 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=52
25 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=19281836b http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=53
26 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=7941380b http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=54
27 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=6448 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=55
28 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=6106 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=56
29 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1027 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=57
30 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1030 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=58
31 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1031 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=59
32 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1033 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=61
33 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1034 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=62
34 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1035 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=63
35 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1036 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=64
36 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1037 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=65
37 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1038 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=66
38 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1041 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=67
39 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1042 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=68
40 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1043 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=69
41 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1044 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=70
42 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1045 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=71
43 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1046 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=72
44 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1047 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=73
45 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1048 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=74
46 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1051 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=76
47 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1052 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=77
48 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1054 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=78
49 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1056 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=79
50 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1057 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=80
51 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1059 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=81
52 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1060 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=82
53 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1061 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=83
54 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1062 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=84
55 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1064 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=85
56 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1065 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=86
57 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1066 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=87
58 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1067 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=114
59 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1068 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=116
60 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1069 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=117
61 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1071 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=119
62 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1073 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=121
63 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1076 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=124
64 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1077 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=125
65 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1078 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=126
66 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1079 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=127
67 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=296 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=128
68 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=5586 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=129
69 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=297 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=130
70 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1080 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=131
71 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1081 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=132
72 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1082 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=133
73 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1084 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=134
74 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1085 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=135
75 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1086 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=136
76 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1087 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=137
77 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1088 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=138
78 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1089 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=139
79 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1098 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=140
80 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1099 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=141
81 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1100 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=142
82 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1101 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=143
83 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1102 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=144
84 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1103 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=145
85 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1105 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=146
86 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1106 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=147
87 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1107 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=148
88 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1108 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=149
89 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1109 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=150
90 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1110 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=151
91 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1111 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=152
92 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1112 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=153
93 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1113 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=154
94 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1114 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=155
95 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1115 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=156
96 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1119 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=159
97 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1120 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=160
98 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1121 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=161
99 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1122 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=162
100 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1123 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=163
101 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1124 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=164
102 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1125 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=165
103 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1127 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=167
104 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1128 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=168
105 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1129 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=169
106 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1130 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=170
107 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1131 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=171
108 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1132 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=172
109 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1134 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=174
110 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1135 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=175
111 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1136 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=176
112 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1137 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=177
113 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1138 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=178
114 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1139 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=179
115 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1140 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=180
116 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1141 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=181
117 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1142 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=182
118 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1143 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=183
119 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1144 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=184
120 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1146 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=186
121 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1147 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=187
122 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1148 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=188
123 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1149 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=189
124 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1150 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=190
125 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1152 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=192
126 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1153 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=193
127 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1154 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=194
128 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1156 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=195
129 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1157 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=196
130 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1159 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=198
131 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1160 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=199
132 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1161 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=200
133 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1162 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=201
134 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1163 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=202
135 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1164 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=203
136 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1165 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=204
137 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1166 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=205
138 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1167 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=206
139 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1168 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=207
140 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1169 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=208
141 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1170 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=209
142 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1171 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=210
143 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1173 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=212
144 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1174 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=213
145 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1175 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=214
146 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1176 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=215
147 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1177 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=216
148 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1178 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=217
149 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1179 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=218
150 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1180 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=219
151 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1181 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=220
152 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1182 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=221
153 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1183 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=222
154 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1184 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=223
155 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1185 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=224
156 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1186 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=225
157 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1187 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=226
158 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1188 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=227
159 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1189 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=228
160 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1190 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=229
161 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1191 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=230
162 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1192 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=231
163 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1193 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=232
164 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=15929656d http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=233
165 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=376 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=234
166 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=298 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=235
167 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=1629 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=236
168 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=1647 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=237
169 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1209 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=239
170 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1210 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=240
171 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1211 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=241
172 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1212 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=242
173 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1213 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=243
174 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1214 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=244
175 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1215 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=245
176 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1216 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=246
177 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1218 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=248
178 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1219 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=249
179 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1220 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=250
180 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1222 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=251
181 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1223 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=252
182 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1224 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=253
183 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1225 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=254
184 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1226 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=255
185 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1227 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=256
186 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1228 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=257
187 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1230 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=258
188 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1231 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=259
189 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1232 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=260
190 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1233 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=261
191 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1234 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=262
192 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1235 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=263
193 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1236 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=264
194 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1237 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=265
195 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1238 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=266
196 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1239 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=267
197 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1240 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=268
198 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1241 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=269
199 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1242 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=270
200 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1243 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=271
201 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1244 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=272
202 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1245 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=273
203 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1246 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=274
204 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1247 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=275
205 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1248 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=276
206 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1251 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=279
207 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1252 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=280
208 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1255 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=281
209 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1256 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=282
210 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1257 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=283
211 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1258 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=284
212 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1262 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=286
213 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1263 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=287
214 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1264 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=288
215 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1265 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=289
216 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1266 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=290
217 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1268 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=292
218 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1269 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=293
219 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1270 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=294
220 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1271 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=295
221 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1272 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=296
222 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1273 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=297
223 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1278 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=302
224 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1279 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=303
225 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1280 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=304
226 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1281 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=305
227 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1282 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=306
228 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1283 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=307
229 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1284 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=308
230 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1285 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=309
231 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1286 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=310
232 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1287 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=311
233 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1288 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=312
234 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1289 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=313
235 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1291 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=315
236 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1292 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=316
237 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1293 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=317
238 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1294 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=318
239 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1295 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=319
240 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1296 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=320
241 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1298 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=322
242 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1299 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=323
243 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1300 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=324
244 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1302 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=326
245 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1306 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=330
246 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1312 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=336
247 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1313 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=337
248 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1314 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=338
249 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1315 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=339
250 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=162 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=341
251 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=5936 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=342
252 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/558/weaverWearne06.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=360
253 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?id=4449054c http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=367
254 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1039 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=416
255 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1040 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=417
256 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=7051 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=444
257 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1427 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=485
258 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1425 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=486
259 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1424 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=487
260 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1423 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=488
261 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1422 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=489
262 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1421 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=490
263 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1420 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=491
264 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1419 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=492
265 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1418 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=493
266 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1417 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=494
267 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1416 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=496
268 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1415 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=497
269 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1362 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=498
270 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1414 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=499
271 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1363 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=500
272 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1413 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=501
273 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1411 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=502
274 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1409 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=503
275 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1365 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=504
276 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1369 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=505
277 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1408 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=506
278 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1406 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=507
279 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1362 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=511
280 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1364 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=514
281 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1367 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=515
282 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1366 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=516
283 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1405 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=517
284 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1364 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=518
285 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1401 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=519
286 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1415 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=520
287 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1368 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=521
288 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1399 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=523
289 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1370 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=524
290 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1398 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=525
291 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1371 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=526
292 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1397 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=527
293 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1396 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=528
294 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1372 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=529
295 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1373 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=530
296 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1374 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=531
297 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1375 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=532
298 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1376 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=533
299 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1380 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=534
300 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1395 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=535
301 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1394 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=536
302 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1393 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=537
303 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1392 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=538
304 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1391 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=539
305 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1390 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=540
306 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1389 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=541
307 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1387 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=542
308 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1386 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=543
309 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1385 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=544
310 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1384 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=545
311 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1382 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=546
312 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1381 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=547
313 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1362 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=550
314 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1363 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=551
315 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1364 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=552
316 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1365 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=553
317 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1366 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=554
318 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1367 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=555
319 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1368 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=556
320 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1369 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=557
321 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1370 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=558
322 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1371 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=559
323 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1372 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=560
324 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1374 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=562
325 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1375 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=563
326 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1376 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=564
327 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1379 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=565
328 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1380 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=566
329 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1381 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=567
330 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1382 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=568
331 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1384 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=569
332 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1385 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=571
333 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1386 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=572
334 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1387 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=573
335 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1045 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=574
336 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1389 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=575
337 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1390 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=576
338 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1391 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=577
339 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1392 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=578
340 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1393 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=579
341 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1394 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=580
342 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1395 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=581
343 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1396 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=582
344 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1397 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=583
345 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1398 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=584
346 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1399 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=585
347 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1400 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=586
348 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1401 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=587
349 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1402 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=588
350 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1405 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=589
351 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1409 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=590
352 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1409 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=591
353 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1411 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=592
354 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1413 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=593
355 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1414 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=594
356 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1415 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=595
357 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1416 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=596
358 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1418 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=598
359 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1419 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=599
360 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1420 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=600
361 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1421 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=601
362 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1422 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=602
363 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1423 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=603
364 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1424 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=604
365 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1425 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=605
366 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1427 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=606
367 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1428 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=607
368 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1429 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=608
369 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1430 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=609
370 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1431 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=610
371 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1432 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=611
372 visiome https://visiome.neuroinf.jp/modules/xoonips/detail.php?item_id=7252 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=612
373 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1434 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=613
374 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1435 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=614
375 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1450 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=615
376 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1452 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=616
377 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1453 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=617
378 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1454 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=618
379 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1455 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=619
380 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1458 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=620
381 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1460 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=621
382 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1461 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=622
383 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1462 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=623
384 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1463 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=624
385 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1466 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=625
386 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1465 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=626
387 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1467 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=627
388 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1470 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=628
389 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1471 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=629
390 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1472 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=630
391 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1473 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=631
392 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1474 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=632
393 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1476 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=633
394 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1477 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=634
395 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1479 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=635
396 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1481 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=636
397 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1482 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=637
398 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1483 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=638
399 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1486 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=639
400 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1487 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=640
401 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1488 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=641
402 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1489 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=642
403 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1490 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=643
404 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1493 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=644
405 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1496 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=645
406 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1497 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=646
407 cerebellum https://cerebellum.neuroinf.jp/modules/xoonips/detail.php?item_id=1498 http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=647
408 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/533/SundtEtAl2015.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=656
409 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/536/baker_etal_JCNS_2010.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=657
410 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/538/CS56PyModelDB.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=659
411 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/539/TCconvergenceModel.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=660
412 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/540/BahlEtAl2012.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=661
413 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/541/ACh_ModelDB.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=662
414 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/543/OLMmodel_r3.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=664
415 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/548/GentilettiEtAl2016.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=668
416 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/556/FUS_model.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=677
417 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/560/ShepherdBrayton1979.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=680
418 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/561/gc-1.1_r2.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=681
419 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/564/VladimirovTuTraub2012.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=683
420 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/565/xiaoshenli.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=684
421 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/566/kv72-R213QW-mutations_r2.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=685
422 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/567/Ih_current.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=686
423 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/569/Schizophr.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=687
424 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/570/SaudargieneEtAl2015.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=688
425 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/571/bpap.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=689
426 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/572/magical7.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=691
427 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/575/HyunEtAl2015.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=696
428 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/576/MasurkarChen2011_r1.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=697
429 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/577/Nakano_FICN_model_r1.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=698
430 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/582/AshhadNarayanan2013.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=699
431 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/583/DiFrancescoNoble1985.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=700
432 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/584/DGC.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=701
433 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/586/DG_BC.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=703
434 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/587/DRG_Devor.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=704
435 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/588/Kv72_ModelDB.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=705
436 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/589/SousaEtAl2014.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=706
437 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/590/MiglioreEtAl2015.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=707
438 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/592/Chloride_Model.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=708
439 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/593/MiglioreEJN2016_r2.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=709
440 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/595/Moore2015.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=711
441 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/597/FFI_CA1_r3.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=713
442 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/598/stadler2014_layerV_r1.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=714
443 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/600/2VN.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=716
444 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/602/Branch_Point_Tapering.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=718
445 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/604/MenonEtAl2009_r1.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=720
446 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/606/CA3Atrophy.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=722
447 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/607/Gorin_et_al_2016.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=723
448 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/608/Poleg-PolskyDiamond2011.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=724
449 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/613/Demo.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=728
450 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/614/ShortEtAl2016.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=729
451 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/618/Casaleggio2014.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=733
452 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/623/MiglioreMcTavish2013.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=736
453 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/624/KimEtAl2017.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=737
454 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/626/fig1b.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=738
455 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/627/cortex_r1.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=739
456 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/629/oltedal.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=741
457 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/632/ka_rgc.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=744
458 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/634/na_rgc.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=745
459 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/636/V1_PFC_ModelDB.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=747
460 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/640/moore83.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=751
461 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/642/SpaceClampDemo.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=753
462 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/644/anderson.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=755
463 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/645/VNO.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=756
464 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/645/VNO.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=757
465 cns https://cns.neuroinf.jp/modules/fmanager/index.php/view/647/Watanabe-et-al_2017_r1.zip http://sim.neuroinf.jp/modules/xoonips/detail.php?item_id=758
+6 -5
View File
@@ -1,8 +1,8 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" sizes="any" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
@@ -10,14 +10,15 @@
content="The Invertebrate Brain Platform offers you direct access to a growing database of information on nervous systems and behaviour of various species of invertebrates and a large body of ancillary material to promote the use of invertebrate systems in research and edcuation and facilitate information transfer to engineers that are looking for mechanisms that may be useful to solve a wide range of technological problems. The database is linked to explanations of the contents to allow users to familiarise themselves with the data and the context in which they were obtained. The platform has four entrance points taylored to different target user groups. The first entrance point is designed for users that are interested in using invertebrates for research purposes, in particular in the field of neuroscience, to assist them in intitiating research projects. A second entrance point is available for those that are concerned with implementations of design principles of invertebrate nervous systems and behaviour in industrial applications. The third portal is destined for providing quick access for instructors that intend to use invertebrates for educational purposes and the remaining entrance point facilitates obtaining general comparative information on sensory and central nervous systems and behaviour of invertebrates."
/>
<meta name="robots" content="index,follow" />
<meta name="keywords" content="neuroinformatics, xoonips, database, dynamic brain platform, dynamic principles of brain functions" />
<meta name="keywords" content="neuroinformatics, xoonips, database, invertebrate brain platform, invertebrate, insect" />
<meta name="author" content="Neuroinformatics Unit, RIKEN Center for Brain Science" />
<meta name="copyright" content="Copyright &copy; 2018" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="manifest" href="/manifest.json" />
<title>Invertebrate Brain Platform</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
+1799
View File
File diff suppressed because it is too large Load Diff
+36 -58
View File
@@ -1,60 +1,38 @@
{
"name": "invbrain",
"version": "0.1.0",
"private": true,
"dependencies": {
"@types/async-lock": "^1.1.2",
"@types/jest": "26.0.23",
"@types/lokijs": "^1.5.4",
"@types/node": "15.6.1",
"@types/react": "17.0.8",
"@types/react-dom": "17.0.5",
"@types/react-helmet": "^6.1.1",
"@types/react-html-parser": "^2.0.1",
"@types/react-router-dom": "^5.1.7",
"@types/react-router-hash-link": "^2.4.0",
"async-lock": "^1.3.0",
"axios": "^0.21.1",
"lokijs": "^1.5.12",
"moment": "^2.29.1",
"rc-tree": "^4.1.5",
"react": "^17.0.2",
"react-app-polyfill": "^2.0.0",
"react-cookie": "^4.0.3",
"react-dom": "^17.0.2",
"react-ga": "^3.3.0",
"react-helmet": "^6.1.0",
"react-html-parser": "^2.0.2",
"react-image-lightbox": "^5.1.1",
"react-overlays": "^5.0.1",
"react-router-dom": "^5.2.0",
"react-router-hash-link": "^2.4.3",
"react-scripts": "4.0.3",
"react-spinner-material": "^1.3.1",
"typescript": "4.3.2",
"xregexp": "^5.0.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all",
"ie 11"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version",
"ie 11"
]
}
"name": "invbrain",
"version": "2.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview",
"lint": "biome lint",
"format": "biome format --write",
"check": "biome check --write"
},
"dependencies": {
"@dr.pogodin/react-helmet": "^3.2.3",
"@orrisroot/react-html-parser": "^3.0.1",
"date-fns": "^4.4.0",
"ky": "^2.1.0",
"lokijs": "^1.5.12",
"react": "^19.3.0",
"react-cookie": "^8.1.2",
"react-dom": "^19.3.0",
"react-ga4": "^3.0.1",
"react-router": "^8.3.1",
"sanitize.css": "^13.0.0"
},
"devDependencies": {
"@biomejs/biome": "^2.5.13",
"@types/lokijs": "^1.5.14",
"@types/node": "^24.13.4",
"@types/react": "^19.3.0",
"@types/react-dom": "^19.3.0",
"@vitejs/plugin-react": "^6.1.1",
"sirv": "^3.0.2",
"typescript": "~7.0.2",
"vite": "^8.3.0"
}
}
+13 -13
View File
@@ -1,15 +1,15 @@
{
"short_name": "Invertebrate Brain Platform",
"name": "Invertebrate Brain Platform",
"icons": [
{
"src": "favicon.ico",
"sizes": "32x32 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
"short_name": "Invertebrate Brain Platform",
"name": "Invertebrate Brain Platform",
"icons": [
{
"src": "favicon.ico",
"sizes": "32x32 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
-1
View File
@@ -1,2 +1 @@
@import url("./common/assets/xoops.css");
@import url("./custom/assets/style.css");
-9
View File
@@ -1,9 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});
+8 -8
View File
@@ -1,17 +1,17 @@
import React from 'react';
import { HelmetProvider } from '@dr.pogodin/react-helmet';
import { CookiesProvider } from 'react-cookie';
import { BrowserRouter } from 'react-router-dom';
import './App.css';
import { BrowserRouter } from 'react-router';
import AppRoot from './common/AppRoot';
import './App.css';
const App: React.FC = () => {
return (
const App = () => (
<HelmetProvider>
<CookiesProvider>
<BrowserRouter>
<AppRoot />
</BrowserRouter >
</BrowserRouter>
</CookiesProvider>
);
}
</HelmetProvider>
);
export default App;
+33 -53
View File
@@ -1,67 +1,47 @@
import React, { Component } from 'react';
import { ReactCookieProps, withCookies } from 'react-cookie';
import ReactGA from 'react-ga';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import Config, { MultiLang } from '../config';
import { useEffect, useRef } from 'react';
import { useCookies } from 'react-cookie';
import ReactGA from 'react-ga4';
import { useLocation } from 'react-router';
import Config, { type MultiLang } from '../config';
import Page from '../custom/Page';
interface Props extends RouteComponentProps, ReactCookieProps { }
interface State {
lang: MultiLang;
const isAnalyticsEnabled = import.meta.env.PROD && Config.GOOGLE_ANALYTICS_TRACKING_ID !== '';
if (isAnalyticsEnabled) {
// Page views are sent from the location effect below, the first one included;
// gtag's own page_view on config would count the landing page twice.
ReactGA.initialize(Config.GOOGLE_ANALYTICS_TRACKING_ID, { gtagOptions: { send_page_view: false } });
}
class AppRoot extends Component<Props, State> {
const toMultiLang = (value: unknown): MultiLang | null => (value === 'en' || value === 'ja' ? value : null);
constructor(props: Props) {
super(props);
this.state = { lang: 'en' };
if (Config.GOOGLE_ANALYTICS_TRACKING_ID !== '') {
ReactGA.initialize(Config.GOOGLE_ANALYTICS_TRACKING_ID);
}
}
const AppRoot = () => {
const location = useLocation();
const [cookies, setCookie] = useCookies(['ml_lang']);
const previousLocation = useRef<string | null>(null);
static getDerivedStateFromProps(nextProps: Props, prevState: State) {
const params = new URLSearchParams(nextProps.location.search);
const param_lang = params.get('ml_lang');
const cookie_lang = typeof nextProps.cookies !== 'undefined' ? nextProps.cookies.get('ml_lang') : null;
let lang = param_lang || (typeof cookie_lang === 'string' ? cookie_lang : null) || prevState.lang;
if (lang !== 'en' && lang !== 'ja') {
lang = 'en';
}
if (cookie_lang !== lang) {
if (typeof nextProps.cookies !== 'undefined') {
nextProps.cookies.set('ml_lang', lang, { path: '/' });
}
}
if (prevState.lang !== lang) {
return { lang };
}
return null;
}
const paramLang = toMultiLang(new URLSearchParams(location.search).get('ml_lang'));
const cookieLang = toMultiLang(cookies.ml_lang);
const lang: MultiLang = paramLang ?? cookieLang ?? 'en';
componentDidMount() {
const { pathname } = this.props.location;
if (Config.GOOGLE_ANALYTICS_TRACKING_ID !== '') {
ReactGA.set({ page: pathname });
ReactGA.pageview(pathname);
useEffect(() => {
if (cookies.ml_lang !== lang) {
setCookie('ml_lang', lang, { path: '/' });
}
}
}, [cookies.ml_lang, lang, setCookie]);
componentDidUpdate(prevProps: Props) {
const { pathname, search } = this.props.location;
if (Config.GOOGLE_ANALYTICS_TRACKING_ID !== '') {
ReactGA.set({ page: pathname });
ReactGA.pageview(pathname);
useEffect(() => {
if (isAnalyticsEnabled) {
ReactGA.send({ hitType: 'pageview', page: location.pathname + location.search });
}
if (pathname !== prevProps.location.pathname || search !== prevProps.location.search) {
const current = location.pathname + location.search;
if (previousLocation.current !== null && previousLocation.current !== current) {
window.scrollTo(0, 0);
}
}
previousLocation.current = current;
}, [location.pathname, location.search]);
render() {
const { lang } = this.state;
return <Page lang={lang} />;
}
}
return <Page lang={lang} />;
};
export default withCookies(withRouter(AppRoot));
export default AppRoot;
+20 -30
View File
@@ -1,40 +1,30 @@
import React, { Component } from 'react';
import { Redirect, RouteComponentProps } from 'react-router';
import { MultiLang } from '../config';
import { Navigate, useLocation } from 'react-router';
import type { MultiLang } from '../config';
import PageNotFound from './lib/PageNotFound';
interface Params {
module: string;
pathname: string;
}
interface Props extends RouteComponentProps<Params> {
interface Props {
lang: MultiLang;
}
class XoopsPathRedirect extends Component<Props> {
getRedirectUrl() {
const { pathname } = this.props.location;
switch (pathname || '') {
case '/index.php': {
return '/';
}
}
return '';
const getRedirectUrl = (pathname: string): string => {
switch (pathname || '') {
case '/index.php':
return '/';
}
return '';
};
render() {
const { lang } = this.props;
if (this.props.location.pathname === '/') {
return null;
}
const url = this.getRedirectUrl();
if (url === '') {
return <PageNotFound lang={lang} />;
}
return <Redirect to={url} />;
const XoopsPathRedirect = (props: Props) => {
const { lang } = props;
const location = useLocation();
if (location.pathname === '/') {
return null;
}
}
const url = getRedirectUrl(location.pathname);
if (url === '') {
return <PageNotFound lang={lang} />;
}
return <Navigate to={url} replace />;
};
export default XoopsPathRedirect;
-34
View File
@@ -1,34 +0,0 @@
import React from 'react';
import { RouteComponentProps, withRouter } from 'react-router';
import { MultiLang } from '../../config';
interface Props extends RouteComponentProps {
lang: MultiLang;
}
const SelectLang = (props: Props) => {
const { lang, history } = props;
const langs: MultiLang[] = ['en', 'ja'];
const titles = {
en: 'English',
ja: 'Japanese',
};
return (
<div>
<select value={lang} onChange={(e) => {
const xlang = e.target.value;
const params = new URLSearchParams(history.location.search);
params.set('ml_lang', xlang);
const url = history.location.pathname + '?' + params.toString();
history.push(url);
}}>
{langs.map((xlang) => {
return <option key={xlang} value={xlang}>{titles[xlang]}</option>;
})}
</select>
</div>
);
}
export default withRouter(SelectLang);
+53
View File
@@ -0,0 +1,53 @@
import type { ComponentProps, MouseEvent } from 'react';
import { Link, type To } from 'react-router';
type LinkProps = ComponentProps<typeof Link>;
const RETRY_INTERVAL_MS = 16;
const RETRY_COUNT = 20;
const hashOf = (to: To): string => {
if (typeof to === 'string') {
const idx = to.indexOf('#');
return idx === -1 ? '' : to.slice(idx + 1);
}
return (to.hash ?? '').replace(/^#/, '');
};
const scrollToHash = (hash: string, remaining = RETRY_COUNT) => {
if (hash === '') {
return;
}
const id = decodeURIComponent(hash);
const target = document.getElementById(id) ?? document.querySelector(`[name="${CSS.escape(id)}"]`);
if (target !== null) {
target.scrollIntoView();
return;
}
// The target may not be in the DOM yet (pico pages fetch their content).
if (remaining > 0) {
setTimeout(() => {
scrollToHash(hash, remaining - 1);
}, RETRY_INTERVAL_MS);
}
};
/**
* A `<Link>` that also scrolls to the element named by the URL fragment.
* Replaces `react-router-hash-link`, which is unmaintained and still targets react-router v5.
*/
const HashLink = ({ onClick, to, ...rest }: LinkProps) => {
const handleClick = (e: MouseEvent<HTMLAnchorElement>) => {
onClick?.(e);
if (e.defaultPrevented) {
return;
}
// Let react-router commit the navigation before looking for the target.
setTimeout(() => {
scrollToHash(hashOf(to));
}, 0);
};
return <Link {...rest} to={to} onClick={handleClick} />;
};
export default HashLink;
+8 -10
View File
@@ -1,11 +1,9 @@
import React from 'react';
import { RouteComponentProps, withRouter } from 'react-router';
import { Link } from 'react-router-dom';
import { MultiLang } from '../../config';
import { Link, useLocation } from 'react-router';
import type { MultiLang } from '../../config';
import mlangEnglish from '../assets/images/mlang_english.gif';
import mlangJapanese from '../assets/images/mlang_japanese.gif';
interface Props extends RouteComponentProps {
interface Props {
lang: MultiLang;
className?: string;
image?: string;
@@ -18,17 +16,17 @@ const langResources = {
const LangFlag = (props: Props) => {
const { lang, className, image } = props;
const params = new URLSearchParams(props.location.search);
const location = useLocation();
const params = new URLSearchParams(location.search);
const flagLang = lang === 'en' ? 'ja' : 'en';
params.set('ml_lang', flagLang);
const url = props.location.pathname + '?' + params.toString();
const url = `${location.pathname}?${params.toString()}`;
const imageSrc = image || langResources[flagLang].image;
return (
<Link className={className} to={url}>
<img src={imageSrc} alt={langResources[flagLang].title} title={langResources[flagLang].title} />
</Link>
);
}
};
export default withRouter(LangFlag);
export default LangFlag;
+27
View File
@@ -0,0 +1,27 @@
.container {
display: flex;
justify-content: center;
align-content: center;
margin: 100px 0;
}
.spinner {
width: 120px;
height: 120px;
border: 8px solid #eeeeee;
border-top-color: #cccccc;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: reduce) {
.spinner {
animation-duration: 4s;
}
}
+7 -10
View File
@@ -1,12 +1,9 @@
import React from 'react';
import Spinner from 'react-spinner-material';
import styles from './Loading.module.css';
const Loading = () => {
return (
<div style={{ display: 'flex', justifyContent: 'center', alignContent: 'center', margin: '100px 0' }}>
<Spinner radius={60} color={'#cccccc'} stroke={8} visible={true} />
</div>
);
}
const Loading = () => (
<div className={styles.container}>
<div className={styles.spinner} role="status" aria-label="Loading" />
</div>
);
export default Loading;
export default Loading;
+5 -5
View File
@@ -1,5 +1,4 @@
import React from 'react';
import { MultiLang } from '../../config';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
interface Props {
@@ -8,8 +7,9 @@ interface Props {
const NoticeSiteHasBeenArchived = (props: Props) => {
const { lang } = props;
const notice = '[en]This site has been archived since FY2019 and is no longer updated.[/en][ja]このサイトは、2019年度よりアーカイブサイトとして運用されています。[/ja]';
const notice =
'[en]This site has been archived since FY2019 and is no longer updated.[/en][ja]このサイトは、2019年度よりアーカイブサイトとして運用されています。[/ja]';
return <p style={{ color: 'red' }}>{Functions.mlang(notice, lang)}</p>;
}
};
export default NoticeSiteHasBeenArchived;
export default NoticeSiteHasBeenArchived;
+34 -44
View File
@@ -1,54 +1,44 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import { RouteComponentProps, withRouter } from 'react-router';
import { MultiLang } from '../../config';
import { Helmet } from '@dr.pogodin/react-helmet';
import { useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
interface Props extends RouteComponentProps {
interface Props {
lang: MultiLang;
}
class PageNotFound extends Component<Props> {
const TOP_URL = '/';
private url = '/';
private timer: NodeJS.Timer | null = null;
const PageNotFound = (props: Props) => {
const { lang } = props;
const location = useLocation();
const navigate = useNavigate();
goToTopPage() {
if (this.props.location.pathname !== '/') {
if (this.timer) {
clearTimeout(this.timer);
}
this.timer = setTimeout(() => {
this.timer = null;
this.props.history.push(this.url);
}, 5000);
useEffect(() => {
if (location.pathname === TOP_URL) {
return;
}
}
const timer = setTimeout(() => {
void navigate(TOP_URL);
}, 5000);
return () => clearTimeout(timer);
}, [location.pathname, navigate]);
componentWillUnmount() {
if (this.timer) {
clearTimeout(this.timer);
}
}
return (
<div>
<Helmet>
<title>Page Not Found - {Functions.siteTitle(lang)}</title>
</Helmet>
<h1>Page Not Found</h1>
<section>
<p>The page you were trying to access doesn't exist.</p>
<p>
If the page does not automatically reload, please go to the <a href={TOP_URL}>top page</a>
</p>
</section>
</div>
);
};
render() {
const { lang } = this.props;
if (process.env.NODE_ENV === 'production') {
this.goToTopPage();
}
return (
<div>
<Helmet>
<title>Page Not Found - {Functions.siteTitle(lang)}</title>
</Helmet>
<h1>Page Not Found</h1>
<section>
<p>The page you were trying to access doesn't exist.</p>
<p>If the page does not automatically reload, please click <a href={this.url}>here</a></p>
</section>
</div>
);
}
}
export default withRouter(PageNotFound);
export default PageNotFound;
+112 -70
View File
@@ -1,8 +1,14 @@
import React, { ReactElement } from 'react';
import ReactHtmlParser, { convertNodeToElement } from 'react-html-parser';
import { HashLink } from 'react-router-hash-link';
import { MultiLang } from '../../config';
import ReactHtmlParser, {
convertNodeToElement,
type DomElement,
type DomNode,
type Transform,
} from '@orrisroot/react-html-parser';
import type { CSSProperties } from 'react';
import { useLocation } from 'react-router';
import Config, { type MultiLang } from '../../config';
import Functions from '../../functions';
import HashLink from './HashLink';
interface Props {
lang: MultiLang;
@@ -16,102 +22,138 @@ interface Props {
const preConvertXCode = (text: string, doxcode: boolean): string => {
if (doxcode) {
return text.replace(/\[code\](.*)\[\/code\]/sg, (m0, m1) => {
return '[code]' + Functions.base64Encode(m1) + '[/code]';
return text.replace(/\[code\](.*)\[\/code\]/gs, (_m0, m1) => {
return `[code]${Functions.base64Encode(m1)}[/code]`;
});
}
return text;
}
};
const postConvertXCode = (text: string, doxcode: boolean, doimage: boolean): string => {
if (doxcode) {
return text.replace(/\[code\](.*)\[\/code\]/sg, (m0, m1) => {
return text.replace(/\[code\](.*)\[\/code\]/gs, (_m0, m1) => {
const text = convertXCode(Functions.htmlspecialchars(Functions.base64Decode(m1)), doimage);
return '<div class="xoopsCode"><pre><code>' + text + '</code></pre></div>';
return `<div class="xoopsCode"><pre><code>${text}</code></pre></div>`;
});
}
return text;
}
};
const convertClickable = (text: string) => {
text = text.replace(/(^|[^\]_a-zA-Z0-9-="'/]+)((?:https?|ftp)(?::\/\/[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+[a-zA-Z0-9=]))/g, (...matches) => {
return matches[1] + '<a href="' + matches[2] + '" target="_blank" rel="external noopener noreferrer">' + matches[2] + '</a>';
});
text = text.replace(/(^|[^\]_a-zA-Z0-9-="'/:.]+)([a-zA-Z0-9.!#$%&*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+)/g, (...matches) => {
return matches[1] + '<a href="mailto:' + matches[2] + '">' + matches[2] + '</a>';
});
text = text.replace(
/(^|[^\]_a-zA-Z0-9-="'/]+)((?:https?|ftp)(?::\/\/[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+[a-zA-Z0-9=]))/g,
(...matches) => {
return (
matches[1] +
'<a href="' +
matches[2] +
'" target="_blank" rel="external noopener noreferrer">' +
matches[2] +
'</a>'
);
}
);
text = text.replace(
/(^|[^\]_a-zA-Z0-9-="'/:.]+)([a-zA-Z0-9.!#$%&*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+)/g,
(...matches) => {
return `${matches[1]}<a href="mailto:${matches[2]}">${matches[2]}</a>`;
}
);
return text;
}
};
const convertXCode = (text: string, doimage: boolean): string => {
const convertXCode = (text: string, _doimage: boolean): string => {
// TODO: implement
return text;
}
};
const convertSmiley = (text: string) => {
// TODO: implement
return text;
}
};
const convertBr = (text: string): string => {
return text.replace(/(\r?\n|\r)/g, '<br />');
}
};
interface TransformParsedNode {
type: string;
next: object | null;
prev: object | null;
parent: object | null;
name: string;
attribs: any;
children: object[];
data: string;
}
const cssConvert = (text: string): object => {
const ret: any = {};
const cssConvert = (text: string): CSSProperties => {
const ret: Record<string, string> = {};
text.split(';').forEach((line) => {
const line_ = line.trim();
if (line.length === 0) {
if (line_.length === 0) {
return;
}
const kv = line_.split(':');
const key = Functions.camelCase(kv[0].trim());
const value = kv[1].trim();
ret[key] = value;
})
return ret;
}
const transform = (node: object, idx: number): ReactElement | null | void => {
const node_ = node as TransformParsedNode;
if (node_.type === 'tag' && node_.name === 'a') {
const url = (node_.attribs && node_.attribs['href']) || '/';
const download = (node_.attribs && node_.attribs['download']) || '';
const rel = (node_.attribs && node_.attribs['rel']) || '';
const klass = (node_.attribs && node_.attribs['class']) || '';
const target = (node_.attribs && node_.attribs['target']) || '';
const isFile = download !== '' || /\.(zip|pdf|png|gif|jpg|gz|bz2|xz|mpg|mp3|mp4)$/i.test(url);
const isExternal = /^(_blank|_top|_parent)$/.test(target) || /external/.test(rel) || /external/.test(klass) || /^(mailto|https?:?\/\/)/.test(url);
if (!isFile && !isExternal) {
const style = (node_.attribs && node_.attribs['style']) || '';
const title = (node_.attribs && node_.attribs['title']) || null;
return <HashLink key={idx} to={url} style={cssConvert(style)} title={title}>
{node_.children.map((value: object, index: number) => {
return convertNodeToElement(value, index, transform);
})}
</HashLink>;
if (kv.length < 2) {
return;
}
}
if (node_.type === 'tag' && node_.name === 'img') {
const src = (node_.attribs && node_.attribs['src']) || '';
node_.attribs['src'] = src.replace('`XOOPS_URL`', process.env.PUBLIC_URL);
return convertNodeToElement(node_ as object, idx, transform);
}
}
ret[Functions.camelCase(kv[0].trim())] = kv.slice(1).join(':').trim();
});
return ret as CSSProperties;
};
/**
* Stored content links are often written relative to the page that contains
* them (`../General/behavior.html`, `#section`, ...), so they have to be
* resolved the way a browser resolves an `href`. react-router would instead
* resolve them against the route hierarchy.
*/
const resolveUrl = (href: string, basePath: string): string => {
const url = new URL(href, window.location.origin + basePath);
return url.pathname + url.search + url.hash;
};
const makeTransform = (basePath: string): Transform => {
const transform: Transform = (node: DomNode, idx: number | string) => {
if (node.type !== 'tag') {
return undefined;
}
const element = node as DomElement;
const attribs = element.attribs ?? {};
if (element.name === 'a') {
const url = attribs.href || '/';
const download = attribs.download || '';
const rel = attribs.rel || '';
const klass = attribs.class || '';
const target = attribs.target || '';
// Data files are served by the web server, not by the app.
const isFile = download !== '' || /\.(zip|pdf|png|gif|jpg|gz|bz2|xz|mpg|mp3|mp4)$/i.test(url);
const isExternal =
/^(_blank|_top|_parent)$/.test(target) ||
/external/.test(rel) ||
/external/.test(klass) ||
/^(mailto|https?:?\/\/)/.test(url);
if (isFile || isExternal) {
return undefined;
}
return (
<HashLink
key={idx}
to={resolveUrl(url, basePath)}
style={cssConvert(attribs.style || '')}
title={attribs.title}
>
{element.children.map((child, index) => convertNodeToElement(child, index, transform))}
</HashLink>
);
}
if (element.name === 'img' && typeof attribs.src === 'string') {
// Rewritten in place; returning undefined lets the parser render it.
attribs.src = attribs.src.replace('`XOOPS_URL`', Config.BASE_URL);
}
return undefined;
};
return transform;
};
/**
* Renders converted XOOPS text. It returns a fragment rather than a wrapper
* element because the CosmoDB list templates are table cells placed directly
* inside a `<tr>`.
*/
const XoopsCode = (props: Props) => {
const { lang } = props;
const { pathname } = useLocation();
let text = props.text;
const dohtml = !!props.dohtml;
const dosmiley = !!props.dosmiley;
@@ -134,7 +176,7 @@ const XoopsCode = (props: Props) => {
}
text = postConvertXCode(text, doxcode, doimage);
text = Functions.mlang(text, lang);
return <>{ReactHtmlParser(text, { transform })}</>;
}
return <>{ReactHtmlParser(text, { transform: makeTransform(pathname) })}</>;
};
export default XoopsCode;
export default XoopsCode;
+25
View File
@@ -0,0 +1,25 @@
import { useEffect, useState } from 'react';
/**
* Runs a module's lazy `initialize()` and reports its outcome: `null` while it
* is pending, then the boolean it resolved to. The modules fetch their own
* index the first time one of their pages is shown, and cache the promise, so
* this is cheap to call from every page.
*/
const useInitialized = (initialize: () => Promise<boolean>): boolean | null => {
const [status, setStatus] = useState<boolean | null>(null);
useEffect(() => {
let active = true;
initialize().then((result) => {
if (active) {
setStatus(result);
}
});
return () => {
active = false;
};
}, [initialize]);
return status;
};
export default useInitialized;
+10 -3
View File
@@ -1,8 +1,14 @@
const SITE_TITLE = 'Invertebrate Brain Platform';
const SITE_SLOGAN = '';
const GOOGLE_ANALYTICS_TRACKING_ID = 'UA-2780881-1';
// Replaces the Universal Analytics property (UA-2780881-1), shut down in 2023.
const GOOGLE_ANALYTICS_TRACKING_ID = 'G-JF4NM0XJHK';
const PICO_MODULES = ['documents', 'htmldocs'];
// Vite's BASE_URL always carries a trailing slash ('/' when the app is served
// from the document root). Strip it so it can be concatenated the same way
// CRA's PUBLIC_URL was.
const BASE_URL = import.meta.env.BASE_URL.replace(/\/$/, '');
export type MultiLang = 'en' | 'ja';
const Config = {
@@ -10,6 +16,7 @@ const Config = {
SITE_SLOGAN,
GOOGLE_ANALYTICS_TRACKING_ID,
PICO_MODULES,
}
BASE_URL,
};
export default Config;
export default Config;
+44 -81
View File
@@ -1,101 +1,64 @@
import React, { Component } from 'react';
import { Redirect, Route, RouteComponentProps, Switch } from 'react-router-dom';
import { Navigate, Route, Routes, useLocation } from 'react-router';
import Loading from '../common/lib/Loading';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import useInitialized from '../common/lib/useInitialized';
import type { MultiLang } from '../config';
import './assets/style.css';
import CosmoDbDetail from './CosmoDbDetail';
import CosmoDbList from './CosmoDbList';
import CosmoDbContext from './lib/CosmoDbContext';
import type CosmoDbContext from './lib/CosmoDbContext';
import CosmoDbUtils from './lib/CosmoDbUtils';
interface Props {
lang: MultiLang;
modulepath: string;
dirname: string;
}
interface State {
loading: boolean;
context: CosmoDbContext | null;
interface PageProps {
lang: MultiLang;
context: CosmoDbContext;
}
class CosmoDb extends Component<Props, State> {
const CosmoDbListPage = (props: PageProps) => {
const { lang, context } = props;
const { search } = useLocation();
return <CosmoDbList lang={lang} context={context} params={new URLSearchParams(search)} />;
};
private isActive: boolean;
public constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
context: null,
};
const CosmoDbDetailPage = (props: PageProps) => {
const { lang, context } = props;
const { search } = useLocation();
const params = new URLSearchParams(search);
const idStr = params.get('id') || '';
const tabStr = params.get('tab') || '1';
if (!/^\d+/.test(idStr) || !/^\d+/.test(tabStr)) {
return <PageNotFound lang={lang} />;
}
return <CosmoDbDetail lang={lang} context={context} id={parseInt(idStr, 10)} tab={parseInt(tabStr, 10)} />;
};
public componentDidMount() {
this.isActive = true;
this.updatePage();
const CosmoDb = (props: Props) => {
const { lang, dirname } = props;
const context = CosmoDbUtils.getContext(dirname);
const status = useInitialized(context.initialize);
if (status === null) {
return <Loading />;
}
public componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, modulepath } = this.props;
if (prevProps.lang !== lang || prevProps.modulepath !== modulepath) {
this.updatePage();
}
if (!status) {
return <PageNotFound lang={lang} />;
}
public componentWillUnmount() {
this.isActive = false;
}
public async updatePage() {
const { modulepath } = this.props;
const context = CosmoDbUtils.getContext(modulepath);
const status = await context.initialize();
if (this.isActive) {
this.setState({ loading: false, context: status ? context : null });
}
}
public render() {
const { lang, modulepath } = this.props;
const { loading, context } = this.state;
const topUrl = modulepath + '/list.php?id=1';
if (loading) {
return <Loading />;
}
if (context === null) {
return <PageNotFound lang={lang} />;
}
return <div className="cosmodb">
<Switch>
<Route exact path={modulepath} render={(props: RouteComponentProps) => {
return <Redirect to={topUrl} />
}} />
<Route exact path={`${modulepath}/index.php`} render={(props: RouteComponentProps) => {
return <Redirect to={topUrl} />
}} />
<Route path={`${modulepath}/list.php`} render={(props: RouteComponentProps) => {
const { location } = props;
const params = new URLSearchParams(location.search);
return <CosmoDbList lang={lang} context={context} params={params} />;
}} />
<Route path={`${modulepath}/detail.php`} render={(props: RouteComponentProps) => {
const { location } = props;
const params = new URLSearchParams(location.search);
const idStr = params.get('id') || '';
const tabStr = params.get('tab') || '1';
if (!/^\d+/.test(idStr) || !/^\d+/.test(tabStr)) {
return <PageNotFound lang={lang} />;
}
const id = parseInt(idStr);
const tab = parseInt(tabStr);
return <CosmoDbDetail lang={lang} context={context} id={id} tab={tab} />;
}} />
<Route component={PageNotFound} />
</Switch>
</div>;
}
}
const topUrl = context.getUrl('list.php?id=1');
return (
<div className="cosmodb">
<Routes>
<Route index element={<Navigate to={topUrl} replace />} />
<Route path="index.php" element={<Navigate to={topUrl} replace />} />
<Route path="list.php" element={<CosmoDbListPage lang={lang} context={context} />} />
<Route path="detail.php" element={<CosmoDbDetailPage lang={lang} context={context} />} />
<Route path="*" element={<PageNotFound lang={lang} />} />
</Routes>
</div>
);
};
export default CosmoDb;
+41 -57
View File
@@ -1,81 +1,65 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { Helmet } from '@dr.pogodin/react-helmet';
import { useEffect, useState } from 'react';
import Loading from '../common/lib/Loading';
import PageNotFound from '../common/lib/PageNotFound';
import XoopsCode from '../common/lib/XoopsCode';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import CosmoDbContext, { CosmoDbBasicData, CosmoDbDetailData } from './lib/CosmoDbContext';
import type CosmoDbContext from './lib/CosmoDbContext';
import type { CosmoDbDetailData } from './lib/CosmoDbContext';
interface Props extends RouteComponentProps {
interface Props {
lang: MultiLang;
context: CosmoDbContext;
id: number;
tab: number;
}
interface State {
loading: boolean;
basic: CosmoDbBasicData | null;
interface LoadedDetail {
context: CosmoDbContext;
id: number;
detail: CosmoDbDetailData | null;
}
class CosmoDbDetail extends Component<Props, State> {
const CosmoDbDetail = (props: Props) => {
const { lang, context, id, tab } = props;
const basic = context.getBasic(id);
const [loaded, setLoaded] = useState<LoadedDetail | null>(null);
private isActive: boolean;
public constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
basic: null,
detail: null,
useEffect(() => {
let active = true;
context.getDetail(id).then((detail) => {
if (active) {
setLoaded({ context, id, detail });
}
});
return () => {
active = false;
};
}
}, [context, id]);
public componentDidMount() {
this.isActive = true;
this.updatePage();
if (basic === null) {
return <PageNotFound lang={lang} />;
}
public componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, context, id, tab } = this.props;
if (prevProps.lang !== lang || prevProps.context.getUrl('') !== context.getUrl('') || prevProps.id !== id || prevProps.tab !== tab) {
this.updatePage();
}
// A detail loaded for the previous item must not be shown for this one.
if (loaded === null || loaded.context !== context || loaded.id !== id) {
return <Loading />;
}
public componentWillUnmount() {
this.isActive = false;
if (loaded.detail === null) {
return <PageNotFound lang={lang} />;
}
public async updatePage() {
const { context, id } = this.props;
const basic = context.getBasic(id);
const detail = basic !== null ? await context.getDetail(id) : null;
if (this.isActive) {
this.setState({ loading: false, basic, detail });
}
}
public render() {
const { lang, context, tab } = this.props;
if (this.state.loading) {
return <Loading />;
}
if (this.state.basic === null || this.state.detail === null) {
return <PageNotFound lang={lang} />;
}
const html = context.renderDetail(this.state.basic, this.state.detail, tab);
return <div className="detail">
const html = context.renderDetail(basic, loaded.detail, tab);
return (
<div className="detail">
<Helmet>
<title>{Functions.mlang(this.state.basic.label, lang)} - {Functions.mlang(context.getModuleName(), lang)} - {Functions.siteTitle(lang)}</title>
<title>
{Functions.mlang(basic.label, lang)} - {Functions.mlang(context.getModuleName(), lang)} -{' '}
{Functions.siteTitle(lang)}
</title>
</Helmet>
<XoopsCode lang={lang} text={html} dohtml={true} />
</div>;
}
}
</div>
);
};
export default withRouter(CosmoDbDetail);
export default CosmoDbDetail;
+33 -23
View File
@@ -1,46 +1,56 @@
import React from 'react';
import { Helmet } from 'react-helmet';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { Helmet } from '@dr.pogodin/react-helmet';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import CosmoDbContext, { CosmoDbListDataType } from './lib/CosmoDbContext';
import type CosmoDbContext from './lib/CosmoDbContext';
import { CosmoDbListDataType } from './lib/CosmoDbContext';
import CosmoDbListListView from './lib/CosmoDbListListView';
import CosmoDbListPageNavi from './lib/CosmoDbListPageNavi';
import CosmoDbListThumbnailView from './lib/CosmoDbListThumbnailView';
import CosmoDbListViewSwitcher from './lib/CosmoDbListViewSwitcher';
interface Props extends RouteComponentProps {
interface Props {
lang: MultiLang;
context: CosmoDbContext;
params: URLSearchParams;
}
const CosmoDbList: React.FC<Props> = (props: Props) => {
const CosmoDbList = (props: Props) => {
const { lang, context, params } = props;
const paramId = params.get('id');
if (paramId === null || !/^\d+$/.test(paramId)) {
return <PageNotFound lang={lang} />;
}
const id = parseInt(paramId);
let list = context.getList(id);
const id = parseInt(paramId, 10);
const list = context.getList(id);
if (list === null) {
return <PageNotFound lang={lang} />;
}
const result = context.search(params);
return <div className="list">
<Helmet>
<title>{Functions.mlang(context.getModuleName(), lang)} - {Functions.siteTitle(lang)}</title>
</Helmet>
<CosmoDbListViewSwitcher lang={lang} context={context} params={params} />
<CosmoDbListPageNavi lang={lang} context={context} params={params} total={result.total} />
<hr />
{list.type === CosmoDbListDataType.List ?
<CosmoDbListListView lang={lang} context={context} list={list} params={params} data={result.result} /> :
<CosmoDbListThumbnailView lang={lang} context={context} list={list} params={params} data={result.result} />
}
<CosmoDbListPageNavi lang={lang} context={context} params={params} total={result.total} />
</div>;
return (
<div className="list">
<Helmet>
<title>
{Functions.mlang(context.getModuleName(), lang)} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<CosmoDbListViewSwitcher lang={lang} context={context} params={params} />
<CosmoDbListPageNavi lang={lang} context={context} params={params} total={result.total} />
<hr />
{list.type === CosmoDbListDataType.List ? (
<CosmoDbListListView lang={lang} context={context} list={list} params={params} data={result.result} />
) : (
<CosmoDbListThumbnailView
lang={lang}
context={context}
list={list}
params={params}
data={result.result}
/>
)}
<CosmoDbListPageNavi lang={lang} context={context} params={params} total={result.total} />
</div>
);
};
export default withRouter(CosmoDbList);
export default CosmoDbList;
+120 -120
View File
@@ -1,269 +1,269 @@
.cosmodb {
font-size: 95%;
font-size: 95%;
}
.cosmodb th {
color: #ffffff;
background-color: #802d2d;
padding: 2px;
vertical-align: middle;
text-align: left;
color: #ffffff;
background-color: #802d2d;
padding: 2px;
vertical-align: middle;
text-align: left;
}
.cosmodb th a {
color: #ffffff;
color: #ffffff;
}
.cosmodb th a:hover {
color: #ff6600;
color: #ff6600;
}
.cosmodb hr {
border-width: 1px 0 0 0;
border-style: solid;
border-color: #dedbde;
border-width: 1px 0 0 0;
border-style: solid;
border-color: #dedbde;
}
.cosmodb figure {
margin: 0;
margin: 0;
}
.cosmodb .list .view-switcher {
font-size: 95%;
text-align: right;
font-size: 95%;
text-align: right;
}
.cosmodb .list .pagenavi {
margin: 5px 0;
font-size: 95%;
margin: 5px 0;
font-size: 95%;
}
.cosmodb .list .pagenavi .pages {
margin-left: 10px;
font-weight: bold;
margin-left: 10px;
font-weight: bold;
}
.cosmodb .list .list-sortbar {
margin: 5px 0;
text-align: right;
margin: 5px 0;
text-align: right;
}
.cosmodb .list .list-sortbar select {
margin-right: 3px;
margin-right: 3px;
}
.cosmodb .list .list-sortbar .formButton {
background: white;
border: 1px solid;
background: white;
border: 1px solid;
}
.cosmodb .list .list-view .list-table {
margin: 10px 0;
border-collapse: collapse;
border: 1px solid #dedbde;
text-align: left;
margin: 10px 0;
border-collapse: collapse;
border: 1px solid #dedbde;
text-align: left;
}
.cosmodb .list .list-view .list-table th {
padding: 2px;
vertical-align: middle;
padding: 2px;
vertical-align: middle;
}
.cosmodb .list .list-view .list-table td {
padding: 3px;
border: 1px solid #dedbde;
padding: 3px;
border: 1px solid #dedbde;
}
.cosmodb .list .thumbnail-view .thumbnail-table {
width: 100%;
border-collapse: collapse;
width: 100%;
border-collapse: collapse;
}
.cosmodb .list .thumbnail-view .thumbnail-table td {
padding: 0px;
border-width: 0px;
vertical-align: top;
padding: 0px;
border-width: 0px;
vertical-align: top;
}
.cosmodb .list .thumbnail-view .thumbnail-table td .list_table th a {
color: #ffffff;
color: #ffffff;
}
.cosmodb .list .thumbnail-view .thumbnail-table td .list_table th a:hover {
color: #ff6600;
text-decoration: none;
color: #ff6600;
text-decoration: none;
}
.cosmodb .list .thumbnail-view .thumbnail-table td .list_table {
border-collapse: collapse;
border: 1px solid #dedbde;
text-align: left;
border-collapse: collapse;
border: 1px solid #dedbde;
text-align: left;
}
.cosmodb .list .thumbnail-view .thumbnail-table td .list_table td {
padding: 3px;
border: 1px solid #dedbde;
padding: 3px;
border: 1px solid #dedbde;
}
.cosmodb .list .thumbnail-view .thumbnail-table td .list_table td img {
border: 2px solid transparent;
border: 2px solid transparent;
}
.cosmodb .list .thumbnail-view .thumbnail-table td .list_table td img:hover {
border-color: #ff6600;
border-color: #ff6600;
}
.cosmodb .detail table td {
padding: 3px;
padding: 3px;
}
.cosmodb .detail .label_header {
color: #db4d4d;
font-size: 15px;
font-weight: bold;
border-bottom: 1px solid #dddddd;
color: #db4d4d;
font-size: 15px;
font-weight: bold;
border-bottom: 1px solid #dddddd;
}
.cosmodb .detail .h_under {
margin: 10px 0 30px;
font-weight: bold;
margin: 10px 0 30px;
font-weight: bold;
}
.cosmodb .detail .images {
text-align: center;
text-align: center;
}
.cosmodb .detail .images td img {
border: 2px solid transparent;
border: 2px solid transparent;
}
.cosmodb .detail .images td img:hover {
border-color: #ff6600;
border-color: #ff6600;
}
.cosmodb .detail .list_table td.even {
width: 120px;
width: 120px;
}
.cosmodb .detail .h {
width: 100%;
font-size: 120%;
text-align: left;
border-bottom: 1px solid #dddddd;
margin-top: 40px;
color: #db4d4d;
font-weight: bold;
width: 100%;
font-size: 120%;
text-align: left;
border-bottom: 1px solid #dddddd;
margin-top: 40px;
color: #db4d4d;
font-weight: bold;
}
.cosmodb .detail .keywords>ul {
padding-left: 0;
.cosmodb .detail .keywords > ul {
padding-left: 0;
}
.cosmodb .detail .keywords>ul>li {
list-style-type: none;
font-style: italic;
.cosmodb .detail .keywords > ul > li {
list-style-type: none;
font-style: italic;
}
.cosmodb .detail .keywords>ul>li>ul {
padding-left: 20px;
font-style: normal;
.cosmodb .detail .keywords > ul > li > ul {
padding-left: 20px;
font-style: normal;
}
.cosmodb .detail .keywords>ul>li>ul li {
list-style: square inside;
color: #2F5376;
.cosmodb .detail .keywords > ul > li > ul li {
list-style: square inside;
color: #2f5376;
}
.cosmodb .detail .datatree ul {
margin: 0;
padding: 0;
position: relative;
margin: 0;
padding: 0;
position: relative;
}
.cosmodb .detail .datatree ul li {
margin: 0 0 0 14px;
padding: 0;
list-style-type: none;
white-space: nowrap;
border-left: 1px solid #cccccc;
margin: 0 0 0 14px;
padding: 0;
list-style-type: none;
white-space: nowrap;
border-left: 1px solid #cccccc;
}
.cosmodb .detail .datatree ul li div {
padding-left: 10px;
position: relative;
padding-left: 10px;
position: relative;
}
.cosmodb .detail .datatree ul li div::before {
content: "";
position: absolute;
top: 0px;
left: -1px;
bottom: 50%;
width: 7px;
border: 1px solid #cccccc;
border-top: 0 none transparent;
border-right: 0 none transparent;
border-radius: 0 0 0 0px;
content: "";
position: absolute;
top: 0px;
left: -1px;
bottom: 50%;
width: 7px;
border: 1px solid #cccccc;
border-top: 0 none transparent;
border-right: 0 none transparent;
border-radius: 0 0 0 0px;
}
.cosmodb .detail .datatree ul>li:last-child {
border-left: 1px solid transparent;
.cosmodb .detail .datatree ul > li:last-child {
border-left: 1px solid transparent;
}
.cosmodb .detail .datatree li.root {
background: url(images/icon-root.png) no-repeat 6px 0;
background: url(images/icon-root.png) no-repeat 6px 0;
}
.cosmodb .detail .datatree li.root>div {
visibility: hidden;
.cosmodb .detail .datatree li.root > div {
visibility: hidden;
}
.cosmodb .detail .datatree li.dir>div {
background: url(images/icon-folder-open.png) no-repeat 8px 0;
text-indent: 18px;
.cosmodb .detail .datatree li.dir > div {
background: url(images/icon-folder-open.png) no-repeat 8px 0;
text-indent: 18px;
}
.cosmodb .detail .datatree li.file>div {
background: url(images/icon-file.png) no-repeat 8px 0;
text-indent: 14px;
.cosmodb .detail .datatree li.file > div {
background: url(images/icon-file.png) no-repeat 8px 0;
text-indent: 14px;
}
.cosmodb .detail .news {
border-bottom: 1px dashed #ddd;
border-bottom: 1px dashed #ddd;
}
.cosmodb .detail .news .date {
display: inline-block;
width: 100px;
display: inline-block;
width: 100px;
}
.cosmodb .detail .news .filename {
display: inline-block;
width: calc(100% - 200px);
display: inline-block;
width: calc(100% - 200px);
}
.cosmodb .detail .news .user {
display: inline-block;
width: 100px;
display: inline-block;
width: 100px;
}
.cosmodb .detail .links .title {
font-weight: bold;
font-weight: bold;
}
.cosmodb .detail .links .link span {
vertical-align: top;
display: inline-block;
vertical-align: top;
display: inline-block;
}
.cosmodb .detail .links .link .name {
width: 50%;
width: 50%;
}
.cosmodb .detail .links .link .note {
width: 30%;
width: 30%;
}
.cosmodb .detail .links .link .user {
width: 10%;
}
width: 10%;
}
+209 -121
View File
@@ -1,14 +1,17 @@
import axios from 'axios';
import { format } from 'date-fns';
import ky from 'ky';
import loki from 'lokijs';
import XRegExp from 'xregexp';
import Config from '../../config';
import Functions from '../../functions';
const formatDate = (timestamp: number, pattern: string): string => format(new Date(timestamp * 1000), pattern);
export enum CosmoDbComponentDataType {
System = 1,
RadioButtom,
CheckBox,
Text,
Select
Select,
}
export interface CosmoDbComponentData {
@@ -35,7 +38,7 @@ export interface CosmoDbKeywordData {
export enum CosmoDbListDataType {
List = 1,
Thumbnail
Thumbnail,
}
export interface CosmoDbListData {
@@ -98,7 +101,7 @@ export interface CosmoDbDetailCommentTopicData {
export interface CosmoDbDetailLinkData {
type: number;
user: string,
user: string;
name: string;
href: string;
note: string;
@@ -118,8 +121,6 @@ export interface CosmoDbBasicSearchResult {
}
class CosmoDbContext {
private isInitialized: boolean;
private modulepath: string;
private database: loki;
private component: Collection<CosmoDbComponentData>;
@@ -127,9 +128,9 @@ class CosmoDbContext {
private detailTemplate: string | null;
private list: Collection<CosmoDbListData>;
private basic: Collection<CosmoDbBasicData>;
private initializing: Promise<boolean> | null;
public constructor(modulepath: string) {
this.isInitialized = false;
this.modulepath = modulepath;
this.database = new loki(modulepath);
this.component = this.database.addCollection('component');
@@ -137,6 +138,7 @@ class CosmoDbContext {
this.detailTemplate = null;
this.list = this.database.addCollection('list');
this.basic = this.database.addCollection('data');
this.initializing = null;
}
public getModuleName(): string {
@@ -147,12 +149,16 @@ class CosmoDbContext {
return `${this.modulepath}/${path}`;
}
private getJsonUrl(path: string): URL {
return new URL(Config.BASE_URL + this.getUrl(path), window.location.href);
}
public getListUrl(params: URLSearchParams): string {
return this.getUrl('list.php?' + params.toString());
return this.getUrl(`list.php?${params.toString()}`);
}
public getDetailUrl(id: number, tab?: number): string {
const tabParam = (typeof tab !== 'undefined' && tab !== 1) ? `&tab=${tab.toString()}` : ''
const tabParam = typeof tab !== 'undefined' && tab !== 1 ? `&tab=${tab.toString()}` : '';
return this.getUrl(`detail.php?id=${id}${tabParam}`);
}
@@ -205,19 +211,21 @@ class CosmoDbContext {
replace = basic.author;
break;
case 'Creation Date':
replace = Functions.formatDate(basic.reg_date, 'YYYY-MM-DD');
replace = formatDate(basic.reg_date, 'yyyy-MM-dd');
break;
case 'Views':
replace = basic.views.toString();
break;
}
} else {
const component = basic.components.find((c) => { return c.name === value.name; });
const component = basic.components.find((c) => {
return c.name === value.name;
});
replace = typeof component !== 'undefined' ? component.value : '';
}
replace = Functions.htmlspecialchars(replace);
if (replace !== '' && linkToDetail) {
replace = `<a href="${url}">` + replace + '</a>';
replace = `<a href="${url}">${replace}</a>`;
}
text = text.replace(`{${value.name}}`, replace);
});
@@ -229,7 +237,7 @@ class CosmoDbContext {
}
dirs += value.name.substr(0, 3);
}
})
});
dirs = Functions.htmlspecialchars(dirs);
if (dirs !== '' && linkToDetail) {
dirs = `<a href="${url}">${dirs}</a>`;
@@ -239,7 +247,7 @@ class CosmoDbContext {
}
public renderDetail(basic: CosmoDbBasicData, detail: CosmoDbDetailData, tab: number): string {
let template = this.detailTemplate || '';
const template = this.detailTemplate || '';
return this.renderBasic(basic, template, false)
.replace(/{(AddBookmark|AddLink|Config|FileManager)}/g, '')
.replace('{Acomment}', this.renderDetailAuthorComment(detail))
@@ -247,10 +255,12 @@ class CosmoDbContext {
.replace('{Keyword}', this.renderDetailKeywords(detail))
.replace('{News}', this.renderDetailNews(basic))
.replace('{Link}', this.renderDetailLinks(basic, detail))
.replace(XRegExp('{Image\\s+(.*?)\\s+(.*?)\\s*}', 'g'), (whole, m1, m2) => this.renderDetailImage(basic, m1, m2))
.replace(/\{Image\s+(.*?)\s+(.*?)\s*\}/g, (_whole, m1, m2) => this.renderDetailImage(basic, m1, m2))
.replace('{Dtree}', this.renderDetailDataTree(basic))
.replace(XRegExp('{href_tab(\\d+)}(.*?){/href_tab}', 'g'), (whole, m1, m2) => this.renderDetailHrefTab(basic, m1, m2))
.replace(XRegExp('{tab(\\d+)}(.*?){/tab}', 'sg'), (whole, m1, m2) => this.renderDetailTab(tab, m1, m2));
.replace(/\{href_tab(\d+)\}(.*?)\{\/href_tab\}/g, (_whole, m1, m2) =>
this.renderDetailHrefTab(basic, m1, m2)
)
.replace(/\{tab(\d+)\}(.*?)\{\/tab\}/gs, (_whole, m1, m2) => this.renderDetailTab(tab, m1, m2));
}
public search(params: URLSearchParams): CosmoDbBasicSearchResult {
@@ -258,36 +268,88 @@ class CosmoDbContext {
const paramN = params.get('n');
const paramSort = params.get('sort');
const paramSortMethod = params.get('sort_method');
const offset = (paramItem !== null && /^\d+/.test(paramItem)) ? parseInt(paramItem) : 0;
const limit = (paramN !== null && /^\d+/.test(paramN)) ? parseInt(paramN) : 20;
const sort = (paramSort !== null && /^\d+/.test(paramSort)) ? parseInt(paramSort) : 1;
const sortMethod = (paramSortMethod !== null && paramSortMethod === 'asc') ? 'asc' : 'desc';
const component = this.component.findOne({ comp_id: sort })
const offset = paramItem !== null && /^\d+/.test(paramItem) ? parseInt(paramItem, 10) : 0;
const limit = paramN !== null && /^\d+/.test(paramN) ? parseInt(paramN, 10) : 20;
const sort = paramSort !== null && /^\d+/.test(paramSort) ? parseInt(paramSort, 10) : 1;
const sortMethod = paramSortMethod !== null && paramSortMethod === 'asc' ? 'asc' : 'desc';
const component = this.component.findOne({ comp_id: sort });
const sortFunc = (a: CosmoDbBasicData, b: CosmoDbBasicData) => {
if (component !== null) {
if (component.type === CosmoDbComponentDataType.System) {
switch (component.name) {
case 'ID':
return a.id === b.id ? 0 : (a.id > b.id ? (sortMethod === 'asc' ? 1 : -1) : (sortMethod === 'asc' ? -1 : 1));
return a.id === b.id
? 0
: a.id > b.id
? sortMethod === 'asc'
? 1
: -1
: sortMethod === 'asc'
? -1
: 1;
case 'Data Name':
return a.label === b.label ? 0 : (a.label > b.label ? (sortMethod === 'asc' ? 1 : -1) : (sortMethod === 'asc' ? -1 : 1));
return a.label === b.label
? 0
: a.label > b.label
? sortMethod === 'asc'
? 1
: -1
: sortMethod === 'asc'
? -1
: 1;
case 'Author':
return a.author === b.author ? 0 : (a.author > b.author ? (sortMethod === 'asc' ? 1 : -1) : (sortMethod === 'asc' ? -1 : 1));
return a.author === b.author
? 0
: a.author > b.author
? sortMethod === 'asc'
? 1
: -1
: sortMethod === 'asc'
? -1
: 1;
case 'Creation Date':
return a.reg_date === b.reg_date ? 0 : (a.reg_date > b.reg_date ? (sortMethod === 'asc' ? 1 : -1) : (sortMethod === 'asc' ? -1 : 1));
return a.reg_date === b.reg_date
? 0
: a.reg_date > b.reg_date
? sortMethod === 'asc'
? 1
: -1
: sortMethod === 'asc'
? -1
: 1;
case 'Views':
return a.views === b.views ? 0 : (a.views > b.views ? (sortMethod === 'asc' ? 1 : -1) : (sortMethod === 'asc' ? -1 : 1));
return a.views === b.views
? 0
: a.views > b.views
? sortMethod === 'asc'
? 1
: -1
: sortMethod === 'asc'
? -1
: 1;
}
} else {
const ac = a.components.find((value) => { return value.name === component.name });
const bc = b.components.find((value) => { return value.name === component.name });
const ac = a.components.find((value) => {
return value.name === component.name;
});
const bc = b.components.find((value) => {
return value.name === component.name;
});
if (typeof ac !== 'undefined' && typeof bc !== 'undefined') {
return ac.value === bc.value ? 0 : (ac.value > bc.value ? (sortMethod === 'asc' ? 1 : -1) : (sortMethod === 'asc' ? -1 : 1));
return ac.value === bc.value
? 0
: ac.value > bc.value
? sortMethod === 'asc'
? 1
: -1
: sortMethod === 'asc'
? -1
: 1;
}
}
}
return 0;
}
};
const resultSet = this.basic.chain().find();
return {
total: resultSet.count(),
@@ -296,85 +358,91 @@ class CosmoDbContext {
}
public async getDetail(contentId: number): Promise<CosmoDbDetailData | null> {
let page: CosmoDbDetailData | null = null;
try {
const response = await axios.get(this.getUrl(`${contentId}.json`));
page = response.data as CosmoDbDetailData;
} catch (e) {
// ignore
return await ky.get(this.getJsonUrl(`${contentId}.json`)).json<CosmoDbDetailData>();
} catch {
return null;
}
return page;
}
public async initialize(): Promise<boolean> {
if (!this.isInitialized) {
try {
const response = await axios.get(this.getUrl('index.json'));
const index = response.data as CosmoDbIndexData;
index.component.forEach((value) => {
this.component.insert(value);
});
index.keyword.forEach((value) => {
this.keyword.insert(value);
});
this.detailTemplate = index.detail;
index.list.forEach((value) => {
this.list.insert(value);
/**
* Loads the module index once. Concurrent callers share the same request,
* so the collections are never filled twice.
*/
public initialize = (): Promise<boolean> => {
if (this.initializing === null) {
this.initializing = ky
.get(this.getJsonUrl('index.json'))
.json<CosmoDbIndexData>()
.then((index) => {
this.component.insert(index.component);
this.keyword.insert(index.keyword);
this.detailTemplate = index.detail;
this.list.insert(index.list);
this.basic.insert(index.data);
return true;
})
index.data.forEach((value) => {
this.basic.insert(value);
})
} catch (err) {
// ignore
}
this.isInitialized = true;
.catch(() => false);
}
return this.isInitialized;
}
return this.initializing;
};
private renderTextArea(text: string): string {
const regexI = XRegExp('\\[i\\](.*?)\\[/i\\]', 'sg');
const regexB = XRegExp('\\[b\\](.*?)\\[/b\\]', 'sg');
text = text.replace(/\r?\n/g, '<br />')
.replace(regexI, (whole, m1) => `<em>${m1}</em>`)
.replace(regexB, (whole, m1) => `<strong>${m1}</strong>`);
const regexI = /\[i\](.*?)\[\/i\]/gs;
const regexB = /\[b\](.*?)\[\/b\]/gs;
text = text
.replace(/\r?\n/g, '<br />')
.replace(regexI, (_whole, m1) => `<em>${m1}</em>`)
.replace(regexB, (_whole, m1) => `<strong>${m1}</strong>`);
return text;
}
private renderComment(comment: CosmoDbDetailCommentData, showSubject: boolean) {
const datetime = Functions.formatDate(comment.reg_date, 'YYYY-MM-DD HH:mm');
const datetime = formatDate(comment.reg_date, 'yyyy-MM-dd HH:mm');
const message = this.renderTextArea(comment.message);
const subject = showSubject ? `<b>${this.renderTextArea(comment.subject)}</b><br />` : '';
return `<tr>`
+ `<td class="even" style="text-align: center">${comment.reg_user}<br />${datetime.replace(' ', '<br />')}</td>`
+ `<td>${subject}${message}</td>`
+ `</tr>`;
return (
`<tr>` +
`<td class="even" style="text-align: center">${comment.reg_user}<br />${datetime.replace(' ', '<br />')}</td>` +
`<td>${subject}${message}</td>` +
`</tr>`
);
}
private renderDetailAuthorComment(detail: CosmoDbDetailData): string {
const topics = detail.comment_topics.find((value) => { return value.type === 'auth'; });
const topics = detail.comment_topics.find((value) => {
return value.type === 'auth';
});
let result = '';
if (typeof topics !== 'undefined') {
result = '<table class="list_table"><tbody>'
+ '<tr><th colspan="2">[en]Author Comment[/en][ja]オーサーコメント[/ja]</th></tr>'
+ this.renderComment(topics.comment, false)
+ topics.replies.map((value) => this.renderComment(value, true)).join('')
+ '</tbody></table>';
result =
'<table class="list_table"><tbody>' +
'<tr><th colspan="2">[en]Author Comment[/en][ja]オーサーコメント[/ja]</th></tr>' +
this.renderComment(topics.comment, false) +
topics.replies.map((value) => this.renderComment(value, true)).join('') +
'</tbody></table>';
}
return result;
}
private renderDetailUserComment(detail: CosmoDbDetailData): string {
const topics = detail.comment_topics.filter((value) => { return value.type === 'user'; });
const topics = detail.comment_topics.filter((value) => {
return value.type === 'user';
});
let result = '';
if (topics.length > 0) {
result = '<table class="list_table"><tbody>'
+ '<tr><th colspan="2">[en]User Comment[/en][ja]ユーザーコメント[/ja]</th></tr>'
+ topics.map((topic) => {
return this.renderComment(topic.comment, true)
+ topic.replies.map((comment) => this.renderComment(comment, true)).join('');
}).join('')
+ '</tbody></table>';
result =
'<table class="list_table"><tbody>' +
'<tr><th colspan="2">[en]User Comment[/en][ja]ユーザーコメント[/ja]</th></tr>' +
topics
.map((topic) => {
return (
this.renderComment(topic.comment, true) +
topic.replies.map((comment) => this.renderComment(comment, true)).join('')
);
})
.join('') +
'</tbody></table>';
}
return result;
}
@@ -396,7 +464,11 @@ class CosmoDbContext {
}
});
const renderChildKeywords = (id: number): string => {
const keywords = this.keyword.chain().find({ pid: id, kw_id: { '$in': allKwIds } }).simplesort('sort').data();
const keywords = this.keyword
.chain()
.find({ pid: id, kw_id: { $in: allKwIds } })
.simplesort('sort')
.data();
if (keywords.length === 0) {
return '';
}
@@ -404,10 +476,10 @@ class CosmoDbContext {
rows.push('<ul>');
keywords.forEach((keyword) => {
rows.push(`<li>${keyword.keyword}${renderChildKeywords(keyword.kw_id)}</li>`);
})
});
rows.push('</ul>');
return rows.join('');
}
};
return `<div class="keywords">${renderChildKeywords(0)}</div>`;
}
@@ -415,7 +487,7 @@ class CosmoDbContext {
let result = '';
basic.items.forEach((item) => {
if (item.type === 'file') {
const date = Functions.formatDate(item.reg_date, 'YYYY-MM-DD');
const date = formatDate(item.reg_date, 'yyyy-MM-dd');
const fname = Functions.htmlspecialchars(item.path === '' ? item.name : `${item.path}/${item.name}`);
const uname = Functions.htmlspecialchars(`${item.reg_user}`);
result += `<div class="news"><span class="date">${date}</span><span class="filename">${fname}</span><span class="user">${uname}</span></div>`;
@@ -432,20 +504,24 @@ class CosmoDbContext {
const user = Functions.htmlspecialchars(link.user);
if (link.type === 1) {
const name = Functions.htmlspecialchars(basic.label);
const href = this.getDetailUrl(parseInt(link.name));
linkIn.push(`<div class="link"><span class="name"><a href="${href}">${name}</a></span><span class="note">${note}</span><span class="user">${user}</span></div>`);
const href = this.getDetailUrl(parseInt(link.name, 10));
linkIn.push(
`<div class="link"><span class="name"><a href="${href}">${name}</a></span><span class="note">${note}</span><span class="user">${user}</span></div>`
);
} else {
const name = Functions.htmlspecialchars(link.name);
const href = Functions.htmlspecialchars(link.href);
linkOut.push(`<div class="link"><span class="name"><a href="${href}">${name}</a></span><span class="note">${note}</span><span class="user">${user}</span></div>`);
linkOut.push(
`<div class="link"><span class="name"><a href="${href}">${name}</a></span><span class="note">${note}</span><span class="user">${user}</span></div>`
);
}
});
let result: string = '';
if (linkIn.length !== 0) {
result += `<div class="links"><div class="title">[en]Relative data[/en][ja]関連データ[/ja]</div>${linkIn.join('')}</div>`
result += `<div class="links"><div class="title">[en]Relative data[/en][ja]関連データ[/ja]</div>${linkIn.join('')}</div>`;
}
if (linkOut.length !== 0) {
result += `<div class="links"><div class="title">[en]Relative URL[/en][ja]関連URL[/ja]</div>${linkOut.join('')}</div>`
result += `<div class="links"><div class="title">[en]Relative URL[/en][ja]関連URL[/ja]</div>${linkOut.join('')}</div>`;
}
return result;
}
@@ -453,28 +529,31 @@ class CosmoDbContext {
private renderDetailImage(basic: CosmoDbBasicData, arg1: string, arg2: string): string {
const dirs = arg1.split('|');
const options = arg2.split('|');
const images = basic.thumbnails.filter((thumbnail) => XRegExp(`^${dirs.join('|')}/`).test(thumbnail.url))
.sort((a, b) => a.url === b.url ? 0 : (a.url > b.url ? 1 : -1));
const images = basic.thumbnails
.filter((thumbnail) => new RegExp(`^${dirs.join('|')}/`).test(thumbnail.url))
.sort((a, b) => (a.url === b.url ? 0 : a.url > b.url ? 1 : -1));
if (options.length !== 3 || images.length === 0) {
return '';
}
const imgStyles: string[] = [];
if (options[0] !== '') {
const value = /^d+/.test(options[0]) ? `${options[0]}px` : options[0];
const value = /^\d+$/.test(options[0]) ? `${options[0]}px` : options[0];
imgStyles.push(`width:${value}`);
}
if (options[1] !== '') {
const value = /^d+/.test(options[1]) ? `${options[1]}px` : options[1];
const value = /^\d+$/.test(options[1]) ? `${options[1]}px` : options[1];
imgStyles.push(`height:${value}`);
}
const imgStyle = imgStyles.length !== 0 ? 'style="' + imgStyles.join(';') + '" ' : '';
const maxCol = Math.min(parseInt(options[2]), images.length);
const imgStyle = imgStyles.length !== 0 ? `style="${imgStyles.join(';')}" ` : '';
const maxCol = Math.min(parseInt(options[2], 10), images.length);
const rows: string[] = [];
let cols: string[] = [];
images.forEach((image) => {
const url = Functions.htmlspecialchars(this.getThumbnailUrl(basic.id, image.url));
const caption = Functions.htmlspecialchars(image.caption);
cols.push(`<td><figure><a href="${url}"><img src="${url}" alt="${url}" ${imgStyle}/></a><figcaption>${caption}</figcaption></figure></td>`);
cols.push(
`<td><figure><a href="${url}"><img src="${url}" alt="${url}" ${imgStyle}/></a><figcaption>${caption}</figcaption></figure></td>`
);
if (cols.length === maxCol) {
rows.push(`<tr>${cols.join('')}</tr>`);
cols = [];
@@ -487,40 +566,49 @@ class CosmoDbContext {
cols = [];
}
}
let result = `<table class="images"><tbody>${rows.join('')}</tbody></table>`;
const result = `<table class="images"><tbody>${rows.join('')}</tbody></table>`;
return result;
}
private renderDetailDataTree(basic: CosmoDbBasicData): string {
const renderChildTree = (path: string): string => {
return '<ul>'
+ basic.items.filter((item) => item.path === path).sort((a, b) => {
if (a.type === 'dir' && b.type === 'file') {
return -1;
} else if (a.type === 'file' && b.type === 'dir') {
return 1;
}
return a.name === b.name ? 0 : (a.name > b.name ? 1 : -1)
}).map((item) => {
const name = Functions.htmlspecialchars(item.name);
const path = item.path === '' ? item.name : `${item.path}/${item.name}`;
const url = Functions.htmlspecialchars(this.getDataUrl(basic.id, `${path}`));
const node = item.type === 'dir' ? `<div>${name}</div>${renderChildTree(`${path}`)}` : `<div><a href="${url}" download="${name}">${name}</a></div>`;
return `<li class="${item.type}">${node}</li>`;
}).join('')
+ '</ul>';
}
return (
'<ul>' +
basic.items
.filter((item) => item.path === path)
.sort((a, b) => {
if (a.type === 'dir' && b.type === 'file') {
return -1;
} else if (a.type === 'file' && b.type === 'dir') {
return 1;
}
return a.name === b.name ? 0 : a.name > b.name ? 1 : -1;
})
.map((item) => {
const name = Functions.htmlspecialchars(item.name);
const path = item.path === '' ? item.name : `${item.path}/${item.name}`;
const url = Functions.htmlspecialchars(this.getDataUrl(basic.id, `${path}`));
const node =
item.type === 'dir'
? `<div>${name}</div>${renderChildTree(`${path}`)}`
: `<div><a href="${url}" download="${name}">${name}</a></div>`;
return `<li class="${item.type}">${node}</li>`;
})
.join('') +
'</ul>'
);
};
return `<div class="datatree"><ul><li class="root"><div>ROOT</div>${renderChildTree('')}</li></ul></div>`;
}
private renderDetailHrefTab(basic: CosmoDbBasicData, no: string, label: string): string {
const tab = parseInt(no);
const tab = parseInt(no, 10);
const href = this.getDetailUrl(basic.id, tab);
return `<a href="${Functions.htmlspecialchars(href)}">${Functions.htmlspecialchars(label)}</a>`;
}
private renderDetailTab(tab: number, no: string, data: string): string {
return tab === parseInt(no) ? data : '';
return tab === parseInt(no, 10) ? data : '';
}
}
+25 -21
View File
@@ -1,7 +1,7 @@
import React from 'react';
import XoopsCode from '../../common/lib/XoopsCode';
import { MultiLang } from '../../config';
import CosmoDbContext, { CosmoDbBasicData, CosmoDbListData } from './CosmoDbContext';
import type { MultiLang } from '../../config';
import type CosmoDbContext from './CosmoDbContext';
import type { CosmoDbBasicData, CosmoDbListData } from './CosmoDbContext';
import CosmoDbListSortBar from './CosmoDbListSortBar';
interface Props {
@@ -12,29 +12,33 @@ interface Props {
data: CosmoDbBasicData[];
}
const CosmoDbListListView: React.FC<Props> = (props: Props) => {
const CosmoDbListListView = (props: Props) => {
const { lang, context, list, params, data } = props;
const components = context.getComponents();
let rowHeader = list.list_th;
components.forEach((value) => {
rowHeader = rowHeader.replace(`{${value.name}}`, value.tag);
})
return <div className="list-view">
<CosmoDbListSortBar lang={lang} context={context} list={list} params={params} />
<table className="list-table">
<tbody>
<tr>
<XoopsCode lang={lang} text={rowHeader} dohtml={true} />
</tr>
{data.map((value) => {
let row = context.renderBasic(value, list.template, true);
return <tr key={value.id}>
<XoopsCode lang={lang} text={row} dohtml={true} />
</tr>;
})}
</tbody>
</table>
</div>;
});
return (
<div className="list-view">
<CosmoDbListSortBar lang={lang} context={context} list={list} params={params} />
<table className="list-table">
<tbody>
<tr>
<XoopsCode lang={lang} text={rowHeader} dohtml={true} />
</tr>
{data.map((value) => {
const row = context.renderBasic(value, list.template, true);
return (
<tr key={value.id}>
<XoopsCode lang={lang} text={row} dohtml={true} />
</tr>
);
})}
</tbody>
</table>
</div>
);
};
export default CosmoDbListListView;
+40 -24
View File
@@ -1,8 +1,8 @@
import React, { Fragment } from 'react';
import { Link } from 'react-router-dom';
import { MultiLang } from '../../config';
import { Fragment, type ReactNode } from 'react';
import { Link } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import CosmoDbContext from './CosmoDbContext';
import type CosmoDbContext from './CosmoDbContext';
interface Props {
lang: MultiLang;
@@ -11,12 +11,12 @@ interface Props {
total: number;
}
const CosmoDbListPageNavi: React.FC<Props> = (props: Props) => {
const CosmoDbListPageNavi = (props: Props) => {
const { lang, context, params, total } = props;
const paramItem = params.get('item');
const paramN = params.get('n');
const offset = (paramItem !== null && /^\d+$/.test(paramItem)) ? parseInt(paramItem) : 0;
let limit = (paramN !== null && /^\d+$/.test(paramN)) ? parseInt(paramN) : 20;
const offset = paramItem !== null && /^\d+$/.test(paramItem) ? parseInt(paramItem, 10) : 0;
const limit = paramN !== null && /^\d+$/.test(paramN) ? parseInt(paramN, 10) : 20;
if (offset > total) {
return null;
}
@@ -33,7 +33,7 @@ const CosmoDbListPageNavi: React.FC<Props> = (props: Props) => {
if (rangeMax > max - 1) {
rangeMax = max - 1;
}
const link = (num: number, el?: JSX.Element) => {
const link = (num: number, el?: ReactNode) => {
const label = el || num;
const nParams = new URLSearchParams(params);
if (num - 1 > 0) {
@@ -42,33 +42,49 @@ const CosmoDbListPageNavi: React.FC<Props> = (props: Props) => {
nParams.set('item', '0');
}
const url = context.getListUrl(nParams);
return num === now ? <>({label})</> : <Link to={url}>{label}</Link>
}
const items: JSX.Element[] = [];
return num === now ? <>({label})</> : <Link to={url}>{label}</Link>;
};
const items: { key: string; node: ReactNode }[] = [];
if (prev !== 0) {
items.push(link(prev, <>&laquo;</>));
items.push({ key: 'prev', node: link(prev, <>&laquo;</>) });
}
items.push(link(min));
items.push({ key: `${min}`, node: link(min) });
if (now - min > 4) {
items.push(<>...</>);
items.push({ key: 'gap-prev', node: <>...</> });
}
for (let range = rangeMin; range <= rangeMax; range++) {
items.push(link(range));
items.push({ key: `${range}`, node: link(range) });
}
if (max - now > 4) {
items.push(<>...</>);
items.push({ key: 'gap-next', node: <>...</> });
}
items.push(link(max));
items.push({ key: `${max}`, node: link(max) });
if (next !== 0) {
items.push(link(next, <>&raquo;</>));
items.push({ key: 'next', node: link(next, <>&raquo;</>) });
}
const rangeS = offset + 1;
const rangeE = (offset + limit) < total ? offset + limit : total;
const rangeE = offset + limit < total ? offset + limit : total;
return <nav className="pagenavi">
<span className="label">{Functions.mlang(`[en]${total} Hits (${rangeS}-${rangeE})[/en][ja]全${total}件 (${rangeS}-${rangeE}件目)[/ja]`, lang)}</span>
{total > limit && <span className="pages">{items.map((el, index) => <Fragment key={index}>{index !== 0 && <>&nbsp;</>}{el}</Fragment>)}</span>}
</nav>;
}
return (
<nav className="pagenavi">
<span className="label">
{Functions.mlang(
`[en]${total} Hits (${rangeS}-${rangeE})[/en][ja]全${total}件 (${rangeS}-${rangeE}件目)[/ja]`,
lang
)}
</span>
{total > limit && (
<span className="pages">
{items.map((item, index) => (
<Fragment key={item.key}>
{index !== 0 && <>&nbsp;</>}
{item.node}
</Fragment>
))}
</span>
)}
</nav>
);
};
export default CosmoDbListPageNavi;
+57 -101
View File
@@ -1,127 +1,83 @@
import React, { ChangeEvent, Component, FormEvent } from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { MultiLang } from '../../config';
import { type ChangeEvent, type FormEvent, useState } from 'react';
import { useNavigate } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import CosmoDbContext, { CosmoDbListData, CosmoDbListDataType } from './CosmoDbContext';
import type CosmoDbContext from './CosmoDbContext';
import { type CosmoDbListData, CosmoDbListDataType } from './CosmoDbContext';
import CosmoDbUtils from './CosmoDbUtils';
interface Props extends RouteComponentProps {
interface Props {
lang: MultiLang;
context: CosmoDbContext;
list: CosmoDbListData;
params: URLSearchParams;
}
interface State {
pathname: string;
listType: CosmoDbListDataType;
sort: number;
sort_method: 'asc' | 'desc'
n: number;
size: string;
}
type SortMethod = 'asc' | 'desc';
class CosmoDbListSortBar extends Component<Props, State> {
const CosmoDbListSortBar = (props: Props) => {
const { lang, context, list, params } = props;
const navigate = useNavigate();
const paramSort = params.get('sort');
const paramN = params.get('n');
const [sort, setSort] = useState(paramSort !== null && /^\d+$/.test(paramSort) ? parseInt(paramSort, 10) : 1);
const [sortMethod, setSortMethod] = useState<SortMethod>(params.get('sort_method') === 'asc' ? 'asc' : 'desc');
const [n, setN] = useState(paramN !== null && /^\d+$/.test(paramN) ? parseInt(paramN, 10) : 20);
const [size, setSize] = useState(CosmoDbUtils.getThumbnailSize(params.get('size'), list.thumb_size)?.name ?? '');
public constructor(props: Props) {
super(props);
this.state = CosmoDbListSortBar.props2state(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChangeSort = this.handleChangeSort.bind(this);
this.handleChangeSortMethod = this.handleChangeSortMethod.bind(this);
this.handleChangeN = this.handleChangeN.bind(this);
this.handleChangeSize = this.handleChangeSize.bind(this);
}
public static props2state(props: Props): State {
const { location, list, params } = props;
const paramSort = params.get('sort');
const paramSortMethod = params.get('sort_method');
const paramN = params.get('n');
const size = CosmoDbUtils.getThumbnailSize(params.get('size'), list.thumb_size);
return {
pathname: location.pathname,
listType: list.type,
sort: paramSort !== null && /^\d+$/.test(paramSort) ? parseInt(paramSort) : 1,
sort_method: paramSortMethod !== null && paramSortMethod === 'asc' ? 'asc' : 'desc',
n: paramN !== null && /^\d+$/.test(paramN) ? parseInt(paramN) : 20,
size: size !== null ? size.name : ''
};
}
public static getDerivedStateFromProps(nextProps: Props, prevState: State) {
const pathname = nextProps.location.pathname;
if (pathname !== prevState.pathname || nextProps.list.type !== prevState.listType) {
return CosmoDbListSortBar.props2state(nextProps);
}
return null;
}
private handleSubmit(event: FormEvent<HTMLFormElement>) {
const { context, list, params } = this.props;
const nParams = new URLSearchParams(params);
const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
const nParams = new URLSearchParams(params);
if (list.type === CosmoDbListDataType.Thumbnail) {
nParams.set('size', this.state.size);
nParams.set('size', size);
}
nParams.set('sort', this.state.sort.toString());
nParams.set('sort_method', this.state.sort_method);
nParams.set('n', this.state.n.toString());
const url = context.getListUrl(nParams);
this.props.history.push(url);
}
nParams.set('sort', sort.toString());
nParams.set('sort_method', sortMethod);
nParams.set('n', n.toString());
void navigate(context.getListUrl(nParams));
};
private handleChangeSort(event: ChangeEvent<HTMLSelectElement>) {
const sort = parseInt(event.target.value);
this.setState({ sort });
}
private handleChangeSortMethod(event: ChangeEvent<HTMLSelectElement>) {
const sort_method = event.target.value as 'asc' | 'desc';
this.setState({ sort_method });
}
private handleChangeN(event: ChangeEvent<HTMLSelectElement>) {
const n = parseInt(event.target.value);
this.setState({ n });
}
private handleChangeSize(event: ChangeEvent<HTMLSelectElement>) {
const size = event.target.value;
this.setState({ size });
}
public render() {
const { lang, context, list } = this.props;
const components = context.getComponents();
const optionsSort: JSX.Element[] = [];
components.forEach((value) => {
if (value.onoff === 0) {
optionsSort.push(<option key={value.comp_id} value={value.comp_id}>{Functions.mlang(value.tag, lang)}</option>);
}
});
const optionsSize: JSX.Element[] = list.thumb_size.split(';').map((value) => {
const key = value.split(',')[0];
return <option key={key}>{key}</option>
});
return <form className="list-sortbar" onSubmit={this.handleSubmit}>
<select value={this.state.sort} onChange={this.handleChangeSort}>
{optionsSort}
const components = context.getComponents().filter((value) => value.onoff === 0);
return (
<form className="list-sortbar" onSubmit={handleSubmit}>
<select
value={sort}
onChange={(event: ChangeEvent<HTMLSelectElement>) => setSort(parseInt(event.target.value, 10))}
>
{components.map((value) => (
<option key={value.comp_id} value={value.comp_id}>
{Functions.mlang(value.tag, lang)}
</option>
))}
</select>
<select value={this.state.sort_method} onChange={this.handleChangeSortMethod}>
<select
value={sortMethod}
onChange={(event: ChangeEvent<HTMLSelectElement>) => setSortMethod(event.target.value as SortMethod)}
>
<option value="asc">{Functions.mlang('[en]ascending order[/en][ja]昇順[/ja]', lang)}</option>
<option value="desc">{Functions.mlang('[en]descending order[/en][ja]降順[/ja]', lang)}</option>
</select>
<select value={this.state.n} onChange={this.handleChangeN}>
<select
value={n}
onChange={(event: ChangeEvent<HTMLSelectElement>) => setN(parseInt(event.target.value, 10))}
>
<option value="20">20</option>
<option value="40">40</option>
<option value="60">60</option>
<option value="80">80</option>
<option value="100">100</option>
</select>
{list.type === CosmoDbListDataType.Thumbnail && <select value={this.state.size} onChange={this.handleChangeSize}>{optionsSize}</select>}
{list.type === CosmoDbListDataType.Thumbnail && (
<select value={size} onChange={(event: ChangeEvent<HTMLSelectElement>) => setSize(event.target.value)}>
{list.thumb_size.split(';').map((value) => {
const key = value.split(',')[0];
return <option key={key}>{key}</option>;
})}
</select>
)}
<input className="formButton" type="submit" value="Sort" />
</form>;
}
}
export default withRouter(CosmoDbListSortBar);
</form>
);
};
export default CosmoDbListSortBar;
+26 -18
View File
@@ -1,8 +1,9 @@
import React from 'react';
import type { ReactNode } from 'react';
import XoopsCode from '../../common/lib/XoopsCode';
import { MultiLang } from '../../config';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import CosmoDbContext, { CosmoDbBasicData, CosmoDbListData } from './CosmoDbContext';
import type CosmoDbContext from './CosmoDbContext';
import type { CosmoDbBasicData, CosmoDbListData } from './CosmoDbContext';
import CosmoDbListSortBar from './CosmoDbListSortBar';
import CosmoDbUtils from './CosmoDbUtils';
@@ -14,14 +15,14 @@ interface Props {
data: CosmoDbBasicData[];
}
const CosmoDbListThumbnailView: React.FC<Props> = (props: Props) => {
const CosmoDbListThumbnailView = (props: Props) => {
const { lang, context, list, params, data } = props;
const size = CosmoDbUtils.getThumbnailSize(params.get('size'), list.thumb_size);
if (size === null) {
return null;
}
const rows: JSX.Element[] = [];
let cols: JSX.Element[] = [];
const rows: ReactNode[] = [];
let cols: ReactNode[] = [];
let col = 1;
const thumbRegex = new RegExp(`^${list.thumb_dir}/`);
const imgStyles: string[] = [];
@@ -31,7 +32,7 @@ const CosmoDbListThumbnailView: React.FC<Props> = (props: Props) => {
if (size.width > 0) {
imgStyles.push(`width:${size.width}px`);
}
const imgStyle = imgStyles.length !== 0 ? 'style="' + imgStyles.join(';') + '" ' : '';
const imgStyle = imgStyles.length !== 0 ? `style="${imgStyles.join(';')}" ` : '';
data.forEach((value) => {
const thumbs = value.thumbnails.filter((thumbnail) => {
return thumbRegex.test(thumbnail.url);
@@ -40,12 +41,19 @@ const CosmoDbListThumbnailView: React.FC<Props> = (props: Props) => {
if (thumbs.length === 0) {
thumbs.push({ url: '', caption: '' });
}
thumbs.forEach((thumb, tindex) => {
thumbs.forEach((thumb) => {
const imgUrl = context.getThumbnailUrl(value.id, thumb.url);
const style = thumb.url === '' ? '' : imgStyle;
const image = `<img src="${Functions.htmlspecialchars(imgUrl)}" alt="${Functions.htmlspecialchars(thumb.url)}" ${style}/>`;
const template = list.template.replace('{Image}', `<div ${imgStyle}><a href="${Functions.htmlspecialchars(url)}">${image}</a></div>`);
cols.push(<td key={`${value.id}.${tindex}`}><XoopsCode lang={lang} text={context.renderBasic(value, template, true)} dohtml={true} /></td>);
const template = list.template.replace(
'{Image}',
`<div ${imgStyle}><a href="${Functions.htmlspecialchars(url)}">${image}</a></div>`
);
cols.push(
<td key={`${value.id}:${thumb.url}`}>
<XoopsCode lang={lang} text={context.renderBasic(value, template, true)} dohtml={true} />
</td>
);
if (cols.length === size.maxCol) {
rows.push(<tr key={col}>{cols}</tr>);
cols = [];
@@ -61,14 +69,14 @@ const CosmoDbListThumbnailView: React.FC<Props> = (props: Props) => {
}
col++;
}
return <div className="thumbnail-view">
<CosmoDbListSortBar lang={lang} context={context} list={list} params={params} />
<table className="thumbnail-table">
<tbody>
{rows}
</tbody>
</table>
</div>;
return (
<div className="thumbnail-view">
<CosmoDbListSortBar lang={lang} context={context} list={list} params={params} />
<table className="thumbnail-table">
<tbody>{rows}</tbody>
</table>
</div>
);
};
export default CosmoDbListThumbnailView;
+15 -14
View File
@@ -1,9 +1,9 @@
import React, { Fragment } from 'react';
import { Link } from 'react-router-dom';
import { Fragment, type ReactNode } from 'react';
import { Link } from 'react-router';
import PageNotFound from '../../common/lib/PageNotFound';
import { MultiLang } from '../../config';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import CosmoDbContext from './CosmoDbContext';
import type CosmoDbContext from './CosmoDbContext';
interface Props {
lang: MultiLang;
@@ -11,33 +11,34 @@ interface Props {
params: URLSearchParams;
}
const CosmoDbListViewSwitcher: React.FC<Props> = (props: Props) => {
const CosmoDbListViewSwitcher = (props: Props) => {
const { lang, context, params } = props;
let viewSwitcher: JSX.Element[] = [];
const viewSwitcher: ReactNode[] = [];
const paramId = params.get('id');
if (paramId === null || !/^\d+$/.test(paramId)) {
return <PageNotFound lang={lang} />;
}
const id = parseInt(paramId);
const id = parseInt(paramId, 10);
const lists = context.getLists();
lists.forEach((value, index) => {
const name = Functions.mlang(value.name, lang);
if (index > 0) {
viewSwitcher.push(<Fragment key={`${index}|`}> | </Fragment>);
viewSwitcher.push(<Fragment key={`${value.list_id}|`}> | </Fragment>);
}
if (value.list_id === id) {
viewSwitcher.push(<span key={value.list_id}>{name}</span>);
}
else {
} else {
const nParams = new URLSearchParams(params);
nParams.set('id', value.list_id.toString());
const url = context.getListUrl(nParams);
viewSwitcher.push(<Link key={value.list_id} to={url}>{name}</Link>);
viewSwitcher.push(
<Link key={value.list_id} to={url}>
{name}
</Link>
);
}
});
return <div className="view-switcher">
{viewSwitcher}
</div>;
return <div className="view-switcher">{viewSwitcher}</div>;
};
export default CosmoDbListViewSwitcher;
+34 -36
View File
@@ -1,45 +1,43 @@
import CosmoDbContext from './CosmoDbContext';
class CosmoDbUtils {
const contexts = new Map<string, CosmoDbContext>();
private static contexts: Map<string, CosmoDbContext> = new Map<string, CosmoDbContext>();
private constructor() {
// blcok to access from outside of this class
const getContext = (dirname: string): CosmoDbContext => {
let context = contexts.get(dirname);
if (typeof context === 'undefined') {
context = new CosmoDbContext(`/modules/${dirname}`);
contexts.set(dirname, context);
}
return context;
};
public static getContext(modulepath: string): CosmoDbContext {
let context = this.contexts.get(modulepath);
if (typeof context === 'undefined') {
context = new CosmoDbContext(modulepath);
this.contexts.set(modulepath, context);
}
return context;
const getThumbnailSize = (paramSize: string | null, thumbSize: string) => {
const options = thumbSize.split(';').map((value) => value.split(','));
if (options.length === 0 || options.filter((value) => value.length !== 4).length !== 0) {
return null;
}
const size = paramSize === null ? options[0][0] : paramSize;
const option = options.find((value) => value[0] === size);
if (typeof option === 'undefined') {
return null;
}
const imgWidth = /^\d+$/.test(option[1]) ? parseInt(option[1], 10) : 0;
const imgHeight = /^\d+$/.test(option[2]) ? parseInt(option[2], 10) : 0;
const maxCol = /^\d+$/.test(option[3]) ? parseInt(option[3], 10) : 0;
if (imgHeight < 0 || imgWidth < 0 || maxCol <= 0) {
return null;
}
return {
name: option[0],
height: imgHeight,
width: imgWidth,
maxCol: maxCol,
};
};
public static getThumbnailSize(paramSize: string | null, thumbSize: string) {
const options = thumbSize.split(';').map((value) => { return value.split(','); });
if (options.length === 0 || options.filter((value) => { return value.length !== 4; }).length !== 0) {
return null;
}
const size = paramSize === null ? options[0][0] : paramSize;
const option = options.find((value) => { return value[0] === size; });
if (typeof option === 'undefined') {
return null;
}
const imgWidth = /^\d+$/.test(option[1]) ? parseInt(option[1]) : 0;
const imgHeight = /^\d+$/.test(option[2]) ? parseInt(option[2]) : 0;
const maxCol = /^\d+$/.test(option[3]) ? parseInt(option[3]) : 0;
if (imgHeight < 0 || imgWidth < 0 || maxCol <= 0) {
return null;
}
return {
name: option[0],
height: imgHeight,
width: imgWidth,
maxCol: maxCol,
}
}
}
const CosmoDbUtils = {
getContext,
getThumbnailSize,
};
export default CosmoDbUtils;
+27 -29
View File
@@ -1,7 +1,6 @@
import React from 'react';
import { Redirect, Route, RouteComponentProps, Switch } from 'react-router-dom';
import { Navigate, Route, Routes, useLocation } from 'react-router';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import CreditsIndex from './CreditsIndex';
import CreditsPage from './CreditsPage';
@@ -9,35 +8,34 @@ interface Props {
lang: MultiLang;
}
const CreditsTop = (props: Props) => {
const { lang } = props;
const { search } = useLocation();
const paramId = new URLSearchParams(search).get('id');
if (paramId === null) {
return <CreditsIndex lang={lang} />;
}
if (/^[1-9][0-9]*$/.test(paramId)) {
return <CreditsPage lang={lang} id={parseInt(paramId, 10)} />;
}
return <PageNotFound lang={lang} />;
};
const CreditsRedirect = () => {
const { search, hash } = useLocation();
return <Navigate to={`/modules/credits/index.php${search}${hash}`} replace />;
};
const Credits = (props: Props) => {
const { lang } = props;
const pathname = '/modules/credits';
return (
<>
<Switch>
<Route exact path={`${pathname}/index.php`} render={(props: RouteComponentProps) => {
const { location } = props;
const params = new URLSearchParams(location.search);
const paramId = params.get('id');
if (null === paramId) {
return <CreditsIndex lang={lang} />;
}
if (/^[1-9][0-9]*$/.test(paramId)) {
const id = parseInt(paramId, 10);
return <CreditsPage lang={lang} id={id} />;
}
return <PageNotFound lang={lang} />;
}} />
<Route exact path={`${pathname}/aboutus.php`} render={() => <CreditsPage lang={lang} id={0} />} />
<Route exact path={pathname} render={(props: RouteComponentProps) => {
const { location } = props;
const url = pathname + '/index.php' + location.search + location.hash;
return <Redirect to={url} />
}} />
<Route component={PageNotFound} />
</Switch>
</>
<Routes>
<Route index element={<CreditsRedirect />} />
<Route path="index.php" element={<CreditsTop lang={lang} />} />
<Route path="aboutus.php" element={<CreditsPage lang={lang} id={0} />} />
<Route path="*" element={<PageNotFound lang={lang} />} />
</Routes>
);
}
};
export default Credits;
+42 -68
View File
@@ -1,84 +1,58 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import { Helmet } from '@dr.pogodin/react-helmet';
import { useEffect, useState } from 'react';
import { Link } from 'react-router';
import Loading from '../common/lib/Loading';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import CreditsUtils, { CreditsIndexData } from './lib/CreditsUtils';
import CreditsUtils, { type CreditsIndexData } from './lib/CreditsUtils';
interface Props {
lang: MultiLang;
}
interface State {
loading: boolean;
index: CreditsIndexData | null;
}
const CreditsIndex = (props: Props) => {
const { lang } = props;
const [index, setIndex] = useState<CreditsIndexData | null | undefined>(undefined);
class CreditsIndex extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
index: null,
useEffect(() => {
let active = true;
CreditsUtils.getIndex().then((index) => {
if (active) {
setIndex(index);
}
});
return () => {
active = false;
};
}
}, []);
componentDidMount() {
this.isActive = true;
this.updatePage();
if (typeof index === 'undefined') {
return <Loading />;
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang } = this.props;
if (prevProps.lang !== lang) {
this.updatePage();
}
if (index === null) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(index.name, lang);
return (
<>
<Helmet>
<title>
{mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<ul>
{index.pages.map((page) => (
<li key={page.id}>
<Link to={CreditsUtils.getPageUrl(page.id)}>{Functions.mlang(page.title, lang)}</Link>
</li>
))}
</ul>
</>
);
};
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
const index = await CreditsUtils.getIndex();
if (this.isActive) {
this.setState({ loading: false, index });
}
}
render() {
const { lang } = this.props;
if (this.state.loading) {
return <Loading />;
}
if (null === this.state.index) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(this.state.index.name, lang);
return (
<>
<Helmet>
<title>{mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<ul>
{this.state.index.pages.map((page) => {
const title = Functions.mlang(page.title, lang);
const url = CreditsUtils.getPageUrl(page.id);
return <li key={page.id}><Link to={url}>{title}</Link></li>;
})}
</ul>
</>
);
}
}
export default CreditsIndex;
+49 -66
View File
@@ -1,86 +1,69 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import { Helmet } from '@dr.pogodin/react-helmet';
import { format } from 'date-fns';
import { useEffect, useState } from 'react';
import Loading from '../common/lib/Loading';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import XoopsCode from '../common/lib/XoopsCode';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import CreditsUtils, { CreditsIndexData, CreditsPageDetailData } from './lib/CreditsUtils';
import CreditsUtils, { type CreditsIndexData, type CreditsPageDetailData } from './lib/CreditsUtils';
interface Props {
lang: MultiLang;
id: number;
}
interface State {
loading: boolean;
interface LoadedPage {
id: number;
index: CreditsIndexData | null;
page: CreditsPageDetailData | null;
}
class CreditsPage extends Component<Props, State> {
const CreditsPage = (props: Props) => {
const { lang, id } = props;
const [loaded, setLoaded] = useState<LoadedPage | null>(null);
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
index: null,
page: null
useEffect(() => {
let active = true;
Promise.all([CreditsUtils.getIndex(), CreditsUtils.getPage(id)]).then(([index, page]) => {
if (active) {
setLoaded({ id, index, page });
}
});
return () => {
active = false;
};
}
}, [id]);
componentDidMount() {
this.isActive = true;
this.updatePage();
if (loaded === null || loaded.id !== id) {
return <Loading />;
}
const { index, page } = loaded;
if (index === null || page === null) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(index.name, lang);
const title = Functions.mlang(page.title, lang);
const lastupdate = page.lastupdate === 0 ? '' : format(new Date(page.lastupdate * 1000), 'MMMM do, yyyy');
return (
<>
<Helmet>
<title>
{title} - {mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{title}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
{lastupdate !== '' && (
<div style={{ textAlign: 'right' }}>
{Functions.mlang('[en]Last Update[/en][ja]最終更新日[/ja]', lang)} : {lastupdate}
</div>
)}
<hr />
<XoopsCode lang={lang} text={page.content} dohtml={true} />
</>
);
};
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, id } = this.props;
if (prevProps.lang !== lang || prevProps.id !== id) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
const { id } = this.props;
const index = await CreditsUtils.getIndex();
const page = await CreditsUtils.getPage(id);
if (this.isActive) {
this.setState({ loading: false, index, page });
}
}
render() {
const { lang } = this.props;
if (this.state.loading) {
return <Loading />;
}
if (null === this.state.page || null === this.state.index) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(this.state.index.name, lang);
const title = Functions.mlang(this.state.page.title, lang);
const lastupdate = this.state.page.lastupdate === 0 ? '' : Functions.formatDate(this.state.page.lastupdate, 'MMMM Do, YYYY');
return (
<>
<Helmet>
<title>{title} - {mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{title}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
{'' !== lastupdate && <div style={{ textAlign: 'right' }}>{Functions.mlang('[en]Last Update[/en][ja]最終更新日[/ja]', lang)} : {lastupdate}</div>}
<hr />
<XoopsCode lang={lang} text={this.state.page.content} dohtml={true} />
</>
);
}
}
export default CreditsPage;
export default CreditsPage;
+19 -22
View File
@@ -1,4 +1,5 @@
import axios from 'axios';
import ky from 'ky';
import Config from '../../config';
export interface CreditsPageData {
id: number;
@@ -16,46 +17,42 @@ export interface CreditsIndexData {
}
class CreditsUtils {
private pathname: string;
private index?: CreditsIndexData | null;
private index: Promise<CreditsIndexData | null> | null = null;
constructor(path: string) {
this.pathname = path;
}
getIndexUrl(): string {
return this.pathname + '/';
return `${this.pathname}/`;
}
getPageUrl(id: number): string {
return this.getIndexUrl() + (0 === id ? 'aboutus.php' : ('?id=' + id));
return this.getIndexUrl() + (0 === id ? 'aboutus.php' : `?id=${id}`);
}
async getIndex(): Promise<CreditsIndexData | null> {
if (typeof this.index === 'undefined') {
try {
const url = this.getIndexUrl() + 'index.json';
const response = await axios.get(url);
const index = response.data as CreditsIndexData;
this.index = index;
} catch (err) {
this.index = null;
}
private getDataUrl(fname: string): URL {
return new URL(Config.BASE_URL + this.getIndexUrl() + fname, window.location.href);
}
/** Fetched once; concurrent callers share the request. */
getIndex(): Promise<CreditsIndexData | null> {
if (this.index === null) {
this.index = ky
.get(this.getDataUrl('index.json'))
.json<CreditsIndexData>()
.catch(() => null);
}
return this.index;
}
async getPage(id: number): Promise<CreditsPageDetailData | null> {
let page = null;
try {
const url = this.getIndexUrl() + id + '.json';
const response = await axios.get(url);
page = response.data as CreditsPageDetailData;
} catch (err) {
// ignore
return await ky.get(this.getDataUrl(`${id}.json`)).json<CreditsPageDetailData>();
} catch {
return null;
}
return page;
}
}
+3 -4
View File
@@ -1,16 +1,15 @@
import React from 'react';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
interface Props {
lang: MultiLang;
}
const Footer: React.FC<Props> = (props: Props) => {
const Footer = (_props: Props) => {
return (
<footer id="footer">
<span className="copyright">Copyright (C) 2018 Neuroinformatics Unit, RIKEN Center for Brain Science</span>
</footer>
);
}
};
export default Footer;
+358 -129
View File
@@ -1,140 +1,369 @@
import React, { Component } from 'react';
import { Link, RouteComponentProps, withRouter } from 'react-router-dom';
import { useState } from 'react';
import { Link } from 'react-router';
import LangFlag from '../common/lib/LangFlag';
import Config, { MultiLang } from '../config';
import Config, { type MultiLang } from '../config';
import Functions from '../functions';
import imageEnglish from './assets/images/mlang_english.png';
import imageJapanese from './assets/images/mlang_japanese.png';
interface Props extends RouteComponentProps {
interface Props {
lang: MultiLang;
}
interface State {
keyword: string;
menuid: number;
}
class Header extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
keyword: '',
menuid: 0
};
}
setMenuId(menuid: number) {
this.setState({ menuid });
}
render() {
const { lang } = this.props;
return (
<header id="header">
<div className="clearfix">
<Link className="logo" to="/"><span className="hidden">{Config.SITE_TITLE}</span></Link>
<div className="utility">
<LangFlag lang="en" image={imageJapanese} /> <LangFlag lang="ja" image={imageEnglish} />
</div>
const Header = (props: Props) => {
const { lang } = props;
const [menuid, setMenuId] = useState(0);
return (
<header id="header">
<div className="clearfix">
<Link className="logo" to="/">
<span className="hidden">{Config.SITE_TITLE}</span>
</Link>
<div className="utility">
<LangFlag lang="en" image={imageJapanese} /> <LangFlag lang="ja" image={imageEnglish} />
</div>
<nav className="menubar">
<ul className="mainmenu">
<li><Link to="/">{Functions.mlang('[en]HOME[/en][ja]ホーム[/ja]', lang)}</Link></li>
<li onMouseEnter={() => this.setMenuId(1)} onMouseLeave={() => this.setMenuId(0)}><Link to="/modules/htmldocs/IVBPF/Database/ivbpf.html">+ {Functions.mlang('[en]DATABASE[/en][ja]データベース[/ja]', lang)}</Link>
{1 === this.state.menuid &&
<div className="submenu">
<Link className="item" to="/modules/newdb10/list.php?id=2">{Functions.mlang('[en]Invertebrte Sensory System[/en][ja]無脊椎動物の感覚器[/ja]', lang)}</Link>
<Link className="item" to="/modules/newdb1/list.php?id=2">{Functions.mlang('[en]Invertebrate Brain Gallery[/en][ja]無脊椎動物脳ギャラリー[/ja]', lang)}</Link>
<Link className="item" to="/modules/newdb5/list.php?id=2">{Functions.mlang('[en]Silkmoth Brain and Neurons[/en][ja]カイコガの脳と神経[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/BombyxStandardBrain/index.html">{Functions.mlang('[en]Silkmoth Standard Brain[/en][ja]カイコガ標準脳[/ja]', lang)}</Link>
<Link className="item" to="/modules/newdb112/list.php?id=2">{Functions.mlang('[en]Honeybee Brain and Neurons[/en][ja]ミツバチの脳と神経[/ja]', lang)}</Link>
<Link className="item" to="/modules/newdb9/list.php?id=2">{Functions.mlang('[en]Cricket Brain and Neurons[/en][ja]コオロギの脳と神経[/ja]', lang)}</Link>
<Link className="item" to="/modules/newdb12/list.php?id=2">{Functions.mlang('[en]Fly Brain and Neurons[/en][ja]ハエの脳と神経[/ja]', lang)}</Link>
<Link className="item" to="/modules/newdb8/list.php?id=2">{Functions.mlang('[en]Cockroach Brain and Neurons[/en][ja]ゴキブリの脳と神経[/ja]', lang)}</Link>
<Link className="item" to="/modules/newdb3/list.php?id=2">{Functions.mlang('[en]Crayfish Brain and Neurons[/en][ja]ザリガニの脳と神経[/ja]', lang)}</Link>
<Link className="item" to="/modules/newdb7/list.php?id=2">{Functions.mlang('[en]Invertebrate Image and Movie[/en][ja]無脊椎動物の画像と映像[/ja]', lang)}</Link>
<Link className="item" to="/modules/newdb13/list.php?id=2">{Functions.mlang('[en]Lepidoptera Antennal Lobe[/en][ja]各種鱗翅目昆虫触角葉糸球体構造[/ja]', lang)}</Link>
<Link className="item" to="/modules/newdb2/list.php?id=2">{Functions.mlang('[en]Application Software[/en][ja]アプリケーションソフトウェア[/ja]', lang)}</Link>
<Link className="item" to="/modules/PubMedPDF/journal.php?journal=266">{Functions.mlang('[en]Conference Posters[/en][ja]研究発表ポスター[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Database/Experimental_set_ups.html">{Functions.mlang('[en]Measurement Instruments[/en][ja]計測装置の製作方法[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Education/education.html">{Functions.mlang('[en]Documents for Student Experiments[/en][ja]生物教育と実習テキスト[/ja]', lang)}</Link>
<Link className="item" to="/modules/PubMedPDF/">{Functions.mlang('[en]Reference and Textbooks[/en][ja]文献と教科書[/ja]', lang)}</Link>
</div>
}
</li>
<li onMouseEnter={() => this.setMenuId(2)} onMouseLeave={() => this.setMenuId(0)}><Link to="/modules/htmldocs/IVBPF/Science/insect_nervous_system.html">+ {Functions.mlang('[en]RESEARCH[/en][ja]研 究[/ja]', lang)}</Link>
{2 === this.state.menuid &&
<div className="submenu">
<Link className="item" to="/modules/htmldocs/IVBPF/Science/sensory-system.html">{Functions.mlang('[en]Sensory systems of insect[/en][ja]昆虫の感覚系[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/General/Insects_nervous_systems.html">{Functions.mlang('[en]Central nervous system of insects[/en][ja]昆虫の脳神経系[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/General/behavior.html">{Functions.mlang('[en]Animal and insect behavior[/en][ja]動物と昆虫の行動[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/General/methods.html">{Functions.mlang('[en]Methods for investigating neurons[/en][ja]昆虫のニューロンの調べ方[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Latest_topics/insect_robot_hybrid_system.html">{Functions.mlang('[en]Insect machine hybrid system[/en][ja]昆虫−ロボット融合システム(サイボーグ昆虫)[/ja]', lang)}</Link>
{'ja' === lang &&
<Link className="item" to="/modules/htmldocs/IVBPF/Science/multicompartment_model.html"></Link>
}
<Link className="item" to="/modules/htmldocs/IVBPF/Latest_topics/supercom.html">{Functions.mlang('[en]Reconstructing an insect brain using a next-generation super computer[/en][ja]昆虫脳を再構成する:次世代スーパーコンピュータ[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/kei/index.html">{Functions.mlang('[en]Resources of IOSSIM[/en][ja]IOSSIMの公開ページ[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Latest_topics/behavior_control.html">{Functions.mlang('[en]External control of insect behavior and neurorehabilitation[/en][ja]昆虫行動制御・神経回路修復[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Science/comparative-physiology.html">{Functions.mlang('[en]Comparative table of invertebrate[/en][ja]無脊椎動物脳比較表[/ja]', lang)}</Link>
</div>
}
</li>
<li onMouseEnter={() => this.setMenuId(3)} onMouseLeave={() => this.setMenuId(0)}><Link to="/modules/htmldocs/IVBPF/Engineering/Engineering_contents.html">+ {Functions.mlang('[en]APPLICATION[/en][ja]機能利用[/ja]', lang)}</Link>
{3 === this.state.menuid &&
<div className="submenu">
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Spider_strings.html">{Functions.mlang('[en]Materials: Spider Silk[/en][ja]材料:クモの糸[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Insect_kutikura.html">{Functions.mlang('[en]Materials: Insect Cuticle[/en][ja]材料:クチクラ[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Insect_wing_based_joint_robot.html">{Functions.mlang('[en]Materials: Insect Wing[/en][ja]材料:昆虫の翅の柔軟なロボット関節への応用[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/odor_sensor.html">{Functions.mlang('[en]Sensor: Odor Sensor[/en][ja]感覚システム:匂いセンサ[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/model_based_robot.html">{Functions.mlang('[en]Sensor: Odor-source Searching Robot[/en][ja]感覚システム:匂い源探索ロボット[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Artificial_sensor.html">{Functions.mlang('[en]Sensor: Flow sensor[/en][ja]感覚システム:人工感覚毛センサ[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Ant_based_optic_navigation_robot.html">{Functions.mlang('[en]Sensor: Visual navigation in the deseart ant[/en][ja]感覚システム:サバクアリの視覚ナビゲーション[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Cricket_sound_orientation_robot.html">{Functions.mlang('[en]Sensor: Sound orientation in the cricket[/en][ja]感覚システム:コオロギによる音源定位[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Fly_based_flight_robot.html">{Functions.mlang('[en]Robot control: A visually guided flight robot[/en][ja]ロボット制御:ハエにヒントを得た視覚誘導飛行ロボット[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Ocellar_based_flight_controller.html">{Functions.mlang('[en]Robot control: A flight-stabilization device based on ocelli[/en][ja]ロボット制御:単眼による飛行安定装置[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Insect_controlled_robot.html">{Functions.mlang('[en]Robot control: Insect controlled robot[/en][ja]ロボット制御:昆虫が操縦するロボット[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Insect_based_flight_robot.html">{Functions.mlang('[en]Robot control: An insect-based flying robot[/en][ja]ロボット制御:昆虫による飛行関連ロボット[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Insect_based_walking_robot.html">{Functions.mlang('[en]Robot control: Insect walking and a walking-controlled robot[/en][ja]ロボット制御:昆虫の歩行と歩行制御ロボット[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/biobot.html">{Functions.mlang('[en]Biobot[/en][ja]昆虫行動制御:昆虫の行動を遠隔で制御する[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Insect_based_construction_method.html">{Functions.mlang('[en]An architectural insecticide method based on insect traits[/en][ja]建築的防虫法:昆虫の習性に基づく建築的防虫法[/ja]', lang)}</Link>
</div>
}
</li>
<li onMouseEnter={() => this.setMenuId(4)} onMouseLeave={() => this.setMenuId(0)}><Link to="/modules/htmldocs/IVBPF/Education/education.html">+ {Functions.mlang('[en]EDUCATION[/en][ja]教 育[/ja]', lang)}</Link>
{4 === this.state.menuid && 'ja' === lang &&
<div className="submenu">
<Link className="item" to="/modules/htmldocs/IVBPF/outreach/index.html"></Link>
<Link className="item" to="/modules/noneLectClass/"></Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Education/experiments/index.html"></Link>
<Link className="item" to="/modules/htmldocs/IVBPF/outreach/museum.html"></Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Education/Experimental_set_ups.html"></Link>
</div>
}
</li>
<li onMouseEnter={() => this.setMenuId(5)} onMouseLeave={() => this.setMenuId(0)}><span>+ {Functions.mlang('[en]REFERENCE[/en][ja]リファレンス[/ja]', lang)}</span>
{5 === this.state.menuid &&
<div className="submenu">
<Link className="item" to="/modules/xwords/index.php">{Functions.mlang('[en]Glossary[/en][ja]用語集[/ja]', lang)}</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Science/comparative-physiology.html">{Functions.mlang('[en]Comparative Table[/en][ja]無脊椎動物脳比較表[/ja]', lang)}</Link>
</div>
}
</li>
</div>
<nav className="menubar">
<ul className="mainmenu">
<li>
<Link to="/">{Functions.mlang('[en]HOME[/en][ja]ホーム[/ja]', lang)}</Link>
</li>
<li onMouseEnter={() => setMenuId(1)} onMouseLeave={() => setMenuId(0)}>
<Link to="/modules/htmldocs/IVBPF/Database/ivbpf.html">
+ {Functions.mlang('[en]DATABASE[/en][ja]データベース[/ja]', lang)}
</Link>
{1 === menuid && (
<div className="submenu">
<Link className="item" to="/modules/newdb10/list.php?id=2">
{Functions.mlang(
'[en]Invertebrte Sensory System[/en][ja]無脊椎動物の感覚器[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/newdb1/list.php?id=2">
{Functions.mlang(
'[en]Invertebrate Brain Gallery[/en][ja]無脊椎動物脳ギャラリー[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/newdb5/list.php?id=2">
{Functions.mlang(
'[en]Silkmoth Brain and Neurons[/en][ja]カイコガの脳と神経[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/BombyxStandardBrain/index.html">
{Functions.mlang('[en]Silkmoth Standard Brain[/en][ja]カイコガ標準脳[/ja]', lang)}
</Link>
<Link className="item" to="/modules/newdb112/list.php?id=2">
{Functions.mlang(
'[en]Honeybee Brain and Neurons[/en][ja]ミツバチの脳と神経[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/newdb9/list.php?id=2">
{Functions.mlang(
'[en]Cricket Brain and Neurons[/en][ja]コオロギの脳と神経[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/newdb12/list.php?id=2">
{Functions.mlang('[en]Fly Brain and Neurons[/en][ja]ハエの脳と神経[/ja]', lang)}
</Link>
<Link className="item" to="/modules/newdb8/list.php?id=2">
{Functions.mlang(
'[en]Cockroach Brain and Neurons[/en][ja]ゴキブリの脳と神経[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/newdb3/list.php?id=2">
{Functions.mlang(
'[en]Crayfish Brain and Neurons[/en][ja]ザリガニの脳と神経[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/newdb7/list.php?id=2">
{Functions.mlang(
'[en]Invertebrate Image and Movie[/en][ja]無脊椎動物の画像と映像[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/newdb13/list.php?id=2">
{Functions.mlang(
'[en]Lepidoptera Antennal Lobe[/en][ja]各種鱗翅目昆虫触角葉糸球体構造[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/newdb2/list.php?id=2">
{Functions.mlang(
'[en]Application Software[/en][ja]アプリケーションソフトウェア[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/PubMedPDF/journal.php?journal=266">
{Functions.mlang('[en]Conference Posters[/en][ja]研究発表ポスター[/ja]', lang)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Database/Experimental_set_ups.html">
{Functions.mlang(
'[en]Measurement Instruments[/en][ja]計測装置の製作方法[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Education/education.html">
{Functions.mlang(
'[en]Documents for Student Experiments[/en][ja]生物教育と実習テキスト[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/PubMedPDF/">
{Functions.mlang('[en]Reference and Textbooks[/en][ja]文献と教科書[/ja]', lang)}
</Link>
</div>
)}
</li>
<li onMouseEnter={() => setMenuId(2)} onMouseLeave={() => setMenuId(0)}>
<Link to="/modules/htmldocs/IVBPF/Science/insect_nervous_system.html">
+ {Functions.mlang('[en]RESEARCH[/en][ja]研 究[/ja]', lang)}
</Link>
{2 === menuid && (
<div className="submenu">
<Link className="item" to="/modules/htmldocs/IVBPF/Science/sensory-system.html">
{Functions.mlang('[en]Sensory systems of insect[/en][ja]昆虫の感覚系[/ja]', lang)}
</Link>
<Link
className="item"
to="/modules/htmldocs/IVBPF/General/Insects_nervous_systems.html"
>
{Functions.mlang(
'[en]Central nervous system of insects[/en][ja]昆虫の脳神経系[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/General/behavior.html">
{Functions.mlang(
'[en]Animal and insect behavior[/en][ja]動物と昆虫の行動[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/General/methods.html">
{Functions.mlang(
'[en]Methods for investigating neurons[/en][ja]昆虫のニューロンの調べ方[/ja]',
lang
)}
</Link>
<Link
className="item"
to="/modules/htmldocs/IVBPF/Latest_topics/insect_robot_hybrid_system.html"
>
{Functions.mlang(
'[en]Insect machine hybrid system[/en][ja]昆虫−ロボット融合システム(サイボーグ昆虫)[/ja]',
lang
)}
</Link>
{'ja' === lang && (
<Link
className="item"
to="/modules/htmldocs/IVBPF/Science/multicompartment_model.html"
>
</Link>
)}
<Link className="item" to="/modules/htmldocs/IVBPF/Latest_topics/supercom.html">
{Functions.mlang(
'[en]Reconstructing an insect brain using a next-generation super computer[/en][ja]昆虫脳を再構成する:次世代スーパーコンピュータ[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/kei/index.html">
{Functions.mlang('[en]Resources of IOSSIM[/en][ja]IOSSIMの公開ページ[/ja]', lang)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Latest_topics/behavior_control.html">
{Functions.mlang(
'[en]External control of insect behavior and neurorehabilitation[/en][ja]昆虫行動制御・神経回路修復[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Science/comparative-physiology.html">
{Functions.mlang(
'[en]Comparative table of invertebrate[/en][ja]無脊椎動物脳比較表[/ja]',
lang
)}
</Link>
</div>
)}
</li>
<li onMouseEnter={() => setMenuId(3)} onMouseLeave={() => setMenuId(0)}>
<Link to="/modules/htmldocs/IVBPF/Engineering/Engineering_contents.html">
+ {Functions.mlang('[en]APPLICATION[/en][ja]機能利用[/ja]', lang)}
</Link>
{3 === menuid && (
<div className="submenu">
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Spider_strings.html">
{Functions.mlang('[en]Materials: Spider Silk[/en][ja]材料:クモの糸[/ja]', lang)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Insect_kutikura.html">
{Functions.mlang('[en]Materials: Insect Cuticle[/en][ja]材料:クチクラ[/ja]', lang)}
</Link>
<Link
className="item"
to="/modules/htmldocs/IVBPF/Engineering/Insect_wing_based_joint_robot.html"
>
{Functions.mlang(
'[en]Materials: Insect Wing[/en][ja]材料:昆虫の翅の柔軟なロボット関節への応用[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/odor_sensor.html">
{Functions.mlang(
'[en]Sensor: Odor Sensor[/en][ja]感覚システム:匂いセンサ[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/model_based_robot.html">
{Functions.mlang(
'[en]Sensor: Odor-source Searching Robot[/en][ja]感覚システム:匂い源探索ロボット[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/Artificial_sensor.html">
{Functions.mlang(
'[en]Sensor: Flow sensor[/en][ja]感覚システム:人工感覚毛センサ[/ja]',
lang
)}
</Link>
<Link
className="item"
to="/modules/htmldocs/IVBPF/Engineering/Ant_based_optic_navigation_robot.html"
>
{Functions.mlang(
'[en]Sensor: Visual navigation in the deseart ant[/en][ja]感覚システム:サバクアリの視覚ナビゲーション[/ja]',
lang
)}
</Link>
<Link
className="item"
to="/modules/htmldocs/IVBPF/Engineering/Cricket_sound_orientation_robot.html"
>
{Functions.mlang(
'[en]Sensor: Sound orientation in the cricket[/en][ja]感覚システム:コオロギによる音源定位[/ja]',
lang
)}
</Link>
<Link
className="item"
to="/modules/htmldocs/IVBPF/Engineering/Fly_based_flight_robot.html"
>
{Functions.mlang(
'[en]Robot control: A visually guided flight robot[/en][ja]ロボット制御:ハエにヒントを得た視覚誘導飛行ロボット[/ja]',
lang
)}
</Link>
<Link
className="item"
to="/modules/htmldocs/IVBPF/Engineering/Ocellar_based_flight_controller.html"
>
{Functions.mlang(
'[en]Robot control: A flight-stabilization device based on ocelli[/en][ja]ロボット制御:単眼による飛行安定装置[/ja]',
lang
)}
</Link>
<Link
className="item"
to="/modules/htmldocs/IVBPF/Engineering/Insect_controlled_robot.html"
>
{Functions.mlang(
'[en]Robot control: Insect controlled robot[/en][ja]ロボット制御:昆虫が操縦するロボット[/ja]',
lang
)}
</Link>
<Link
className="item"
to="/modules/htmldocs/IVBPF/Engineering/Insect_based_flight_robot.html"
>
{Functions.mlang(
'[en]Robot control: An insect-based flying robot[/en][ja]ロボット制御:昆虫による飛行関連ロボット[/ja]',
lang
)}
</Link>
<Link
className="item"
to="/modules/htmldocs/IVBPF/Engineering/Insect_based_walking_robot.html"
>
{Functions.mlang(
'[en]Robot control: Insect walking and a walking-controlled robot[/en][ja]ロボット制御:昆虫の歩行と歩行制御ロボット[/ja]',
lang
)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Engineering/biobot.html">
{Functions.mlang(
'[en]Biobot[/en][ja]昆虫行動制御:昆虫の行動を遠隔で制御する[/ja]',
lang
)}
</Link>
<Link
className="item"
to="/modules/htmldocs/IVBPF/Engineering/Insect_based_construction_method.html"
>
{Functions.mlang(
'[en]An architectural insecticide method based on insect traits[/en][ja]建築的防虫法:昆虫の習性に基づく建築的防虫法[/ja]',
lang
)}
</Link>
</div>
)}
</li>
<li onMouseEnter={() => setMenuId(4)} onMouseLeave={() => setMenuId(0)}>
<Link to="/modules/htmldocs/IVBPF/Education/education.html">
+ {Functions.mlang('[en]EDUCATION[/en][ja]教 育[/ja]', lang)}
</Link>
{4 === menuid && 'ja' === lang && (
<div className="submenu">
<Link className="item" to="/modules/htmldocs/IVBPF/outreach/index.html">
</Link>
<Link className="item" to="/modules/noneLectClass/">
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Education/experiments/index.html">
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/outreach/museum.html">
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Education/Experimental_set_ups.html">
</Link>
</div>
)}
</li>
<li onMouseEnter={() => setMenuId(5)} onMouseLeave={() => setMenuId(0)}>
<span>+ {Functions.mlang('[en]REFERENCE[/en][ja]リファレンス[/ja]', lang)}</span>
{5 === menuid && (
<div className="submenu">
<Link className="item" to="/modules/xwords/index.php">
{Functions.mlang('[en]Glossary[/en][ja]用語集[/ja]', lang)}
</Link>
<Link className="item" to="/modules/htmldocs/IVBPF/Science/comparative-physiology.html">
{Functions.mlang('[en]Comparative Table[/en][ja]無脊椎動物脳比較表[/ja]', lang)}
</Link>
</div>
)}
</li>
<li onMouseEnter={() => this.setMenuId(6)} onMouseLeave={() => this.setMenuId(0)}><span>+ {Functions.mlang('[en]INFORMATION[/en][ja]情 報[/ja]', lang)}</span>
{6 === this.state.menuid &&
<div className="submenu">
<Link className="item" to="/modules/credits/index.php">{Functions.mlang('[en]About This Site[/en][ja]このサイトについて[/ja]', lang)}</Link>
</div>
}
</li>
</ul>
</nav>
</header>
);
<li onMouseEnter={() => setMenuId(6)} onMouseLeave={() => setMenuId(0)}>
<span>+ {Functions.mlang('[en]INFORMATION[/en][ja]情 報[/ja]', lang)}</span>
{6 === menuid && (
<div className="submenu">
<Link className="item" to="/modules/credits/index.php">
{Functions.mlang('[en]About This Site[/en][ja]このサイトについて[/ja]', lang)}
</Link>
</div>
)}
</li>
</ul>
</nav>
</header>
);
};
}
}
export default withRouter(Header);
export default Header;
+72 -49
View File
@@ -1,7 +1,6 @@
import React from 'react';
import { Redirect, Route, Switch } from 'react-router-dom';
import { Navigate, Route, Routes } from 'react-router';
import XoopsPathRedirect from '../common/XoopsPathRedirect';
import { MultiLang } from '../config';
import Config, { type MultiLang } from '../config';
import CosmoDb from '../cosmodb/CosmoDb';
import Credits from '../credits/Credits';
import Pico from '../pico/Pico';
@@ -15,54 +14,78 @@ interface Props {
lang: MultiLang;
}
const Page: React.FC<Props> = (props: Props) => {
const TOP_URL = '/modules/htmldocs/IVBPF/Top/index.html';
const COSMODB_MODULES = [
'newdb1',
'newdb2',
'newdb3',
'newdb5',
'newdb7',
'newdb8',
'newdb9',
'newdb10',
'newdb112',
'newdb12',
'newdb13',
];
const Page = (props: Props) => {
const { lang } = props;
const url = '/modules/htmldocs/IVBPF/Top/index.html';
return <div id="page">
<Header lang={lang} />
<div id="main">
<Switch>
<Route path="/modules/newdb1" render={() => <CustomBlock lang={lang} modulepath="/modules/newdb1" />} />
<Route path="/modules/newdb2" render={() => <CustomBlock lang={lang} modulepath="/modules/newdb2" />} />
<Route path="/modules/newdb3" render={() => <CustomBlock lang={lang} modulepath="/modules/newdb3" />} />
<Route path="/modules/newdb5" render={() => <CustomBlock lang={lang} modulepath="/modules/newdb5" />} />
<Route path="/modules/newdb7" render={() => <CustomBlock lang={lang} modulepath="/modules/newdb7" />} />
<Route path="/modules/newdb8" render={() => <CustomBlock lang={lang} modulepath="/modules/newdb8" />} />
<Route path="/modules/newdb9" render={() => <CustomBlock lang={lang} modulepath="/modules/newdb9" />} />
<Route path="/modules/newdb10" render={() => <CustomBlock lang={lang} modulepath="/modules/newdb10" />} />
<Route path="/modules/newdb112" render={() => <CustomBlock lang={lang} modulepath="/modules/newdb112" />} />
<Route path="/modules/newdb12" render={() => <CustomBlock lang={lang} modulepath="/modules/newdb12" />} />
<Route path="/modules/newdb13" render={() => <CustomBlock lang={lang} modulepath="/modules/newdb13" />} />
<Route path="/modules/noneLectClass" render={() => <CustomBlock lang={lang} modulepath="/modules/noneLectClass" />} />
</Switch>
<div className="mainContent">
<Switch>
<Route exact path="/" render={() => <Redirect to={url} />} />
<Route path="/modules/htmldocs/index.html" render={() => <Redirect to={url} />} />
<Route path="/modules/htmldocs/IVBPF/index.html" render={() => <Redirect to={url} />} />
<Route path="/modules/htmldocs" render={() => <Pico lang={lang} modulepath="/modules/htmldocs" showTitle={false} />} />
<Route path="/modules/documents" render={() => <Pico lang={lang} modulepath="/modules/documents" showTitle={false} />} />
<Route path="/modules/newdb1" render={() => <CosmoDb lang={lang} modulepath="/modules/newdb1" />} />
<Route path="/modules/newdb2" render={() => <CosmoDb lang={lang} modulepath="/modules/newdb2" />} />
<Route path="/modules/newdb3" render={() => <CosmoDb lang={lang} modulepath="/modules/newdb3" />} />
<Route path="/modules/newdb5" render={() => <CosmoDb lang={lang} modulepath="/modules/newdb5" />} />
<Route path="/modules/newdb7" render={() => <CosmoDb lang={lang} modulepath="/modules/newdb7" />} />
<Route path="/modules/newdb8" render={() => <CosmoDb lang={lang} modulepath="/modules/newdb8" />} />
<Route path="/modules/newdb9" render={() => <CosmoDb lang={lang} modulepath="/modules/newdb9" />} />
<Route path="/modules/newdb10" render={() => <CosmoDb lang={lang} modulepath="/modules/newdb10" />} />
<Route path="/modules/newdb112" render={() => <CosmoDb lang={lang} modulepath="/modules/newdb112" />} />
<Route path="/modules/newdb12" render={() => <CosmoDb lang={lang} modulepath="/modules/newdb12" />} />
<Route path="/modules/newdb13" render={() => <CosmoDb lang={lang} modulepath="/modules/newdb13" />} />
<Route path="/modules/credits" render={() => <Credits lang={lang} />} />
<Route path="/modules/PubMedPDF" render={() => <PubmedPdf lang={lang} />} />
<Route path="/modules/xwords" render={() => <Xwords lang={lang} />} />
<Route path="/modules/noneLectClass" render={() => <div>: <a href="http://www.brain.rcast.u-tokyo.ac.jp/others/2010-jinseiken/100131-jinseiken-text.pdf">100131-jinseiken-text.pdf</a></div>} />
<Route component={XoopsPathRedirect} />
</Switch>
return (
<div id="page">
<Header lang={lang} />
<div id="main">
<Routes>
{[...COSMODB_MODULES, 'noneLectClass'].map((dirname) => (
<Route
key={dirname}
path={`/modules/${dirname}/*`}
element={<CustomBlock lang={lang} modulepath={`/modules/${dirname}`} />}
/>
))}
<Route path="*" element={null} />
</Routes>
<div className="mainContent">
<Routes>
<Route index element={<Navigate to={TOP_URL} replace />} />
<Route path="/modules/htmldocs/index.html" element={<Navigate to={TOP_URL} replace />} />
<Route path="/modules/htmldocs/IVBPF/index.html" element={<Navigate to={TOP_URL} replace />} />
{Config.PICO_MODULES.map((dirname) => (
<Route
key={dirname}
path={`/modules/${dirname}/*`}
element={<Pico lang={lang} dirname={dirname} />}
/>
))}
{COSMODB_MODULES.map((dirname) => (
<Route
key={dirname}
path={`/modules/${dirname}/*`}
element={<CosmoDb lang={lang} dirname={dirname} />}
/>
))}
<Route path="/modules/credits/*" element={<Credits lang={lang} />} />
<Route path="/modules/PubMedPDF/*" element={<PubmedPdf lang={lang} />} />
<Route path="/modules/xwords/*" element={<Xwords lang={lang} />} />
<Route
path="/modules/noneLectClass/*"
element={
<div>
:{' '}
<a href="http://www.brain.rcast.u-tokyo.ac.jp/others/2010-jinseiken/100131-jinseiken-text.pdf">
100131-jinseiken-text.pdf
</a>
</div>
}
/>
<Route path="*" element={<XoopsPathRedirect lang={lang} />} />
</Routes>
</div>
</div>
<Footer lang={lang} />
</div>
<Footer lang={lang} />
</div>;
}
);
};
export default Page;
+116 -117
View File
@@ -1,22 +1,22 @@
*,
*::before,
*::after {
box-sizing: border-box;
box-sizing: border-box;
}
html,
body,
#root {
width: 100%;
min-width: 880px;
width: 100%;
min-width: 880px;
}
body {
font-family: Arial, Helvetica, sans-serif;
color: #000000;
background-color: #c6c6c6;
margin: 0;
font-size: 90%;
font-family: Arial, Helvetica, sans-serif;
color: #000000;
background-color: #c6c6c6;
margin: 0;
font-size: 90%;
}
h1,
@@ -25,242 +25,241 @@ h3,
h4,
h5,
h6 {
font-family: Georgia, "Times New Roman", Times, serif;
margin-bottom: 0.5rem;
font-weight: bold;
line-height: 1.2;
color: inherit;
font-family: Georgia, "Times New Roman", Times, serif;
margin-bottom: 0.5rem;
font-weight: bold;
line-height: 1.2;
color: inherit;
}
h1 {
font-size: 1.802em;
font-size: 1.802em;
}
h2 {
font-size: 1.602em;
font-size: 1.602em;
}
h3 {
font-size: 1.424em;
font-size: 1.424em;
}
h4 {
font-size: 1.266em;
font-size: 1.266em;
}
h5 {
font-size: 1.125em;
font-size: 1.125em;
}
h6 {
font-size: 1em;
font-size: 1em;
}
a {
color: #333333;
text-decoration: none;
color: #333333;
text-decoration: none;
}
a:hover {
color: #ff6600;
text-decoration: underline;
color: #ff6600;
text-decoration: underline;
}
table {
width: 100%;
width: 100%;
}
td,
th {
padding: 10px;
padding: 10px;
}
th,
td,
.head {
vertical-align: top;
vertical-align: top;
}
.foot {
vertical-align: middle;
vertical-align: middle;
}
th,
.head,
.foot {
font-weight: bold;
background-color: #cee1eb;
font-weight: bold;
background-color: #cee1eb;
}
.even {
background-color: #eff4f9;
background-color: #eff4f9;
}
.odd {
background-color: #f5f7f7;
background-color: #f5f7f7;
}
.clearfix::after {
content: "";
display: block;
clear: both;
content: "";
display: block;
clear: both;
}
.hidden {
display: none;
display: none;
}
.text-center {
text-align: center;
text-align: center;
}
.text-left {
text-align: left;
text-align: left;
}
.text-right {
text-align: right;
text-align: right;
}
.font-weight-bold {
font-weight: bold;
font-weight: bold;
}
.font-italic {
font-style: italic;
font-style: italic;
}
.block .blockTitle {
padding: 5px 10px;
color: #ffffff;
background: #802d2d;
font-weight: bold;
padding: 5px 10px;
color: #ffffff;
background: #802d2d;
font-weight: bold;
}
.block .blockContent {
border-left: 1px solid#cccccc;
border-right: 1px solid #cccccc;
border-bottom: 1px solid #dddddd;
padding: 3px;
margin-bottom: 8px;
border-left: 1px solid #cccccc;
border-right: 1px solid #cccccc;
border-bottom: 1px solid #dddddd;
padding: 3px;
margin-bottom: 8px;
}
#page {
margin: 5px 15px;
margin: 5px 15px;
}
#header {
color: #ffffff;
background-color: #802d2d;
color: #ffffff;
background-color: #802d2d;
}
#header .logo {
float: left;
display: block;
height: 40px;
width: 180px;
background-image: url(images/logo.png);
float: left;
display: block;
height: 40px;
width: 180px;
background-image: url(images/logo.png);
}
#header .utility {
float: right;
padding-top: 7px;
padding-right: 15px;
float: right;
padding-top: 7px;
padding-right: 15px;
}
#header .menubar {
height: 22px;
border-top: 1px solid #000000;
border-bottom: 1px solid #000000;
background-color: #464646;
color: #ffffff;
height: 22px;
border-top: 1px solid #000000;
border-bottom: 1px solid #000000;
background-color: #464646;
color: #ffffff;
}
#header .mainmenu {
margin: 0;
padding: 0;
list-style-type: none;
margin: 0;
padding: 0;
list-style-type: none;
}
#header .mainmenu li {
margin: 0 10px;
line-height: 20px;
font-size: 0.8em;
width: 100px;
display: inline-block;
text-align: left;
font-weight: bold;
margin: 0 10px;
line-height: 20px;
font-size: 0.8em;
width: 100px;
display: inline-block;
text-align: left;
font-weight: bold;
}
#header .mainmenu li:first-child {
text-align: center;
text-align: center;
}
#header .mainmenu li>a,
#header .mainmenu li>span {
display: inline-block;
width: 100%;
color: #ffffff;
background-color: #464646;
text-decoration: none;
#header .mainmenu li > a,
#header .mainmenu li > span {
display: inline-block;
width: 100%;
color: #ffffff;
background-color: #464646;
text-decoration: none;
}
#header .mainmenu li>a:hover,
#header .mainmenu li>span:hover {
background-color: #6f6f6f;
#header .mainmenu li > a:hover,
#header .mainmenu li > span:hover {
background-color: #6f6f6f;
}
#header .mainmenu .submenu {
position: relative;
float: left;
background-color: lightyellow;
border: 1px solid #000000;
z-index: 10;
animation: fadeIn 1s ease 0s 1 normal;
position: relative;
float: left;
background-color: lightyellow;
border: 1px solid #000000;
z-index: 10;
animation: fadeIn 1s ease 0s 1 normal;
}
@keyframes fadeIn {
0% {
opacity: 0;
}
0% {
opacity: 0;
}
100% {
opacity: 1;
}
100% {
opacity: 1;
}
}
#header .mainmenu .submenu .item {
display: block;
padding: 1px 5px;
white-space: nowrap;
text-decoration: none;
display: block;
padding: 1px 5px;
white-space: nowrap;
text-decoration: none;
}
#header .mainmenu .submenu .item:not(:first-child) {
border-top: 1px solid #000000;
border-top: 1px solid #000000;
}
#header .mainmenu .submenu .item:hover {
background-color: yellow;
background-color: yellow;
}
#footer {
height: 42px;
border-top: 2px solid #000000;
color: #ffffff;
background-color: #802d2d;
text-align: center;
height: 42px;
border-top: 2px solid #000000;
color: #ffffff;
background-color: #802d2d;
text-align: center;
}
#footer .copyright {
line-height: 38px;
display: block;
font-size: 90%;
line-height: 38px;
display: block;
font-size: 90%;
}
#main {
background-color: #ffffff;
padding: 15px;
min-height: 500px;
}
background-color: #ffffff;
padding: 15px;
min-height: 500px;
}
+36 -21
View File
@@ -1,6 +1,5 @@
import React from 'react';
import XoopsCode from '../../common/lib/XoopsCode';
import { MultiLang } from '../../config';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
interface Props {
@@ -12,75 +11,91 @@ const contents = [
{
modulepath: '/modules/newdb1',
title: '[en]Invertebrate Brain Gallery[/en][ja]無脊椎動物脳ギャラリー[/ja]',
content: '<p>[en]Many invertebrate animals have evolved a rich variety of brains (head ganglia). Unusually large brains of squids and octopuses and small but sophisticated brains of arthropods, especially those of insects, are among the most fascinating brains created on earth by natural selection. Here, photographs of invertebrates of 6 phyla, 35 orders and 47 species and those of their central nervous systems are presented, with brief explanations of their characteristics. Enjoy seeing the pictures and consider evolution of brains in invertebrates. These images can be only used for research and education freely. Providers (Dr. Makoto Mizunami) have copyright for images and documents. [/en][ja]脳を持つ動物は脊椎動物だけではありません。多くの無脊椎動物は、実に多様な脳を発達させています。イカやタコの哺乳類に匹敵するほどの巨大な脳や、節足動物、特に昆虫の小さく精巧な脳は、自然選択が生み出した脳のなかでも最も興味深いものの1つと言えます。ここでは、6門、35目、47種の無脊椎動物とその脳および中枢神経系全体の取り出し標本の写真を展示し、解説しています。画像を見ながら、脳の進化について考えるとよいでしょう。  これらの画像は、教育、研究のためには自由に利用することができます。なお、画像、文章の著作権は、提供者(北海道大学・水波誠)にあります。 [/ja]</p>',
content:
'<p>[en]Many invertebrate animals have evolved a rich variety of brains (head ganglia). Unusually large brains of squids and octopuses and small but sophisticated brains of arthropods, especially those of insects, are among the most fascinating brains created on earth by natural selection. Here, photographs of invertebrates of 6 phyla, 35 orders and 47 species and those of their central nervous systems are presented, with brief explanations of their characteristics. Enjoy seeing the pictures and consider evolution of brains in invertebrates. These images can be only used for research and education freely. Providers (Dr. Makoto Mizunami) have copyright for images and documents. [/en][ja]脳を持つ動物は脊椎動物だけではありません。多くの無脊椎動物は、実に多様な脳を発達させています。イカやタコの哺乳類に匹敵するほどの巨大な脳や、節足動物、特に昆虫の小さく精巧な脳は、自然選択が生み出した脳のなかでも最も興味深いものの1つと言えます。ここでは、6門、35目、47種の無脊椎動物とその脳および中枢神経系全体の取り出し標本の写真を展示し、解説しています。画像を見ながら、脳の進化について考えるとよいでしょう。  これらの画像は、教育、研究のためには自由に利用することができます。なお、画像、文章の著作権は、提供者(北海道大学・水波誠)にあります。 [/ja]</p>',
},
{
modulepath: '/modules/newdb2',
title: '[en]Application software[/en][ja]アプリケーションソフトウェア[/ja]',
content: '<p>Information and URL for application software can be used in the invertebrate neuroethology are presented.</p>',
content:
'<p>Information and URL for application software can be used in the invertebrate neuroethology are presented.</p>',
},
{
modulepath: '/modules/newdb3',
title: '[en]Crayfish Brain and Neurons[/en][ja]ザリガニの脳と神経[/ja]',
content: '<p>Experimental data, such as confocal images by laser scanning microscope and electrical responses to the pheromone stimulus are presented. Providers (*) have copyright for images and documents.</p>',
content:
'<p>Experimental data, such as confocal images by laser scanning microscope and electrical responses to the pheromone stimulus are presented. Providers (*) have copyright for images and documents.</p>',
},
{
modulepath: '/modules/newdb5',
title: '[en]Bombyx Brain and Neurons[/en][ja]カイコガの脳・神経細胞データ[/ja]',
content: '<p>[en]Experimental data, such as confocal images by laser scanning microscope and electrical responses to the pheromone stimulus are presented. Providers (Prof. Ryohei Kanzaki et al., The University of Tokyo) have copyright for images and documents. [/en][ja]カイコガの脳および同定ニューロンの共焦点レーザ顕微鏡画像、フェロモン刺激に対する電気応答などの実測データを提供しています。一連のデータの著作権は、東京大学・神崎亮平が管理しています。(データ取得者はファイル名末尾の記号による。 se:関洋一 rf:福島亮太 sn:並木重宏 sw:和田賢 hi:Evan Hill Ki:吉川 美都子) [/ja]</p>',
content:
'<p>[en]Experimental data, such as confocal images by laser scanning microscope and electrical responses to the pheromone stimulus are presented. Providers (Prof. Ryohei Kanzaki et al., The University of Tokyo) have copyright for images and documents. [/en][ja]カイコガの脳および同定ニューロンの共焦点レーザ顕微鏡画像、フェロモン刺激に対する電気応答などの実測データを提供しています。一連のデータの著作権は、東京大学・神崎亮平が管理しています。(データ取得者はファイル名末尾の記号による。 se:関洋一 rf:福島亮太 sn:並木重宏 sw:和田賢 hi:Evan Hill Ki:吉川 美都子) [/ja]</p>',
},
{
modulepath: '/modules/newdb7',
title: '[en]Movies and Images[/en][ja]無脊椎動物の写真と映像[/ja]',
content: '<p>Movie and image data of invertebrate animals are presented by this database. It can be used for educational fields. Providers (*) have copyright for images and documents.</p>',
content:
'<p>Movie and image data of invertebrate animals are presented by this database. It can be used for educational fields. Providers (*) have copyright for images and documents.</p>',
},
{
modulepath: '/modules/newdb8',
title: '[en]Cockroach Brain and Neurons[/en][ja]ゴキブリの脳と神経[/ja]',
content: '<p>Experimental data, such as confocal images by laser scanning microscope are presented. Providers (.......)have copyright for images and documents. Providers (*) have copyright for images and documents.</p>',
content:
'<p>Experimental data, such as confocal images by laser scanning microscope are presented. Providers (.......)have copyright for images and documents. Providers (*) have copyright for images and documents.</p>',
},
{
modulepath: '/modules/newdb9',
title: '[en]Cricket Brain and Neurons[/en][ja]コオロギの脳と神経[/ja]',
content: '<p>Experimental data, sch as confocal images by laser scanning microscope are preseunted. Providers (*) have copyright for images and documents.</p>',
content:
'<p>Experimental data, sch as confocal images by laser scanning microscope are preseunted. Providers (*) have copyright for images and documents.</p>',
},
{
modulepath: '/modules/newdb10',
title: '[en]Invertebrate Sensory System[/en][ja]無脊椎動物の感覚器[/ja]',
content: '<p>Scanning migrographs of inverbetrates of antenna. Sensory hairs for olfaction and taste are shown. Providers (*) have copyright for images and documents.</p>',
content:
'<p>Scanning migrographs of inverbetrates of antenna. Sensory hairs for olfaction and taste are shown. Providers (*) have copyright for images and documents.</p>',
},
{
modulepath: '/modules/newdb112',
title: '[en]Honeybee Brain and Neurons[/en][ja]ミツバチの脳と神経[/ja]',
content: '<p>Experimental data, such as confocal images by laser scanning microscope and electrical responses to the pheromone stimulus are presented. Providers (*) have copyright for images and documents.</p>',
content:
'<p>Experimental data, such as confocal images by laser scanning microscope and electrical responses to the pheromone stimulus are presented. Providers (*) have copyright for images and documents.</p>',
},
{
modulepath: '/modules/newdb12',
title: '[en]Fly Brain and Neurons[/en][ja]ハエの脳と神経[/ja]',
content: '<p>Experimental data, such as images of transmission electron microscope and fluorescence maicroscope are presented. Providers (*) have copyright for images and documents.</p>',
content:
'<p>Experimental data, such as images of transmission electron microscope and fluorescence maicroscope are presented. Providers (*) have copyright for images and documents.</p>',
},
{
modulepath: '/modules/newdb13',
title: '[en]Glomerular Structures of Lepidopteran Insects[/en][ja]各種鱗翅目昆虫触角葉糸球体構造[/ja]',
content: '[en]<p>Insects have a pair of the antenna. In lepidopteran insects there are several different types of sensillum on the antennae for olfaction (i.e., sensilla torichodea, sensilla basiconica, and sensilla coeloconica). Each sensillum contains olfactory receptor neurons (ORNs). Axons of the ORNs project to the first order olfactory center, the antennal lobe (AL). The AL consists of a dorsally located male specific macroglomerular complex (MGC) and ventrally located ordinary glomeruli (OG). Pheromonal information is processed in the MGC and general odor information is processed in the OGs. Glomerular structures in different lepidopteran insects are demonstrated.</p><p><a href="/modules/htmldocs/IVBPF/General/sensory-system.html">Pheromone and general odor processing</a></p>[/en][ja]<p>昆虫はわれわれヒトを含めた哺乳類に匹敵する,あるいはそれ以上の優れた嗅覚能力を持っています.嗅覚受容細胞(匂いセンサ)で受容された匂い情報は嗅覚系一次中枢において匂いの識別処理が行われます.哺乳類ではこの脳領域を嗅球(olfactory bulb),昆虫では触角葉(antennal lobe)と言いいます.触角葉は糸球体といわれる多数の球状構造からできています.このデータベースで挙げた鱗翅目昆虫の糸球体は,触角葉の入り口にある大きい糸球体(大糸球体(macroglomerular complex; MGC))とその他の小さなたくさんの糸球体(常糸球体(ordinary glomerulus))から構成されます.前者はフェロモン情報処理に,後者は植物や食物などの一般臭の情報を処理します.</p><p><a href="/modules/htmldocs/IVBPF/General/sensory-system.html">フェロモン及び一般臭受容の詳細</a> <a href="/modules/htmldocs/IVBPF/General/general_odor_processing.html">匂い識別機構の詳細</a></p>[/ja]',
content:
'[en]<p>Insects have a pair of the antenna. In lepidopteran insects there are several different types of sensillum on the antennae for olfaction (i.e., sensilla torichodea, sensilla basiconica, and sensilla coeloconica). Each sensillum contains olfactory receptor neurons (ORNs). Axons of the ORNs project to the first order olfactory center, the antennal lobe (AL). The AL consists of a dorsally located male specific macroglomerular complex (MGC) and ventrally located ordinary glomeruli (OG). Pheromonal information is processed in the MGC and general odor information is processed in the OGs. Glomerular structures in different lepidopteran insects are demonstrated.</p><p><a href="/modules/htmldocs/IVBPF/General/sensory-system.html">Pheromone and general odor processing</a></p>[/en][ja]<p>昆虫はわれわれヒトを含めた哺乳類に匹敵する,あるいはそれ以上の優れた嗅覚能力を持っています.嗅覚受容細胞(匂いセンサ)で受容された匂い情報は嗅覚系一次中枢において匂いの識別処理が行われます.哺乳類ではこの脳領域を嗅球(olfactory bulb),昆虫では触角葉(antennal lobe)と言いいます.触角葉は糸球体といわれる多数の球状構造からできています.このデータベースで挙げた鱗翅目昆虫の糸球体は,触角葉の入り口にある大きい糸球体(大糸球体(macroglomerular complex; MGC))とその他の小さなたくさんの糸球体(常糸球体(ordinary glomerulus))から構成されます.前者はフェロモン情報処理に,後者は植物や食物などの一般臭の情報を処理します.</p><p><a href="/modules/htmldocs/IVBPF/General/sensory-system.html">フェロモン及び一般臭受容の詳細</a> <a href="/modules/htmldocs/IVBPF/General/general_odor_processing.html">匂い識別機構の詳細</a></p>[/ja]',
},
{
modulepath: '/modules/noneLectClass',
title: '中高教員対象研修会',
content: '動物の行動が発現するしくみについての講義をとおして、感覚・脳・行動の成り立ち(神経・脳の役割)を学び、カイコガの匂い源探索の行動実験により、感覚・脳・行動の機能を考え、推測していきます。さらに、筋電位を計測する安価な増幅器を作製し、実際に作製した増幅器を使って、昆虫の羽ばたきをおこす筋肉の電位を計測することで、成体がつくる生物電気について学びます。また、成体が発生する電気によりロボット(チョロQ)を動かすことで、生物と工学の接点について学び、ブレインマシンインターフェース(BMI)といわれる、脳信号で車椅子を操作する最新の技術への取っ掛かりを実験によって体験します。'
}
content:
'動物の行動が発現するしくみについての講義をとおして、感覚・脳・行動の成り立ち(神経・脳の役割)を学び、カイコガの匂い源探索の行動実験により、感覚・脳・行動の機能を考え、推測していきます。さらに、筋電位を計測する安価な増幅器を作製し、実際に作製した増幅器を使って、昆虫の羽ばたきをおこす筋肉の電位を計測することで、成体がつくる生物電気について学びます。また、成体が発生する電気によりロボット(チョロQ)を動かすことで、生物と工学の接点について学び、ブレインマシンインターフェース(BMI)といわれる、脳信号で車椅子を操作する最新の技術への取っ掛かりを実験によって体験します。',
},
];
const CustomBlock: React.FC<Props> = (props: Props) => {
const CustomBlock = (props: Props) => {
const { lang, modulepath } = props;
const data = contents.find((value) => modulepath === value.modulepath);
if (typeof data === 'undefined') {
return null;
}
return <div className="block">
<div className="blockTitle">{Functions.mlang(data.title, lang)}</div>
<div className="blockContent"><XoopsCode lang={lang} text={data.content} dohtml={true} /></div>
</div>;
}
return (
<div className="block">
<div className="blockTitle">{Functions.mlang(data.title, lang)}</div>
<div className="blockContent">
<XoopsCode lang={lang} text={data.content} dohtml={true} />
</div>
</div>
);
};
export default CustomBlock;
+44 -44
View File
@@ -1,18 +1,16 @@
import moment from 'moment';
import XRegExp from 'xregexp';
import Config, { MultiLang } from './config';
import Config, { type MultiLang } from './config';
const escape = (str: string): string => {
const escapeUrl = (str: string) => {
return encodeURIComponent(str).replace(/[!'()*]/g, (c) => {
return '%' + c.charCodeAt(0).toString(16);
return `%${c.charCodeAt(0).toString(16)}`;
});
}
};
const unescape = (str: string): string => {
const unescapeUrl = (str: string) => {
return decodeURIComponent(str);
}
};
const htmlspecialchars = (str: string): string => {
const htmlspecialchars = (str: string) => {
return str.replace(/(<|>|&|'|")/g, (match) => {
switch (match) {
case '<':
@@ -21,46 +19,42 @@ const htmlspecialchars = (str: string): string => {
return '&gt;';
case '&':
return '&amp;';
case '\'':
case "'":
return '&#039;';
case '"':
return '&quot;';
}
return '';
});
}
};
const camelCase = (str: string): string => {
const camelCase = (str: string) => {
return str.replace(/[-_](.)/g, (...matches) => {
return matches[1].toUpperCase();
});
}
};
const snakeCase = (str: string): string => {
const snakeCase = (str: string) => {
var camel = camelCase(str);
return camel.replace(/[A-Z]/g, (...matches) => {
return "_" + matches[0].charAt(0).toLowerCase();
return `_${matches[0].charAt(0).toLowerCase()}`;
});
}
};
const pascalCase = (str: string): string => {
const pascalCase = (str: string) => {
var camel = camelCase(str);
return camel.charAt(0).toUpperCase() + camel.slice(1);
}
};
const base64Encode = (str: string): string => {
const base64Encode = (str: string) => {
return btoa(unescape(encodeURIComponent(str)));
}
};
const base64Decode = (str: string): string => {
const base64Decode = (str: string) => {
return decodeURIComponent(escape(atob(str)));
}
};
const formatDate = (timestamp: number, format: string): string => {
return moment(new Date(timestamp * 1000)).format(format);
}
const ordinal = (num: number): string => {
const ordinal = (num: number) => {
const hundred = num % 100;
if (hundred >= 10 && hundred <= 20) {
return 'th';
@@ -68,69 +62,75 @@ const ordinal = (num: number): string => {
const ten = num % 10;
const suffix = ['st', 'nd', 'rd'];
return ten > 0 && ten < 4 ? suffix[ten - 1] : 'th';
}
};
const mlang = (str: string, lang: MultiLang): string => {
const mlang = (str: string, lang: MultiLang) => {
const mlLangs = ['en', 'ja'];
// escape brackets inside of <input type="text" value="...">
let text = str.replace(/(<input)([^>]*)(>)/isg, (whole, m1, m2, m3) => {
let text = str.replace(/(<input)([^>]*)(>)/gis, (whole, m1, m2, m3) => {
if (m2.match(/type=["']?(?:text|hidden)["']?/is)) {
return m1 + m2.replace(/\[/g, '__ml[ml__') + m3;
}
return whole;
});
// escape brackets inside of <textarea></textarea>
text = text.replace(/(<textarea[^>]*>)(.*)(<\/textarea>)/isg, (whole, m1, m2, m3) => {
text = text.replace(/(<textarea[^>]*>)(.*)(<\/textarea>)/gis, (_whole, m1, m2, m3) => {
return m1 + m2.replace(/\[/g, '__ml[ml__') + m3;
});
// simple pattern to strip selected lang_tags
const re = new RegExp('\\[/?(?:[^\\]]+\\|)?' + lang + '(?:\\|[^\\]]+)?\\](?:<br />)?', 'g');
const re = new RegExp(`\\[/?(?:[^\\]]+\\|)?${lang}(?:\\|[^\\]]+)?\\](?:<br />)?`, 'g');
text = text.replace(re, '');
// eliminate description between the other language tags.
mlLangs.forEach((mlLang) => {
if (mlLang !== lang) {
const re = XRegExp('\\[(?:[^/][^\\]]+\\|)?' + mlLang + '(?:\\|[^\\]]+)?\\].*?\\[/(?:[^\\]]+\\|)?' + mlLang + '(?:\\|[^\\]]+)?\\](?:<br />)?', 'isg');
const re = new RegExp(
'\\[(?:[^/][^\\]]+\\|)?' +
mlLang +
'(?:\\|[^\\]]+)?\\].*?\\[/(?:[^\\]]+\\|)?' +
mlLang +
'(?:\\|[^\\]]+)?\\](?:<br />)?',
'gis'
);
text = text.replace(re, (whole) => {
return whole.match(/<\/table>/) ? whole : '';
});
}
});
// unescape brackets inside of <textarea></textarea>
text = text.replace(/(<textarea[^>]*>)(.*)(<\/textarea>)/isg, (whole, m1, m2, m3) => {
text = text.replace(/(<textarea[^>]*>)(.*)(<\/textarea>)/gis, (_whole, m1, m2, m3) => {
return m1 + m2.replace(/__ml\[ml__/g, '[') + m3;
});
// unescape brackets inside of <input type="text" value="...">
text = text.replace(/(<input)([^>]*)(>)/isg, (whole, m1, m2, m3) => {
text = text.replace(/(<input)([^>]*)(>)/gis, (whole, m1, m2, m3) => {
if (m2.match(/type=["']?(?:text|hidden)["']?/is)) {
return m1 + m2.replace(/__ml\[ml__/g, '[') + m3;
}
return whole;
});
return text;
}
};
const siteTitle = (lang: MultiLang): string => {
const siteTitle = (lang: MultiLang) => {
return mlang(Config.SITE_TITLE, lang);
}
};
const siteSlogan = (lang: MultiLang): string => {
const siteSlogan = (lang: MultiLang) => {
return mlang(Config.SITE_SLOGAN, lang);
}
};
const Functions = {
escape,
unescape,
escape: escapeUrl,
unescape: unescapeUrl,
htmlspecialchars,
camelCase,
snakeCase,
pascalCase,
base64Encode,
base64Decode,
formatDate,
ordinal,
mlang,
siteTitle,
siteSlogan,
};
export default Functions;
export default Functions;
+1 -1
View File
@@ -1 +1 @@
@import-normalize;
@import url("./common/assets/xoops.css");
-14
View File
@@ -1,14 +0,0 @@
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
// import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
// serviceWorker.unregister();
+19
View File
@@ -0,0 +1,19 @@
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import 'sanitize.css';
import 'sanitize.css/forms.css';
import 'sanitize.css/typography.css';
import './sanitize-overrides.css';
import App from './App';
import './index.css';
const container = document.getElementById('root');
if (container === null) {
throw new Error('Root container #root was not found in the document.');
}
createRoot(container).render(
<StrictMode>
<App />
</StrictMode>
);
+35 -96
View File
@@ -1,10 +1,9 @@
import React, { Component } from 'react';
import { Redirect, Route, RouteComponentProps, Switch } from 'react-router-dom';
import { useLocation } from 'react-router';
import Loading from '../common/lib/Loading';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import useInitialized from '../common/lib/useInitialized';
import type { MultiLang } from '../config';
import './assets/pico_main.css';
import PicoContext from './lib/PicoContext';
import PicoUtils from './lib/PicoUtils';
import PicoCategory from './PicoCategory';
import PicoContent from './PicoContent';
@@ -13,105 +12,45 @@ import PicoMenu from './PicoMenu';
interface Props {
lang: MultiLang;
modulepath: string;
showTitle: boolean;
dirname: string;
}
interface State {
loading: boolean;
context: PicoContext | null;
}
class Pico extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
context: null,
};
const Pico = (props: Props) => {
const { lang, dirname } = props;
const { pathname, search } = useLocation();
const context = PicoUtils.getContext(dirname);
const status = useInitialized(context.initialize);
if (status === null) {
return <Loading />;
}
componentDidMount() {
this.isActive = true;
this.updatePage();
if (!status) {
return <PageNotFound lang={lang} />;
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, modulepath } = this.props;
if (prevProps.lang !== lang || prevProps.modulepath !== modulepath) {
this.updatePage();
const link = pathname.replace(new RegExp(`^${context.getModulePath()}/?`), '');
const content = context.getContentByPath(link);
if (content !== null) {
return <PicoContent lang={lang} context={context} contentId={content.id} />;
}
const category = context.getCategoryByPath(link);
if (category !== null) {
return <PicoCategory lang={lang} context={context} catId={category.id} />;
}
if (link === '' || link === 'index.php') {
const params = new URLSearchParams(search);
const paramCatId = params.get('cat_id');
if (paramCatId?.match(/^\d+$/)) {
return <PicoCategory lang={lang} context={context} catId={parseInt(paramCatId, 10)} />;
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
const { modulepath, showTitle } = this.props;
const context = PicoUtils.getContext(modulepath, showTitle);
const status = await context.initialize();
if (this.isActive) {
this.setState({ loading: false, context: status ? context : null });
const paramContentId = params.get('content_id');
if (paramContentId?.match(/^\d+$/)) {
return <PicoContent lang={lang} context={context} contentId={parseInt(paramContentId, 10)} />;
}
}
render() {
const { lang, modulepath } = this.props;
const { loading, context } = this.state;
if (loading) {
return <Loading />;
if (params.get('page') === 'menu') {
return <PicoMenu lang={lang} context={context} />;
}
if (context === null) {
return <PageNotFound lang={lang} />;
}
return <Switch>
<Route path={`${modulepath}`} render={(props: RouteComponentProps) => {
const { location } = props;
const { pathname, search } = location;
const regex = new RegExp(`^${modulepath}/?`);
const link = pathname.replace(regex, '');
const content = context.getContentByPath(link);
if (content !== null) {
return <PicoContent lang={lang} context={context} contentId={content.id} />;
}
const category = context.getCategoryByPath(link);
if (category !== null) {
return <PicoCategory lang={lang} context={context} catId={category.id} />;
}
if (link === '' || link === 'index.php') {
const params = new URLSearchParams(search);
const paramCatId = params.get('cat_id');
if (paramCatId !== null && paramCatId.match(/^\d+$/)) {
const catId = parseInt(paramCatId, 10);
return <PicoCategory lang={lang} context={context} catId={catId} />;
}
const paramContentId = params.get('content_id');
if (paramContentId !== null && paramContentId.match(/^\d+$/)) {
const contentId = parseInt(paramContentId, 10);
return <PicoContent lang={lang} context={context} contentId={contentId} />;
}
const paramPage = params.get('page');
if (paramPage !== null && paramPage === 'menu') {
return <PicoMenu lang={lang} context={context} />;
}
return <PicoIndex lang={lang} context={context} />;
}
return <PageNotFound lang={lang} />;
}} />
<Route exact path={modulepath} render={(props: RouteComponentProps) => {
const { location } = props;
const url = modulepath + '/index.php' + location.search + location.hash;
return <Redirect to={url} />
}} />
<Route component={PageNotFound} />
</Switch>;
return <PicoIndex lang={lang} context={context} />;
}
}
return <PageNotFound lang={lang} />;
};
export default Pico;
+28 -16
View File
@@ -1,10 +1,11 @@
import React, { Fragment } from 'react';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import { Helmet } from '@dr.pogodin/react-helmet';
import { Fragment } from 'react';
import { Link } from 'react-router';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import PicoContext, { PicoCategoryData, PicoContentData } from './lib/PicoContext';
import type PicoContext from './lib/PicoContext';
import type { PicoCategoryData, PicoContentData } from './lib/PicoContext';
interface Props {
lang: MultiLang;
@@ -28,7 +29,10 @@ const PicoCategory = (props: Props) => {
return (
<div className="pico_container">
<Helmet>
<title>{Functions.mlang(category.title, lang)} - {Functions.mlang(pico.name, lang)} - {Functions.siteTitle(lang)}</title>
<title>
{Functions.mlang(category.title, lang)} - {Functions.mlang(pico.name, lang)} -{' '}
{Functions.siteTitle(lang)}
</title>
</Helmet>
{pico.show_breadcrumbs !== 0 && (
<div className="pico_breadcrumbs">
@@ -36,7 +40,9 @@ const PicoCategory = (props: Props) => {
return (
<Fragment key={parentCategory.id}>
{idx > 0 && <>&nbsp;&gt;&nbsp;</>}
<Link key={parentCategory.id} to={context.getUrl(parentCategory.link)}>{Functions.mlang(parentCategory.title, lang)}</Link>
<Link key={parentCategory.id} to={context.getUrl(parentCategory.link)}>
{Functions.mlang(parentCategory.title, lang)}
</Link>
</Fragment>
);
})}
@@ -44,20 +50,20 @@ const PicoCategory = (props: Props) => {
{Functions.mlang(category.title, lang)}
</div>
)}
{catId === 0 && pico.message !== '' && (
<p>{Functions.mlang(pico.message, lang)}</p>
)}
{catId === 0 && pico.message !== '' && <p>{Functions.mlang(pico.message, lang)}</p>}
<h1>{Functions.mlang(category.title, lang)}</h1>
{category.desc !== '' && (
<p>{Functions.mlang(category.desc, lang)}</p>
)}
{category.desc !== '' && <p>{Functions.mlang(category.desc, lang)}</p>}
{subCategories.length > 0 && (
<>
<h2>{Functions.mlang('[en]Subcageroies[/en][ja]サブカテゴリー[/ja]', lang)}</h2>
{subCategories.map((subCategory: PicoCategoryData) => {
return (
<dl key={subCategory.id} className="pico_subcategory">
<dt><Link to={context.getUrl(subCategory.link)}>{Functions.mlang(subCategory.title, lang)}</Link></dt>
<dt>
<Link to={context.getUrl(subCategory.link)}>
{Functions.mlang(subCategory.title, lang)}
</Link>
</dt>
<dd>{Functions.mlang(subCategory.desc, lang)}</dd>
</dl>
);
@@ -69,7 +75,13 @@ const PicoCategory = (props: Props) => {
<h2>{Functions.mlang('[en]Contents[/en][ja]コンテンツ[/ja]', lang)}</h2>
<ul className="pico_list_contents">
{contents.map((content: PicoContentData) => {
return <li key={content.id}><Link to={context.getUrl(content.link)}>{Functions.mlang(content.title, lang)}</Link></li>;
return (
<li key={content.id}>
<Link to={context.getUrl(content.link)}>
{Functions.mlang(content.title, lang)}
</Link>
</li>
);
})}
</ul>
</>
@@ -78,4 +90,4 @@ const PicoCategory = (props: Props) => {
);
};
export default PicoCategory;
export default PicoCategory;
+61 -88
View File
@@ -1,14 +1,14 @@
import React, { Component, Fragment } from 'react';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import { HashLink } from 'react-router-hash-link';
import { Helmet } from '@dr.pogodin/react-helmet';
import { Fragment, useEffect, useState } from 'react';
import { Link } from 'react-router';
import HashLink from '../common/lib/HashLink';
import Loading from '../common/lib/Loading';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import XoopsCode from '../common/lib/XoopsCode';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import PicoContext, { PicoCategoryData, PicoPageData } from './lib/PicoContext';
import type PicoContext from './lib/PicoContext';
import type { PicoCategoryData, PicoPageData } from './lib/PicoContext';
interface Props {
lang: MultiLang;
@@ -16,97 +16,70 @@ interface Props {
contentId: number;
}
interface State {
loading: boolean;
interface LoadedPage {
context: PicoContext;
contentId: number;
page: PicoPageData | null;
}
class PicoContent extends Component<Props, State> {
const PicoContent = (props: Props) => {
const { lang, context, contentId } = props;
const [loaded, setLoaded] = useState<LoadedPage | null>(null);
private isActive: boolean;
constructor(props: Props) {
super(props);
this.state = {
loading: true,
page: null,
useEffect(() => {
let active = true;
context.getPage(contentId).then((page) => {
if (active) {
setLoaded({ context, contentId, page });
}
});
return () => {
active = false;
};
this.isActive = false;
}
}, [context, contentId]);
componentDidMount() {
const { contentId } = this.props;
this.isActive = true;
this.updatePage(contentId);
// A page loaded for the previous content must not be shown for this one.
if (loaded === null || loaded.context !== context || loaded.contentId !== contentId) {
return <Loading />;
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { context, contentId } = this.props;
const prevContext = prevProps.context;
const prevContentId = prevProps.contentId;
if (context !== prevContext || contentId !== prevContentId) {
this.setState({ loading: true, page: null });
this.updatePage(contentId);
}
const { page } = loaded;
if (page === null) {
return <PageNotFound lang={lang} />;
}
componentWillUnmount() {
this.isActive = false;
const pico = context.getModule();
if (pico === null) {
return <PageNotFound lang={lang} />;
}
async updatePage(contentId: number) {
const { context } = this.props;
const page = await context.getPage(contentId);
if (this.isActive) {
this.setState({ loading: false, page });
}
}
render() {
const { lang, context, contentId } = this.props;
const { loading, page } = this.state;
if (loading) {
return <Loading />;
}
if (page === null) {
return <PageNotFound lang={lang} />;
}
const pico = context.getModule();
if (pico === null) {
return <PageNotFound lang={lang} />;
}
const categories = context.getContentCategery(contentId);
return (
<div className="pico_container">
<Helmet>
<title>{Functions.mlang(page.title, lang)} - {Functions.mlang(pico.name, lang)} - {Functions.siteTitle(lang)}</title>
</Helmet>
{context.isShowTitle() && <>
<h2>{Functions.mlang(pico.name, lang)}</h2>
<NoticeSiteHasBeenArchived lang={lang} />
</>}
{pico.show_breadcrumbs !== 0 && (
<div className="pico_breadcrumbs">
{categories.map((category: PicoCategoryData, idx: number) => {
return (
<Fragment key={category.id}>
{idx > 0 && <>&nbsp;&gt;&nbsp;</>}
<Link key={category.id} to={context.getUrl(category.link)}>{Functions.mlang(category.title, lang)}</Link>
</Fragment>
);
})}
&nbsp;&gt;&nbsp;{Functions.mlang(page.title, lang)}
</div>
)}
<div id="top_of_pico_body" className="pico_body">
<XoopsCode lang={lang} text={page.content[lang]} dohtml={true} />
</div>
<div className="bottom_of_content_body">
<HashLink to="#top_of_pico_body">{Functions.mlang('[en]Jump to the top[/en][ja]この記事の1行目に飛ぶ[/ja]', lang)}</HashLink>
const categories = context.getContentCategery(contentId);
return (
<div className="pico_container">
<Helmet>
<title>
{Functions.mlang(page.title, lang)} - {Functions.mlang(pico.name, lang)} -{' '}
{Functions.siteTitle(lang)}
</title>
</Helmet>
{pico.show_breadcrumbs !== 0 && (
<div className="pico_breadcrumbs">
{categories.map((category: PicoCategoryData, idx: number) => (
<Fragment key={category.id}>
{idx > 0 && <>&nbsp;&gt;&nbsp;</>}
<Link to={context.getUrl(category.link)}>{Functions.mlang(category.title, lang)}</Link>
</Fragment>
))}
&nbsp;&gt;&nbsp;{Functions.mlang(page.title, lang)}
</div>
)}
<div id="top_of_pico_body" className="pico_body">
<XoopsCode lang={lang} text={page.content[lang]} dohtml={true} />
</div>
);
}
}
<div className="bottom_of_content_body">
<HashLink to="#top_of_pico_body">
{Functions.mlang('[en]Jump to the top[/en][ja]この記事の1行目に飛ぶ[/ja]', lang)}
</HashLink>
</div>
</div>
);
};
export default PicoContent;
+5 -7
View File
@@ -1,7 +1,6 @@
import React from 'react';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import PicoContext from './lib/PicoContext';
import type { MultiLang } from '../config';
import type PicoContext from './lib/PicoContext';
import PicoCategory from './PicoCategory';
import PicoContent from './PicoContent';
import PicoMenu from './PicoMenu';
@@ -18,17 +17,16 @@ const PicoIndex = (props: Props) => {
return <PageNotFound lang={lang} />;
}
if (pico.show_menuinmoduletop !== 0) {
return <PicoMenu lang={lang} context={context} />
return <PicoMenu lang={lang} context={context} />;
}
if (pico.show_listasindex !== 0) {
return <PicoCategory lang={lang} context={context} catId={0} />
return <PicoCategory lang={lang} context={context} catId={0} />;
}
const content = context.getFirstContent(0);
if (content === null) {
return <PageNotFound lang={lang} />;
}
return <PicoContent lang={lang} context={context} contentId={content.id} />;
}
};
export default PicoIndex;
+32 -20
View File
@@ -1,10 +1,10 @@
import React from 'react';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import { Helmet } from '@dr.pogodin/react-helmet';
import { Link } from 'react-router';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import PicoContext, { PicoCategoryData, PicoContentData } from './lib/PicoContext';
import type PicoContext from './lib/PicoContext';
import type { PicoCategoryData, PicoContentData } from './lib/PicoContext';
interface Props {
lang: MultiLang;
@@ -22,7 +22,7 @@ const PicoMenuCategory = (props: PicoMenuCategoryProps) => {
const { lang, context, category, depth } = props;
const subCategories = context.getSubCategories(category.id);
const contents = context.getCategoryContents(category.id);
const level = 'level' + depth;
const level = `level${depth}`;
const link = <Link to={context.getUrl(category.link)}>{Functions.mlang(category.title, lang)}</Link>;
let title = <h6>{link}</h6>;
switch (depth) {
@@ -49,21 +49,32 @@ const PicoMenuCategory = (props: PicoMenuCategoryProps) => {
<div className={level}>
<ul className="pico_list_contents_in_menu">
{contents.map((content: PicoContentData) => {
return <li key={content.id}><Link to={context.getUrl(content.link)}>{Functions.mlang(content.title, lang)}</Link></li>;
return (
<li key={content.id}>
<Link to={context.getUrl(content.link)}>
{Functions.mlang(content.title, lang)}
</Link>
</li>
);
})}
</ul>
</div>
)}
{subCategories.length > 0 && (
<>
{subCategories.map((subCategory: PicoCategoryData) => {
return <PicoMenuCategory key={subCategory.id} lang={lang} context={context} category={subCategory} depth={depth + 1} />;
})}
</>
)}
{subCategories.length > 0 &&
subCategories.map((subCategory: PicoCategoryData) => {
return (
<PicoMenuCategory
key={subCategory.id}
lang={lang}
context={context}
category={subCategory}
depth={depth + 1}
/>
);
})}
</>
);
}
};
const PicoMenu = (props: Props) => {
const { lang, context } = props;
@@ -78,14 +89,15 @@ const PicoMenu = (props: Props) => {
return (
<div className="pico_container pico_menu">
<Helmet>
<title>{Functions.mlang('[en]Menu[/en][ja]メニュー[/ja]', lang)} - {Functions.mlang(pico.name, lang)} - {Functions.siteTitle(lang)}</title>
<title>
{Functions.mlang('[en]Menu[/en][ja]メニュー[/ja]', lang)} - {Functions.mlang(pico.name, lang)} -{' '}
{Functions.siteTitle(lang)}
</title>
</Helmet>
{pico.message !== '' && (
<p>{Functions.mlang(pico.message, lang)}</p>
)}
{pico.message !== '' && <p>{Functions.mlang(pico.message, lang)}</p>}
<PicoMenuCategory lang={lang} context={context} category={category} depth={1} />
</div>
);
};
export default PicoMenu;
export default PicoMenu;
+1 -1
View File
@@ -103,7 +103,7 @@ table.pico_form_table td.pico_waiting {
table.pico_form_table td,
table.pico_form_table th {
color: black;
vertical-align: top !important;
vertical-align: top;
text-align: left;
}
p.pico_submit {
+38 -39
View File
@@ -1,5 +1,6 @@
import axios from 'axios';
import ky from 'ky';
import loki from 'lokijs';
import Config from '../../config';
export interface PicoModuleData {
name: string;
@@ -40,37 +41,38 @@ export interface PicoPageData {
content: {
en: string;
ja: string;
}
};
}
export const PICO_CATEGORY_ID_ROOT = 65535;
class PicoContext {
private isInitialized: boolean;
private modulepath: string;
private showTitle: boolean;
private dirname: string;
private database: loki;
private module: PicoModuleData | null;
private categories: Collection<PicoCategoryData>;
private contents: Collection<PicoContentData>;
private initializing: Promise<boolean> | null;
constructor(modulepath: string, showTitle: boolean) {
this.isInitialized = false;
this.modulepath = modulepath;
this.showTitle = showTitle;
this.database = new loki(modulepath);
constructor(dirname: string) {
this.dirname = dirname;
this.database = new loki(dirname);
this.module = null;
this.categories = this.database.addCollection('categories');
this.contents = this.database.addCollection('contents');
this.initializing = null;
}
isShowTitle(): boolean {
return this.showTitle;
getModulePath(): string {
return `/modules/${this.dirname}`;
}
getUrl(path: string): string {
return `${this.modulepath}/${path}`;
return `${this.getModulePath()}/${path}`;
}
private getDataUrl(path: string): URL {
return new URL(Config.BASE_URL + this.getUrl(path), window.location.href);
}
getModule(): PicoModuleData | null {
@@ -127,35 +129,32 @@ class PicoContext {
}
async getPage(contentId: number): Promise<PicoPageData | null> {
let page: PicoPageData | null = null;
try {
const response = await axios.get(this.getUrl(`${contentId}.json`));
page = response.data as PicoPageData;
} catch (e) {
// ignore
return await ky.get(this.getDataUrl(`${contentId}.json`)).json<PicoPageData>();
} catch {
return null;
}
return page;
}
async initialize(): Promise<boolean> {
if (!this.isInitialized) {
try {
const response = await axios.get(this.getUrl('index.json'));
const index = response.data as PicoIndexData;
this.module = index.module;
index.categories.forEach((value) => {
this.categories.insert(value);
});
index.contents.forEach((value) => {
this.contents.insert(value);
});
} catch (err) {
// ignore
}
this.isInitialized = true;
/**
* Loads the module index once. Concurrent callers share the same request,
* so the collections are never filled twice.
*/
initialize = (): Promise<boolean> => {
if (this.initializing === null) {
this.initializing = ky
.get(this.getDataUrl('index.json'))
.json<PicoIndexData>()
.then((index) => {
this.module = index.module;
this.categories.insert(index.categories);
this.contents.insert(index.contents);
return true;
})
.catch(() => false);
}
return this.isInitialized;
}
return this.initializing;
};
}
export default PicoContext;
export default PicoContext;
+11 -15
View File
@@ -1,22 +1,18 @@
import PicoContext from './PicoContext';
class PicoUtils {
const contexts = new Map<string, PicoContext>();
private static contexts: Map<string, PicoContext> = new Map<string, PicoContext>();
private constructor() {
// blcok to access from outside of this class
const getContext = (dirname: string): PicoContext => {
let context = contexts.get(dirname);
if (typeof context === 'undefined') {
context = new PicoContext(dirname);
contexts.set(dirname, context);
}
return context;
};
public static getContext(modulepath: string, showTitle: boolean): PicoContext {
let context = this.contexts.get(modulepath);
if (typeof context === 'undefined') {
context = new PicoContext(modulepath, showTitle);
this.contexts.set(modulepath, context);
}
return context;
}
}
const PicoUtils = {
getContext,
};
export default PicoUtils;
+82 -71
View File
@@ -1,7 +1,9 @@
import React from 'react';
import { Redirect, Route, RouteComponentProps, Switch } from 'react-router-dom';
import { Navigate, Route, Routes, useLocation } from 'react-router';
import Loading from '../common/lib/Loading';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import useInitialized from '../common/lib/useInitialized';
import type { MultiLang } from '../config';
import PubmedPdfUtils from './lib/PubmedPdfUtils';
import PubmedPdfAuthorsByInitial from './PubmedPdfAuthorsByInitial';
import PubmedPdfIndex from './PubmedPdfIndex';
import PubmedPdfJournalsByYear from './PubmedPdfJournalsByYear';
@@ -14,77 +16,86 @@ interface Props {
lang: MultiLang;
}
const useParams = () => new URLSearchParams(useLocation().search);
const AuthorPage = (props: Props) => {
const { lang } = props;
const params = useParams();
const initial = params.get('initial');
if (initial !== null && /^[A-Z]/.test(initial)) {
return <PubmedPdfAuthorsByInitial lang={lang} initial={initial} />;
}
const authorIdStr = params.get('author');
if (authorIdStr !== null && /^[0-9]+/.test(authorIdStr)) {
const yearStr = params.get('year');
const year = yearStr !== null && /^[0-9]+/.test(yearStr) ? parseInt(yearStr, 10) : 0;
return <PubmedPdfPapersByAuthor lang={lang} authorId={parseInt(authorIdStr, 10)} year={year} />;
}
return <PageNotFound lang={lang} />;
};
const YearPage = (props: Props) => {
const { lang } = props;
const params = useParams();
const yearStr = params.get('year');
const journalIdStr = params.get('journal');
if (yearStr === null || !/^[0-9]+/.test(yearStr) || (journalIdStr !== null && !/^[0-9]+/.test(journalIdStr))) {
return <PageNotFound lang={lang} />;
}
const year = parseInt(yearStr, 10);
const journalId = journalIdStr !== null ? parseInt(journalIdStr, 10) : 0;
if (journalId === 0) {
return <PubmedPdfJournalsByYear lang={lang} year={year} />;
}
return <PubmedPdfPapersByYear lang={lang} year={year} journalId={journalId} />;
};
const JournalPage = (props: Props) => {
const { lang } = props;
const params = useParams();
const journalIdStr = params.get('journal');
const yearStr = params.get('year');
if (journalIdStr === null || !/^[0-9]+/.test(journalIdStr) || (yearStr !== null && !/^[0-9]+/.test(yearStr))) {
return <PageNotFound lang={lang} />;
}
const year = yearStr !== null ? parseInt(yearStr, 10) : 0;
return <PubmedPdfPapersByJournal lang={lang} journalId={parseInt(journalIdStr, 10)} year={year} />;
};
const PaperDescPage = (props: Props) => {
const { lang } = props;
const idStr = useParams().get('id');
if (idStr === null || !/^[0-9]+/.test(idStr)) {
return <PageNotFound lang={lang} />;
}
return <PubmedPdfPaperDesc lang={lang} id={parseInt(idStr, 10)} />;
};
const IndexRedirect = () => {
const { search, hash } = useLocation();
return <Navigate to={`${PubmedPdfUtils.getIndexUrl()}${search}${hash}`} replace />;
};
const PubmedPdf = (props: Props) => {
const { lang } = props;
const pathname = '/modules/PubMedPDF';
const status = useInitialized(PubmedPdfUtils.initialize);
if (status === null) {
return <Loading />;
}
if (!status) {
return <PageNotFound lang={lang} />;
}
return (
<>
<Switch>
<Route exact path={`${pathname}/index.php`} render={() => {
return <PubmedPdfIndex lang={lang} />;
}} />
<Route exact path={`${pathname}/author.php`} render={(props: RouteComponentProps) => {
const { location } = props;
const params = new URLSearchParams(location.search);
const initial = params.get('initial');
if (initial !== null && /^[A-Z]/.test(initial)) {
return <PubmedPdfAuthorsByInitial lang={lang} initial={initial} />;
}
const authorIdStr = params.get('author');
if (authorIdStr !== null && /^[0-9]+/.test(authorIdStr)) {
const authorId = parseInt(authorIdStr);
const yearStr = params.get('year');
const year = (yearStr !== null && /^[0-9]+/.test(yearStr)) ? parseInt(yearStr) : 0;
return <PubmedPdfPapersByAuthor lang={lang} authorId={authorId} year={year} />;
}
return <PageNotFound lang={lang} />
}} />
<Route exact path={`${pathname}/year.php`} render={(props: RouteComponentProps) => {
const { location } = props;
const params = new URLSearchParams(location.search);
const yearStr = params.get('year');
const journalIdStr = params.get('journal');
if (yearStr === null || !(/^[0-9]+/.test(yearStr)) || (journalIdStr !== null && !(/^[0-9]+/.test(journalIdStr)))) {
return <PageNotFound lang={lang} />;
}
const year = parseInt(yearStr);
const journalId = journalIdStr !== null ? parseInt(journalIdStr) : 0;
if (journalId === 0) {
return <PubmedPdfJournalsByYear lang={lang} year={year} />;
}
return <PubmedPdfPapersByYear lang={lang} year={year} journalId={journalId} />;
}} />
<Route exact path={`${pathname}/journal.php`} render={(props: RouteComponentProps) => {
const { location } = props;
const params = new URLSearchParams(location.search);
const journalIdStr = params.get('journal');
const yearStr = params.get('year');
if (journalIdStr === null || !(/^[0-9]+/.test(journalIdStr)) || (yearStr !== null && !(/^[0-9]+/.test(yearStr)))) {
return <PageNotFound lang={lang} />
}
const journalId = parseInt(journalIdStr);
const year = yearStr !== null ? parseInt(yearStr) : 0;
return <PubmedPdfPapersByJournal lang={lang} journalId={journalId} year={year} />;
}} />
<Route exact path={`${pathname}/paper_desc.php`} render={(props: RouteComponentProps) => {
const { location } = props;
const params = new URLSearchParams(location.search);
const idStr = params.get('id');
if (idStr === null || !(/^[0-9]+/.test(idStr))) {
return <PageNotFound lang={lang} />
}
const id = parseInt(idStr);
return <PubmedPdfPaperDesc lang={lang} id={id} />;
}} />
<Route exact path={pathname} render={(props: RouteComponentProps) => {
const { location } = props;
const url = pathname + '/index.php' + location.search + location.hash;
return <Redirect to={url} />;
}} />
<Route component={PageNotFound} />
</Switch>
</>
<Routes>
<Route index element={<IndexRedirect />} />
<Route path="index.php" element={<PubmedPdfIndex lang={lang} />} />
<Route path="author.php" element={<AuthorPage lang={lang} />} />
<Route path="year.php" element={<YearPage lang={lang} />} />
<Route path="journal.php" element={<JournalPage lang={lang} />} />
<Route path="paper_desc.php" element={<PaperDescPage lang={lang} />} />
<Route path="*" element={<PageNotFound lang={lang} />} />
</Routes>
);
}
};
export default PubmedPdf;
+39 -83
View File
@@ -1,97 +1,53 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import Loading from '../common/lib/Loading';
import { Helmet } from '@dr.pogodin/react-helmet';
import { Link } from 'react-router';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import './assets/pubmedpdf.css';
import PubmedPdfBreadcrumbs from './lib/PubmedPdfBreadcrumbs';
import PubmedPdfUtils, { PubmedPdfBreadcrumbsData } from './lib/PubmedPdfUtils';
import PubmedPdfUtils, { type PubmedPdfBreadcrumbsData } from './lib/PubmedPdfUtils';
interface Props {
lang: MultiLang;
initial: string;
}
interface State {
loading: boolean;
name: string;
}
class PubmedPdfAuthorsByInitial extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
name: '',
};
}
componentDidMount() {
this.isActive = true;
this.updatePage();
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, initial } = this.props;
if (prevProps.lang !== lang || prevProps.initial !== initial) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
await PubmedPdfUtils.initialize();
if (this.isActive) {
const name = PubmedPdfUtils.getName();
this.setState({ loading: false, name });
}
}
render() {
const { lang, initial } = this.props;
const { loading, name } = this.state;
if (loading) {
return <Loading />;
}
if ('' === name) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(name, lang);
const authors = PubmedPdfUtils.getAuthors(initial);
const breadcrumbs: PubmedPdfBreadcrumbsData[] = [
{ id: `a-${initial}`, name: initial, link: PubmedPdfUtils.getAuthorInitialUrl(initial) }
];
return (
<div className="pubmedpdf" >
<Helmet>
<title>{mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<PubmedPdfBreadcrumbs lang={lang} breadcrumbs={breadcrumbs} />
<hr />
<div className="authors">
<div className="author-group">
{authors.map((author) => {
return <span className="author" key={author.id}><Link to={PubmedPdfUtils.getAuthorUrl(author.id, 0)}>{Functions.mlang(author.name, lang)}</Link> ({author.count})</span>;
})}
</div>
const PubmedPdfAuthorsByInitial = (props: Props) => {
const { lang, initial } = props;
const name = PubmedPdfUtils.getName();
const mtitle = Functions.mlang(name, lang);
const authors = PubmedPdfUtils.getAuthors(initial);
const breadcrumbs: PubmedPdfBreadcrumbsData[] = [
{ id: `a-${initial}`, name: initial, link: PubmedPdfUtils.getAuthorInitialUrl(initial) },
];
return (
<div className="pubmedpdf">
<Helmet>
<title>
{mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<PubmedPdfBreadcrumbs lang={lang} breadcrumbs={breadcrumbs} />
<hr />
<div className="authors">
<div className="author-group">
{authors.map((author) => {
return (
<span className="author" key={author.id}>
<Link to={PubmedPdfUtils.getAuthorUrl(author.id, 0)}>
{Functions.mlang(author.name, lang)}
</Link>{' '}
({author.count})
</span>
);
})}
</div>
<hr />
</div>
);
}
}
<hr />
</div>
);
};
export default PubmedPdfAuthorsByInitial;
+77 -106
View File
@@ -1,123 +1,94 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import { HashLink } from 'react-router-hash-link';
import Loading from '../common/lib/Loading';
import { Helmet } from '@dr.pogodin/react-helmet';
import { Link } from 'react-router';
import HashLink from '../common/lib/HashLink';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import './assets/pubmedpdf.css';
import PubmedPdfUtils from './lib/PubmedPdfUtils';
interface Props {
lang: MultiLang;
}
interface State {
loading: boolean;
name: string;
}
class PubmedPdfIndex extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
name: '',
};
}
componentDidMount() {
this.isActive = true;
this.updatePage();
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang } = this.props;
if (prevProps.lang !== lang) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
await PubmedPdfUtils.initialize();
if (this.isActive) {
const name = PubmedPdfUtils.getName();
this.setState({ loading: false, name });
}
}
render() {
const { lang } = this.props;
const { loading, name } = this.state;
if (loading) {
return <Loading />;
}
if ('' === name) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(name, lang);
const authorInitials = PubmedPdfUtils.getAuthorInitials();
const years = PubmedPdfUtils.getYears();
const journalInitials = PubmedPdfUtils.getJournalInitials();
return (
<div className="pubmedpdf" >
<Helmet>
<title>{mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<nav className="header">
<div className="count">
<strong>{PubmedPdfUtils.getCountPapers()}</strong> papers registered
</div>
<div className="link">
<a href="https://www.ncbi.nlm.nih.gov/pubmed" target="_blank" rel="noopener noreferrer">[PubMed]</a>
</div>
</nav>
<h4 className="pt">{Functions.mlang('[en]Author[/en][ja]著者[/ja]', lang)}</h4>
<div className="initials">
{authorInitials.map((initial) => {
return <span className="initial" key={initial}><Link to={PubmedPdfUtils.getAuthorInitialUrl(initial)}>{initial}</Link></span>
})}
const PubmedPdfIndex = (props: Props) => {
const { lang } = props;
const name = PubmedPdfUtils.getName();
const mtitle = Functions.mlang(name, lang);
const authorInitials = PubmedPdfUtils.getAuthorInitials();
const years = PubmedPdfUtils.getYears();
const journalInitials = PubmedPdfUtils.getJournalInitials();
return (
<div className="pubmedpdf">
<Helmet>
<title>
{mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<nav className="header">
<div className="count">
<strong>{PubmedPdfUtils.getCountPapers()}</strong> papers registered
</div>
<h4 className="pt">{Functions.mlang('[en]Year[/en][ja]発行年[/ja]', lang)}</h4>
<div className="years">
{years.map((year) => {
return <div className="year" key={year.year}><Link to={PubmedPdfUtils.getYearUrl(year.year, 0)}>{year.year}</Link> ({year.count})</div>;
})}
<div className="link">
<a href="https://www.ncbi.nlm.nih.gov/pubmed" target="_blank" rel="noopener noreferrer">
[PubMed]
</a>
</div>
<h4 className="pt">{Functions.mlang('[en]Journal/Book[/en][ja]ジャーナル/書籍[/ja]', lang)}</h4>
<div className="journals">
{journalInitials.map((initial) => {
return <span className="initial" key={initial}><HashLink to={PubmedPdfUtils.getIndexUrl() + `#${initial}`}>{initial}</HashLink></span>
})}
{journalInitials.map((initial) => {
const journals = PubmedPdfUtils.getJournalsByInitial(initial);
return <div id={initial} className="journal-group" key={initial}>
</nav>
<h4 className="pt">{Functions.mlang('[en]Author[/en][ja]著者[/ja]', lang)}</h4>
<div className="initials">
{authorInitials.map((initial) => {
return (
<span className="initial" key={initial}>
<Link to={PubmedPdfUtils.getAuthorInitialUrl(initial)}>{initial}</Link>
</span>
);
})}
</div>
<h4 className="pt">{Functions.mlang('[en]Year[/en][ja]発行年[/ja]', lang)}</h4>
<div className="years">
{years.map((year) => {
return (
<div className="year" key={year.year}>
<Link to={PubmedPdfUtils.getYearUrl(year.year, 0)}>{year.year}</Link> ({year.count})
</div>
);
})}
</div>
<h4 className="pt">{Functions.mlang('[en]Journal/Book[/en][ja]ジャーナル/書籍[/ja]', lang)}</h4>
<div className="journals">
{journalInitials.map((initial) => {
return (
<span className="initial" key={initial}>
<HashLink to={`${PubmedPdfUtils.getIndexUrl()}#${initial}`}>{initial}</HashLink>
</span>
);
})}
{journalInitials.map((initial) => {
const journals = PubmedPdfUtils.getJournalsByInitial(initial);
return (
<div id={initial} className="journal-group" key={initial}>
<div className="title">{initial}</div>
{journals.map((journal) => {
const name = Functions.mlang(journal.name, lang);
const nameShort = name.substr(0, 20) + (name.length > 20 ? '...' : '');
return <div className="journal" key={journal.id}>
<Link to={PubmedPdfUtils.getJournalUrl(journal.id, 0)} title={name}>{nameShort}</Link> ({journal.count})
</div>;
const nameShort = name.slice(0, 20) + (name.length > 20 ? '...' : '');
return (
<div className="journal" key={journal.id}>
<Link to={PubmedPdfUtils.getJournalUrl(journal.id, 0)} title={name}>
{nameShort}
</Link>{' '}
({journal.count})
</div>
);
})}
</div>;
})}
</div>
</div>
);
})}
</div>
);
}
}
</div>
);
};
export default PubmedPdfIndex;
+43 -87
View File
@@ -1,103 +1,59 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import Loading from '../common/lib/Loading';
import { Helmet } from '@dr.pogodin/react-helmet';
import { Link } from 'react-router';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import './assets/pubmedpdf.css';
import PubmedPdfBreadcrumbs from './lib/PubmedPdfBreadcrumbs';
import PubmedPdfUtils, { PubmedPdfBreadcrumbsData } from './lib/PubmedPdfUtils';
import PubmedPdfUtils, { type PubmedPdfBreadcrumbsData } from './lib/PubmedPdfUtils';
interface Props {
lang: MultiLang;
year: number;
}
interface State {
loading: boolean;
name: string;
}
class PubmedPdfJournalsByYear extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
name: '',
};
const PubmedPdfJournalsByYear = (props: Props) => {
const { lang, year } = props;
const name = PubmedPdfUtils.getName();
const mtitle = Functions.mlang(name, lang);
const journals = PubmedPdfUtils.getJournalsByYear(year);
if (journals.length === 0) {
return <PageNotFound lang={lang} />;
}
componentDidMount() {
this.isActive = true;
this.updatePage();
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, year } = this.props;
if (prevProps.lang !== lang || prevProps.year !== year) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
await PubmedPdfUtils.initialize();
if (this.isActive) {
const name = PubmedPdfUtils.getName();
this.setState({ loading: false, name });
}
}
render() {
const { lang, year } = this.props;
const { loading, name } = this.state;
if (loading) {
return <Loading />;
}
if ('' === name) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(name, lang);
const journals = PubmedPdfUtils.getJournalsByYear(year);
if (journals.length === 0) {
return <PageNotFound lang={lang} />;
}
const breadcrumbs: PubmedPdfBreadcrumbsData[] = [
{ id: `y.${year}`, name: `${year}`, link: PubmedPdfUtils.getYearUrl(year, 0) }
];
return (
<div className="pubmedpdf">
<Helmet>
<title>{mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<PubmedPdfBreadcrumbs lang={lang} breadcrumbs={breadcrumbs} />
<hr />
<div className="journals">
<div className="journal-group">
{journals.map((journal) => {
const name = Functions.mlang(journal.name, lang);
const nameShort = name.substr(0, 20) + (name.length > 20 ? '...' : '');
return <div className="journal" key={journal.id}>
<Link to={PubmedPdfUtils.getYearUrl(year, journal.id)} title={name}>{nameShort}</Link> ({journal.count})
</div>;
})}
</div>
const breadcrumbs: PubmedPdfBreadcrumbsData[] = [
{ id: `y.${year}`, name: `${year}`, link: PubmedPdfUtils.getYearUrl(year, 0) },
];
return (
<div className="pubmedpdf">
<Helmet>
<title>
{mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<PubmedPdfBreadcrumbs lang={lang} breadcrumbs={breadcrumbs} />
<hr />
<div className="journals">
<div className="journal-group">
{journals.map((journal) => {
const name = Functions.mlang(journal.name, lang);
const nameShort = name.slice(0, 20) + (name.length > 20 ? '...' : '');
return (
<div className="journal" key={journal.id}>
<Link to={PubmedPdfUtils.getYearUrl(year, journal.id)} title={name}>
{nameShort}
</Link>{' '}
({journal.count})
</div>
);
})}
</div>
<hr />
</div>
);
}
}
<hr />
</div>
);
};
export default PubmedPdfJournalsByYear;
+76 -109
View File
@@ -1,123 +1,90 @@
import React, { Component, Fragment } from 'react';
import { Helmet } from 'react-helmet';
import Loading from '../common/lib/Loading';
import { Helmet } from '@dr.pogodin/react-helmet';
import { Fragment } from 'react';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import './assets/pubmedpdf.css';
import PubmedPdfUtils from './lib/PubmedPdfUtils';
interface Props {
lang: MultiLang;
id: number;
}
interface State {
loading: boolean;
name: string;
}
class PubmedPdfPaperDesc extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
name: '',
};
const PubmedPdfPaperDesc = (props: Props) => {
const { lang, id } = props;
const name = PubmedPdfUtils.getName();
const paper = PubmedPdfUtils.getPaper(id);
if (paper === null) {
return <PageNotFound lang={lang} />;
}
componentDidMount() {
this.isActive = true;
this.updatePage();
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang } = this.props;
if (prevProps.lang !== lang) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
await PubmedPdfUtils.initialize();
if (this.isActive) {
const name = PubmedPdfUtils.getName();
this.setState({ loading: false, name });
}
}
render() {
const { lang, id } = this.props;
const { loading, name } = this.state;
if (loading) {
return <Loading />;
}
if ('' === name) {
return <PageNotFound lang={lang} />;
}
const paper = PubmedPdfUtils.getPaper(id);
if (paper === null) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(name, lang);
const journal = PubmedPdfUtils.getJournal(paper.journal_id);
const title = Functions.mlang(paper.title, lang);
const journalName = journal !== null ? Functions.mlang(journal.name, lang) : '';
const pubmedLink = paper.pmid > 0 ? <a href={`https://www.ncbi.nlm.nih.gov/pubmed/${paper.pmid}`} target="_blank" rel="noopener noreferrer">{paper.pmid}</a> : '';
return (
<div className="pubmedpdf" >
<Helmet>
<title>{title} - {mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<NoticeSiteHasBeenArchived lang={lang} />
<div className="paper_desc">
<table className="outer">
<tbody>
<tr>
<td className="head">PMID</td>
<td className="odd">{pubmedLink}</td>
</tr>
<tr>
<td className="head">Title</td>
<td className="even">{title}</td>
</tr>
<tr>
<td className="head">Author</td>
<td className="odd">{paper.author_ids.map((authorId, index) => {
const author = PubmedPdfUtils.getAuthor(authorId);
return <Fragment key={authorId}>
{index !== 0 && (paper.author_ids.length - 1 !== index ? <>, </> : <> and </>)}
{author !== null && author.name}
</Fragment>;
})}</td>
</tr>
<tr>
<td className="head">Journal/Book</td>
<td className="even">{journalName}</td>
</tr>
<tr>
<td className="head">Year</td>
<td className="odd">{paper.year}</td>
</tr>
<tr>
<td className="head">vol/pp</td>
<td className="even">{paper.volume && `${paper.volume} / `}{paper.page}</td>
</tr>
</tbody>
</table>
</div>
</div>
const mtitle = Functions.mlang(name, lang);
const journal = PubmedPdfUtils.getJournal(paper.journal_id);
const title = Functions.mlang(paper.title, lang);
const journalName = journal !== null ? Functions.mlang(journal.name, lang) : '';
const pubmedLink =
paper.pmid > 0 ? (
<a href={`https://www.ncbi.nlm.nih.gov/pubmed/${paper.pmid}`} target="_blank" rel="noopener noreferrer">
{paper.pmid}
</a>
) : (
''
);
}
}
return (
<div className="pubmedpdf">
<Helmet>
<title>
{title} - {mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<NoticeSiteHasBeenArchived lang={lang} />
<div className="paper_desc">
<table className="outer">
<tbody>
<tr>
<td className="head">PMID</td>
<td className="odd">{pubmedLink}</td>
</tr>
<tr>
<td className="head">Title</td>
<td className="even">{title}</td>
</tr>
<tr>
<td className="head">Author</td>
<td className="odd">
{paper.author_ids.map((authorId, index) => {
const author = PubmedPdfUtils.getAuthor(authorId);
return (
<Fragment key={authorId}>
{index !== 0 &&
(paper.author_ids.length - 1 !== index ? <>, </> : <> and </>)}
{author?.name}
</Fragment>
);
})}
</td>
</tr>
<tr>
<td className="head">Journal/Book</td>
<td className="even">{journalName}</td>
</tr>
<tr>
<td className="head">Year</td>
<td className="odd">{paper.year}</td>
</tr>
<tr>
<td className="head">vol/pp</td>
<td className="even">
{paper.volume && `${paper.volume} / `}
{paper.page}
</td>
</tr>
</tbody>
</table>
</div>
</div>
);
};
export default PubmedPdfPaperDesc;
+53 -93
View File
@@ -1,15 +1,13 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import Loading from '../common/lib/Loading';
import { Helmet } from '@dr.pogodin/react-helmet';
import { Link } from 'react-router';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import './assets/pubmedpdf.css';
import PubmedPdfBreadcrumbs from './lib/PubmedPdfBreadcrumbs';
import PubmedPdfListItemPaper from './lib/PubmedPdfPaper';
import PubmedPdfUtils, { PubmedPdfBreadcrumbsData } from './lib/PubmedPdfUtils';
import PubmedPdfUtils, { type PubmedPdfBreadcrumbsData } from './lib/PubmedPdfUtils';
interface Props {
lang: MultiLang;
@@ -17,95 +15,57 @@ interface Props {
year: number;
}
interface State {
loading: boolean;
name: string;
}
class PubmedPdfPapersByAuthor extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
name: '',
};
const PubmedPdfPapersByAuthor = (props: Props) => {
const { lang, authorId, year } = props;
const name = PubmedPdfUtils.getName();
const mtitle = Functions.mlang(name, lang);
const author = PubmedPdfUtils.getAuthor(authorId);
if (author === null) {
return <PageNotFound lang={lang} />;
}
componentDidMount() {
this.isActive = true;
this.updatePage();
const initial = PubmedPdfUtils.getInitial(author.name);
const breadcrumbs: PubmedPdfBreadcrumbsData[] = [
{ id: `a-${initial}`, name: initial, link: PubmedPdfUtils.getAuthorInitialUrl(initial) },
{
id: `a.${authorId}`,
name: Functions.mlang(author.name, lang),
link: PubmedPdfUtils.getAuthorUrl(authorId, 0),
},
];
if (year !== 0) {
breadcrumbs.push({ id: `y.${year}`, name: `${year}`, link: PubmedPdfUtils.getAuthorUrl(authorId, year) });
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, authorId, year } = this.props;
if (prevProps.lang !== lang || prevProps.authorId !== authorId || prevProps.year !== year) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
await PubmedPdfUtils.initialize();
if (this.isActive) {
const name = PubmedPdfUtils.getName();
this.setState({ loading: false, name });
}
}
render() {
const { lang, authorId, year } = this.props;
const { loading, name } = this.state;
if (loading) {
return <Loading />;
}
if ('' === name) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(name, lang);
const author = PubmedPdfUtils.getAuthor(authorId);
if (author === null) {
return <PageNotFound lang={lang} />;
}
const initial = PubmedPdfUtils.getInitial(author.name);
const breadcrumbs: PubmedPdfBreadcrumbsData[] = [
{ id: `a-${initial}`, name: initial, link: PubmedPdfUtils.getAuthorInitialUrl(initial) },
{ id: `a.${authorId}`, name: Functions.mlang(author.name, lang), link: PubmedPdfUtils.getAuthorUrl(authorId, 0) }
];
if (year !== 0) {
breadcrumbs.push({ id: `y.${year}`, name: `${year}`, link: PubmedPdfUtils.getAuthorUrl(authorId, year) });
}
const papers = PubmedPdfUtils.getPapersByAuthorId(authorId, year);
const years = PubmedPdfUtils.getYearsByPapers(papers);
return (
<div className="pubmedpdf">
<Helmet>
<title>{mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<PubmedPdfBreadcrumbs lang={lang} breadcrumbs={breadcrumbs} />
<hr />
<div className="years">
{years.map((year) => {
return <div className="year" key={year.year}><Link to={PubmedPdfUtils.getAuthorUrl(authorId, year.year)}>{year.year}</Link> ({year.count})</div>;
})}
</div>
<hr />
<div className="papers">
{papers.map((paper) => {
return <PubmedPdfListItemPaper key={paper.id} lang={lang} paper={paper} />;
})}
</div>
const papers = PubmedPdfUtils.getPapersByAuthorId(authorId, year);
const years = PubmedPdfUtils.getYearsByPapers(papers);
return (
<div className="pubmedpdf">
<Helmet>
<title>
{mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<PubmedPdfBreadcrumbs lang={lang} breadcrumbs={breadcrumbs} />
<hr />
<div className="years">
{years.map((year) => {
return (
<div className="year" key={year.year}>
<Link to={PubmedPdfUtils.getAuthorUrl(authorId, year.year)}>{year.year}</Link> ({year.count}
)
</div>
);
})}
</div>
);
}
}
<hr />
<div className="papers">
{papers.map((paper) => {
return <PubmedPdfListItemPaper key={paper.id} lang={lang} paper={paper} />;
})}
</div>
</div>
);
};
export default PubmedPdfPapersByAuthor;
+50 -88
View File
@@ -1,15 +1,13 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import Loading from '../common/lib/Loading';
import { Helmet } from '@dr.pogodin/react-helmet';
import { Link } from 'react-router';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import './assets/pubmedpdf.css';
import PubmedPdfBreadcrumbs from './lib/PubmedPdfBreadcrumbs';
import PubmedPdfListItemPaper from './lib/PubmedPdfPaper';
import PubmedPdfUtils, { PubmedPdfBreadcrumbsData } from './lib/PubmedPdfUtils';
import PubmedPdfUtils, { type PubmedPdfBreadcrumbsData } from './lib/PubmedPdfUtils';
interface Props {
lang: MultiLang;
@@ -17,95 +15,59 @@ interface Props {
year: number;
}
interface State {
loading: boolean;
name: string;
}
class PubmedPdfPapersByJournal extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
name: '',
};
const PubmedPdfPapersByJournal = (props: Props) => {
const { lang, journalId, year } = props;
const name = PubmedPdfUtils.getName();
const mtitle = Functions.mlang(name, lang);
const journal = PubmedPdfUtils.getJournal(journalId);
if (journal === null) {
return <PageNotFound lang={lang} />;
}
componentDidMount() {
this.isActive = true;
this.updatePage();
const breadcrumbs: PubmedPdfBreadcrumbsData[] = [
{
id: `j.${journal.id}`,
name: Functions.mlang(journal.name, lang),
link: PubmedPdfUtils.getJournalUrl(journalId, 0),
},
];
if (year !== 0) {
breadcrumbs.push({ id: `y.${year}`, name: `${year}`, link: PubmedPdfUtils.getJournalUrl(journalId, year) });
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, journalId, year } = this.props;
if (prevProps.lang !== lang || prevProps.journalId !== journalId || prevProps.year !== year) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
await PubmedPdfUtils.initialize();
if (this.isActive) {
const name = PubmedPdfUtils.getName();
this.setState({ loading: false, name });
}
}
render() {
const { lang, journalId, year } = this.props;
const { loading, name } = this.state;
if (loading) {
return <Loading />;
}
if ('' === name) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(name, lang);
const journal = PubmedPdfUtils.getJournal(journalId);
if (journal === null) {
return <PageNotFound lang={lang} />;
}
const breadcrumbs: PubmedPdfBreadcrumbsData[] = [
{ id: `j.${journal.id}`, name: Functions.mlang(journal.name, lang), link: PubmedPdfUtils.getJournalUrl(journalId, 0) }
];
if (year !== 0) {
breadcrumbs.push({ id: `y.${year}`, name: `${year}`, link: PubmedPdfUtils.getJournalUrl(journalId, year) });
}
const papers = PubmedPdfUtils.getPapersByJournalId(journalId, year);
const years = PubmedPdfUtils.getYearsByPapers(papers);
return (
<div className="pubmedpdf">
<Helmet>
<title>{mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<PubmedPdfBreadcrumbs lang={lang} breadcrumbs={breadcrumbs} />
<hr />
{year === 0 && <>
const papers = PubmedPdfUtils.getPapersByJournalId(journalId, year);
const years = PubmedPdfUtils.getYearsByPapers(papers);
return (
<div className="pubmedpdf">
<Helmet>
<title>
{mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<PubmedPdfBreadcrumbs lang={lang} breadcrumbs={breadcrumbs} />
<hr />
{year === 0 && (
<>
<div className="years">
{years.map((year) => {
return <div className="year" key={year.year}><Link to={PubmedPdfUtils.getJournalUrl(journalId, year.year)}>{year.year}</Link> ({year.count})</div>;
return (
<div className="year" key={year.year}>
<Link to={PubmedPdfUtils.getJournalUrl(journalId, year.year)}>{year.year}</Link> (
{year.count})
</div>
);
})}
</div>
<hr />
</>}
<div className="papers">
{papers.map((paper) => {
return <PubmedPdfListItemPaper key={paper.id} lang={lang} paper={paper} />;
})}
</div>
</>
)}
<div className="papers">
{papers.map((paper) => {
return <PubmedPdfListItemPaper key={paper.id} lang={lang} paper={paper} />;
})}
</div>
);
}
}
</div>
);
};
export default PubmedPdfPapersByJournal;
+37 -82
View File
@@ -1,14 +1,12 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import Loading from '../common/lib/Loading';
import { Helmet } from '@dr.pogodin/react-helmet';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import './assets/pubmedpdf.css';
import PubmedPdfBreadcrumbs from './lib/PubmedPdfBreadcrumbs';
import PubmedPdfListItemPaper from './lib/PubmedPdfPaper';
import PubmedPdfUtils, { PubmedPdfBreadcrumbsData } from './lib/PubmedPdfUtils';
import PubmedPdfUtils, { type PubmedPdfBreadcrumbsData } from './lib/PubmedPdfUtils';
interface Props {
lang: MultiLang;
@@ -16,84 +14,41 @@ interface Props {
journalId: number;
}
interface State {
loading: boolean;
name: string;
}
class PubmedPdfPapersByYear extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
name: '',
};
const PubmedPdfPapersByYear = (props: Props) => {
const { lang, year, journalId } = props;
const name = PubmedPdfUtils.getName();
const mtitle = Functions.mlang(name, lang);
const journal = PubmedPdfUtils.getJournal(journalId);
if (journal === null) {
return <PageNotFound lang={lang} />;
}
componentDidMount() {
this.isActive = true;
this.updatePage();
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, year, journalId } = this.props;
if (prevProps.lang !== lang || prevProps.year !== year || prevProps.journalId !== journalId) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
await PubmedPdfUtils.initialize();
if (this.isActive) {
const name = PubmedPdfUtils.getName();
this.setState({ loading: false, name });
}
}
render() {
const { lang, year, journalId } = this.props;
const { loading, name } = this.state;
if (loading) {
return <Loading />;
}
if ('' === name) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(name, lang);
const journal = PubmedPdfUtils.getJournal(journalId);
if (journal === null) {
return <PageNotFound lang={lang} />;
}
const breadcrumbs: PubmedPdfBreadcrumbsData[] = [
{ id: `y.${year}`, name: `${year}`, link: PubmedPdfUtils.getYearUrl(year, 0) },
{ id: `j.${journal.id}`, name: Functions.mlang(journal.name, lang), link: PubmedPdfUtils.getYearUrl(year, journalId) }
];
const papers = PubmedPdfUtils.getPapersByJournalId(journalId, year);
return (
<div className="pubmedpdf">
<Helmet>
<title>{mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<PubmedPdfBreadcrumbs lang={lang} breadcrumbs={breadcrumbs} />
<hr />
<div className="papers">
{papers.map((paper) => {
return <PubmedPdfListItemPaper key={paper.id} lang={lang} paper={paper} />;
})}
</div>
const breadcrumbs: PubmedPdfBreadcrumbsData[] = [
{ id: `y.${year}`, name: `${year}`, link: PubmedPdfUtils.getYearUrl(year, 0) },
{
id: `j.${journal.id}`,
name: Functions.mlang(journal.name, lang),
link: PubmedPdfUtils.getYearUrl(year, journalId),
},
];
const papers = PubmedPdfUtils.getPapersByJournalId(journalId, year);
return (
<div className="pubmedpdf">
<Helmet>
<title>
{mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<PubmedPdfBreadcrumbs lang={lang} breadcrumbs={breadcrumbs} />
<hr />
<div className="papers">
{papers.map((paper) => {
return <PubmedPdfListItemPaper key={paper.id} lang={lang} paper={paper} />;
})}
</div>
);
}
}
</div>
);
};
export default PubmedPdfPapersByYear;
+22 -22
View File
@@ -2,54 +2,54 @@
.pubmedpdf .years::after,
.pubmedpdf .author-group::after,
.pubmedpdf .journal-group::after {
content: "";
display: block;
clear: both;
content: "";
display: block;
clear: both;
}
.pubmedpdf nav.header .count {
float: left;
float: left;
}
.pubmedpdf nav.header .link {
float: right;
float: right;
}
.pubmedpdf h4.pt {
border-bottom: 1px dashed #555;
width: 100%;
border-bottom: 1px dashed #555;
width: 100%;
}
.pubmedpdf span.initial:not(:first-child) {
margin-left: 0.5em;
margin-left: 0.5em;
}
.pubmedpdf .years .year {
float: left;
width: 12%;
float: left;
width: 12%;
}
.pubmedpdf .journal-group .title {
margin: 0.8em 0 0.3em;
padding: 5px;
background-color: #eff4f9;
margin: 0.8em 0 0.3em;
padding: 5px;
background-color: #eff4f9;
}
.pubmedpdf .journal-group .journal {
float: left;
width: 33%;
float: left;
width: 33%;
}
.pubmedpdf .author-group .author {
float: left;
width: 25%;
float: left;
width: 25%;
}
.pubmedpdf .papers .paper {
margin: 0.5em 0;
padding: 0.5em;
background-color: #eff4f9;
margin: 0.5em 0;
padding: 0.5em;
background-color: #eff4f9;
}
.pubmedpdf .paper_desc table td.head {
width: 150px;
}
width: 150px;
}
+28 -23
View File
@@ -1,36 +1,41 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { MultiLang } from '../../config';
import { Link } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import PubmedPdfUtils, { PubmedPdfBreadcrumbsData } from './PubmedPdfUtils';
import PubmedPdfUtils, { type PubmedPdfBreadcrumbsData } from './PubmedPdfUtils';
interface Props {
lang: MultiLang;
breadcrumbs: PubmedPdfBreadcrumbsData[];
}
const PubmedPdfBreadcrumbs: React.FC<Props> = (props: Props) => {
const PubmedPdfBreadcrumbs = (props: Props) => {
const { lang, breadcrumbs } = props;
const items: PubmedPdfBreadcrumbsData[] = [
{ id: 'h', name: '[en]Home[/en][ja]ホーム[/ja]', link: '/' },
{ id: 'm', name: PubmedPdfUtils.getName(), link: PubmedPdfUtils.getIndexUrl() }
{ id: 'm', name: PubmedPdfUtils.getName(), link: PubmedPdfUtils.getIndexUrl() },
];
return <div className="breadcrumbs">
{items.map((item, index) => {
const name = Functions.mlang(item.name, lang);
return <span key={item.id}>
{index !== 0 && <>&nbsp;&raquo;&nbsp;</>}
<Link to={item.link}>{name}</Link>
</span>;
})}
{breadcrumbs.map((item, index) => {
const name = Functions.mlang(item.name, lang);
return <span key={item.id}>
&nbsp;&raquo;&nbsp;
{index === (breadcrumbs.length - 1) ? name : <Link to={item.link}>{name}</Link>}
</span>;
})}
</div>;
}
return (
<div className="breadcrumbs">
{items.map((item, index) => {
const name = Functions.mlang(item.name, lang);
return (
<span key={item.id}>
{index !== 0 && <>&nbsp;&raquo;&nbsp;</>}
<Link to={item.link}>{name}</Link>
</span>
);
})}
{breadcrumbs.map((item, index) => {
const name = Functions.mlang(item.name, lang);
return (
<span key={item.id}>
&nbsp;&raquo;&nbsp;
{index === breadcrumbs.length - 1 ? name : <Link to={item.link}>{name}</Link>}
</span>
);
})}
</div>
);
};
export default PubmedPdfBreadcrumbs;
+41 -24
View File
@@ -1,38 +1,55 @@
import React, { Fragment } from 'react';
import { Link } from 'react-router-dom';
import { MultiLang } from '../../config';
import { Fragment } from 'react';
import { Link } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import PubmedPdfUtils, { PubmedPdfPaperData } from './PubmedPdfUtils';
import PubmedPdfUtils, { type PubmedPdfPaperData } from './PubmedPdfUtils';
interface Props {
lang: MultiLang;
paper: PubmedPdfPaperData;
}
const PubmedPdfListItemPaper: React.FC<Props> = (props: Props) => {
const PubmedPdfListItemPaper = (props: Props) => {
const { lang, paper } = props;
const url = PubmedPdfUtils.getPaperDescUrl(paper.id);
const journal = PubmedPdfUtils.getJournal(paper.journal_id);
const title = Functions.mlang(paper.title, lang);
const journalName = journal !== null ? Functions.mlang(journal.name, lang) : '';
const pubmedLink = paper.pmid > 0 ? <> [<a href={`https://www.ncbi.nlm.nih.gov/pubmed/${paper.pmid}`} target="_blank" rel="noopener noreferrer">PubMed: {paper.pmid}</a>]</> : '';
return <div className="paper">
<strong>
{paper.author_ids.map((authorId, index) => {
const author = PubmedPdfUtils.getAuthor(authorId);
return <Fragment key={authorId}>
{index !== 0 && (paper.author_ids.length - 1 !== index ? <>, </> : <> and </>)}
{author !== null && author.name}
</Fragment>;
})}
&nbsp;({paper.year}).
</strong><br />
<Link to={url}>{title}</Link><br />
<em>{journalName}</em>
{paper.volume !== '' && `, ${paper.volume}`}
{paper.page !== '' && `, ${paper.page}`}
.{pubmedLink}
</div>;
}
const pubmedLink =
paper.pmid > 0 ? (
<>
{' '}
[
<a href={`https://www.ncbi.nlm.nih.gov/pubmed/${paper.pmid}`} target="_blank" rel="noopener noreferrer">
PubMed: {paper.pmid}
</a>
]
</>
) : (
''
);
return (
<div className="paper">
<strong>
{paper.author_ids.map((authorId, index) => {
const author = PubmedPdfUtils.getAuthor(authorId);
return (
<Fragment key={authorId}>
{index !== 0 && (paper.author_ids.length - 1 !== index ? <>, </> : <> and </>)}
{author?.name}
</Fragment>
);
})}
&nbsp;({paper.year}).
</strong>
<br />
<Link to={url}>{title}</Link>
<br />
<em>{journalName}</em>
{paper.volume !== '' && `, ${paper.volume}`}
{paper.page !== '' && `, ${paper.page}`}.{pubmedLink}
</div>
);
};
export default PubmedPdfListItemPaper;
+63 -61
View File
@@ -1,5 +1,6 @@
import axios from 'axios';
import ky from 'ky';
import loki from 'lokijs';
import Config from '../../config';
export interface PubmedPdfAuthorData {
id: number;
@@ -39,12 +40,10 @@ export interface PubmedPdfIndexData {
export interface PubmedPdfBreadcrumbsData {
id: string;
name: string;
link: string
link: string;
}
class PubmedPdfUtils {
private isInitialized: boolean;
private pathname: string;
private database: loki;
private name: string;
@@ -54,42 +53,43 @@ class PubmedPdfUtils {
private years: Collection<PubmedPdfYearData>;
private authorInitials: string[];
private journalInitials: string[];
private initializing: Promise<boolean> | null;
constructor(path: string) {
this.isInitialized = false;
this.pathname = path;
this.database = new loki(path);
this.name = '';
this.authors = this.database.addCollection('authors');
this.journals = this.database.addCollection('journals');
this.papers = this.database.addCollection('papers');
this.years = this.database.addCollection('years');;
this.years = this.database.addCollection('years');
this.authorInitials = [];
this.journalInitials = [];
this.initializing = null;
}
getIndexUrl(): string {
return this.pathname + '/index.php';
return `${this.pathname}/index.php`;
}
getAuthorUrl(id: number, year: number): string {
return this.pathname + `/author.php?author=${id}` + (year !== 0 ? `&year=${year}` : '');
return `${this.pathname}/author.php?author=${id}${year !== 0 ? `&year=${year}` : ''}`;
}
getAuthorInitialUrl(initial: string): string {
return this.pathname + `/author.php?initial=${initial}`;
return `${this.pathname}/author.php?initial=${initial}`;
}
getYearUrl(year: number, journalId: number): string {
return this.pathname + `/year.php?year=${year}` + (journalId !== 0 ? `&journal=${journalId}` : '');
return `${this.pathname}/year.php?year=${year}${journalId !== 0 ? `&journal=${journalId}` : ''}`;
}
getJournalUrl(journalId: number, year: number): string {
return this.pathname + `/journal.php?journal=${journalId}` + (year !== 0 ? `&year=${year}` : '');
return `${this.pathname}/journal.php?journal=${journalId}${year !== 0 ? `&year=${year}` : ''}`;
}
getPaperDescUrl(id: number): string {
return this.pathname + `/paper_desc.php?id=${id}`;
return `${this.pathname}/paper_desc.php?id=${id}`;
}
getName(): string {
@@ -128,23 +128,23 @@ class PubmedPdfUtils {
}
count[paper.year]++;
});
const years = Object.keys(count).map((key) => parseInt(key));
years.sort();
const years = Object.keys(count).map((key) => parseInt(key, 10));
years.sort((a, b) => a - b);
return years.map((year) => {
return { year: year, count: count[year] };
});
}
getAuthors(initial?: string): PubmedPdfAuthorData[] {
const filter: any = {};
const filter: LokiQuery<PubmedPdfAuthorData & LokiObj> = {};
if (typeof initial !== 'undefined') {
filter.name = { '$regex': [`^${initial}`, 'i'] };
filter.name = { $regex: [`^${initial}`, 'i'] };
}
return this.authors.chain().find(filter).simplesort('name').data();
}
getJournalsByInitial(initial: string): PubmedPdfJournalData[] {
const filter = { name: { '$regex': [`^${initial}`, 'i'] } };
const filter = { name: { $regex: [`^${initial}`, 'i'] } };
return this.journals.chain().find(filter).simplesort('name').data();
}
@@ -159,18 +159,18 @@ class PubmedPdfUtils {
count[paper.journal_id]++;
});
return Object.keys(count).map((journalIdStr) => {
const journalId = parseInt(journalIdStr);
const journalId = parseInt(journalIdStr, 10);
const journal = this.getJournal(journalId);
return {
id: journalId,
name: journal !== null ? journal.name : '',
count: count[journalId]
count: count[journalId],
};
});
}
getPapersByAuthorId(authorId: number, year: number): PubmedPdfPaperData[] {
const filter: any = { author_ids: { '$contains': authorId } };
const filter: LokiQuery<PubmedPdfPaperData & LokiObj> = { author_ids: { $contains: authorId } };
if (year !== 0) {
filter.year = year;
}
@@ -178,7 +178,7 @@ class PubmedPdfUtils {
}
getPapersByJournalId(journalId: number, year: number): PubmedPdfPaperData[] {
const filter: any = { journal_id: journalId };
const filter: LokiQuery<PubmedPdfPaperData & LokiObj> = { journal_id: journalId };
if (year !== 0) {
filter.year = year;
}
@@ -189,51 +189,53 @@ class PubmedPdfUtils {
return this.papers.count();
}
async initialize(): Promise<boolean> {
if (!this.isInitialized) {
try {
const url = this.pathname + '/index.json';
const response = await axios.get(url);
const index = response.data as PubmedPdfIndexData;
this.name = index.name;
index.author.forEach((value) => {
const initial = this.getInitial(value.name);
if (this.authorInitials.indexOf(initial) === -1) {
this.authorInitials.push(initial);
}
this.authors.insert(value);
});
this.authorInitials.sort();
index.journal.forEach((value) => {
const initial = this.getInitial(value.name);
if (this.journalInitials.indexOf(initial) === -1) {
this.journalInitials.push(initial);
}
this.journals.insert(value);
});
this.journalInitials.sort();
index.paper.forEach((value) => {
const year = this.years.findOne({ year: value.year });
if (year !== null) {
year.count++;
this.years.update(year);
} else {
this.years.insert({ year: value.year, count: 1 });
}
this.papers.insert(value);
});
} catch (err) {
// ignore
}
this.isInitialized = true;
/**
* Loads the module index once. Concurrent callers share the same request,
* so the collections are never filled twice.
*/
initialize = (): Promise<boolean> => {
if (this.initializing === null) {
this.initializing = ky
.get(new URL(`${Config.BASE_URL}${this.pathname}/index.json`, window.location.href))
.json<PubmedPdfIndexData>()
.then((index) => {
this.name = index.name;
index.author.forEach((value) => {
const initial = this.getInitial(value.name);
if (!this.authorInitials.includes(initial)) {
this.authorInitials.push(initial);
}
this.authors.insert(value);
});
this.authorInitials.sort();
index.journal.forEach((value) => {
const initial = this.getInitial(value.name);
if (!this.journalInitials.includes(initial)) {
this.journalInitials.push(initial);
}
this.journals.insert(value);
});
this.journalInitials.sort();
index.paper.forEach((value) => {
const year = this.years.findOne({ year: value.year });
if (year !== null) {
year.count++;
this.years.update(year);
} else {
this.years.insert({ year: value.year, count: 1 });
}
this.papers.insert(value);
});
return true;
})
.catch(() => false);
}
return this.isInitialized;
}
return this.initializing;
};
getInitial(name: string) {
return name.charAt(0).toUpperCase();
}
}
export default new PubmedPdfUtils('/modules/PubMedPDF');
-1
View File
@@ -1 +0,0 @@
/// <reference types="react-scripts" />
+20
View File
@@ -0,0 +1,20 @@
/*
* The theme's widths and paddings are content-box measurements; sanitize.css
* makes every element border-box.
*/
*,
::before,
::after {
box-sizing: content-box;
}
/* Controls and tables are laid out as border-box, which is what the theme
assumes when it sizes them. */
button,
select,
table,
input[type="button"],
input[type="reset"],
input[type="submit"] {
box-sizing: border-box;
}
-143
View File
@@ -1,143 +0,0 @@
// This optional code is used to register a service worker.
// register() is not called by default.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on subsequent visits to a page, after all the
// existing tabs open on the page have been closed, since previously cached
// resources are updated in the background.
// To learn more about the benefits of this model and instructions on how to
// opt-in, read https://bit.ly/CRA-PWA
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
type Config = {
onSuccess?: (registration: ServiceWorkerRegistration) => void;
onUpdate?: (registration: ServiceWorkerRegistration) => void;
};
export function register(config?: Config) {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(
(process as { env: { [key: string]: string } }).env.PUBLIC_URL,
window.location.href
);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Let's check if a service worker still exists or not.
checkValidServiceWorker(swUrl, config);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://bit.ly/CRA-PWA'
);
});
} else {
// Is not localhost. Just register service worker
registerValidSW(swUrl, config);
}
});
}
}
function registerValidSW(swUrl: string, config?: Config) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker == null) {
return;
}
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the updated precached content has been fetched,
// but the previous service worker will still serve the older
// content until all client tabs are closed.
console.log(
'New content is available and will be used when all ' +
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
);
// Execute callback
if (config && config.onUpdate) {
config.onUpdate(registration);
}
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
// Execute callback
if (config && config.onSuccess) {
config.onSuccess(registration);
}
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl: string, config?: Config) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
const contentType = response.headers.get('content-type');
if (
response.status === 404 ||
(contentType != null && contentType.indexOf('javascript') === -1)
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl, config);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}
+76 -57
View File
@@ -1,7 +1,9 @@
import React from 'react';
import { Redirect, Route, RouteComponentProps, Switch } from 'react-router-dom';
import { Navigate, Route, Routes, useLocation } from 'react-router';
import Loading from '../common/lib/Loading';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import useInitialized from '../common/lib/useInitialized';
import type { MultiLang } from '../config';
import XwordsUtils from './lib/XwordsUtils';
import XwordsCategory from './XwordsCategory';
import XwordsEntry from './XwordsEntry';
import XwordsIndex from './XwordsIndex';
@@ -12,63 +14,80 @@ interface Props {
lang: MultiLang;
}
const useParams = () => new URLSearchParams(useLocation().search);
const intParam = (params: URLSearchParams, key: string, defaultValue: string): number => {
const value = params.get(key) || defaultValue;
return /^[0-9]+$/.test(value) ? parseInt(value, 10) : 0;
};
const CategoryPage = (props: Props) => {
const params = useParams();
return (
<XwordsCategory
lang={props.lang}
catId={intParam(params, 'categoryID', '0')}
start={intParam(params, 'start', '0')}
/>
);
};
const LetterPage = (props: Props) => {
const params = useParams();
return (
<XwordsLetter
lang={props.lang}
catId={intParam(params, 'categoryID', '0')}
initial={params.get('init') || ''}
start={intParam(params, 'start', '0')}
/>
);
};
const EntryPage = (props: Props) => {
const params = useParams();
return <XwordsEntry lang={props.lang} entryId={intParam(params, 'entryID', '0')} />;
};
const SearchPage = (props: Props) => {
const params = useParams();
return (
<XwordsSearch
lang={props.lang}
type={intParam(params, 'type', '4')}
catId={intParam(params, 'catID', '0')}
andor={params.get('andor') || 'OR'}
term={params.get('term') || ''}
start={intParam(params, 'start', '0')}
/>
);
};
const IndexRedirect = () => {
const { search, hash } = useLocation();
return <Navigate to={`${XwordsUtils.getIndexUrl()}${search}${hash}`} replace />;
};
const Xwords = (props: Props) => {
const { lang } = props;
const pathname = '/modules/xwords';
const status = useInitialized(XwordsUtils.initialize);
if (status === null) {
return <Loading />;
}
if (!status) {
return <PageNotFound lang={lang} />;
}
return (
<>
<Switch>
<Route exact path={`${pathname}/index.php`} render={() => {
return <XwordsIndex lang={lang} />;
}} />
<Route exact path={`${pathname}/category.php`} render={(props: RouteComponentProps) => {
const { location } = props;
const params = new URLSearchParams(location.search);
const catIdStr = params.get('categoryID') || '0';
const catId = /^[0-9]+$/.test(catIdStr) ? parseInt(catIdStr) : 0;
const startStr = params.get('start') || '0';
const start = /^[0-9]+$/.test(startStr) ? parseInt(startStr) : 0;
return <XwordsCategory lang={lang} catId={catId} start={start} />;
}} />
<Route exact path={`${pathname}/letter.php`} render={(props: RouteComponentProps) => {
const { location } = props;
const params = new URLSearchParams(location.search);
const catIdStr = params.get('categoryID') || '0';
const catId = /^[0-9]+$/.test(catIdStr) ? parseInt(catIdStr) : 0;
const initial = params.get('init') || '';
const startStr = params.get('start') || '0';
const start = /^[0-9]+$/.test(startStr) ? parseInt(startStr) : 0;
return <XwordsLetter lang={lang} catId={catId} initial={initial} start={start} />;
}} />
<Route exact path={`${pathname}/entry.php`} render={(props: RouteComponentProps) => {
const { location } = props;
const params = new URLSearchParams(location.search);
const entryIdStr = params.get('entryID') || '0';
const entryId = /^[0-9]+$/.test(entryIdStr) ? parseInt(entryIdStr) : 0;
return <XwordsEntry lang={lang} entryId={entryId} />;
}} />
<Route exact path={`${pathname}/search.php`} render={(props: RouteComponentProps) => {
const { location } = props;
const params = new URLSearchParams(location.search);
const typeStr = params.get('type') || '4';
const type = /^[0-9]+$/.test(typeStr) ? parseInt(typeStr) : 0;
const catIdStr = params.get('catID') || '0';
const catId = /^[0-9]+$/.test(catIdStr) ? parseInt(catIdStr) : 0;
const andor = params.get('andor') || 'OR';
const term = params.get('term') || '';
const startStr = params.get('start') || '0';
const start = /^[0-9]+$/.test(startStr) ? parseInt(startStr) : 0;
return <XwordsSearch lang={lang} type={type} catId={catId} andor={andor} term={term} start={start} />
}} />
<Route exact path={pathname} render={(props: RouteComponentProps) => {
const { location } = props;
const url = pathname + '/index.php' + location.search + location.hash;
return <Redirect to={url} />
}} />
<Route component={PageNotFound} />
</Switch>
</>
<Routes>
<Route index element={<IndexRedirect />} />
<Route path="index.php" element={<XwordsIndex lang={lang} />} />
<Route path="category.php" element={<CategoryPage lang={lang} />} />
<Route path="letter.php" element={<LetterPage lang={lang} />} />
<Route path="entry.php" element={<EntryPage lang={lang} />} />
<Route path="search.php" element={<SearchPage lang={lang} />} />
<Route path="*" element={<PageNotFound lang={lang} />} />
</Routes>
);
}
};
export default Xwords;
+75 -105
View File
@@ -1,10 +1,8 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import Loading from '../common/lib/Loading';
import { Helmet } from '@dr.pogodin/react-helmet';
import { Link } from 'react-router';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import './assets/xwords.css';
import XwordsBreadcrumbs from './lib/XwordsBreadcrumbs';
@@ -19,20 +17,35 @@ interface CategoryListProps {
lang: MultiLang;
}
const CategoryList: React.FC<CategoryListProps> = (props: CategoryListProps) => {
const CategoryList = (props: CategoryListProps) => {
const { lang } = props;
const categories = XwordsUtils.getCategories();
const title = Functions.mlang('[en]List of Categories[/en][ja]分類説明一覧[/ja]', lang);
return <div className="categories">
<h4 className="title">{title}</h4>
{categories.map((category) => {
return <div key={category.id} className="category">
<Link className="link" to={XwordsUtils.getCategoryUrl(category.id)}>{Functions.mlang(XwordsUtils.getCategoryName(category.id), lang)}</Link>
<span className="num">[{Functions.mlang('[en]Number of entries:[/en][ja]登録数[/ja]' + category.total + '[en]entries[/en][ja]語[/ja]', lang)}]</span>
</div>;
})}
</div>
}
return (
<div className="categories">
<h4 className="title">{title}</h4>
{categories.map((category) => {
return (
<div key={category.id} className="category">
<Link className="link" to={XwordsUtils.getCategoryUrl(category.id)}>
{Functions.mlang(XwordsUtils.getCategoryName(category.id), lang)}
</Link>
<span className="num">
[
{Functions.mlang(
'[en]Number of entries:[/en][ja]登録数[/ja]' +
category.total +
'[en]entries[/en][ja]語[/ja]',
lang
)}
]
</span>
</div>
);
})}
</div>
);
};
interface Props {
lang: MultiLang;
@@ -40,95 +53,52 @@ interface Props {
start: number;
}
interface State {
loading: boolean;
name: string | null;
}
class XwordsCategory extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
name: null,
};
const XwordsCategory = (props: Props) => {
const { lang, catId, start } = props;
const name = XwordsUtils.getName();
const mtitle = Functions.mlang(name, lang);
const ctitle = Functions.mlang(XwordsUtils.getCategoryName(catId), lang);
if (ctitle === '') {
return <PageNotFound lang={lang} />;
}
componentDidMount() {
this.isActive = true;
this.updatePage();
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, catId, start } = this.props;
if (prevProps.lang !== lang || prevProps.catId !== catId || prevProps.start !== start) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
await XwordsUtils.initialize();
if (this.isActive) {
const name = XwordsUtils.getName();
this.setState({ loading: false, name });
}
}
render() {
const { lang, catId, start } = this.props;
const { loading, name } = this.state;
if (loading) {
return <Loading />;
}
if (null === name) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(name, lang);
const ctitle = Functions.mlang(XwordsUtils.getCategoryName(catId), lang);
if (ctitle === '') {
return <PageNotFound lang={lang} />;
}
const title = catId === 0 ? Functions.mlang('[en]List of Categories[/en][ja]分類説明一覧[/ja]', lang) : Functions.mlang('[en]Category[/en][ja]用途別分類[/ja] : ', lang) + ctitle;
const baseUrl = XwordsUtils.getCategoryUrl(catId);
const result = {
total: XwordsUtils.getCountEntries(catId, ''),
entries: XwordsUtils.getEntries(catId, '', start)
};
return (
<div className="xwords">
<Helmet>
<title>{title} - {mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{title}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<XwordsBreadcrumbs lang={lang} catId={catId} />
<div className="row">
<XwordsCategoryFieldset lang={lang} />
</div>
<div className="row">
<XwordsInitialFieldset lang={lang} catId={catId} />
</div>
{catId === 0 && <CategoryList lang={lang} />}
{catId !== 0 &&
<>
<div className="row two">
<XwordsRecentlyFieldset lang={lang} catId={catId} />
<XwordsRankingFieldset lang={lang} catId={catId} />
</div>
<h4 className="title">{Functions.mlang(XwordsUtils.getCategoryName(catId), lang)}</h4>
<XwordsEntries lang={lang} baseUrl={baseUrl} result={result} start={start} />
</>
}
const title =
catId === 0
? Functions.mlang('[en]List of Categories[/en][ja]分類説明一覧[/ja]', lang)
: Functions.mlang('[en]Category[/en][ja]用途別分類[/ja] : ', lang) + ctitle;
const baseUrl = XwordsUtils.getCategoryUrl(catId);
const result = {
total: XwordsUtils.getCountEntries(catId, ''),
entries: XwordsUtils.getEntries(catId, '', start),
};
return (
<div className="xwords">
<Helmet>
<title>
{title} - {mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{title}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<XwordsBreadcrumbs lang={lang} catId={catId} />
<div className="row">
<XwordsCategoryFieldset lang={lang} />
</div>
);
}
}
<div className="row">
<XwordsInitialFieldset lang={lang} catId={catId} />
</div>
{catId === 0 && <CategoryList lang={lang} />}
{catId !== 0 && (
<>
<div className="row two">
<XwordsRecentlyFieldset lang={lang} catId={catId} />
<XwordsRankingFieldset lang={lang} catId={catId} />
</div>
<h4 className="title">{Functions.mlang(XwordsUtils.getCategoryName(catId), lang)}</h4>
<XwordsEntries lang={lang} baseUrl={baseUrl} result={result} start={start} />
</>
)}
</div>
);
};
export default XwordsCategory;
+41 -86
View File
@@ -1,9 +1,8 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import Loading from '../common/lib/Loading';
import { Helmet } from '@dr.pogodin/react-helmet';
import { format } from 'date-fns';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import './assets/xwords.css';
import XwordsBreadcrumbs from './lib/XwordsBreadcrumbs';
@@ -16,92 +15,48 @@ interface Props {
entryId: number;
}
interface State {
loading: boolean;
name: string | null;
}
class XwordsEntry extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
name: null,
};
const XwordsEntry = (props: Props) => {
const { lang, entryId } = props;
const name = XwordsUtils.getName();
const entry = XwordsUtils.getEntry(entryId);
if (null == entry) {
return <PageNotFound lang={lang} />;
}
componentDidMount() {
this.isActive = true;
this.updatePage();
}
const mtitle = Functions.mlang(name, lang);
const title = Functions.mlang(entry.term, lang);
const date = format(new Date(entry.timestamp * 1000), lang === 'en' ? 'MMMM do, yyyy' : 'yyyy年M月d日');
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, entryId } = this.props;
if (prevProps.lang !== lang || prevProps.entryId !== entryId) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
await XwordsUtils.initialize();
if (this.isActive) {
const name = XwordsUtils.getName();
this.setState({ loading: false, name });
}
}
render() {
const { lang, entryId } = this.props;
const { loading, name } = this.state;
if (loading) {
return <Loading />;
}
if (null === name) {
return <PageNotFound lang={lang} />;
}
const entry = XwordsUtils.getEntry(entryId);
if (null == entry) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(name, lang);
const title = Functions.mlang(entry.term, lang);
const date = lang === 'en' ? Functions.formatDate(entry.timestamp, 'MMMM Do, YYYY') : Functions.formatDate(entry.timestamp, 'YYYY年M月D日');
return (
<div className="xwords">
<Helmet>
<title>{title} - {mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{title}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<XwordsBreadcrumbs lang={lang} catId={entry.cat_id} initial={entry.initial} entryId={entry.id} />
<div className="row">
<XwordsCategoryFieldset lang={lang} />
</div>
<div className="row">
<XwordsInitialFieldset lang={lang} catId={entry.cat_id} />
</div>
<div className="entry">
<h4 className="title">{Functions.mlang(title, lang)}</h4>
<div className="description">
<div className="yomi">{Functions.mlang('[en]Yomi[/en][ja]読み[/ja] : ' + entry.yomi, lang)}</div>
<div className="definition">{Functions.mlang(entry.definition, lang)}</div>
<div className="note">
<span className="date">{Functions.mlang('[en]Date[/en][ja]投稿日[/ja]', lang)} : {date}</span>
</div>
return (
<div className="xwords">
<Helmet>
<title>
{title} - {mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{title}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<XwordsBreadcrumbs lang={lang} catId={entry.cat_id} initial={entry.initial} entryId={entry.id} />
<div className="row">
<XwordsCategoryFieldset lang={lang} />
</div>
<div className="row">
<XwordsInitialFieldset lang={lang} catId={entry.cat_id} />
</div>
<div className="entry">
<h4 className="title">{Functions.mlang(title, lang)}</h4>
<div className="description">
<div className="yomi">{Functions.mlang(`[en]Yomi[/en][ja]読み[/ja] : ${entry.yomi}`, lang)}</div>
<div className="definition">{Functions.mlang(entry.definition, lang)}</div>
<div className="note">
<span className="date">
{Functions.mlang('[en]Date[/en][ja]投稿日[/ja]', lang)} : {date}
</span>
</div>
</div>
</div>
);
}
}
</div>
);
};
export default XwordsEntry;
+33 -83
View File
@@ -1,9 +1,6 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import Loading from '../common/lib/Loading';
import { Helmet } from '@dr.pogodin/react-helmet';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import './assets/xwords.css';
import XwordsBreadcrumbs from './lib/XwordsBreadcrumbs';
@@ -15,87 +12,40 @@ import XwordsRecentlyFieldset from './lib/XwordsRecentlyFieldset';
import XwordsSearchFieldset from './lib/XwordsSearchFieldset';
import XwordsUtils from './lib/XwordsUtils';
interface Props {
lang: MultiLang;
}
interface State {
loading: boolean;
name: string;
}
class XwordsIndex extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
name: '',
};
}
componentDidMount() {
this.isActive = true;
this.updatePage();
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang } = this.props;
if (prevProps.lang !== lang) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
await XwordsUtils.initialize();
if (this.isActive) {
const name = XwordsUtils.getName();
this.setState({ loading: false, name });
}
}
render() {
const { lang } = this.props;
const { loading, name } = this.state;
if (loading) {
return <Loading />;
}
if ('' === name) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(name, lang);
return (
<div className="xwords">
<Helmet>
<title>{mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<XwordsBreadcrumbs lang={lang} />
<div className="row">
<XwordsCategoryFieldset lang={lang} />
</div>
<div className="row">
<XwordsInitialFieldset lang={lang} catId={0} />
</div>
<div className="row three">
<XwordsRecentlyFieldset lang={lang} catId={0} />
<XwordsRankingFieldset lang={lang} catId={0} />
<XwordsRandomFieldset lang={lang} />
</div>
<div className="row">
<XwordsSearchFieldset lang={lang} type={4} catId={0} andor="OR" term="" />
</div>
const XwordsIndex = (props: Props) => {
const { lang } = props;
const name = XwordsUtils.getName();
const mtitle = Functions.mlang(name, lang);
return (
<div className="xwords">
<Helmet>
<title>
{mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{mtitle}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<XwordsBreadcrumbs lang={lang} />
<div className="row">
<XwordsCategoryFieldset lang={lang} />
</div>
);
}
}
<div className="row">
<XwordsInitialFieldset lang={lang} catId={0} />
</div>
<div className="row three">
<XwordsRecentlyFieldset lang={lang} catId={0} />
<XwordsRankingFieldset lang={lang} catId={0} />
<XwordsRandomFieldset lang={lang} />
</div>
<div className="row">
<XwordsSearchFieldset lang={lang} type={4} catId={0} andor="OR" term="" />
</div>
</div>
);
};
export default XwordsIndex;
+37 -85
View File
@@ -1,9 +1,7 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import Loading from '../common/lib/Loading';
import { Helmet } from '@dr.pogodin/react-helmet';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import './assets/xwords.css';
import XwordsBreadcrumbs from './lib/XwordsBreadcrumbs';
@@ -19,87 +17,41 @@ interface Props {
start: number;
}
interface State {
loading: boolean;
name: string | null;
}
class XwordsLetter extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
name: null,
};
const XwordsLetter = (props: Props) => {
const { lang, catId, initial, start } = props;
const name = XwordsUtils.getName();
const mtitle = Functions.mlang(name, lang);
const ctitle = Functions.mlang(XwordsUtils.getCategoryName(catId), lang);
const ititle = Functions.mlang(XwordsUtils.getInitialName(initial), lang);
if (ctitle === '' || ititle === '') {
return <PageNotFound lang={lang} />;
}
componentDidMount() {
this.isActive = true;
this.updatePage();
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, catId, initial } = this.props;
if (prevProps.lang !== lang || prevProps.catId !== catId || prevProps.initial !== initial) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
await XwordsUtils.initialize();
if (this.isActive) {
const name = XwordsUtils.getName();
this.setState({ loading: false, name });
}
}
render() {
const { lang, catId, initial, start } = this.props;
const { loading, name } = this.state;
if (loading) {
return <Loading />;
}
if (null === name) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(name, lang);
const ctitle = Functions.mlang(XwordsUtils.getCategoryName(catId), lang);
const ititle = Functions.mlang(XwordsUtils.getInitialName(initial), lang);
if (ctitle === '' || ititle === '') {
return <PageNotFound lang={lang} />;
}
const title = Functions.mlang('[en]Initial[/en][ja]頭文字[/ja] : ', lang) + ititle;
const baseUrl = XwordsUtils.getLetterUrl(initial, catId);
const result = {
total: XwordsUtils.getCountEntries(catId, initial),
entries: XwordsUtils.getEntries(catId, initial, start)
};
return (
<div className="xwords">
<Helmet>
<title>{ititle} - {ctitle} - {mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{title}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<XwordsBreadcrumbs lang={lang} catId={catId} initial={initial} />
<div className="row">
<XwordsCategoryFieldset lang={lang} />
</div>
<div className="row">
<XwordsInitialFieldset lang={lang} catId={catId} />
</div>
<h4 className="title">{Functions.mlang(XwordsUtils.getInitialName(initial), lang)}</h4>
<XwordsEntries lang={lang} baseUrl={baseUrl} result={result} start={start} />
const title = Functions.mlang('[en]Initial[/en][ja]頭文字[/ja] : ', lang) + ititle;
const baseUrl = XwordsUtils.getLetterUrl(initial, catId);
const result = {
total: XwordsUtils.getCountEntries(catId, initial),
entries: XwordsUtils.getEntries(catId, initial, start),
};
return (
<div className="xwords">
<Helmet>
<title>
{ititle} - {ctitle} - {mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{title}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<XwordsBreadcrumbs lang={lang} catId={catId} initial={initial} />
<div className="row">
<XwordsCategoryFieldset lang={lang} />
</div>
);
}
}
<div className="row">
<XwordsInitialFieldset lang={lang} catId={catId} />
</div>
<h4 className="title">{Functions.mlang(XwordsUtils.getInitialName(initial), lang)}</h4>
<XwordsEntries lang={lang} baseUrl={baseUrl} result={result} start={start} />
</div>
);
};
export default XwordsLetter;
+39 -83
View File
@@ -1,15 +1,12 @@
import React, { Component } from 'react';
import { Helmet } from 'react-helmet';
import Loading from '../common/lib/Loading';
import { Helmet } from '@dr.pogodin/react-helmet';
import NoticeSiteHasBeenArchived from '../common/lib/NoticeSiteHasBeenArchived';
import PageNotFound from '../common/lib/PageNotFound';
import { MultiLang } from '../config';
import type { MultiLang } from '../config';
import Functions from '../functions';
import './assets/xwords.css';
import XwordsBreadcrumbs from './lib/XwordsBreadcrumbs';
import XwordsEntries from './lib/XwordsEntries';
import XwordsSearchFieldset from './lib/XwordsSearchFieldset';
import XwordsUtils, { XwordsSearchResult } from './lib/XwordsUtils';
import XwordsUtils from './lib/XwordsUtils';
interface Props {
lang: MultiLang;
@@ -20,82 +17,41 @@ interface Props {
start: number;
}
interface State {
loading: boolean;
name: string | null;
result: XwordsSearchResult;
}
class XwordsSearch extends Component<Props, State> {
private isActive: boolean;
constructor(props: Props) {
super(props);
this.isActive = false;
this.state = {
loading: true,
name: null,
result: { total: 0, entries: [] },
};
}
componentDidMount() {
this.isActive = true;
this.updatePage();
}
componentDidUpdate(prevProps: Props, prevState: State) {
const { lang, type, catId, andor, term, start } = this.props;
if (prevProps.lang !== lang || prevProps.type !== type || prevProps.catId !== catId || prevProps.andor !== andor || prevProps.term !== term || prevProps.start !== start) {
this.updatePage();
}
}
componentWillUnmount() {
this.isActive = false;
}
async updatePage() {
await XwordsUtils.initialize();
if (this.isActive) {
const { type, catId, andor, term, start } = this.props;
const name = XwordsUtils.getName();
const result = XwordsUtils.search(type, catId, andor, term, start);
this.setState({ loading: false, name, result });
}
}
render() {
const { lang, type, catId, andor, term, start } = this.props;
const { loading, name, result } = this.state;
if (loading) {
return <Loading />;
}
if (name === null) {
return <PageNotFound lang={lang} />;
}
const mtitle = Functions.mlang(name, lang);
const title = Functions.mlang('[en]Search[/en][ja]検索[/ja]', lang);
const baseUrl = XwordsUtils.getSearchUrl(type, catId, andor, term);
const etitle = result.total === 0 ?
Functions.mlang('[en]No entries found.[/en][ja]該当なし。再度お試しください。[/ja]', lang) :
Functions.mlang('[en]' + result.total + ' entries found.[/en][ja]上記の条件で ' + result.total + ' 件見つかりました。[/ja]', lang);
return (
<div className="xwords">
<Helmet>
<title>{title} - {mtitle} - {Functions.siteTitle(lang)}</title>
</Helmet>
<h3>{title}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<XwordsBreadcrumbs lang={lang} isSearch={true} />
<div className="row">
<XwordsSearchFieldset lang={lang} type={type} catId={catId} andor={andor} term={term} />
</div>
<h4 className="title">{etitle}</h4>
{result.total > 0 && <XwordsEntries lang={lang} baseUrl={baseUrl} result={result} start={start} />}
const XwordsSearch = (props: Props) => {
const { lang, type, catId, andor, term, start } = props;
const name = XwordsUtils.getName();
const mtitle = Functions.mlang(name, lang);
const title = Functions.mlang('[en]Search[/en][ja]検索[/ja]', lang);
const result = XwordsUtils.search(type, catId, andor, term, start);
const baseUrl = XwordsUtils.getSearchUrl(type, catId, andor, term);
const etitle =
result.total === 0
? Functions.mlang('[en]No entries found.[/en][ja]該当なし。再度お試しください。[/ja]', lang)
: Functions.mlang(
'[en]' +
result.total +
' entries found.[/en][ja]上記の条件で ' +
result.total +
' 件見つかりました。[/ja]',
lang
);
return (
<div className="xwords">
<Helmet>
<title>
{title} - {mtitle} - {Functions.siteTitle(lang)}
</title>
</Helmet>
<h3>{title}</h3>
<NoticeSiteHasBeenArchived lang={lang} />
<XwordsBreadcrumbs lang={lang} isSearch={true} />
<div className="row">
<XwordsSearchFieldset lang={lang} type={type} catId={catId} andor={andor} term={term} />
</div>
);
}
}
<h4 className="title">{etitle}</h4>
{result.total > 0 && <XwordsEntries lang={lang} baseUrl={baseUrl} result={result} start={start} />}
</div>
);
};
export default XwordsSearch;
+65 -65
View File
@@ -1,148 +1,148 @@
.xwords .row {
font-size: 90%;
font-size: 90%;
}
.xwords .row fieldset.item {
border: 1px solid #777788;
margin: 1em 0em;
text-align: left;
background-color: transparent;
border: 1px solid #777788;
margin: 1em 0em;
text-align: left;
background-color: transparent;
}
.xwords .row.two fieldset.item {
display: inline-block;
width: 49%;
vertical-align: top;
display: inline-block;
width: 49%;
vertical-align: top;
}
.xwords .row.two fieldset.item:not(:last-child) {
margin-right: 2%;
margin-right: 2%;
}
.xwords .row.three fieldset.item {
display: inline-block;
width: 32%;
vertical-align: top;
display: inline-block;
width: 32%;
vertical-align: top;
}
.xwords .row.three fieldset.item:not(:last-child) {
margin-right: 2%;
margin-right: 2%;
}
.xwords .row fieldset.item legend.title {
padding: 2px 5px;
background: #2f5376;
color: #ffffff;
border-bottom: 1px solid #000000;
padding: 2px 5px;
background: #2f5376;
color: #ffffff;
border-bottom: 1px solid #000000;
}
.xwords .row fieldset.item div.body {
margin: 1em;
line-height: 1.5;
text-align: center;
margin: 1em;
line-height: 1.5;
text-align: center;
}
.xwords .row fieldset.item.category div.body span {
margin: 0 5px;
margin: 0 5px;
}
.xwords .row fieldset.item.initial div.body span {
margin: 0 8px;
margin: 0 8px;
}
.xwords .row fieldset.item div.body span.info {
font-size: 90%;
color: #333333;
font-size: 90%;
color: #333333;
}
.xwords .row fieldset.item.recently div.body span.info {
margin-left: 3px;
margin-left: 3px;
}
.xwords .row fieldset.item.ranking div.body span.info {
margin-right: 3px;
margin-right: 3px;
}
.xwords .row fieldset.item.search div.body dl {
margin: 1em 0;
margin: 1em 0;
}
.xwords .row fieldset.item.search div.body dl dt {
width: 25%;
text-align: right;
float: left;
margin: 0 0.5em 0 0;
width: 25%;
text-align: right;
float: left;
margin: 0 0.5em 0 0;
}
.xwords .row fieldset.item.search div.body dl dd {
text-align: left;
clear: right;
text-align: left;
clear: right;
}
.xwords .row fieldset.item div.body a {
font-weight: bold;
font-weight: bold;
}
.xwords .row fieldset.item div.body ul {
text-align: left;
padding-left: 0;
text-align: left;
padding-left: 0;
}
.xwords .row fieldset.item div.body ul li {
list-style-type: none;
list-style-type: none;
}
.xwords .row fieldset.item div.body .term {
text-align: left;
background-color: #f5f7f7;
text-align: left;
background-color: #f5f7f7;
}
.xwords .row fieldset.item div.body .definition {
text-align: left;
text-align: left;
}
.xwords .breadcrumbs {
font-size: 80%;
font-size: 80%;
}
.xwords h4.title {
text-align: center;
text-align: center;
}
.xwords .categories .category {
margin: 20px 0;
margin: 20px 0;
}
.xwords .categories .category .link {
padding: 3px 1px;
background-color: #cee1eb;
font-size: 1.1em;
font-weight: bold;
padding: 3px 1px;
background-color: #cee1eb;
font-size: 1.1em;
font-weight: bold;
}
.xwords .categories .category .num {
margin-left: 10px;
font-size: 0.6em;
color: #cd5c5c;
margin-left: 10px;
font-size: 0.6em;
color: #cd5c5c;
}
.xwords .entries .entry {
margin: 20px 0;
margin: 20px 0;
}
.xwords .entries .entry .link {
padding: 3px 1px;
background-color: #cee1eb;
font-size: 1.1em;
font-weight: bold;
padding: 3px 1px;
background-color: #cee1eb;
font-size: 1.1em;
font-weight: bold;
}
.xwords .entries .entry .description {
margin: 0.5em 0 0.5em 1em;
font-size: 0.9em;
margin: 0.5em 0 0.5em 1em;
font-size: 0.9em;
}
.xwords .entries .entry .description .definition {
margin-left: 10px;
margin-left: 10px;
}
.xwords > .entry > .description {
margin: 1em;
margin: 1em;
}
.xwords > .entry > .description .yomi {
margin: 1em 0;
margin: 1em 0;
}
.xwords > .entry > .description .note {
margin: 1em 0;
text-align: right;
font-size: 0.9em;
margin: 1em 0;
text-align: right;
font-size: 0.9em;
}
.xwords .entries .pagenavi {
text-align: right;
font-size: 0.9em;
text-align: right;
font-size: 0.9em;
}
+34 -20
View File
@@ -1,6 +1,5 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { MultiLang } from '../../config';
import { Link } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import XwordsUtils from './XwordsUtils';
@@ -12,33 +11,48 @@ interface Props {
isSearch?: boolean;
}
const XwordsBreadcrumbs: React.FC<Props> = (props: Props) => {
const XwordsBreadcrumbs = (props: Props) => {
const { lang, catId, initial, entryId, isSearch } = props;
const items: { id: string, name: string, link: string }[] = [];
const items: { id: string; name: string; link: string }[] = [];
items.push({ id: 'h', name: '[en]Home[/en][ja]ホーム[/ja]', link: '/' });
items.push({ id: 'm', name: XwordsUtils.getName(), link: XwordsUtils.getIndexUrl() });
if (typeof isSearch !== undefined && isSearch) {
if (isSearch) {
items.push({ id: 's', name: '[en]Search[/en][ja]検索[/ja]', link: '/' });
} else if (typeof catId !== 'undefined') {
const cname = catId === 0 && typeof initial === 'undefined' ? '[en]List of Categories[/en][ja]分類説明一覧[/ja]' : XwordsUtils.getCategoryName(catId);
items.push({ id: 'c' + catId, name: cname, link: XwordsUtils.getCategoryUrl(catId) });
const cname =
catId === 0 && typeof initial === 'undefined'
? '[en]List of Categories[/en][ja]分類説明一覧[/ja]'
: XwordsUtils.getCategoryName(catId);
items.push({ id: `c${catId}`, name: cname, link: XwordsUtils.getCategoryUrl(catId) });
if (typeof initial !== 'undefined') {
items.push({ id: 'i' + initial, name: XwordsUtils.getInitialName(initial), link: XwordsUtils.getLetterUrl(initial, catId) });
items.push({
id: `i${initial}`,
name: XwordsUtils.getInitialName(initial),
link: XwordsUtils.getLetterUrl(initial, catId),
});
if (typeof entryId !== 'undefined') {
items.push({ id: 'e' + entryId, name: XwordsUtils.getEntryName(entryId), link: XwordsUtils.getEntryUrl(entryId) })
items.push({
id: `e${entryId}`,
name: XwordsUtils.getEntryName(entryId),
link: XwordsUtils.getEntryUrl(entryId),
});
}
}
}
return <div className="breadcrumbs">
{items.map((item, index) => {
const name = Functions.mlang(item.name, lang);
return <span key={item.id}>
{index !== 0 && <>&nbsp;&raquo;&nbsp;</>}
{index === (items.length - 1) ? name : <Link to={item.link}>{name}</Link>}
</span>;
})}
</div>;
}
return (
<div className="breadcrumbs">
{items.map((item, index) => {
const name = Functions.mlang(item.name, lang);
return (
<span key={item.id}>
{index !== 0 && <>&nbsp;&raquo;&nbsp;</>}
{index === items.length - 1 ? name : <Link to={item.link}>{name}</Link>}
</span>
);
})}
</div>
);
};
export default XwordsBreadcrumbs;
+31 -17
View File
@@ -1,6 +1,5 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { MultiLang } from '../../config';
import { Link } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import XwordsUtils from './XwordsUtils';
@@ -8,21 +7,36 @@ interface Props {
lang: MultiLang;
}
const XwordsCategoryFieldset: React.FC<Props> = (props: Props) => {
const XwordsCategoryFieldset = (props: Props) => {
const { lang } = props;
const category = XwordsUtils.getCategories();
return <fieldset className="item category">
<legend className="title" > {Functions.mlang('[en]Categories[/en][ja]用途別分類(カテゴリー)別[/ja]', lang)}</legend>
<div className="body">
{category.map((category) => {
const url = XwordsUtils.getCategoryUrl(category.id);
const title = '[' + category.total + ']';
const name = Functions.mlang(category.name, lang);
return <span key={category.id} ><Link to={url} title={title}>{name}</Link></span>
})}
<span><Link to={XwordsUtils.getCategoryUrl(0)}>{Functions.mlang('[en]List of Categories[/en][ja]分類説明一覧[/ja]', lang)}</Link></span>
</div>
</fieldset>;
}
return (
<fieldset className="item category">
<legend className="title">
{' '}
{Functions.mlang('[en]Categories[/en][ja]用途別分類(カテゴリー)別[/ja]', lang)}
</legend>
<div className="body">
{category.map((category) => {
const url = XwordsUtils.getCategoryUrl(category.id);
const title = `[${category.total}]`;
const name = Functions.mlang(category.name, lang);
return (
<span key={category.id}>
<Link to={url} title={title}>
{name}
</Link>
</span>
);
})}
<span>
<Link to={XwordsUtils.getCategoryUrl(0)}>
{Functions.mlang('[en]List of Categories[/en][ja]分類説明一覧[/ja]', lang)}
</Link>
</span>
</div>
</fieldset>
);
};
export default XwordsCategoryFieldset;
+33 -21
View File
@@ -1,9 +1,8 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { MultiLang } from '../../config';
import { Link } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import XwordsEntriesPageNavi from './XwordsEntriesPageNavi';
import XwordsUtils, { XwordsEntryData, XwordsSearchResult } from './XwordsUtils';
import XwordsUtils, { type XwordsEntryData, type XwordsSearchResult } from './XwordsUtils';
interface Props {
lang: MultiLang;
@@ -12,26 +11,39 @@ interface Props {
start: number;
}
const XwordsEntries: React.FC<Props> = (props: Props) => {
const XwordsEntries = (props: Props) => {
const { lang, baseUrl, result, start } = props;
const definition = (entry: XwordsEntryData): string => {
const text = Functions.mlang(entry.definition, lang);
return text.substr(0, 50) + (text.length > 50 ? '...' : '');
return text.slice(0, 50) + (text.length > 50 ? '...' : '');
};
return <div className="entries">
{result.entries.length === 0 && <>{Functions.mlang('[en]No entries found[/en][ja]エントリが見つかりませんでした[/ja]', lang)}</>}
<XwordsEntriesPageNavi lang={lang} baseUrl={baseUrl} total={result.total} start={start} />
{result.entries.map((entry) => {
return <div key={entry.id} className="entry">
<div className="title"><Link className="link" to={XwordsUtils.getEntryUrl(entry.id)}>{Functions.mlang(entry.term, lang)}</Link></div>
<div className="description">
<span className="yomi">{Functions.mlang('[en]Yomi[/en][ja]読み[/ja] : ' + entry.yomi, lang)}</span>
<span className="definition">{Functions.mlang('[en]Definition[/en][ja]解説[/ja] : ', lang) + definition(entry)}</span>
</div>
</div>;
})}
<XwordsEntriesPageNavi lang={lang} baseUrl={baseUrl} total={result.total} start={start} />
</div>
}
return (
<div className="entries">
{result.entries.length === 0 &&
Functions.mlang('[en]No entries found[/en][ja]エントリが見つかりませんでした[/ja]', lang)}
<XwordsEntriesPageNavi lang={lang} baseUrl={baseUrl} total={result.total} start={start} />
{result.entries.map((entry) => {
return (
<div key={entry.id} className="entry">
<div className="title">
<Link className="link" to={XwordsUtils.getEntryUrl(entry.id)}>
{Functions.mlang(entry.term, lang)}
</Link>
</div>
<div className="description">
<span className="yomi">
{Functions.mlang(`[en]Yomi[/en][ja]読み[/ja] : ${entry.yomi}`, lang)}
</span>
<span className="definition">
{Functions.mlang('[en]Definition[/en][ja]解説[/ja] : ', lang) + definition(entry)}
</span>
</div>
</div>
);
})}
<XwordsEntriesPageNavi lang={lang} baseUrl={baseUrl} total={result.total} start={start} />
</div>
);
};
export default XwordsEntries;
+27 -22
View File
@@ -1,6 +1,6 @@
import React, { Fragment } from 'react';
import { Link } from 'react-router-dom';
import { MultiLang } from '../../config';
import { Fragment, type ReactNode } from 'react';
import { Link } from 'react-router';
import type { MultiLang } from '../../config';
interface Props {
lang: MultiLang;
@@ -9,7 +9,7 @@ interface Props {
start: number;
}
const XwordsEntriesPageNavi: React.FC<Props> = (props: Props) => {
const XwordsEntriesPageNavi = (props: Props) => {
const { baseUrl, total, start } = props;
if (total <= 20 || start > total) {
return null;
@@ -27,34 +27,39 @@ const XwordsEntriesPageNavi: React.FC<Props> = (props: Props) => {
if (rangeMax > max - 1) {
rangeMax = max - 1;
}
const link = (num: number, el?: JSX.Element) => {
const link = (num: number, el?: ReactNode) => {
const label = el || num;
const url = baseUrl + (num - 1 > 0 ? ('&start=' + ((num - 1) * 20)) : '');
return num === now ? <>({label})</> : <Link to={url}>{label}</Link>
}
const items: JSX.Element[] = [];
const url = baseUrl + (num - 1 > 0 ? `&start=${(num - 1) * 20}` : '');
return num === now ? <>({label})</> : <Link to={url}>{label}</Link>;
};
const items: { key: string; node: ReactNode }[] = [];
if (prev !== 0) {
items.push(link(prev, <>&laquo;</>));
items.push({ key: 'prev', node: link(prev, <>&laquo;</>) });
}
items.push(link(min));
items.push({ key: `${min}`, node: link(min) });
if (now - min > 4) {
items.push(<>...</>);
items.push({ key: 'gap-prev', node: <>...</> });
}
for (let range = rangeMin; range <= rangeMax; range++) {
items.push(link(range));
items.push({ key: `${range}`, node: link(range) });
}
if (max - now > 4) {
items.push(<>...</>);
items.push({ key: 'gap-next', node: <>...</> });
}
items.push(link(max));
items.push({ key: `${max}`, node: link(max) });
if (next !== 0) {
items.push(link(next, <>&raquo;</>));
items.push({ key: 'next', node: link(next, <>&raquo;</>) });
}
return <nav className="pagenavi">
{items.map((el, index) => {
return <Fragment key={index}>{index !== 0 && <>&nbsp;</>}{el}</Fragment>;
})}
</nav>;
}
return (
<nav className="pagenavi">
{items.map((item, index) => (
<Fragment key={item.key}>
{index !== 0 && <>&nbsp;</>}
{item.node}
</Fragment>
))}
</nav>
);
};
export default XwordsEntriesPageNavi;
+27 -22
View File
@@ -1,6 +1,5 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { MultiLang } from '../../config';
import { Link } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import XwordsUtils, { XWORDS_INITIAL_KEYS } from './XwordsUtils';
@@ -9,30 +8,36 @@ interface Props {
catId: number;
}
const XwordsInitialFieldset: React.FC<Props> = (props: Props) => {
const XwordsInitialFieldset = (props: Props) => {
const { lang, catId } = props;
const initial = XwordsUtils.getCountInitials(catId);
const initialsAlpha: JSX.Element[] = [];
const initialsKana: JSX.Element[] = [];
XWORDS_INITIAL_KEYS.forEach((value, idx) => {
const initials = XWORDS_INITIAL_KEYS.map((value) => {
const num = initial[value.key];
const url = XwordsUtils.getLetterUrl(value.key, catId);
const label = Functions.mlang(value.label, lang);
const name = num === 0 ? label : <Link to={url} title={`[ ${num} ]`}>{label}</Link>;
const el = <span key={value.key}>{name}</span>;
if (idx < 26) {
initialsAlpha.push(el);
} else {
initialsKana.push(el);
}
return (
<span key={value.key}>
{num === 0 ? (
label
) : (
<Link to={url} title={`[ ${num} ]`}>
{label}
</Link>
)}
</span>
);
});
return <fieldset className="item initial">
<legend className="title">{Functions.mlang('[en]Initials[/en][ja]頭文字(イニシャル)別[/ja]', lang)}</legend>
<div className="body">
<div>{initialsAlpha}</div>
<div>{initialsKana}</div>
</div>
</fieldset>;
}
return (
<fieldset className="item initial">
<legend className="title">
{Functions.mlang('[en]Initials[/en][ja]頭文字(イニシャル)別[/ja]', lang)}
</legend>
<div className="body">
<div>{initials.slice(0, 26)}</div>
<div>{initials.slice(26)}</div>
</div>
</fieldset>
);
};
export default XwordsInitialFieldset;
+28 -16
View File
@@ -1,6 +1,5 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { MultiLang } from '../../config';
import { Link } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import XwordsUtils from './XwordsUtils';
@@ -8,30 +7,43 @@ interface Props {
lang: MultiLang;
}
const XwordsRandomFieldset: React.FC<Props> = (props: Props) => {
const XwordsRandomFieldset = (props: Props) => {
const { lang } = props;
const categories = XwordsUtils.getCategories();
const random = XwordsUtils.getRandomEntry();
if (random === null) {
return null;
}
const randomCategory = categories.find((category) => { return category.id === random.cat_id; });
const randomCategory = categories.find((category) => {
return category.id === random.cat_id;
});
if (typeof randomCategory === 'undefined') {
return null;
}
const randomDefinition = Functions.mlang(random.definition, lang);
return <fieldset className="item random">
<legend className="title">{Functions.mlang('[en]Random[/en][ja]ランダム[/ja]', lang)}</legend>
<div className="body">
<div className="term">
<Link to={XwordsUtils.getEntryUrl(random.id)}>{Functions.mlang(random.term, lang)}</Link> <span className="info">[{Functions.mlang('[en]Category[/en][ja]用途[/ja]', lang)}: <Link to={XwordsUtils.getCategoryUrl(randomCategory.id)}>{Functions.mlang(randomCategory.name, lang)}</Link>]</span>
return (
<fieldset className="item random">
<legend className="title">{Functions.mlang('[en]Random[/en][ja]ランダム[/ja]', lang)}</legend>
<div className="body">
<div className="term">
<Link to={XwordsUtils.getEntryUrl(random.id)}>{Functions.mlang(random.term, lang)}</Link>{' '}
<span className="info">
[{Functions.mlang('[en]Category[/en][ja]用途[/ja]', lang)}:{' '}
<Link to={XwordsUtils.getCategoryUrl(randomCategory.id)}>
{Functions.mlang(randomCategory.name, lang)}
</Link>
]
</span>
</div>
<div className="definition">
<span className="info">{Functions.mlang('[en]Definition: [/en][ja]解説: [/ja]', lang)}</span>
{randomDefinition.slice(0, 30)}
{randomDefinition.length > 30 && <>...</>}
</div>
</div>
<div className="definition">
<span className="info">{Functions.mlang('[en]Definition: [/en][ja]解説: [/ja]', lang)}</span>{randomDefinition.substr(0, 30)}{randomDefinition.length > 30 && <>...</>}
</div>
</div>
</fieldset>;
}
</fieldset>
);
};
export default XwordsRandomFieldset;
+25 -16
View File
@@ -1,6 +1,5 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { MultiLang } from '../../config';
import { Link } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import XwordsUtils from './XwordsUtils';
@@ -9,20 +8,30 @@ interface Props {
catId: number;
}
const XwordsRankingFieldset: React.FC<Props> = (props: Props) => {
const XwordsRankingFieldset = (props: Props) => {
const { lang, catId } = props;
const ranking = XwordsUtils.getRankingEntries(catId);
const title = catId === 0 ? '[en]Ranking[/en][ja]ランキング[/ja]' : '[en]Ranking in this Category[/en][ja]この分野でのランキング[/ja]';
return <fieldset className="item ranking">
<legend className="title">{Functions.mlang(title, lang)}</legend>
<div className="body">
<ul>
{ranking.map((entry, idx) => {
return <li key={entry.id}><span className="info">{(idx + 1) + Functions.ordinal(idx + 1)}</span> <Link to={XwordsUtils.getEntryUrl(entry.id)}>{Functions.mlang(entry.term, lang)}</Link></li>
})}
</ul>
</div>
</fieldset>;
}
const title =
catId === 0
? '[en]Ranking[/en][ja]ランキング[/ja]'
: '[en]Ranking in this Category[/en][ja]この分野でのランキング[/ja]';
return (
<fieldset className="item ranking">
<legend className="title">{Functions.mlang(title, lang)}</legend>
<div className="body">
<ul>
{ranking.map((entry, idx) => {
return (
<li key={entry.id}>
<span className="info">{idx + 1 + Functions.ordinal(idx + 1)}</span>{' '}
<Link to={XwordsUtils.getEntryUrl(entry.id)}>{Functions.mlang(entry.term, lang)}</Link>
</li>
);
})}
</ul>
</div>
</fieldset>
);
};
export default XwordsRankingFieldset;
+27 -17
View File
@@ -1,6 +1,6 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { MultiLang } from '../../config';
import { format } from 'date-fns';
import { Link } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import XwordsUtils from './XwordsUtils';
@@ -9,21 +9,31 @@ interface Props {
catId: number;
}
const XwordsRecentlyFieldset: React.FC<Props> = (props: Props) => {
const XwordsRecentlyFieldset = (props: Props) => {
const { lang, catId } = props;
const recent = XwordsUtils.getRecentlyEntries(catId);
const title = catId === 0 ? '[en]New Arrival[/en][ja]新着[/ja]' : '[en]New Arrival in this Category[/en][ja]この分野での新着[/ja]';
return <fieldset className="item recently">
<legend className="title">{Functions.mlang(title, lang)}</legend>
<div className="body">
<ul>
{recent.map((entry) => {
const date = Functions.formatDate(entry.timestamp, 'YYYY/M/D');
return <li key={entry.id}><Link to={XwordsUtils.getEntryUrl(entry.id)}>{Functions.mlang(entry.term, lang)}</Link> <span className="info">[{date}]</span></li>
})}
</ul>
</div>
</fieldset>;
}
const title =
catId === 0
? '[en]New Arrival[/en][ja]新着[/ja]'
: '[en]New Arrival in this Category[/en][ja]この分野での新着[/ja]';
return (
<fieldset className="item recently">
<legend className="title">{Functions.mlang(title, lang)}</legend>
<div className="body">
<ul>
{recent.map((entry) => {
const date = format(new Date(entry.timestamp * 1000), 'yyyy/M/d');
return (
<li key={entry.id}>
<Link to={XwordsUtils.getEntryUrl(entry.id)}>{Functions.mlang(entry.term, lang)}</Link>{' '}
<span className="info">[{date}]</span>
</li>
);
})}
</ul>
</div>
</fieldset>
);
};
export default XwordsRecentlyFieldset;
+63 -70
View File
@@ -1,10 +1,10 @@
import React, { ChangeEvent, Component, FormEvent } from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { MultiLang } from '../../config';
import { type FormEvent, useState } from 'react';
import { useNavigate } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import XwordsUtils from './XwordsUtils';
interface Props extends RouteComponentProps {
interface Props {
lang: MultiLang;
type: number;
catId: number;
@@ -12,99 +12,92 @@ interface Props extends RouteComponentProps {
term: string;
}
interface State {
type: number;
catId: number;
andor: string;
term: string;
}
const XwordsSearchFieldset = (props: Props) => {
const { lang } = props;
const navigate = useNavigate();
const [type, setType] = useState(props.type);
const [catId, setCatId] = useState(props.catId);
const [andor, setAndor] = useState(props.andor);
const [term, setTerm] = useState(props.term);
class XwordsSearchFieldset extends Component<Props, State> {
constructor(props: Props) {
super(props);
const { type, catId, andor, term } = props;
this.state = { type, catId, andor, term };
this.handleChangeType = this.handleChangeType.bind(this);
this.handleChangeCatId = this.handleChangeCatId.bind(this);
this.handleChangeAndOr = this.handleChangeAndOr.bind(this);
this.handleChangeTerm = this.handleChangeTerm.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChangeType(event: ChangeEvent<HTMLSelectElement>) {
const type = parseInt(event.target.value.trim());
this.setState({ type });
}
handleChangeCatId(event: ChangeEvent<HTMLSelectElement>) {
const catId = parseInt(event.target.value.trim());
this.setState({ catId });
}
handleChangeAndOr(event: ChangeEvent<HTMLSelectElement>) {
const andor = event.target.value.trim();
this.setState({ andor });
}
handleChangeTerm(event: ChangeEvent<HTMLInputElement>) {
const term = event.target.value;
this.setState({ term });
}
handleSubmit(event: FormEvent<HTMLFormElement>) {
const { type, catId, andor, term } = this.state;
const term_ = term.trim();
const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
const term_ = term.trim();
if (term_.length > 0) {
const url = XwordsUtils.getSearchUrl(type, catId, andor, term_);
this.props.history.push(url);
void navigate(XwordsUtils.getSearchUrl(type, catId, andor, term_));
}
}
};
render() {
const { lang } = this.props;
const { type, catId, andor, term } = this.state;
const categories = XwordsUtils.getCategories();
return <fieldset className="item search">
const categories = XwordsUtils.getCategories();
return (
<fieldset className="item search">
<legend className="title">{Functions.mlang('[en]Search[/en][ja]検索[/ja]', lang)}</legend>
<div className="body">
<form onSubmit={this.handleSubmit}>
<form onSubmit={handleSubmit}>
<dl>
<dt>{Functions.mlang('[en]Target[/en][ja]検索対象[/ja]', lang)}</dt>
<dd>
<select onChange={this.handleChangeType} value={type}>
<select onChange={(event) => setType(parseInt(event.target.value.trim(), 10))} value={type}>
<option value="1">{Functions.mlang('[en]Term[/en][ja]見出し語[/ja]', lang)}</option>
<option value="2">{Functions.mlang('[en]Yomi[/en][ja]読み方[/ja]', lang)}</option>
<option value="3">{Functions.mlang('[en]Definition[/en][ja]説明文[/ja]', lang)}</option>
<option value="4">{Functions.mlang('[en]Term+Yomi+Definition[/en][ja]見出し語+読み方+説明文[/ja]', lang)}</option>
<option value="4">
{Functions.mlang(
'[en]Term+Yomi+Definition[/en][ja]見出し語+読み方+説明文[/ja]',
lang
)}
</option>
</select>
</dd>
<dt>{Functions.mlang('[en]Category[/en][ja]用途別分類[/ja]', lang)}</dt>
<dd>
<select onChange={this.handleChangeCatId} value={catId}>
<option value="0">{Functions.mlang('[en]ANY[/en][ja]全分類(カテゴリー)[/ja]', lang)}</option>
{categories.map((value) => <option key={value.id} value={value.id}>{Functions.mlang(value.name, lang)}</option>)}
<select
onChange={(event) => setCatId(parseInt(event.target.value.trim(), 10))}
value={catId}
>
<option value="0">
{Functions.mlang('[en]ANY[/en][ja]全分類(カテゴリー)[/ja]', lang)}
</option>
{categories.map((value) => (
<option key={value.id} value={value.id}>
{Functions.mlang(value.name, lang)}
</option>
))}
</select>
</dd>
<dt>{Functions.mlang('[en]Condition[/en][ja]検索の種類[/ja]', lang)}</dt>
<dd>
<select onChange={this.handleChangeAndOr} value={andor}>
<option value="AND">{Functions.mlang('[en]AND[/en][ja]すべての語に一致するもの[/ja]', lang)}</option>
<option value="OR">{Functions.mlang('[en]OR[/en][ja]いずれかの語に一致するもの[/ja]', lang)}</option>
<option value="EXACT">{Functions.mlang('[en]EXACT[/en][ja]スペースも含め1語として[/ja]', lang)}</option>
<select onChange={(event) => setAndor(event.target.value.trim())} value={andor}>
<option value="AND">
{Functions.mlang('[en]AND[/en][ja]すべての語に一致するもの[/ja]', lang)}
</option>
<option value="OR">
{Functions.mlang('[en]OR[/en][ja]いずれかの語に一致するもの[/ja]', lang)}
</option>
<option value="EXACT">
{Functions.mlang('[en]EXACT[/en][ja]スペースも含め1語として[/ja]', lang)}
</option>
</select>
</dd>
<dt>{Functions.mlang('[en]Word[/en][ja]検索語[/ja]', lang)}</dt>
<dd>
<input type="text" name="term" onChange={this.handleChangeTerm} value={term} />
<input className="formButton" type="submit" value={Functions.mlang('[en]Search![/en][ja]検索![/ja]', lang)} />
<input
type="text"
name="term"
onChange={(event) => setTerm(event.target.value)}
value={term}
/>
<input
className="formButton"
type="submit"
value={Functions.mlang('[en]Search![/en][ja]検索![/ja]', lang)}
/>
</dd>
</dl>
</form>
</div>
</fieldset>;
}
}
</fieldset>
);
};
export default withRouter(XwordsSearchFieldset);
export default XwordsSearchFieldset;

Some files were not shown because too many files have changed in this diff Show More