1
0
mirror of https://github.com/vbalien/voca.git synced 2025-12-06 11:26:21 +09:00

refactoring

This commit is contained in:
2022-02-26 03:16:54 +09:00
parent 0bc8aee9ff
commit 0467dd90e1
17 changed files with 47320 additions and 165 deletions

12
.prettierrc Normal file
View File

@@ -0,0 +1,12 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"jsxSingleQuote": false,
"bracketSameLine": false,
"arrowParens": "avoid",
"useTabs": false,
"bracketSpacing": true,
"endOfLine": "auto"
}

View File

@@ -1,8 +1,9 @@
{
"compilerOptions": {
"allowJs": true,
"lib": ["deno.window"],
"strict": true
"lib": ["dom", "deno.ns"],
"strict": true,
"jsx": "react"
},
"lint": {
"files": {

15
doc/index.html Normal file
View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Voca</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module">
import * as website from "/website.bundle.js";
website.render();
</script>
</head>
<body>
<div id="root"></div>
</body>
</html>

1
doc/voca.json Normal file

File diff suppressed because one or more lines are too long

46815
doc/website.bundle.js Normal file

File diff suppressed because one or more lines are too long

162
lock.json Normal file
View File

@@ -0,0 +1,162 @@
{
"https://cdn.esm.sh/v66/@pdf-lib/fontkit@1.1.1/deno/fontkit.js": "d7db7332b8d42d9c1fda37d769dd54b08c2cbf2427924832d57527c09e4ee76e",
"https://cdn.esm.sh/v66/@pdf-lib/fontkit@1.1.1/fontkit.d.ts": "bd0e61404ddd62334c58f0ab54412c702e665fe6dcaec458874b71c47e067bdf",
"https://cdn.esm.sh/v66/@pdf-lib/standard-fonts@1.0.0/deno/standard-fonts.js": "f7202580d7c805a0cfaddd5f3348fc96cdac25668184625b00c0808fc820f290",
"https://cdn.esm.sh/v66/@pdf-lib/standard-fonts@1.0.0/lib/Encoding.d.ts": "33036b5ee618a7bf30f5b667b4cfb08de73c809d115f2afea28520633aff7e72",
"https://cdn.esm.sh/v66/@pdf-lib/standard-fonts@1.0.0/lib/Font.d.ts": "35c36f02a6afa6e5ec3e570eb46077c1f7e39a08b84ecf02dd26add5ba9b7bad",
"https://cdn.esm.sh/v66/@pdf-lib/standard-fonts@1.0.0/lib/index.d.ts": "2551aa7554cd376531423f179e4c7356a34b2599111460961255f03ce46f8db9",
"https://cdn.esm.sh/v66/@pdf-lib/upng@1.0.1/deno/upng.js": "32e308d582b2454b2b97294f7ee1925c4fcd07c2880114c24fbf297ac7387f44",
"https://cdn.esm.sh/v66/@types/prop-types@15.7.4/index.d.ts": "f7b46d22a307739c145e5fddf537818038fdfffd580d79ed717f4d4d37249380",
"https://cdn.esm.sh/v66/@types/react-dom@17.0.11/index.d.ts": "fe7b3384346ab2b02f3532bf001b67a4ade0b53410009011ee6b26540f190480",
"https://cdn.esm.sh/v66/@types/react@17.0.39/global.d.ts": "ecf78e637f710f340ec08d5d92b3f31b134a46a4fcf2e758690d8c46ce62cba6",
"https://cdn.esm.sh/v66/@types/react@17.0.39/index.d.ts": "9b23a5d8018e7977353631a1ae35a771243347646934b18d65994a0de47c89e4",
"https://cdn.esm.sh/v66/@types/scheduler@0.16.2/tracing.d.ts": "f5a8b384f182b3851cec3596ccc96cb7464f8d3469f48c74bf2befb782a19de5",
"https://cdn.esm.sh/v66/csstype@3.0.10/index.d.ts": "381899b8d1d4c1be716f18cb5242ba39f66f4b1e31d45af62a32a99f8edcb39d",
"https://cdn.esm.sh/v66/lodash@4.2.0/deno/shuffle.js": "0e7f3b20aba2b1e508b8f9e8480a88c7207f4ca76eb3d930503ffe9f39fae70f",
"https://cdn.esm.sh/v66/object-assign@4.1.1/deno/object-assign.js": "c25277a2b3d09a66ba75be29bf438396cd2c62e9d37d766c255987da9f3730cd",
"https://cdn.esm.sh/v66/pako@1.0.11/deno/pako.js": "8e14ad598a092edf506134058f9f0c0117651902cff8d11b331dba57c4fb248b",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/Embeddable.d.ts": "8cebcedd6601c23bf4e564564fe34455221d597c095e89ca4d4fb355d1c0221f",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/PDFDocument.d.ts": "dcdc7f0a91065ea851b92f01f6ea08c05f91685b9a58e1b5cdfe4cd289f5d956",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/PDFDocumentOptions.d.ts": "2a23524eb776af53a3a678941ef6c449eaca4a72e72d727395e2edfff2c44ae0",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/PDFEmbeddedPage.d.ts": "b018e692345000de20b9135fc8a555650aa675ef983a1048d80d77cacb8618e2",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/PDFFont.d.ts": "68f5478285f549f199abf8d8e2a4cb0f31ac0507a6d8ed31f56a28846646b529",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/PDFImage.d.ts": "80a3582f957a33669978b88e85cdec52868c914ec08fee03a2dc7f6186ce978a",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/PDFJavaScript.d.ts": "0f06a05424556245d0e113f96d37eae06ea9cae3657b6bc0552ef3d5b60faf53",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/PDFPage.d.ts": "bc9499c1af2a0f7496c616bfee9aca62092189ffa94cd92c60d05b8f7591d34b",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/PDFPageOptions.d.ts": "9f441450aad12af07e4dbe9ef55e7837d52b91761ef82c738ffaacd084f1b1c1",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/StandardFonts.d.ts": "0f70f8a108bbcb88ee89b09a1fba3101baaaca9f43bd3b0ce759c48bb92364d2",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/colors.d.ts": "0617b9c674ac99095b6ded0a795eaa45348ef03d4b5d9a53c028d218222b10d4",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/errors.d.ts": "5bf4687baebab04013c54b4a416496ab3566459b006434c2f53c599398a3e9d7",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/form/PDFButton.d.ts": "f5b828acafe32d1c71f3357618b2c52d2f6632229d8b2409f787fd139f808631",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/form/PDFCheckBox.d.ts": "33233affa71cf547dfbf80f686658318af303e06c63d0a323f12101fdaf9c495",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/form/PDFDropdown.d.ts": "c612e401d825102f35b24c3f29eb274fa6b4ac3232fb1207ebdfdd3c7e03979e",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/form/PDFField.d.ts": "be23eb2ba4671adf939065271a635363a35b0e55a8c8b08591612e414df9dc3f",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/form/PDFForm.d.ts": "dd2da6cf914a56d9087187dbc2097f4a544220628d30ba13273fdc54ba052bb0",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/form/PDFOptionList.d.ts": "e5982e7cc52679c2a8a96e77e68c4d9353513f4b9d9441b7e360a9e8227578f3",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/form/PDFRadioGroup.d.ts": "e7732a3a56c8a0ff591da5cd396c65b7e5c604ad086a5813e792507a2ff8c2c9",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/form/PDFSignature.d.ts": "5308adb0131499ccbbf57ec8bfb5cdc6fdcf35e54abd76aff5cd6760abe9f970",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/form/PDFTextField.d.ts": "4778779b4ef513f5ba2b2b10396a0cf6555d120a46c6f1404996767e457deb55",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/form/appearances.d.ts": "0fb224ca70f5ae2b9a8458831cd5b8ef3dea658003cf9350c966cb8e7c11e237",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/form/index.d.ts": "b22e51c1e650fcd86c2e3990c97a2697f63db722abbc2bf479875d078acb295e",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/image/alignment.d.ts": "e3f204b768d6148d2e62ed34109ec4df9c7ba8e3cfa02e147f6a16f971df5bda",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/image/index.d.ts": "0b61a6240c60536acc0fb7741e0de2ede7e3d1bd04832816dbef9a7516eec210",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/index.d.ts": "853530bb483db546721e91f139150a8e015f7f47a94cae3b7b594752c8541cc8",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/objects.d.ts": "1149a0723b59a924d28ad8c784ca98c2d01cedf9f0c346b5ef4c83e28178e2f5",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/operations.d.ts": "6cb79e2a0b64a71aa51538f6eb5398f595f6276e9e5dcbb7a3556d9914ad6f40",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/operators.d.ts": "8947140290058f7af3fc0e3bab90d3471b65fcbbcd1efc86a91631400a7cf2d0",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/rotations.d.ts": "00de1f626f116fe65b6686c434dbdea5d92705a25b7b04afa2141645ee4c2f89",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/sizes.d.ts": "658d379aea7a0f9447d438164597c274e7abf96e7b0ce49100666e7894d16a5c",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/text/alignment.d.ts": "dadddfdb8fceeffdbc3746a726af2ccc7290bcc33d6bef50824402aba284f323",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/text/index.d.ts": "7a6d571ecf8317c59b33b4dd77239e05276e0115be9b1a5389da4e1a0b799820",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/api/text/layout.d.ts": "0ff2f47d484b29c62a67e270252c9d34737cf62b291b9bad482ac9aa7923fc80",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/PDFContext.d.ts": "4f6b977cfb3fac757fd7f5cc96d2634b1e70df3509268b9c1ec7876a06485f72",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/PDFObjectCopier.d.ts": "4ec10e882d6247e5cef6a7b76edca4e88c49e218fce309032612836abec7b8c8",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroButton.d.ts": "34aaf34faa8d2fe0ca8c49f5439aa47c21405cc566f3cb911f99d9613c0ef834",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroCheckBox.d.ts": "fc3bd3ad4bc183aa9938624a57db7483a74c76e30fc5d66404bc42e575dfce1d",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroChoice.d.ts": "a0b7e02001afd8f929ced43282cc471177525f2f80a020d98f8e9c597408b75c",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroComboBox.d.ts": "2435bdbb188628f20bdbaf7e64bc329b4b7965be533252e780d2ed5a5703a0dc",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroField.d.ts": "4ad8777ee03b92f93be010d74f63d9fe280aecd81e66780572c182f6d29d5b1e",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroForm.d.ts": "9a78718848da2890dae8ff5d6f74e5f1db7a83e4e351f6fd11934c6ef421d4ba",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroListBox.d.ts": "ca888f989c7971c5edf6da60f644b29e75aa5636e0d7e0c803d413f7ba9b4b54",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroNonTerminal.d.ts": "1f0b8b5c9272f5adddbf147f175ae6332b724fbd0acdc8be006bb9626f933413",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroPushButton.d.ts": "76f32394ebffda5bf1f590641a3b56bfcc64a721a3f500f3ba81003f5c068e23",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroRadioButton.d.ts": "bb52c36002e471645c96dda86c8fac4c827df55ad7989834fb1169bd75af3f37",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroSignature.d.ts": "3fb2cf0655c561323179199d0771bc777b9374ded1893757b3c45d6a105e05fc",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroTerminal.d.ts": "4b9de4c735c1ac8117150007bcd7672e9c8866c7cf5df6e7c35c2ac5def8b8e0",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/PDFAcroText.d.ts": "d3577467ea5859f6cc2f775f8e97fe1dca06a38a7d90b74fbb4d9687a43763cb",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/flags.d.ts": "b9a08fd532279b96b21ea7298ed91013dd47090e0873f978e6ed1ff4c7351c16",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/index.d.ts": "1c36b14684852516c7763c5bcdcfd05581e9d7138782e7719a892ed4cf7d72c9",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/acroform/utils.d.ts": "c0a1e9550a96b447f79842ea598bad8984fdc5a6d8503470646c58eefcbda2f1",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/annotation/AppearanceCharacteristics.d.ts": "c7c02136ccba0ea2de03f28c0c4ddedb0d714b4e22c7adeb4af1a2a640dd143e",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/annotation/BorderStyle.d.ts": "d3a81af4ace81b17c7076286a6ffd46506055decea6d2b10acbc786dac4690f1",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/annotation/PDFAnnotation.d.ts": "8b6254b9b95d790014bf909cbfffc67ee44217cba56b76a676ed1aec184d507e",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/annotation/PDFWidgetAnnotation.d.ts": "d3b7d2950391fd273af9a6627e1e119c316245c9069882b1553f11250f8b9d81",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/annotation/flags.d.ts": "eadfdaea8c75a894d9aa222795011604a151510b6ff17ed05e403053523e2a2b",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/annotation/index.d.ts": "5078182e3cf735d60d7eab53385d3e15a55f440da80bdddc6bbf75f83398623b",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/document/PDFCrossRefSection.d.ts": "5defe6ab89905e523061a55d234448a8fc54c29f2552f9f2a357af8b6977f948",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/document/PDFHeader.d.ts": "5ea041f4b495d455b4bf2d49f8ad9d31be97873c32bb1886c3f464dc71129682",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/document/PDFTrailer.d.ts": "9bb4f5cf9a670ae32ce0b3aa62632620929f4a9c0848136a2bd6ae9a84b944d2",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/document/PDFTrailerDict.d.ts": "e5b5ebee4cfc895a5bd093c604843590ec96d594efe5f2dc8eea23e097c3f352",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/embedders/CustomFontEmbedder.d.ts": "f0673535ab28b74bf0d127ae665a4e67d84e260161bef2c25bfdb8fb25f4402c",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/embedders/CustomFontSubsetEmbedder.d.ts": "2b7bab1b28974ad208c32a4c17f41b0a9080433132a248d91c395052f6714b31",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/embedders/FileEmbedder.d.ts": "be203ade74ecc8d90d584052f150f16b1244240a602aff190751fe96e85a9321",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/embedders/JavaScriptEmbedder.d.ts": "104da2ab8b6ce338a8f13be420b1f90997364255f6d64dcc49a52276d97b8ba8",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/embedders/JpegEmbedder.d.ts": "b431d91f9d3637bd39cf6e584da299d4ecb929666758b906688232ba715dda95",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/embedders/PDFPageEmbedder.d.ts": "2f9b5065babf295c092b695c581f6e98b090d8a4341677692e382e88dbe2d02a",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/embedders/PngEmbedder.d.ts": "54f8867dfbe28597d34f91e8196069d982b5a65d7cd3280bfe9551ca257e2576",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/embedders/StandardFontEmbedder.d.ts": "eb5b909d0816e946b5a6bdb5ceec4c631576cc133c07d2437969d0439793ef4b",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/errors.d.ts": "d1640e4ca6a8943ab92e6746ab1faeb4618e766f8121d007d34992315f27f39e",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/index.d.ts": "ee5e483e2634111b4b95dad655e2efb9ba113703c0254c995f1bfaf215f392c8",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/interactive/ViewerPreferences.d.ts": "11ecd53b61cfb7659a9d21ea624e75825a39480c1b0a157b7fc0b1d668966f74",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFArray.d.ts": "2c62e91c919a0f643caf4226cfb4f1f5b17762093377b998ae55338b8f573bb7",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFBool.d.ts": "bde75da11a3ae1649dfe63ece9bf0569f3888dee66e54525dd078de390b76286",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFDict.d.ts": "8c813b5173d7777039b9203bf32bd859a9a23b2aa21f3740bfd051ef96c66fc8",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFHexString.d.ts": "0639222fc470ed1e8fb97062e95b7c264245f704c42569e81a5e1b6b47382966",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFInvalidObject.d.ts": "90b3a0ee225216a7ab155ddb02fffa5d5cb4f3d217c5d82ea6a08431c1af2402",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFName.d.ts": "dcfcf25d751d3f6c844f17033ae3f49be020c0e3b4a214e08fcd8fc82097ecfd",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFNull.d.ts": "1dea142fa54883dff9fd057f923c4aa6f134b847efe213b4a111e0f11f0df0a5",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFNumber.d.ts": "351d1c2e3fb4eb23d15f1187f81cb9b11d36fd6b5c678c765fc3a0296c21bc99",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFObject.d.ts": "204a2f73dcf97664d74e30aff1ddc24e886cac552ec483c681f82af5acfea7c8",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFRawStream.d.ts": "b816c6f56337a808721d72c04d5258ee97a922eeea146a930a29363931a274e7",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFRef.d.ts": "28bd2e876d6f5423d7b6f4e1b697fc5dbe32266b046086dcc88dfadc86bdba7e",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFStream.d.ts": "688cdc37a8022af805e9ae846c7b32859d0a24dbb7d40546c3d6ddc23f25758a",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/objects/PDFString.d.ts": "07c42b7ec44ad75822520fc772fc8bd647827a7587796a48bca353f34e726a68",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/operators/PDFOperator.d.ts": "248c56150fdaec89382223eeb4807a028dd15dd715d8aef2b2592c46cb1663a0",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/operators/PDFOperatorNames.d.ts": "948446c52c54b41e032b30ed72c90b44c994fc16e6b36dc77718c752547c2a06",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/parser/BaseParser.d.ts": "a4ba9b0023249ecd09dbd3fbcb4299851e7df00b6a92e44ca2dd1fe6d5e0d0e0",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/parser/ByteStream.d.ts": "572735fc11a350e652cbdf5a30f6663675eea11174dfdcc10979c2096b7ab7fc",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/parser/PDFObjectParser.d.ts": "36df83951486557bef14cd416431beb9855e877c1927c371ea31d3673c474a43",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/parser/PDFObjectStreamParser.d.ts": "23e346b8b74219a19ffe26d082ca561f6aa49995bd032242a9a5df5445eff0f9",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/parser/PDFParser.d.ts": "bfb44eb39cc699822b938f61e219f97c6914f72e3ce6174243a334620f4a71be",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/parser/PDFXRefStreamParser.d.ts": "489dbc8690e507346a90a81355f8d0d3feee0d1c6cf8b1ddcb1af3ecfcae4c59",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/streams/Stream.d.ts": "115942c9b9e0c3af469acea2ba3662e37b3961828d75be391a271ac83b3ab955",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/streams/decode.d.ts": "959af56c1091ebad1808aeb36bf901e27a0ca65d1d45395c7429dd8bed5b3e8c",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/structures/PDFCatalog.d.ts": "8a686a0b42c873d8aa4b72c199eefeb713462a696ae420698b5ed2b0a68193dc",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/structures/PDFContentStream.d.ts": "2cded5c6d0b2dacd418fb63d203cf98007015ea8d4ceda50deb3355fa3f021f8",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/structures/PDFCrossRefStream.d.ts": "8949ba296fab817d5e41905df7cfd5840e4c820e5bd141d392120cafe77487b5",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/structures/PDFFlateStream.d.ts": "ea076ee3066eb7868056c3986c914019e8a0b9fcdaa4dd7778b7c372e1818385",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/structures/PDFObjectStream.d.ts": "a65c82cb69c75fd70fadc4234a6fa9c6475e83de97866b3b42edaaf172ffd36d",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/structures/PDFPageLeaf.d.ts": "f1feee3bf123251a13e8ab615f49e4cd0672ec9dab8ccae48547899e21edf32c",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/structures/PDFPageTree.d.ts": "6dace086b8f3943cd655e17facc4642a40946a4435a19e1bc6dd4921f87123e7",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/syntax/CharCodes.d.ts": "0505eaa16c80073f10be1ddecb5332592333db6ed8ed0b95c33cd7b994b8a479",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/writers/PDFStreamWriter.d.ts": "9ece168329b59a174241899baabfff3810c447b50af7ad208bc672d9f98bb212",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/core/writers/PDFWriter.d.ts": "8d2d4362b4d089dda5fa2f90978918cd323da132834fe253c66dbd070151d9f1",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/index.d.ts": "079fe72e307ded61d01bee8d12f4603426a1f30db6e7e9114e1cee36b09d91c1",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/types/fontkit.d.ts": "18d04690ca4b053a3c83a5aa13dfcaef2f6fd9b0fdc00e0b114eb67285b1fc16",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/types/index.d.ts": "858a1384d057f847e35c037085081aa6db325e41cbcf99d811c4a8d97eeff0dd",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/types/matrix.d.ts": "f8e1caaf276800b302f2108fa2bbc2ef4ba89a040debe758e5e10b01ce206624",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/Cache.d.ts": "72f2b044547b334a9434934982b22bac1035f1f25cb9816295d14d506c5649ea",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/arrays.d.ts": "c375763cae88da361d081391267763a4231cd8067993d8fc6dc5370478f32f07",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/async.d.ts": "62dcc9dcaa8e368af4ffddc33bc44f3e48fa21e03bf6a04100a889a909e1e9e5",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/base64.d.ts": "de55e16fc3ad00868395f15365c783298b51fc4c30b77dfb0593cf87cc95a2a1",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/errors.d.ts": "7d0bef5ec280f8fbf4740fcf0bcdfe7835f8aeb7ebf2c82d3059337d0d8606d4",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/index.d.ts": "538290352c32f5b48f81a86fde30c6f4874881ff19538031058534883d9b7272",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/numbers.d.ts": "fe622d3fb8472cfee515916597034e79ad62f5b96ced18c8c8e0877ff1fd03c5",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/objects.d.ts": "b19f885dea651f95976b5d391f5581df32f69deee71eef0b3770d5baf6b238f4",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/pdfDocEncoding.d.ts": "9ba40f5c6f5aa3cdb8bede4e28803e9a05f253049d483155b35922c7000248d6",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/rng.d.ts": "c7b610ccaf7e6c2d00b1ca3a132a28b8b8d754e30798ae46ebbfa13f149faa9f",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/strings.d.ts": "6a4477c60589dc29a5fbb5382034a36008e9cb4e8c4978163d4085228d6e3114",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/unicode.d.ts": "c700afbcbe055cb5939fcf815c6d3e52ddaf148619afcf0bebd389f75d8b72ac",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/cjs/utils/validators.d.ts": "7f8f332fbcd19b69ba48533fdd3a66bcbd4402eabf3f5d7b4be84cda5591a82b",
"https://cdn.esm.sh/v66/pdf-lib@1.17.1/deno/pdf-lib.js": "edf68ad7a3be4d23c2aa32ed6c5a5bd0c12567242d5eb65994d599d55d01958e",
"https://cdn.esm.sh/v66/react-dom@17.0.2/deno/react-dom.js": "38f06ceffb61a27fbfbe09d8de2677a73e19335448e41863abd18b2c39af1882",
"https://cdn.esm.sh/v66/react@17.0.2/deno/react.js": "97486becbaff9a6b9b09bca0b248c4b7c612788556d53392f5bd9aff509d156a",
"https://cdn.esm.sh/v66/scheduler@0.20.2/deno/scheduler.js": "b4cdd1b96d31eaba84e8d2c4cac10481597ca6d7b533ff859bcf1d5ba079cf27",
"https://cdn.esm.sh/v66/tslib@1.14.1/deno/tslib.js": "2a9240e861900c5c0a5dddf3e06cd519a9b4b5d3006d7699b8d035a386958156",
"https://deno.land/std@0.127.0/_util/assert.ts": "6396c1bd0361c4939e7f32f9b03efffcd04b640a1b206ed67058553d6cb59cc4",
"https://deno.land/std@0.127.0/_util/os.ts": "49b92edea1e82ba295ec946de8ffd956ed123e2948d9bd1d3e901b04e4307617",
"https://deno.land/std@0.127.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3",
"https://deno.land/std@0.127.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09",
"https://deno.land/std@0.127.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b",
"https://deno.land/std@0.127.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633",
"https://deno.land/std@0.127.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee",
"https://deno.land/std@0.127.0/path/mod.ts": "4275129bb766f0e475ecc5246aa35689eeade419d72a48355203f31802640be7",
"https://deno.land/std@0.127.0/path/posix.ts": "663e4a6fe30a145f56aa41a22d95114c4c5582d8b57d2d7c9ed27ad2c47636bb",
"https://deno.land/std@0.127.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9",
"https://deno.land/std@0.127.0/path/win32.ts": "e7bdf63e8d9982b4d8a01ef5689425c93310ece950e517476e22af10f41a136e",
"https://esm.sh/@pdf-lib/fontkit@^1.0.0": "7415e16c6c0c4776ae5378c8da0a94611d15c98892f35bea7beb796895195f29",
"https://esm.sh/lodash@4.2/shuffle?no-check": "20996d80527bf3498a55de5d101be1d54e3e10e878999fd7c8ec23752db21e08",
"https://esm.sh/pdf-lib@^1.11.1": "456a82f5d6ada35eedfa8517dd5405440b583c6d1dfcee41d80dabc53ef69ac5",
"https://esm.sh/react-dom@17": "30211652040d1e94159b216b27c1d43345e174b801d84507cebdc9b8b3831507",
"https://esm.sh/react@17": "deb68fd867c032081cc8c5e9a77936dd0e35508c6e6fe1651abe6a82d79793ba"
}

163
main.ts
View File

@@ -1,163 +0,0 @@
import {
PDFDocument,
PDFPage,
rgb,
} from "https://cdn.skypack.dev/pdf-lib@^1.11.1?dts";
import fontkit from "https://cdn.skypack.dev/@pdf-lib/fontkit@^1.0.0?dts";
type Result = {
id: number;
word: string;
answer: string;
};
async function generateVoca(levels: number[], day: number) {
const re =
/<p class="word">(?<id>\d+?)\. (?<word>.+?)<\/p>.*?<span class="af_answer">(?<answer>.+?)<\/span>/gis;
const res = await fetch(
`https://www.hackers.co.kr/?c=s_toeic/new_voca_toeic_testpaper/toeic_study/new_paper&mode=new_view&level=${
levels.join(",")
}&level_type=&lang_text=2&question=1000&day3=${day}&day4=${day}&day_auto=N&index=1`,
);
const body = await res.text();
const matches = [...body.matchAll(re)].map((m) => ({
...(m.groups as unknown as Result),
id: Number.parseInt(m.groups?.id as string),
}));
const pdfDoc = await PDFDocument.create();
const fontBytes = await Deno.readFile("./NanumGothic.ttf");
pdfDoc.registerFontkit(fontkit);
const customFont = await pdfDoc.embedFont(fontBytes);
const fontSize = 12;
const margin = 20;
const perColumn = 25;
const perPage = 50;
let page!: PDFPage;
let col = -1;
let yCursor = 1;
// 문제 생성
for (let i = 0; i < matches.length; ++i) {
const data = matches[i];
if (i % perPage === 0) {
page = pdfDoc.addPage();
yCursor = 1;
col = -1;
}
if (i % perColumn === 0) {
col++;
yCursor = 1;
}
page.drawText(`${data.id}. ${data.word}`, {
x: margin + (page.getWidth() / 2) * col,
y: page.getHeight() - (fontSize + margin) * yCursor,
size: fontSize,
font: customFont,
color: rgb(0, 0, 0),
});
page.drawText("_________________", {
x: margin + (page.getWidth() / 2) * col + 140,
y: page.getHeight() - (fontSize + margin) * yCursor - 3,
size: fontSize,
font: customFont,
color: rgb(0, 0, 0),
});
yCursor++;
}
// 답 생성
for (let i = 0; i < matches.length; ++i) {
const data = matches[i];
if (i % perPage === 0) {
page = pdfDoc.addPage();
yCursor = 1;
col = -1;
}
if (i % perColumn === 0) {
col++;
yCursor = 1;
}
page.drawText(`${data.id}. ${data.word}`, {
x: margin + (page.getWidth() / 2) * col,
y: page.getHeight() - (fontSize + margin) * yCursor,
size: fontSize,
font: customFont,
color: rgb(0, 0, 0),
});
page.drawText("_________________", {
x: margin + (page.getWidth() / 2) * col + 140,
y: page.getHeight() - (fontSize + margin) * yCursor - 3,
size: fontSize,
font: customFont,
color: rgb(0, 0, 0),
});
page.drawText(data.answer, {
x: margin + (page.getWidth() / 2) * col + 140,
y: page.getHeight() - (fontSize + margin) * yCursor,
size: 8,
font: customFont,
color: rgb(1, 0, 0),
});
yCursor++;
}
const pdfBytes = await pdfDoc.save();
return pdfBytes;
}
const port = 8055;
const server = Deno.listen({ port });
console.log(
`HTTP webserver running. Access it at: http://localhost:${port}/`,
);
for await (const conn of server) {
serveHttp(conn);
}
async function serveHttp(conn: Deno.Conn) {
const httpConn = Deno.serveHttp(conn);
for await (const requestEvent of httpConn) {
const { searchParams, pathname } = new URL(requestEvent.request.url);
if (pathname.startsWith("/generate")) {
if (!searchParams.has("level") || !searchParams.has("day")) {
requestEvent.respondWith(
new Response("Not Found", {
status: 404,
}),
);
continue;
}
const levels = searchParams.getAll("level").map((l) =>
Number.parseInt(l)
);
const day = Number.parseInt(searchParams.get("day")!) ?? 1;
const data = await generateVoca(levels, day);
requestEvent.respondWith(
new Response(data, {
status: 200,
headers: {
"Content-Disposition": 'attachment; filename="voca.pdf"',
},
}),
);
} else if (pathname.startsWith("/") || pathname.startsWith("/index.html")) {
const file = await Deno.readFile("./index.html");
requestEvent.respondWith(
new Response(file, {
headers: {
"content-type": "text/html",
},
}),
);
}
}
}

13
scripts.yml Normal file
View File

@@ -0,0 +1,13 @@
scripts:
crawl:
cmd: src/crawl.ts
allow:
- net
- write
- read
lock: lock.json
config: deno.jsonc
bundle: deno bundle -c deno.jsonc src/website/mod.ts doc/website.bundle.js
generate-lock: deno cache --lock=lock.json --lock-write src/deps.ts

52
src/crawl.ts Normal file
View File

@@ -0,0 +1,52 @@
import { path } from "./deps.ts";
import { JSONType, Voca } from "./types.ts";
const __dirname = path.dirname(path.fromFileUrl(import.meta.url));
async function getVocaList(levels: number[], day: number): Promise<Voca[]> {
const re =
/<p class="word">(?:\d+?)\. (?<word>.+?)<\/p>.*?<span class="af_answer">(?<answer>.+?)<\/span>/gis;
const res = await fetch(
`https://www.hackers.co.kr/?c=s_toeic/new_voca_toeic_testpaper/toeic_study/new_paper&mode=new_view&level=${
levels.join(",")
}&level_type=&lang_text=2&question=1000&day3=${day}&day4=${day}&day_auto=N&index=1`,
);
const body = await res.text();
const matches = [...body.matchAll(re)].map((m) => ({
...(m.groups as unknown as Voca),
}));
return matches;
}
const levels = [6, 7, 8, 9];
const days = [...Array(30)].map((_, i) => i + 1);
const result: JSONType = { data: [] };
for (const level of levels) {
for (const day of days) {
console.log(`GET: ${level}-${day}`);
const voca_list = await getVocaList([level], day);
voca_list.sort((a, b) => {
const wordA = a.word.toUpperCase();
const wordB = b.word.toUpperCase();
if (wordA < wordB) {
return -1;
}
if (wordA > wordB) {
return 1;
}
return 0;
});
result.data.push({
level,
day,
voca_list,
});
}
}
Deno.writeTextFileSync(
path.join(__dirname, "../doc/", "voca.json"),
JSON.stringify(result),
);

2
src/deps.ts Normal file
View File

@@ -0,0 +1,2 @@
export * as path from "https://deno.land/std@0.127.0/path/mod.ts";
export * from "./website/deps.ts";

14
src/types.ts Normal file
View File

@@ -0,0 +1,14 @@
export type Voca = {
word: string;
answer: string;
};
export type VocaChunk = {
level: number;
day: number;
voca_list: Voca[];
};
export type JSONType = {
data: VocaChunk[];
};

10
src/website/app.tsx Normal file
View File

@@ -0,0 +1,10 @@
import { React } from "./deps.ts";
import DownloadForm from "./components/download-form.tsx";
export default function App() {
return (
<div>
<DownloadForm />
</div>
);
}

View File

@@ -0,0 +1,99 @@
import { React } from "../deps.ts";
import { downloadVocaQuiz } from "../pdf.ts";
export default function DownloadForm() {
const [levels, setLevels] = React.useState<number[]>([6, 7]);
const [day, setDay] = React.useState<number>(1);
const handleSubmit: React.FormEventHandler = React.useCallback((ev) => {
downloadVocaQuiz(levels.sort(), day);
ev.preventDefault();
}, [levels, day]);
const handleDayChange: React.FormEventHandler<HTMLSelectElement> = (ev) => {
const select = ev.target as HTMLSelectElement;
setDay(Number.parseInt(select.value));
};
const handleLevelChange: React.FormEventHandler<HTMLInputElement> = (ev) => {
const checkbox = ev.target as HTMLInputElement;
if (checkbox.checked) {
setLevels((prev) => [...prev, Number.parseInt(checkbox.value)]);
} else {
setLevels((prev) =>
prev.filter((val) => val !== Number.parseInt(checkbox.value))
);
}
};
return (
<>
<form onSubmit={handleSubmit}>
<fieldset>
<legend> </legend>
<div>
<input
type="checkbox"
id="10"
value="10"
checked={levels.find((val) => val === 10) !== undefined}
onChange={handleLevelChange}
/>
<label htmlFor="10"> </label>
</div>
<div>
<input
type="checkbox"
id="6"
value="6"
checked={levels.find((val) => val === 6) !== undefined}
onChange={handleLevelChange}
/>
<label htmlFor="6">(550+), (650+)</label>
</div>
<div>
<input
type="checkbox"
id="7"
value="7"
checked={levels.find((val) => val === 7) !== undefined}
onChange={handleLevelChange}
/>
<label htmlFor="7">(750+)</label>
</div>
<div>
<input
type="checkbox"
id="8"
value="8"
checked={levels.find((val) => val === 8) !== undefined}
onChange={handleLevelChange}
/>
<label htmlFor="8">(850+)</label>
</div>
<div>
<input
type="checkbox"
id="9"
value="9"
checked={levels.find((val) => val === 9) !== undefined}
onChange={handleLevelChange}
/>
<label htmlFor="9">(900+)</label>
</div>
</fieldset>
<div>
<label htmlFor="day"></label>
<select id="day" value={day} onChange={handleDayChange}>
{[...Array(30)].map((_, i) => <option value={i + 1}>{i + 1}
</option>)}
</select>
</div>
<div>
<button type="submit">PDF </button>
</div>
</form>
</>
);
}

5
src/website/deps.ts Normal file
View File

@@ -0,0 +1,5 @@
export { PDFDocument, PDFPage, rgb } from "https://esm.sh/pdf-lib@^1.11.1";
export { default as fontkit } from "https://esm.sh/@pdf-lib/fontkit@^1.0.0";
export { default as React } from "https://esm.sh/react@17";
export { default as ReactDOM } from "https://esm.sh/react-dom@17";
export { default as shuffle } from "https://esm.sh/lodash@4.2/shuffle?no-check";

7
src/website/mod.ts Normal file
View File

@@ -0,0 +1,7 @@
import { ReactDOM } from "./deps.ts";
import app from "./app.tsx";
export function render() {
const rootEl = document.getElementById("root");
ReactDOM.render(app(), rootEl);
}

110
src/website/pdf.ts Normal file
View File

@@ -0,0 +1,110 @@
import { fontkit, PDFDocument, PDFPage, rgb, shuffle } from "./deps.ts";
import { JSONType, Voca } from "../types.ts";
function downloadBuffer(buffer: Uint8Array, fileName: string) {
const a: HTMLAnchorElement = document.createElement("a");
const blob = new Blob([buffer], { type: "application/octet-stream" });
a.href = URL.createObjectURL(blob);
a.download = fileName;
document.body.appendChild(a);
a.style.display = "none";
a.click();
a.remove();
}
export async function makePdf(voca_list: Voca[]) {
const pdfDoc = await PDFDocument.create();
const fontBytes = await fetch("./NanumGothic.ttf").then((res) =>
res.arrayBuffer()
);
pdfDoc.registerFontkit(fontkit);
const customFont = await pdfDoc.embedFont(fontBytes);
const fontSize = 12;
const margin = 20;
const perColumn = 25;
const perPage = 50;
let page!: PDFPage;
let col = -1;
let yCursor = 1;
// 문제 생성
for (let i = 0; i < voca_list.length; ++i) {
const data = voca_list[i];
if (i % perPage === 0) {
page = pdfDoc.addPage();
yCursor = 1;
col = -1;
}
if (i % perColumn === 0) {
col++;
yCursor = 1;
}
page.drawText(`${i + 1}. ${data.word}`, {
x: margin + (page.getWidth() / 2) * col,
y: page.getHeight() - (fontSize + margin) * yCursor,
size: fontSize,
font: customFont,
color: rgb(0, 0, 0),
});
page.drawText("_________________", {
x: margin + (page.getWidth() / 2) * col + 140,
y: page.getHeight() - (fontSize + margin) * yCursor - 3,
size: fontSize,
font: customFont,
color: rgb(0, 0, 0),
});
yCursor++;
}
// 답 생성
for (let i = 0; i < voca_list.length; ++i) {
const data = voca_list[i];
if (i % perPage === 0) {
page = pdfDoc.addPage();
yCursor = 1;
col = -1;
}
if (i % perColumn === 0) {
col++;
yCursor = 1;
}
page.drawText(`${i + 1}. ${data.word}`, {
x: margin + (page.getWidth() / 2) * col,
y: page.getHeight() - (fontSize + margin) * yCursor,
size: fontSize,
font: customFont,
color: rgb(0, 0, 0),
});
page.drawText("_________________", {
x: margin + (page.getWidth() / 2) * col + 140,
y: page.getHeight() - (fontSize + margin) * yCursor - 3,
size: fontSize,
font: customFont,
color: rgb(0, 0, 0),
});
page.drawText(data.answer, {
x: margin + (page.getWidth() / 2) * col + 140,
y: page.getHeight() - (fontSize + margin) * yCursor,
size: 8,
font: customFont,
color: rgb(1, 0, 0),
});
yCursor++;
}
const pdfBytes = await pdfDoc.save();
return pdfBytes;
}
export async function downloadVocaQuiz(levels: number[], day: number) {
const json: JSONType = await (await fetch("/voca.json")).json();
const voca_list = json.data.filter((chunk) =>
levels.includes(chunk.level) && chunk.day === day
).flatMap((chunk) => chunk.voca_list);
const bufferPdf = await makePdf(shuffle(voca_list));
downloadBuffer(bufferPdf, "voca.pdf");
}