@heycys/gallery 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +50 -2
- package/THIRD-PARTY-NOTICES.md +3303 -0
- package/assets/writing-preferences.md +107 -0
- package/bin/gallery.mjs +10 -0
- package/browser/editor/components/bookmark/icons.mjs +6 -0
- package/browser/editor/components/bookmark/index.mjs +80 -0
- package/browser/editor/components/bookmark/page.mjs +147 -0
- package/browser/editor/components/builders.mjs +19 -0
- package/browser/editor/components/callout/index.mjs +64 -0
- package/browser/editor/components/code/index.mjs +327 -0
- package/browser/editor/components/code/page.mjs +561 -0
- package/browser/editor/components/colors.mjs +50 -0
- package/browser/editor/components/columns/index.mjs +104 -0
- package/browser/editor/components/columns/page.mjs +310 -0
- package/browser/editor/components/details/index.mjs +73 -0
- package/browser/editor/components/details/page.mjs +86 -0
- package/browser/editor/components/dialog/index.mjs +84 -0
- package/browser/editor/components/dialog/page.mjs +201 -0
- package/browser/editor/components/divider/index.mjs +48 -0
- package/browser/editor/components/embed/icons.mjs +11 -0
- package/browser/editor/components/embed/index.mjs +123 -0
- package/browser/editor/components/embed/page.mjs +309 -0
- package/browser/editor/components/figure/index.mjs +87 -0
- package/browser/editor/components/figure/page.mjs +42 -0
- package/browser/editor/components/file/icons.mjs +14 -0
- package/browser/editor/components/file/index.mjs +77 -0
- package/browser/editor/components/file/page.mjs +114 -0
- package/browser/editor/components/flowchart/add.mjs +123 -0
- package/browser/editor/components/flowchart/index.mjs +246 -0
- package/browser/editor/components/flowchart/page.mjs +453 -0
- package/browser/editor/components/heading/index.mjs +53 -0
- package/browser/editor/components/heading/page.mjs +6 -0
- package/browser/editor/components/highlight/index.mjs +63 -0
- package/browser/editor/components/icon/index.mjs +57 -0
- package/browser/editor/components/icon/page.mjs +286 -0
- package/browser/editor/components/icons.mjs +48 -0
- package/browser/editor/components/image/crop.mjs +189 -0
- package/browser/editor/components/image/index.mjs +104 -0
- package/browser/editor/components/image/page.mjs +385 -0
- package/browser/editor/components/image/viewer.mjs +213 -0
- package/browser/editor/components/installed/index.mjs +179 -0
- package/browser/editor/components/installed/page.mjs +523 -0
- package/browser/editor/components/installed/served.mjs +35 -0
- package/browser/editor/components/kit.mjs +67 -0
- package/browser/editor/components/list/index.mjs +194 -0
- package/browser/editor/components/list/join.mjs +68 -0
- package/browser/editor/components/list/numbers.mjs +107 -0
- package/browser/editor/components/list/page.mjs +632 -0
- package/browser/editor/components/math/index.mjs +88 -0
- package/browser/editor/components/math/page.mjs +236 -0
- package/browser/editor/components/math/tex-logo.mjs +6 -0
- package/browser/editor/components/media/icons.mjs +19 -0
- package/browser/editor/components/media/page.mjs +192 -0
- package/browser/editor/components/media/parts.mjs +60 -0
- package/browser/editor/components/media/size.mjs +20 -0
- package/browser/editor/components/media/toolbar.mjs +37 -0
- package/browser/editor/components/media/write.mjs +7 -0
- package/browser/editor/components/pages.mjs +46 -0
- package/browser/editor/components/paragraph/index.mjs +43 -0
- package/browser/editor/components/paragraph/page.mjs +52 -0
- package/browser/editor/components/placeholder-bar.mjs +17 -0
- package/browser/editor/components/placeholder.mjs +128 -0
- package/browser/editor/components/quote/index.mjs +33 -0
- package/browser/editor/components/registry.mjs +859 -0
- package/browser/editor/components/rows.mjs +16 -0
- package/browser/editor/components/section/index.mjs +42 -0
- package/browser/editor/components/section/page.mjs +141 -0
- package/browser/editor/components/set-apart.mjs +24 -0
- package/browser/editor/components/sheets/index.mjs +137 -0
- package/browser/editor/components/sheets/page.mjs +227 -0
- package/browser/editor/components/sheets/pills.mjs +226 -0
- package/browser/editor/components/table/grid.mjs +73 -0
- package/browser/editor/components/table/index.mjs +308 -0
- package/browser/editor/components/table/page.mjs +683 -0
- package/browser/editor/components/table/slots.mjs +41 -0
- package/browser/editor/components/widget/index.mjs +50 -0
- package/browser/editor/page/annotate/anchors.mjs +230 -0
- package/browser/editor/page/annotate/card.mjs +102 -0
- package/browser/editor/page/annotate/index.mjs +1656 -0
- package/browser/editor/page/at-menu/index.mjs +317 -0
- package/browser/editor/page/autosave.mjs +1023 -0
- package/browser/editor/page/beside.mjs +21 -0
- package/browser/editor/page/block-info.mjs +63 -0
- package/browser/editor/page/block-menu/colors.mjs +84 -0
- package/browser/editor/page/block-menu/index.mjs +217 -0
- package/browser/editor/page/blocks.mjs +255 -0
- package/browser/editor/page/caret.mjs +682 -0
- package/browser/editor/page/changes/bar.mjs +102 -0
- package/browser/editor/page/changes/ghost.mjs +206 -0
- package/browser/editor/page/changes/gone-words.mjs +94 -0
- package/browser/editor/page/changes/index.mjs +447 -0
- package/browser/editor/page/changes/words.mjs +27 -0
- package/browser/editor/page/chip-fills.mjs +126 -0
- package/browser/editor/page/clipboard/import/colors.mjs +192 -0
- package/browser/editor/page/clipboard/import/html.mjs +792 -0
- package/browser/editor/page/clipboard/import/inline.mjs +232 -0
- package/browser/editor/page/clipboard/import/languages.mjs +42 -0
- package/browser/editor/page/clipboard/import/markdown.mjs +760 -0
- package/browser/editor/page/clipboard/import/math.mjs +100 -0
- package/browser/editor/page/clipboard/import/office.mjs +245 -0
- package/browser/editor/page/clipboard/import/read.mjs +120 -0
- package/browser/editor/page/clipboard/import/rich.mjs +29 -0
- package/browser/editor/page/clipboard/import/to-blocks.mjs +290 -0
- package/browser/editor/page/clipboard/index.mjs +816 -0
- package/browser/editor/page/clipboard/own/blocks.mjs +211 -0
- package/browser/editor/page/clipboard/own/chart-keys.mjs +58 -0
- package/browser/editor/page/clipboard/own/describe.mjs +124 -0
- package/browser/editor/page/clipboard/own/export.mjs +167 -0
- package/browser/editor/page/clipboard/own/ids.mjs +39 -0
- package/browser/editor/page/clipboard/own/index.mjs +13 -0
- package/browser/editor/page/clipboard/own/rules.mjs +44 -0
- package/browser/editor/page/clipboard/own/selection.mjs +159 -0
- package/browser/editor/page/clipboard/own/writers.mjs +315 -0
- package/browser/editor/page/columns/index.mjs +360 -0
- package/browser/editor/page/commit.mjs +1813 -0
- package/browser/editor/page/conflicts.mjs +249 -0
- package/browser/editor/page/convert.mjs +831 -0
- package/browser/editor/page/core.mjs +1693 -0
- package/browser/editor/page/drag/drop.mjs +307 -0
- package/browser/editor/page/drag/index.mjs +351 -0
- package/browser/editor/page/drag/preview.mjs +126 -0
- package/browser/editor/page/edge-scroll.mjs +50 -0
- package/browser/editor/page/editor.mjs +1780 -0
- package/browser/editor/page/emoji-picker/emoji-tab.mjs +287 -0
- package/browser/editor/page/emoji-picker/glyph-html.mjs +26 -0
- package/browser/editor/page/emoji-picker/grid.mjs +81 -0
- package/browser/editor/page/emoji-picker/icon-tab.mjs +217 -0
- package/browser/editor/page/emoji-picker/icons.mjs +31 -0
- package/browser/editor/page/emoji-picker/index.mjs +166 -0
- package/browser/editor/page/emoji-picker/styles.mjs +161 -0
- package/browser/editor/page/emoji-picker/support.mjs +204 -0
- package/browser/editor/page/emoji-picker/upload.mjs +236 -0
- package/browser/editor/page/export-report.mjs +23 -0
- package/browser/editor/page/fills.mjs +62 -0
- package/browser/editor/page/find/index.mjs +107 -0
- package/browser/editor/page/flags.mjs +70 -0
- package/browser/editor/page/fold/index.mjs +348 -0
- package/browser/editor/page/fold/rule.mjs +125 -0
- package/browser/editor/page/folded.mjs +23 -0
- package/browser/editor/page/format-bar/bar.mjs +449 -0
- package/browser/editor/page/format-bar/brush.mjs +77 -0
- package/browser/editor/page/format-bar/colors.mjs +46 -0
- package/browser/editor/page/format-bar/index.mjs +404 -0
- package/browser/editor/page/formula/index.mjs +236 -0
- package/browser/editor/page/formula/panel.mjs +336 -0
- package/browser/editor/page/formula/symbols.mjs +156 -0
- package/browser/editor/page/frame.mjs +74 -0
- package/browser/editor/page/frames.mjs +196 -0
- package/browser/editor/page/geometry.mjs +402 -0
- package/browser/editor/page/gesture.mjs +45 -0
- package/browser/editor/page/handle/index.mjs +650 -0
- package/browser/editor/page/handle-sizes.mjs +14 -0
- package/browser/editor/page/hints/index.mjs +84 -0
- package/browser/editor/page/history.mjs +401 -0
- package/browser/editor/page/insert/index.mjs +256 -0
- package/browser/editor/page/kept.mjs +38 -0
- package/browser/editor/page/links/address.mjs +40 -0
- package/browser/editor/page/links/index.mjs +866 -0
- package/browser/editor/page/links/pages.mjs +131 -0
- package/browser/editor/page/links/views.mjs +369 -0
- package/browser/editor/page/long-runs.mjs +75 -0
- package/browser/editor/page/look.mjs +77 -0
- package/browser/editor/page/made.mjs +24 -0
- package/browser/editor/page/margin.mjs +373 -0
- package/browser/editor/page/markdown/index.mjs +88 -0
- package/browser/editor/page/markdown/rules.mjs +33 -0
- package/browser/editor/page/marks.mjs +377 -0
- package/browser/editor/page/media-menu/index.mjs +158 -0
- package/browser/editor/page/menu.mjs +544 -0
- package/browser/editor/page/merge.mjs +124 -0
- package/browser/editor/page/notices.mjs +142 -0
- package/browser/editor/page/offered.mjs +32 -0
- package/browser/editor/page/outline/folds.mjs +53 -0
- package/browser/editor/page/outline/index.mjs +783 -0
- package/browser/editor/page/outline/list.mjs +184 -0
- package/browser/editor/page/outline/read.mjs +201 -0
- package/browser/editor/page/outline/strip.mjs +287 -0
- package/browser/editor/page/outline/tree.mjs +248 -0
- package/browser/editor/page/overlay-layer.mjs +227 -0
- package/browser/editor/page/overlays.mjs +205 -0
- package/browser/editor/page/own.mjs +28 -0
- package/browser/editor/page/pads.mjs +71 -0
- package/browser/editor/page/page-objects.mjs +105 -0
- package/browser/editor/page/panel.mjs +65 -0
- package/browser/editor/page/placement.mjs +58 -0
- package/browser/editor/page/post.mjs +41 -0
- package/browser/editor/page/present-links.mjs +50 -0
- package/browser/editor/page/quiet.mjs +48 -0
- package/browser/editor/page/resize/index.mjs +327 -0
- package/browser/editor/page/select-all/index.mjs +262 -0
- package/browser/editor/page/selection/delete.mjs +61 -0
- package/browser/editor/page/selection/index.mjs +164 -0
- package/browser/editor/page/selection/marquee.mjs +174 -0
- package/browser/editor/page/session.mjs +168 -0
- package/browser/editor/page/slash-menu/index.mjs +291 -0
- package/browser/editor/page/storage.mjs +48 -0
- package/browser/editor/page/sync-state.mjs +267 -0
- package/browser/editor/page/table/aligns.mjs +29 -0
- package/browser/editor/page/table/cell-bar.mjs +141 -0
- package/browser/editor/page/table/cells.mjs +527 -0
- package/browser/editor/page/table/icons.mjs +40 -0
- package/browser/editor/page/table/index.mjs +990 -0
- package/browser/editor/page/table/lists.mjs +187 -0
- package/browser/editor/page/table/widths.mjs +313 -0
- package/browser/editor/page/tex.mjs +32 -0
- package/browser/editor/page/text-select/index.mjs +671 -0
- package/browser/editor/page/tooltip.mjs +98 -0
- package/browser/editor/page/type-grid.mjs +83 -0
- package/browser/editor/page/typing/code-edges.mjs +274 -0
- package/browser/editor/page/typing/index.mjs +282 -0
- package/browser/editor/page/typing/leave.mjs +68 -0
- package/browser/editor/page/ui.mjs +160 -0
- package/browser/shared/annotations.mjs +569 -0
- package/browser/shared/code-folds.mjs +14 -0
- package/browser/shared/code-languages.mjs +70 -0
- package/browser/shared/code-lines.mjs +30 -0
- package/browser/shared/colors.mjs +30 -0
- package/browser/shared/component-catalog.mjs +573 -0
- package/browser/shared/components/bookmark.mjs +26 -0
- package/browser/shared/components/callout.mjs +9 -0
- package/browser/shared/components/chart.mjs +20 -0
- package/browser/shared/components/code.mjs +37 -0
- package/browser/shared/components/columns.mjs +16 -0
- package/browser/shared/components/details.mjs +15 -0
- package/browser/shared/components/dialog.mjs +28 -0
- package/browser/shared/components/diff.mjs +18 -0
- package/browser/shared/components/divider.mjs +6 -0
- package/browser/shared/components/embed.mjs +25 -0
- package/browser/shared/components/figure.mjs +14 -0
- package/browser/shared/components/file.mjs +23 -0
- package/browser/shared/components/heading.mjs +6 -0
- package/browser/shared/components/highlight.mjs +9 -0
- package/browser/shared/components/icon.mjs +18 -0
- package/browser/shared/components/image.mjs +39 -0
- package/browser/shared/components/index.mjs +396 -0
- package/browser/shared/components/installed.mjs +232 -0
- package/browser/shared/components/list.mjs +146 -0
- package/browser/shared/components/math.mjs +49 -0
- package/browser/shared/components/mention.mjs +33 -0
- package/browser/shared/components/page.mjs +46 -0
- package/browser/shared/components/paragraph.mjs +9 -0
- package/browser/shared/components/quote.mjs +6 -0
- package/browser/shared/components/section.mjs +8 -0
- package/browser/shared/components/sheets.mjs +80 -0
- package/browser/shared/components/state.mjs +20 -0
- package/browser/shared/components/table.mjs +49 -0
- package/browser/shared/components/text.mjs +14 -0
- package/browser/shared/components/widget.mjs +10 -0
- package/browser/shared/copy-ids.mjs +72 -0
- package/browser/shared/css-references.mjs +110 -0
- package/browser/shared/document-look.mjs +178 -0
- package/browser/shared/emoji/custom.mjs +91 -0
- package/browser/shared/emoji/data/LICENSE-lucide.txt +43 -0
- package/browser/shared/emoji/data/LICENSE-mingcute.txt +202 -0
- package/browser/shared/emoji/data/LICENSE-tabler.txt +21 -0
- package/browser/shared/emoji/data/README.md +28 -0
- package/browser/shared/emoji/data/categories.json +1 -0
- package/browser/shared/emoji/data/icons.json +1 -0
- package/browser/shared/emoji/data/keywords-en.json +1 -0
- package/browser/shared/emoji/data/keywords-zh.json +1 -0
- package/browser/shared/emoji/data/names.json +1 -0
- package/browser/shared/emoji/data/positions.json +1 -0
- package/browser/shared/emoji/data/twemoji-index.json +1 -0
- package/browser/shared/emoji/data/twemoji-svg.bin +0 -0
- package/browser/shared/emoji/data.mjs +194 -0
- package/browser/shared/emoji/emoji.mjs +38 -0
- package/browser/shared/emoji/glyphs.mjs +134 -0
- package/browser/shared/emoji/icon-value.mjs +91 -0
- package/browser/shared/escape.mjs +20 -0
- package/browser/shared/export-wrap.mjs +89 -0
- package/browser/shared/files.mjs +33 -0
- package/browser/shared/html-tree.mjs +59 -0
- package/browser/shared/http.mjs +22 -0
- package/browser/shared/i18n/en.mjs +1223 -0
- package/browser/shared/i18n/index.mjs +132 -0
- package/browser/shared/ids.mjs +24 -0
- package/browser/shared/import-types.mjs +23 -0
- package/browser/shared/inline-spacing.mjs +97 -0
- package/browser/shared/layers.mjs +42 -0
- package/browser/shared/long-runs.mjs +39 -0
- package/browser/shared/media.mjs +162 -0
- package/browser/shared/new-names.mjs +67 -0
- package/browser/shared/number-reading.mjs +92 -0
- package/browser/shared/old-names.mjs +143 -0
- package/browser/shared/outline.mjs +194 -0
- package/browser/shared/page-address.mjs +140 -0
- package/browser/shared/page-links.mjs +86 -0
- package/browser/shared/paths.mjs +73 -0
- package/browser/shared/preferences.mjs +116 -0
- package/browser/shared/preview-server.mjs +247 -0
- package/browser/shared/qa-levels.mjs +93 -0
- package/browser/shared/reading-place.mjs +91 -0
- package/browser/shared/renamed-storage.mjs +220 -0
- package/browser/shared/reports.mjs +46 -0
- package/browser/shared/search.mjs +85 -0
- package/browser/shared/session.mjs +77 -0
- package/browser/shared/table-chart.mjs +113 -0
- package/browser/shared/table-hides.mjs +120 -0
- package/browser/shared/table-slots.mjs +75 -0
- package/browser/shared/words.mjs +23 -0
- package/browser/shared/workspace-look.mjs +91 -0
- package/browser/shared/workspace.mjs +535 -0
- package/browser/shared/writing-preferences.mjs +68 -0
- package/browser/shared/zoom.mjs +57 -0
- package/dist/chunk-2B5E4CDJ.mjs +2 -0
- package/dist/chunk-342HXE3Q.mjs +2 -0
- package/dist/chunk-3HIRPVLU.mjs +2 -0
- package/dist/chunk-43B75J5T.mjs +2 -0
- package/dist/chunk-4FS7Z7WR.mjs +2 -0
- package/dist/chunk-4K5KC6V2.mjs +2 -0
- package/dist/chunk-5L7RYZCL.mjs +2 -0
- package/dist/chunk-5MHMDLZD.mjs +4 -0
- package/dist/chunk-5ZKJ3H4P.mjs +8 -0
- package/dist/chunk-64K7IPLO.mjs +255 -0
- package/dist/chunk-6QXGZM36.mjs +8 -0
- package/dist/chunk-6RGJOMJP.mjs +16 -0
- package/dist/chunk-742D2WWJ.mjs +19 -0
- package/dist/chunk-7DTINW6U.mjs +48 -0
- package/dist/chunk-A55HN5OK.mjs +2 -0
- package/dist/chunk-AGDILNWB.mjs +2 -0
- package/dist/chunk-AJ73XJF3.mjs +2 -0
- package/dist/chunk-AUZGSZJH.mjs +13 -0
- package/dist/chunk-BFE45AKL.mjs +2 -0
- package/dist/chunk-BGGDRNYQ.mjs +10 -0
- package/dist/chunk-BXO2ZY5P.mjs +2 -0
- package/dist/chunk-C564NU2H.mjs +77 -0
- package/dist/chunk-CEH4MRCC.mjs +2 -0
- package/dist/chunk-CY2FNNAB.mjs +16 -0
- package/dist/chunk-DFUDV4LX.mjs +2 -0
- package/dist/chunk-DKXG4XDG.mjs +2 -0
- package/dist/chunk-E7LWZRXY.mjs +4 -0
- package/dist/chunk-EZQ34M3F.mjs +124 -0
- package/dist/chunk-EZY3WC6Z.mjs +15 -0
- package/dist/chunk-FDLXYYG4.mjs +4 -0
- package/dist/chunk-FUKQNOQS.mjs +9 -0
- package/dist/chunk-GB5SOYQJ.mjs +7 -0
- package/dist/chunk-GRAXKKG4.mjs +2 -0
- package/dist/chunk-HYMEEXKN.mjs +4 -0
- package/dist/chunk-IVDLMMBD.mjs +2 -0
- package/dist/chunk-JPOSLGOC.mjs +6 -0
- package/dist/chunk-JVHHHGEA.mjs +3 -0
- package/dist/chunk-L3QKH4OK.mjs +26 -0
- package/dist/chunk-LAE5NQ4B.mjs +2 -0
- package/dist/chunk-LCTHTZIL.mjs +960 -0
- package/dist/chunk-LEF6DRCK.mjs +59 -0
- package/dist/chunk-LKX55H76.mjs +2 -0
- package/dist/chunk-LS4F7JUM.mjs +2 -0
- package/dist/chunk-MAFIGVXY.mjs +2 -0
- package/dist/chunk-NO5NJCHO.mjs +2 -0
- package/dist/chunk-NQPVAU63.mjs +2 -0
- package/dist/chunk-NSKUTQ5J.mjs +5 -0
- package/dist/chunk-O35FIXRB.mjs +2 -0
- package/dist/chunk-P2CAZPDP.mjs +3 -0
- package/dist/chunk-PL6GHLGD.mjs +15 -0
- package/dist/chunk-QAIHRH3I.mjs +13 -0
- package/dist/chunk-QJIR2BLP.mjs +6 -0
- package/dist/chunk-QR6A54KJ.mjs +3 -0
- package/dist/chunk-QUPLVPB2.mjs +7 -0
- package/dist/chunk-R7BNENLY.mjs +4 -0
- package/dist/chunk-S6O4UHLC.mjs +2 -0
- package/dist/chunk-SGJWQKEI.mjs +2 -0
- package/dist/chunk-SYGN7GLU.mjs +2 -0
- package/dist/chunk-TMYZB6AV.mjs +2 -0
- package/dist/chunk-TX6JH7TR.mjs +2 -0
- package/dist/chunk-TYK6VNAB.mjs +10 -0
- package/dist/chunk-U3SSPL4K.mjs +8 -0
- package/dist/chunk-U6KNPJPR.mjs +2 -0
- package/dist/chunk-UALRNVSE.mjs +4 -0
- package/dist/chunk-UH4SIXTR.mjs +2 -0
- package/dist/chunk-UMHUSOPJ.mjs +2 -0
- package/dist/chunk-V3HXVQEM.mjs +2 -0
- package/dist/chunk-V5JTW2LH.mjs +27 -0
- package/dist/chunk-V5VXUJKG.mjs +2 -0
- package/dist/chunk-V6XZ4VIR.mjs +2 -0
- package/dist/chunk-VBXMADMP.mjs +2 -0
- package/dist/chunk-VNV55RUA.mjs +2 -0
- package/dist/chunk-VPD2PS35.mjs +2 -0
- package/dist/chunk-W3BGBJQW.mjs +2 -0
- package/dist/chunk-W4VKN3GF.mjs +7 -0
- package/dist/chunk-W5BXXPDJ.mjs +3 -0
- package/dist/chunk-W7XHE4CT.mjs +2 -0
- package/dist/chunk-XNROSH2T.mjs +4 -0
- package/dist/chunk-XUNHRCOG.mjs +6 -0
- package/dist/chunk-Y34NR5JL.mjs +2 -0
- package/dist/chunk-Y6RLRPG3.mjs +3 -0
- package/dist/chunk-YEY3RSFQ.mjs +2 -0
- package/dist/cli.mjs +2 -0
- package/dist/server.mjs +2 -0
- package/dist/worker.mjs +5 -0
- package/kit/charts.js +355 -0
- package/kit/code.js +164 -0
- package/kit/dialogs.js +157 -0
- package/kit/math.js +2004 -0
- package/kit/report.css +2932 -0
- package/kit/runtime.js +1782 -0
- package/kit/sheets.js +123 -0
- package/kit/state.js +217 -0
- package/kit/tables.js +1499 -0
- package/kit/tokens.js +29 -0
- package/kit/ui.js +658 -0
- package/package.json +41 -4
- package/release.json +25 -0
- package/sdk/column-widths.d.ts +56 -0
- package/sdk/doc-charts.d.ts +82 -0
- package/sdk/doc-code.d.ts +28 -0
- package/sdk/doc-dialogs.d.ts +4 -0
- package/sdk/doc-kit.d.ts +147 -0
- package/sdk/doc-math.d.ts +3 -0
- package/sdk/doc-sheets.d.ts +15 -0
- package/sdk/doc-state.d.ts +41 -0
- package/sdk/doc-tables.d.ts +24 -0
- package/sdk/doc-tokens.d.ts +22 -0
- package/sdk/index.d.ts +30 -0
- package/skill/SKILL.md +150 -0
- package/skill/agents/openai.yaml +5 -0
- package/skill/references/building-components.md +367 -0
- package/skill/references/example-report.html +356 -0
- package/skill/references/writing-html.md +187 -0
- package/skill/sdk/column-widths.d.ts +56 -0
- package/skill/sdk/doc-charts.d.ts +82 -0
- package/skill/sdk/doc-code.d.ts +28 -0
- package/skill/sdk/doc-dialogs.d.ts +4 -0
- package/skill/sdk/doc-kit.d.ts +147 -0
- package/skill/sdk/doc-math.d.ts +3 -0
- package/skill/sdk/doc-sheets.d.ts +15 -0
- package/skill/sdk/doc-state.d.ts +41 -0
- package/skill/sdk/doc-tables.d.ts +24 -0
- package/skill/sdk/doc-tokens.d.ts +22 -0
- package/skill/sdk/index.d.ts +30 -0
- package/starter/doc.html +21 -0
- package/starter/doc.json +5 -0
- package/vendor/d3.v7.9.0.min.js +2 -0
- package/vendor/katex/auto-render.min.js +1 -0
- package/vendor/katex/contrib/mhchem.min.js +1 -0
- package/vendor/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/vendor/katex/katex.min.css +1 -0
- package/vendor/katex/katex.min.js +1 -0
- package/vendor/pdfjs/LICENSE +177 -0
- package/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
- package/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
- package/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
- package/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
- package/vendor/pdfjs/cmaps/LICENSE +36 -0
- package/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
- package/vendor/pdfjs/legacy/build/pdf.min.mjs +27 -0
- package/vendor/pdfjs/legacy/build/pdf.worker.min.mjs +27 -0
- package/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
- package/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +363 -0
- package/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
- package/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- package/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
- package/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
- package/vendor/types/@types/d3/LICENSE +21 -0
- package/vendor/types/@types/d3/index.d.ts +39 -0
- package/vendor/types/@types/d3/package.json +81 -0
- package/vendor/types/@types/d3-array/LICENSE +21 -0
- package/vendor/types/@types/d3-array/index.d.ts +1118 -0
- package/vendor/types/@types/d3-array/package.json +56 -0
- package/vendor/types/@types/d3-axis/LICENSE +21 -0
- package/vendor/types/@types/d3-axis/index.d.ts +293 -0
- package/vendor/types/@types/d3-axis/package.json +47 -0
- package/vendor/types/@types/d3-brush/LICENSE +21 -0
- package/vendor/types/@types/d3-brush/index.d.ts +255 -0
- package/vendor/types/@types/d3-brush/package.json +42 -0
- package/vendor/types/@types/d3-chord/LICENSE +21 -0
- package/vendor/types/@types/d3-chord/index.d.ts +471 -0
- package/vendor/types/@types/d3-chord/package.json +40 -0
- package/vendor/types/@types/d3-color/LICENSE +21 -0
- package/vendor/types/@types/d3-color/index.d.ts +669 -0
- package/vendor/types/@types/d3-color/package.json +55 -0
- package/vendor/types/@types/d3-contour/LICENSE +21 -0
- package/vendor/types/@types/d3-contour/index.d.ts +222 -0
- package/vendor/types/@types/d3-contour/package.json +38 -0
- package/vendor/types/@types/d3-delaunay/LICENSE +21 -0
- package/vendor/types/@types/d3-delaunay/index.d.ts +316 -0
- package/vendor/types/@types/d3-delaunay/package.json +30 -0
- package/vendor/types/@types/d3-dispatch/LICENSE +21 -0
- package/vendor/types/@types/d3-dispatch/index.d.ts +96 -0
- package/vendor/types/@types/d3-dispatch/package.json +51 -0
- package/vendor/types/@types/d3-drag/LICENSE +21 -0
- package/vendor/types/@types/d3-drag/index.d.ts +395 -0
- package/vendor/types/@types/d3-drag/package.json +42 -0
- package/vendor/types/@types/d3-dsv/LICENSE +21 -0
- package/vendor/types/@types/d3-dsv/index.d.ts +482 -0
- package/vendor/types/@types/d3-dsv/package.json +45 -0
- package/vendor/types/@types/d3-ease/LICENSE +21 -0
- package/vendor/types/@types/d3-ease/index.d.ts +316 -0
- package/vendor/types/@types/d3-ease/package.json +40 -0
- package/vendor/types/@types/d3-fetch/LICENSE +21 -0
- package/vendor/types/@types/d3-fetch/index.d.ts +282 -0
- package/vendor/types/@types/d3-fetch/package.json +37 -0
- package/vendor/types/@types/d3-force/LICENSE +21 -0
- package/vendor/types/@types/d3-force/index.d.ts +899 -0
- package/vendor/types/@types/d3-force/package.json +45 -0
- package/vendor/types/@types/d3-format/LICENSE +21 -0
- package/vendor/types/@types/d3-format/index.d.ts +337 -0
- package/vendor/types/@types/d3-format/package.json +45 -0
- package/vendor/types/@types/d3-geo/LICENSE +21 -0
- package/vendor/types/@types/d3-geo/index.d.ts +1371 -0
- package/vendor/types/@types/d3-geo/package.json +48 -0
- package/vendor/types/@types/d3-hierarchy/LICENSE +21 -0
- package/vendor/types/@types/d3-hierarchy/index.d.ts +928 -0
- package/vendor/types/@types/d3-hierarchy/package.json +50 -0
- package/vendor/types/@types/d3-interpolate/LICENSE +21 -0
- package/vendor/types/@types/d3-interpolate/index.d.ts +387 -0
- package/vendor/types/@types/d3-interpolate/package.json +47 -0
- package/vendor/types/@types/d3-path/LICENSE +21 -0
- package/vendor/types/@types/d3-path/index.d.ts +108 -0
- package/vendor/types/@types/d3-path/package.json +41 -0
- package/vendor/types/@types/d3-polygon/LICENSE +21 -0
- package/vendor/types/@types/d3-polygon/index.d.ts +41 -0
- package/vendor/types/@types/d3-polygon/package.json +40 -0
- package/vendor/types/@types/d3-quadtree/LICENSE +21 -0
- package/vendor/types/@types/d3-quadtree/index.d.ts +204 -0
- package/vendor/types/@types/d3-quadtree/package.json +45 -0
- package/vendor/types/@types/d3-random/LICENSE +21 -0
- package/vendor/types/@types/d3-random/index.d.ts +313 -0
- package/vendor/types/@types/d3-random/package.json +41 -0
- package/vendor/types/@types/d3-scale/LICENSE +21 -0
- package/vendor/types/@types/d3-scale/index.d.ts +2669 -0
- package/vendor/types/@types/d3-scale/package.json +53 -0
- package/vendor/types/@types/d3-scale-chromatic/LICENSE +21 -0
- package/vendor/types/@types/d3-scale-chromatic/index.d.ts +520 -0
- package/vendor/types/@types/d3-scale-chromatic/package.json +46 -0
- package/vendor/types/@types/d3-selection/LICENSE +21 -0
- package/vendor/types/@types/d3-selection/index.d.ts +1210 -0
- package/vendor/types/@types/d3-selection/package.json +56 -0
- package/vendor/types/@types/d3-shape/LICENSE +21 -0
- package/vendor/types/@types/d3-shape/index.d.ts +2792 -0
- package/vendor/types/@types/d3-shape/package.json +53 -0
- package/vendor/types/@types/d3-time/LICENSE +21 -0
- package/vendor/types/@types/d3-time/index.d.ts +697 -0
- package/vendor/types/@types/d3-time/package.json +46 -0
- package/vendor/types/@types/d3-time-format/LICENSE +21 -0
- package/vendor/types/@types/d3-time-format/index.d.ts +202 -0
- package/vendor/types/@types/d3-time-format/package.json +40 -0
- package/vendor/types/@types/d3-timer/LICENSE +21 -0
- package/vendor/types/@types/d3-timer/index.d.ts +68 -0
- package/vendor/types/@types/d3-timer/package.json +45 -0
- package/vendor/types/@types/d3-transition/LICENSE +21 -0
- package/vendor/types/@types/d3-transition/index.d.ts +664 -0
- package/vendor/types/@types/d3-transition/package.json +47 -0
- package/vendor/types/@types/d3-zoom/LICENSE +21 -0
- package/vendor/types/@types/d3-zoom/index.d.ts +611 -0
- package/vendor/types/@types/d3-zoom/package.json +48 -0
- package/vendor/types/@types/geojson/LICENSE +21 -0
- package/vendor/types/@types/geojson/index.d.ts +202 -0
- package/vendor/types/@types/geojson/package.json +46 -0
- package/vendor/typescript/LICENSE.txt +55 -0
- package/vendor/typescript/lib.decorators.d.ts +384 -0
- package/vendor/typescript/lib.decorators.legacy.d.ts +22 -0
- package/vendor/typescript/lib.dom.d.ts +39429 -0
- package/vendor/typescript/lib.dom.iterable.d.ts +571 -0
- package/vendor/typescript/lib.es2015.collection.d.ts +147 -0
- package/vendor/typescript/lib.es2015.core.d.ts +597 -0
- package/vendor/typescript/lib.es2015.d.ts +28 -0
- package/vendor/typescript/lib.es2015.generator.d.ts +77 -0
- package/vendor/typescript/lib.es2015.iterable.d.ts +605 -0
- package/vendor/typescript/lib.es2015.promise.d.ts +81 -0
- package/vendor/typescript/lib.es2015.proxy.d.ts +128 -0
- package/vendor/typescript/lib.es2015.reflect.d.ts +144 -0
- package/vendor/typescript/lib.es2015.symbol.d.ts +46 -0
- package/vendor/typescript/lib.es2015.symbol.wellknown.d.ts +326 -0
- package/vendor/typescript/lib.es2016.array.include.d.ts +116 -0
- package/vendor/typescript/lib.es2016.d.ts +21 -0
- package/vendor/typescript/lib.es2016.intl.d.ts +31 -0
- package/vendor/typescript/lib.es2017.arraybuffer.d.ts +21 -0
- package/vendor/typescript/lib.es2017.d.ts +26 -0
- package/vendor/typescript/lib.es2017.date.d.ts +31 -0
- package/vendor/typescript/lib.es2017.intl.d.ts +44 -0
- package/vendor/typescript/lib.es2017.object.d.ts +49 -0
- package/vendor/typescript/lib.es2017.sharedmemory.d.ts +135 -0
- package/vendor/typescript/lib.es2017.string.d.ts +45 -0
- package/vendor/typescript/lib.es2017.typedarrays.d.ts +53 -0
- package/vendor/typescript/lib.es2018.asyncgenerator.d.ts +77 -0
- package/vendor/typescript/lib.es2018.asynciterable.d.ts +53 -0
- package/vendor/typescript/lib.es2018.d.ts +24 -0
- package/vendor/typescript/lib.es2018.intl.d.ts +83 -0
- package/vendor/typescript/lib.es2018.promise.d.ts +30 -0
- package/vendor/typescript/lib.es2018.regexp.d.ts +37 -0
- package/vendor/typescript/lib.es2019.array.d.ts +79 -0
- package/vendor/typescript/lib.es2019.d.ts +24 -0
- package/vendor/typescript/lib.es2019.intl.d.ts +23 -0
- package/vendor/typescript/lib.es2019.object.d.ts +33 -0
- package/vendor/typescript/lib.es2019.string.d.ts +37 -0
- package/vendor/typescript/lib.es2019.symbol.d.ts +24 -0
- package/vendor/typescript/lib.es2020.bigint.d.ts +765 -0
- package/vendor/typescript/lib.es2020.d.ts +27 -0
- package/vendor/typescript/lib.es2020.date.d.ts +42 -0
- package/vendor/typescript/lib.es2020.intl.d.ts +474 -0
- package/vendor/typescript/lib.es2020.number.d.ts +28 -0
- package/vendor/typescript/lib.es2020.promise.d.ts +47 -0
- package/vendor/typescript/lib.es2020.sharedmemory.d.ts +99 -0
- package/vendor/typescript/lib.es2020.string.d.ts +44 -0
- package/vendor/typescript/lib.es2020.symbol.wellknown.d.ts +41 -0
- package/vendor/typescript/lib.es2021.d.ts +23 -0
- package/vendor/typescript/lib.es2021.intl.d.ts +166 -0
- package/vendor/typescript/lib.es2021.promise.d.ts +48 -0
- package/vendor/typescript/lib.es2021.string.d.ts +33 -0
- package/vendor/typescript/lib.es2021.weakref.d.ts +78 -0
- package/vendor/typescript/lib.es2022.array.d.ts +121 -0
- package/vendor/typescript/lib.es2022.d.ts +25 -0
- package/vendor/typescript/lib.es2022.error.d.ts +75 -0
- package/vendor/typescript/lib.es2022.intl.d.ts +145 -0
- package/vendor/typescript/lib.es2022.object.d.ts +26 -0
- package/vendor/typescript/lib.es2022.regexp.d.ts +39 -0
- package/vendor/typescript/lib.es2022.string.d.ts +25 -0
- package/vendor/typescript/lib.es5.d.ts +4601 -0
- package/vendor/typescript/package.json +4 -0
- package/vendor/typescript/typescript.js +446 -0
- package/web/assets/index-Bh74DfsV.css +1 -0
- package/web/assets/index-UW0RyFFt.js +13 -0
- package/web/index.html +14 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// A document's link in the workbench's address (#项目周报-Q3-k3xv9q2a): its title in the words a link can
|
|
2
|
+
// hold, the rest of it dashes, then the document's page id; a title that leaves no words is the id
|
|
3
|
+
// alone. The words are a label and nothing more: a link is read by what stands after its last dash,
|
|
4
|
+
// so that an address written down before a rename opens its document for ever, and two documents of
|
|
5
|
+
// one title need nothing to tell them apart.
|
|
6
|
+
//
|
|
7
|
+
// A page id has the look of a block id (shared/ids.mjs) and is worked out from the folder name, the
|
|
8
|
+
// document's identity, which a title never changes. So nothing is kept anywhere: no file, no list to
|
|
9
|
+
// keep in step, and a page alone in a tab or with no list read yet can always say its own address.
|
|
10
|
+
// The folder name opens its document too, for what was written by it. A document in the trash has its
|
|
11
|
+
// id, and has its address back when it is restored; one restored under another folder name goes by
|
|
12
|
+
// that name's id, as the links of files to it change too.
|
|
13
|
+
//
|
|
14
|
+
// Pure, and the same on the server, in the workbench and on a page, so that a title typed shows in the
|
|
15
|
+
// address at once. Only the documents of the sidebar and of the trash go by a link: 写作偏好 stands
|
|
16
|
+
// outside the tree of pages.
|
|
17
|
+
|
|
18
|
+
// What is no word of a title, a mark going with what it sits on (an emoji's variation selector).
|
|
19
|
+
const NOT_WORDS = /(?:[^\p{L}\p{M}\p{N}_]\p{M}*)+/gu;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A document's page id: eight letters and digits, a letter first, from a 53-bit hash of its folder
|
|
23
|
+
* name (cyrb53).
|
|
24
|
+
* @param {string} slug
|
|
25
|
+
*/
|
|
26
|
+
export function pageId(slug) {
|
|
27
|
+
let one = 0xdeadbeef;
|
|
28
|
+
let two = 0x41c6ce57;
|
|
29
|
+
for (let at = 0; at < slug.length; at++) {
|
|
30
|
+
one = Math.imul(one ^ slug.charCodeAt(at), 2654435761);
|
|
31
|
+
two = Math.imul(two ^ slug.charCodeAt(at), 1597334677);
|
|
32
|
+
}
|
|
33
|
+
one = Math.imul(one ^ (one >>> 16), 2246822507) ^ Math.imul(two ^ (two >>> 13), 3266489909);
|
|
34
|
+
two = Math.imul(two ^ (two >>> 16), 2246822507) ^ Math.imul(one ^ (one >>> 13), 3266489909);
|
|
35
|
+
const hash = (two >>> 0) % 2 ** 21 * 2 ** 32 + (one >>> 0);
|
|
36
|
+
return String.fromCharCode(97 + hash % 26) + Math.floor(hash / 26).toString(36).padStart(7, "0").slice(-7);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A document's link, what stands after # in its address: its title's words and its page id, the id
|
|
41
|
+
* alone for a title that leaves no words or one not known here.
|
|
42
|
+
* @param {{ slug: string, title?: string }} page
|
|
43
|
+
*/
|
|
44
|
+
export function pageLink({ slug, title }) {
|
|
45
|
+
const words = String(title ?? "").replace(NOT_WORDS, "-").replace(/^[-\p{M}]+|-+$/gu, "");
|
|
46
|
+
return words ? `${words}-${pageId(slug)}` : pageId(slug);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Each document's link: a Map of slug to link, which is also the list of documents an address is read
|
|
51
|
+
* against (pageOfLink).
|
|
52
|
+
* @param {{ slug: string, title?: string }[]} pages
|
|
53
|
+
* @returns {Map<string, string>}
|
|
54
|
+
*/
|
|
55
|
+
export const pageLinks = (pages) => new Map(pages.map((page) => [page.slug, pageLink(page)]));
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The document `value` names of those in `links`: by its folder name, else by the page id after the
|
|
59
|
+
* last dash of a link, or that id alone, whatever words stand before it. Its slug, or null.
|
|
60
|
+
* @param {Map<string, string>} links
|
|
61
|
+
* @param {string} value
|
|
62
|
+
*/
|
|
63
|
+
export function pageOfLink(links, value) {
|
|
64
|
+
if (links.has(value)) return value;
|
|
65
|
+
const id = value.slice(value.lastIndexOf("-") + 1);
|
|
66
|
+
for (const slug of links.keys()) if (pageId(slug) === id) return slug;
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Whether `name` (a slug or a link, what stands before any "/" of an address) names a document of the trash ({ slug, title } each).
|
|
72
|
+
* @param {{ slug: string, title?: string }[]} trash
|
|
73
|
+
* @param {string} name
|
|
74
|
+
*/
|
|
75
|
+
export const inTrash = (trash, name) => pageOfLink(pageLinks(trash), name.split("/")[0]) !== null;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* What an address written for anyone goes by: `links` and the links of the trash (`trash`: { slug,
|
|
79
|
+
* title } each).
|
|
80
|
+
* @param {Map<string, string>} links
|
|
81
|
+
* @param {{ slug: string, title?: string }[]} trash
|
|
82
|
+
*/
|
|
83
|
+
export const namedLinks = (links, trash) => new Map([...pageLinks(trash), ...links]);
|
|
84
|
+
|
|
85
|
+
/** The pages of a list of reports (`reports` of the outline's answer) that hold a link: all but 写作偏好. */
|
|
86
|
+
export const linkedPages = (reports) => Object.values(reports).filter(({ instructions }) => !instructions);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { findWorkspace, layoutOf } from "./workspace.mjs";
|
|
5
|
+
|
|
6
|
+
// Where everything is on disk, for every system, in two kinds: the workspace's (the user's documents
|
|
7
|
+
// and what Gallery keeps of them: ./workspace.mjs) and the package's (Gallery's own files). Only paths
|
|
8
|
+
// are computed here, at import, and nothing is made: the gallery command sets GALLERY_WORKSPACE (from
|
|
9
|
+
// --workspace, or the workspace it found) before it imports anything that imports this; npm run dev
|
|
10
|
+
// sets it to the repository's reports/ (vite.config.ts), the tests to folders of their own.
|
|
11
|
+
|
|
12
|
+
// The package: the folder up from this file whose package.json is @heycys/gallery's (src/shared/ here,
|
|
13
|
+
// a dist/ chunk in the release).
|
|
14
|
+
function findPackageRoot() {
|
|
15
|
+
for (let directory = path.dirname(fileURLToPath(import.meta.url)); ; directory = path.dirname(directory)) {
|
|
16
|
+
try {
|
|
17
|
+
if (JSON.parse(readFileSync(path.join(directory, "package.json"), "utf8")).name === "@heycys/gallery") return directory;
|
|
18
|
+
} catch {}
|
|
19
|
+
if (path.dirname(directory) === directory) return path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export const packageRoot = findPackageRoot();
|
|
23
|
+
/** The package's folder (its old name, which the tests and the maintainers' scripts use). */
|
|
24
|
+
export const projectRoot = packageRoot;
|
|
25
|
+
/**
|
|
26
|
+
* Whether this is the release build (npm run release:build, src/cli/release-build.mjs): release.json in
|
|
27
|
+
* the package, which says its version and the stamps of its files (src/server/stamps.mjs). Gallery's
|
|
28
|
+
* own files are then the package's folders (dist/, web/, browser/, kit/, vendor/…), else the source
|
|
29
|
+
* checkout's (src/, public/, node_modules/).
|
|
30
|
+
*/
|
|
31
|
+
export const releaseFile = path.join(packageRoot, "release.json");
|
|
32
|
+
export const release = existsSync(releaseFile);
|
|
33
|
+
|
|
34
|
+
// The workspace: the user's documents (<workspace>/<slug>/) and what is made of them.
|
|
35
|
+
export const workspaceRoot = path.resolve(process.env.GALLERY_WORKSPACE || findWorkspace().root);
|
|
36
|
+
const workspace = layoutOf(workspaceRoot);
|
|
37
|
+
/** The documents' folder: the workspace's root (its old name, which 60 modules import). */
|
|
38
|
+
export const reportsDirectory = workspaceRoot;
|
|
39
|
+
export const generatedDirectory = workspace.built; // built previews (nothing serves them: the export builds through them)
|
|
40
|
+
export const exportsDirectory = workspace.exports; // the offline deliverables, the user's
|
|
41
|
+
export const qaDirectory = workspace.qa; // gallery qa's pictures of what it flagged in an export
|
|
42
|
+
export const backupsDirectory = workspace.backups; // documents as they were before a migration (add-block-ids.mjs)
|
|
43
|
+
export const editStateDirectory = workspace.state; // the editor's token, snapshots, recent versions…
|
|
44
|
+
// What a server a command started says while it runs (it runs on after that command).
|
|
45
|
+
export const previewLogFile = workspace.serverLog;
|
|
46
|
+
|
|
47
|
+
// Gallery's own files, which a command never writes (a global install may be read-only): the shared
|
|
48
|
+
// kit and the starter, what the preview serves, what the checks and the import read. In the release
|
|
49
|
+
// each is a folder of the package (docs/internals.md, "Packaging"); in the source checkout, where it is
|
|
50
|
+
// kept or built (npm run dev's predev writes public/kit and public/vendor: src/cli/build-kit.mjs).
|
|
51
|
+
const inPackage = (built, ...source) => path.join(packageRoot, ...(release ? built : source));
|
|
52
|
+
export const kitSourceDirectory = path.join(packageRoot, "src", "render", "kit"); // the source checkout's only
|
|
53
|
+
export const starterDirectory = inPackage(["starter"], "src", "render", "starter");
|
|
54
|
+
export const vendorDirectory = inPackage(["vendor"], "public", "vendor");
|
|
55
|
+
export const kitPublicDirectory = inPackage(["kit"], "public", "kit");
|
|
56
|
+
/** The editor's browser modules, at their path under src/ (the preview serves them so: src/server/routes.mjs). */
|
|
57
|
+
export const browserDirectory = inPackage(["browser"], "src");
|
|
58
|
+
/** The emoji and icon data (the editor fetches it; the render reads it for a page's icon). */
|
|
59
|
+
export const emojiDataDirectory = path.join(browserDirectory, "shared", "emoji", "data");
|
|
60
|
+
/** The workbench as built (index.html and assets/): the release's; the source checkout's is Vite's (src/workbench/app/). */
|
|
61
|
+
export const workbenchDirectory = release ? path.join(packageRoot, "web") : null;
|
|
62
|
+
/** The SDK's types (the type check's roots, and what a script's JSDoc imports of ../../sdk reach). */
|
|
63
|
+
export const sdkDirectory = path.join(packageRoot, "sdk");
|
|
64
|
+
/** Gallery's default 写作偏好 (shared/writing-preferences.mjs). */
|
|
65
|
+
export const defaultPreferencesFile = inPackage(["assets", "writing-preferences.md"], "src", "shared", "writing-preferences.md");
|
|
66
|
+
/** TypeScript (src/render/typescript.mjs): the release's own minified copy, beside the libs it reads; null: the typescript package. */
|
|
67
|
+
export const typescriptFile = release ? path.join(packageRoot, "vendor", "typescript", "typescript.js") : null;
|
|
68
|
+
/** Where the type check finds d3's types (the type library d3, and the d3-* it names). */
|
|
69
|
+
export const typeRoots = [inPackage(["vendor", "types", "@types"], "node_modules", "@types")];
|
|
70
|
+
/** pdf.js (a PDF's import: src/transfer/import.mjs): the release's subset; null: the pdfjs-dist package. */
|
|
71
|
+
export const pdfjsDirectory = release ? path.join(packageRoot, "vendor", "pdfjs") : null;
|
|
72
|
+
/** The thin skill gallery skill install writes: the release's (the source checkout makes it: src/cli/package-skill.mjs). */
|
|
73
|
+
export const skillDirectory = release ? path.join(packageRoot, "skill") : null;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// The reader's preferences of Gallery's UI (the workbench's 设置): switches (and a width) kept in localStorage,
|
|
2
|
+
// which the workbench and every report page share (one origin), so the page editor follows a change
|
|
3
|
+
// at once (the storage event reaches every other page of the origin). Each has its default (off, but for
|
|
4
|
+
// showChanges) until changed.
|
|
5
|
+
// editFrame 显示编辑框: the dashed frame around the text being edited (editor/page/frame.mjs)
|
|
6
|
+
// quietNotices 减少通知: the notices of everyday operations (what was just done, how to go on) are not
|
|
7
|
+
// shown, only what the reader must act on or would not know otherwise (editor/page/quiet.mjs)
|
|
8
|
+
// showChanges 显示变更: what an Agent wrote marked on the page, with the bar to keep or revert it
|
|
9
|
+
// (editor/page/changes/); on until switched off, and off, what comes under review is kept as it comes
|
|
10
|
+
// outlineWidth the outline's width in full, as the reader dragged it (px; 0: its default), for every report
|
|
11
|
+
// outlineCollapsed the outline as its strip where the room would give it the list in full: a click on its
|
|
12
|
+
// guide (editor/page/outline/), and again on the guide in the strip's card to have the list back;
|
|
13
|
+
// for every report, as its width
|
|
14
|
+
//
|
|
15
|
+
// Whether the outline (目录, the top bar's 更多; editor/page/outline/) shows is no preference of the UI
|
|
16
|
+
// but the report's, as what is folded in it is: switched on for one report, the others keep
|
|
17
|
+
// theirs, and every report has it off until it is switched on there. It is kept apart, under its own
|
|
18
|
+
// key (OUTLINE_OPEN_KEY): the slugs of the reports that have it on, the one switched on last at the end,
|
|
19
|
+
// at most OPEN_KEEP of them (switched on for one more, the one switched on longest ago lets it go), so
|
|
20
|
+
// what is kept stays small with no list of the reports to check it against. Off, a report is taken out
|
|
21
|
+
// of it. The page's head reads it before the page shows (editor/page/margin.mjs), and a page follows a
|
|
22
|
+
// switch made in another (the workbench's top bar, another tab) by the storage event, as the switches above.
|
|
23
|
+
// Both keys are named in renamed-storage.mjs, which carries what the old names hold (before 2026-10-26).
|
|
24
|
+
|
|
25
|
+
import { KEYS, OLD_KEYS } from "./renamed-storage.mjs";
|
|
26
|
+
|
|
27
|
+
const KEY = KEYS.preferences;
|
|
28
|
+
/** The preferences, each with its default (a switch's false but 显示变更's, a width's 0). */
|
|
29
|
+
export const PREFERENCES = { editFrame: false, quietNotices: false, showChanges: true, outlineWidth: 0, outlineCollapsed: false };
|
|
30
|
+
|
|
31
|
+
/** The key they are kept under (the page's head reads the outline's width and whether it is collapsed before it shows: editor/page/margin.mjs). */
|
|
32
|
+
export const PREFERENCES_KEY = KEY;
|
|
33
|
+
|
|
34
|
+
function stored() {
|
|
35
|
+
try {
|
|
36
|
+
const value = JSON.parse(globalThis.localStorage?.getItem(KEY) ?? "{}");
|
|
37
|
+
return value && typeof value === "object" ? value : {};
|
|
38
|
+
} catch {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** The value of preference `name` (one of the other kind than its default's: the default). */
|
|
44
|
+
export function preference(name) {
|
|
45
|
+
const value = stored()[name];
|
|
46
|
+
return typeof value === typeof PREFERENCES[name] && (typeof value !== "number" || Number.isFinite(value)) ? value : PREFERENCES[name];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Keep preference `name` as `value`. What is no preference any more is let go as one is kept (the
|
|
51
|
+
* outline's switch, once one for every report, is now each report's own: outlineOpen).
|
|
52
|
+
*/
|
|
53
|
+
export function setPreference(name, value) {
|
|
54
|
+
if (!Object.hasOwn(PREFERENCES, name)) return;
|
|
55
|
+
try {
|
|
56
|
+
const kept = typeof PREFERENCES[name] === "number" ? (Number.isFinite(Number(value)) ? Number(value) : PREFERENCES[name]) : Boolean(value);
|
|
57
|
+
const known = Object.fromEntries(Object.entries(stored()).filter(([key]) => Object.hasOwn(PREFERENCES, key)));
|
|
58
|
+
globalThis.localStorage?.setItem(KEY, JSON.stringify({ ...known, [name]: kept }));
|
|
59
|
+
} catch {}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Call `listener` when another page of the origin changes the preferences (the workbench, for a report page). */
|
|
63
|
+
export function onPreferences(listener) {
|
|
64
|
+
globalThis.addEventListener?.("storage", (event) => {
|
|
65
|
+
if (event.key === KEY || event.key === null) listener();
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ---------- the outline, each report's ----------
|
|
70
|
+
|
|
71
|
+
const OPEN_KEY = KEYS.outlineOpen;
|
|
72
|
+
const OPEN_KEEP = 100; // reports with the outline on
|
|
73
|
+
|
|
74
|
+
/** The key the reports with the outline on are kept under (a JSON list of their slugs; the page's head reads it: editor/page/margin.mjs). */
|
|
75
|
+
export const OUTLINE_OPEN_KEY = OPEN_KEY;
|
|
76
|
+
/** The two keys under their names before 2026-10-26, for the page's head, which runs before renamed-storage.mjs has carried them. */
|
|
77
|
+
export const OLD_PREFERENCES_KEY = OLD_KEYS.preferences;
|
|
78
|
+
export const OLD_OUTLINE_OPEN_KEY = OLD_KEYS.outlineOpen;
|
|
79
|
+
|
|
80
|
+
function openSlugs() {
|
|
81
|
+
try {
|
|
82
|
+
const value = JSON.parse(globalThis.localStorage?.getItem(OPEN_KEY) ?? "[]");
|
|
83
|
+
return Array.isArray(value) ? value.filter((slug) => typeof slug === "string" && slug !== "") : [];
|
|
84
|
+
} catch {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Whether report `slug` has its outline on (off until it is switched on there). */
|
|
90
|
+
export function outlineOpen(slug) {
|
|
91
|
+
return typeof slug === "string" && slug !== "" && openSlugs().includes(slug);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Report `slug`'s outline switched on or off: on, it is the one switched on last (at most OPEN_KEEP
|
|
96
|
+
* reports, the one switched on longest ago let go); off, it is taken out.
|
|
97
|
+
*/
|
|
98
|
+
export function setOutlineOpen(slug, on) {
|
|
99
|
+
if (typeof slug !== "string" || slug === "") return;
|
|
100
|
+
try {
|
|
101
|
+
const slugs = openSlugs().filter((one) => one !== slug);
|
|
102
|
+
if (on) slugs.push(slug);
|
|
103
|
+
globalThis.localStorage?.setItem(OPEN_KEY, JSON.stringify(slugs.slice(-OPEN_KEEP)));
|
|
104
|
+
} catch {}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Call `listener` when another page of the origin switches a report's outline (the workbench's 更多 ›
|
|
109
|
+
* 目录, the same report in another tab): it reads outlineOpen() for its own report, which may not have
|
|
110
|
+
* changed (another report switched).
|
|
111
|
+
*/
|
|
112
|
+
export function onOutlineOpen(listener) {
|
|
113
|
+
globalThis.addEventListener?.("storage", (event) => {
|
|
114
|
+
if (event.key === OPEN_KEY || event.key === null) listener();
|
|
115
|
+
});
|
|
116
|
+
}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import net from "node:net";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { packageRoot } from "./paths.mjs";
|
|
7
|
+
import { layoutOf } from "./workspace.mjs";
|
|
8
|
+
|
|
9
|
+
// Where a workspace's Gallery server listens (one a gallery command started, kind "cli", or npm run
|
|
10
|
+
// dev's, kind "dev"): the one way the commands tell this workspace's server from any other. gallery
|
|
11
|
+
// export hands a document in through the server's edit service (POST /__gallery/edit/hand-in), in the
|
|
12
|
+
// queue its pages' commits run in, instead of writing the file beside them; gallery open, new and
|
|
13
|
+
// import give a document's address on it, or start one when none runs (src/cli/server-process.mjs).
|
|
14
|
+
// The server keeps a small file in its workspace while it listens, .gallery/server.json (one server
|
|
15
|
+
// a workspace), with its port, its process, the token its requests need, its kind and Gallery's
|
|
16
|
+
// version; a command finds it there, or does without it when there is none, or its process is gone.
|
|
17
|
+
// A port is never asked whose it is: 4317 may be another workspace's server, whose pages would write
|
|
18
|
+
// that workspace's files.
|
|
19
|
+
|
|
20
|
+
// A directory as one name, however it was reached: on Windows a drive letter and the folders' names
|
|
21
|
+
// may be typed in either case (`cd /d d:\…` in cmd gives d:\), and they name the same directory.
|
|
22
|
+
const canonical = (directory) => {
|
|
23
|
+
const resolved = path.resolve(directory);
|
|
24
|
+
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
25
|
+
};
|
|
26
|
+
/** Whether two paths name the same directory (a server's workspace and a command's). */
|
|
27
|
+
export const sameDirectory = (a, b) => canonical(a) === canonical(b);
|
|
28
|
+
|
|
29
|
+
const fileOf = (reportsDirectory) => layoutOf(reportsDirectory).serverFile;
|
|
30
|
+
/** Gallery's version, as its package says it (a server of another version is another Gallery's). */
|
|
31
|
+
export const galleryVersion = (() => {
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(readFileSync(path.join(packageRoot, "package.json"), "utf8")).version ?? "0.0.0";
|
|
34
|
+
} catch {
|
|
35
|
+
return "0.0.0";
|
|
36
|
+
}
|
|
37
|
+
})();
|
|
38
|
+
|
|
39
|
+
// Whether a process runs (only asked: nothing is sent to it).
|
|
40
|
+
const runs = (pid) => {
|
|
41
|
+
try {
|
|
42
|
+
process.kill(pid, 0);
|
|
43
|
+
return true;
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return error.code === "EPERM";
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Keep where the server listens: { port, pid, workspace, token, nonce, kind, version, started }, for
|
|
51
|
+
* as long as it does (the owner's alone on POSIX: the token authorizes writes), so
|
|
52
|
+
* that a server that runs is one the commands find, never one a command starts a second server
|
|
53
|
+
* beside (which would take the announcement: the pages' commits in one queue, an export's hand-in in
|
|
54
|
+
* another). Every `every` ms (0: never) it is written again when its file is gone (taken away by
|
|
55
|
+
* hand, or by a server of these reports that closed as this one wrote it) or names a process that is
|
|
56
|
+
* gone (left behind). One that names another process that runs is left: a server of these reports
|
|
57
|
+
* started later (the last to start is the one the commands use), or the one Vite started again in
|
|
58
|
+
* this process. The .gallery/ folder is made again, never the workspace (a workspace deleted stays
|
|
59
|
+
* deleted). Resolves to a function that stops that and, only while the announcement is this one's
|
|
60
|
+
* (`nonce`), gives the file back to the server it was written over when that one's process runs (in
|
|
61
|
+
* another process: in this one it is Vite's earlier server), or else takes it away: for when the
|
|
62
|
+
* server closes. A server stopped without closing leaves it behind, which the commands find out (its
|
|
63
|
+
* process gone, its port answering no more).
|
|
64
|
+
*/
|
|
65
|
+
export async function announcePreviewServer({ reportsDirectory, port, token, kind = "dev", version = galleryVersion, every = 1000 }) {
|
|
66
|
+
const file = fileOf(reportsDirectory);
|
|
67
|
+
const nonce = randomBytes(8).toString("hex");
|
|
68
|
+
const text = `${JSON.stringify({ port, pid: process.pid, workspace: path.resolve(reportsDirectory), token, nonce, kind, version, started: new Date().toISOString() })}\n`;
|
|
69
|
+
const save = (content) => fs.writeFile(file, content, { mode: 0o600 });
|
|
70
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
71
|
+
const before = await fs.readFile(file, "utf8").catch(() => null);
|
|
72
|
+
await save(text);
|
|
73
|
+
let closed = false;
|
|
74
|
+
const look = async () => {
|
|
75
|
+
let there = null;
|
|
76
|
+
try {
|
|
77
|
+
there = JSON.parse(await fs.readFile(file, "utf8"));
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if (error.code !== "ENOENT") return; // being written (by another server), or not an announcement: left
|
|
80
|
+
}
|
|
81
|
+
if (there && (there.nonce === nonce || !Number.isInteger(there.pid) || runs(there.pid))) return;
|
|
82
|
+
if (closed) return;
|
|
83
|
+
await fs.mkdir(path.dirname(file)).catch(() => {});
|
|
84
|
+
await save(text).catch(() => {});
|
|
85
|
+
};
|
|
86
|
+
let looking = Promise.resolve();
|
|
87
|
+
const keeping = every > 0 ? setInterval(() => (looking = looking.then(look).catch(() => {})), every) : null;
|
|
88
|
+
keeping?.unref();
|
|
89
|
+
return async () => {
|
|
90
|
+
closed = true;
|
|
91
|
+
clearInterval(keeping);
|
|
92
|
+
await looking;
|
|
93
|
+
try {
|
|
94
|
+
if (JSON.parse(await fs.readFile(file, "utf8")).nonce !== nonce) return;
|
|
95
|
+
} catch {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
let earlier = null;
|
|
99
|
+
try {
|
|
100
|
+
earlier = JSON.parse(before);
|
|
101
|
+
} catch {}
|
|
102
|
+
const back = Number.isInteger(earlier?.pid) && earlier.pid !== process.pid && runs(earlier.pid);
|
|
103
|
+
await (back ? save(before) : fs.rm(file, { force: true })).catch(() => {});
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// The announcement of this workspace's server, while its process runs: { port, pid, workspace, token, nonce, kind, version, started }.
|
|
108
|
+
export async function readAnnouncement({ reportsDirectory }) {
|
|
109
|
+
let found;
|
|
110
|
+
try {
|
|
111
|
+
found = JSON.parse(await fs.readFile(fileOf(reportsDirectory), "utf8"));
|
|
112
|
+
} catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
if (!Number.isInteger(found?.port) || !Number.isInteger(found.pid) || typeof found.token !== "string" || typeof found.workspace !== "string" || !sameDirectory(found.workspace, reportsDirectory)) return null;
|
|
116
|
+
return runs(found.pid) ? found : null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Whether process `pid` runs (only asked: nothing is sent to it). */
|
|
120
|
+
export const processRuns = runs;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* How the server an announcement names answers on its port, within `timeout` ms: "yes", as that
|
|
124
|
+
* server (GET /__gallery/workspace/info there names the announcement's token, its process and this
|
|
125
|
+
* workspace, docs/workbench.md; there itself, not where it sends the request on to); "no", as none (a
|
|
126
|
+
* server stopped without closing leaves its announcement behind, and by now its process's number may
|
|
127
|
+
* be another program's, its port another server's); or "busy": the port took the request and gave no
|
|
128
|
+
* answer in time.
|
|
129
|
+
*/
|
|
130
|
+
export async function answerOf(found, reportsDirectory, timeout) {
|
|
131
|
+
try {
|
|
132
|
+
const response = await fetch(`http://127.0.0.1:${found.port}/__gallery/workspace/info`, { redirect: "error", signal: AbortSignal.timeout(timeout) });
|
|
133
|
+
const info = response.ok ? await response.json() : null;
|
|
134
|
+
const same = info?.token === found.token && info.server?.pid === found.pid && typeof info.server.workspace === "string" && sameDirectory(info.server.workspace, reportsDirectory);
|
|
135
|
+
return same ? "yes" : "no";
|
|
136
|
+
} catch (error) {
|
|
137
|
+
return error?.name === "TimeoutError" ? "busy" : "no";
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* The running server of this workspace: { port, token, pid }, or null when none says it runs. With
|
|
143
|
+
* `answering`, only one that answers on its port as the server its announcement names, within
|
|
144
|
+
* `timeout` ms (gallery open, which gives its address to the user); gallery export asks without it,
|
|
145
|
+
* its hand-in's own request telling whether the server takes it (a server slow to answer may still
|
|
146
|
+
* write the file).
|
|
147
|
+
*/
|
|
148
|
+
export async function findPreviewServer({ reportsDirectory, answering = false, timeout = 10_000 }) {
|
|
149
|
+
const found = await readAnnouncement({ reportsDirectory });
|
|
150
|
+
if (!found || (answering && (await answerOf(found, reportsDirectory, timeout)) !== "yes")) return null;
|
|
151
|
+
return { port: found.port, token: found.token, pid: found.pid };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Whether `port` of 127.0.0.1 is free: nothing holds it (held for a moment), and nothing answers on
|
|
156
|
+
* it (a server listening on every address may leave 127.0.0.1 alone to be held).
|
|
157
|
+
*/
|
|
158
|
+
export const portIsFree = (port) => new Promise((resolve) => {
|
|
159
|
+
const holder = net.createServer();
|
|
160
|
+
holder.once("error", () => resolve(false));
|
|
161
|
+
holder.listen(port, "127.0.0.1", () => holder.close(() => {
|
|
162
|
+
const socket = net.connect(port, "127.0.0.1");
|
|
163
|
+
socket.once("connect", () => {
|
|
164
|
+
socket.destroy();
|
|
165
|
+
resolve(false);
|
|
166
|
+
});
|
|
167
|
+
socket.once("error", (error) => resolve(error.code === "ECONNREFUSED"));
|
|
168
|
+
}));
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
/** -1, 0 or 1 as version `a` is older than, the same as or newer than `b` (numbers by dots: 0.1.0 < 0.1.10 < 0.2.0). */
|
|
172
|
+
export function compareVersions(a, b) {
|
|
173
|
+
const parts = (version) => String(version ?? "0").split(/[.+-]/).slice(0, 3).map((part) => Number.parseInt(part, 10) || 0);
|
|
174
|
+
const [x, y] = [parts(a), parts(b)];
|
|
175
|
+
for (let index = 0; index < 3; index++) if ((x[index] ?? 0) !== (y[index] ?? 0)) return (x[index] ?? 0) < (y[index] ?? 0) ? -1 : 1;
|
|
176
|
+
return 0;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
180
|
+
// Whether process `pid` is gone within `ms` (asked every 100 ms).
|
|
181
|
+
async function goneWithin(pid, ms) {
|
|
182
|
+
for (const until = Date.now() + ms; Date.now() < until; await sleep(100)) if (!runs(pid)) return true;
|
|
183
|
+
return !runs(pid);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Stop the server announcement `found` names, which answered as that server during this call
|
|
188
|
+
* (answerOf "yes": its process is this server's, never a number used again): POST
|
|
189
|
+
* /__gallery/workspace/stop (its token; the server finishes the saves in its queue, closes and exits), then,
|
|
190
|
+
* when its process still runs after `wait` ms, that process killed. Resolves to { ok: true, killed }
|
|
191
|
+
* or { ok: false, reason: "dev" (npm run dev's: stopped where it runs) | "running" (it would not stop), message }.
|
|
192
|
+
*/
|
|
193
|
+
export async function stopServer(found, { wait = 10_000 } = {}) {
|
|
194
|
+
const host = `127.0.0.1:${found.port}`;
|
|
195
|
+
let status = 0;
|
|
196
|
+
try {
|
|
197
|
+
const response = await fetch(`http://${host}/__gallery/workspace/stop`, {
|
|
198
|
+
method: "POST",
|
|
199
|
+
headers: { "Content-Type": "application/json", Origin: `http://${host}`, "X-Gallery-Token": found.token },
|
|
200
|
+
body: "{}",
|
|
201
|
+
signal: AbortSignal.timeout(wait),
|
|
202
|
+
});
|
|
203
|
+
status = response.status;
|
|
204
|
+
await response.text().catch(() => "");
|
|
205
|
+
} catch {} // it closed as it answered, or did not answer: its process says
|
|
206
|
+
if (status === 409) return { ok: false, reason: "dev", message: `This workspace's server is npm run dev's (port ${found.port}, pid ${found.pid}): stop it where it runs.` };
|
|
207
|
+
if (await goneWithin(found.pid, wait)) return { ok: true, killed: false };
|
|
208
|
+
try {
|
|
209
|
+
process.kill(found.pid);
|
|
210
|
+
} catch {}
|
|
211
|
+
if (await goneWithin(found.pid, 3000)) return { ok: true, killed: true };
|
|
212
|
+
return { ok: false, reason: "running", message: `The server on port ${found.port} (pid ${found.pid}) did not stop: end that process yourself.` };
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* This workspace's server, for a command that needs one (src/cli/server-process.mjs serverFor): the
|
|
217
|
+
* one its announcement names when it answers there within `timeout` ms (as findPreviewServer with
|
|
218
|
+
* `answering`), or else one `start(port)` starts on the first free port of `ports`. A server of
|
|
219
|
+
* Gallery's of an older `version` (a command's, kind "cli": never npm run dev's) is stopped first
|
|
220
|
+
* (`stop(found)`, stopServer) and replaced; a newer one, or npm run dev's of any version, is used.
|
|
221
|
+
* Resolves to { port, started: what `start` gave, or null for a server that ran already, running: {
|
|
222
|
+
* pid, kind, version } of that one, replaced: { pid, version } of the one stopped, or null, passed:
|
|
223
|
+
* the ports passed over, as "4317 (in use)" }; `port` is null when none of `ports` is free; when the
|
|
224
|
+
* announced server's port took the request and gave no answer in time, with `busy: { port, pid,
|
|
225
|
+
* version, newer }`: this workspace's server, busy or stuck, and none is started beside it; and when
|
|
226
|
+
* an older one would not stop, with `stuck: { port, pid, message }`.
|
|
227
|
+
*/
|
|
228
|
+
export async function previewServerFor({ reportsDirectory, ports, start, stop = stopServer, timeout = 10_000, version = galleryVersion }) {
|
|
229
|
+
const found = await readAnnouncement({ reportsDirectory });
|
|
230
|
+
const answer = found ? await answerOf(found, reportsDirectory, timeout) : "no";
|
|
231
|
+
const kind = found?.kind === "dev" ? "dev" : "cli";
|
|
232
|
+
const order = found ? compareVersions(found.version, version) : 0;
|
|
233
|
+
if (answer === "busy") return { port: null, started: null, passed: [], replaced: null, busy: { port: found.port, pid: found.pid, version: found.version ?? null, newer: kind === "cli" && order > 0 } };
|
|
234
|
+
let replaced = null;
|
|
235
|
+
if (answer === "yes") {
|
|
236
|
+
if (kind === "dev" || order >= 0) return { port: found.port, started: null, passed: [], replaced: null, running: { pid: found.pid, kind, version: found.version ?? null } };
|
|
237
|
+
const stopped = await stop(found);
|
|
238
|
+
if (!stopped.ok) return { port: null, started: null, passed: [], replaced: null, stuck: { port: found.port, pid: found.pid, message: stopped.message } };
|
|
239
|
+
replaced = { pid: found.pid, version: found.version ?? null };
|
|
240
|
+
}
|
|
241
|
+
const passed = [];
|
|
242
|
+
for (const port of ports) {
|
|
243
|
+
if (await portIsFree(port)) return { port, started: await start(port), passed, replaced };
|
|
244
|
+
passed.push(`${port} (in use)`);
|
|
245
|
+
}
|
|
246
|
+
return { port: null, started: null, passed, replaced };
|
|
247
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// The levels of what gallery qa finds (src/cli/qa.mjs, docs/render.md "Quality check"), and
|
|
2
|
+
// of the kit's layout notes (data-doc-layout), which the preview's note reads with the same
|
|
3
|
+
// function (render/preview-checks.mjs puts layoutNotesScript() in the page): a note that fails qa is
|
|
4
|
+
// among the preview's failures, the others its 排版提示. levelOf and layoutNotesOf read nothing but
|
|
5
|
+
// WIDE, KINDS and NARROW_INFO, so they can be written into a page as their text. And the windows
|
|
6
|
+
// gallery qa looks in, whose widths the preview's note names.
|
|
7
|
+
|
|
8
|
+
// Three widths in a window 900px tall, and the widest again in a laptop's window (768px tall), where
|
|
9
|
+
// a frame of the kit's height (72vh) shows fewer rows: that look says only what the first did not.
|
|
10
|
+
export const LOOKS = [
|
|
11
|
+
{ width: 1024, height: 900, label: "1024" },
|
|
12
|
+
{ width: 1024, height: 768, label: "1024×768", laptop: true },
|
|
13
|
+
{ width: 736, height: 900, label: "736" },
|
|
14
|
+
{ width: 360, height: 900, label: "360" },
|
|
15
|
+
];
|
|
16
|
+
// The widths blocks are pictured at (the laptop's window adds no pictures of blocks).
|
|
17
|
+
export const WIDTHS = LOOKS.filter((look) => !look.laptop).map((look) => look.width);
|
|
18
|
+
|
|
19
|
+
// A table's columns or rows out of sight, and a code block or a formula whose content scrolls inside
|
|
20
|
+
// its frame, are a warning only where a reader has room for them (WIDE and wider), and info below,
|
|
21
|
+
// where a frame that scrolls is what it does (NARROW_INFO).
|
|
22
|
+
export const WIDE = 736;
|
|
23
|
+
export const LEVELS = ["fail", "warn", "unverified", "info"];
|
|
24
|
+
export const KINDS = {
|
|
25
|
+
error: "fail", // the page's error, uncaught or on the console
|
|
26
|
+
request: "fail", // a request that failed
|
|
27
|
+
blocked: "fail", // what the export's policy blocked: a file not embedded
|
|
28
|
+
image: "fail", // a picture that did not load
|
|
29
|
+
"chart-empty": "fail", // a chart that drew nothing (the kit's data-missing too)
|
|
30
|
+
"chart-text-clipped": "fail", // a chart's text cut by a clip
|
|
31
|
+
"chart-text-outside": "fail", // a chart's text outside its card
|
|
32
|
+
"raw-formula": "fail", // TeX shown as written
|
|
33
|
+
"formula-error": "fail", // a formula KaTeX refused
|
|
34
|
+
overflow: "fail", // the page wider than the window
|
|
35
|
+
"overflow-in-block": "warn", // words past the side of their box in a whole block or a figure's drawing, over what is beside it
|
|
36
|
+
"cut-in-block": "warn", // words or marks of a whole block or a figure's drawing cut at the bottom of a box that clips them
|
|
37
|
+
"table-columns": "warn", // a table's columns out of sight or cut (below WIDE: info)
|
|
38
|
+
"table-rows": "warn", // a table's rows below a frame of the kit's height (below WIDE: info)
|
|
39
|
+
"code-scrolls": "warn", // a code block's code scrolling inside its frame (below WIDE: info)
|
|
40
|
+
"formula-scrolls": "warn", // a formula block scrolling inside its frame (below WIDE: info)
|
|
41
|
+
"chart-text-overlap": "warn", // two texts of a drawing over each other
|
|
42
|
+
"svg-text-small": "warn", // a drawing's text its viewBox scales below a readable size
|
|
43
|
+
ticks: "warn", // a value axis's tick labels closer than a digit's width and a hair (0.6em)
|
|
44
|
+
"layout-note": "info", // the kit's other notes on its layout
|
|
45
|
+
"table-scrolls": "info", // a table that scrolls in its frame
|
|
46
|
+
"code-title-cut": "info", // a code block's title cut to fit its header
|
|
47
|
+
unverified: "unverified", // a wait that ran out, a state not reached, a picture not taken
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// The kinds that warn at WIDE and wider and are info below.
|
|
51
|
+
export const NARROW_INFO = ["table-columns", "table-rows", "code-scrolls", "formula-scrolls"];
|
|
52
|
+
|
|
53
|
+
/** The level of a finding of `kind` at a window `width` px wide. */
|
|
54
|
+
export function levelOf(kind, width) {
|
|
55
|
+
if (NARROW_INFO.includes(kind)) return width >= WIDE ? "warn" : "info";
|
|
56
|
+
return KINDS[kind] ?? "warn";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The notes the kit wrote on an element (data-doc-layout: one a line, each "<name>: <message>",
|
|
61
|
+
* such as "data-missing: its table has merged cells: …"), each with the kind of finding it makes and
|
|
62
|
+
* its level at a window `width` px wide: data-missing fails (a chart drawn from a table with nothing
|
|
63
|
+
* to draw, its card saying why: chart-empty); columns-hidden is a table's columns out of sight and
|
|
64
|
+
* rows-hidden its rows below its frame (warnings where a reader has room for them, info below); any
|
|
65
|
+
* other note is info. [{ note, name, kind, level }]
|
|
66
|
+
*/
|
|
67
|
+
export function layoutNotesOf(value, width = Infinity) {
|
|
68
|
+
const kinds = { "columns-hidden": "table-columns", "rows-hidden": "table-rows", "data-missing": "chart-empty" };
|
|
69
|
+
return String(value ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((note) => {
|
|
70
|
+
const name = note.split(":")[0].trim().toLowerCase();
|
|
71
|
+
const kind = kinds[name] ?? "layout-note";
|
|
72
|
+
return { note, name, kind, level: levelOf(kind, width) };
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A layout note of the kit's that fails (layoutNotesOf's `note`, "<name>: <message>"), in the words of
|
|
78
|
+
* the person reading the preview's note, in Chinese unless { english } (the UI's language): a chart
|
|
79
|
+
* that drew nothing (the preview says its card's own line of why when it has one), in a sentence. The
|
|
80
|
+
* note itself, in English, is gallery qa's and an Agent's, and stays as it is on the page; a note it
|
|
81
|
+
* does not know is said as it is. Written with no outside name, so the preview's page can carry it
|
|
82
|
+
* (layoutNotesScript).
|
|
83
|
+
*/
|
|
84
|
+
export function noteInWords(note, { english = false } = {}) {
|
|
85
|
+
const text = String(note ?? "").trim();
|
|
86
|
+
const colon = text.indexOf(":");
|
|
87
|
+
const name = colon < 0 ? "" : text.slice(0, colon).trim().toLowerCase();
|
|
88
|
+
if (name === "data-missing") return english ? "The chart was not drawn: its table gave it nothing to draw" : "图表没有画出来:从表格里没读到能画的数据";
|
|
89
|
+
return text;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** levelOf, layoutNotesOf and noteInWords as a script's text, for a page (the preview's note) to read notes as qa does and say them. */
|
|
93
|
+
export const layoutNotesScript = () => `const WIDE = ${WIDE}; const KINDS = ${JSON.stringify(KINDS)}; const NARROW_INFO = ${JSON.stringify(NARROW_INFO)}; ${levelOf}; ${layoutNotesOf}; ${noteInWords};`;
|