2 Commits

435 changed files with 443 additions and 166597 deletions

View File

@@ -31,7 +31,8 @@ jobs:
path: |
~/.bun/install/cache
node_modules
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
vendor/subminer-yomitan/node_modules
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock', 'vendor/subminer-yomitan/package-lock.json') }}
restore-keys: |
${{ runner.os }}-bun-

View File

@@ -40,7 +40,8 @@ jobs:
path: |
~/.bun/install/cache
node_modules
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
vendor/subminer-yomitan/node_modules
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock', 'vendor/subminer-yomitan/package-lock.json') }}
restore-keys: |
${{ runner.os }}-bun-
@@ -84,6 +85,11 @@ jobs:
with:
bun-version: 1.3.5
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22.12.0
- name: Cache dependencies
uses: actions/cache@v4
with:
@@ -91,7 +97,8 @@ jobs:
~/.bun/install/cache
node_modules
vendor/texthooker-ui/node_modules
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock', 'vendor/texthooker-ui/package.json') }}
vendor/subminer-yomitan/node_modules
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock', 'vendor/texthooker-ui/package.json', 'vendor/subminer-yomitan/package-lock.json') }}
restore-keys: |
${{ runner.os }}-bun-
@@ -140,6 +147,11 @@ jobs:
with:
bun-version: 1.3.5
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22.12.0
- name: Cache dependencies
uses: actions/cache@v4
with:
@@ -147,7 +159,8 @@ jobs:
~/.bun/install/cache
node_modules
vendor/texthooker-ui/node_modules
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock', 'vendor/texthooker-ui/package.json') }}
vendor/subminer-yomitan/node_modules
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock', 'vendor/texthooker-ui/package.json', 'vendor/subminer-yomitan/package-lock.json') }}
restore-keys: |
${{ runner.os }}-bun-

1
.gitignore vendored
View File

@@ -5,6 +5,7 @@ node_modules/
out/
dist/
release/
build/yomitan/
# Launcher build artifact (produced by make build-launcher)
/subminer

3
.gitmodules vendored
View File

@@ -8,3 +8,6 @@
[submodule "yomitan-jlpt-vocab"]
path = vendor/yomitan-jlpt-vocab
url = https://github.com/stephenmk/yomitan-jlpt-vocab
[submodule "vendor/subminer-yomitan"]
path = vendor/subminer-yomitan
url = https://github.com/ksyasuda/subminer-yomitan

View File

@@ -54,7 +54,7 @@ chmod +x ~/.local/bin/subminer
> [!NOTE]
> The `subminer` wrapper uses a [Bun](https://bun.sh) shebang. Make sure `bun` is on your `PATH`.
**From source** or **macOS**see the [installation guide](https://docs.subminer.moe/installation#from-source).
**From source** or **macOS**initialize submodules first (`git submodule update --init --recursive`). Source builds now also require Node.js 22 + npm because bundled Yomitan is built from the `vendor/subminer-yomitan` submodule into `build/yomitan` during `bun run build`. Full install guide: [docs.subminer.moe/installation#from-source](https://docs.subminer.moe/installation#from-source).
### 2. Launch the app once
@@ -92,7 +92,7 @@ subminer --start video.mkv # optional explicit overlay start when plugin auto_st
| Required | Optional |
| ------------------------------------------ | -------------------------------------------------- |
| `bun` | |
| `bun`, `node` 22, `npm` | |
| `mpv` with IPC socket | `yt-dlp` |
| `ffmpeg` | `guessit` (better AniSkip title/episode detection) |
| `mecab` + `mecab-ipadic` | `fzf` / `rofi` |

View File

@@ -0,0 +1,51 @@
---
id: TASK-110
title: Replace vendored Yomitan with submodule-built Chrome artifact workflow
status: Done
assignee: []
created_date: '2026-03-07 11:05'
updated_date: '2026-03-07 11:22'
labels:
- yomitan
- build
- release
dependencies: []
priority: high
ordinal: 9010
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Replace the checked-in `vendor/yomitan` release tree with a `subminer-yomitan` git submodule. Build Yomitan from source, extract the Chromium zip artifact into a stable local build directory, and make SubMiner dev/runtime/tests/release packaging load that extracted extension instead of the source tree or vendored files.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 Repo tracks Yomitan as a git submodule instead of committed extension files under `vendor/yomitan`.
- [x] #2 SubMiner has a reproducible build/extract step that produces a local Chromium extension directory from `subminer-yomitan`.
- [x] #3 Dev/runtime/tests resolve the extracted build output as the default Yomitan extension path.
- [x] #4 Release packaging includes the extracted Chromium extension files instead of the old vendored tree.
- [x] #5 Docs and verification commands reflect the new workflow.
<!-- AC:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Replaced the checked-in `vendor/yomitan` extension tree with a `vendor/subminer-yomitan` git submodule and added a reproducible `bun run build:yomitan` workflow that builds `yomitan-chrome.zip`, extracts it into `build/yomitan`, and reuses a source-state stamp to skip redundant rebuilds. Runtime path resolution, helper CLIs, Yomitan integration tests, packaging, CI cache keys, and README source-build notes now all target that generated artifact instead of the old vendored files.
Verification:
- `bun run build:yomitan`
- `bun test src/core/services/yomitan-extension-paths.test.ts src/core/services/yomitan-structured-content-generator.test.ts src/yomitan-translator-sort.test.ts`
- `bun run typecheck`
- `bun run build`
- `bun run test:core:src`
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -4,6 +4,13 @@ import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { spawn, spawnSync } from 'node:child_process';
import {
createDefaultSetupState,
getDefaultConfigDir,
getSetupStatePath,
readSetupState,
writeSetupState,
} from '../src/shared/setup-state.js';
type RunResult = {
status: number | null;
@@ -58,6 +65,13 @@ function createSmokeCase(name: string): SmokeCase {
`socket_path=${socketPath}\n`,
);
const configDir = getDefaultConfigDir({ xdgConfigHome, homeDir });
const setupState = createDefaultSetupState();
setupState.status = 'completed';
setupState.completedAt = '2026-03-07T00:00:00.000Z';
setupState.completionSource = 'user';
writeSetupState(getSetupStatePath(configDir), setupState);
const fakeMpvLogPath = path.join(artifactsDir, 'fake-mpv.log');
const fakeAppLogPath = path.join(artifactsDir, 'fake-app.log');
const fakeAppStartLogPath = path.join(artifactsDir, 'fake-app-start.log');
@@ -224,6 +238,22 @@ async function waitForJsonLines(
}
}
test('launcher smoke fixture seeds completed setup state', () => {
const smokeCase = createSmokeCase('setup-state');
try {
const configDir = getDefaultConfigDir({
xdgConfigHome: smokeCase.xdgConfigHome,
homeDir: smokeCase.homeDir,
});
const statePath = getSetupStatePath(configDir);
assert.equal(readSetupState(statePath)?.status, 'completed');
} finally {
fs.rmSync(smokeCase.root, { recursive: true, force: true });
fs.rmSync(smokeCase.socketDir, { recursive: true, force: true });
}
});
test('launcher mpv status returns ready when socket is connectable', async () => {
await withSmokeCase('mpv-status', async (smokeCase) => {
const env = makeTestEnv(smokeCase);

View File

@@ -8,10 +8,11 @@
"typecheck": "tsc --noEmit -p tsconfig.typecheck.json",
"typecheck:watch": "tsc --watch --preserveWatchOutput -p tsconfig.typecheck.json",
"get-frequency": "bun run scripts/get_frequency.ts --pretty --color-top-x 10000 --yomitan-user-data ~/.config/SubMiner --colorized-line",
"get-frequency:electron": "bun build scripts/get_frequency.ts --format=cjs --target=node --outfile dist/scripts/get_frequency.js --external electron && electron dist/scripts/get_frequency.js --pretty --color-top-x 10000 --yomitan-user-data ~/.config/SubMiner --colorized-line",
"get-frequency:electron": "bun run build:yomitan && bun build scripts/get_frequency.ts --format=cjs --target=node --outfile dist/scripts/get_frequency.js --external electron && electron dist/scripts/get_frequency.js --pretty --color-top-x 10000 --yomitan-user-data ~/.config/SubMiner --colorized-line",
"test-yomitan-parser": "bun run scripts/test-yomitan-parser.ts",
"test-yomitan-parser:electron": "bun build scripts/test-yomitan-parser.ts --format=cjs --target=node --outfile dist/scripts/test-yomitan-parser.js --external electron && electron dist/scripts/test-yomitan-parser.js",
"build": "tsc -p tsconfig.json && bun run build:renderer && cp src/renderer/index.html src/renderer/style.css dist/renderer/ && cp -r src/renderer/fonts dist/renderer/ && bash scripts/build-macos-helper.sh",
"test-yomitan-parser:electron": "bun run build:yomitan && bun build scripts/test-yomitan-parser.ts --format=cjs --target=node --outfile dist/scripts/test-yomitan-parser.js --external electron && electron dist/scripts/test-yomitan-parser.js",
"build:yomitan": "node scripts/build-yomitan.mjs",
"build": "bun run build:yomitan && tsc -p tsconfig.json && bun run build:renderer && cp src/renderer/index.html src/renderer/style.css dist/renderer/ && cp -r src/renderer/fonts dist/renderer/ && bash scripts/build-macos-helper.sh",
"build:renderer": "esbuild src/renderer/renderer.ts --bundle --platform=browser --format=esm --target=es2022 --outfile=dist/renderer/renderer.js --sourcemap",
"format": "prettier --write .",
"format:check": "prettier --check .",
@@ -21,8 +22,8 @@
"test:plugin:src": "lua scripts/test-plugin-start-gate.lua",
"test:launcher:smoke:src": "bun test launcher/smoke.e2e.test.ts",
"test:launcher:src": "bun test launcher/config.test.ts launcher/config-domain-parsers.test.ts launcher/parse-args.test.ts launcher/main.test.ts launcher/commands/command-modules.test.ts launcher/smoke.e2e.test.ts && bun run test:plugin:src",
"test:core:src": "bun test src/cli/args.test.ts src/cli/help.test.ts src/shared/setup-state.test.ts src/core/services/cli-command.test.ts src/core/services/field-grouping-overlay.test.ts src/core/services/numeric-shortcut-session.test.ts src/core/services/secondary-subtitle.test.ts src/core/services/mpv-render-metrics.test.ts src/core/services/overlay-content-measurement.test.ts src/core/services/mpv-control.test.ts src/core/services/mpv.test.ts src/core/services/runtime-options-ipc.test.ts src/core/services/runtime-config.test.ts src/core/services/config-hot-reload.test.ts src/core/services/discord-presence.test.ts src/core/services/tokenizer.test.ts src/core/services/tokenizer/annotation-stage.test.ts src/core/services/tokenizer/parser-selection-stage.test.ts src/core/services/tokenizer/parser-enrichment-stage.test.ts src/core/services/subsync.test.ts src/core/services/overlay-bridge.test.ts src/core/services/overlay-shortcut-handler.test.ts src/core/services/mining.test.ts src/core/services/anki-jimaku.test.ts src/core/services/jimaku-download-path.test.ts src/core/services/jellyfin.test.ts src/core/services/jellyfin-remote.test.ts src/core/services/immersion-tracker-service.test.ts src/core/services/overlay-runtime-init.test.ts src/core/services/app-ready.test.ts src/core/services/startup-bootstrap.test.ts src/core/services/subtitle-processing-controller.test.ts src/core/services/anilist/anilist-update-queue.test.ts src/core/utils/shortcut-config.test.ts src/main/runtime/first-run-setup-plugin.test.ts src/main/runtime/first-run-setup-service.test.ts src/main/runtime/first-run-setup-window.test.ts src/main/runtime/tray-runtime.test.ts src/main/runtime/tray-main-actions.test.ts src/main/runtime/tray-main-deps.test.ts src/main/runtime/tray-runtime-handlers.test.ts src/main/runtime/cli-command-context-main-deps.test.ts src/main/runtime/app-ready-main-deps.test.ts src/renderer/error-recovery.test.ts src/renderer/subtitle-render.test.ts src/renderer/handlers/mouse.test.ts src/renderer/handlers/keyboard.test.ts src/renderer/modals/jimaku.test.ts src/subsync/utils.test.ts src/main/anilist-url-guard.test.ts src/window-trackers/x11-tracker.test.ts launcher/config.test.ts launcher/config-domain-parsers.test.ts launcher/parse-args.test.ts launcher/main.test.ts launcher/commands/command-modules.test.ts launcher/setup-gate.test.ts",
"test:core:dist": "bun test dist/cli/args.test.js dist/cli/help.test.js dist/core/services/cli-command.test.js dist/core/services/ipc.test.js dist/core/services/anki-jimaku-ipc.test.js dist/core/services/field-grouping-overlay.test.js dist/core/services/numeric-shortcut-session.test.js dist/core/services/secondary-subtitle.test.js dist/core/services/mpv-render-metrics.test.js dist/core/services/overlay-content-measurement.test.js dist/core/services/mpv-control.test.js dist/core/services/mpv.test.js dist/core/services/runtime-options-ipc.test.js dist/core/services/runtime-config.test.js dist/core/services/config-hot-reload.test.js dist/core/services/discord-presence.test.js dist/core/services/tokenizer.test.js dist/core/services/tokenizer/annotation-stage.test.js dist/core/services/tokenizer/parser-selection-stage.test.js dist/core/services/tokenizer/parser-enrichment-stage.test.js dist/core/services/subsync.test.js dist/core/services/overlay-bridge.test.js dist/core/services/overlay-manager.test.js dist/core/services/overlay-shortcut-handler.test.js dist/core/services/mining.test.js dist/core/services/anki-jimaku.test.js dist/core/services/jimaku-download-path.test.js dist/core/services/jellyfin.test.js dist/core/services/jellyfin-remote.test.js dist/core/services/immersion-tracker-service.test.js dist/core/services/overlay-runtime-init.test.js dist/core/services/app-ready.test.js dist/core/services/startup-bootstrap.test.js dist/core/services/subtitle-processing-controller.test.js dist/core/services/anilist/anilist-token-store.test.js dist/core/services/anilist/anilist-update-queue.test.js dist/renderer/error-recovery.test.js dist/renderer/subtitle-render.test.js dist/renderer/handlers/mouse.test.js dist/renderer/handlers/keyboard.test.js dist/renderer/modals/jimaku.test.js dist/subsync/utils.test.js dist/main/anilist-url-guard.test.js dist/window-trackers/x11-tracker.test.js",
"test:core:src": "bun test src/cli/args.test.ts src/cli/help.test.ts src/shared/setup-state.test.ts src/core/services/cli-command.test.ts src/core/services/field-grouping-overlay.test.ts src/core/services/numeric-shortcut-session.test.ts src/core/services/secondary-subtitle.test.ts src/core/services/mpv-render-metrics.test.ts src/core/services/overlay-content-measurement.test.ts src/core/services/mpv-control.test.ts src/core/services/mpv.test.ts src/core/services/runtime-options-ipc.test.ts src/core/services/runtime-config.test.ts src/core/services/yomitan-extension-paths.test.ts src/core/services/config-hot-reload.test.ts src/core/services/discord-presence.test.ts src/core/services/tokenizer.test.ts src/core/services/tokenizer/annotation-stage.test.ts src/core/services/tokenizer/parser-selection-stage.test.ts src/core/services/tokenizer/parser-enrichment-stage.test.ts src/core/services/subsync.test.ts src/core/services/overlay-bridge.test.ts src/core/services/overlay-shortcut-handler.test.ts src/core/services/mining.test.ts src/core/services/anki-jimaku.test.ts src/core/services/jimaku-download-path.test.ts src/core/services/jellyfin.test.ts src/core/services/jellyfin-remote.test.ts src/core/services/immersion-tracker-service.test.ts src/core/services/overlay-runtime-init.test.ts src/core/services/app-ready.test.ts src/core/services/startup-bootstrap.test.ts src/core/services/subtitle-processing-controller.test.ts src/core/services/anilist/anilist-update-queue.test.ts src/core/utils/shortcut-config.test.ts src/main/runtime/first-run-setup-plugin.test.ts src/main/runtime/first-run-setup-service.test.ts src/main/runtime/first-run-setup-window.test.ts src/main/runtime/tray-runtime.test.ts src/main/runtime/tray-main-actions.test.ts src/main/runtime/tray-main-deps.test.ts src/main/runtime/tray-runtime-handlers.test.ts src/main/runtime/cli-command-context-main-deps.test.ts src/main/runtime/app-ready-main-deps.test.ts src/renderer/error-recovery.test.ts src/renderer/subtitle-render.test.ts src/renderer/handlers/mouse.test.ts src/renderer/handlers/keyboard.test.ts src/renderer/modals/jimaku.test.ts src/subsync/utils.test.ts src/main/anilist-url-guard.test.ts src/window-trackers/x11-tracker.test.ts launcher/config.test.ts launcher/config-domain-parsers.test.ts launcher/parse-args.test.ts launcher/main.test.ts launcher/commands/command-modules.test.ts launcher/setup-gate.test.ts",
"test:core:dist": "bun test dist/cli/args.test.js dist/cli/help.test.js dist/core/services/cli-command.test.js dist/core/services/ipc.test.js dist/core/services/anki-jimaku-ipc.test.js dist/core/services/field-grouping-overlay.test.js dist/core/services/numeric-shortcut-session.test.js dist/core/services/secondary-subtitle.test.js dist/core/services/mpv-render-metrics.test.js dist/core/services/overlay-content-measurement.test.js dist/core/services/mpv-control.test.js dist/core/services/mpv.test.js dist/core/services/runtime-options-ipc.test.js dist/core/services/runtime-config.test.js dist/core/services/yomitan-extension-paths.test.js dist/core/services/config-hot-reload.test.js dist/core/services/discord-presence.test.js dist/core/services/tokenizer.test.js dist/core/services/tokenizer/annotation-stage.test.js dist/core/services/tokenizer/parser-selection-stage.test.js dist/core/services/tokenizer/parser-enrichment-stage.test.js dist/core/services/subsync.test.js dist/core/services/overlay-bridge.test.js dist/core/services/overlay-manager.test.js dist/core/services/overlay-shortcut-handler.test.js dist/core/services/mining.test.js dist/core/services/anki-jimaku.test.js dist/core/services/jimaku-download-path.test.js dist/core/services/jellyfin.test.js dist/core/services/jellyfin-remote.test.js dist/core/services/immersion-tracker-service.test.js dist/core/services/overlay-runtime-init.test.js dist/core/services/app-ready.test.js dist/core/services/startup-bootstrap.test.js dist/core/services/subtitle-processing-controller.test.js dist/core/services/anilist/anilist-token-store.test.js dist/core/services/anilist/anilist-update-queue.test.js dist/renderer/error-recovery.test.js dist/renderer/subtitle-render.test.js dist/renderer/handlers/mouse.test.js dist/renderer/handlers/keyboard.test.js dist/renderer/modals/jimaku.test.js dist/subsync/utils.test.js dist/main/anilist-url-guard.test.js dist/window-trackers/x11-tracker.test.js",
"test:core:smoke:dist": "bun test dist/cli/help.test.js dist/core/services/runtime-config.test.js dist/core/services/ipc.test.js dist/core/services/overlay-manager.test.js dist/core/services/anilist/anilist-token-store.test.js dist/core/services/startup-bootstrap.test.js dist/renderer/error-recovery.test.js dist/main/anilist-url-guard.test.js dist/window-trackers/x11-tracker.test.js",
"test:smoke:dist": "bun run test:config:smoke:dist && bun run test:core:smoke:dist",
"test:subtitle:src": "bun test src/core/services/subsync.test.ts src/subsync/utils.test.ts",
@@ -117,7 +118,7 @@
],
"extraResources": [
{
"from": "vendor/yomitan",
"from": "build/yomitan",
"to": "yomitan"
},
{

144
scripts/build-yomitan.mjs Normal file
View File

@@ -0,0 +1,144 @@
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { createHash } from 'node:crypto';
import { execFileSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
const dirname = path.dirname(fileURLToPath(import.meta.url));
const repoRoot = path.resolve(dirname, '..');
const submoduleDir = path.join(repoRoot, 'vendor', 'subminer-yomitan');
const submodulePackagePath = path.join(submoduleDir, 'package.json');
const submodulePackageLockPath = path.join(submoduleDir, 'package-lock.json');
const buildOutputDir = path.join(repoRoot, 'build', 'yomitan');
const stampPath = path.join(buildOutputDir, '.subminer-build.json');
const zipPath = path.join(submoduleDir, 'builds', 'yomitan-chrome.zip');
const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
const dependencyStampPath = path.join(submoduleDir, 'node_modules', '.subminer-package-lock-hash');
function run(command, args, cwd) {
execFileSync(command, args, { cwd, stdio: 'inherit' });
}
function readCommand(command, args, cwd) {
return execFileSync(command, args, { cwd, encoding: 'utf8' }).trim();
}
function readStamp() {
try {
return JSON.parse(fs.readFileSync(stampPath, 'utf8'));
} catch {
return null;
}
}
function hashFile(filePath) {
const hash = createHash('sha256');
hash.update(fs.readFileSync(filePath));
return hash.digest('hex');
}
function ensureSubmodulePresent() {
if (!fs.existsSync(submodulePackagePath)) {
throw new Error(
'Missing vendor/subminer-yomitan submodule. Run `git submodule update --init --recursive`.',
);
}
}
function getSourceState() {
const revision = readCommand('git', ['rev-parse', 'HEAD'], submoduleDir);
const dirty = readCommand('git', ['status', '--short', '--untracked-files=no'], submoduleDir);
return { revision, dirty };
}
function isBuildCurrent(force) {
if (force) {
return false;
}
if (!fs.existsSync(path.join(buildOutputDir, 'manifest.json'))) {
return false;
}
const stamp = readStamp();
if (!stamp) {
return false;
}
const currentState = getSourceState();
return stamp.revision === currentState.revision && stamp.dirty === currentState.dirty;
}
function ensureDependenciesInstalled() {
const nodeModulesDir = path.join(submoduleDir, 'node_modules');
const currentLockHash = hashFile(submodulePackageLockPath);
let installedLockHash = '';
try {
installedLockHash = fs.readFileSync(dependencyStampPath, 'utf8').trim();
} catch {}
if (!fs.existsSync(nodeModulesDir) || installedLockHash !== currentLockHash) {
run(npmCommand, ['ci'], submoduleDir);
fs.mkdirSync(nodeModulesDir, { recursive: true });
fs.writeFileSync(dependencyStampPath, `${currentLockHash}\n`, 'utf8');
}
}
function installAndBuild() {
ensureDependenciesInstalled();
run(npmCommand, ['run', 'build', '--', '--target', 'chrome'], submoduleDir);
}
function extractBuild() {
if (!fs.existsSync(zipPath)) {
throw new Error(`Expected Yomitan build artifact at ${zipPath}`);
}
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'subminer-yomitan-'));
try {
run('unzip', ['-qo', zipPath, '-d', tempDir], repoRoot);
fs.rmSync(buildOutputDir, { recursive: true, force: true });
fs.mkdirSync(path.dirname(buildOutputDir), { recursive: true });
fs.cpSync(tempDir, buildOutputDir, { recursive: true });
if (!fs.existsSync(path.join(buildOutputDir, 'manifest.json'))) {
throw new Error(`Extracted Yomitan build missing manifest.json in ${buildOutputDir}`);
}
} finally {
fs.rmSync(tempDir, { recursive: true, force: true });
}
}
function writeStamp() {
const state = getSourceState();
fs.writeFileSync(
stampPath,
`${JSON.stringify(
{
revision: state.revision,
dirty: state.dirty,
builtAt: new Date().toISOString(),
},
null,
2,
)}\n`,
'utf8',
);
}
function main() {
const force = process.argv.includes('--force');
ensureSubmodulePresent();
if (isBuildCurrent(force)) {
process.stdout.write(`Yomitan build current: ${buildOutputDir}\n`);
return;
}
process.stdout.write('Building Yomitan Chrome artifact...\n');
installAndBuild();
extractBuild();
writeStamp();
process.stdout.write(`Yomitan extracted to ${buildOutputDir}\n`);
}
main();

View File

@@ -4,6 +4,7 @@ import process from 'node:process';
import { createTokenizerDepsRuntime, tokenizeSubtitle } from '../src/core/services/tokenizer.js';
import { createFrequencyDictionaryLookup } from '../src/core/services/frequency-dictionary.js';
import { resolveYomitanExtensionPath as resolveBuiltYomitanExtensionPath } from '../src/core/services/yomitan-extension-paths.js';
import { MecabTokenizer } from '../src/mecab-tokenizer.js';
import type { MergedToken, FrequencyDictionaryLookup } from '../src/types.js';
@@ -94,7 +95,7 @@ function parseCliArgs(argv: string[]): CliOptions {
if (!next) {
throw new Error('Missing value for --yomitan-extension');
}
yomitanExtensionPath = path.resolve(next);
yomitanExtensionPath = next;
continue;
}
@@ -103,7 +104,7 @@ function parseCliArgs(argv: string[]): CliOptions {
if (!next) {
throw new Error('Missing value for --yomitan-user-data');
}
yomitanUserDataPath = path.resolve(next);
yomitanUserDataPath = next;
continue;
}
@@ -225,12 +226,12 @@ function parseCliArgs(argv: string[]): CliOptions {
}
if (arg.startsWith('--yomitan-extension=')) {
yomitanExtensionPath = path.resolve(arg.slice('--yomitan-extension='.length));
yomitanExtensionPath = arg.slice('--yomitan-extension='.length);
continue;
}
if (arg.startsWith('--yomitan-user-data=')) {
yomitanUserDataPath = path.resolve(arg.slice('--yomitan-user-data='.length));
yomitanUserDataPath = arg.slice('--yomitan-user-data='.length);
continue;
}
@@ -524,7 +525,10 @@ function destroyUnknownParserWindow(window: unknown): void {
}
}
async function createYomitanRuntimeState(userDataPath: string): Promise<YomitanRuntimeState> {
async function createYomitanRuntimeState(
userDataPath: string,
extensionPath?: string,
): Promise<YomitanRuntimeState> {
const state: YomitanRuntimeState = {
yomitanExt: null,
parserWindow: null,
@@ -547,6 +551,7 @@ async function createYomitanRuntimeState(userDataPath: string): Promise<YomitanR
const loadYomitanExtension = (await import('../src/core/services/yomitan-extension-loader.js'))
.loadYomitanExtension as (options: {
userDataPath: string;
extensionPath?: string;
getYomitanParserWindow: () => unknown;
setYomitanParserWindow: (window: unknown) => void;
setYomitanParserReadyPromise: (promise: Promise<void> | null) => void;
@@ -556,6 +561,7 @@ async function createYomitanRuntimeState(userDataPath: string): Promise<YomitanR
const extension = await loadYomitanExtension({
userDataPath,
extensionPath,
getYomitanParserWindow: () => state.parserWindow,
setYomitanParserWindow: (window) => {
state.parserWindow = window;
@@ -589,17 +595,16 @@ async function createYomitanRuntimeStateWithSearch(
userDataPath: string,
extensionPath?: string,
): Promise<YomitanRuntimeState> {
const preferredPath = extensionPath ? path.resolve(extensionPath) : undefined;
const defaultVendorPath = path.resolve(process.cwd(), 'vendor', 'yomitan');
const candidates = [...(preferredPath ? [preferredPath] : []), defaultVendorPath];
const resolvedExtensionPath = resolveBuiltYomitanExtensionPath({
explicitPath: extensionPath,
cwd: process.cwd(),
});
const candidates = resolvedExtensionPath ? [resolvedExtensionPath] : [];
for (const candidate of candidates) {
if (!candidate) {
continue;
}
try {
if (fs.existsSync(path.join(candidate, 'manifest.json'))) {
const state = await createYomitanRuntimeState(userDataPath);
const state = await createYomitanRuntimeState(userDataPath, candidate);
if (state.available) {
return state;
}
@@ -613,7 +618,7 @@ async function createYomitanRuntimeStateWithSearch(
}
}
return createYomitanRuntimeState(userDataPath);
return createYomitanRuntimeState(userDataPath, resolvedExtensionPath ?? undefined);
}
async function getFrequencyLookup(dictionaryPath: string): Promise<FrequencyDictionaryLookup> {

View File

@@ -1,287 +1,16 @@
#!/bin/bash
#
# SubMiner - All-in-one sentence mining overlay
# Copyright (C) 2024 sudacode
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# patch-yomitan.sh - Apply Electron compatibility patches to Yomitan
#
# This script applies the necessary patches to make Yomitan work in Electron
# after upgrading to a new version. Run this after extracting a fresh Yomitan release.
#
# Usage: ./patch-yomitan.sh [yomitan_dir]
# yomitan_dir: Path to the Yomitan directory (default: vendor/yomitan)
#
set -e
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
YOMITAN_DIR="${1:-$SCRIPT_DIR/../vendor/yomitan}"
YOMITAN_MANIFEST_PATH="$YOMITAN_DIR/manifest.json"
cat <<'EOF'
patch-yomitan.sh is retired.
if [ ! -d "$YOMITAN_DIR" ]; then
echo "Error: Yomitan directory not found: $YOMITAN_DIR"
exit 1
fi
SubMiner now uses the forked source submodule at vendor/subminer-yomitan and builds the
Chromium extension artifact into build/yomitan.
if [ ! -f "$YOMITAN_MANIFEST_PATH" ]; then
echo "Error: manifest.json not found at $YOMITAN_MANIFEST_PATH"
exit 1
fi
Use:
git submodule update --init --recursive
bun run build:yomitan
echo "Patching manifest.json..."
if node - "$YOMITAN_MANIFEST_PATH" <<'PATCH_EOF'
const fs = require('node:fs');
const path = process.argv[2];
const manifest = JSON.parse(fs.readFileSync(path, 'utf8'));
const stableKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxclvOy2sunfRa2UeSV/L9xyuMR9V65z85mbKCy0XvSLUkTBXM8BnvnrDu1DHhLjpidA3cBtetVt7rzwsJSA6/CzlMmtG6L6//3MOAH5Mhng8tXXWXbuNuJobLv/7MORPqoqYKZuoL1bnUvjdrf4Pb3BBDZtHN8LcDz13gOO4dnEFQbSE4F5RQ4mIQAGMkmbmlJkwFk5I022XyX+cWm/+9VvwPuEDA1Qf7X1G+4use3hGYWVPcRb6xTp7swXsO/fP7auE51gYQD0Ht36wr32UR6lfRmsahbHOX4RLe36S8B4ee74kk5C8iCsZf2fidWmevzLk7kK0GW15pv3dpGFpPQIDAQAB';
if (manifest.key === stableKey) {
process.exit(0);
}
manifest.key = stableKey;
fs.writeFileSync(path, `${JSON.stringify(manifest, null, 4)}\n`, 'utf8');
process.exit(0);
PATCH_EOF
then
echo " - Set stable manifest key in manifest.json"
else
echo " - Failed to patch manifest.json"
exit 1
fi
echo "Patching Yomitan in: $YOMITAN_DIR"
PERMISSIONS_UTIL="$YOMITAN_DIR/js/data/permissions-util.js"
if [ ! -f "$PERMISSIONS_UTIL" ]; then
echo "Error: permissions-util.js not found at $PERMISSIONS_UTIL"
exit 1
fi
echo "Patching permissions-util.js..."
if grep -q "Electron workaround" "$PERMISSIONS_UTIL"; then
echo " - Already patched, skipping"
else
cat > "$PERMISSIONS_UTIL.tmp" << 'PATCH_EOF'
/*
* Copyright (C) 2023-2025 Yomitan Authors
* Copyright (C) 2021-2022 Yomichan Authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {getFieldMarkers} from './anki-util.js';
/**
* This function returns whether an Anki field marker might require clipboard permissions.
* This is speculative and may not guarantee that the field marker actually does require the permission,
* as the custom handlebars template is not deeply inspected.
* @param {string} marker
* @returns {boolean}
*/
function ankiFieldMarkerMayUseClipboard(marker) {
switch (marker) {
case 'clipboard-image':
case 'clipboard-text':
return true;
default:
return false;
}
}
/**
* @param {chrome.permissions.Permissions} permissions
* @returns {Promise<boolean>}
*/
export function hasPermissions(permissions) {
return new Promise((resolve, reject) => {
chrome.permissions.contains(permissions, (result) => {
const e = chrome.runtime.lastError;
if (e) {
reject(new Error(e.message));
} else {
resolve(result);
}
});
});
}
/**
* @param {chrome.permissions.Permissions} permissions
* @param {boolean} shouldHave
* @returns {Promise<boolean>}
*/
export function setPermissionsGranted(permissions, shouldHave) {
return (
shouldHave ?
new Promise((resolve, reject) => {
chrome.permissions.request(permissions, (result) => {
const e = chrome.runtime.lastError;
if (e) {
reject(new Error(e.message));
} else {
resolve(result);
}
});
}) :
new Promise((resolve, reject) => {
chrome.permissions.remove(permissions, (result) => {
const e = chrome.runtime.lastError;
if (e) {
reject(new Error(e.message));
} else {
resolve(!result);
}
});
})
);
}
/**
* @returns {Promise<chrome.permissions.Permissions>}
*/
export function getAllPermissions() {
// Electron workaround - chrome.permissions.getAll() not available
return Promise.resolve({
origins: ["<all_urls>"],
permissions: ["clipboardWrite", "storage", "unlimitedStorage", "scripting", "contextMenus"]
});
}
/**
* @param {string} fieldValue
* @returns {string[]}
*/
export function getRequiredPermissionsForAnkiFieldValue(fieldValue) {
const markers = getFieldMarkers(fieldValue);
for (const marker of markers) {
if (ankiFieldMarkerMayUseClipboard(marker)) {
return ['clipboardRead'];
}
}
return [];
}
/**
* @param {chrome.permissions.Permissions} permissions
* @param {import('settings').ProfileOptions} options
* @returns {boolean}
*/
export function hasRequiredPermissionsForOptions(permissions, options) {
const permissionsSet = new Set(permissions.permissions);
if (!permissionsSet.has('nativeMessaging') && (options.parsing.enableMecabParser || options.general.enableYomitanApi)) {
return false;
}
if (!permissionsSet.has('clipboardRead')) {
if (options.clipboard.enableBackgroundMonitor || options.clipboard.enableSearchPageMonitor) {
return false;
}
const fieldsList = options.anki.cardFormats.map((cardFormat) => cardFormat.fields);
for (const fields of fieldsList) {
for (const {value: fieldValue} of Object.values(fields)) {
const markers = getFieldMarkers(fieldValue);
for (const marker of markers) {
if (ankiFieldMarkerMayUseClipboard(marker)) {
return false;
}
}
}
}
}
return true;
}
PATCH_EOF
mv "$PERMISSIONS_UTIL.tmp" "$PERMISSIONS_UTIL"
echo " - Patched successfully"
fi
OPTIONS_SCHEMA="$YOMITAN_DIR/data/schemas/options-schema.json"
if [ ! -f "$OPTIONS_SCHEMA" ]; then
echo "Error: options-schema.json not found at $OPTIONS_SCHEMA"
exit 1
fi
echo "Patching options-schema.json..."
if grep -q '"selectText".*"default": true' "$OPTIONS_SCHEMA"; then
sed -i '/"selectText": {/,/"default":/{s/"default": true/"default": false/}' "$OPTIONS_SCHEMA"
echo " - Changed selectText default to false"
elif grep -q '"selectText".*"default": false' "$OPTIONS_SCHEMA"; then
echo " - selectText already set to false, skipping"
else
echo " - Warning: Could not find selectText setting"
fi
if grep -q '"layoutAwareScan".*"default": true' "$OPTIONS_SCHEMA"; then
sed -i '/"layoutAwareScan": {/,/"default":/{s/"default": true/"default": false/}' "$OPTIONS_SCHEMA"
echo " - Changed layoutAwareScan default to false"
elif grep -q '"layoutAwareScan".*"default": false' "$OPTIONS_SCHEMA"; then
echo " - layoutAwareScan already set to false, skipping"
else
echo " - Warning: Could not find layoutAwareScan setting"
fi
POPUP_JS="$YOMITAN_DIR/js/app/popup.js"
if [ ! -f "$POPUP_JS" ]; then
echo "Error: popup.js not found at $POPUP_JS"
exit 1
fi
echo "Patching popup.js..."
if grep -q "yomitan-popup-shown" "$POPUP_JS"; then
echo " - Already patched, skipping"
else
# Add the visibility event dispatch after the existing _onVisibleChange code
# We need to add it after: void this._invokeSafe('displayVisibilityChanged', {value});
sed -i "/void this._invokeSafe('displayVisibilityChanged', {value});/a\\
\\
// Dispatch custom events for popup visibility (Electron integration)\\
if (value) {\\
window.dispatchEvent(new CustomEvent('yomitan-popup-shown'));\\
} else {\\
window.dispatchEvent(new CustomEvent('yomitan-popup-hidden'));\\
}" "$POPUP_JS"
echo " - Added visibility events"
fi
echo ""
echo "Yomitan patching complete!"
echo ""
echo "Changes applied:"
echo " 1. permissions-util.js: Hardcoded permissions (Electron workaround)"
echo " 2. options-schema.json: selectText=false, layoutAwareScan=false"
echo " 3. popup.js: Added yomitan-popup-shown/hidden events"
echo ""
echo "To verify: Run 'bun run dev' and check for 'Yomitan extension loaded successfully'"
If you need to change Electron compatibility behavior, patch the forked source repo and rebuild.
EOF

View File

@@ -4,6 +4,7 @@ import path from 'node:path';
import process from 'node:process';
import { createTokenizerDepsRuntime, tokenizeSubtitle } from '../src/core/services/tokenizer.js';
import { resolveYomitanExtensionPath as resolveBuiltYomitanExtensionPath } from '../src/core/services/yomitan-extension-paths.js';
import { MecabTokenizer } from '../src/mecab-tokenizer.js';
import type { MergedToken } from '../src/types.js';
@@ -112,12 +113,12 @@ function parseCliArgs(argv: string[]): CliOptions {
if (!next) {
throw new Error('Missing value for --yomitan-extension');
}
yomitanExtensionPath = path.resolve(next);
yomitanExtensionPath = next;
continue;
}
if (arg.startsWith('--yomitan-extension=')) {
yomitanExtensionPath = path.resolve(arg.slice('--yomitan-extension='.length));
yomitanExtensionPath = arg.slice('--yomitan-extension='.length);
continue;
}
@@ -126,12 +127,12 @@ function parseCliArgs(argv: string[]): CliOptions {
if (!next) {
throw new Error('Missing value for --yomitan-user-data');
}
yomitanUserDataPath = path.resolve(next);
yomitanUserDataPath = next;
continue;
}
if (arg.startsWith('--yomitan-user-data=')) {
yomitanUserDataPath = path.resolve(arg.slice('--yomitan-user-data='.length));
yomitanUserDataPath = arg.slice('--yomitan-user-data='.length);
continue;
}
@@ -372,21 +373,10 @@ function findSelectedCandidateIndexes(
}
function resolveYomitanExtensionPath(explicitPath?: string): string | null {
const candidates = [
explicitPath ? path.resolve(explicitPath) : null,
path.resolve(process.cwd(), 'vendor', 'yomitan'),
];
for (const candidate of candidates) {
if (!candidate) {
continue;
}
if (fs.existsSync(path.join(candidate, 'manifest.json'))) {
return candidate;
}
}
return null;
return resolveBuiltYomitanExtensionPath({
explicitPath,
cwd: process.cwd(),
});
}
async function setupYomitanRuntime(options: CliOptions): Promise<YomitanRuntimeState> {
@@ -420,7 +410,7 @@ async function setupYomitanRuntime(options: CliOptions): Promise<YomitanRuntimeS
const extensionPath = resolveYomitanExtensionPath(options.yomitanExtensionPath);
if (!extensionPath) {
state.note = 'no Yomitan extension directory found';
state.note = 'no built Yomitan extension directory found; run `bun run build:yomitan`';
return state;
}

View File

@@ -1,13 +1,17 @@
import { BrowserWindow, Extension, session } from 'electron';
import * as fs from 'fs';
import * as path from 'path';
import { createLogger } from '../../logger';
import { ensureExtensionCopy } from './yomitan-extension-copy';
import {
getYomitanExtensionSearchPaths,
resolveExistingYomitanExtensionPath,
} from './yomitan-extension-paths';
const logger = createLogger('main:yomitan-extension-loader');
export interface YomitanExtensionLoaderDeps {
userDataPath: string;
extensionPath?: string;
getYomitanParserWindow: () => BrowserWindow | null;
setYomitanParserWindow: (window: BrowserWindow | null) => void;
setYomitanParserReadyPromise: (promise: Promise<void> | null) => void;
@@ -18,25 +22,17 @@ export interface YomitanExtensionLoaderDeps {
export async function loadYomitanExtension(
deps: YomitanExtensionLoaderDeps,
): Promise<Extension | null> {
const searchPaths = [
path.join(__dirname, '..', '..', 'vendor', 'yomitan'),
path.join(__dirname, '..', '..', '..', 'vendor', 'yomitan'),
path.join(process.resourcesPath, 'yomitan'),
'/usr/share/SubMiner/yomitan',
path.join(deps.userDataPath, 'yomitan'),
];
let extPath: string | null = null;
for (const p of searchPaths) {
if (fs.existsSync(p)) {
extPath = p;
break;
}
}
const searchPaths = getYomitanExtensionSearchPaths({
explicitPath: deps.extensionPath,
moduleDir: __dirname,
resourcesPath: process.resourcesPath,
userDataPath: deps.userDataPath,
});
let extPath = resolveExistingYomitanExtensionPath(searchPaths, fs.existsSync);
if (!extPath) {
logger.error('Yomitan extension not found in any search path');
logger.error('Install Yomitan to one of:', searchPaths);
logger.error('Run `bun run build:yomitan` or install Yomitan to one of:', searchPaths);
return null;
}

View File

@@ -0,0 +1,50 @@
import assert from 'node:assert/strict';
import path from 'node:path';
import test from 'node:test';
import {
getYomitanExtensionSearchPaths,
resolveExistingYomitanExtensionPath,
} from './yomitan-extension-paths';
test('getYomitanExtensionSearchPaths prioritizes generated build output before packaged fallbacks', () => {
const searchPaths = getYomitanExtensionSearchPaths({
cwd: '/repo',
moduleDir: '/repo/dist/core/services',
resourcesPath: '/opt/SubMiner/resources',
userDataPath: '/Users/kyle/.config/SubMiner',
});
assert.deepEqual(searchPaths, [
path.join('/repo', 'build', 'yomitan'),
path.join('/opt/SubMiner/resources', 'yomitan'),
'/usr/share/SubMiner/yomitan',
path.join('/Users/kyle/.config/SubMiner', 'yomitan'),
]);
});
test('resolveExistingYomitanExtensionPath returns first manifest-backed candidate', () => {
const existing = new Set<string>([
path.join('/repo', 'build', 'yomitan', 'manifest.json'),
path.join('/repo', 'vendor', 'subminer-yomitan', 'ext', 'manifest.json'),
]);
const resolved = resolveExistingYomitanExtensionPath(
[
path.join('/repo', 'build', 'yomitan'),
path.join('/repo', 'vendor', 'subminer-yomitan', 'ext'),
],
(candidate) => existing.has(candidate),
);
assert.equal(resolved, path.join('/repo', 'build', 'yomitan'));
});
test('resolveExistingYomitanExtensionPath ignores source tree without built manifest', () => {
const resolved = resolveExistingYomitanExtensionPath(
[path.join('/repo', 'vendor', 'subminer-yomitan', 'ext')],
() => false,
);
assert.equal(resolved, null);
});

View File

@@ -0,0 +1,57 @@
import * as fs from 'node:fs';
import * as path from 'node:path';
export interface YomitanExtensionPathOptions {
explicitPath?: string;
cwd?: string;
moduleDir?: string;
resourcesPath?: string;
userDataPath?: string;
}
function pushUnique(values: string[], candidate: string | null | undefined): void {
if (!candidate || values.includes(candidate)) {
return;
}
values.push(candidate);
}
export function getYomitanExtensionSearchPaths(
options: YomitanExtensionPathOptions = {},
): string[] {
const searchPaths: string[] = [];
pushUnique(searchPaths, options.explicitPath ? path.resolve(options.explicitPath) : null);
pushUnique(searchPaths, options.cwd ? path.resolve(options.cwd, 'build', 'yomitan') : null);
pushUnique(
searchPaths,
options.moduleDir
? path.resolve(options.moduleDir, '..', '..', '..', 'build', 'yomitan')
: null,
);
pushUnique(searchPaths, options.resourcesPath ? path.join(options.resourcesPath, 'yomitan') : null);
pushUnique(searchPaths, '/usr/share/SubMiner/yomitan');
pushUnique(searchPaths, options.userDataPath ? path.join(options.userDataPath, 'yomitan') : null);
return searchPaths;
}
export function resolveExistingYomitanExtensionPath(
searchPaths: string[],
existsSync: (path: string) => boolean = fs.existsSync,
): string | null {
for (const candidate of searchPaths) {
if (existsSync(path.join(candidate, 'manifest.json'))) {
return candidate;
}
}
return null;
}
export function resolveYomitanExtensionPath(
options: YomitanExtensionPathOptions = {},
existsSync: (path: string) => boolean = fs.existsSync,
): string | null {
return resolveExistingYomitanExtensionPath(getYomitanExtensionSearchPaths(options), existsSync);
}

View File

@@ -2,6 +2,7 @@ import assert from 'node:assert/strict';
import path from 'node:path';
import test from 'node:test';
import { pathToFileURL } from 'node:url';
import { resolveYomitanExtensionPath } from './yomitan-extension-paths';
class FakeStyle {
private values = new Map<string, string>();
@@ -155,14 +156,17 @@ function findFirstByClass(node: FakeNode, className: string): FakeNode | null {
}
test('StructuredContentGenerator uses direct img loading for popup glossary images', async () => {
const yomitanRoot = resolveYomitanExtensionPath({ cwd: process.cwd() });
assert.ok(yomitanRoot, 'Run `bun run build:yomitan` before Yomitan integration tests.');
const { DisplayContentManager } = await import(
pathToFileURL(
path.join(process.cwd(), 'vendor/yomitan/js/display/display-content-manager.js'),
path.join(yomitanRoot, 'js', 'display', 'display-content-manager.js'),
).href
);
const { StructuredContentGenerator } = await import(
pathToFileURL(
path.join(process.cwd(), 'vendor/yomitan/js/display/structured-content-generator.js'),
path.join(yomitanRoot, 'js', 'display', 'structured-content-generator.js'),
).href
);

View File

@@ -1,8 +1,9 @@
import assert from 'node:assert/strict';
import path from 'node:path';
import test from 'node:test';
import { pathToFileURL } from 'node:url';
// @ts-expect-error Vendored Yomitan translator has no local TypeScript declarations.
import { Translator } from '../vendor/yomitan/js/language/translator.js';
import { resolveYomitanExtensionPath } from './core/services/yomitan-extension-paths';
type SortableTermEntry = {
matchPrimaryReading: boolean;
@@ -28,8 +29,20 @@ type SortableDefinition = {
index: number;
};
test('Translator prioritizes SubMiner term entries without changing dictionary index order', () => {
const translator = new Translator({});
async function loadTranslator(): Promise<{ new (...args: unknown[]): { [key: string]: unknown } }> {
const yomitanRoot = resolveYomitanExtensionPath({ cwd: process.cwd() });
assert.ok(yomitanRoot, 'Run `bun run build:yomitan` before Yomitan integration tests.');
const module = await import(
pathToFileURL(path.join(yomitanRoot, 'js', 'language', 'translator.js')).href
);
return module.Translator as { new (...args: unknown[]): { [key: string]: unknown } };
}
test('Translator prioritizes SubMiner term entries without changing dictionary index order', async () => {
const Translator = await loadTranslator();
const translator = new Translator({}) as {
_sortTermDictionaryEntries: (entries: unknown[]) => void;
};
const entries: SortableTermEntry[] = [
{
matchPrimaryReading: true,
@@ -64,8 +77,11 @@ test('Translator prioritizes SubMiner term entries without changing dictionary i
assert.equal(entries[0]?.dictionaryAlias, 'SubMiner Character Dictionary');
});
test('Translator prioritizes SubMiner definitions without changing dictionary index order', () => {
const translator = new Translator({});
test('Translator prioritizes SubMiner definitions without changing dictionary index order', async () => {
const Translator = await loadTranslator();
const translator = new Translator({}) as {
_sortTermDictionaryEntryDefinitions: (definitions: unknown[]) => void;
};
const definitions: SortableDefinition[] = [
{
dictionary: 'JMdict',

1
vendor/subminer-yomitan vendored Submodule

Submodule vendor/subminer-yomitan added at 9863d865e1

View File

@@ -1,64 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Yomitan Action Popup</title>
<link rel="icon" type="image/png" href="/images/icon16.png" sizes="16x16">
<link rel="icon" type="image/png" href="/images/icon19.png" sizes="19x19">
<link rel="icon" type="image/png" href="/images/icon32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/images/icon38.png" sizes="38x38">
<link rel="icon" type="image/png" href="/images/icon48.png" sizes="48x48">
<link rel="icon" type="image/png" href="/images/icon64.png" sizes="64x64">
<link rel="icon" type="image/png" href="/images/icon128.png" sizes="128x128">
<link rel="stylesheet" type="text/css" href="/css/material.css">
<link rel="stylesheet" type="text/css" href="/css/action-popup.css">
<script src="/js/pages/action-popup-main.js" type="module"></script>
</head>
<body>
<div id="loading">
Loading...
</div>
<div id="action-popup">
<div class="action-container action-select-profile" hidden>
<div class="action-item-left">
<h2 class="action-title">Profile</h2>
</div>
<div class="action-item-right">
<select tabindex="0" class="profile-select" id="profile-select">
</select>
</div>
</div>
<div class="action-container">
<div class="action-item-center">
<label class="toggle">
<input tabindex="0" type="checkbox" class="enable-search">
<div class="toggle-group">
<span class="toggle-on">On</span>
<span class="toggle-off">Off</span>
<span class="toggle-handle"></span>
</div>
</label>
<p class="tooltip">Hover over text to scan</p>
</div>
</div>
<div class="action-container action-buttons">
<button tabindex="0" type="button" class="low-emphasis action-open-settings" title="Settings" data-hotkey='["global:openSettingsPage","title","Settings ({0})"]'>
<div class="action-icon">
<span class="icon" data-icon="cog"></span>
</div>
</button>
<button tabindex="0" type="button" class="low-emphasis action-open-search" title="Search&#010;Shift+click to open here" data-hotkey='["global:openSearchPage","title","Search ({0})\nShift+click to open here"]'>
<div class="action-icon">
<span class="icon" data-icon="magnifying-glass"></span>
</div>
</button>
<button tabindex="0" type="button" class="low-emphasis action-open-info" title="Information" data-hotkey='["global:openInfoPage","title","Information ({0})"]'>
<div class="action-icon">
<span class="icon" data-icon="question-mark-circle"></span>
</div>
</button>
</div>
</div>
</body>
</html>

View File

@@ -1,10 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Yomitan Background</title>
</head>
<body>
<script type="module" src="js/background/background-main.js"></script>
</body>
</html>

View File

@@ -1,376 +0,0 @@
/*
* Copyright (C) 2023-2025 Yomitan Authors
* Copyright (C) 2020-2022 Yomichan Authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/* Variables */
:root {
--font-size-no-units: 14;
--font-size: calc(1px * var(--font-size-no-units));
--line-height-no-units: 20;
--line-height: calc(var(--line-height-no-units) / var(--font-size-no-units));
--background-color: #f8f9fa;
--text-color: #333333;
}
:root[data-theme=dark] {
--background-color: #1e1e1e;
--text-color: #cccccc;
}
/* Initilization */
body[data-loaded=true] #loading {
display: none;
}
body:not([data-loaded=true]) #action-popup {
display: none;
}
:root[data-mode=full] #action-popup {
display: initial;
}
#action-popup {
display: flex;
flex-flow: column nowrap;
align-items: center;
}
body {
padding: 5px;
margin: 0;
font-family: 'Segoe UI', Tahoma, sans-serif;
font-size: var(--font-size);
width: max-content;
height: max-content;
background-color: var(--background-color);
}
/* Toggle */
body[data-loaded=true] .toggle-group {
transition: transform 0.35s;
}
.toggle>input[type=checkbox] {
width: 0;
height: 0;
opacity: 0;
display: block;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.toggle>input[type=checkbox]:not(:checked)~.toggle-group {
transform: translateX(-50%);
}
.toggle {
box-sizing: border-box;
width: 85px;
height: 43px;
position: relative;
overflow: hidden;
border: 1px solid #245580;
border-radius: 4px;
display: inline-block;
}
.toggle-group {
position: absolute;
width: 200%;
left: 0;
top: 0;
bottom: 0;
user-select: none;
}
.toggle-on,
.toggle-off,
.toggle-handle {
display: flex;
justify-content: center;
align-items: center;
padding: 6px 12px;
font-size: var(--font-size);
font-weight: bold;
line-height: var(--line-height);
text-align: center;
white-space: nowrap;
cursor: pointer;
}
.toggle-on,
.toggle-off {
position: absolute;
top: 0;
bottom: 0;
margin: 0;
border: 0;
}
.toggle-on {
padding-right: 24px;
left: 0;
right: 50%;
color: #ffffff;
border-color: #2e6da4;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), inset 0 3px 5px rgba(0, 0, 0, 0);
background-image: linear-gradient(225deg, #bc00ff, #00eeff);
background-repeat: repeat-x;
}
input[type=checkbox]:focus~.toggle-group>.toggle-on,
input[type=checkbox]~.toggle-group>.toggle-on:hover {
filter: grayscale(30%);
}
input[type=checkbox]:focus:not(:focus-visible)~.toggle-group>.toggle-on:not(:hover) {
background-image: linear-gradient(225deg, #bc00ff, #00eeff);
}
input[type=checkbox]:focus-visible~.toggle-group>.toggle-on {
filter: grayscale(30%);
}
input[type=checkbox]~.toggle-group>.toggle-on:active,
input[type=checkbox]~.toggle-group>.toggle-on:active:focus {
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
.toggle-off {
padding-left: 24px;
left: 50%;
right: 0;
}
.toggle-handle {
position: relative;
margin: 0 auto;
padding-top: 0;
padding-bottom: 0;
height: 100%;
width: 0;
border-style: solid;
border-width: 0 1px;
border-radius: 4px;
border-color: #cccccc;
}
.toggle-off,
.toggle-handle {
color: #333333;
text-shadow: 0 1px 0 #ffffff;
background-color: #ffffff;
background-repeat: repeat-x;
}
input[type=checkbox]:focus~.toggle-group>.toggle-off,
input[type=checkbox]~.toggle-group>.toggle-off:hover,
input[type=checkbox]~.toggle-group>.toggle-handle:hover {
background-color: #e6e6e6;
}
input[type=checkbox]:focus:not(:focus-visible)~.toggle-group>.toggle-off:not(:hover) {
background-color: #ffffff;
}
input[type=checkbox]:focus-visible~.toggle-group>.toggle-off,
input[type=checkbox]~.toggle-group>.toggle-off:hover {
background-color: #e6e6e6;
}
input[type=checkbox]~.toggle-group>.toggle-off:active,
input[type=checkbox]~.toggle-group>.toggle-handle:active,
input[type=checkbox]~.toggle-group>.toggle-off:active:focus,
input[type=checkbox]~.toggle-group>.toggle-handle:active:focus {
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
/* Action Containers */
h2.action-title {
padding: 0;
margin: 0;
font-size: 1.125em;
line-height: 1.5;
}
.action-icon:hover {
cursor: pointer;
}
.action-icon {
flex: 0 0 auto;
align-self: center;
}
.action-icon>.icon {
display: block;
background-color: var(--button-default-icon-color);
width: 1.5em;
height: 1.5em;
}
.low-emphasis {
position: relative;
}
.action-item-left {
flex: 1 1 auto;
align-self: center;
position: relative;
display: flex;
justify-content: flex-start;
}
.action-item-center {
flex: 1 1 auto;
align-self: center;
display: flex;
flex-flow: column nowrap;
align-items: center;
justify-content: center;
}
.action-item-right {
flex: 0 1 auto;
align-self: stretch;
display: flex;
flex-flow: row nowrap;
align-items: center;
align-content: center;
justify-content: flex-end;
}
.action-container:not([hidden]) {
display: flex;
justify-content: space-between;
align-items: center;
padding: 5px;
}
.action-container button {
flex: 0 0 auto;
}
.action-container.action-buttons {
gap: 0.25em;
}
/* Actions */
.action-container.action-select-profile {
position: relative;
gap: 0.5em;
}
select.profile-select {
width: 7em;
height: 100%;
box-sizing: border-box;
border: 0;
margin: 0;
cursor: pointer;
font-size: var(--font-size);
overflow: hidden;
text-overflow: ellipsis;
}
/* Tooltip */
.tooltip {
color: #808080;
padding: 0;
margin: 0;
margin-top: 0.25em;
}
.enable-dictionary-tooltip {
color: #f0ad4e;
}
.tooltip>a:link, a:visited {
color: #f0ad4e;
}
/* Mobile overrides */
:root[data-mode=full] #action-popup {
display: initial;
}
:root[data-mode=full] body {
min-width: 95%;
width: max-content;
font-size: calc(var(--font-size) * 2);
text-align: center;
}
:root[data-mode=full] .toggle-on, :root[data-mode=full] .toggle-off {
font-size: calc(var(--font-size) * 4);
}
:root[data-mode=full] .toggle-handle {
padding-left: 65px;
padding-right: 65px;
border-radius: 10px;
}
:root[data-mode=full] .toggle {
width: 100%;
padding-top: 37.7%;
}
:root[data-mode=full] #extension-info {
max-width: 95vw;
overflow-wrap: break-word;
}
:root[data-mode=full] select.profile-select {
font-size: calc(var(--font-size) * 2);
}
/* Fallback Mobile overrides */
/* Treat devices that can't hover as mobile devices */
@media (hover: none) {
#action-popup {
display: initial;
}
body {
min-width: 95%;
width: max-content;
font-size: calc(var(--font-size) * 2);
text-align: center;
}
.toggle-on, .toggle-off {
font-size: calc(var(--font-size) * 4);
}
.toggle-handle {
padding-left: 65px;
padding-right: 65px;
border-radius: 10px;
}
.toggle {
width: 100%;
padding-top: 37.7%;
}
#extension-info {
max-width: 95vw;
overflow-wrap: break-word;
}
select.profile-select {
font-size: calc(var(--font-size) * 2);
}
}
/* Dark mode before themes are applied
DO NOT use this for normal theming */
@media (prefers-color-scheme: dark) {
body:not([data-loaded=true]) {
color: #cccccc;
background-color: #1e1e1e;
}
}

View File

@@ -1,30 +0,0 @@
/*
* Copyright (C) 2023-2025 Yomitan Authors
* Copyright (C) 2022 Yomichan Authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/* stylelint-disable declaration-no-important */
#clipboard-rich-content-paste-target * {
background-image: none !important;
list-style-image: none !important;
content: none !important;
cursor: auto !important;
border-image-source: none !important;
offset-path: none !important;
-webkit-mask-image: none !important;
mask-image: none !important;
}
/* stylelint-enable declaration-no-important */

View File

@@ -1,132 +0,0 @@
/*
* Copyright (C) 2023-2025 Yomitan Authors
* Copyright (C) 2021-2022 Yomichan Authors
*
* This program is free software: you can redistribute it and/or modify
* it under the entrys of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
:root {
--pronunciation-annotation-color: #000000;
}
:root[data-theme=dark] {
--pronunciation-annotation-color: #ffffff;
}
.pronunciation-downstep-notation {
display: inline;
}
.pronunciation-text {
display: inline;
}
.pronunciation-mora {
display: inline-block;
position: relative;
}
.pronunciation-mora-line {
border-color: var(--pronunciation-annotation-color);
}
.pronunciation-mora[data-pitch=high]>.pronunciation-mora-line {
display: block;
user-select: none;
pointer-events: none;
position: absolute;
top: 0.1em;
left: 0;
right: 0;
height: 0;
border-top-width: 0.1em;
border-top-style: solid;
}
.pronunciation-mora[data-pitch=high][data-pitch-next=low]>.pronunciation-mora-line {
right: -0.1em;
height: 0.4em;
border-right-width: 0.1em;
border-right-style: solid;
}
.pronunciation-mora[data-pitch=high][data-pitch-next=low] {
padding-right: 0.1em;
margin-right: 0.1em;
}
.pronunciation-devoice-indicator {
display: block;
position: absolute;
left: 50%;
top: 50%;
width: 1.125em;
height: 1.125em;
border: calc(1.5em / var(--font-size-no-units)) dotted var(--danger-color);
border-radius: 50%;
box-sizing: border-box;
z-index: 1;
transform: translate(-50%, -50%);
}
.pronunciation-nasal-indicator {
display: block;
position: absolute;
right: -0.125em;
top: 0.125em;
width: 0.375em;
height: 0.375em;
border: calc(1.5em / var(--font-size-no-units)) solid var(--danger-color);
border-radius: 50%;
box-sizing: border-box;
z-index: 1;
}
.pronunciation-nasal-diacritic {
position: absolute;
width: 0;
height: 0;
opacity: 0;
}
.pronunciation-character {
display: inline;
}
.pronunciation-character-group {
display: inline-block;
position: relative;
}
.pronunciation-graph {
display: inline-block;
vertical-align: middle;
height: 1.5em;
}
.pronunciation-graph-line,
.pronunciation-graph-line-tail {
fill: none;
stroke: var(--pronunciation-annotation-color);
stroke-width: 5;
}
.pronunciation-graph-line-tail {
stroke-dasharray: 5 5;
}
.pronunciation-graph-dot {
fill: var(--pronunciation-annotation-color);
stroke: var(--pronunciation-annotation-color);
stroke-width: 5;
}
.pronunciation-graph-dot-downstep1 {
fill: none;
stroke: var(--pronunciation-annotation-color);
stroke-width: 5;
}
.pronunciation-graph-dot-downstep2 {
fill: var(--pronunciation-annotation-color);
}
.pronunciation-graph-triangle {
fill: none;
stroke: var(--pronunciation-annotation-color);
stroke-width: 5;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,36 +0,0 @@
/*
* Copyright (C) 2023-2025 Yomitan Authors
* Copyright (C) 2021-2022 Yomichan Authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#permissions-origin-list {
display: grid;
grid-template-columns: auto 1fr auto;
grid-template-rows: auto;
align-items: center;
justify-content: center;
}
.permissions-origin-index {
margin: 0 0.5em;
}
input[type=text].permissions-origin-input {
width: auto;
justify-self: stretch;
}
.permissions-origin-button {
justify-self: center;
margin-left: 0.5em;
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright (C) 2023-2025 Yomitan Authors
* Copyright (C) 2016-2022 Yomichan Authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
iframe.yomitan-popup {
all: initial;
font-size: 1px;
background-color: #ffffff;
border: 1em solid #999999;
box-shadow: 0 0 10em rgba(0, 0, 0, 0.5);
position: fixed;
resize: none;
visibility: hidden;
z-index: 2147483647;
box-sizing: border-box;
}
iframe.yomitan-popup[data-theme=dark] {
background-color: #1e1e1e;
border-color: #666666;
}
iframe.yomitan-popup[data-outer-theme=dark] {
box-shadow: 0 0 10em rgba(255, 255, 255, 0.5);
}
iframe.yomitan-popup[data-outer-theme=none] {
box-shadow: none;
}
iframe.yomitan-popup[data-popup-display-mode=full-width] {
border-left: none;
border-right: none;
}
iframe.yomitan-popup[data-popup-display-mode=full-width][data-below=true] {
border-bottom: none;
}
iframe.yomitan-popup[data-popup-display-mode=full-width]:not([data-below=true]) {
border-top: none;
}

View File

@@ -1,164 +0,0 @@
/*
* Copyright (C) 2023-2025 Yomitan Authors
* Copyright (C) 2020-2022 Yomichan Authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
:root {
--font-size-no-units: 14;
--font-size: calc(1px * var(--font-size-no-units));
--line-height-no-units: 20;
--line-height: calc(var(--line-height-no-units) / var(--font-size-no-units));
--animation-duration: 0s;
--example-text-color: #333333;
--background-color: rgba(0, 0, 0, 0);
}
:root[data-loaded=true] {
--animation-duration: 0.25s;
}
:root[data-theme=dark] {
--example-text-color: #d4d4d4;
--background-color: rgba(0, 0, 0, 0);
}
html {
background-color: var(--background-color);
}
html.dark {
background-color: var(--background-color);
}
html,
body {
margin: 0;
padding: 0;
border: 0;
overflow: hidden;
width: 100%;
height: 100%;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: var(--font-size);
line-height: var(--line-height);
}
.content {
display: flex;
min-width: 100%;
min-height: 100%;
box-sizing: border-box;
padding: 1em;
flex-flow: column nowrap;
align-items: center;
justify-content: center;
}
.content-body {
max-width: 100%;
width: 400px;
}
.top-options {
max-width: 100%;
display: flex;
flex-flow: row nowrap;
align-items: center;
}
.top-options-left {
flex: 1 1 auto;
}
.top-options-right {
flex: 0 0 auto;
}
.example-text-container {
position: relative;
}
.example-text {
display: block;
width: 100%;
font-size: 24px;
line-height: 1.25em;
height: 1.25em;
box-sizing: border-box;
border: 1px solid rgba(221, 221, 221, 0);
margin: 0;
padding: 0;
outline: none;
color: var(--example-text-color);
background-color: transparent;
white-space: pre;
transition: background-color var(--animation-duration) linear 0s, border-color var(--animation-duration) linear 0s;
}
.example-text:hover,
.example-text-input {
border-color: #dddddd;
}
.example-text[hidden] {
display: none;
}
.example-text-input {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.example-text-input:not([hidden])+.example-text {
visibility: hidden;
}
.popup-placeholder {
display: flex;
width: 100%;
height: 250px;
padding-top: 10px;
border: 1px solid rgba(0, 0, 0, 0);
flex-flow: column nowrap;
justify-content: center;
}
.placeholder-info {
flex: 0 1 auto;
visibility: hidden;
opacity: 0;
transition: opacity var(--animation-duration) linear 0s, visibility 0s linear var(--animation-duration);
}
.placeholder-info.placeholder-info-visible {
color: var(--example-text-color);
visibility: visible;
opacity: 1;
transition: opacity var(--animation-duration) linear 0s, visibility 0s linear 0s;
}
.theme-button {
display: inline-block;
margin-left: 0.5em;
text-decoration: none;
cursor: pointer;
white-space: nowrap;
line-height: 0;
}
.theme-button>input {
vertical-align: middle;
margin: 0 0.25em 0 0;
padding: 0;
}
.theme-button>span {
vertical-align: middle;
}
.theme-button:hover>span {
text-decoration: underline;
}

View File

@@ -1,489 +0,0 @@
:root {
--padding: 10px;
--padding-negative: calc(var(--padding) * -1);
--content-width: 700px;
--shadow-vertical: 0 1px 4px 0 var(--shadow-color), 0 2px 2px 0 var(--shadow-color);
--shadow-left: -1px 0 4px 0 var(--shadow-color), -2px 0 2px 0 var(--shadow-color);
--settings-group-horizontal-margin: 0;
--settings-group-inner-vertical-padding: 0.85em;
--settings-group-inner-horizontal-padding: 1.5em;
--settings-group-inner-horizontal-padding-half: calc(var(--settings-group-inner-horizontal-padding) * 0.5);
--settings-group-inner-horizontal-padding-half-wrappable: var(--settings-group-inner-horizontal-padding-half);
--settings-group-inner-horizontal-padding-fourth: calc(var(--settings-group-inner-horizontal-padding) * 0.25);
--settings-group-border-radius: 0.3em;
--settings-group-right-max-height: 40px;
--settings-group-wrap: nowrap;
--show-preview-label-height: 40px;
--font-size-no-units: 14;
--font-size: calc(1px * var(--font-size-no-units));
--font-size-small: 12px;
--outline-item-height: 40px;
--outline-item-icon-size: 32px;
--input-short-width: calc(var(--input-width-large) / 2 - var(--padding) / 2);
--input-short-height: 24px;
--input-medium-width: calc(var(--input-width-large) * 0.75);
--fab-button-size: 56px;
--fab-button-padding: 16px;
--modal-width: 600px;
--modal-height: 400px;
--modal-width-small: 400px;
--modal-height-small: 200px;
--modal-width-medium: 600px;
--modal-height-medium: 400px;
--modal-transition-offset: -64px;
--badge-size: 16px;
--link-color: var(--accent-color);
--link-color-hover: var(--accent-color-dark);
--separator-color1: #cccccc;
--separator-color2: #eeeeee;
--outline-item-background-color: rgba(13, 13, 13, 0);
--outline-item-background-color-hover: rgba(13, 13, 13, 0.15);
--warning-color: #96751c;
--warning-color-light: #edc75e;
--dim-background-color: rgba(0, 0, 0, 0.5);
--content-dimmer-color: rgba(0, 0, 0, 0.1);
--advanced-color: #6640be;
--advanced-color-lighter: hsl(258, 50%, 75%);
--advanced-color-transparent25: rgba(102, 64, 190, 0.5);
--modal-padding-horizontal: 1em;
--modal-padding-vertical: 0.625em;
--modal-padding-vertical-half: calc(var(--modal-padding-vertical) * 0.5);
--modal-button-spacing: 0.625em;
}
:root:not([data-loaded=true]) {
--animation-duration: 0s;
}
:root[data-theme=dark] {
--separator-color1: #333333;
--separator-color2: #222222;
}
/* Modal */
.modal {
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
overscroll-behavior: contain;
background-color: var(--dim-background-color);
outline: none;
z-index: 10000;
opacity: 1;
visibility: visible;
transition:
opacity var(--animation-duration2) ease-out,
visibility 0s linear;
}
.modal[hidden] {
opacity: 0;
visibility: hidden;
transition:
opacity var(--animation-duration2) ease-in,
visibility 0s linear var(--animation-duration2);
}
.modal[hidden]:not(.hidden-animating) {
display: none;
}
.modal-content {
max-width: 100%;
max-height: 100%;
width: var(--modal-width);
height: var(--modal-height);
background-color: var(--background-color-light);
flex: 0 1 auto;
border-radius: 0.5em;
transform: translate(0, 0);
transition:
transform var(--animation-duration2) ease-out,
width var(--animation-duration2) ease-in-out,
height var(--animation-duration2) ease-in-out,
border-radius var(--animation-duration2) ease-in-out;
box-shadow: var(--shadow-vertical);
display: flex;
flex-flow: column nowrap;
overflow: hidden;
}
.modal[hidden] .modal-content {
pointer-events: none;
}
.modal-content.modal-content-small {
width: var(--modal-width-small);
min-height: var(--modal-height-small);
height: auto;
max-height: 100%;
}
.modal-content.modal-content-medium {
width: var(--modal-width-medium);
min-height: var(--modal-height-medium);
height: auto;
max-height: 100%;
}
.modal-content.modal-content-full {
width: var(--content-width);
height: 100%;
transform: translate(0, 0);
border-radius: 0;
}
.modal[hidden] .modal-content {
transform: translate(0, var(--modal-transition-offset));
transition:
transform 0s linear var(--animation-duration2),
width var(--animation-duration2) ease-in-out,
height var(--animation-duration2) ease-in-out,
border-radius var(--animation-duration2) ease-in-out;
}
.modal-header {
flex: 0 0 auto;
padding: var(--modal-padding-vertical) var(--modal-padding-horizontal) var(--modal-padding-vertical-half);
display: flex;
width: 100%;
align-items: center;
box-sizing: border-box;
}
.modal-title {
font-size: 1.125em;
flex: 1 1 auto;
}
.modal-footer {
flex: 0 0 auto;
padding: var(--modal-padding-vertical-half) var(--modal-padding-horizontal) var(--modal-padding-vertical);
margin-right: calc(var(--modal-button-spacing) * -1);
margin-top: calc(var(--modal-button-spacing) * -1);
display: flex;
flex-flow: row wrap;
align-items: flex-end;
justify-items: flex-end;
justify-content: flex-end;
}
.modal-footer>* {
margin-right: var(--modal-button-spacing);
margin-top: var(--modal-button-spacing);
}
.modal-body {
flex: 1 1 auto;
overflow: auto;
padding: var(--modal-padding-vertical-half) var(--modal-padding-horizontal);
}
.modal-body-addon {
flex: 0 0 auto;
padding: var(--modal-padding-vertical-half) var(--modal-padding-horizontal);
}
.modal-body>.settings-item,
.modal-settings-group>.settings-item {
margin-left: calc(var(--modal-padding-horizontal) * -1);
}
.modal-body .settings-item {
margin-right: calc(var(--modal-padding-horizontal) * -1);
}
.modal-body .settings-item+.settings-item {
border-top: none;
}
.modal-body .settings-item-left {
padding-left: var(--modal-padding-horizontal);
padding-top: var(--settings-group-inner-horizontal-padding-fourth);
padding-bottom: var(--settings-group-inner-horizontal-padding-fourth);
}
.modal-body .settings-item-right {
padding-right: var(--modal-padding-horizontal);
padding-top: var(--settings-group-inner-horizontal-padding-fourth);
padding-bottom: var(--settings-group-inner-horizontal-padding-fourth);
}
.modal-body .settings-item-children {
padding-left: var(--modal-padding-horizontal);
padding-right: var(--modal-padding-horizontal);
padding-bottom: var(--settings-group-inner-horizontal-padding-fourth);
}
.modal.modal-left {
display: flex;
flex-flow: row nowrap;
width: 100%;
height: 100%;
background-color: transparent;
pointer-events: none;
}
.modal-content-container {
pointer-events: none;
width: 100%;
height: 100%;
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
}
.modal-content-container>.modal-content,
.modal-content-container>.modal-content-dimmer {
pointer-events: auto;
}
.modal-content-container>.modal-content-dimmer {
background: var(--custom-css-modal-background);
width: var(--custom-css-dim-size);
height: 100%;
margin-right: calc(100% - var(--custom-css-dim-size));
position: absolute;
}
.modal-header-button-container {
margin-top: calc(-1 * var(--modal-padding-vertical-half));
margin-bottom: calc(-1 * var(--modal-padding-vertical-half));
}
.modal-header-button-group {
display: block;
position: relative;
width: var(--icon-button-size);
height: var(--icon-button-size);
}
.modal-header-button {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
button.icon-button.modal-header-button {
--button-content-color: var(--button-default-icon-color-light);
--button-hover-content-color: var(--button-default-icon-color);
--button-active-content-color: var(--button-default-icon-color);
}
button.icon-button.modal-header-button>.icon-button-inner>.icon {
transition: background-color var(--animation-duration) ease-in-out;
}
.modal-header-button[data-modal-action=expand],
.modal-header-button[data-modal-action=collapse] {
visibility: visible;
opacity: 1;
z-index: 1;
transition:
opacity var(--animation-duration2) ease-in-out 0s,
visibility 0s ease-in-out 0s;
}
.modal-content.modal-content-full .modal-header-button[data-modal-action=expand],
.modal-content:not(.modal-content-full) .modal-header-button[data-modal-action=collapse] {
visibility: hidden;
opacity: 0;
pointer-events: none;
z-index: 0;
transition:
opacity var(--animation-duration2) ease-in-out 0s,
visibility 0s ease-in-out var(--animation-duration2);
}
.modal-separator-line {
border-top: var(--thin-border-size) solid var(--separator-color1);
margin: 0 calc(var(--modal-padding-horizontal) * -1);
}
.modal-separator-line-light {
border-top: var(--thin-border-size) solid var(--separator-color2);
margin: 0 calc(var(--modal-padding-horizontal) * -1);
}
/* Settings styles */
.settings-group {
margin: 0 var(--settings-group-horizontal-margin);
padding: 0;
box-sizing: border-box;
background-color: var(--background-color-light);
box-shadow: var(--shadow-vertical);
border-radius: var(--settings-group-border-radius);
overflow-x: hidden;
}
.settings-group.settings-group-top-margin {
margin-top: 1.0125em;
}
.settings-item {
position: relative;
}
.settings-item:not([hidden]) {
display: block;
}
.settings-item-outer {
display: block;
width: 100%;
}
.settings-item-inner {
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-content: stretch;
width: 100%;
}
.settings-item-inner.settings-item-inner-wrappable {
flex-wrap: var(--settings-group-wrap);
}
.settings-item-left {
padding: var(--settings-group-inner-vertical-padding) var(--settings-group-inner-horizontal-padding-half) var(--settings-group-inner-vertical-padding) var(--settings-group-inner-horizontal-padding);
flex: 1 1 auto;
align-self: center;
position: relative;
}
.settings-item-left:last-child {
padding-right: var(--settings-group-inner-horizontal-padding);
}
.settings-item-right {
padding: var(--settings-group-inner-vertical-padding) var(--settings-group-inner-horizontal-padding) var(--settings-group-inner-vertical-padding) var(--settings-group-inner-horizontal-padding-half);
flex: 0 1 auto;
align-self: stretch;
max-height: var(--settings-group-right-max-height);
display: flex;
flex-flow: row nowrap;
align-items: center;
align-content: center;
justify-content: flex-end;
}
.settings-item-inner.settings-item-inner-wrappable>.settings-item-left {
padding-right: var(--settings-group-inner-horizontal-padding-half-wrappable);
}
.settings-item-inner.settings-item-inner-wrappable>.settings-item-right {
padding-left: var(--settings-group-inner-horizontal-padding-half-wrappable);
}
.settings-item-center {
padding: var(--settings-group-inner-vertical-padding) var(--settings-group-inner-horizontal-padding) var(--settings-group-inner-vertical-padding) var(--settings-group-inner-horizontal-padding);
flex: 0 1 100%;
align-self: flex-start;
text-align: center;
}
.settings-item+.settings-item {
border-top: var(--thin-border-size) solid var(--separator-color2);
}
.settings-item-description {
color: var(--text-color-light2);
}
.settings-item-right.open-panel-button-container {
padding: 0.25em 1em 0.25em 0.75em;
max-height: calc(var(--settings-group-right-max-height) + var(--settings-group-inner-vertical-padding) * 2);
}
.settings-item-children {
padding: 0em var(--settings-group-inner-horizontal-padding-half) var(--settings-group-inner-vertical-padding) var(--settings-group-inner-horizontal-padding);
margin-top: 0;
}
.settings-item-children.settings-item-children-group {
padding: 0 0 0 calc(var(--settings-group-inner-horizontal-padding) + var(--settings-group-inner-horizontal-padding));
}
.settings-item-children.settings-item-children-group .settings-item {
border-top: var(--thin-border-size) solid var(--separator-color2);
}
.settings-item-children.settings-item-children-group .settings-item-left {
padding-left: 0;
}
.settings-item-children.settings-item-children-group .settings-item-inner.settings-item-inner-wrappable>.settings-item-left:not(:last-child) {
padding-right: calc(var(--settings-group-inner-horizontal-padding-half-wrappable) * 2);
}
.settings-item-children.settings-item-children-group .settings-item-inner.settings-item-inner-wrappable>.settings-item-right {
padding-left: 0;
}
.settings-item-children.settings-item-children-group .settings-item-children {
padding-left: 0;
}
.settings-item.settings-item-button,
a.settings-item.settings-item-button {
cursor: pointer;
color: var(--text-color);
text-decoration: none;
background-color: transparent;
transition: background-color var(--animation-duration) ease-in-out;
}
.settings-item.settings-item-button>.settings-item-inner,
.settings-item.settings-item-button>.settings-item-inner>.settings-item-left,
.settings-item.settings-item-button>.settings-item-inner>.settings-item-right {
margin-top: 0;
}
.settings-item.settings-item-button:hover,
.settings-item.settings-item-button:active {
background-color: var(--background-color);
}
.settings-item.settings-item-button .icon-button>.icon-button-inner>.icon {
transition: background-color var(--animation-duration) ease-in-out;
}
.settings-item.settings-item-button:hover .icon-button>.icon-button-inner>.icon,
.settings-item.settings-item-button:active .icon-button>.icon-button-inner>.icon {
background-color: var(--accent-color);
}
.settings-item-invalid-indicator {
display: none;
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 0.5em;
background-color: var(--danger-color);
}
.settings-item[data-invalid=true] .settings-item-invalid-indicator {
display: block;
}
/* Settings item groups */
.settings-item-group {
margin-right: var(--padding-negative);
display: flex;
flex-flow: row nowrap;
align-items: center;
align-content: center;
justify-content: flex-end;
}
.settings-item-group.settings-item-group-wrap {
flex-wrap: wrap;
}
.settings-item-group-item {
flex: 0 1 auto;
padding-right: var(--padding);
}
.settings-item-group-item-label {
font-size: var(--font-size-small);
line-height: 1;
}
input[type=text].short-width,
input[type=number].short-width,
select.short-width {
width: var(--input-short-width);
}
input[type=text].medium-width,
input[type=number].medium-width,
select.medium-width {
width: var(--input-medium-width);
}
input[type=text].short-height,
input[type=number].short-height,
select.short-height {
height: var(--input-short-height);
margin-top: calc(var(--settings-group-right-max-height) - var(--input-short-height) - var(--font-size-small));
line-height: var(--line-height);
}
.settings-item-button-group-container {
max-height: none;
width: 100%;
}
.settings-item-button-group {
display: flex;
width: 100%;
flex-flow: row wrap;
max-height: none;
justify-content: flex-start;
margin-top: var(--padding-negative);
margin-right: var(--padding-negative);
}
.settings-item-button-group-item {
flex: 0 1 auto;
padding-top: var(--padding);
padding-right: var(--padding);
}
.settings-item-progress-report {
display: none;
font-weight: bold;
color: #4169e1;
}
.settings-item-error-report {
display: none;
font-weight: bold;
color: #8b0000;
}

View File

@@ -1,245 +0,0 @@
/*
* Copyright (C) 2023-2025 Yomitan Authors
* Copyright (C) 2020-2022 Yomichan Authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/* Variables */
:root {
--search-scroll-container-horizontal-padding: 0.72em;
--query-horizontal-padding: 0;
--padding: calc(10em / var(--font-size-no-units));
--content-width-search: 700;
--content-width: calc(1em * var(--content-width-search) / var(--font-size-no-units));
--background-color: #ffffff;
--separator-color1: #cccccc;
--search-textbox-height: calc(var(--textarea-line-height) + var(--textarea-padding) * 2);
--search-textbox-min-height: calc(var(--textarea-line-height) + var(--textarea-padding) * 2);
--search-textbox-max-height: calc(var(--textarea-line-height) * 5 + var(--textarea-padding) * 2);
--cog-icon-size: 26px;
}
:root:not([data-loaded=true]) {
--animation-duration: 0s;
}
:root[data-theme=dark] {
--separator-color1: #333333;
}
/* Common styles */
:root {
height: 100%;
}
body {
background-color: var(--background-color);
margin: 0;
padding: 0;
color: var(--text-color);
height: 100%;
overflow: hidden;
}
.search-header {
padding-left: var(--search-scroll-container-horizontal-padding);
padding-right: var(--search-scroll-container-horizontal-padding);
}
h1 {
font-size: 2em;
line-height: 1.5em;
margin: 0;
padding: 0.25em 0 0;
font-weight: normal;
box-sizing: border-box;
border-bottom: calc(1em / (var(--font-size-no-units) * 2)) solid var(--separator-color1);
}
/* Search bar */
.search-textbox-container {
display: flex;
flex-flow: row nowrap;
width: 100%;
align-items: center;
margin: 0;
padding: 0;
border: 0;
}
#search-textbox {
color: var(--text-color);
flex: 1 1 auto;
box-sizing: border-box;
padding: var(--textarea-padding);
background-color: var(--input-background-color);
border-radius: 0;
line-height: var(--textarea-line-height);
border: 0;
outline: none;
width: 100%;
height: var(--search-textbox-height);
min-height: var(--search-textbox-min-height);
max-height: var(--search-textbox-max-height);
resize: none;
font-size: var(--font-size);
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
white-space: pre-wrap;
z-index: 1;
}
.search-button {
flex: 0 0 auto;
position: relative;
width: 2.5em;
height: var(--search-textbox-height);
min-height: var(--search-textbox-min-height);
max-height: var(--search-textbox-max-height);
background-color: var(--input-background-color);
border: 0;
padding: 0;
margin: 0;
cursor: pointer;
outline: none;
transition: background-color var(--animation-duration) ease-in-out;
border-radius: 0;
}
.search-button:hover,
.search-button:focus {
background-color: var(--input-background-color-dark);
}
.search-button:focus:not(:focus-visible):not(:hover) {
background-color: var(--input-background-color);
}
.search-button:focus-visible {
background-color: var(--input-background-color-dark);
}
.search-button:active,
.search-button:active:focus {
background-color: var(--input-background-color-darker);
}
.search-button>.icon {
display: block;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: var(--button-default-icon-color);
--icon-size: 16px 16px;
}
.clear-button {
flex: 0 0 auto;
position: relative;
width: 2.5em;
height: var(--search-textbox-height);
min-height: var(--search-textbox-min-height);
max-height: var(--search-textbox-max-height);
background-color: var(--input-background-color);
border: 0;
padding: 0;
margin: 0;
cursor: pointer;
outline: none;
transition: background-color var(--animation-duration) ease-in-out;
border-radius: 0;
}
.clear-button:hover,
.clear-button:focus {
background-color: var(--input-background-color-dark);
}
.clear-button:focus:not(:focus-visible):not(:hover) {
background-color: var(--input-background-color);
}
.clear-button:focus-visible {
background-color: var(--input-background-color-dark);
}
.clear-button:active,
.clear-button:active:focus {
background-color: var(--input-background-color-darker);
}
.clear-button>.icon {
display: block;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: var(--button-default-icon-color);
--icon-size: 16px 16px;
}
/* Search options */
#search-settings-button>.icon {
display: block;
background-color: var(--button-default-icon-color);
width: var(--cog-icon-size);
height: var(--cog-icon-size);
transition: var(--animation-duration) filter ease-in-out;
}
#search-settings-button>.icon:hover,
#search-settings-button>.icon:focus {
filter: invert(0.5);
}
#search-settings-button {
margin-right: 0;
float: right;
}
.search-options-right {
flex: 1;
}
.search-options {
display: flex;
flex-flow: row wrap;
margin: 0.5em 0 0 0;
align-items: center;
}
.search-option {
flex: 0 1 auto;
margin: 0.5em 2em 0.5em 0;
align-items: center;
cursor: pointer;
}
.search-option:not([hidden]) {
display: flex;
}
.search-option-label {
padding-left: 0.5em;
}
/* Search styles */
#intro {
overflow: hidden;
}
#intro>p {
margin: 0;
}
:root[data-search-mode=action-popup] #intro,
:root[data-search-mode=action-popup] #search-option-clipboard-monitor-container {
display: none;
}
:root[data-search-mode=action-popup],
:root[data-search-mode=action-popup] body {
width: 640px;
height: 480px;
}
/* Dark mode before themes are applied
DO NOT use this for normal theming */
@media (prefers-color-scheme: dark) {
:root:not([data-loaded=true]) {
background-color: #1e1e1e;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,259 +0,0 @@
/*
* Copyright (C) 2023-2025 Yomitan Authors
* Copyright (C) 2021-2022 Yomichan Authors
*
* This program is free software: you can redistribute it and/or modify
* it under the entrys of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/* Glossary images */
.gloss-image-container {
display: inline-block;
white-space: nowrap;
max-width: 100%;
max-height: 100vh;
position: relative;
vertical-align: top;
line-height: 0;
font-size: calc(1em / var(--font-size-no-units));
overflow: hidden;
}
.gloss-image-link[data-background=true]>.gloss-image-container {
background-color: var(--gloss-image-background-color);
}
.gloss-image-link {
cursor: inherit;
color: var(--accent-color);
display: inline-block;
position: relative;
line-height: 1;
max-width: 100%;
}
.gloss-image-link:hover {
color: var(--accent-color-dark);
cursor: pointer;
}
.gloss-image-container-overlay {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
font-size: calc(1em * var(--font-size-no-units));
line-height: var(--line-height);
display: table;
table-layout: fixed;
white-space: normal;
color: var(--text-color-light3);
}
.gloss-image-link[data-has-image=true][data-image-load-state=load-error] .gloss-image-container-overlay::after {
content: 'Image failed to load';
display: table-cell;
width: 100%;
height: 100%;
vertical-align: middle;
text-align: center;
padding: 0.25em;
}
.gloss-image-background {
--image: none;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: var(--text-color);
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center center;
-webkit-mask-mode: alpha;
-webkit-mask-size: contain;
-webkit-mask-image: var(--image);
mask-repeat: no-repeat;
mask-position: center center;
mask-mode: alpha;
mask-size: contain;
mask-image: var(--image);
display: none;
}
.gloss-image {
display: inline-block;
vertical-align: top;
object-fit: contain;
border: none;
outline: none;
}
.gloss-image-link[data-has-aspect-ratio=true] .gloss-image {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.gloss-image-link[data-image-rendering=pixelated] .gloss-image,
.gloss-image-link[data-image-rendering=pixelated] .gloss-image-background {
image-rendering: auto;
image-rendering: -moz-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: pixelated;
image-rendering: crisp-edges;
}
.gloss-image-link[data-image-rendering=crisp-edges] .gloss-image,
.gloss-image-link[data-image-rendering=crisp-edges] .gloss-image-background {
image-rendering: auto;
image-rendering: -moz-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
}
:root[data-browser=firefox] .gloss-image-link[data-image-rendering=crisp-edges] .gloss-image,
:root[data-browser=firefox] .gloss-image-link[data-image-rendering=crisp-edges] .gloss-image-background,
:root[data-browser=firefox-mobile] .gloss-image-link[data-image-rendering=crisp-edges] .gloss-image,
:root[data-browser=firefox-mobile] .gloss-image-link[data-image-rendering=crisp-edges] .gloss-image-background {
image-rendering: auto;
}
.gloss-image-link[data-has-aspect-ratio=true] .gloss-image-sizer {
display: inline-block;
width: 0;
vertical-align: top;
font-size: 0;
}
.gloss-image-link-text {
display: none;
line-height: var(--line-height);
}
.gloss-image-link-text::before {
content: '[';
}
.gloss-image-link-text::after {
content: ']';
}
.gloss-image-description {
display: block;
white-space: pre-line;
}
.gloss-image-link[data-appearance=monochrome] .gloss-image {
/* Workaround for coloring monochrome gloss images due to issues with masking using a canvas without loading extra media */
/* drop-shadow with 0.01px blur is at minimum required for Firefox to render the shadow when used on a canvas */
--shadow-settings: 0 0 0.01px var(--text-color);
filter: grayscale(1) opacity(0.5) drop-shadow(var(--shadow-settings)) drop-shadow(var(--shadow-settings)) saturate(1000%) brightness(1000%);
}
.gloss-image-link[data-size-units=em] .gloss-image-container {
font-size: 1em;
}
.gloss-image-link[data-vertical-align=baseline] { vertical-align: baseline; }
.gloss-image-link[data-vertical-align=sub] { vertical-align: sub; }
.gloss-image-link[data-vertical-align=super] { vertical-align: super; }
.gloss-image-link[data-vertical-align=text-top] { vertical-align: top; }
.gloss-image-link[data-vertical-align=text-bottom] { vertical-align: bottom; }
.gloss-image-link[data-vertical-align=middle] { vertical-align: middle; }
.gloss-image-link[data-vertical-align=top] { vertical-align: top; }
.gloss-image-link[data-vertical-align=bottom] { vertical-align: bottom; }
.gloss-image-link[data-collapsed=true],
:root[data-glossary-layout-mode^=compact] .gloss-image-link[data-collapsible=true] {
vertical-align: baseline;
}
.gloss-image-link[data-collapsed=true] .gloss-image-container,
:root[data-glossary-layout-mode^=compact] .gloss-image-link[data-collapsible=true] .gloss-image-container {
display: none;
position: absolute;
left: 0;
top: 100%;
z-index: 1;
}
.entry:nth-last-of-type(1):not(:nth-of-type(1)) .gloss-image-link[data-collapsed=true] .gloss-image-container,
:root[data-glossary-layout-mode^=compact] .entry:nth-last-of-type(1):not(:nth-of-type(1)) .gloss-image-link[data-collapsible=true] .gloss-image-container,
:root[data-glossary-layout-mode^=compact] .definition-item:nth-last-of-type(1) .gloss-image-link[data-collapsible=true] .gloss-image-container {
bottom: 100%;
top: auto;
}
.gloss-image-link[data-collapsed=true]:hover .gloss-image-container,
.gloss-image-link[data-collapsed=true]:focus .gloss-image-container,
:root[data-glossary-layout-mode^=compact] .gloss-image-link[data-collapsible=true]:hover .gloss-image-container,
:root[data-glossary-layout-mode^=compact] .gloss-image-link[data-collapsible=true]:focus .gloss-image-container {
display: block;
}
.gloss-image-link[data-collapsed=true] .gloss-image-link-text,
:root[data-glossary-layout-mode^=compact] .gloss-image-link[data-collapsible=true] .gloss-image-link-text {
display: inline;
}
.gloss-image-link[data-collapsed=true]~.gloss-image-description,
:root[data-glossary-layout-mode^=compact] .gloss-image-description {
display: inline;
}
/* Links */
.gloss-link-text {
vertical-align: baseline;
}
.gloss-link-external-icon {
display: inline-block;
vertical-align: middle;
width: calc(16em / var(--font-size-no-units));
height: calc(16em / var(--font-size-no-units));
margin-left: 0.25em;
background-color: var(--link-color);
position: relative;
}
/* Structured content glossary styles */
.gloss-sc-table-container {
display: block;
}
.gloss-sc-table {
table-layout: auto;
border-collapse: collapse;
}
.gloss-sc-thead,
.gloss-sc-tfoot,
.gloss-sc-th {
font-weight: bold;
background-color: var(--background-color-dark1);
}
.gloss-sc-th,
.gloss-sc-td {
border-width: calc(1em / var(--font-size-no-units));
border-style: solid;
border-color: var(--text-color-light2);
padding: 0.25em;
vertical-align: top;
}
.gloss-sc-ol,
.gloss-sc-ul {
padding-left: var(--list-padding2);
}
:root[data-glossary-layout-mode^=compact] .gloss-sc-ul[data-sc-content=glossary] {
display: inline;
list-style: none;
padding-left: 0;
}
:root[data-glossary-layout-mode^=compact] .gloss-sc-ul[data-sc-content=glossary] .gloss-sc-li {
display: inline;
}
:root[data-glossary-layout-mode^=compact] .gloss-sc-ul[data-sc-content=glossary] .gloss-sc-li:not(:first-child)::before {
white-space: pre-wrap;
content: var(--compact-list-separator);
display: inline;
color: var(--text-color-light3);
}
.gloss-sc-details {
padding-left: var(--list-padding1);
}
.gloss-sc-summary {
list-style-position: outside;
}

View File

@@ -1,21 +0,0 @@
:root:not([data-debug=true]) .debug-only {
display: none;
}
:root:not([data-advanced=true]) .advanced-only {
display: none;
}
:root:not([data-advanced=false]) .basic-only {
display: none;
}
:root:not([data-language=ja]):not([data-language=zh]):not([data-language=yue]) .jpzhyue-only {
display: none;
}
:root:not([data-language=ja]):not([data-language=zh]):not([data-language=yue]):not([data-language=ko]) .jpzhyueko-only {
display: none;
}
:root:is([data-language=ja], [data-language=zh], [data-language=yue], [data-language=ko]) .not-jpzhyueko {
display: none;
}
:root:not([data-language=ja]) .jp-only {
display: none;
}

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) 2023-2025 Yomitan Authors
* Copyright (C) 2019-2022 Yomichan Authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const ANKI_COMPACT_GLOSS_STYLES = `
ul[data-sc-content="glossary"] > li:not(:first-child)::before {
white-space: pre-wrap;
content: ' | ';
display: inline;
color: #777777;
}
ul[data-sc-content="glossary"] > li {
display: inline;
}
ul[data-sc-content="glossary"] {
display: inline;
list-style: none;
padding-left: 0;
}
`;
/**
* @returns {string}
*/
export function getAnkiCompactGlossStyles() {
return ANKI_COMPACT_GLOSS_STYLES.trim();
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,166 +0,0 @@
[
{
"selectors": [".pronunciation-downstep-notation"],
"styles": [
["display", "inline"]
]
},
{
"selectors": [".pronunciation-text"],
"styles": [
["display", "inline"]
]
},
{
"selectors": [".pronunciation-mora"],
"styles": [
["display", "inline-block"],
["position", "relative"]
]
},
{
"selectors": [".pronunciation-mora-line"],
"styles": [
["border-color", "currentColor"]
]
},
{
"selectors": [".pronunciation-mora[data-pitch=high]>.pronunciation-mora-line"],
"styles": [
["display", "block"],
["user-select", "none"],
["pointer-events", "none"],
["position", "absolute"],
["top", "0.1em"],
["left", "0"],
["right", "0"],
["height", "0"],
["border-top-width", "0.1em"],
["border-top-style", "solid"]
]
},
{
"selectors": [".pronunciation-mora[data-pitch=high][data-pitch-next=low]>.pronunciation-mora-line"],
"styles": [
["right", "-0.1em"],
["height", "0.4em"],
["border-right-width", "0.1em"],
["border-right-style", "solid"]
]
},
{
"selectors": [".pronunciation-mora[data-pitch=high][data-pitch-next=low]"],
"styles": [
["padding-right", "0.1em"],
["margin-right", "0.1em"]
]
},
{
"selectors": [".pronunciation-devoice-indicator"],
"styles": [
["display", "block"],
["position", "absolute"],
["left", "50%"],
["top", "50%"],
["width", "1.125em"],
["height", "1.125em"],
["border-radius", "50%"],
["box-sizing", "border-box"],
["z-index", "1"],
["transform", "translate(-50%, -50%)"],
["border", "1.5px dotted #c83c28"]
]
},
{
"selectors": [".pronunciation-nasal-indicator"],
"styles": [
["display", "block"],
["position", "absolute"],
["right", "-0.125em"],
["top", "0.125em"],
["width", "0.375em"],
["height", "0.375em"],
["border-radius", "50%"],
["box-sizing", "border-box"],
["z-index", "1"],
["border", "1.5px solid #c83c28"]
]
},
{
"selectors": [".pronunciation-nasal-diacritic"],
"styles": [
["position", "absolute"],
["width", "0"],
["height", "0"],
["opacity", "0"]
]
},
{
"selectors": [".pronunciation-character"],
"styles": [
["display", "inline"]
]
},
{
"selectors": [".pronunciation-character-group"],
"styles": [
["display", "inline-block"],
["position", "relative"]
]
},
{
"selectors": [".pronunciation-graph"],
"styles": [
["display", "inline-block"],
["vertical-align", "middle"],
["height", "1.5em"]
]
},
{
"selectors": [
".pronunciation-graph-line",
".pronunciation-graph-line-tail"
],
"styles": [
["fill", "none"],
["stroke-width", "5"],
["stroke", "currentColor"]
]
},
{
"selectors": [".pronunciation-graph-line-tail"],
"styles": [
["stroke-dasharray", "5 5"]
]
},
{
"selectors": [".pronunciation-graph-dot"],
"styles": [
["stroke-width", "5"],
["fill", "currentColor"],
["stroke", "currentColor"]
]
},
{
"selectors": [".pronunciation-graph-dot-downstep1"],
"styles": [
["fill", "none"],
["stroke-width", "5"],
["stroke", "currentColor"]
]
},
{
"selectors": [".pronunciation-graph-dot-downstep2"],
"styles": [
["fill", "currentColor"]
]
},
{
"selectors": [".pronunciation-graph-triangle"],
"styles": [
["fill", "none"],
["stroke-width", "5"],
["stroke", "currentColor"]
]
}
]

View File

@@ -1,901 +0,0 @@
{
"afb": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-afb-en",
"description": "Gulf Arabic to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-afb-en.zip"
}
]
},
"aii": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [
{
"name": "kty-aii-en-ipa",
"description": "Assyrian Neo-Aramaic IPA dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-aii-en-ipa.zip"
}
],
"terms": [
{
"name": "kty-aii-en",
"description": "Assyrian Neo-Aramaic to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-aii-en.zip"
}
]
},
"ang": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-ang-en",
"description": "Old English to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-ang-en.zip"
}
]
},
"ar": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [
{
"name": "kty-ar-en-ipa",
"description": "Arabic IPA dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-ar-en-ipa.zip"
}
],
"terms": [
{
"name": "kty-ar-en",
"description": "Arabic to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-ar-en.zip"
}
]
},
"arz": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [
{
"name": "kty-ar-en-ipa",
"description": "Arabic IPA dictionary created from Wiktionary data.",
"homepage": "https://github.com/yomidevs/kaikki-to-yomitan/blob/master/downloads.md",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-ar-en-ipa.zip"
}
],
"terms": [
{
"name": "kty-ar-en",
"description": "Arabic to English dictionary created from Wiktionary data.",
"homepage": "https://github.com/yomidevs/kaikki-to-yomitan/blob/master/downloads.md",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-ar-en.zip"
}
]
},
"cs": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-cs-en",
"description": "Czech to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-cs-en.zip"
}
]
},
"de": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-de-en",
"description": "German to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-de-en.zip"
}
]
},
"el": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-el-en",
"description": "Greek to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-el-en.zip"
}
]
},
"en": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-en-en",
"description": "English to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-en-en.zip"
}
]
},
"enm": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-enm-en",
"description": "Middle English to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-enm-en.zip"
}
]
},
"eo": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-eo-en",
"description": "Esperanto to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-eo-en.zip"
}
]
},
"es": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-es-en",
"description": "Spanish to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-es-en.zip"
}
]
},
"fa": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-fa-en",
"description": "Persian to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-fa-en.zip"
}
]
},
"fi": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-fi-en",
"description": "Finnish to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-fi-en.zip"
}
]
},
"fr": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-fr-en",
"description": "French to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-fr-en.zip"
}
]
},
"grc": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-grc-en",
"description": "Ancient Greek to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-grc-en.zip"
}
]
},
"haw": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "pukui-elbert-1986",
"description": "English to Hawaiian Dictionary from Pukui-Elbert in 1986",
"homepage": "https://github.com/bee-san/awesome-hawaiian-language",
"downloadUrl": "https://github.com/bee-san/awesome-hawaiian-language/releases/download/0.0.1/Pukui-Elbert-1986-Deduped-Yomitan.zip"
},
{
"name": "combined-dictionary",
"description": "English to Hawaiian Dictionary from Stephen (Kepano) Trussel",
"homepage": "https://github.com/bee-san/awesome-hawaiian-language",
"downloadUrl": "https://github.com/bee-san/awesome-hawaiian-language/releases/download/0.0.1/Combined-Hawaiian-Dictionary-2020-Mitch-Cleaned.zip"
},
{
"name": "hawaiian-place-names-2002",
"description": "Hawaiian Place Names, published 2002",
"homepage": "https://github.com/bee-san/awesome-hawaiian-language",
"downloadUrl": "https://github.com/bee-san/awesome-hawaiian-language/releases/download/0.0.1/Hawaii-place-names-2002-yomitan.zip"
}
]
},
"he": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-he-en",
"description": "Hebrew to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-he-en.zip"
}
]
},
"hi": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-hi-en",
"description": "Hindi to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-hi-en.zip"
}
]
},
"hu": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-hu-en",
"description": "Hungarian to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-hu-en.zip"
}
]
},
"id": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-id-en",
"description": "Indonesian to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-id-en.zip"
}
]
},
"it": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-it-en",
"description": "Italian to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-it-en.zip"
}
]
},
"ja": {
"frequency": [
{
"name": "BCCWJ",
"description": "Based on the Balanced Corpus of Contemporary Written Japanese covering books, magazines, newspapers, blogs, forums, textbooks, and legal documents among others.",
"homepage": "https://github.com/Kuuuube/yomitan-dictionaries?tab=readme-ov-file#bccwj-suw-luw-combined",
"downloadUrl": "https://github.com/Kuuuube/yomitan-dictionaries/releases/download/yomitan-permalink/BCCWJ_SUW_LUW_combined.zip"
},
{
"name": "JPDB",
"description": "A frequency dictionary based on the corpus from the online Japanese dictionary and SRS system at https://jpdb.io.",
"homepage": "https://github.com/Kuuuube/yomitan-dictionaries?tab=readme-ov-file#jpdb-v22-frequency",
"downloadUrl": "https://github.com/Kuuuube/yomitan-dictionaries/releases/download/yomitan-permalink/JPDB_v2.2_Frequency_Kana.zip"
},
{
"name": "Jiten",
"description": "A frequency dictionary based on the corpus from the media stats database at https://jiten.moe",
"homepage": "https://jiten.moe/other",
"downloadUrl": "https://api.jiten.moe/api/frequency-list/download?downloadType=yomitan"
}
],
"grammar": [],
"kanji": [
{
"name": "KANJIDIC",
"description": "An English dictionary with readings, meanings, stroke order diagrams, frequency, grade level, JLPT level and frequency of kanji characters.",
"homepage": "https://github.com/yomidevs/jmdict-yomitan?tab=readme-ov-file#kanjidic-for-yomitan",
"downloadUrl": "https://github.com/yomidevs/jmdict-yomitan/releases/latest/download/KANJIDIC_english.zip"
}
],
"pronunciation": [],
"terms": [
{
"name": "Jitendex",
"description": "A free and openly licensed Japanese-to-English dictionary with example sentences, usage notes, etymology notes, cross references, antonyms, definition notes.",
"homepage": "https://jitendex.org",
"downloadUrl": "https://github.com/stephenmk/stephenmk.github.io/releases/latest/download/jitendex-yomitan.zip"
},
{
"name": "JMnedict",
"description": "A dictionary of Japanese proper names maintained by the Electronic Dictionary Research and Development Group.",
"homepage": "https://github.com/yomidevs/jmdict-yomitan?tab=readme-ov-file#jmnedict-for-yomitan",
"downloadUrl": "https://github.com/yomidevs/jmdict-yomitan/releases/latest/download/JMnedict.zip"
}
]
},
"km": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-km-en",
"description": "Khmer to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-km-en.zip"
}
]
},
"kn": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-kn-en",
"description": "Kannada to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-kn-en.zip"
}
]
},
"ko": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-ko-en",
"description": "Korean to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-ko-en.zip"
}
]
},
"la": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-la-en",
"description": "Latin to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-la-en.zip"
}
]
},
"lv": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-lv-en",
"description": "Latvian to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-lv-en.zip"
}
]
},
"mn": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-mn-en",
"description": "Mongolian to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-mn-en.zip"
}
]
},
"mt": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [
{
"name": "kty-mt-en-ipa",
"description": "Maltese IPA dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-mt-en-ipa.zip"
}
],
"terms": [
{
"name": "kty-mt-en",
"description": "Maltese to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-mt-en.zip"
}
]
},
"nl": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-nl-en",
"description": "Dutch to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-nl-en.zip"
}
]
},
"no": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-nb-en",
"description": "Norwegian Bokmål to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-nb-en.zip"
},
{
"name": "kty-nn-en",
"description": "Norwegian Nynorsk to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-nn-en.zip"
}
]
},
"pl": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-pl-en",
"description": "Polish to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-pl-en.zip"
}
]
},
"pt": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-pt-en",
"description": "Portuguese to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-pt-en.zip"
}
]
},
"ro": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-ro-en",
"description": "Romanian to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-ro-en.zip"
}
]
},
"ru": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-ru-en",
"description": "Russian to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-ru-en.zip"
},
{
"name": "opr-ru-en",
"description": "OpenRussian is a user-contributed, libre Russian dictionary including the accents, examples, audio, related words and synonyms.",
"homepage": "https://github.com/ImenaOphelia/openrussian-to-yomitan",
"downloadUrl": "https://github.com/ImenaOphelia/openrussian-to-yomitan/releases/latest/download/opr-ru-en.zip"
}
]
},
"scn": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-scn-en",
"description": "Sicillian to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-scn-en.zip"
}
]
},
"sga": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-sga-en",
"description": "Old Irish to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-sga-en.zip"
}
]
},
"sh": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-sh-en",
"description": "Serbo-Croatian to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-sh-en.zip"
}
]
},
"sq": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-sq-en",
"description": "Albanian to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-sq-en.zip"
}
]
},
"sv": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-sv-en",
"description": "Swedish to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-sv-en.zip"
}
]
},
"th": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-th-en",
"description": "Thai to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-th-en.zip"
}
]
},
"tl": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-tl-en",
"description": "Tagalog to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-tl-en.zip"
}
]
},
"tok": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "toki-pona-to-chinese",
"description": "Toki Pona to Chinese dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-chinese.zip"
},
{
"name": "toki-pona-to-czech",
"description": "Toki Pona to Czech dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-czech.zip"
},
{
"name": "toki-pona-to-dutch",
"description": "Toki Pona to Dutch dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-dutch.zip"
},
{
"name": "toki-pona-to-english",
"description": "Toki Pona to English dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-english.zip"
},
{
"name": "toki-pona-to-esperanto",
"description": "Toki Pona to Esperanto dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-esperanto.zip"
},
{
"name": "toki-pona-to-french",
"description": "Toki Pona to French dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-french.zip"
},
{
"name": "toki-pona-to-german",
"description": "Toki Pona to German dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-german.zip"
},
{
"name": "toki-pona-to-indonesian",
"description": "Toki Pona to Indonesian dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-indonesian.zip"
},
{
"name": "toki-pona-to-italian",
"description": "Toki Pona to Italian dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-italian.zip"
},
{
"name": "toki-pona-to-polish",
"description": "Toki Pona to Polish dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-polish.zip"
},
{
"name": "toki-pona-to-portuguese",
"description": "Toki Pona to Portuguese dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-portuguese.zip"
},
{
"name": "toki-pona-to-russian",
"description": "Toki Pona to Russian dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-russian.zip"
},
{
"name": "toki-pona-to-slovak",
"description": "Toki Pona to Slovak dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-slovak.zip"
},
{
"name": "toki-pona-to-spanish",
"description": "Toki Pona to Spanish dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-spanish.zip"
},
{
"name": "toki-pona-to-turkish",
"description": "Toki Pona to Turkish dictionary",
"homepage": "https://github.com/bee-san/awesome-toki-pona",
"downloadUrl": "https://github.com/bee-san/awesome-toki-pona/releases/download/0.0.3/toki-pona-to-turkish.zip"
}
]
},
"tr": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-tr-en",
"description": "Turkish to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-tr-en.zip"
}
]
},
"uk": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-uk-en",
"description": "Ukranian to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-uk-en.zip"
}
]
},
"vi": {
"frequency": [],
"grammar": [],
"kanji": [],
"pronunciation": [],
"terms": [
{
"name": "kty-vi-en",
"description": "Vietnamese to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-vi-en.zip"
}
]
},
"yue": {
"frequency": [
{
"name": "Words.hk Frequency",
"description": "Frequency list of Cantonese terms and honzi provided by words.hk.",
"homepage": "https://github.com/MarvNC/wordshk-yomitan",
"downloadUrl": "https://github.com/MarvNC/wordshk-yomitan/releases/download/2024-09-17/YUE.Freq.Words.hk.Frequency.zip"
}
],
"grammar": [],
"kanji": [
{
"name": "Words.hk 粵典 漢字",
"description": "A free and open Cantonese dictionary with definitions and example sentences in Cantonese and English.",
"homepage": "https://github.com/MarvNC/wordshk-yomitan",
"downloadUrl": "https://github.com/MarvNC/wordshk-yomitan/releases/download/2025-07-09/Words.hk.Honzi.2025-07-08.zip"
}
],
"pronunciation": [],
"terms": [
{
"name": "Words.hk 粵典",
"description": "A free and open Cantonese dictionary with definitions and example sentences in Cantonese and English.",
"homepage": "https://github.com/MarvNC/wordshk-yomitan",
"downloadUrl": "https://github.com/MarvNC/wordshk-yomitan/releases/download/2025-07-09/Words.hk.2025-07-08.zip"
},
{
"name": "CC-Canto",
"description": "CC-Canto is an open source Cantonese dictionary project created by Pleco, intended to be used alongside the CC-CEDICT dictionary. It provides Cantonese specific words and definitions.",
"homepage": "https://github.com/MarvNC/cc-cedict-yomitan",
"downloadUrl": "https://github.com/MarvNC/cc-cedict-yomitan/releases/latest/download/CC-Canto.zip"
},
{
"name": "CC-CEDICT Canto",
"description": "CC-CEDICT is a continuation of the CEDICT project with the aim to provide a complete downloadable Chinese to English dictionary with pronunciation in pinyin for the Chinese characters. This version includes Cantonese readings provided by Pleco.",
"homepage": "https://github.com/MarvNC/cc-cedict-yomitan",
"downloadUrl": "https://github.com/MarvNC/cc-cedict-yomitan/releases/latest/download/CC-CEDICT.Canto.zip"
},
{
"name": "Cantodict",
"description": "CantoDict was a Cantonese-English dictionary created and maintained by Adam Sheik and public contributors.",
"homepage": "https://github.com/MarvNC/yomitan-dictionaries?tab=readme-ov-file#cantodict",
"downloadUrl": "https://github.com/MarvNC/yomichan-dictionaries/raw/master/dl/%5BCantonese%5D%20Cantodict.zip"
}
]
},
"zh": {
"frequency": [],
"grammar": [],
"kanji": [
{
"name": "CC-CEDICT",
"description": "A free and open Chinese-English dictionary provided by the CC-CEDICT project.",
"homepage": "https://github.com/MarvNC/cc-cedict-yomitan",
"downloadUrl": "https://github.com/MarvNC/cc-cedict-yomitan/releases/latest/download/CC-CEDICT.Hanzi.zip"
}
],
"pronunciation": [],
"terms": [
{
"name": "CC-CEDICT",
"description": "A free and open Chinese-English dictionary provided by the CC-CEDICT project.",
"homepage": "https://github.com/MarvNC/cc-cedict-yomitan",
"downloadUrl": "https://github.com/MarvNC/cc-cedict-yomitan/releases/latest/download/CC-CEDICT.zip"
},
{
"name": "kty-zh-en",
"description": "Chinese to English dictionary created from Wiktionary data.",
"homepage": "https://yomidevs.github.io/kaikki-to-yomitan/",
"downloadUrl": "https://pub-c3d38cca4dc2403b88934c56748f5144.r2.dev/releases/latest/kty-zh-en.zip"
}
]
}
}

View File

@@ -1,862 +0,0 @@
{
"ar": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
}
],
"arz": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
}
],
"cs": [
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"da": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"de": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"el": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
},
{
"modification": {
"action": "set",
"path": "scanning.length",
"value": 24
},
"description": "Increase the default scanning length from 16 to 24 characters."
}
],
"en": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
},
{
"modification": {
"action": "set",
"path": "sentenceParsing.terminationCharacters",
"value": [
{
"enabled": true,
"character1": "\"",
"character2": "\"",
"includeCharacterAtStart": false,
"includeCharacterAtEnd": false
},
{
"enabled": false,
"character1": "'",
"character2": "'",
"includeCharacterAtStart": false,
"includeCharacterAtEnd": false
},
{
"enabled": true,
"character1": ".",
"character2": null,
"includeCharacterAtStart": false,
"includeCharacterAtEnd": true
},
{
"enabled": true,
"character1": "!",
"character2": null,
"includeCharacterAtStart": false,
"includeCharacterAtEnd": true
},
{
"enabled": true,
"character1": "?",
"character2": null,
"includeCharacterAtStart": false,
"includeCharacterAtEnd": true
},
{
"enabled": true,
"character1": "…",
"character2": null,
"includeCharacterAtStart": false,
"includeCharacterAtEnd": true
}
]
},
"description": "Disable apostrophes as a sentence terminator."
}
],
"eo": [
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"es": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"fi": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"fr": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "translation.textReplacements.groups",
"value": [
[
{
"pattern": "l('|)",
"ignoreCase": true,
"replacement": ""
},
{
"pattern": "j('|)",
"ignoreCase": true,
"replacement": ""
},
{
"pattern": "d('|)",
"ignoreCase": true,
"replacement": ""
},
{
"pattern": "s('|)",
"ignoreCase": true,
"replacement": ""
}
]
]
},
"description": "Separating the l', j', d', s' from the word."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"he": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"hi": [
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"hu": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"id": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"it": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"ja": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "character"
},
"description": "Scan text one character at a time."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "letter"
},
"description": "Lookup words by letter in the dictionary."
}
],
"ko": [
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"kn": [
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"la": [
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"lv": [
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"mn": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"nl": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"no": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"pl": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"pt": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"ro": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"ru": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"sga": [
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"sh": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"sq": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"sv": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"tr": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
},
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"uk": [
{
"modification": {
"action": "set",
"path": "parsing.enableScanningParser",
"value": false
},
"description": "Turn off Yomitan's internal parser for languages with spaces."
}
],
"vi": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "word"
},
"description": "Scan text one word at a time (as opposed to one character)."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "word"
},
"description": "Lookup whole words in the dictionary."
}
],
"yue": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "character"
},
"description": "Scan text one character at a time."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "letter"
},
"description": "Lookup words by letter in the dictionary."
}
],
"zh": [
{
"modification": {
"action": "set",
"path": "scanning.scanResolution",
"value": "character"
},
"description": "Scan text one character at a time."
},
{
"modification": {
"action": "set",
"path": "translation.searchResolution",
"value": "letter"
},
"description": "Lookup words by letter in the dictionary."
}
]
}

View File

@@ -1,34 +0,0 @@
{
"$id": "customAudioList",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"type",
"audioSources"
],
"additionalProperties": false,
"properties": {
"type": {
"type": "string",
"const": "audioSourceList"
},
"audioSources": {
"type": "array",
"items": {
"type": "object",
"required": [
"url"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"url": {
"type": "string"
}
}
}
}
}
}

View File

@@ -1,125 +0,0 @@
{
"$id": "dictionaryIndex",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"isoLanguageCode": {
"type": "string",
"description": "ISO language code (ISO 639-1 where possible, ISO 639-3 otherwise).",
"pattern": "^[a-z]{2,3}$"
}
},
"type": "object",
"description": "Index file containing information about the data contained in the dictionary.",
"required": [
"title",
"revision"
],
"properties": {
"title": {
"type": "string",
"description": "Title of the dictionary."
},
"revision": {
"type": "string",
"description": "Revision of the dictionary. This value is displayed, and used to check for dictionary updates."
},
"minimumYomitanVersion": {
"type": "string",
"description": "Minimum version of Yomitan that is compatible with this dictionary."
},
"sequenced": {
"type": "boolean",
"default": false,
"description": "Whether or not this dictionary contains sequencing information for related terms."
},
"format": {
"type": "integer",
"description": "Format of data found in the JSON data files.",
"enum": [1, 2, 3]
},
"version": {
"type": "integer",
"description": "Alias for format.",
"enum": [1, 2, 3]
},
"author": {
"type": "string",
"description": "Creator of the dictionary."
},
"isUpdatable": {
"type": "boolean",
"const": true,
"description": "Whether this dictionary contains links to its latest version."
},
"indexUrl": {
"type": "string",
"description": "URL for the index file of the latest revision of the dictionary, used to check for updates."
},
"downloadUrl": {
"type": "string",
"description": "URL for the download of the latest revision of the dictionary."
},
"url": {
"type": "string",
"description": "URL for the source of the dictionary, displayed in the dictionary details."
},
"description": {
"type": "string",
"description": "Description of the dictionary data."
},
"attribution": {
"type": "string",
"description": "Attribution information for the dictionary data."
},
"sourceLanguage": {
"$ref": "#/definitions/isoLanguageCode",
"description": "Language of the terms in the dictionary."
},
"targetLanguage": {
"$ref": "#/definitions/isoLanguageCode",
"description": "Main language of the definitions in the dictionary."
},
"frequencyMode": {
"type": "string",
"enum": ["occurrence-based", "rank-based"]
},
"tagMeta": {
"type": "object",
"description": "Tag information for terms and kanji. This object is obsolete and individual tag files should be used instead.",
"additionalProperties": {
"type": "object",
"description": "Information about a single tag. The object key is the name of the tag.",
"properties": {
"category": {
"type": "string",
"description": "Category for the tag."
},
"order": {
"type": "number",
"description": "Sorting order for the tag."
},
"notes": {
"type": "string",
"description": "Notes for the tag."
},
"score": {
"type": "number",
"description": "Score used to determine popularity. Negative values are more rare and positive values are more frequent. This score is also used to sort search results."
}
},
"additionalProperties": false
}
}
},
"anyOf": [
{
"required": ["format"]
},
{
"required": ["version"]
}
],
"dependencies": {
"isUpdatable": ["indexUrl", "downloadUrl"]
}
}

View File

@@ -1,35 +0,0 @@
{
"$id": "dictionaryKanjiBankV1",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"description": "Data file containing kanji information.",
"items": {
"type": "array",
"description": "Information about a single kanji character.",
"minItems": 4,
"maxItems": 4,
"items": [
{
"type": "string",
"description": "Kanji character.",
"minLength": 1
},
{
"type": "string",
"description": "String of space-separated onyomi readings for the kanji character. An empty string is treated as no readings."
},
{
"type": "string",
"description": "String of space-separated kunyomi readings for the kanji character. An empty string is treated as no readings."
},
{
"type": "string",
"description": "String of space-separated tags for the kanji character. An empty string is treated as no tags."
}
],
"additionalItems": {
"type": "string",
"description": "A meaning for the kanji character."
}
}
}

View File

@@ -1,47 +0,0 @@
{
"$id": "dictionaryKanjiBankV3",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"description": "Data file containing kanji information.",
"items": {
"type": "array",
"description": "Information about a single kanji character.",
"minItems": 6,
"maxItems": 6,
"additionalItems": false,
"items": [
{
"type": "string",
"description": "Kanji character.",
"minLength": 1
},
{
"type": "string",
"description": "String of space-separated onyomi readings for the kanji character. An empty string is treated as no readings."
},
{
"type": "string",
"description": "String of space-separated kunyomi readings for the kanji character. An empty string is treated as no readings."
},
{
"type": "string",
"description": "String of space-separated tags for the kanji character. An empty string is treated as no tags."
},
{
"type": "array",
"description": "Array of meanings for the kanji character.",
"items": {
"type": "string",
"description": "A meaning for the kanji character."
}
},
{
"type": "object",
"description": "Various stats for the kanji character.",
"additionalProperties": {
"type": "string"
}
}
]
}
}

View File

@@ -1,52 +0,0 @@
{
"$id": "dictionaryKanjiMetaBankV3",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"frequency": {
"oneOf": [
{
"type": ["string", "number"]
},
{
"type": "object",
"additionalProperties": false,
"required": [
"value"
],
"properties": {
"value": {
"type": "number"
},
"displayValue": {
"type": "string"
}
}
}
]
}
},
"type": "array",
"description": "Custom metadata for kanji characters.",
"items": {
"type": "array",
"description": "Metadata about a single kanji character.",
"minItems": 3,
"maxItems": 3,
"additionalItems": false,
"items": [
{
"type": "string",
"minLength": 1
},
{
"type": "string",
"const": "freq",
"description": "Type of data. \"freq\" corresponds to frequency information."
},
{
"$ref": "#/definitions/frequency",
"description": "Data for the character."
}
]
}
}

View File

@@ -1,35 +0,0 @@
{
"$id": "dictionaryTagBankV3",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"description": "Data file containing tag information for terms and kanji.",
"items": {
"type": "array",
"description": "Information about a single tag.",
"minItems": 5,
"maxItems": 5,
"additionalItems": false,
"items": [
{
"type": "string",
"description": "Tag name."
},
{
"type": "string",
"description": "Category for the tag."
},
{
"type": "number",
"description": "Sorting order for the tag."
},
{
"type": "string",
"description": "Notes for the tag."
},
{
"type": "number",
"description": "Score used to determine popularity. Negative values are more rare and positive values are more frequent. This score is also used to sort search results."
}
]
}
}

View File

@@ -1,38 +0,0 @@
{
"$id": "dictionaryTermBankV1",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"description": "Data file containing term information.",
"items": {
"type": "array",
"description": "Information about a single term.",
"minItems": 5,
"maxItems": 5,
"items": [
{
"type": "string",
"description": "The text for the term."
},
{
"type": "string",
"description": "Reading of the term, or an empty string if the reading is the same as the term."
},
{
"type": ["string", "null"],
"description": "String of space-separated tags for the definition. An empty string is treated as no tags."
},
{
"type": "string",
"description": "String of space-separated rule identifiers for the definition which is used to validate delinflection. Valid rule identifiers are: v1: ichidan verb; v5: godan verb; vs: suru verb; vz: zuru verb; vk: kuru verb; adj-i: i-adjective. An empty string corresponds to words which aren't inflected, such as nouns."
},
{
"type": "number",
"description": "Score used to determine popularity. Negative values are more rare and positive values are more frequent. This score is also used to sort search results."
}
],
"additionalItems": {
"type": "string",
"description": "Single definition for the term."
}
}
}

View File

@@ -1,593 +0,0 @@
{
"$id": "dictionaryTermBankV3",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"structuredContent": {
"oneOf": [
{
"type": "string",
"description": "Represents a text node."
},
{
"type": "array",
"items": {
"$ref": "#/definitions/structuredContent",
"description": "An array of child content."
}
},
{
"type": "object",
"oneOf": [
{
"type": "object",
"description": "Empty tags.",
"required": [
"tag"
],
"additionalProperties": false,
"properties": {
"tag": {
"type": "string",
"const": "br"
},
"data": {
"$ref": "#/definitions/structuredContentData"
}
}
},
{
"type": "object",
"description": "Generic container tags.",
"required": [
"tag"
],
"additionalProperties": false,
"properties": {
"tag": {
"type": "string",
"enum": ["ruby", "rt", "rp", "table", "thead", "tbody", "tfoot", "tr"]
},
"content": {
"$ref": "#/definitions/structuredContent"
},
"data": {
"$ref": "#/definitions/structuredContentData"
},
"lang": {
"type": "string",
"description": "Defines the language of an element in the format defined by RFC 5646."
}
}
},
{
"type": "object",
"description": "Table tags.",
"required": [
"tag"
],
"additionalProperties": false,
"properties": {
"tag": {
"type": "string",
"enum": ["td", "th"]
},
"content": {
"$ref": "#/definitions/structuredContent"
},
"data": {
"$ref": "#/definitions/structuredContentData"
},
"colSpan": {
"type": "integer",
"minimum": 1
},
"rowSpan": {
"type": "integer",
"minimum": 1
},
"style": {
"$ref": "#/definitions/structuredContentStyle"
},
"lang": {
"type": "string",
"description": "Defines the language of an element in the format defined by RFC 5646."
}
}
},
{
"type": "object",
"description": "Container tags supporting configurable styles.",
"required": [
"tag"
],
"additionalProperties": false,
"properties": {
"tag": {
"type": "string",
"enum": ["span", "div", "ol", "ul", "li", "details", "summary"]
},
"content": {
"$ref": "#/definitions/structuredContent"
},
"data": {
"$ref": "#/definitions/structuredContentData"
},
"style": {
"$ref": "#/definitions/structuredContentStyle"
},
"title": {
"type": "string",
"description": "Hover text for the element."
},
"open": {
"type": "boolean",
"description": "Whether or not the details element is open by default."
},
"lang": {
"type": "string",
"description": "Defines the language of an element in the format defined by RFC 5646."
}
}
},
{
"type": "object",
"description": "Image tag.",
"required": [
"tag",
"path"
],
"additionalProperties": false,
"properties": {
"tag": {
"type": "string",
"const": "img"
},
"data": {
"$ref": "#/definitions/structuredContentData"
},
"path": {
"type": "string",
"description": "Path to the image file in the archive."
},
"width": {
"type": "number",
"description": "Preferred width of the image.",
"minimum": 0
},
"height": {
"type": "number",
"description": "Preferred height of the image.",
"minimum": 0
},
"title": {
"type": "string",
"description": "Hover text for the image."
},
"alt": {
"type": "string",
"description": "Alt text for the image."
},
"description": {
"type": "string",
"description": "Description of the image."
},
"pixelated": {
"type": "boolean",
"description": "Whether or not the image should appear pixelated at sizes larger than the image's native resolution.",
"default": false
},
"imageRendering": {
"type": "string",
"description": "Controls how the image is rendered. The value of this field supersedes the pixelated field.",
"enum": ["auto", "pixelated", "crisp-edges"],
"default": "auto"
},
"appearance": {
"type": "string",
"description": "Controls the appearance of the image. The \"monochrome\" value will mask the opaque parts of the image using the current text color.",
"enum": ["auto", "monochrome"],
"default": "auto"
},
"background": {
"type": "boolean",
"description": "Whether or not a background color is displayed behind the image.",
"default": true
},
"collapsed": {
"type": "boolean",
"description": "Whether or not the image is collapsed by default.",
"default": false
},
"collapsible": {
"type": "boolean",
"description": "Whether or not the image can be collapsed.",
"default": false
},
"verticalAlign": {
"type": "string",
"description": "The vertical alignment of the image.",
"enum": ["baseline", "sub", "super", "text-top", "text-bottom", "middle", "top", "bottom"]
},
"border": {
"type": "string",
"description": "Shorthand for border width, style, and color."
},
"borderRadius": {
"type": "string",
"description": "Roundness of the corners of the image's outer border edge."
},
"sizeUnits": {
"type": "string",
"description": "The units for the width and height.",
"enum": ["px", "em"]
}
}
},
{
"type": "object",
"description": "Link tag.",
"required": [
"tag",
"href"
],
"additionalProperties": false,
"properties": {
"tag": {
"type": "string",
"const": "a"
},
"content": {
"$ref": "#/definitions/structuredContent"
},
"href": {
"type": "string",
"description": "The URL for the link. URLs starting with a ? are treated as internal links to other dictionary content.",
"pattern": "^(?:https?:|\\?)[\\w\\W]*"
},
"lang": {
"type": "string",
"description": "Defines the language of an element in the format defined by RFC 5646."
}
}
}
]
}
]
},
"structuredContentData": {
"type": "object",
"description": "Generic data attributes that should be added to the element.",
"additionalProperties": {
"type": "string"
}
},
"structuredContentStyle": {
"type": "object",
"additionalProperties": false,
"properties": {
"fontStyle": {
"type": "string",
"enum": ["normal", "italic"],
"default": "normal"
},
"fontWeight": {
"type": "string",
"enum": ["normal", "bold"],
"default": "normal"
},
"fontSize": {
"type": "string",
"default": "medium"
},
"color": {
"type": "string"
},
"background": {
"type": "string"
},
"backgroundColor": {
"type": "string"
},
"textDecorationLine": {
"oneOf": [
{
"type": "string",
"enum": ["none", "underline", "overline", "line-through"],
"default": "none"
},
{
"type": "array",
"items": {
"type": "string",
"enum": ["underline", "overline", "line-through"],
"default": "none"
}
}
]
},
"textDecorationStyle": {
"type": "string",
"enum": ["solid", "double", "dotted", "dashed", "wavy"],
"default": "solid"
},
"textDecorationColor": {
"type": "string"
},
"borderColor": {
"type": "string"
},
"borderStyle": {
"type": "string"
},
"borderRadius": {
"type": "string"
},
"borderWidth": {
"type": "string"
},
"clipPath": {
"type": "string"
},
"verticalAlign": {
"type": "string",
"enum": ["baseline", "sub", "super", "text-top", "text-bottom", "middle", "top", "bottom"],
"default": "baseline"
},
"textAlign": {
"type": "string",
"enum": ["start", "end", "left", "right", "center", "justify", "justify-all", "match-parent"],
"default": "start"
},
"textEmphasis": {
"type": "string"
},
"textShadow": {
"type": "string"
},
"margin": {
"type": "string"
},
"marginTop": {
"type": ["number", "string"],
"default": 0
},
"marginLeft": {
"type": ["number", "string"],
"default": 0
},
"marginRight": {
"type": ["number", "string"],
"default": 0
},
"marginBottom": {
"type": ["number", "string"],
"default": 0
},
"padding": {
"type": "string"
},
"paddingTop": {
"type": "string"
},
"paddingLeft": {
"type": "string"
},
"paddingRight": {
"type": "string"
},
"paddingBottom": {
"type": "string"
},
"wordBreak": {
"type": "string",
"enum": ["normal", "break-all", "keep-all"],
"default": "normal"
},
"whiteSpace": {
"type": "string",
"default": "normal"
},
"cursor": {
"type": "string",
"default": "auto"
},
"listStyleType": {
"type": "string",
"default": "disc"
}
}
}
},
"type": "array",
"description": "Data file containing term information.",
"items": {
"type": "array",
"description": "Information about a single term.",
"minItems": 8,
"maxItems": 8,
"additionalItems": false,
"items": [
{
"type": "string",
"description": "The text for the term."
},
{
"type": "string",
"description": "Reading of the term, or an empty string if the reading is the same as the term."
},
{
"type": ["string", "null"],
"description": "String of space-separated tags for the definition. An empty string is treated as no tags."
},
{
"type": "string",
"description": "String of space-separated rule identifiers for the definition which is used to validate deinflection. An empty string should be used for words which aren't inflected."
},
{
"type": "number",
"description": "Score used to determine popularity. Negative values are more rare and positive values are more frequent. This score is also used to sort search results."
},
{
"type": "array",
"description": "Array of definitions for the term.",
"items": {
"oneOf": [
{
"type": "string",
"description": "Single definition for the term."
},
{
"type": "object",
"description": "Single detailed definition for the term.",
"required": [
"type"
],
"properties": {
"type": {
"type": "string",
"description": "The type of the data for this definition.",
"enum": ["text", "image", "structured-content"]
}
},
"oneOf": [
{
"required": [
"type",
"text"
],
"additionalProperties": false,
"properties": {
"type": {
"type": "string",
"const": "text"
},
"text": {
"type": "string",
"description": "Single definition for the term."
}
}
},
{
"required": [
"type",
"content"
],
"additionalProperties": false,
"properties": {
"type": {
"type": "string",
"const": "structured-content"
},
"content": {
"$ref": "#/definitions/structuredContent",
"description": "Single definition for the term using a structured content object."
}
}
},
{
"required": [
"type",
"path"
],
"additionalProperties": false,
"properties": {
"type": {
"type": "string",
"const": "image"
},
"path": {
"type": "string",
"description": "Path to the image file in the archive."
},
"width": {
"type": "integer",
"description": "Preferred width of the image.",
"minimum": 1
},
"height": {
"type": "integer",
"description": "Preferred height of the image.",
"minimum": 1
},
"title": {
"type": "string",
"description": "Hover text for the image."
},
"alt": {
"type": "string",
"description": "Alt text for the image."
},
"description": {
"type": "string",
"description": "Description of the image."
},
"pixelated": {
"type": "boolean",
"description": "Whether or not the image should appear pixelated at sizes larger than the image's native resolution.",
"default": false
},
"imageRendering": {
"type": "string",
"description": "Controls how the image is rendered. The value of this field supersedes the pixelated field.",
"enum": ["auto", "pixelated", "crisp-edges"],
"default": "auto"
},
"appearance": {
"type": "string",
"description": "Controls the appearance of the image. The \"monochrome\" value will mask the opaque parts of the image using the current text color.",
"enum": ["auto", "monochrome"],
"default": "auto"
},
"background": {
"type": "boolean",
"description": "Whether or not a background color is displayed behind the image.",
"default": true
},
"collapsed": {
"type": "boolean",
"description": "Whether or not the image is collapsed by default.",
"default": false
},
"collapsible": {
"type": "boolean",
"description": "Whether or not the image can be collapsed.",
"default": true
}
}
}
]
},
{
"type": "array",
"description": "Deinflection of the term to an uninflected term.",
"minItems": 2,
"maxItems": 2,
"items": [
{
"type": "string",
"description": "The uninflected term."
},
{
"type": "array",
"description": "A chain of inflection rules that produced the inflected term",
"items": {
"type": "string",
"description": "A single inflection rule."
}
}
]
}
]
}
},
{
"type": "integer",
"description": "Sequence number for the term. Terms with the same sequence number can be shown together when the \"resultOutputMode\" option is set to \"merge\"."
},
{
"type": "string",
"description": "String of space-separated tags for the term. An empty string is treated as no tags."
}
]
}
}

View File

@@ -1,227 +0,0 @@
{
"$id": "dictionaryTermMetaBankV3",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"frequency": {
"oneOf": [
{
"type": ["string", "number"]
},
{
"type": "object",
"additionalProperties": false,
"required": [
"value"
],
"properties": {
"value": {
"type": "number"
},
"displayValue": {
"type": "string"
}
}
}
]
}
},
"type": "array",
"description": "Custom metadata for terms.",
"items": {
"type": "array",
"description": "Metadata about a single term.",
"minItems": 3,
"maxItems": 3,
"additionalItems": false,
"items": [
{
"type": "string",
"description": "The text for the term."
},
{
"type": "string",
"enum": ["freq", "pitch", "ipa"],
"description": "Type of data. \"freq\" corresponds to frequency information; \"pitch\" corresponds to pitch information. \"ipa\" corresponds to IPA transcription."
},
{
"description": "Data for the term."
}
],
"oneOf": [
{
"minItems": 3,
"maxItems": 3,
"items": [
{},
{"const": "freq"},
{
"oneOf": [
{
"$ref": "#/definitions/frequency",
"description": "Frequency information for the term."
},
{
"type": "object",
"required": [
"reading",
"frequency"
],
"additionalProperties": false,
"properties": {
"reading": {
"type": "string",
"description": "Reading for the term."
},
"frequency": {
"$ref": "#/definitions/frequency",
"description": "Frequency information for the term."
}
}
}
]
}
]
},
{
"minItems": 3,
"maxItems": 3,
"items": [
{},
{"const": "pitch"},
{
"type": "object",
"description": "Pitch accent information for the term.",
"required": [
"reading",
"pitches"
],
"additionalProperties": false,
"properties": {
"reading": {
"type": "string",
"description": "Reading for the term."
},
"pitches": {
"type": "array",
"description": "List of different pitch accent information for the term and reading combination.",
"items": {
"type": "object",
"required": [
"position"
],
"additionalProperties": false,
"properties": {
"position": {
"oneOf": [
{
"type": "integer",
"description": "Mora position of the pitch accent downstep. A value of 0 indicates that the word does not have a downstep (heiban).",
"minimum": 0
},
{
"type": "string",
"description": "Pitch level of each mora with H representing high and L representing low. For example: HHLL for a 4 mora word.",
"pattern": "^[HL]+$"
}
]
},
"nasal": {
"oneOf": [
{
"type": "integer",
"description": "Position of a mora with nasal sound.",
"minimum": 0
},
{
"type": "array",
"description": "Positions of morae with nasal sound.",
"items": {
"type": "integer",
"minimum": 0
}
}
]
},
"devoice": {
"oneOf": [
{
"type": "integer",
"description": "Position of a mora with devoiced sound.",
"minimum": 0
},
{
"type": "array",
"description": "Positions of morae with devoiced sound.",
"items": {
"type": "integer",
"minimum": 0
}
}
]
},
"tags": {
"type": "array",
"description": "List of tags for this pitch accent.",
"items": {
"type": "string",
"description": "Tag for this pitch accent. This typically corresponds to a certain type of part of speech."
}
}
}
}
}
}
}
]
},
{
"minItems": 3,
"maxItems": 3,
"items": [
{},
{"const": "ipa"},
{
"type": ["object"],
"description": "IPA transcription information for the term.",
"required": [
"reading",
"transcriptions"
],
"additionalProperties": false,
"properties": {
"reading": {
"type": "string",
"description": "Reading for the term."
},
"transcriptions": {
"type": "array",
"description": "List of different IPA transcription information for the term and reading combination.",
"items": {
"type": "object",
"required": [
"ipa"
],
"additionalProperties": false,
"properties": {
"ipa": {
"type": "string",
"description": "IPA transcription for the term."
},
"tags": {
"type": "array",
"description": "List of tags for this IPA transcription.",
"items": {
"type": "string",
"description": "Tag for this IPA transcription."
}
}
}
}
}
}
}
]
}
]
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,78 +0,0 @@
{
"$id": "recommendedDictionaries",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Contains data for recommended dictionaries on welcome page.",
"type": "object",
"patternProperties": {
"^.{2,}$": {
"type": "object",
"properties": {
"terms": {
"type": "array",
"items": {
"$ref": "#/definitions/Dictionary"
}
},
"kanji": {
"type": "array",
"items": {
"$ref": "#/definitions/Dictionary"
}
},
"frequency": {
"type": "array",
"items": {
"$ref": "#/definitions/Dictionary"
}
},
"grammar": {
"type": "array",
"items": {
"$ref": "#/definitions/Dictionary"
}
},
"pronunciation": {
"type": "array",
"items": {
"$ref": "#/definitions/Dictionary"
}
}
},
"required": [
"terms",
"kanji",
"frequency",
"grammar"
],
"additionalProperties": false
}
},
"definitions": {
"Dictionary": {
"type": "object",
"required": [
"name",
"downloadUrl",
"description"
],
"properties": {
"name": {
"type": "string",
"minLength": 2
},
"downloadUrl": {
"type": "string",
"minLength": 2
},
"description": {
"type": "string",
"minLength": 2
},
"homepage": {
"type": "string",
"minLength": 2
}
}
}
}
}

View File

@@ -1,180 +0,0 @@
{
"$id": "recommendedSettings",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Contains data for recommended default options overrides by language.",
"type": "object",
"$defs": {
"path": {
"type": "string",
"minLength": 2
},
"value": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "number"
},
{
"type": "boolean"
},
{
"type": "array"
},
{
"type": "object"
}
]
},
"description": {
"type": "string",
"minLength": 2
}
},
"patternProperties": {
"^.{2,}$": {
"title": "Language",
"type": "array",
"items": {
"title": "Modification",
"type": "object",
"oneOf": [
{
"type": "object",
"title": "ModificationSet",
"properties": {
"modification": {
"type": "object",
"properties": {
"action": {
"type": "string",
"const": "set"
},
"path": {
"$ref": "#/$defs/path"
},
"value": {
"$ref": "#/$defs/value"
}
}
},
"description": {
"$ref": "#/$defs/description"
}
}
},
{
"type": "object",
"title": "ModificationDelete",
"properties": {
"modification": {
"type": "object",
"properties": {
"action": {
"type": "string",
"const": "delete"
},
"path": {
"$ref": "#/$defs/path"
},
"value": {
"$ref": "#/$defs/value"
}
}
},
"description": {
"$ref": "#/$defs/description"
}
}
},
{
"type": "object",
"title": "ModificationSwap",
"properties": {
"modification": {
"type": "object",
"properties": {
"action": {
"type": "string",
"const": "swap"
},
"path1": {
"$ref": "#/$defs/path"
},
"path2": {
"$ref": "#/$defs/path"
}
}
},
"description": {
"$ref": "#/$defs/description"
}
}
},
{
"type": "object",
"title": "ModificationSplice",
"properties": {
"modification": {
"type": "object",
"properties": {
"action": {
"type": "string",
"const": "splice"
},
"path": {
"$ref": "#/$defs/path"
},
"start": {
"type": "number"
},
"deleteCount": {
"type": "number"
},
"items": {
"type": "array",
"items": {
"$ref": "#/$defs/value"
}
}
}
},
"description": {
"$ref": "#/$defs/description"
}
}
},
{
"type": "object",
"title": "ModificationPush",
"properties": {
"modification": {
"type": "object",
"properties": {
"action": {
"type": "string",
"const": "push"
},
"path": {
"$ref": "#/$defs/path"
},
"items": {
"type": "array",
"items": {
"$ref": "#/$defs/value"
}
}
}
},
"description": {
"$ref": "#/$defs/description"
}
}
}
]
}
}
}
}

View File

@@ -1,340 +0,0 @@
[
{
"selectors": [".gloss-image-container"],
"styles": [
["display", "inline-block"],
["white-space", "nowrap"],
["max-width", "100%"],
["max-height", "100vh"],
["position", "relative"],
["vertical-align", "top"],
["line-height", "0"],
["overflow", "hidden"],
["font-size", "1px"]
]
},
{
"selectors": [".gloss-image-link"],
"styles": [
["cursor", "inherit"],
["display", "inline-block"],
["position", "relative"],
["line-height", "1"],
["max-width", "100%"],
["color", "inherit"]
]
},
{
"selectors": [".gloss-image-container-overlay"],
"styles": [
["position", "absolute"],
["left", "0"],
["top", "0"],
["width", "100%"],
["height", "100%"],
["font-size", "calc(1em * var(--font-size-no-units))"],
["line-height", "var(--line-height)"],
["display", "table"],
["table-layout", "fixed"],
["white-space", "normal"],
["color", "var(--text-color-light3)"]
]
},
{
"selectors": [".gloss-image-link[data-has-image=true][data-image-load-state=load-error] .gloss-image-container-overlay::after"],
"styles": [
["content", "'Image failed to load'"],
["display", "table-cell"],
["width", "100%"],
["height", "100%"],
["vertical-align", "middle"],
["text-align", "center"],
["padding", "0.25em"]
]
},
{
"selectors": [".gloss-image-background"],
"styles": [
["--image", "none"],
["position", "absolute"],
["left", "0"],
["top", "0"],
["width", "100%"],
["height", "100%"],
["-webkit-mask-repeat", "no-repeat"],
["-webkit-mask-position", "center center"],
["-webkit-mask-mode", "alpha"],
["-webkit-mask-size", "contain"],
["-webkit-mask-image", "var(--image)"],
["mask-repeat", "no-repeat"],
["mask-position", "center center"],
["mask-mode", "alpha"],
["mask-size", "contain"],
["mask-image", "var(--image)"],
["background-color", "currentColor"]
]
},
{
"selectors": [".gloss-image"],
"styles": [
["display", "inline-block"],
["vertical-align", "top"],
["object-fit", "contain"],
["border", "none"],
["outline", "none"]
]
},
{
"selectors": [".gloss-image-link[data-has-aspect-ratio=true] .gloss-image"],
"styles": [
["position", "absolute"],
["left", "0"],
["top", "0"],
["width", "100%"],
["height", "100%"]
]
},
{
"selectors": [
".gloss-image-link[data-image-rendering=pixelated] .gloss-image",
".gloss-image-link[data-image-rendering=pixelated] .gloss-image-background"
],
"styles": [
["image-rendering", "auto"],
["image-rendering", "-moz-crisp-edges"],
["image-rendering", "-webkit-optimize-contrast"],
["image-rendering", "pixelated"],
["image-rendering", "crisp-edges"]
]
},
{
"selectors": [
".gloss-image-link[data-image-rendering=crisp-edges] .gloss-image",
".gloss-image-link[data-image-rendering=crisp-edges] .gloss-image-background"
],
"styles": [
["image-rendering", "auto"],
["image-rendering", "-moz-crisp-edges"],
["image-rendering", "-webkit-optimize-contrast"],
["image-rendering", "crisp-edges"]
]
},
{
"selectors": [
":root[data-browser=firefox] .gloss-image-link[data-image-rendering=crisp-edges] .gloss-image",
":root[data-browser=firefox] .gloss-image-link[data-image-rendering=crisp-edges] .gloss-image-background",
":root[data-browser=firefox-mobile] .gloss-image-link[data-image-rendering=crisp-edges] .gloss-image",
":root[data-browser=firefox-mobile] .gloss-image-link[data-image-rendering=crisp-edges] .gloss-image-background"
],
"styles": [
["image-rendering", "auto"]
]
},
{
"selectors": [".gloss-image-link[data-has-aspect-ratio=true] .gloss-image-sizer"],
"styles": [
["display", "inline-block"],
["width", "0"],
["vertical-align", "top"],
["font-size", "0"]
]
},
{
"selectors": [".gloss-image-link-text"],
"styles": [
["display", "none"],
["line-height", "var(--line-height)"]
]
},
{
"selectors": [".gloss-image-link-text::before"],
"styles": [
["content", "'['"]
]
},
{
"selectors": [".gloss-image-link-text::after"],
"styles": [
["content", "']'"]
]
},
{
"selectors": [".gloss-image-description"],
"styles": [
["display", "block"],
["white-space", "pre-line"]
]
},
{
"selectors": [".gloss-image-link[data-appearance=monochrome] .gloss-image"],
"styles": [
["--shadow-settings", "0 0 0.01px var(--text-color)"],
["filter", "grayscale(1) opacity(0.5) drop-shadow(var(--shadow-settings)) drop-shadow(var(--shadow-settings)) saturate(1000%) brightness(1000%)"],
["opacity", "0"]
]
},
{
"selectors": [".gloss-image-link[data-size-units=em] .gloss-image-container"],
"styles": [
["font-size", "1em"]
]
},
{
"selectors": [".gloss-image-link[data-vertical-align=baseline]"],
"styles": [
["vertical-align", "baseline"]
]
},
{
"selectors": [".gloss-image-link[data-vertical-align=sub]"],
"styles": [
["vertical-align", "sub"]
]
},
{
"selectors": [".gloss-image-link[data-vertical-align=super]"],
"styles": [
["vertical-align", "super"]
]
},
{
"selectors": [".gloss-image-link[data-vertical-align=text-top]"],
"styles": [
["vertical-align", "top"]
]
},
{
"selectors": [".gloss-image-link[data-vertical-align=text-bottom]"],
"styles": [
["vertical-align", "bottom"]
]
},
{
"selectors": [".gloss-image-link[data-vertical-align=middle]"],
"styles": [
["vertical-align", "middle"]
]
},
{
"selectors": [".gloss-image-link[data-vertical-align=top]"],
"styles": [
["vertical-align", "top"]
]
},
{
"selectors": [".gloss-image-link[data-vertical-align=bottom]"],
"styles": [
["vertical-align", "bottom"]
]
},
{
"selectors": [
".gloss-image-link[data-collapsed=true]",
":root[data-glossary-layout-mode^=compact] .gloss-image-link[data-collapsible=true]"
],
"styles": [
["vertical-align", "baseline"]
]
},
{
"selectors": [
".gloss-image-link[data-collapsed=true] .gloss-image-container",
":root[data-glossary-layout-mode^=compact] .gloss-image-link[data-collapsible=true] .gloss-image-container"
],
"styles": [
["display", "none"],
["position", "absolute"],
["left", "0"],
["top", "100%"],
["z-index", "1"]
]
},
{
"selectors": [
".entry:nth-last-of-type(1):not(:nth-of-type(1)) .gloss-image-link[data-collapsed=true] .gloss-image-container",
":root[data-glossary-layout-mode^=compact] .entry:nth-last-of-type(1):not(:nth-of-type(1)) .gloss-image-link[data-collapsible=true] .gloss-image-container",
":root[data-glossary-layout-mode^=compact] .definition-item:nth-last-of-type(1) .gloss-image-link[data-collapsible=true] .gloss-image-container"
],
"styles": [
["bottom", "100%"],
["top", "auto"]
]
},
{
"selectors": [
".gloss-image-link[data-collapsed=true]:hover .gloss-image-container",
".gloss-image-link[data-collapsed=true]:focus .gloss-image-container",
":root[data-glossary-layout-mode^=compact] .gloss-image-link[data-collapsible=true]:hover .gloss-image-container",
":root[data-glossary-layout-mode^=compact] .gloss-image-link[data-collapsible=true]:focus .gloss-image-container"
],
"styles": [
["display", "block"]
]
},
{
"selectors": [
".gloss-image-link[data-collapsed=true] .gloss-image-link-text",
":root[data-glossary-layout-mode^=compact] .gloss-image-link[data-collapsible=true] .gloss-image-link-text"
],
"styles": [
["display", "inline"]
]
},
{
"selectors": [
".gloss-image-link[data-collapsed=true]~.gloss-image-description",
":root[data-glossary-layout-mode^=compact] .gloss-image-description"
],
"styles": [
["display", "inline"]
]
},
{
"selectors": [".gloss-link-external-icon"],
"styles": [
["display", "none"]
]
},
{
"selectors": [".gloss-sc-table-container"],
"styles": [
["display", "block"]
]
},
{
"selectors": [".gloss-sc-table"],
"styles": [
["table-layout", "auto"],
["border-collapse", "collapse"]
]
},
{
"selectors": [
".gloss-sc-thead",
".gloss-sc-tfoot",
".gloss-sc-th"
],
"styles": [
["font-weight", "bold"]
]
},
{
"selectors": [
".gloss-sc-th",
".gloss-sc-td"
],
"styles": [
["border-style", "solid"],
["padding", "0.25em"],
["vertical-align", "top"],
["border-width", "1px"],
["border-color", "currentColor"]
]
},
{
"selectors": [".gloss-image-link:not([data-appearance=monochrome]) .gloss-image-background"],
"styles": [
["display", "none"]
]
}
]

View File

@@ -1,30 +0,0 @@
{{#*inline "part-of-speech-pretty"}}
{{~#if (op "===" . "v1")~}}Ichidan verb
{{~else if (op "===" . "v5")~}}Godan verb
{{~else if (op "===" . "vk")~}}Kuru verb
{{~else if (op "===" . "vs")~}}Suru verb
{{~else if (op "===" . "vz")~}}Zuru verb
{{~else if (op "===" . "adj-i")~}}I-adjective
{{~else if (op "===" . "n")~}}Noun
{{~else~}}{{.}}
{{~/if~}}
{{/inline}}
{{#*inline "part-of-speech"}}
{{~#scope~}}
{{~#if (op "!==" definition.type "kanji")~}}
{{~#set "first" true}}{{/set~}}
{{~#each definition.expressions~}}
{{~#each wordClasses~}}
{{~#unless (get (concat "used_" .))~}}
{{~> part-of-speech-pretty . ~}}
{{~#unless (get "first")}}, {{/unless~}}
{{~#set (concat "used_" .) true~}}{{~/set~}}
{{~#set "first" false~}}{{~/set~}}
{{~/unless~}}
{{~/each~}}
{{~/each~}}
{{~#if (get "first")~}}Unknown{{~/if~}}
{{~/if~}}
{{~/scope~}}
{{/inline}}

View File

@@ -1,3 +0,0 @@
{{#*inline "search-query"}}
{{~#multiLine}}{{context.fullQuery}}{{/multiLine~}}
{{/inline}}

View File

@@ -1,148 +0,0 @@
{{#*inline "selection-text"}}
{{~#if (hasMedia "selectionText")}}{{#getMedia "selectionText"}}{{/getMedia}}{{/if~}}
{{/inline}}
{{#*inline "sentence-furigana"}}
{{~#if definition.cloze~}}
{{~#if (hasMedia "textFurigana" definition.cloze.sentence)~}}
{{#getMedia "textFurigana" definition.cloze.sentence escape=false}}{{/getMedia}}
{{~else~}}
{{definition.cloze.sentence}}
{{~/if~}}
{{~/if~}}
{{/inline}}
{{<<<<<<<}}
{{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{/each}}
{{=======}}
{{#each glossary}}{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}{{/each}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}}
{{=======}}
{{#each glossary}}{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}{{#unless @last}} | {{/unless}}{{/each}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}
{{=======}}
{{#each glossary}}<li>{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}</li>{{/each}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#if definition.audioFileName~}}
[sound:{{definition.audioFileName}}]
{{~/if~}}
{{=======}}
{{~#if (hasMedia "audio")~}}
[sound:{{#getMedia "audio"}}{{/getMedia}}]
{{~/if~}}
{{>>>>>>>}}
{{<<<<<<<}}
<img src="{{definition.screenshotFileName}}" />
{{=======}}
{{~#if (hasMedia "screenshot")~}}
<img src="{{#getMedia "screenshot"}}{{/getMedia}}" />
{{~/if~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#if definition.clipboardImageFileName~}}
<img src="{{definition.clipboardImageFileName}}" />
{{~/if~}}
{{=======}}
{{~#if (hasMedia "clipboardImage")~}}
<img src="{{#getMedia "clipboardImage"}}{{/getMedia}}" />
{{~/if~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#if definition.clipboardText~}}{{definition.clipboardText}}{{~/if~}}
{{=======}}
{{~#if (hasMedia "clipboardText")}}{{#getMedia "clipboardText"}}{{/getMedia}}{{/if~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#*inline "pitch-accent-item-downstep-notation"}}
{{~#scope~}}
<span>
{{~#set "style1a"~}}display:inline-block;position:relative;{{~/set~}}
{{~#set "style1b"~}}padding-right:0.1em;margin-right:0.1em;{{~/set~}}
{{~#set "style2a"~}}display:block;user-select:none;pointer-events:none;position:absolute;top:0.1em;left:0;right:0;height:0;border-top:0.1em solid;{{~/set~}}
{{~#set "style2b"~}}right:-0.1em;height:0.4em;border-right:0.1em solid;{{~/set~}}
{{~#each (getKanaMorae reading)~}}
{{~#set "style1"}}{{#get "style1a"}}{{/get}}{{/set~}}
{{~#set "style2"}}{{/set~}}
{{~#if (isMoraPitchHigh @index ../position)}}
{{~#set "style2"}}{{#get "style2a"}}{{/get}}{{/set~}}
{{~#if (op "!" (isMoraPitchHigh (op "+" @index 1) ../position))~}}
{{~#set "style1" (op "+" (get "style1") (get "style1b"))}}{{/set~}}
{{~#set "style2" (op "+" (get "style2") (get "style2b"))}}{{/set~}}
{{~/if~}}
{{~/if~}}
<span style="{{#get "style1"}}{{/get}}">{{{.}}}<span style="{{#get "style2"}}{{/get}}"></span></span>
{{~/each~}}
</span>
{{~/scope~}}
{{/inline}}
{{#*inline "pitch-accent-item-graph-position-x"}}{{#op "+" 25 (op "*" index 50)}}{{/op}}{{/inline}}
{{#*inline "pitch-accent-item-graph-position-y"}}{{#op "+" 25 (op "?:" (isMoraPitchHigh index position) 0 50)}}{{/op}}{{/inline}}
{{#*inline "pitch-accent-item-graph-position"}}{{> pitch-accent-item-graph-position-x index=index position=position}} {{> pitch-accent-item-graph-position-y index=index position=position}}{{/inline}}
{{#*inline "pitch-accent-item-graph"}}
{{~#scope~}}
{{~#set "morae" (getKanaMorae reading)}}{{/set~}}
{{~#set "morae-count" (property (get "morae") "length")}}{{/set~}}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {{#op "+" 50 (op "*" 50 (get "morae-count"))}}{{/op}} 100" style="display:inline-block;height:2em;">
<defs>
<g id="term-pitch-accent-graph-dot"><circle cx="0" cy="0" r="15" style="fill:#000;stroke:#000;stroke-width:5;" /></g>
<g id="term-pitch-accent-graph-dot-downstep"><circle cx="0" cy="0" r="15" style="fill:none;stroke:#000;stroke-width:5;" /><circle cx="0" cy="0" r="5" style="fill:none;stroke:#000;stroke-width:5;" /></g>
<g id="term-pitch-accent-graph-triangle"><path d="M0 13 L15 -13 L-15 -13 Z" style="fill:none;stroke:#000;stroke-width:5;" /></g>
</defs>
<path style="fill:none;stroke:#000;stroke-width:5;" d="
{{~#set "cmd" "M"}}{{/set~}}
{{~#each (get "morae")~}}
{{~#get "cmd"}}{{/get~}}
{{~> pitch-accent-item-graph-position index=@index position=../position~}}
{{~#set "cmd" "L"}}{{/set~}}
{{~/each~}}
"></path>
<path style="fill:none;stroke:#000;stroke-width:5;stroke-dasharray:5 5;" d="M{{> pitch-accent-item-graph-position index=(op "-" (get "morae-count") 1) position=position}} L{{> pitch-accent-item-graph-position index=(get "morae-count") position=position}}"></path>
{{#each (get "morae")}}
<use href="{{#if (op "&&" (isMoraPitchHigh @index ../position) (op "!" (isMoraPitchHigh (op "+" @index 1) ../position)))}}#term-pitch-accent-graph-dot-downstep{{else}}#term-pitch-accent-graph-dot{{/if}}" x="{{> pitch-accent-item-graph-position-x index=@index position=../position}}" y="{{> pitch-accent-item-graph-position-y index=@index position=../position}}"></use>
{{/each}}
<use href="#term-pitch-accent-graph-triangle" x="{{> pitch-accent-item-graph-position-x index=(get "morae-count") position=position}}" y="{{> pitch-accent-item-graph-position-y index=(get "morae-count") position=position}}"></use>
</svg>
{{~/scope~}}
{{/inline}}
{{#*inline "pitch-accent-item-position"~}}
<span>[{{position}}]</span>
{{~/inline}}
{{#*inline "pitch-accent-item"}}
{{~#if (op "==" format "downstep-notation")~}}
{{~> pitch-accent-item-downstep-notation~}}
{{~else if (op "==" format "graph")~}}
{{~> pitch-accent-item-graph~}}
{{~else if (op "==" format "position")~}}
{{~> pitch-accent-item-position~}}
{{~/if~}}
{{/inline}}
{{=======}}
{{#*inline "pitch-accent-item"}}
{{~#pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}{{~/pronunciation~}}
{{/inline}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#*inline "pitch-accents"}}
{{~> pitch-accent-list format='downstep-notation'~}}
{{/inline}}
{{=======}}
{{#*inline "pitch-accents"}}
{{~> pitch-accent-list format='text'~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,109 +0,0 @@
{{! Pitch Accents }}
{{#*inline "pitch-accent-item-downstep-notation"}}
{{~#scope~}}
<span>
{{~#set "style1a"~}}display:inline-block;position:relative;{{~/set~}}
{{~#set "style1b"~}}padding-right:0.1em;margin-right:0.1em;{{~/set~}}
{{~#set "style2a"~}}display:block;user-select:none;pointer-events:none;position:absolute;top:0.1em;left:0;right:0;height:0;border-top:0.1em solid;{{~/set~}}
{{~#set "style2b"~}}right:-0.1em;height:0.4em;border-right:0.1em solid;{{~/set~}}
{{~#each (getKanaMorae reading)~}}
{{~#set "style1"}}{{#get "style1a"}}{{/get}}{{/set~}}
{{~#set "style2"}}{{/set~}}
{{~#if (isMoraPitchHigh @index ../position)}}
{{~#set "style2"}}{{#get "style2a"}}{{/get}}{{/set~}}
{{~#if (op "!" (isMoraPitchHigh (op "+" @index 1) ../position))~}}
{{~#set "style1" (op "+" (get "style1") (get "style1b"))}}{{/set~}}
{{~#set "style2" (op "+" (get "style2") (get "style2b"))}}{{/set~}}
{{~/if~}}
{{~/if~}}
<span style="{{#get "style1"}}{{/get}}">{{{.}}}<span style="{{#get "style2"}}{{/get}}"></span></span>
{{~/each~}}
</span>
{{~/scope~}}
{{/inline}}
{{#*inline "pitch-accent-item-graph-position-x"}}{{#op "+" 25 (op "*" index 50)}}{{/op}}{{/inline}}
{{#*inline "pitch-accent-item-graph-position-y"}}{{#op "+" 25 (op "?:" (isMoraPitchHigh index position) 0 50)}}{{/op}}{{/inline}}
{{#*inline "pitch-accent-item-graph-position"}}{{> pitch-accent-item-graph-position-x index=index position=position}} {{> pitch-accent-item-graph-position-y index=index position=position}}{{/inline}}
{{#*inline "pitch-accent-item-graph"}}
{{~#scope~}}
{{~#set "morae" (getKanaMorae reading)}}{{/set~}}
{{~#set "morae-count" (property (get "morae") "length")}}{{/set~}}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {{#op "+" 50 (op "*" 50 (get "morae-count"))}}{{/op}} 100" style="display:inline-block;height:2em;">
<defs>
<g id="term-pitch-accent-graph-dot"><circle cx="0" cy="0" r="15" style="fill:#000;stroke:#000;stroke-width:5;" /></g>
<g id="term-pitch-accent-graph-dot-downstep"><circle cx="0" cy="0" r="15" style="fill:none;stroke:#000;stroke-width:5;" /><circle cx="0" cy="0" r="5" style="fill:none;stroke:#000;stroke-width:5;" /></g>
<g id="term-pitch-accent-graph-triangle"><path d="M0 13 L15 -13 L-15 -13 Z" style="fill:none;stroke:#000;stroke-width:5;" /></g>
</defs>
<path style="fill:none;stroke:#000;stroke-width:5;" d="
{{~#set "cmd" "M"}}{{/set~}}
{{~#each (get "morae")~}}
{{~#get "cmd"}}{{/get~}}
{{~> pitch-accent-item-graph-position index=@index position=../position~}}
{{~#set "cmd" "L"}}{{/set~}}
{{~/each~}}
"></path>
<path style="fill:none;stroke:#000;stroke-width:5;stroke-dasharray:5 5;" d="M{{> pitch-accent-item-graph-position index=(op "-" (get "morae-count") 1) position=position}} L{{> pitch-accent-item-graph-position index=(get "morae-count") position=position}}"></path>
{{#each (get "morae")}}
<use href="{{#if (op "&&" (isMoraPitchHigh @index ../position) (op "!" (isMoraPitchHigh (op "+" @index 1) ../position)))}}#term-pitch-accent-graph-dot-downstep{{else}}#term-pitch-accent-graph-dot{{/if}}" x="{{> pitch-accent-item-graph-position-x index=@index position=../position}}" y="{{> pitch-accent-item-graph-position-y index=@index position=../position}}"></use>
{{/each}}
<use href="#term-pitch-accent-graph-triangle" x="{{> pitch-accent-item-graph-position-x index=(get "morae-count") position=position}}" y="{{> pitch-accent-item-graph-position-y index=(get "morae-count") position=position}}"></use>
</svg>
{{~/scope~}}
{{/inline}}
{{#*inline "pitch-accent-item-position"~}}
<span>[{{position}}]</span>
{{~/inline}}
{{#*inline "pitch-accent-item"}}
{{~#if (op "==" format "downstep-notation")~}}
{{~> pitch-accent-item-downstep-notation~}}
{{~else if (op "==" format "graph")~}}
{{~> pitch-accent-item-graph~}}
{{~else if (op "==" format "position")~}}
{{~> pitch-accent-item-position~}}
{{~/if~}}
{{/inline}}
{{#*inline "pitch-accent-item-disambiguation"}}
{{~#scope~}}
{{~#set "exclusive" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}}
{{~#if (op ">" (property (get "exclusive") "length") 0)~}}
{{~#set "separator" ""~}}{{/set~}}
<em>({{#each (get "exclusive")~}}
{{~#get "separator"}}{{/get~}}{{{.}}}
{{~/each}} only) </em>
{{~/if~}}
{{~/scope~}}
{{/inline}}
{{#*inline "pitch-accent-list"}}
{{~#if (op ">" pitchCount 0)~}}
{{~#if (op ">" pitchCount 1)~}}<ol>{{~/if~}}
{{~#each pitches~}}
{{~#each pitches~}}
{{~#if (op ">" ../../pitchCount 1)~}}<li>{{~/if~}}
{{~> pitch-accent-item-disambiguation~}}
{{~> pitch-accent-item format=../../format~}}
{{~#if (op ">" ../../pitchCount 1)~}}</li>{{~/if~}}
{{~/each~}}
{{~/each~}}
{{~#if (op ">" pitchCount 1)~}}</ol>{{~/if~}}
{{~else~}}
No pitch accent data
{{~/if~}}
{{/inline}}
{{#*inline "pitch-accents"}}
{{~> pitch-accent-list format='downstep-notation'~}}
{{/inline}}
{{#*inline "pitch-accent-graphs"}}
{{~> pitch-accent-list format='graph'~}}
{{/inline}}
{{#*inline "pitch-accent-positions"}}
{{~> pitch-accent-list format='position'~}}
{{/inline}}
{{! End Pitch Accents }}

View File

@@ -1,161 +0,0 @@
{{<<<<<<<}}
{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}
{{=======}}
{{formatGlossary ../dictionary .}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#furigana}}{{{.}}}{{/furigana~}}
{{=======}}
{{~furigana .~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#furigana}}{{{definition}}}{{/furigana}}
{{=======}}
{{furigana definition}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#furigana expression reading~}}{{~/furigana~}}
{{=======}}
{{~furigana expression reading~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#furigana expression reading}}{{/furigana~}}
{{=======}}
{{~furigana expression reading~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#furiganaPlain}}{{{.}}}{{/furiganaPlain~}}
{{=======}}
{{~furiganaPlain .~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#furiganaPlain}}{{{definition}}}{{/furiganaPlain}}
{{=======}}
{{furiganaPlain definition}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#furiganaPlain expression reading~}}{{~/furiganaPlain~}}
{{=======}}
{{~furiganaPlain expression reading~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#furiganaPlain expression reading}}{{/furiganaPlain~}}
{{=======}}
{{~furiganaPlain expression reading~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#getMedia "audio"}}{{/getMedia}}
{{=======}}
{{getMedia "audio"}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#getMedia "screenshot"}}{{/getMedia}}
{{=======}}
{{getMedia "screenshot"}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#getMedia "clipboardImage"}}{{/getMedia}}
{{=======}}
{{getMedia "clipboardImage"}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#getMedia "clipboardText"}}{{/getMedia}}
{{=======}}
{{getMedia "clipboardText"}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#getMedia "selectionText"}}{{/getMedia}}
{{=======}}
{{getMedia "selectionText"}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#getMedia "textFurigana" definition.cloze.sentence escape=false}}{{/getMedia}}
{{=======}}
{{getMedia "textFurigana" definition.cloze.sentence escape=false}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}{{~/pronunciation~}}
{{=======}}
{{~pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#set "any" false}}{{/set~}}
{{=======}}
{{~set "any" false~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#set "any" true}}{{/set~}}
{{=======}}
{{~set "any" true~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#set "previousDictionary" dictionary~}}{{~/set~}}
{{=======}}
{{~set "previousDictionary" dictionary~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#set "exclusive" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}}
{{=======}}
{{~set "exclusive" (spread exclusiveExpressions exclusiveReadings)~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#set "separator" ""~}}{{/set~}}
{{=======}}
{{~set "separator" ""~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#get "separator"}}{{/get~}}
{{=======}}
{{~get "separator"~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#set "found" false}}{{/set~}}
{{=======}}
{{~set "found" false~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#set "found" true}}{{/set~}}
{{=======}}
{{~set "found" true~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#set "first" true}}{{/set~}}
{{=======}}
{{~set "first" true~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#set "first" false~}}{{~/set~}}
{{=======}}
{{~set "first" false~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#set (concat "used_" .) true~}}{{~/set~}}
{{=======}}
{{~set (concat "used_" .) true~}}
{{>>>>>>>}}

View File

@@ -1,92 +0,0 @@
{{#*inline "cloze-body-kana"}}
{{~#if definition.cloze}}{{definition.cloze.bodyKana}}{{/if~}}
{{/inline}}
{{#*inline "phonetic-transcriptions"}}
{{~#if (op ">" definition.phoneticTranscriptions.length 0)~}}
<ul>
{{~#each definition.phoneticTranscriptions~}}
{{~#each phoneticTranscriptions~}}
<li>
{{~set "any" false~}}
{{~#each tags~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{name}}
{{~set "any" true~}}
{{~/each~}}
{{~#if (get "any")}})</i> {{/if~}}
{{ipa~}}
</li>
{{~/each~}}
{{~/each~}}
</ul>
{{~/if~}}
{{/inline}}
{{<<<<<<<}}
{{#*inline "conjugation"}}
{{~#if definition.reasons~}}
{{~#each definition.reasons~}}
{{~#if (op ">" @index 0)}} « {{/if~}}
{{.}}
{{~/each~}}
{{~/if~}}
{{/inline}}
{{=======}}
{{#*inline "conjugation"}}
{{~#if (op ">" definition.inflectionRuleChainCandidates.length 0)~}}
{{~set "multiple" false~}}
{{~#if (op ">" definition.inflectionRuleChainCandidates.length 1)~}}
{{~set "multiple" true~}}
{{~/if~}}
{{~#if (get "multiple")~}}<ul>{{/if~}}
{{~#each definition.inflectionRuleChainCandidates~}}
{{~#if (op ">" inflectionRules.length 0)~}}
{{~#if (get "multiple")~}}<li>{{/if~}}
{{~#each inflectionRules~}}
{{~#if (op ">" @index 0)}} « {{/if~}}
{{.}}
{{~/each~}}
{{~#if (get "multiple")~}}</li>{{/if~}}
{{~/if~}}
{{~/each~}}
{{~#if (get "multiple")~}}</ul>{{/if~}}
{{~/if~}}
{{/inline}}
{{>>>>>>>}}
{{#*inline "frequency-harmonic-rank"}}
{{~#if (op "===" definition.frequencyHarmonic -1) ~}}
9999999
{{~else ~}}
{{definition.frequencyHarmonic}}
{{~/if~}}
{{/inline}}
{{#*inline "frequency-harmonic-occurrence"}}
{{~#if (op "===" definition.frequencyHarmonic -1) ~}}
0
{{~else ~}}
{{definition.frequencyHarmonic}}
{{~/if~}}
{{/inline}}
{{#*inline "frequency-average-rank"}}
{{~#if (op "===" definition.frequencyAverage -1) ~}}
9999999
{{~else ~}}
{{definition.frequencyAverage}}
{{~/if~}}
{{/inline}}
{{#*inline "frequency-average-occurrence"}}
{{~#if (op "===" definition.frequencyAverage -1) ~}}
0
{{~else ~}}
{{definition.frequencyAverage}}
{{~/if~}}
{{/inline}}
{{~#*inline "pitch-accent-categories"~}}
{{~#each (pitchCategories @root)~}}{{~.~}}{{~#unless @last~}},{{~/unless~}}{{~/each~}}
{{~/inline~}}

View File

@@ -1,21 +0,0 @@
{{<<<<<<<}}
{{#*inline "sentence-furigana"}}
{{~#if definition.cloze~}}
{{~#if (hasMedia "textFurigana" definition.cloze.sentence)~}}
{{getMedia "textFurigana" definition.cloze.sentence escape=false}}
{{~else~}}
{{definition.cloze.sentence}}
{{~/if~}}
{{~/if~}}
{{/inline}}
{{=======}}
{{#*inline "sentence-furigana"}}
{{~#if definition.cloze~}}
{{~#if (hasMedia "textFurigana" definition.cloze.sentence)~}}
{{{getMedia "textFurigana" definition.cloze.sentence escape=false}}}
{{~else~}}
{{{definition.cloze.sentence}}}
{{~/if~}}
{{~/if~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,9 +0,0 @@
{{<<<<<<<}}
{{#*inline "url"}}
<a href="{{definition.url}}">{{definition.url}}</a>
{{/inline}}
{{=======}}
{{~#*inline "url"~}}
<a href="{{definition.url}}">{{definition.url}}</a>
{{~/inline~}}
{{>>>>>>>}}

View File

@@ -1,13 +0,0 @@
{{<<<<<<<}}
{{#*inline "pitch-accent-graphs"}}
{{~> pitch-accent-list format='graph'~}}
{{/inline}}
{{=======}}
{{#*inline "pitch-accent-graphs"}}
{{~> pitch-accent-list format='graph'~}}
{{/inline}}
{{#*inline "pitch-accent-graphs-jj"}}
{{~> pitch-accent-list format='graph-jj'~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,69 +0,0 @@
{{<<<<<<<}}
{{#*inline "sentence"}}
{{~#if definition.cloze}}{{definition.cloze.sentence}}{{/if~}}
{{/inline}}
{{=======}}
{{#*inline "sentence"}}
{{~#if definition.cloze}}{{{definition.cloze.sentence}}}{{/if~}}
{{/inline}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#*inline "cloze-prefix"}}
{{~#if definition.cloze}}{{definition.cloze.prefix}}{{/if~}}
{{/inline}}
{{=======}}
{{#*inline "cloze-prefix"}}
{{~#if definition.cloze}}{{{definition.cloze.prefix}}}{{/if~}}
{{/inline}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#*inline "cloze-body"}}
{{~#if definition.cloze}}{{definition.cloze.body}}{{/if~}}
{{/inline}}
{{=======}}
{{#*inline "cloze-body"}}
{{~#if definition.cloze}}{{{definition.cloze.body}}}{{/if~}}
{{/inline}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#*inline "cloze-body-kana"}}
{{~#if definition.cloze}}{{definition.cloze.bodyKana}}{{/if~}}
{{/inline}}
{{=======}}
{{#*inline "cloze-body-kana"}}
{{~#if definition.cloze}}{{{definition.cloze.bodyKana}}}{{/if~}}
{{/inline}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#*inline "cloze-suffix"}}
{{~#if definition.cloze}}{{definition.cloze.suffix}}{{/if~}}
{{/inline}}
{{=======}}
{{#*inline "cloze-suffix"}}
{{~#if definition.cloze}}{{{definition.cloze.suffix}}}{{/if~}}
{{/inline}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#*inline "clipboard-text"}}
{{~#if (hasMedia "clipboardText")}}{{getMedia "clipboardText"}}{{/if~}}
{{/inline}}
{{=======}}
{{#*inline "clipboard-text"}}
{{~#if (hasMedia "clipboardText")}}{{{getMedia "clipboardText"}}}{{/if~}}
{{/inline}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#*inline "selection-text"}}
{{~#if (hasMedia "selectionText")}}{{getMedia "selectionText"}}{{/if~}}
{{/inline}}
{{=======}}
{{#*inline "selection-text"}}
{{~#if (hasMedia "selectionText")}}{{{getMedia "selectionText"}}}{{/if~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,59 +0,0 @@
{{<<<<<<<}}
{{~#*inline "glossary"~}}
<div style="text-align: left;">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#if (op ">" definition.definitions.length 1)~}}
<ol>{{~#each definition.definitions~}}<li>{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}</li>{{~/each~}}</ol>
{{~else~}}
{{~#each definition.definitions~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/each~}}
{{~/if~}}
{{~else if (op "===" definition.type "kanji")~}}
{{~#if (op ">" definition.glossary.length 1)~}}
<ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
{{~else~}}
{{~#each definition.glossary~}}{{.}}{{~/each~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}
{{=======}}
{{~#*inline "glossary"~}}
<div style="text-align: left;">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~#unless (op "&&" selectedDictionary (op "!=" selectedDictionary definition.dictionary))~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~/unless~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#if (op ">" definition.definitions.length 1)~}}
<ol>
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
<li>
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
</li>
{{~/unless~}}
{{~/each~}}
</ol>
{{~else~}}
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
{{~/unless~}}
{{~/each~}}
{{~/if~}}
{{~else if (op "===" definition.type "kanji")~}}
{{~#if (op ">" definition.glossary.length 1)~}}
<ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
{{~else~}}
{{~#each definition.glossary~}}{{.}}{{~/each~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}
{{>>>>>>>}}

View File

@@ -1,33 +0,0 @@
{{<<<<<<<}}
{{#*inline "glossary-brief"}}
{{~> glossary brief=true ~}}
{{/inline}}
{{=======}}
{{#*inline "glossary-brief"}}
{{~> glossary brief=true ~}}
{{/inline}}
{{~#*inline "glossary-first"~}}
<div style="text-align: left;">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#if (op ">" definition.definitions.length 1)~}}
{{~#with definition.definitions.[0]~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/with~}}
{{~else~}}
{{~#with definition.definitions.[0]~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/with~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}
{{#*inline "glossary-first-no-dictionary"}}
{{~> glossary-first noDictionaryTag=true ~}}
{{/inline}}
{{#*inline "glossary-first-brief"}}
{{~> glossary-first brief=true ~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,3 +0,0 @@
{{#*inline "onyomi-hiragana"}}
{{~#each definition.onyomi}}{{hiragana .}}{{#unless @last}}, {{/unless}}{{/each~}}
{{/inline}}

View File

@@ -1,33 +0,0 @@
{{<<<<<<<}}
{{#*inline "pitch-accent-list"}}
{{~#if (op ">" pitchCount 0)~}}
{{~#if (op ">" pitchCount 1)~}}<ol>{{~/if~}}
{{~#each pitches~}}
{{~#each pitches~}}
{{~#if (op ">" ../../pitchCount 1)~}}<li>{{~/if~}}
{{~> pitch-accent-item-disambiguation~}}
{{~> pitch-accent-item format=../../format~}}
{{~#if (op ">" ../../pitchCount 1)~}}</li>{{~/if~}}
{{~/each~}}
{{~/each~}}
{{~#if (op ">" pitchCount 1)~}}</ol>{{~/if~}}
{{~else~}}
No pitch accent data
{{~/if~}}
{{/inline}}
{{=======}}
{{#*inline "pitch-accent-list"}}
{{~#if (op ">" pitchCount 0)~}}
{{~#if (op ">" pitchCount 1)~}}<ol>{{~/if~}}
{{~#each pitches~}}
{{~#each pitches~}}
{{~#if (op ">" ../../pitchCount 1)~}}<li>{{~/if~}}
{{~> pitch-accent-item-disambiguation~}}
{{~> pitch-accent-item format=../../format~}}
{{~#if (op ">" ../../pitchCount 1)~}}</li>{{~/if~}}
{{~/each~}}
{{~/each~}}
{{~#if (op ">" pitchCount 1)~}}</ol>{{~/if~}}
{{~/if~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,43 +0,0 @@
{{<<<<<<<}}
{{#*inline "conjugation"}}
{{~#if (op ">" definition.inflectionRuleChainCandidates.length 0)~}}
{{~set "multiple" false~}}
{{~#if (op ">" definition.inflectionRuleChainCandidates.length 1)~}}
{{~set "multiple" true~}}
{{~/if~}}
{{~#if (get "multiple")~}}<ul>{{/if~}}
{{~#each definition.inflectionRuleChainCandidates~}}
{{~#if (op ">" inflectionRules.length 0)~}}
{{~#if (get "multiple")~}}<li>{{/if~}}
{{~#each inflectionRules~}}
{{~#if (op ">" @index 0)}} « {{/if~}}
{{.}}
{{~/each~}}
{{~#if (get "multiple")~}}</li>{{/if~}}
{{~/if~}}
{{~/each~}}
{{~#if (get "multiple")~}}</ul>{{/if~}}
{{~/if~}}
{{/inline}}
{{=======}}
{{#*inline "conjugation"}}
{{~#if (op ">" definition.inflectionRuleChainCandidates.length 0)~}}
{{~set "multiple" false~}}
{{~#if (op ">" definition.inflectionRuleChainCandidates.length 1)~}}
{{~set "multiple" true~}}
{{~/if~}}
{{~#if (get "multiple")~}}<ul>{{/if~}}
{{~#each definition.inflectionRuleChainCandidates~}}
{{~#if (op ">" inflectionRules.length 0)~}}
{{~#if (get "multiple")~}}<li>{{/if~}}
{{~#each inflectionRules~}}
{{~#if (op ">" @index 0)}} « {{/if~}}
{{name}}
{{~/each~}}
{{~#if (get "multiple")~}}</li>{{/if~}}
{{~/if~}}
{{~/each~}}
{{~#if (get "multiple")~}}</ul>{{/if~}}
{{~/if~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,9 +0,0 @@
{{#*inline "clipboard-image"}}
{{~#if definition.clipboardImageFileName~}}
<img src="{{definition.clipboardImageFileName}}" />
{{~/if~}}
{{/inline}}
{{#*inline "clipboard-text"}}
{{~#if definition.clipboardText~}}{{definition.clipboardText}}{{~/if~}}
{{/inline}}

View File

@@ -1,129 +0,0 @@
{{<<<<<<<}}
{{~#*inline "glossary"~}}
<div style="text-align: left;">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~#unless (op "&&" selectedDictionary (op "!=" selectedDictionary definition.dictionary))~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~/unless~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#if (op ">" definition.definitions.length 1)~}}
<ol>
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
<li>
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
</li>
{{~/unless~}}
{{~/each~}}
</ol>
{{~else~}}
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
{{~/unless~}}
{{~/each~}}
{{~/if~}}
{{~else if (op "===" definition.type "kanji")~}}
{{~#if (op ">" definition.glossary.length 1)~}}
<ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
{{~else~}}
{{~#each definition.glossary~}}{{.}}{{~/each~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}
{{=======}}
{{~#*inline "glossary"~}}
<div style="text-align: left;" class="yomitan-glossary">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~#unless (op "&&" selectedDictionary (op "!=" selectedDictionary definition.dictionary))~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~#if definition.glossaryScopedStyles~}}
<style>{{{definition.glossaryScopedStyles}}}</style>
{{~/if~}}
{{~/unless~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#if (op ">" definition.definitions.length 1)~}}
<ol>
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
<li data-dictionary="{{dictionary}}">
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
</li>
{{~#if dictScopedStyles~}}
<style>{{{dictScopedStyles}}}</style>
{{~/if~}}
{{~/unless~}}
{{~/each~}}
</ol>
{{~else~}}
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
{{~#if glossaryScopedStyles~}}
<style>{{{glossaryScopedStyles}}}</style>
{{~/if~}}
{{~/unless~}}
{{~/each~}}
{{~/if~}}
{{~else if (op "===" definition.type "kanji")~}}
{{~#if (op ">" definition.glossary.length 1)~}}
<ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
{{~else~}}
{{~#each definition.glossary~}}{{.}}{{~/each~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}
{{>>>>>>>}}
{{<<<<<<<}}
{{~#*inline "glossary-first"~}}
<div style="text-align: left;">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#if (op ">" definition.definitions.length 1)~}}
{{~#with definition.definitions.[0]~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/with~}}
{{~else~}}
{{~#with definition.definitions.[0]~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/with~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}
{{=======}}
{{~#*inline "glossary-first"~}}
<div style="text-align: left;" class="yomitan-glossary">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~#if definition.glossaryScopedStyles~}}
<style>{{{definition.glossaryScopedStyles}}}</style>
{{~/if~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#if (op ">" definition.definitions.length 1)~}}
{{~#with definition.definitions.[0]~}}
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
{{~#if glossaryScopedStyles~}}
<style>{{{glossaryScopedStyles}}}</style>
{{~/if~}}
{{~/with~}}
{{~else~}}
{{~#with definition.definitions.[0]~}}
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
{{~#if glossaryScopedStyles~}}
<style>{{{glossaryScopedStyles}}}</style>
{{~/if~}}
{{~/with~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}
{{>>>>>>>}}

View File

@@ -1,9 +0,0 @@
{{<<<<<<<}}
{{#*inline "selection-text"}}
{{~#if (hasMedia "selectionText")}}{{{getMedia "selectionText"}}}{{/if~}}
{{/inline}}
{{=======}}
{{#*inline "popup-selection-text"}}
{{~#if (hasMedia "popupSelectionText")}}{{{getMedia "popupSelectionText"}}}{{/if~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,115 +0,0 @@
{{<<<<<<<}}
{{#*inline "glossary-single"}}
{{~#unless brief~}}
{{~#scope~}}
{{~set "any" false~}}
{{~#each definitionTags~}}
{{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{name}}
{{~set "any" true~}}
{{~/if~}}
{{~/each~}}
{{~#unless noDictionaryTag~}}
{{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{dictionary}}
{{~set "any" true~}}
{{~/if~}}
{{~/unless~}}
{{~#if (get "any")}})</i> {{/if~}}
{{~/scope~}}
{{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
{{~/unless~}}
{{~#if (op "<=" glossary.length 1)~}}
{{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}}
{{~else if @root.compactGlossaries~}}
{{#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each}}
{{~else~}}
<ul>{{#each glossary}}<li>{{formatGlossary ../dictionary .}}</li>{{/each}}</ul>
{{~/if~}}
{{~set "previousDictionary" dictionary~}}
{{/inline}}
{{=======}}
{{#*inline "glossary-single"}}
{{~#unless brief~}}
{{~#scope~}}
{{~set "any" false~}}
{{~#each definitionTags~}}
{{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{name}}
{{~set "any" true~}}
{{~/if~}}
{{~/each~}}
{{~#unless noDictionaryTag~}}
{{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{dictionaryAlias}}
{{~set "any" true~}}
{{~/if~}}
{{~/unless~}}
{{~#if (get "any")}})</i> {{/if~}}
{{~/scope~}}
{{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
{{~/unless~}}
{{~#if (op "<=" glossary.length 1)~}}
{{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}}
{{~else if @root.compactGlossaries~}}
{{#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each}}
{{~else~}}
<ul>{{#each glossary}}<li>{{formatGlossary ../dictionary .}}</li>{{/each}}</ul>
{{~/if~}}
{{~set "previousDictionary" dictionary~}}
{{/inline}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#*inline "dictionary"}}
{{~definition.dictionary~}}
{{/inline}}
{{=======}}
{{#*inline "dictionary"}}
{{~definition.dictionary~}}
{{/inline}}
{{#*inline "dictionary-alias"}}
{{~definition.dictionaryAlias~}}
{{/inline}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#*inline "frequencies"}}
{{~#if (op ">" definition.frequencies.length 0)~}}
<ul style="text-align: left;">
{{~#each definition.frequencies~}}
<li>
{{~#if (op "!==" ../definition.type "kanji")~}}
{{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
{{~furigana expression reading~}}
) {{/if~}}
{{~/if~}}
{{~dictionary}}: {{frequency~}}
</li>
{{~/each~}}
</ul>
{{~/if~}}
{{/inline}}
{{=======}}
{{#*inline "frequencies"}}
{{~#if (op ">" definition.frequencies.length 0)~}}
<ul style="text-align: left;">
{{~#each definition.frequencies~}}
<li>
{{~#if (op "!==" ../definition.type "kanji")~}}
{{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
{{~furigana expression reading~}}
) {{/if~}}
{{~/if~}}
{{~dictionaryAlias}}: {{frequency~}}
</li>
{{~/each~}}
</ul>
{{~/if~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,25 +0,0 @@
{{#*inline "conjugation"}}
{{~#if definition.reasons~}}
{{~#each definition.reasons~}}
{{~#if (op ">" @index 0)}} « {{/if~}}
{{.}}
{{~/each~}}
{{~/if~}}
{{/inline}}
{{#*inline "frequencies"}}
{{~#if (op ">" definition.frequencies.length 0)~}}
<ul style="text-align: left;">
{{~#each definition.frequencies~}}
<li>
{{~#if (op "!==" ../definition.type "kanji")~}}
{{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
{{~#furigana expression reading~}}{{~/furigana~}}
) {{/if~}}
{{~/if~}}
{{~dictionary}}: {{frequency~}}
</li>
{{~/each~}}
</ul>
{{~/if~}}
{{/inline}}

View File

@@ -1,9 +0,0 @@
{{#*inline "sentence-furigana-plain"}}
{{~#if definition.cloze~}}
{{~#if (hasMedia "textFuriganaPlain" definition.cloze.sentence)~}}
{{{getMedia "textFuriganaPlain" definition.cloze.sentence escape=false}}}
{{~else~}}
{{{definition.cloze.sentence}}}
{{~/if~}}
{{~/if~}}
{{/inline}}

View File

@@ -1,43 +0,0 @@
{{<<<<<<<}}
{{#*inline "phonetic-transcriptions"}}
{{~#if (op ">" definition.phoneticTranscriptions.length 0)~}}
<ul>
{{~#each definition.phoneticTranscriptions~}}
{{~#each phoneticTranscriptions~}}
<li>
{{~set "any" false~}}
{{~#each tags~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{name}}
{{~set "any" true~}}
{{~/each~}}
{{~#if (get "any")}})</i> {{/if~}}
{{ipa~}}
</li>
{{~/each~}}
{{~/each~}}
</ul>
{{~/if~}}
{{/inline}}
{{=======}}
{{#*inline "phonetic-transcriptions"}}
{{~#if (op ">" definition.phoneticTranscriptions.length 0)~}}
<ul>
{{~#each definition.phoneticTranscriptions~}}
{{~#each phoneticTranscriptions~}}
<li class="pronunciation" data-pronunciation-type="phonetic-transcription">
{{~set "any" false~}}
{{~#each tags~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
<span class="tag" data-details="{{name}}">{{name}}</span>
{{~set "any" true~}}
{{~/each~}}
{{~#if (get "any")}})</i> {{/if~}}
{{ipa~}}
</li>
{{~/each~}}
{{~/each~}}
</ul>
{{~/if~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,69 +0,0 @@
{{<<<<<<<}}
{{#*inline "expression"}}
{{~#if merge~}}
{{~#if modeTermKana~}}
{{~#each definition.reading~}}
{{{.}}}
{{~#unless @last}}{{/unless~}}
{{~else~}}
{{~#each definition.expression~}}
{{{.}}}
{{~#unless @last}}{{/unless~}}
{{~/each~}}
{{~/each~}}
{{~else~}}
{{~#each definition.expression~}}
{{{.}}}
{{~#unless @last}}{{/unless~}}
{{~/each~}}
{{~/if~}}
{{~else~}}
{{~#if modeTermKana~}}
{{~#if definition.reading~}}
{{definition.reading}}
{{~else~}}
{{definition.expression}}
{{~/if~}}
{{~else~}}
{{definition.expression}}
{{~/if~}}
{{~/if~}}
{{/inline}}
{{=======}}
{{#*inline "expression"}}
{{~#if merge~}}
{{~#each definition.expression~}}
{{{.}}}
{{~#unless @last}}{{/unless~}}
{{~/each~}}
{{~else~}}
{{definition.expression}}
{{~/if~}}
{{/inline}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#*inline "reading"}}
{{~#unless modeTermKana~}}
{{~#if merge~}}
{{~#each definition.reading~}}
{{{.}}}
{{~#unless @last}}{{/unless~}}
{{~/each~}}
{{~else~}}
{{~definition.reading~}}
{{~/if~}}
{{~/unless~}}
{{/inline}}
{{=======}}
{{#*inline "reading"}}
{{~#if merge~}}
{{~#each definition.reading~}}
{{{.}}}
{{~#unless @last}}{{/unless~}}
{{~/each~}}
{{~else~}}
{{~definition.reading~}}
{{~/if~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,16 +0,0 @@
{{~#*inline "glossary-plain"~}}
{{~#scope~}}
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
{{~#unless ../noDictionaryTag~}}
({{dictionaryAlias}})<br>
{{~/unless~}}
{{#each glossary}}{{{formatGlossaryPlain ../dictionary .}}}{{#unless @last}}<br>{{/unless}}{{/each}}{{#unless @last}}<br>{{/unless}}
{{~/unless~}}
{{~/each~}}
{{~/scope~}}
{{~/inline~}}
{{#*inline "glossary-plain-no-dictionary"~}}
{{~> glossary-plain noDictionaryTag=true ~}}
{{/inline}}

View File

@@ -1,47 +0,0 @@
{{<<<<<<<}}
{{#*inline "frequencies"}}
{{~#if (op ">" definition.frequencies.length 0)~}}
<ul style="text-align: left;">
{{~#each definition.frequencies~}}
<li>
{{~#if (op "!==" ../definition.type "kanji")~}}
{{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
{{~furigana expression reading~}}
) {{/if~}}
{{~/if~}}
{{~dictionaryAlias}}: {{frequency~}}
</li>
{{~/each~}}
</ul>
{{~/if~}}
{{/inline}}
{{=======}}
{{#*inline "frequencies"}}
{{~#if (op ">" definition.frequencies.length 0)~}}
<ul style="text-align: left;">
{{~#each definition.frequencies~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
<li>
{{~#if (op "!==" ../definition.type "kanji")~}}
{{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
{{~furigana expression reading~}}
) {{/if~}}
{{~/if~}}
{{~dictionaryAlias}}: {{frequency~}}
</li>
{{~/unless~}}
{{~/each~}}
</ul>
{{~/if~}}
{{/inline}}
{{>>>>>>>}}
{{#*inline "single-frequency-number"}}
{{~#if (op ">" definition.frequencyNumbers.length 0)~}}
{{~#each definition.frequencyNumbers~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
{{frequency~}}
{{~/unless~}}
{{~/each~}}
{{/if}}
{{/inline}}

View File

@@ -1,9 +0,0 @@
{{<<<<<<<}}
{{#*inline "pitch-accent-item"}}
{{~pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}
{{/inline}}
{{=======}}
{{#*inline "pitch-accent-item"}}
{{~pronunciation format=format reading=reading pitchPositions=positions nasalPositions=nasalPositions devoicePositions=devoicePositions~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,80 +0,0 @@
{{<<<<<<<}}
{{~#*inline "glossary"~}}
<div style="text-align: left;" class="yomitan-glossary">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~#unless (op "&&" selectedDictionary (op "!=" selectedDictionary definition.dictionary))~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~#if definition.glossaryScopedStyles~}}
<style>{{{definition.glossaryScopedStyles}}}</style>
{{~/if~}}
{{~/unless~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#if (op ">" definition.definitions.length 1)~}}
<ol>
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
<li data-dictionary="{{dictionary}}">
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
</li>
{{~#if dictScopedStyles~}}
<style>{{{dictScopedStyles}}}</style>
{{~/if~}}
{{~/unless~}}
{{~/each~}}
</ol>
{{~else~}}
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
{{~#if glossaryScopedStyles~}}
<style>{{{glossaryScopedStyles}}}</style>
{{~/if~}}
{{~/unless~}}
{{~/each~}}
{{~/if~}}
{{~else if (op "===" definition.type "kanji")~}}
{{~#if (op ">" definition.glossary.length 1)~}}
<ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
{{~else~}}
{{~#each definition.glossary~}}{{.}}{{~/each~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}
{{=======}}
{{~#*inline "glossary"~}}
<div style="text-align: left;" class="yomitan-glossary">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~#unless (op "&&" selectedDictionary (op "!=" selectedDictionary definition.dictionary))~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~#if definition.glossaryScopedStyles~}}
<style>{{{definition.glossaryScopedStyles}}}</style>
{{~/if~}}
{{~/unless~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
<ol>
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
<li data-dictionary="{{dictionary}}">
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
</li>
{{~#if dictScopedStyles~}}
<style>{{{dictScopedStyles}}}</style>
{{~/if~}}
{{~/unless~}}
{{~/each~}}
</ol>
{{~else if (op "===" definition.type "kanji")~}}
{{~#if (op ">" definition.glossary.length 1)~}}
<ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
{{~else~}}
{{~#each definition.glossary~}}{{.}}{{~/each~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}
{{>>>>>>>}}

View File

@@ -1,36 +0,0 @@
{{<<<<<<<}}
{{~#*inline "glossary-plain"~}}
{{~#scope~}}
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
{{~#unless ../noDictionaryTag~}}
({{dictionaryAlias}})<br>
{{~/unless~}}
{{#each glossary}}{{{formatGlossaryPlain ../dictionary .}}}{{#unless @last}}<br>{{/unless}}{{/each}}{{#unless @last}}<br>{{/unless}}
{{~/unless~}}
{{~/each~}}
{{~/scope~}}
{{~/inline~}}
{{=======}}
{{~#*inline "glossary-plain"~}}
{{~#scope~}}
{{~#if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
{{~#unless ../noDictionaryTag~}}
({{dictionaryAlias}})<br>
{{~/unless~}}
{{#each glossary}}{{{formatGlossaryPlain ../dictionary .}}}{{#unless @last}}<br>{{/unless}}{{/each}}{{#unless @last}}<br>{{/unless}}
{{~/unless~}}
{{~/each~}}
{{~else~}}
{{~#unless (op "&&" selectedDictionary (op "!=" selectedDictionary definition.dictionary))~}}
{{~#unless noDictionaryTag~}}
({{definition.dictionaryAlias}})<br>
{{~/unless~}}
{{#each definition.glossary}}{{{formatGlossaryPlain ../definition.dictionary .}}}{{/each}}
{{~/unless~}}
{{~/if~}}
{{~/scope~}}
{{~/inline~}}
{{>>>>>>>}}

View File

@@ -1,131 +0,0 @@
{{#*inline "stroke-count"}}
{{~#scope~}}
{{~#set "found" false}}{{/set~}}
{{~#each definition.stats.misc~}}
{{~#if (op "===" name "strokes")~}}
{{~#set "found" true}}{{/set~}}
Stroke count: {{value}}
{{~/if~}}
{{~/each~}}
{{~#if (op "!" (get "found"))~}}
Stroke count: Unknown
{{~/if~}}
{{~/scope~}}
{{/inline}}
{{<<<<<<<}}
{{#*inline "glossary-single"}}
{{~#unless brief~}}
{{~#scope~}}
{{~#set "any" false}}{{/set~}}
{{~#if definitionTags~}}{{#each definitionTags~}}
{{~#if (op "||" (op "!" ../data.compactTags) (op "!" redundant))~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{name}}
{{~#set "any" true}}{{/set~}}
{{~/if~}}
{{~/each~}}
{{~#if (get "any")}})</i> {{/if~}}
{{~/if~}}
{{~/scope~}}
{{~#if only~}}({{#each only}}{{{.}}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
{{~/unless~}}
{{~#if glossary.[1]~}}
{{~#if compactGlossaries~}}
{{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}}
{{~else~}}
<ul>{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}</ul>
{{~/if~}}
{{~else~}}
{{~#multiLine}}{{glossary.[0]}}{{/multiLine~}}
{{~/if~}}
{{/inline}}
{{=======}}
{{#*inline "glossary-single"}}
{{~#unless brief~}}
{{~#scope~}}
{{~#set "any" false}}{{/set~}}
{{~#each definitionTags~}}
{{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{name}}
{{~#set "any" true}}{{/set~}}
{{~/if~}}
{{~/each~}}
{{~#unless noDictionaryTag~}}
{{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{dictionary}}
{{~#set "any" true}}{{/set~}}
{{~/if~}}
{{~/unless~}}
{{~#if (get "any")}})</i> {{/if~}}
{{~/scope~}}
{{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
{{~/unless~}}
{{~#if (op "<=" glossary.length 1)~}}
{{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{/each}}
{{~else if @root.compactGlossaries~}}
{{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}}
{{~else~}}
<ul>{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}</ul>
{{~/if~}}
{{~#set "previousDictionary" dictionary~}}{{~/set~}}
{{/inline}}
{{>>>>>>>}}
{{<<<<<<<}}
{{#*inline "glossary"}}
<div style="text-align: left;">
{{~#if modeKanji~}}
{{~#if definition.glossary.[1]~}}
<ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
{{~else~}}
{{definition.glossary.[0]}}
{{~/if~}}
{{~else~}}
{{~#if group~}}
{{~#if definition.definitions.[1]~}}
<ol>{{#each definition.definitions}}<li>{{> glossary-single brief=../brief compactGlossaries=../compactGlossaries data=../.}}</li>{{/each}}</ol>
{{~else~}}
{{~> glossary-single definition.definitions.[0] brief=brief compactGlossaries=compactGlossaries data=.~}}
{{~/if~}}
{{~else if merge~}}
{{~#if definition.definitions.[1]~}}
<ol>{{#each definition.definitions}}<li>{{> glossary-single brief=../brief compactGlossaries=../compactGlossaries data=../.}}</li>{{/each}}</ol>
{{~else~}}
{{~> glossary-single definition.definitions.[0] brief=brief compactGlossaries=compactGlossaries data=.~}}
{{~/if~}}
{{~else~}}
{{~> glossary-single definition brief=brief compactGlossaries=compactGlossaries data=.~}}
{{~/if~}}
{{~/if~}}
</div>
{{/inline}}
{{=======}}
{{~#*inline "glossary"~}}
<div style="text-align: left;">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#if (op ">" definition.definitions.length 1)~}}
<ol>{{~#each definition.definitions~}}<li>{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}</li>{{~/each~}}</ol>
{{~else~}}
{{~#each definition.definitions~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/each~}}
{{~/if~}}
{{~else if (op "===" definition.type "kanji")~}}
{{~#if (op ">" definition.glossary.length 1)~}}
<ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
{{~else~}}
{{~#each definition.glossary~}}{{.}}{{~/each~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}
{{#*inline "glossary-no-dictionary"}}
{{~> glossary noDictionaryTag=true ~}}
{{/inline}}
{{>>>>>>>}}

View File

@@ -1,490 +0,0 @@
{{#*inline "glossary-single"}}
{{~#unless brief~}}
{{~#scope~}}
{{~set "any" false~}}
{{~#each definitionTags~}}
{{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{name}}
{{~set "any" true~}}
{{~/if~}}
{{~/each~}}
{{~#unless noDictionaryTag~}}
{{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{dictionaryAlias}}
{{~set "any" true~}}
{{~/if~}}
{{~/unless~}}
{{~#if (get "any")}})</i> {{/if~}}
{{~/scope~}}
{{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
{{~/unless~}}
{{~#if (op "<=" glossary.length 1)~}}
{{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}}
{{~else if @root.compactGlossaries~}}
{{#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each}}
{{~else~}}
<ul>{{#each glossary}}<li>{{formatGlossary ../dictionary .}}</li>{{/each}}</ul>
{{~/if~}}
{{~set "previousDictionary" dictionary~}}
{{/inline}}
{{#*inline "audio"}}
{{~#if (hasMedia "audio")~}}
[sound:{{getMedia "audio"}}]
{{~/if~}}
{{/inline}}
{{#*inline "character"}}
{{~definition.character~}}
{{/inline}}
{{#*inline "dictionary"}}
{{~definition.dictionary~}}
{{/inline}}
{{#*inline "dictionary-alias"}}
{{~definition.dictionaryAlias~}}
{{/inline}}
{{#*inline "expression"}}
{{~#if merge~}}
{{~#each definition.expression~}}
{{{.}}}
{{~#unless @last}}{{/unless~}}
{{~/each~}}
{{~else~}}
{{definition.expression}}
{{~/if~}}
{{/inline}}
{{#*inline "furigana"}}
{{~#if merge~}}
{{~#each definition.expressions~}}
<span class="expression-{{termFrequency}}">{{~furigana .~}}</span>
{{~#unless @last}}{{/unless~}}
{{~/each~}}
{{~else~}}
{{furigana definition}}
{{~/if~}}
{{/inline}}
{{#*inline "furigana-plain"}}
{{~#if merge~}}
{{~#each definition.expressions~}}
<span class="expression-{{termFrequency}}">{{~furiganaPlain .~}}</span>
{{~#unless @last}}{{/unless~}}
{{~/each~}}
{{~else~}}
{{furiganaPlain definition}}
{{~/if~}}
{{/inline}}
{{~#*inline "glossary"~}}
<div style="text-align: left;" class="yomitan-glossary">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~#unless (op "&&" selectedDictionary (op "!=" selectedDictionary definition.dictionary))~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~#if definition.glossaryScopedStyles~}}
<style>{{{definition.glossaryScopedStyles}}}</style>
{{~/if~}}
{{~/unless~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
<ol>
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
<li data-dictionary="{{dictionary}}">
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
</li>
{{~#if dictScopedStyles~}}
<style>{{{dictScopedStyles}}}</style>
{{~/if~}}
{{~/unless~}}
{{~/each~}}
</ol>
{{~else if (op "===" definition.type "kanji")~}}
{{~#if (op ">" definition.glossary.length 1)~}}
<ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
{{~else~}}
{{~#each definition.glossary~}}{{.}}{{~/each~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}
{{#*inline "glossary-no-dictionary"}}
{{~> glossary noDictionaryTag=true ~}}
{{/inline}}
{{#*inline "glossary-brief"}}
{{~> glossary brief=true ~}}
{{/inline}}
{{~#*inline "glossary-plain"~}}
{{~#scope~}}
{{~#if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#each definition.definitions~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
{{~#unless ../noDictionaryTag~}}
({{dictionaryAlias}})<br>
{{~/unless~}}
{{#each glossary}}{{{formatGlossaryPlain ../dictionary .}}}{{#unless @last}}<br>{{/unless}}{{/each}}{{#unless @last}}<br>{{/unless}}
{{~/unless~}}
{{~/each~}}
{{~else~}}
{{~#unless (op "&&" selectedDictionary (op "!=" selectedDictionary definition.dictionary))~}}
{{~#unless noDictionaryTag~}}
({{definition.dictionaryAlias}})<br>
{{~/unless~}}
{{#each definition.glossary}}{{{formatGlossaryPlain ../definition.dictionary .}}}{{/each}}
{{~/unless~}}
{{~/if~}}
{{~/scope~}}
{{~/inline~}}
{{#*inline "glossary-plain-no-dictionary"~}}
{{~> glossary-plain noDictionaryTag=true ~}}
{{/inline}}
{{~#*inline "glossary-first"~}}
<div style="text-align: left;" class="yomitan-glossary">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~#if definition.glossaryScopedStyles~}}
<style>{{{definition.glossaryScopedStyles}}}</style>
{{~/if~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#if (op ">" definition.definitions.length 1)~}}
{{~#with definition.definitions.[0]~}}
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
{{~#if glossaryScopedStyles~}}
<style>{{{glossaryScopedStyles}}}</style>
{{~/if~}}
{{~/with~}}
{{~else~}}
{{~#with definition.definitions.[0]~}}
{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}
{{~#if glossaryScopedStyles~}}
<style>{{{glossaryScopedStyles}}}</style>
{{~/if~}}
{{~/with~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}
{{#*inline "glossary-first-no-dictionary"}}
{{~> glossary-first noDictionaryTag=true ~}}
{{/inline}}
{{#*inline "glossary-first-brief"}}
{{~> glossary-first brief=true ~}}
{{/inline}}
{{#*inline "kunyomi"}}
{{~#each definition.kunyomi}}{{.}}{{#unless @last}}, {{/unless}}{{/each~}}
{{/inline}}
{{#*inline "onyomi"}}
{{~#each definition.onyomi}}{{.}}{{#unless @last}}, {{/unless}}{{/each~}}
{{/inline}}
{{#*inline "onyomi-hiragana"}}
{{~#each definition.onyomi}}{{hiragana .}}{{#unless @last}}, {{/unless}}{{/each~}}
{{/inline}}
{{#*inline "reading"}}
{{~#if merge~}}
{{~#each definition.reading~}}
{{{.}}}
{{~#unless @last}}{{/unless~}}
{{~/each~}}
{{~else~}}
{{~definition.reading~}}
{{~/if~}}
{{/inline}}
{{#*inline "sentence"}}
{{~#if definition.cloze}}{{{definition.cloze.sentence}}}{{/if~}}
{{/inline}}
{{#*inline "cloze-prefix"}}
{{~#if definition.cloze}}{{{definition.cloze.prefix}}}{{/if~}}
{{/inline}}
{{#*inline "cloze-body"}}
{{~#if definition.cloze}}{{{definition.cloze.body}}}{{/if~}}
{{/inline}}
{{#*inline "cloze-body-kana"}}
{{~#if definition.cloze}}{{{definition.cloze.bodyKana}}}{{/if~}}
{{/inline}}
{{#*inline "cloze-suffix"}}
{{~#if definition.cloze}}{{{definition.cloze.suffix}}}{{/if~}}
{{/inline}}
{{#*inline "tags"}}
{{~#mergeTags definition group merge}}{{this}}{{/mergeTags~}}
{{/inline}}
{{~#*inline "url"~}}
<a href="{{definition.url}}">{{definition.url}}</a>
{{~/inline~}}
{{#*inline "screenshot"}}
{{~#if (hasMedia "screenshot")~}}
<img src="{{getMedia "screenshot"}}" />
{{~/if~}}
{{/inline}}
{{#*inline "document-title"}}
{{~context.document.title~}}
{{/inline}}
{{! Pitch Accents }}
{{#*inline "pitch-accent-item"}}
{{~pronunciation format=format reading=reading pitchPositions=positions nasalPositions=nasalPositions devoicePositions=devoicePositions~}}
{{/inline}}
{{#*inline "pitch-accent-item-disambiguation"}}
{{~#scope~}}
{{~set "exclusive" (spread exclusiveExpressions exclusiveReadings)~}}
{{~#if (op ">" (property (get "exclusive") "length") 0)~}}
{{~set "separator" ""~}}
<em>({{#each (get "exclusive")~}}
{{~get "separator"~}}{{{.}}}
{{~/each}} only) </em>
{{~/if~}}
{{~/scope~}}
{{/inline}}
{{#*inline "pitch-accent-list"}}
{{~#if (op ">" pitchCount 0)~}}
{{~#if (op ">" pitchCount 1)~}}<ol>{{~/if~}}
{{~#each pitches~}}
{{~#each pitches~}}
{{~#if (op ">" ../../pitchCount 1)~}}<li>{{~/if~}}
{{~> pitch-accent-item-disambiguation~}}
{{~> pitch-accent-item format=../../format~}}
{{~#if (op ">" ../../pitchCount 1)~}}</li>{{~/if~}}
{{~/each~}}
{{~/each~}}
{{~#if (op ">" pitchCount 1)~}}</ol>{{~/if~}}
{{~/if~}}
{{/inline}}
{{#*inline "pitch-accents"}}
{{~> pitch-accent-list format='text'~}}
{{/inline}}
{{#*inline "pitch-accent-graphs"}}
{{~> pitch-accent-list format='graph'~}}
{{/inline}}
{{#*inline "pitch-accent-graphs-jj"}}
{{~> pitch-accent-list format='graph-jj'~}}
{{/inline}}
{{#*inline "pitch-accent-positions"}}
{{~> pitch-accent-list format='position'~}}
{{/inline}}
{{~#*inline "pitch-accent-categories"~}}
{{~#each (pitchCategories @root)~}}{{~.~}}{{~#unless @last~}},{{~/unless~}}{{~/each~}}
{{~/inline~}}
{{! End Pitch Accents }}
{{#*inline "phonetic-transcriptions"}}
{{~#if (op ">" definition.phoneticTranscriptions.length 0)~}}
<ul>
{{~#each definition.phoneticTranscriptions~}}
{{~#each phoneticTranscriptions~}}
<li class="pronunciation" data-pronunciation-type="phonetic-transcription">
{{~set "any" false~}}
{{~#each tags~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
<span class="tag" data-details="{{name}}">{{name}}</span>
{{~set "any" true~}}
{{~/each~}}
{{~#if (get "any")}})</i> {{/if~}}
{{ipa~}}
</li>
{{~/each~}}
{{~/each~}}
</ul>
{{~/if~}}
{{/inline}}
{{#*inline "clipboard-image"}}
{{~#if (hasMedia "clipboardImage")~}}
<img src="{{getMedia "clipboardImage"}}" />
{{~/if~}}
{{/inline}}
{{#*inline "clipboard-text"}}
{{~#if (hasMedia "clipboardText")}}{{{getMedia "clipboardText"}}}{{/if~}}
{{/inline}}
{{#*inline "conjugation"}}
{{~#if (op ">" definition.inflectionRuleChainCandidates.length 0)~}}
{{~set "multiple" false~}}
{{~#if (op ">" definition.inflectionRuleChainCandidates.length 1)~}}
{{~set "multiple" true~}}
{{~/if~}}
{{~#if (get "multiple")~}}<ul>{{/if~}}
{{~#each definition.inflectionRuleChainCandidates~}}
{{~#if (op ">" inflectionRules.length 0)~}}
{{~#if (get "multiple")~}}<li>{{/if~}}
{{~#each inflectionRules~}}
{{~#if (op ">" @index 0)}} « {{/if~}}
{{name}}
{{~/each~}}
{{~#if (get "multiple")~}}</li>{{/if~}}
{{~/if~}}
{{~/each~}}
{{~#if (get "multiple")~}}</ul>{{/if~}}
{{~/if~}}
{{/inline}}
{{#*inline "frequencies"}}
{{~#if (op ">" definition.frequencies.length 0)~}}
<ul style="text-align: left;">
{{~#each definition.frequencies~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
<li>
{{~#if (op "!==" ../definition.type "kanji")~}}
{{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
{{~furigana expression reading~}}
) {{/if~}}
{{~/if~}}
{{~dictionaryAlias}}: {{frequency~}}
</li>
{{~/unless~}}
{{~/each~}}
</ul>
{{~/if~}}
{{/inline}}
{{#*inline "single-frequency-number"}}
{{~#if (op ">" definition.frequencyNumbers.length 0)~}}
{{~#each definition.frequencyNumbers~}}
{{~#unless (op "&&" ../selectedDictionary (op "!=" ../selectedDictionary dictionary))~}}
{{frequency~}}
{{~/unless~}}
{{~/each~}}
{{/if}}
{{/inline}}
{{#*inline "frequency-harmonic-rank"}}
{{~#if (op "===" definition.frequencyHarmonic -1) ~}}
9999999
{{~else ~}}
{{definition.frequencyHarmonic}}
{{~/if~}}
{{/inline}}
{{#*inline "frequency-harmonic-occurrence"}}
{{~#if (op "===" definition.frequencyHarmonic -1) ~}}
0
{{~else ~}}
{{definition.frequencyHarmonic}}
{{~/if~}}
{{/inline}}
{{#*inline "frequency-average-rank"}}
{{~#if (op "===" definition.frequencyAverage -1) ~}}
9999999
{{~else ~}}
{{definition.frequencyAverage}}
{{~/if~}}
{{/inline}}
{{#*inline "frequency-average-occurrence"}}
{{~#if (op "===" definition.frequencyAverage -1) ~}}
0
{{~else ~}}
{{definition.frequencyAverage}}
{{~/if~}}
{{/inline}}
{{#*inline "stroke-count"}}
{{~#scope~}}
{{~set "found" false~}}
{{~#each definition.stats.misc~}}
{{~#if (op "===" name "strokes")~}}
{{~set "found" true~}}
Stroke count: {{value}}
{{~/if~}}
{{~/each~}}
{{~#if (op "!" (get "found"))~}}
Stroke count: Unknown
{{~/if~}}
{{~/scope~}}
{{/inline}}
{{#*inline "part-of-speech-pretty"}}
{{~#if (op "===" . "v1")~}}Ichidan verb
{{~else if (op "===" . "v5")~}}Godan verb
{{~else if (op "===" . "vk")~}}Kuru verb
{{~else if (op "===" . "vs")~}}Suru verb
{{~else if (op "===" . "vz")~}}Zuru verb
{{~else if (op "===" . "adj-i")~}}I-adjective
{{~else if (op "===" . "n")~}}Noun
{{~else~}}{{.}}
{{~/if~}}
{{/inline}}
{{#*inline "part-of-speech"}}
{{~#scope~}}
{{~#if (op "!==" definition.type "kanji")~}}
{{~set "first" true~}}
{{~#each definition.expressions~}}
{{~#each wordClasses~}}
{{~#unless (get (concat "used_" .))~}}
{{~> part-of-speech-pretty . ~}}
{{~#unless (get "first")}}, {{/unless~}}
{{~set (concat "used_" .) true~}}
{{~set "first" false~}}
{{~/unless~}}
{{~/each~}}
{{~/each~}}
{{~#if (get "first")~}}Unknown{{~/if~}}
{{~/if~}}
{{~/scope~}}
{{/inline}}
{{#*inline "search-query"}}
{{~#multiLine}}{{context.fullQuery}}{{/multiLine~}}
{{/inline}}
{{#*inline "popup-selection-text"}}
{{~#if (hasMedia "popupSelectionText")}}{{{getMedia "popupSelectionText"}}}{{/if~}}
{{/inline}}
{{#*inline "sentence-furigana"}}
{{~#if definition.cloze~}}
{{~#if (hasMedia "textFurigana" definition.cloze.sentence)~}}
{{{getMedia "textFurigana" definition.cloze.sentence escape=false}}}
{{~else~}}
{{{definition.cloze.sentence}}}
{{~/if~}}
{{~/if~}}
{{/inline}}
{{#*inline "sentence-furigana-plain"}}
{{~#if definition.cloze~}}
{{~#if (hasMedia "textFuriganaPlain" definition.cloze.sentence)~}}
{{{getMedia "textFuriganaPlain" definition.cloze.sentence escape=false}}}
{{~else~}}
{{{definition.cloze.sentence}}}
{{~/if~}}
{{~/if~}}
{{/inline}}
{{~> (lookup . "marker") ~}}

Binary file not shown.

View File

@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M8 1a1.5 1.5 0 00-1.5 1.5A1.5 1.5 0 008 4a1.5 1.5 0 001.5-1.5A1.5 1.5 0 008 1zM2.9297 4.002c-.43218.03031-.79568.33547-.90039.75586-.13403.53615.19225 1.0794.72852 1.2129l3.2422.81055s-.0117 2.2112-.25 3.2773c-.28252 1.2639-1.4043 3.5156-1.4043 3.5156-.23487.49944-.0207 1.0947.47852 1.3301.49944.23487 1.0947.0207 1.3301-.47852l1.8457-3.9219 1.8457 3.9219c.23534.49922.83063.71338 1.3301.47852.49922-.23534.71338-.83064.47852-1.3301 0 0-1.1218-2.2517-1.4043-3.5156-.23831-1.0661-.25-3.2773-.25-3.2773l3.2422-.81055c.53627-.13354.86254-.67675.72852-1.2129-.10471-.42039-.46821-.72555-.90039-.75586a1.00016 1.00016 0 00-.3125.02734s-2.5587.5577-3.8828.7207c-.57896.07128-1.171.07128-1.75 0-1.3241-.163-3.8828-.7207-3.8828-.7207a.99999.99999 0 00-.3125-.02734z"/></svg>

Before

Width:  |  Height:  |  Size: 877 B

View File

@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="inner-fill" x1="-1.7198" x2="-1.7198" y1="3.5719" y2=".79375" gradientTransform="matrix(3.7795 0 0 3.7795 14.5 -6.308e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#6fb558" offset="0"/>
<stop stop-color="#a5db9b" offset="1"/>
</linearGradient>
<linearGradient id="outer-rim" x1="7.5406" x2="5.1594" y1="3.3073" y2=".92604" gradientTransform="matrix(3.7795 0 0 3.7795 -16 -6e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#34812c" offset="0"/>
<stop stop-color="#87b870" offset="1"/>
</linearGradient>
<radialGradient id="center-shadow" cx="2.1167" cy="2.1167" r=".66146" gradientTransform="matrix(4.5354 8.0301e-7 -8.0301e-7 4.5354 -1.6 -1.6)" gradientUnits="userSpaceOnUse">
<stop stop-opacity=".28986" offset="0"/>
<stop stop-opacity="0" offset="1"/>
</radialGradient>
<filter id="green-to-blue" x="-.038462" y="-.038462" width="1.0769" height="1.0769" color-interpolation-filters="sRGB">
<feColorMatrix type="hueRotate" values="105"/>
<feColorMatrix type="saturate" values="1"/>
<feColorMatrix type="hueRotate" values="0"/>
</filter>
<symbol id="plus-in-circle" viewBox="0 0 16 16">
<circle cx="8" cy="8" r="6.5" fill="url(#inner-fill)"/>
<circle cx="8" cy="8" r="5.75" fill="none" stroke="#fff" stroke-opacity=".50196" stroke-width="1.5"/>
<circle cx="8" cy="8" r="6.5" fill="none" stroke="url(#outer-rim)"/>
<circle cx="8" cy="8" r="3" fill="url(#center-shadow)"/>
<path d="m5 7h2v-2h2v2h2v2h-2v2h-2v-2h-2v-2" fill="#fff"/>
</symbol>
</defs>
<g transform="matrix(.91504 0 0 .91504 2.2745 -.91504)" filter="url(#green-to-blue)">
<use xlink:href="#plus-in-circle"/>
</g>
<g transform="matrix(.91504 0 0 .91504 -.91504 2.2745)" filter="url(#green-to-blue)">
<use xlink:href="#plus-in-circle"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="inner-fill" x1="-1.7198" x2="-1.7198" y1="3.5719" y2=".79375" gradientTransform="matrix(3.7795 0 0 3.7795 14.5 -6.308e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#6fb558" offset="0"/>
<stop stop-color="#a5db9b" offset="1"/>
</linearGradient>
<linearGradient id="outer-rim" x1="7.5406" x2="5.1594" y1="3.3073" y2=".92604" gradientTransform="matrix(3.7795 0 0 3.7795 -16 -6e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#34812c" offset="0"/>
<stop stop-color="#87b870" offset="1"/>
</linearGradient>
<radialGradient id="center-shadow" cx="2.1167" cy="2.1167" r=".66146" gradientTransform="matrix(4.5354 8.0301e-7 -8.0301e-7 4.5354 -1.6 -1.6)" gradientUnits="userSpaceOnUse">
<stop stop-opacity=".28986" offset="0"/>
<stop stop-opacity="0" offset="1"/>
</radialGradient>
<filter id="green-to-purple" x="-.038462" y="-.038462" width="1.0769" height="1.0769" color-interpolation-filters="sRGB">
<feColorMatrix type="hueRotate" values="180"/>
<feColorMatrix type="saturate" values="1"/>
<feColorMatrix type="hueRotate" values="0"/>
</filter>
<symbol id="plus-in-circle" viewBox="0 0 16 16">
<circle cx="8" cy="8" r="6.5" fill="url(#inner-fill)"/>
<circle cx="8" cy="8" r="5.75" fill="none" stroke="#fff" stroke-opacity=".50196" stroke-width="1.5"/>
<circle cx="8" cy="8" r="6.5" fill="none" stroke="url(#outer-rim)"/>
<circle cx="8" cy="8" r="3" fill="url(#center-shadow)"/>
<path d="m5 7h2v-2h2v2h2v2h-2v2h-2v-2h-2v-2" fill="#fff"/>
</symbol>
</defs>
<g transform="matrix(.91504 0 0 .91504 2.2745 -.91504)" filter="url(#green-to-purple)">
<use xlink:href="#plus-in-circle"/>
</g>
<g transform="matrix(.91504 0 0 .91504 -.91504 2.2745)" filter="url(#green-to-purple)">
<use xlink:href="#plus-in-circle"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="inner-fill" x1="-1.7198" x2="-1.7198" y1="3.5719" y2=".79375" gradientTransform="matrix(3.7795 0 0 3.7795 14.5 -6.308e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#6fb558" offset="0"/>
<stop stop-color="#a5db9b" offset="1"/>
</linearGradient>
<linearGradient id="outer-rim" x1="7.5406" x2="5.1594" y1="3.3073" y2=".92604" gradientTransform="matrix(3.7795 0 0 3.7795 -16 -6e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#34812c" offset="0"/>
<stop stop-color="#87b870" offset="1"/>
</linearGradient>
<radialGradient id="center-shadow" cx="2.1167" cy="2.1167" r=".66146" gradientTransform="matrix(4.5354 8.0301e-7 -8.0301e-7 4.5354 -1.6 -1.6)" gradientUnits="userSpaceOnUse">
<stop stop-opacity=".28986" offset="0"/>
<stop stop-opacity="0" offset="1"/>
</radialGradient>
<filter id="green-to-purple" x="-.038462" y="-.038462" width="1.0769" height="1.0769" color-interpolation-filters="sRGB">
<feColorMatrix type="hueRotate" values="180"/>
<feColorMatrix type="saturate" values="1"/>
<feColorMatrix type="hueRotate" values="0"/>
</filter>
<symbol id="plus-in-diamond" viewBox="0 0 16 16">
<path d="M8 2 L14 8 L8 14 L2 8 Z" fill="url(#inner-fill)"/>
<path d="M8 3 L13 8 L8 13 L3 8 Z" fill="none" stroke="#fff" stroke-opacity=".50196" stroke-width="1.5"/>
<path d="M8 2 L14 8 L8 14 L2 8 Z" fill="none" stroke="url(#outer-rim)"/>
<circle cx="8" cy="8" r="3" fill="url(#center-shadow)"/>
<path d="m5 7h2v-2h2v2h2v2h-2v2h-2v-2h-2v-2" fill="#fff"/>
</symbol>
</defs>
<g transform="matrix(.91504 0 0 .91504 1.5 -1.5)" filter="url(#green-to-purple)">
<use xlink:href="#plus-in-diamond"/>
</g>
<g transform="matrix(.91504 0 0 .91504 0 3)" filter="url(#green-to-purple)">
<use xlink:href="#plus-in-diamond"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="inner-fill" x1="-1.7198" x2="-1.7198" y1="3.5719" y2=".79375" gradientTransform="matrix(3.7795 0 0 3.7795 14.5 -6.308e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#6fb558" offset="0"/>
<stop stop-color="#a5db9b" offset="1"/>
</linearGradient>
<linearGradient id="outer-rim" x1="7.5406" x2="5.1594" y1="3.3073" y2=".92604" gradientTransform="matrix(3.7795 0 0 3.7795 -16 -6e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#34812c" offset="0"/>
<stop stop-color="#87b870" offset="1"/>
</linearGradient>
<radialGradient id="center-shadow" cx="2.1167" cy="2.1167" r=".66146" gradientTransform="matrix(4.5354 8.0301e-7 -8.0301e-7 4.5354 -1.6 -1.6)" gradientUnits="userSpaceOnUse">
<stop stop-opacity=".28986" offset="0"/>
<stop stop-opacity="0" offset="1"/>
</radialGradient>
<filter id="green-to-purple" x="-.038462" y="-.038462" width="1.0769" height="1.0769" color-interpolation-filters="sRGB">
<feColorMatrix type="hueRotate" values="180"/>
<feColorMatrix type="saturate" values="1"/>
<feColorMatrix type="hueRotate" values="0"/>
</filter>
<symbol id="plus-in-square" viewBox="0 0 16 16">
<rect x="1.5" y="1.5" width="13" height="13" rx="1" fill="url(#inner-fill)"/>
<rect x="2.25" y="2.25" width="11.5" height="11.5" rx="0.75" fill="none" stroke="#fff" stroke-opacity=".50196" stroke-width="1.5"/>
<rect x="1.5" y="1.5" width="13" height="13" rx="1" fill="none" stroke="url(#outer-rim)"/>
<rect x="5" y="5" width="6" height="6" rx="1" fill="url(#center-shadow)"/>
<path d="m5 7h2v-2h2v2h2v2h-2v2h-2v-2h-2v-2" fill="#fff"/>
</symbol>
</defs>
<g transform="matrix(.91504 0 0 .91504 2.2745 -.91504)" filter="url(#green-to-purple)">
<use xlink:href="#plus-in-square"/>
</g>
<g transform="matrix(.91504 0 0 .91504 -.91504 2.2745)" filter="url(#green-to-purple)">
<use xlink:href="#plus-in-square"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="inner-fill" x1="-1.7198" x2="-1.7198" y1="2.7781" y2="1.4552" gradientTransform="matrix(3.7795 0 0 3.7795 14 .5)" gradientUnits="userSpaceOnUse">
<stop stop-color="#6fb558" offset="0"/>
<stop stop-color="#a5db9b" offset="1"/>
</linearGradient>
<linearGradient id="outer-rim" x1="2.1167" x2="1.4552" y1="2.3812" y2="1.7198" gradientTransform="scale(3.7795 3.7795)" gradientUnits="userSpaceOnUse">
<stop stop-color="#34812c" offset="0"/>
<stop stop-color="#87b870" offset="1"/>
</linearGradient>
<radialGradient id="center-shadow" cx="2.1167" cy="2.1167" r=".66146" gradientTransform="matrix(2.2677 -7.9311e-7 7.9312e-7 2.2677 2.7 3.7)" gradientUnits="userSpaceOnUse">
<stop stop-opacity=".28986" offset="0"/>
<stop stop-opacity="0" offset="1"/>
</radialGradient>
<filter id="green-to-blue" x="-.083333" y="-.083333" width="1.1667" height="1.1667" color-interpolation-filters="sRGB">
<feColorMatrix result="color1" type="hueRotate" values="105"/>
<feColorMatrix result="color2" type="saturate" values="1"/>
</filter>
<symbol id="plus-in-circle" viewBox="0 0 16 16">
<circle cx="7.5" cy="8.5" r="3" fill="url(#inner-fill)"/>
<circle cx="7.5" cy="8.5" r="3" fill="none" stroke="url(#outer-rim)"/>
<circle cx="7.5" cy="8.5" r="1.5" fill="url(#center-shadow)"/>
<path d="m6 8h1v-1h1v1h1v1h-1v1h-1v-1h-1v-1" fill="#fff"/>
</symbol>
</defs>
<g transform="translate(1,-1)" filter="url(#green-to-blue)">
<use xlink:href="#plus-in-circle"/>
</g>
<g transform="translate(-1,1)" filter="url(#green-to-blue)">
<use xlink:href="#plus-in-circle"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="inner-fill" x1="-1.7198" x2="-1.7198" y1="2.7781" y2="1.4552" gradientTransform="matrix(3.7795 0 0 3.7795 14 .5)" gradientUnits="userSpaceOnUse">
<stop stop-color="#6fb558" offset="0"/>
<stop stop-color="#a5db9b" offset="1"/>
</linearGradient>
<linearGradient id="outer-rim" x1="2.1167" x2="1.4552" y1="2.3812" y2="1.7198" gradientTransform="scale(3.7795 3.7795)" gradientUnits="userSpaceOnUse">
<stop stop-color="#34812c" offset="0"/>
<stop stop-color="#87b870" offset="1"/>
</linearGradient>
<radialGradient id="center-shadow" cx="2.1167" cy="2.1167" r=".66146" gradientTransform="matrix(2.2677 -7.9311e-7 7.9312e-7 2.2677 2.7 3.7)" gradientUnits="userSpaceOnUse">
<stop stop-opacity=".28986" offset="0"/>
<stop stop-opacity="0" offset="1"/>
</radialGradient>
<filter id="green-to-purple" x="-.083333" y="-.083333" width="1.1667" height="1.1667" color-interpolation-filters="sRGB">
<feColorMatrix result="color1" type="hueRotate" values="180"/>
<feColorMatrix result="color2" type="saturate" values="1"/>
</filter>
<symbol id="plus-in-circle" viewBox="0 0 16 16">
<circle cx="7.5" cy="8.5" r="3" fill="url(#inner-fill)"/>
<circle cx="7.5" cy="8.5" r="3" fill="none" stroke="url(#outer-rim)"/>
<circle cx="7.5" cy="8.5" r="1.5" fill="url(#center-shadow)"/>
<path d="m6 8h1v-1h1v1h1v1h-1v1h-1v-1h-1v-1" fill="#fff"/>
</symbol>
</defs>
<g transform="translate(1,-1)" filter="url(#green-to-purple)">
<use xlink:href="#plus-in-circle"/>
</g>
<g transform="translate(-1,1)" filter="url(#green-to-purple)">
<use xlink:href="#plus-in-circle"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M6 1.5v6H3.5L8 12l4.5-4.5H10v-6H6zM2 11v3.5h12V11h-1v1.5H3V11H2z" fill="#333"/></svg>

Before

Width:  |  Height:  |  Size: 195 B

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="inner-fill" x1="-1.7198" x2="-1.7198" y1="3.5719" y2=".79375" gradientTransform="matrix(3.7795 0 0 3.7795 14.5 -6.308e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#6fb558" offset="0"/>
<stop stop-color="#a5db9b" offset="1"/>
</linearGradient>
<linearGradient id="outer-rim" x1="7.5406" x2="5.1594" y1="3.3073" y2=".92604" gradientTransform="matrix(3.7795 0 0 3.7795 -16 -6e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#34812c" offset="0"/>
<stop stop-color="#87b870" offset="1"/>
</linearGradient>
<radialGradient id="center-shadow" cx="2.1167" cy="2.1167" r=".66146" gradientTransform="matrix(4.5354 8.0301e-7 -8.0301e-7 4.5354 -1.6 -1.6)" gradientUnits="userSpaceOnUse">
<stop stop-opacity=".28986" offset="0"/>
<stop stop-opacity="0" offset="1"/>
</radialGradient>
</defs>
<g>
<circle cx="8" cy="8" r="6.5" fill="url(#inner-fill)"/>
<circle cx="8" cy="8" r="5.75" fill="none" stroke="#fff" stroke-opacity=".50196" stroke-width="1.5"/>
<circle cx="8" cy="8" r="6.5" fill="none" stroke="url(#outer-rim)"/>
<circle cx="8" cy="8" r="3" fill="url(#center-shadow)"/>
<path d="m5 7h2v-2h2v2h2v2h-2v2h-2v-2h-2v-2" fill="#fff"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="inner-fill" x1="-1.7198" x2="-1.7198" y1="3.5719" y2=".79375" gradientTransform="matrix(3.7795 0 0 3.7795 14.5 -6.308e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#6fb558" offset="0"/>
<stop stop-color="#a5db9b" offset="1"/>
</linearGradient>
<linearGradient id="outer-rim" x1="7.5406" x2="5.1594" y1="3.3073" y2=".92604" gradientTransform="matrix(3.7795 0 0 3.7795 -16 -6e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#34812c" offset="0"/>
<stop stop-color="#87b870" offset="1"/>
</linearGradient>
<radialGradient id="center-shadow" cx="2.1167" cy="2.1167" r=".66146" gradientTransform="matrix(4.5354 8.0301e-7 -8.0301e-7 4.5354 -1.6 -1.6)" gradientUnits="userSpaceOnUse">
<stop stop-opacity=".28986" offset="0"/>
<stop stop-opacity="0" offset="1"/>
</radialGradient>
</defs>
<g>
<path d="M8 2 L14 8 L8 14 L2 8 Z" fill="url(#inner-fill)"/>
<path d="M8 3 L13 8 L8 13 L3 8 Z" fill="none" stroke="#fff" stroke-opacity=".50196" stroke-width="1.5"/>
<path d="M8 2 L14 8 L8 14 L2 8 Z" fill="none" stroke="url(#outer-rim)"/>
<circle cx="8" cy="8" r="3" fill="url(#center-shadow)"/>
<path d="m5 7h2v-2h2v2h2v2h-2v2h-2v-2h-2v-2" fill="#fff"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="inner-fill" x1="-1.7198" x2="-1.7198" y1="3.5719" y2=".79375" gradientTransform="matrix(3.7795 0 0 3.7795 14.5 -6.308e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#6fb558" offset="0"/>
<stop stop-color="#a5db9b" offset="1"/>
</linearGradient>
<linearGradient id="outer-rim" x1="7.5406" x2="5.1594" y1="3.3073" y2=".92604" gradientTransform="matrix(3.7795 0 0 3.7795 -16 -6e-7)" gradientUnits="userSpaceOnUse">
<stop stop-color="#34812c" offset="0"/>
<stop stop-color="#87b870" offset="1"/>
</linearGradient>
<radialGradient id="center-shadow" cx="2.1167" cy="2.1167" r=".66146" gradientTransform="matrix(4.5354 8.0301e-7 -8.0301e-7 4.5354 -1.6 -1.6)" gradientUnits="userSpaceOnUse">
<stop stop-opacity=".28986" offset="0"/>
<stop stop-opacity="0" offset="1"/>
</radialGradient>
</defs>
<g>
<rect x="1.5" y="1.5" width="13" height="13" rx="1" fill="url(#inner-fill)"/>
<rect x="2.25" y="2.25" width="11.5" height="11.5" rx="0.75" fill="none" stroke="#fff" stroke-opacity=".50196" stroke-width="1.5"/>
<rect x="1.5" y="1.5" width="13" height="13" rx="1" fill="none" stroke="url(#outer-rim)"/>
<rect x="5" y="5" width="6" height="6" rx="1" fill="url(#center-shadow)"/>
<path d="m5 7h2v-2h2v2h2v2h-2v2h-2v-2h-2v-2" fill="#fff"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M2 2.25L3.75.5H14v13l-1 1v-13H4.75l-1.04592 1H12v13H2z" fill="#333"/></svg>

Before

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M2 0C.892 0 0 .892 0 2v12c0 1.108.892 2 2 2h12c1.108 0 2-.892 2-2V2c0-1.108-.892-2-2-2H2zm0 2h12v12H2V2z" fill="#000"/></svg>

Before

Width:  |  Height:  |  Size: 235 B

View File

@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M6.5 12.5L14 5l-1.5-1.5-6 6-3-3L2 8z"/></svg>

Before

Width:  |  Height:  |  Size: 155 B

View File

@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M1 1h14v14H1z" fill="#000"/></svg>

Before

Width:  |  Height:  |  Size: 144 B

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