thursday-agent 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/api/artifact/route.js +9 -9
- package/.next/server/app/api/artifact/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/files/route.js +3 -3
- package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/route.js +8 -8
- package/.next/server/app/api/bot/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/route.js +8 -8
- package/.next/server/app/api/bot/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/thread/[id]/route.js +3 -3
- package/.next/server/app/api/bot/thread/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/thread/route.js +3 -3
- package/.next/server/app/api/bot/thread/route.js.nft.json +1 -1
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/server/app/api/favicon/[host]/route.js.nft.json +1 -1
- package/.next/server/app/api/file/[...path]/route.js +4 -4
- package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/edit/route.js +11 -11
- package/.next/server/app/api/memory/edit/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/reach/route.js +11 -11
- package/.next/server/app/api/reach/route.js.nft.json +1 -1
- package/.next/server/app/api/routine/route.js +7 -7
- package/.next/server/app/api/routine/route.js.nft.json +1 -1
- package/.next/server/app/api/signins/route.js +5 -5
- package/.next/server/app/api/signins/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[source]/[name]/route.js +7 -7
- package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route.js +7 -7
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/call/route.js +5 -5
- package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/settings/route.js +5 -5
- package/.next/server/app/api/thursday/settings/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/text/route.js +13 -13
- package/.next/server/app/api/thursday/text/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/tool-call/route.js +12 -12
- package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/files/route.js +8 -8
- package/.next/server/app/api/workspace/files/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/route.js +9 -9
- package/.next/server/app/api/workspace/route.js.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +3 -3
- package/.next/server/app/artifact/[...path]/page.js +4 -4
- package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -1
- package/.next/server/app/page/server-reference-manifest.json +60 -60
- package/.next/server/app/page.js +5 -5
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__00qyw01._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__01ypm_z._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__021dkui._.js +3 -0
- package/.next/server/chunks/{[root-of-the-server]__18e65_-._.js → [root-of-the-server]__03xamry._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__05dp5tr._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__09gdscj._.js +7 -0
- package/.next/server/chunks/{[root-of-the-server]__10_7vqz._.js → [root-of-the-server]__0b36yfw._.js} +1 -1
- package/.next/server/chunks/{[root-of-the-server]__1gamvcz._.js → [root-of-the-server]__0jzwdg-._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__0mrk2it._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0nmust6._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__0svzjwa._.js +7 -0
- package/.next/server/chunks/{[root-of-the-server]__16yw3mb._.js → [root-of-the-server]__12m24xl._.js} +1 -1
- package/.next/server/chunks/{[root-of-the-server]__1zrwxis._.js → [root-of-the-server]__12tahb4._.js} +1 -1
- package/.next/server/chunks/{[root-of-the-server]__1ep-pao._.js → [root-of-the-server]__1_h4hf9._.js} +4 -4
- package/.next/server/chunks/{[root-of-the-server]__1-tdj60._.js → [root-of-the-server]__1de1o6m._.js} +2 -2
- package/.next/server/chunks/{[root-of-the-server]__1voqqyc._.js → [root-of-the-server]__1ignh6-._.js} +1 -1
- package/.next/server/chunks/[root-of-the-server]__1t02-1p._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1ygplx1._.js +1 -1
- package/.next/server/chunks/{[root-of-the-server]__11g20j-._.js → [root-of-the-server]__1yl5l25._.js} +1 -1
- package/.next/server/chunks/{[root-of-the-server]__1mbd2w_._.js → [root-of-the-server]__208vmyf._.js} +1 -1
- package/.next/server/chunks/{_1mfu9a3._.js → _02lipqs._.js} +1 -1
- package/.next/server/chunks/_05sa7xl._.js +1 -1
- package/.next/server/chunks/{_1rg5bfd._.js → _074f2ts._.js} +1 -1
- package/.next/server/chunks/_07nxi75._.js +3 -3
- package/.next/server/chunks/_08btiir._.js +7 -0
- package/.next/server/chunks/_0caua_s._.js +1 -1
- package/.next/server/chunks/{_0qoush_._.js → _0gt6cbj._.js} +1 -1
- package/.next/server/chunks/_0xygcxs._.js +3 -3
- package/.next/server/chunks/{_09c4we8._.js → _17i1lt2._.js} +1 -1
- package/.next/server/chunks/_19kea1l._.js +9 -9
- package/.next/server/chunks/_1gn2r2q._.js +3 -3
- package/.next/server/chunks/{_03niwml._.js → _1ntwp1s._.js} +1 -1
- package/.next/server/chunks/_1q6e56i._.js +3 -3
- package/.next/server/chunks/{_02fn1o3._.js → _1tkzgtm._.js} +1 -1
- package/.next/server/chunks/_1wl2g8_._.js +2 -2
- package/.next/server/chunks/{_1w6uf9k._.js → _1y3mnz4._.js} +1 -1
- package/.next/server/chunks/features_workspace_workspace_ts_13h82gv._.js +4 -4
- package/.next/server/chunks/features_workspace_workspace_ts_1iyjroj._.js +4 -4
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0cux6zt._.js → node_modules_consola_dist_chunks_prompt_mjs_04oxl25._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0w32bqh._.js → node_modules_consola_dist_chunks_prompt_mjs_0g87zst._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_1clmnaj._.js → node_modules_consola_dist_chunks_prompt_mjs_1341cnf._.js} +1 -1
- package/.next/server/chunks/ssr/{[root-of-the-server]__02jdtqa._.js → [root-of-the-server]__07660xu._.js} +2 -2
- package/.next/server/chunks/ssr/{[root-of-the-server]__0rnjkw2._.js → [root-of-the-server]__149x25m._.js} +2 -2
- package/.next/server/chunks/ssr/[root-of-the-server]__17h1ggo._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__19s8qyj._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1jyeu61._.js +1 -1
- package/.next/server/chunks/ssr/_088vzgn._.js +3 -0
- package/.next/server/chunks/ssr/{_0wupyvd._.js → _0_vnw9v._.js} +2 -2
- package/.next/server/chunks/ssr/{_1u5vsy-._.js → _0aeknva._.js} +2 -2
- package/.next/server/chunks/ssr/_0fo4552._.js +3 -3
- package/.next/server/chunks/ssr/{_0-ou1b0._.js → _0n2scfq._.js} +2 -2
- package/.next/server/chunks/ssr/_0o_o9ji._.js +3 -0
- package/.next/server/chunks/ssr/_0qne8xs._.js +3 -0
- package/.next/server/chunks/ssr/_0r0g9ki._.js +1 -1
- package/.next/server/chunks/ssr/_0v9r8g2._.js +3 -0
- package/.next/server/chunks/ssr/_0x8ophf._.js +1 -1
- package/.next/server/chunks/ssr/{_0ncuqct._.js → _0ztbn5q._.js} +2 -2
- package/.next/server/chunks/ssr/{_0w8r7o7._.js → _1-41lck._.js} +2 -2
- package/.next/server/chunks/ssr/{_10fwcz_._.js → _14dfh7a._.js} +2 -2
- package/.next/server/chunks/ssr/{_1f6s34p._.js → _15m5ctz._.js} +2 -2
- package/.next/server/chunks/ssr/{_11pnnvd._.js → _18-e7zi._.js} +2 -2
- package/.next/server/chunks/ssr/{_0y28gl3._.js → _1c5iqz1._.js} +3 -3
- package/.next/server/chunks/ssr/{_1dqaksc._.js → _1hbjh6n._.js} +2 -2
- package/.next/server/chunks/ssr/_1neoj22._.js +1 -1
- package/.next/server/chunks/ssr/{_1k0efi3._.js → _1sttj8x._.js} +2 -2
- package/.next/server/chunks/ssr/_1uij_rj._.js +1 -1
- package/.next/server/chunks/ssr/_1umbr78._.js +1 -1
- package/.next/server/chunks/ssr/{_17ble8k._.js → _1vtgiou._.js} +3 -3
- package/.next/server/chunks/ssr/_1w9w1ok._.js +1 -1
- package/.next/server/chunks/ssr/{_1z586yw._.js → _1z6pirx._.js} +2 -2
- package/.next/server/chunks/ssr/features_0796o8r._.js +1 -1
- package/.next/server/chunks/ssr/features_bot_1knyan7._.js +3 -0
- package/.next/server/chunks/ssr/features_bot_1kr0_m-._.js +3 -0
- package/.next/server/chunks/ssr/{features_config_11dpa7r._.js → features_config_0n0zu89._.js} +3 -3
- package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
- package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +1 -1
- package/.next/server/chunks/ssr/features_routine_components_routine-setting_tsx_055fknz._.js +1 -1
- package/.next/server/chunks/ssr/features_workspace_workspace_ts_1wc7_u_._.js +4 -4
- package/.next/server/chunks/ssr/{node_modules_1r5o-bo._.js → node_modules_00h1t1j._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1o9n7_n._.js → node_modules_02ficyi._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0u24mg0._.js → node_modules_03q71_j._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_138kcrz._.js → node_modules_03uejh6._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0x_2io2._.js → node_modules_06grs09._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0n1js5k._.js → node_modules_07mo9rn._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0bas34k._.js → node_modules_09e8kz_._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1dzye0n._.js → node_modules_09ikzel._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_18yn_bs._.js → node_modules_0_d_7gq._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0ka8te1._.js → node_modules_0_p8w7p._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0mark4f._.js → node_modules_0f5bmkb._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0sdjzae._.js → node_modules_0kwie-o._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1ozyial._.js → node_modules_0r-9e4n._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_156m1qh._.js → node_modules_0u_8z64._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0-ew8f8._.js → node_modules_0zf3wuu._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1xua-g1._.js → node_modules_1-7fc7h._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0ld7p-1._.js → node_modules_142z3o5._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0-8r9yw._.js → node_modules_180l3i0._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1tj7_9z._.js → node_modules_197vh1s._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0y5uubt._.js → node_modules_1_n9o9s._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0etz1i0._.js → node_modules_1fw32pg._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0bbwe-u._.js → node_modules_1hefp6h._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_097cl9f._.js → node_modules_1irot3r._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0uibk9z._.js → node_modules_1om2itc._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1zkzksd._.js → node_modules_1ubln7w._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_02uwbwp._.js → node_modules_1wyhtw9._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_133hjui._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0aczkbn._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1b3vwd3._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0ah684s._.js} +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +61 -61
- package/.next/static/chunks/{1ub9obhgfm4jl.js → 024plctckvq-1.js} +1 -1
- package/.next/static/chunks/04toe_3nqfjqt.js +1 -0
- package/.next/static/chunks/{0609ejkwuy4sf.js → 0_b_bi2pobasx.js} +2 -2
- package/.next/static/chunks/{3ro66d9dc70bc.js → 0dfvwgnyrp8qt.js} +1 -1
- package/.next/static/chunks/{314szf8yer-3n.js → 0f47nnshdlucs.js} +1 -1
- package/.next/static/chunks/0sowxe4nnl5qu.js +1 -0
- package/.next/static/chunks/{07vcuxousbmy1.js → 0sv142q1yrva2.js} +1 -1
- package/.next/static/chunks/{0q4ws7qd21chx.js → 0tp868040z9nn.js} +2 -2
- package/.next/static/chunks/{0unonxbajyknw.js → 1-63yde5eaz7i.js} +1 -1
- package/.next/static/chunks/14qitm0kwsb6g.js +15 -0
- package/.next/static/chunks/{2xjr5b-yk_h3o.js → 1bgvxd3xny53w.js} +1 -1
- package/.next/static/chunks/{245_cp14iz637.js → 1cyrrz4q871aj.js} +1 -1
- package/.next/static/chunks/1st3b0c9vhxg3.js +1 -0
- package/.next/static/chunks/{39miwvg4k-b2d.js → 1wbqaidq7vc3_.js} +1 -1
- package/.next/static/chunks/{0cl_fgkphk1oz.js → 28sxb_k460e9h.js} +1 -1
- package/.next/static/chunks/{3j-l8un0d77v7.js → 2v6e_9p95o2e3.js} +1 -1
- package/.next/static/chunks/{23tx-2paw9qa6.js → 3-qp777vtfglj.js} +1 -1
- package/.next/static/chunks/{2jbjyazqfqyoh.js → 33ekkscpcq-z1.js} +1 -1
- package/.next/static/chunks/388l-zszwa_jf.js +1 -0
- package/.next/static/chunks/{3vwjs5kq11417.js → 38edd4rpcbvzp.js} +1 -1
- package/.next/static/chunks/3bwrvpjk95_x4.js +1 -0
- package/.next/static/chunks/{42m371fn687r5.js → 3itdg6t243u6f.js} +1 -1
- package/.next/static/chunks/{2oa4gpkzjtpni.js → 44vre0f7xqsh-.js} +1 -1
- package/README.md +12 -12
- package/guide/bots.md +48 -8
- package/guide/calls.md +13 -12
- package/guide/setup.md +4 -2
- package/package.json +1 -1
- package/public/sounds/NOTICE +3 -0
- package/public/sounds/opening-land.ogg +0 -0
- package/public/sounds/opening-rise.ogg +0 -0
- package/public/sounds/opening-step-1.ogg +0 -0
- package/public/sounds/opening-step-2.ogg +0 -0
- package/public/sounds/opening-step-3.ogg +0 -0
- package/skills/README.md +3 -0
- package/skills/artifact/SKILL.md +6 -5
- package/skills/artifact/references/book.md +22 -8
- package/skills/artifact/references/deck.md +4 -2
- package/skills/artifact/references/document.md +9 -0
- package/skills/artifact/references/sheet.md +108 -0
- package/skills/artifact/runtime/book/book.css +75 -0
- package/skills/artifact/runtime/book/book.html +6 -3
- package/skills/artifact/runtime/book/book.js +21 -0
- package/skills/artifact/runtime/canvas/canvas.css +1 -1
- package/skills/artifact/runtime/canvas/canvas.js +11 -1
- package/skills/artifact/runtime/deck/deck.css +164 -1
- package/skills/artifact/runtime/deck/deck.js +76 -1
- package/skills/artifact/runtime/document/docx.js +631 -0
- package/skills/artifact/runtime/document/markdown.mjs +58 -2
- package/skills/artifact/runtime/document/quick.css +66 -0
- package/skills/artifact/runtime/document/quick.html +1 -0
- package/skills/artifact/runtime/document/quick.js +154 -0
- package/skills/artifact/runtime/document/word.mjs +65 -0
- package/skills/artifact/runtime/sheet/format.mjs +385 -0
- package/skills/artifact/runtime/sheet/formula.mjs +755 -0
- package/skills/artifact/runtime/sheet/sheet.css +499 -0
- package/skills/artifact/runtime/sheet/sheet.html +102 -0
- package/skills/artifact/runtime/sheet/sheet.js +1361 -0
- package/skills/artifact/runtime/sheet/xlsx.mjs +320 -0
- package/skills/artifact/runtime/shell/head.html +1 -1
- package/skills/artifact/runtime/shell/shell.css +3 -0
- package/skills/artifact/runtime/shell/wear.mjs +47 -1
- package/skills/artifact/runtime/vendor/fflate.LICENSE.md +23 -0
- package/skills/artifact/runtime/vendor/fflate.mjs +2710 -0
- package/skills/artifact/scripts/book.mjs +141 -5
- package/skills/artifact/scripts/chart.mjs +229 -11
- package/skills/artifact/scripts/document.mjs +29 -2
- package/skills/artifact/scripts/spreadsheet.mjs +1068 -0
- package/skills/data-report/SKILL.md +8 -1
- package/.next/server/chunks/[root-of-the-server]__0aijj66._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0tvoct-._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__118qjk_._.js +0 -7
- package/.next/server/chunks/[root-of-the-server]__1b8tp42._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1gzcbda._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1qcn1ti._.js +0 -7
- package/.next/server/chunks/_0xx3ryc._.js +0 -7
- package/.next/server/chunks/ssr/[root-of-the-server]__1y5_1cv._.js +0 -3
- package/.next/server/chunks/ssr/_0l1-xc6._.js +0 -3
- package/.next/server/chunks/ssr/_1g48r6t._.js +0 -3
- package/.next/server/chunks/ssr/features_bot_1k25jdg._.js +0 -3
- package/.next/server/chunks/ssr/features_bot_1s_-2vj._.js +0 -3
- package/.next/server/chunks/ssr/lib_utils_ts_0_f1xvm._.js +0 -3
- package/.next/static/chunks/00d54fcfm-lko.js +0 -1
- package/.next/static/chunks/0gjlsu6vrfzod.js +0 -1
- package/.next/static/chunks/17yqt1p_svv13.js +0 -1
- package/.next/static/chunks/203pbwecfs3tm.js +0 -1
- package/.next/static/chunks/3ghvoe_mlljzs.js +0 -15
- package/.next/static/chunks/3gn7dubb4-pwy.js +0 -1
- /package/.next/static/{RtLRT9EEaGn-OqwpMFdYg → VtbCMn-0G969p8QJsWdGv}/_buildManifest.js +0 -0
- /package/.next/static/{RtLRT9EEaGn-OqwpMFdYg → VtbCMn-0G969p8QJsWdGv}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{RtLRT9EEaGn-OqwpMFdYg → VtbCMn-0G969p8QJsWdGv}/_ssgManifest.js +0 -0
|
@@ -17,9 +17,12 @@
|
|
|
17
17
|
// - [x] done / - [ ] next a checklist the reader can tick
|
|
18
18
|
//  alone in its paragraph: a picture with its caption
|
|
19
19
|
// | Item | Value | a column aligned right (---:) is read as numbers
|
|
20
|
+
// a claim.[^1] a footnote, numbered as it is first cited, its line
|
|
21
|
+
// [^1]: Where it comes from anywhere, gathered at the end of the document
|
|
20
22
|
//
|
|
21
23
|
// HTML written inside the Markdown passes through untouched, for tabs, a chip, a figure a
|
|
22
24
|
// chart is drawn into. Comments are dropped: the outlines' guidance never reaches the page.
|
|
25
|
+
import { markSvg } from "../shell/wear.mjs";
|
|
23
26
|
import { Marked, Tokenizer } from "../vendor/marked.mjs";
|
|
24
27
|
|
|
25
28
|
const escape = (text) =>
|
|
@@ -157,6 +160,52 @@ const markdown = new Marked({
|
|
|
157
160
|
},
|
|
158
161
|
});
|
|
159
162
|
|
|
163
|
+
/** A footnote's own line, `[^id]: what it says`, and a citation of one in the text. */
|
|
164
|
+
const NOTE_LINE = /^\[\^([^\]\s]+)\]:\s*(.+)$/;
|
|
165
|
+
const CITE = /\[\^([^\]\s]+)\](?!:)/g;
|
|
166
|
+
const FENCE = /^\s*(```|~~~)/;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* `[^id]` citations and `[^id]: …` lines as the document's own footnotes (quick.css): each
|
|
170
|
+
* citation a numbered link, in the order first cited, and the notes gathered at the end.
|
|
171
|
+
* Code is left as written; a citation with no note, or a note never cited, stays as text.
|
|
172
|
+
*/
|
|
173
|
+
function footnotes(text) {
|
|
174
|
+
const notes = new Map();
|
|
175
|
+
const kept = [];
|
|
176
|
+
let fenced = false;
|
|
177
|
+
for (const line of text.split("\n")) {
|
|
178
|
+
if (FENCE.test(line)) fenced = !fenced;
|
|
179
|
+
const note = fenced ? null : NOTE_LINE.exec(line);
|
|
180
|
+
if (note) notes.set(note[1], note[2]);
|
|
181
|
+
else kept.push(line);
|
|
182
|
+
}
|
|
183
|
+
if (!notes.size) return { text, notes: "" };
|
|
184
|
+
const order = [];
|
|
185
|
+
const anchor = (id) => `fn-${id.replace(/[^\p{L}\p{N}_-]/gu, "-")}`;
|
|
186
|
+
fenced = false;
|
|
187
|
+
const cited = kept.map((line) => {
|
|
188
|
+
if (FENCE.test(line)) fenced = !fenced;
|
|
189
|
+
if (fenced) return line;
|
|
190
|
+
return line.replace(CITE, (whole, id) => {
|
|
191
|
+
if (!notes.has(id)) return whole;
|
|
192
|
+
if (!order.includes(id)) order.push(id);
|
|
193
|
+
const n = order.indexOf(id) + 1;
|
|
194
|
+
return `<sup class="fn"><a href="#${anchor(id)}" id="${anchor(id)}-ref">${n}</a></sup>`;
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
const items = order.map(
|
|
198
|
+
(id) =>
|
|
199
|
+
`<li id="${anchor(id)}">${markdown.parseInline(notes.get(id))} <a class="fn-back" href="#${anchor(id)}-ref" aria-label="Back to the text">↩</a></li>`,
|
|
200
|
+
);
|
|
201
|
+
return {
|
|
202
|
+
text: cited.join("\n"),
|
|
203
|
+
notes: items.length
|
|
204
|
+
? `\n<ol class="footnotes">\n${items.join("\n")}\n</ol>\n`
|
|
205
|
+
: "",
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
160
209
|
/** The keys the line over and under the title is made of. */
|
|
161
210
|
const KEY_LINE = /^(kicker|date|by|status|tone)\s*:\s*\S/i;
|
|
162
211
|
|
|
@@ -189,14 +238,21 @@ function frontMatter(text) {
|
|
|
189
238
|
/** The document's body, as the page's put writes it, from a Markdown text. */
|
|
190
239
|
export function documentBody(text) {
|
|
191
240
|
const { meta, rest } = frontMatter(text.replace(/<!--[\s\S]*?-->/g, ""));
|
|
192
|
-
|
|
241
|
+
const cited = footnotes(rest);
|
|
242
|
+
let html = markdown.parse(cited.text) + cited.notes;
|
|
193
243
|
|
|
194
244
|
// `by` may name several, split by commas: who a memo is from and for, who attended
|
|
195
245
|
const who = (meta.by ?? "")
|
|
196
246
|
.split(",")
|
|
197
247
|
.map((one) => one.trim())
|
|
198
248
|
.filter(Boolean)
|
|
199
|
-
.map((one) =>
|
|
249
|
+
.map((one) =>
|
|
250
|
+
// The bot writing now wears its own face, as the page's head does
|
|
251
|
+
one.toLowerCase() === process.env.THURSDAY_BOT?.trim().toLowerCase() &&
|
|
252
|
+
markSvg(14)
|
|
253
|
+
? `<span class="chip who bot">${markSvg(14)}${escape(one)}</span>`
|
|
254
|
+
: `<span class="chip who">${escape(one)}</span>`,
|
|
255
|
+
);
|
|
200
256
|
const tone = ["good", "warn", "bad"].includes(meta.tone)
|
|
201
257
|
? ` ${meta.tone}`
|
|
202
258
|
: "";
|
|
@@ -296,6 +296,31 @@ body.pg-toc-shut .pg-toc {
|
|
|
296
296
|
:where(.pg-paper) .chip.who::before {
|
|
297
297
|
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round'%3E%3Ccircle cx='12' cy='8' r='4'/%3E%3Cpath d='M4 21a8 8 0 0 1 16 0'/%3E%3C/svg%3E");
|
|
298
298
|
}
|
|
299
|
+
:where(.pg-paper) .chip.who.bot::before {
|
|
300
|
+
display: none;
|
|
301
|
+
}
|
|
302
|
+
/* The bot that wrote it, by its face (shell/wear.mjs markSvg) */
|
|
303
|
+
:where(.pg-paper) .chip .sh-mark {
|
|
304
|
+
margin-right: 0.3rem;
|
|
305
|
+
vertical-align: -0.15em;
|
|
306
|
+
}
|
|
307
|
+
/* How long it takes to read, worked out as it opens (quick.js); never kept in the file */
|
|
308
|
+
:where(.pg-paper) .chip.read::before {
|
|
309
|
+
content: "";
|
|
310
|
+
display: inline-block;
|
|
311
|
+
width: 0.85em;
|
|
312
|
+
height: 0.85em;
|
|
313
|
+
margin-right: 0.3rem;
|
|
314
|
+
vertical-align: -0.1em;
|
|
315
|
+
background: currentColor;
|
|
316
|
+
opacity: 0.7;
|
|
317
|
+
mask:
|
|
318
|
+
center / contain no-repeat
|
|
319
|
+
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7v5l3 2'/%3E%3C/svg%3E");
|
|
320
|
+
}
|
|
321
|
+
:where(.pg-paper) .chip.read {
|
|
322
|
+
color: var(--muted);
|
|
323
|
+
}
|
|
299
324
|
:where(.pg-paper) .chip.status::after {
|
|
300
325
|
content: "";
|
|
301
326
|
display: inline-block;
|
|
@@ -369,6 +394,47 @@ body.pg-toc-shut .pg-toc {
|
|
|
369
394
|
:where(.pg-paper) sup {
|
|
370
395
|
line-height: 0;
|
|
371
396
|
}
|
|
397
|
+
:where(.pg-paper) sup.fn a {
|
|
398
|
+
padding: 0 0.15em;
|
|
399
|
+
font-weight: 600;
|
|
400
|
+
text-decoration: none;
|
|
401
|
+
}
|
|
402
|
+
:where(.pg-paper) .fn-back {
|
|
403
|
+
text-decoration: none;
|
|
404
|
+
}
|
|
405
|
+
/* A footnote read where it is cited: the note, shown beside the number (quick.js) */
|
|
406
|
+
#fn-card {
|
|
407
|
+
position: absolute;
|
|
408
|
+
z-index: 30;
|
|
409
|
+
max-width: 22rem;
|
|
410
|
+
padding: 0.7rem 0.9rem;
|
|
411
|
+
border: 1px solid var(--line);
|
|
412
|
+
border-radius: 12px;
|
|
413
|
+
background: var(--bg);
|
|
414
|
+
color: var(--fg);
|
|
415
|
+
box-shadow: 0 8px 24px rgb(0 0 0 / 0.12);
|
|
416
|
+
font-size: 0.85rem;
|
|
417
|
+
line-height: 1.6;
|
|
418
|
+
}
|
|
419
|
+
#fn-card .fn-back {
|
|
420
|
+
display: none;
|
|
421
|
+
}
|
|
422
|
+
/* A table's column put in order by a press on its heading, while reading (quick.js) */
|
|
423
|
+
body:not(.pg-editing) :where(.pg-paper) th[data-sort] {
|
|
424
|
+
cursor: pointer;
|
|
425
|
+
user-select: none;
|
|
426
|
+
}
|
|
427
|
+
body:not(.pg-editing) :where(.pg-paper) th[data-sort]:hover {
|
|
428
|
+
color: var(--fg);
|
|
429
|
+
}
|
|
430
|
+
:where(.pg-paper) th[aria-sort]::after {
|
|
431
|
+
content: "↑";
|
|
432
|
+
margin-left: 0.3rem;
|
|
433
|
+
color: var(--accent, currentColor);
|
|
434
|
+
}
|
|
435
|
+
:where(.pg-paper) th[aria-sort="descending"]::after {
|
|
436
|
+
content: "↓";
|
|
437
|
+
}
|
|
372
438
|
:where(.pg-paper) ol.footnotes {
|
|
373
439
|
margin-top: 2.4rem;
|
|
374
440
|
padding: 1rem 0 0 1.3rem;
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
<details class="sh-menu">
|
|
35
35
|
{{shell.export}}
|
|
36
36
|
<div class="sh-list">
|
|
37
|
+
<button type="button" class="sh-item" data-docx>Word file<small>.docx</small></button>
|
|
37
38
|
<button type="button" class="sh-item" data-export="print">Print<small>PDF</small></button>
|
|
38
39
|
{{shell.download}}
|
|
39
40
|
</div>
|
|
@@ -160,6 +160,130 @@
|
|
|
160
160
|
contents();
|
|
161
161
|
spy();
|
|
162
162
|
|
|
163
|
+
/* ── reading: a column in order, a footnote in place, the time it takes ──── */
|
|
164
|
+
|
|
165
|
+
// Each table's rows in the order they were written: a sort is a view of the page, and
|
|
166
|
+
// the file keeps that order (shell.clean puts it back in the copy it keeps)
|
|
167
|
+
const written = new WeakMap();
|
|
168
|
+
const collator = new Intl.Collator(undefined, { numeric: true });
|
|
169
|
+
const numberIn = (text) => {
|
|
170
|
+
const n = Number.parseFloat(text.replace(/[^\d.-]/g, ""));
|
|
171
|
+
return Number.isFinite(n) ? n : null;
|
|
172
|
+
};
|
|
173
|
+
const tables = () =>
|
|
174
|
+
[...paper.querySelectorAll("table")].filter(
|
|
175
|
+
(table) => table.tHead?.rows[0] && table.tBodies[0]?.rows.length > 1,
|
|
176
|
+
);
|
|
177
|
+
for (const table of tables()) {
|
|
178
|
+
[...table.tBodies[0].rows].forEach((row, at) => {
|
|
179
|
+
written.set(row, at);
|
|
180
|
+
});
|
|
181
|
+
for (const th of table.tHead.rows[0].cells) {
|
|
182
|
+
th.dataset.sort = "";
|
|
183
|
+
th.tabIndex = 0;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/** Every table back in its written order, its headings unmarked. */
|
|
187
|
+
const unsort = () => {
|
|
188
|
+
for (const table of tables()) {
|
|
189
|
+
const rows = [...table.tBodies[0].rows];
|
|
190
|
+
rows.sort((a, b) => (written.get(a) ?? 0) - (written.get(b) ?? 0));
|
|
191
|
+
table.tBodies[0].append(...rows);
|
|
192
|
+
for (const th of table.tHead.rows[0].cells)
|
|
193
|
+
th.removeAttribute("aria-sort");
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
/** Up, down, then as written: one heading's column at a time. */
|
|
197
|
+
const sortBy = (th) => {
|
|
198
|
+
const table = th.closest("table");
|
|
199
|
+
const body = table.tBodies[0];
|
|
200
|
+
const at = th.cellIndex;
|
|
201
|
+
const was = th.getAttribute("aria-sort");
|
|
202
|
+
const next = was === "ascending" ? "descending" : was ? null : "ascending";
|
|
203
|
+
for (const one of table.tHead.rows[0].cells)
|
|
204
|
+
one.removeAttribute("aria-sort");
|
|
205
|
+
const rows = [...body.rows];
|
|
206
|
+
const key = (row) => row.cells[at]?.textContent.trim() ?? "";
|
|
207
|
+
const numeric =
|
|
208
|
+
th.classList.contains("num") ||
|
|
209
|
+
rows.every((row) => numberIn(key(row)) !== null);
|
|
210
|
+
if (next) {
|
|
211
|
+
th.setAttribute("aria-sort", next);
|
|
212
|
+
const sign = next === "ascending" ? 1 : -1;
|
|
213
|
+
rows.sort(
|
|
214
|
+
(a, b) =>
|
|
215
|
+
sign *
|
|
216
|
+
(numeric
|
|
217
|
+
? numberIn(key(a)) - numberIn(key(b))
|
|
218
|
+
: collator.compare(key(a), key(b))),
|
|
219
|
+
);
|
|
220
|
+
} else rows.sort((a, b) => (written.get(a) ?? 0) - (written.get(b) ?? 0));
|
|
221
|
+
body.append(...rows);
|
|
222
|
+
};
|
|
223
|
+
const browsing = () => !document.body.classList.contains("pg-editing");
|
|
224
|
+
paper.addEventListener("click", (event) => {
|
|
225
|
+
const th = event.target.closest?.("th[data-sort]");
|
|
226
|
+
if (th && browsing()) sortBy(th);
|
|
227
|
+
});
|
|
228
|
+
paper.addEventListener("keydown", (event) => {
|
|
229
|
+
const th = event.target.closest?.("th[data-sort]");
|
|
230
|
+
if (!th || !browsing() || (event.key !== "Enter" && event.key !== " "))
|
|
231
|
+
return;
|
|
232
|
+
event.preventDefault();
|
|
233
|
+
sortBy(th);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// A footnote's note, beside the number that cites it, while the pointer or focus is there
|
|
237
|
+
let card = null;
|
|
238
|
+
const hideNote = () => card?.remove();
|
|
239
|
+
const showNote = (link) => {
|
|
240
|
+
const note = document.getElementById(
|
|
241
|
+
decodeURIComponent(link.hash.slice(1)),
|
|
242
|
+
);
|
|
243
|
+
if (!note) return;
|
|
244
|
+
card ??= Object.assign(document.createElement("div"), { id: "fn-card" });
|
|
245
|
+
card.setAttribute("role", "tooltip");
|
|
246
|
+
card.innerHTML = note.innerHTML;
|
|
247
|
+
document.body.append(card);
|
|
248
|
+
const box = link.getBoundingClientRect();
|
|
249
|
+
const left = Math.min(
|
|
250
|
+
box.left + scrollX,
|
|
251
|
+
scrollX + document.documentElement.clientWidth - card.offsetWidth - 12,
|
|
252
|
+
);
|
|
253
|
+
card.style.left = `${Math.max(scrollX + 12, left)}px`;
|
|
254
|
+
card.style.top = `${box.bottom + scrollY + 6}px`;
|
|
255
|
+
};
|
|
256
|
+
paper.addEventListener("mouseover", (event) => {
|
|
257
|
+
const link = event.target.closest?.("sup.fn a");
|
|
258
|
+
if (link && browsing()) showNote(link);
|
|
259
|
+
});
|
|
260
|
+
paper.addEventListener("mouseout", (event) => {
|
|
261
|
+
if (event.target.closest?.("sup.fn a")) hideNote();
|
|
262
|
+
});
|
|
263
|
+
paper.addEventListener("focusin", (event) => {
|
|
264
|
+
const link = event.target.closest?.("sup.fn a");
|
|
265
|
+
if (link && browsing()) showNote(link);
|
|
266
|
+
else hideNote();
|
|
267
|
+
});
|
|
268
|
+
addEventListener("scroll", hideNote, { passive: true });
|
|
269
|
+
|
|
270
|
+
// How long it reads, beside the other facts under the title, in the reader's language
|
|
271
|
+
const byline = paper.querySelector(".byline");
|
|
272
|
+
if (byline && typeof Intl.Segmenter === "function") {
|
|
273
|
+
let words = 0;
|
|
274
|
+
const segmenter = new Intl.Segmenter(undefined, { granularity: "word" });
|
|
275
|
+
for (const piece of segmenter.segment(paper.textContent))
|
|
276
|
+
if (piece.isWordLike) words++;
|
|
277
|
+
const minutes = Math.max(1, Math.round(words / 200));
|
|
278
|
+
const chip = document.createElement("span");
|
|
279
|
+
chip.className = "chip read";
|
|
280
|
+
chip.textContent = new Intl.NumberFormat(
|
|
281
|
+
document.documentElement.lang || undefined,
|
|
282
|
+
{ style: "unit", unit: "minute", unitDisplay: "short" },
|
|
283
|
+
).format(minutes);
|
|
284
|
+
byline.append(" ", chip);
|
|
285
|
+
}
|
|
286
|
+
|
|
163
287
|
/* ── keeping it (shell.edits) ────────────────────────────────────────────── */
|
|
164
288
|
|
|
165
289
|
const changed = () => shell.edits.changed();
|
|
@@ -203,6 +327,30 @@
|
|
|
203
327
|
}
|
|
204
328
|
for (const el of copy.querySelectorAll(".pg-hot"))
|
|
205
329
|
el.classList.remove("pg-hot");
|
|
330
|
+
// What reading put on the page: a column's order, the time it takes, a note shown
|
|
331
|
+
const live = [...paper.querySelectorAll("table")];
|
|
332
|
+
copy.querySelectorAll("#paper table").forEach((table, at) => {
|
|
333
|
+
const body = table.tBodies[0];
|
|
334
|
+
const order = [...(live[at]?.tBodies[0]?.rows ?? [])].map((row) =>
|
|
335
|
+
written.get(row),
|
|
336
|
+
);
|
|
337
|
+
if (
|
|
338
|
+
body &&
|
|
339
|
+
order.length === body.rows.length &&
|
|
340
|
+
order.every((n) => n !== undefined)
|
|
341
|
+
) {
|
|
342
|
+
const rows = [...body.rows];
|
|
343
|
+
body.append(
|
|
344
|
+
...order.map((_, i) => rows[order.indexOf(i)]).filter(Boolean),
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
for (const th of table.querySelectorAll("th")) {
|
|
348
|
+
th.removeAttribute("aria-sort");
|
|
349
|
+
th.removeAttribute("data-sort");
|
|
350
|
+
th.removeAttribute("tabindex");
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
for (const el of copy.querySelectorAll(".chip.read, #fn-card")) el.remove();
|
|
206
354
|
for (const tabs of copy.querySelectorAll(".tabs")) {
|
|
207
355
|
tabs.querySelector('[role="tablist"]')?.remove();
|
|
208
356
|
for (const panel of tabs.querySelectorAll("[role=tabpanel]")) {
|
|
@@ -264,6 +412,12 @@
|
|
|
264
412
|
};
|
|
265
413
|
|
|
266
414
|
shell.edits.onToggle((on) => {
|
|
415
|
+
// Edits are made on the page as written: no column in order, no reading time among the chips
|
|
416
|
+
if (on) {
|
|
417
|
+
unsort();
|
|
418
|
+
hideNote();
|
|
419
|
+
for (const chip of paper.querySelectorAll(".chip.read")) chip.remove();
|
|
420
|
+
}
|
|
267
421
|
document.body.classList.toggle("pg-editing", on);
|
|
268
422
|
paper.contentEditable = on ? "true" : "false";
|
|
269
423
|
seal();
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* A document's page as a Word file: the page opened in a headless browser of its own and
|
|
4
|
+
* turned into a .docx there by the page's own converter (docx.js), as Export › Word file does
|
|
5
|
+
* for someone reading it — the kit's converter as it is now, over the copy the page was made
|
|
6
|
+
* with, so a page made before a fix to it gets the fix. Prints the file written, and the
|
|
7
|
+
* pictures that could not be put in.
|
|
8
|
+
*
|
|
9
|
+
* node word.mjs <page.html> --out <file.docx>
|
|
10
|
+
*/
|
|
11
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
12
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { serveFolder } from "../../../browser/scripts/serve.mjs";
|
|
15
|
+
import {
|
|
16
|
+
fail,
|
|
17
|
+
inPageApart,
|
|
18
|
+
orFail,
|
|
19
|
+
parseArgs,
|
|
20
|
+
} from "../../../browser/scripts/session.mjs";
|
|
21
|
+
|
|
22
|
+
const opts = parseArgs();
|
|
23
|
+
const file = opts._[0] && resolve(opts._[0]);
|
|
24
|
+
if (!file || typeof opts.out !== "string")
|
|
25
|
+
fail("usage: node word.mjs <page.html> --out <file.docx>");
|
|
26
|
+
const converter = readFileSync(
|
|
27
|
+
join(dirname(fileURLToPath(import.meta.url)), "docx.js"),
|
|
28
|
+
"utf8",
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
// The page's folder, so pictures beside it load
|
|
32
|
+
const served = await serveFolder(dirname(file));
|
|
33
|
+
try {
|
|
34
|
+
const done = orFail(
|
|
35
|
+
await inPageApart(
|
|
36
|
+
async (page, { url, converter }) => {
|
|
37
|
+
const tab = await page.context().newPage();
|
|
38
|
+
try {
|
|
39
|
+
await tab.setViewportSize({ width: 1024, height: 1400 });
|
|
40
|
+
await tab.goto(url, { waitUntil: "load" });
|
|
41
|
+
await tab.evaluate(() => document.fonts.ready);
|
|
42
|
+
await tab.addScriptTag({ content: converter });
|
|
43
|
+
return await tab.evaluate(async () => {
|
|
44
|
+
if (!window.shell?.docx)
|
|
45
|
+
return { error: "this page is not a document: no #paper in it" };
|
|
46
|
+
const { bytes, missed } = await window.shell.docx();
|
|
47
|
+
let text = "";
|
|
48
|
+
for (let i = 0; i < bytes.length; i += 0x8000)
|
|
49
|
+
text += String.fromCharCode(...bytes.subarray(i, i + 0x8000));
|
|
50
|
+
return { data: btoa(text), missed };
|
|
51
|
+
});
|
|
52
|
+
} finally {
|
|
53
|
+
await tab.close();
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{ url: served.url(basename(file)), converter },
|
|
57
|
+
),
|
|
58
|
+
);
|
|
59
|
+
writeFileSync(opts.out, Buffer.from(done.data, "base64"));
|
|
60
|
+
console.log(
|
|
61
|
+
JSON.stringify({ file: resolve(opts.out), missed: done.missed ?? [] }),
|
|
62
|
+
);
|
|
63
|
+
} finally {
|
|
64
|
+
served.close();
|
|
65
|
+
}
|