add src folder
This commit is contained in:
1 parent
79673e55fe
commit
16f3e28690
9 files changed
+232
-204
No files matched your search
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"semi": false,
|
"semi": true,
|
||||||
"arrowParens": "always",
|
"arrowParens": "always",
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "none"
|
"trailingComma": "all"
|
||||||
}
|
}
|
||||||
+27
-27
@@ -1,54 +1,54 @@
|
|||||||
import path from 'path'
|
import path from 'path';
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios';
|
||||||
import fs from 'fs/promises'
|
import fs from 'fs/promises';
|
||||||
import { nanoid } from 'nanoid'
|
import { nanoid } from 'nanoid';
|
||||||
|
|
||||||
const ROOTDIR = 'docs/assets'
|
const ROOTDIR = 'docs/assets';
|
||||||
|
|
||||||
const log = {
|
const log = {
|
||||||
data: {} as Record<string, string>,
|
data: {} as Record<string, string>,
|
||||||
filename: path.join(ROOTDIR, 'download-radical.json'),
|
filename: path.join(ROOTDIR, 'download-radical.json'),
|
||||||
async load() {
|
async load() {
|
||||||
this.data = JSON.parse(await fs.readFile(this.filename, 'utf-8'))
|
this.data = JSON.parse(await fs.readFile(this.filename, 'utf-8'));
|
||||||
return this.data
|
return this.data;
|
||||||
},
|
},
|
||||||
async dump() {
|
async dump() {
|
||||||
await fs.writeFile(this.filename, JSON.stringify(this.data, null, 2))
|
await fs.writeFile(this.filename, JSON.stringify(this.data, null, 2));
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
async function doDownloadRadical(url: string, note?: string) {
|
async function doDownloadRadical(url: string, note?: string) {
|
||||||
const r = await axios.get(url, {
|
const r = await axios.get(url, {
|
||||||
responseType: 'arraybuffer'
|
responseType: 'arraybuffer',
|
||||||
})
|
});
|
||||||
|
|
||||||
const filename = `${nanoid()}.png`
|
const filename = `${nanoid()}.png`;
|
||||||
await fs.writeFile(path.join(ROOTDIR, filename), r.data)
|
await fs.writeFile(path.join(ROOTDIR, filename), r.data);
|
||||||
|
|
||||||
console.info(filename)
|
console.info(filename);
|
||||||
|
|
||||||
if (note) {
|
if (note) {
|
||||||
log.data[filename] = note
|
log.data[filename] = note;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function downloadFromList(toBeDownloaded: Record<string, string>) {
|
async function downloadFromList(toBeDownloaded: Record<string, string>) {
|
||||||
const chunkSize = 50
|
const chunkSize = 50;
|
||||||
const entries = Object.entries(toBeDownloaded)
|
const entries = Object.entries(toBeDownloaded);
|
||||||
for (let i = 0; i < entries.length; i += chunkSize) {
|
for (let i = 0; i < entries.length; i += chunkSize) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
entries.slice(i, i + chunkSize).map(([k, v]) => doDownloadRadical(k, v))
|
entries.slice(i, i + chunkSize).map(([k, v]) => doDownloadRadical(k, v)),
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
await log.load()
|
await log.load();
|
||||||
|
|
||||||
const [, , url, ...parts] = process.argv
|
const [, , url, ...parts] = process.argv;
|
||||||
if (url) {
|
if (url) {
|
||||||
await doDownloadRadical(url, parts.join(' '))
|
await doDownloadRadical(url, parts.join(' '));
|
||||||
} else {
|
} else {
|
||||||
await downloadFromList({
|
await downloadFromList({
|
||||||
'https://git.polv.cc/attachments/d76f268a-8b40-4bba-ab24-e10de2e69f78':
|
'https://git.polv.cc/attachments/d76f268a-8b40-4bba-ab24-e10de2e69f78':
|
||||||
@@ -120,13 +120,13 @@ async function main() {
|
|||||||
'https://aws1.discourse-cdn.com/wanikanicommunity/original/4X/4/3/9/43978d49ccdc893a5ddd768790a9a84e0ad8c965.png':
|
'https://aws1.discourse-cdn.com/wanikanicommunity/original/4X/4/3/9/43978d49ccdc893a5ddd768790a9a84e0ad8c965.png':
|
||||||
'Safety roof',
|
'Safety roof',
|
||||||
'https://aws1.discourse-cdn.com/wanikanicommunity/original/4X/d/2/d/d2d27d66900c320ad70ee40a0985ee355a757f1e.png':
|
'https://aws1.discourse-cdn.com/wanikanicommunity/original/4X/d/2/d/d2d27d66900c320ad70ee40a0985ee355a757f1e.png':
|
||||||
'I have a scooter (Have scooter)'
|
'I have a scooter (Have scooter)',
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await log.dump()
|
await log.dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
main()
|
main();
|
||||||
}
|
}
|
||||||
@@ -1,30 +1,28 @@
|
|||||||
import fs from 'fs'
|
import fs from 'fs';
|
||||||
|
|
||||||
import yaml from 'js-yaml'
|
import { IKanji, IRadical, WaniKani } from '@/wanikani';
|
||||||
import { toKatakana } from 'wanakana'
|
import yaml from 'js-yaml';
|
||||||
|
import { toKatakana } from 'wanakana';
|
||||||
import { subjects } from './dump-subjects'
|
|
||||||
import { IKanji, IRadical } from './shared'
|
|
||||||
|
|
||||||
interface IItem {
|
interface IItem {
|
||||||
document_url: string
|
document_url: string;
|
||||||
level: number
|
level: number;
|
||||||
meaning: string
|
meaning: string;
|
||||||
reading?: string
|
reading?: string;
|
||||||
components: {
|
components: {
|
||||||
[source: string]: string[]
|
[source: string]: string[];
|
||||||
}
|
};
|
||||||
similar: string[]
|
similar: string[];
|
||||||
image?: {
|
image?: {
|
||||||
src: string
|
src: string;
|
||||||
content_type: string
|
content_type: string;
|
||||||
width: string | undefined
|
width: string | undefined;
|
||||||
height: string | undefined
|
height: string | undefined;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IBeautifiedRadicals {
|
interface IBeautifiedRadicals {
|
||||||
[id: string]: IItem
|
[id: string]: IItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const radicals = {
|
export const radicals = {
|
||||||
@@ -32,59 +30,59 @@ export const radicals = {
|
|||||||
filename: 'radicals.yaml',
|
filename: 'radicals.yaml',
|
||||||
load() {
|
load() {
|
||||||
this.data = yaml.load(
|
this.data = yaml.load(
|
||||||
fs.readFileSync(this.filename, 'utf-8')
|
fs.readFileSync(this.filename, 'utf-8'),
|
||||||
) as IBeautifiedRadicals
|
) as IBeautifiedRadicals;
|
||||||
return this.data
|
return this.data;
|
||||||
},
|
},
|
||||||
dump(d: IBeautifiedRadicals) {
|
dump(d: IBeautifiedRadicals) {
|
||||||
this.data = d
|
this.data = d;
|
||||||
this.finalize()
|
this.finalize();
|
||||||
},
|
},
|
||||||
finalize() {
|
finalize() {
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
this.filename,
|
this.filename,
|
||||||
yaml.dump(this.data, {
|
yaml.dump(this.data, {
|
||||||
skipInvalid: true
|
skipInvalid: true,
|
||||||
})
|
}),
|
||||||
)
|
);
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const rs = subjects.load()
|
const rs = await new WaniKani().subjects();
|
||||||
|
|
||||||
const idMap = new Map<number, string>()
|
const idMap = new Map<number, string>();
|
||||||
radicals.data = {}
|
radicals.data = {};
|
||||||
|
|
||||||
rs.filter((r) => r.object === 'radical').map((r0) => {
|
rs.filter((r) => r.object === 'radical').map((r0) => {
|
||||||
const r = r0 as IRadical
|
const r = r0 as IRadical;
|
||||||
const d = {
|
const d = {
|
||||||
document_url: r.data.document_url,
|
document_url: r.data.document_url,
|
||||||
level: r.data.level,
|
level: r.data.level,
|
||||||
meaning: r.data.meanings.filter((m) => m.primary)[0]!.meaning,
|
meaning: r.data.meanings.filter((m) => m.primary)[0]!.meaning,
|
||||||
components: {},
|
components: {},
|
||||||
sup: r.data.amalgamation_subject_ids.map((it) => it.toString()),
|
sup: r.data.amalgamation_subject_ids.map((it) => it.toString()),
|
||||||
similar: []
|
similar: [],
|
||||||
}
|
};
|
||||||
|
|
||||||
let id = r.data.characters
|
let id = r.data.characters;
|
||||||
|
|
||||||
if (id) {
|
if (id) {
|
||||||
radicals.data[id] = d
|
radicals.data[id] = d;
|
||||||
} else {
|
} else {
|
||||||
id = d.meaning
|
id = d.meaning;
|
||||||
|
|
||||||
const st = (im: {
|
const st = (im: {
|
||||||
content_type: string
|
content_type: string;
|
||||||
metadata: { dimensions?: string }
|
metadata: { dimensions?: string };
|
||||||
}) =>
|
}) =>
|
||||||
im.content_type === 'image/svg+xml'
|
im.content_type === 'image/svg+xml'
|
||||||
? 5000
|
? 5000
|
||||||
: im.metadata.dimensions
|
: im.metadata.dimensions
|
||||||
? Math.min(...im.metadata.dimensions.split('x').map(Number))
|
? Math.min(...im.metadata.dimensions.split('x').map(Number))
|
||||||
: 0
|
: 0;
|
||||||
const im = r.data.character_images.sort((a, b) => st(a) - st(b))[0]!
|
const im = r.data.character_images.sort((a, b) => st(a) - st(b))[0]!;
|
||||||
const dim = im.metadata.dimensions?.split('x') || []
|
const dim = im.metadata.dimensions?.split('x') || [];
|
||||||
|
|
||||||
radicals.data[id] = {
|
radicals.data[id] = {
|
||||||
...d,
|
...d,
|
||||||
@@ -92,17 +90,17 @@ async function main() {
|
|||||||
src: im.url,
|
src: im.url,
|
||||||
content_type: im.content_type,
|
content_type: im.content_type,
|
||||||
width: dim[0],
|
width: dim[0],
|
||||||
height: dim[1]
|
height: dim[1],
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
idMap.set(r.id, id)
|
idMap.set(r.id, id);
|
||||||
})
|
});
|
||||||
|
|
||||||
rs.filter((r) => r.object === 'kanji').map((r0) => {
|
rs.filter((r) => r.object === 'kanji').map((r0) => {
|
||||||
const r = r0 as IKanji
|
const r = r0 as IKanji;
|
||||||
const reading = r.data.readings.filter((m) => m.primary)[0]!
|
const reading = r.data.readings.filter((m) => m.primary)[0]!;
|
||||||
const d = {
|
const d = {
|
||||||
document_url: r.data.document_url,
|
document_url: r.data.document_url,
|
||||||
level: r.data.level,
|
level: r.data.level,
|
||||||
@@ -112,13 +110,13 @@ async function main() {
|
|||||||
? toKatakana(reading.reading)
|
? toKatakana(reading.reading)
|
||||||
: reading.reading,
|
: reading.reading,
|
||||||
components: {
|
components: {
|
||||||
wanikani: r.data.component_subject_ids.map((it) => it.toString())
|
wanikani: r.data.component_subject_ids.map((it) => it.toString()),
|
||||||
},
|
},
|
||||||
similar: r.data.visually_similar_subject_ids.map((it) => it.toString())
|
similar: r.data.visually_similar_subject_ids.map((it) => it.toString()),
|
||||||
}
|
};
|
||||||
|
|
||||||
const id = r.data.characters
|
const id = r.data.characters;
|
||||||
idMap.set(r.id, id)
|
idMap.set(r.id, id);
|
||||||
// const prev = radicals.data[id]
|
// const prev = radicals.data[id]
|
||||||
|
|
||||||
// if (prev) {
|
// if (prev) {
|
||||||
@@ -133,22 +131,22 @@ async function main() {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
radicals.data[id] = d
|
radicals.data[id] = d;
|
||||||
})
|
});
|
||||||
|
|
||||||
for (const [k, v] of Object.entries(radicals.data)) {
|
for (const [k, v] of Object.entries(radicals.data)) {
|
||||||
if (v.components?.['wanikani']) {
|
if (v.components?.['wanikani']) {
|
||||||
v.components['wanikani'] = v.components['wanikani']
|
v.components['wanikani'] = v.components['wanikani']
|
||||||
.map((s) => idMap.get(Number(s)) || s)
|
.map((s) => idMap.get(Number(s)) || s)
|
||||||
.filter((s) => s !== k)
|
.filter((s) => s !== k);
|
||||||
}
|
}
|
||||||
v.similar = v.similar.map((s) => idMap.get(Number(s)) || s)
|
v.similar = v.similar.map((s) => idMap.get(Number(s)) || s);
|
||||||
// v.sup = v.sup.map((s) => idMap.get(Number(s)) || s)
|
// v.sup = v.sup.map((s) => idMap.get(Number(s)) || s)
|
||||||
}
|
}
|
||||||
|
|
||||||
radicals.finalize()
|
radicals.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
main()
|
main();
|
||||||
}
|
}
|
||||||
@@ -1,39 +1,39 @@
|
|||||||
import fs from 'fs'
|
import fs from 'fs';
|
||||||
|
|
||||||
import { radicals } from './beautify-radicals'
|
import { radicals } from './beautify-radicals';
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const map = radicals.load()
|
const map = radicals.load();
|
||||||
|
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
'../../_radicals.md',
|
'../../_radicals.md',
|
||||||
Object.entries(map)
|
Object.entries(map)
|
||||||
.map(([k, v]) => {
|
.map(([k, v]) => {
|
||||||
const headers = [k]
|
const headers = [k];
|
||||||
if (v.meaning !== k) {
|
if (v.meaning !== k) {
|
||||||
headers.push(v.meaning)
|
headers.push(v.meaning);
|
||||||
}
|
}
|
||||||
if (v.reading) {
|
if (v.reading) {
|
||||||
headers.push(v.reading)
|
headers.push(v.reading);
|
||||||
}
|
}
|
||||||
headers.push(String(v.level))
|
headers.push(String(v.level));
|
||||||
|
|
||||||
const rows = [`## ${headers.join(', ')}`, '']
|
const rows = [`## ${headers.join(', ')}`, ''];
|
||||||
if (v.image) {
|
if (v.image) {
|
||||||
rows.push(
|
rows.push(
|
||||||
`<img src="${v.image.src}" alt="${k}"${
|
`<img src="${v.image.src}" alt="${k}"${
|
||||||
v.image.width ? ` width="${v.image.width}"` : ''
|
v.image.width ? ` width="${v.image.width}"` : ''
|
||||||
}${v.image.height ? ` height="${v.image.height}"` : ''} />`,
|
}${v.image.height ? ` height="${v.image.height}"` : ''} />`,
|
||||||
''
|
'',
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rows.join('\n')
|
return rows.join('\n');
|
||||||
})
|
})
|
||||||
.join('\n\n')
|
.join('\n\n'),
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
main()
|
main();
|
||||||
}
|
}
|
||||||
@@ -1,53 +1,9 @@
|
|||||||
import fs from 'fs'
|
import { WaniKani } from '@/wanikani';
|
||||||
|
|
||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
import { IKanji, IRadical } from './shared'
|
|
||||||
|
|
||||||
export const subjects = {
|
|
||||||
data: [] as (IKanji | IRadical)[],
|
|
||||||
filename: 'wanikani.json',
|
|
||||||
load() {
|
|
||||||
this.data = JSON.parse(fs.readFileSync(this.filename, 'utf-8'))
|
|
||||||
return this.data
|
|
||||||
},
|
|
||||||
dump(d: (IKanji | IRadical)[]) {
|
|
||||||
this.data = d
|
|
||||||
this.finalize()
|
|
||||||
},
|
|
||||||
finalize() {
|
|
||||||
fs.writeFileSync(this.filename, JSON.stringify(this.data))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const wk = axios.create({
|
await new WaniKani().subjects({ force: true });
|
||||||
baseURL: 'https://api.wanikani.com/v2/',
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${process.env['WANIKANI_API_KEY']}`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const data: (IKanji | IRadical)[] = []
|
|
||||||
|
|
||||||
let nextURL = '/subjects?types=radical,kanji'
|
|
||||||
while (nextURL) {
|
|
||||||
const r = await wk
|
|
||||||
.get<{
|
|
||||||
pages: {
|
|
||||||
next_url?: string
|
|
||||||
}
|
|
||||||
data: (IKanji | IRadical)[]
|
|
||||||
}>(nextURL)
|
|
||||||
.then((r) => r.data)
|
|
||||||
data.push(...r.data)
|
|
||||||
console.info(r.pages.next_url)
|
|
||||||
nextURL = r.pages.next_url || ''
|
|
||||||
}
|
|
||||||
|
|
||||||
subjects.dump(data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
main()
|
main();
|
||||||
}
|
}
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
export interface IKanji {
|
|
||||||
id: number
|
|
||||||
/** Actual type */
|
|
||||||
object: 'kanji'
|
|
||||||
url: string
|
|
||||||
data_updated_at: string
|
|
||||||
data: {
|
|
||||||
level: number
|
|
||||||
document_url: string
|
|
||||||
characters: string
|
|
||||||
meanings: {
|
|
||||||
meaning: string
|
|
||||||
primary: boolean
|
|
||||||
}[]
|
|
||||||
readings: {
|
|
||||||
reading: string
|
|
||||||
primary: boolean
|
|
||||||
type: 'kunyomi' | 'onyomi'
|
|
||||||
}[]
|
|
||||||
component_subject_ids: number[]
|
|
||||||
visually_similar_subject_ids: number[]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IRadical {
|
|
||||||
id: number
|
|
||||||
/** Actual type */
|
|
||||||
object: 'radical'
|
|
||||||
url: string
|
|
||||||
data_updated_at: string
|
|
||||||
data: {
|
|
||||||
level: number
|
|
||||||
document_url: string
|
|
||||||
characters: string | null
|
|
||||||
character_images: {
|
|
||||||
url: string
|
|
||||||
metadata: {
|
|
||||||
inline_styles?: boolean
|
|
||||||
dimensions?: string
|
|
||||||
}
|
|
||||||
content_type: string
|
|
||||||
}[]
|
|
||||||
meanings: {
|
|
||||||
meaning: string
|
|
||||||
primary: boolean
|
|
||||||
}[]
|
|
||||||
amalgamation_subject_ids: number[]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
|
||||||
|
export class AnkiConnect {
|
||||||
|
$axios: AxiosInstance;
|
||||||
|
|
||||||
|
constructor(public url = 'http://localhost:8765') {
|
||||||
|
this.$axios = axios.create({
|
||||||
|
baseURL: url,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+112
@@ -0,0 +1,112 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
|
||||||
|
export class WaniKani {
|
||||||
|
$axios: AxiosInstance;
|
||||||
|
|
||||||
|
constructor(public apiKey = process.env['WANIKANI_API_KEY']!) {
|
||||||
|
this.$axios = axios.create({
|
||||||
|
baseURL: 'https://api.wanikani.com/v2/',
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${process.env['WANIKANI_API_KEY']}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async subjects({
|
||||||
|
force,
|
||||||
|
}: {
|
||||||
|
force?: boolean;
|
||||||
|
} = {}) {
|
||||||
|
const subjects = {
|
||||||
|
data: [] as (IKanji | IRadical)[],
|
||||||
|
filename: 'wanikani.json',
|
||||||
|
load() {
|
||||||
|
this.data = JSON.parse(fs.readFileSync(this.filename, 'utf-8'));
|
||||||
|
return this.data;
|
||||||
|
},
|
||||||
|
dump(d: (IKanji | IRadical)[]) {
|
||||||
|
this.data = d;
|
||||||
|
this.finalize();
|
||||||
|
},
|
||||||
|
finalize() {
|
||||||
|
fs.writeFileSync(this.filename, JSON.stringify(this.data));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let data = subjects.load();
|
||||||
|
if (data.length && !force) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
data = [];
|
||||||
|
|
||||||
|
let nextURL = '/subjects?types=radical,kanji';
|
||||||
|
while (nextURL) {
|
||||||
|
const r = await this.$axios
|
||||||
|
.get<{
|
||||||
|
pages: {
|
||||||
|
next_url?: string;
|
||||||
|
};
|
||||||
|
data: (IKanji | IRadical)[];
|
||||||
|
}>(nextURL)
|
||||||
|
.then((r) => r.data);
|
||||||
|
data.push(...r.data);
|
||||||
|
console.info(r.pages.next_url);
|
||||||
|
nextURL = r.pages.next_url || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
subjects.dump(data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IKanji {
|
||||||
|
id: number;
|
||||||
|
/** Actual type */
|
||||||
|
object: 'kanji';
|
||||||
|
url: string;
|
||||||
|
data_updated_at: string;
|
||||||
|
data: {
|
||||||
|
level: number;
|
||||||
|
document_url: string;
|
||||||
|
characters: string;
|
||||||
|
meanings: {
|
||||||
|
meaning: string;
|
||||||
|
primary: boolean;
|
||||||
|
}[];
|
||||||
|
readings: {
|
||||||
|
reading: string;
|
||||||
|
primary: boolean;
|
||||||
|
type: 'kunyomi' | 'onyomi';
|
||||||
|
}[];
|
||||||
|
component_subject_ids: number[];
|
||||||
|
visually_similar_subject_ids: number[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IRadical {
|
||||||
|
id: number;
|
||||||
|
/** Actual type */
|
||||||
|
object: 'radical';
|
||||||
|
url: string;
|
||||||
|
data_updated_at: string;
|
||||||
|
data: {
|
||||||
|
level: number;
|
||||||
|
document_url: string;
|
||||||
|
characters: string | null;
|
||||||
|
character_images: {
|
||||||
|
url: string;
|
||||||
|
metadata: {
|
||||||
|
inline_styles?: boolean;
|
||||||
|
dimensions?: string;
|
||||||
|
};
|
||||||
|
content_type: string;
|
||||||
|
}[];
|
||||||
|
meanings: {
|
||||||
|
meaning: string;
|
||||||
|
primary: boolean;
|
||||||
|
}[];
|
||||||
|
amalgamation_subject_ids: number[];
|
||||||
|
};
|
||||||
|
}
|
||||||
+4
-4
@@ -27,10 +27,10 @@
|
|||||||
"module": "commonjs", /* Specify what module code is generated. */
|
"module": "commonjs", /* Specify what module code is generated. */
|
||||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||||
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
"baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||||
// "paths": {
|
"paths": {
|
||||||
// "@/*": ["src/*"]
|
"@/*": ["src/*"]
|
||||||
// }, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||||
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
|
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
|
||||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||||
|
|||||||
Reference in new issue
Block a user