@bendyline/squisq 2.1.0 → 2.2.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/LICENSE +21 -0
- package/NOTICE.md +24 -0
- package/dist/{ContentContainer-BXUlIf18.d.ts → ContentContainer-B2w9sUoL.d.ts} +15 -0
- package/dist/{Doc-DynJleo-.d.ts → Doc-BubIpWsp.d.ts} +1 -1
- package/dist/{ImageEditDoc-Ca4Tr9uN.d.ts → ImageEditDoc-CGxk5CHc.d.ts} +1 -1
- package/dist/{annotationCoercion-Dr_DY9Hx.d.ts → annotationCoercion-PtRQhk5V.d.ts} +1 -1
- package/dist/chunk-2L55443L.js +0 -0
- package/dist/{chunk-VWCJ2WXC.js → chunk-2ZWIXGAC.js} +0 -1
- package/dist/{chunk-VYFRI7R6.js → chunk-32R2RZAO.js} +72 -3
- package/dist/chunk-3IGPAPQ7.js +645 -0
- package/dist/{chunk-QE7TWGVT.js → chunk-4VOD55SX.js} +0 -1
- package/dist/{chunk-3E5F2XMR.js → chunk-67L6WRJN.js} +0 -1
- package/dist/{chunk-5DKBFXPY.js → chunk-6ECMNUIP.js} +26 -18
- package/dist/{chunk-JI77MGAK.js → chunk-7ARJZYQY.js} +159 -120
- package/dist/{chunk-DBS6RIFL.js → chunk-7N4G32LG.js} +0 -1
- package/dist/{chunk-JOQYPRDZ.js → chunk-7YEZFHLS.js} +10 -8
- package/dist/{chunk-2UQOHYE2.js → chunk-7ZAAICW4.js} +0 -1
- package/dist/{chunk-66QO7XFB.js → chunk-ACZOVWX3.js} +117 -7
- package/dist/{chunk-5J4HKRJF.js → chunk-BAOV476U.js} +0 -1
- package/dist/chunk-BCCXTMN5.js +699 -0
- package/dist/{chunk-JHZWYRSW.js → chunk-C33GTPUZ.js} +11 -4
- package/dist/{chunk-QUUPYOSP.js → chunk-CB45YGAM.js} +2 -3
- package/dist/{chunk-XNLB57UD.js → chunk-DYPMOPIW.js} +18 -2
- package/dist/{chunk-VR7UPJ7C.js → chunk-FCG3BIZN.js} +12 -1
- package/dist/{chunk-5UYI3RJB.js → chunk-FDYDYL77.js} +54 -40
- package/dist/{chunk-OTKVFVL6.js → chunk-I2O6W7DX.js} +116 -44
- package/dist/{chunk-Q7LROV2H.js → chunk-NKNMGIIN.js} +0 -1
- package/dist/chunk-OPO5K4DZ.js +241 -0
- package/dist/{chunk-TUWMK62B.js → chunk-PUS54YU6.js} +45 -2
- package/dist/chunk-QKPXHDLR.js +0 -0
- package/dist/{chunk-GZY66SDN.js → chunk-R3KTTOMS.js} +0 -1
- package/dist/{chunk-ILWDXLUK.js → chunk-RS5AP3J4.js} +49 -10
- package/dist/chunk-WV5ARNDA.js +0 -0
- package/dist/{chunk-4X3JQXNM.js → chunk-XOFT65EX.js} +1 -2
- package/dist/{chunk-FVTQSNR7.js → chunk-XRW6P7IF.js} +13 -5
- package/dist/chunk-XWNNA3KE.js +0 -0
- package/dist/chunk-YZNGMV3G.js +0 -0
- package/dist/{chunk-R2YZTCLO.js → chunk-ZQKZSJAX.js} +1 -2
- package/dist/doc/index.d.ts +27 -12
- package/dist/doc/index.js +16 -17
- package/dist/generate/index.d.ts +2 -2
- package/dist/generate/index.js +2 -3
- package/dist/icons/index.js +3 -4
- package/dist/icons/inlineIconMarker.js +1 -2
- package/dist/imageEdit/index.d.ts +48 -17
- package/dist/imageEdit/index.js +3 -4
- package/dist/index.d.ts +11 -11
- package/dist/index.js +60 -33
- package/dist/jsonForm/index.d.ts +10 -3
- package/dist/jsonForm/index.js +8 -7
- package/dist/markdown/index.d.ts +75 -11
- package/dist/markdown/index.js +32 -7
- package/dist/{materializePageSection-DDzubQXo.d.ts → materializePageSection-wSLA2A1g.d.ts} +2 -2
- package/dist/narration/index.d.ts +16 -3
- package/dist/narration/index.js +13 -14
- package/dist/random/index.d.ts +11 -2
- package/dist/random/index.js +2 -3
- package/dist/recommend/index.d.ts +1 -1
- package/dist/recommend/index.js +3 -4
- package/dist/schemas/index.d.ts +5 -5
- package/dist/schemas/index.js +5 -6
- package/dist/spatial/index.d.ts +2 -1
- package/dist/spatial/index.js +1 -2
- package/dist/storage/index.d.ts +4 -2
- package/dist/storage/index.js +1 -2
- package/dist/{themeLibrary-B72m0W1y.d.ts → themeLibrary-DU9mUmVl.d.ts} +1 -1
- package/dist/timing/index.js +3 -4
- package/dist/transform/index.d.ts +3 -3
- package/dist/transform/index.js +6 -7
- package/dist/{types-C4kiRn_k.d.ts → types-8QjefM9J.d.ts} +38 -2
- package/dist/{types-BwMPl2CB.d.ts → types-CUNc9biN.d.ts} +24 -1
- package/dist/versions/index.d.ts +14 -11
- package/dist/versions/index.js +2 -3
- package/package.json +4 -2
- package/dist/chunk-2UQOHYE2.js.map +0 -1
- package/dist/chunk-3E5F2XMR.js.map +0 -1
- package/dist/chunk-4X3JQXNM.js.map +0 -1
- package/dist/chunk-5DKBFXPY.js.map +0 -1
- package/dist/chunk-5J4HKRJF.js.map +0 -1
- package/dist/chunk-5UYI3RJB.js.map +0 -1
- package/dist/chunk-66QO7XFB.js.map +0 -1
- package/dist/chunk-AMIR72JP.js +0 -380
- package/dist/chunk-AMIR72JP.js.map +0 -1
- package/dist/chunk-DBS6RIFL.js.map +0 -1
- package/dist/chunk-DNJKBAI7.js +0 -1
- package/dist/chunk-DNJKBAI7.js.map +0 -1
- package/dist/chunk-ET53IIEP.js +0 -1
- package/dist/chunk-ET53IIEP.js.map +0 -1
- package/dist/chunk-FVTQSNR7.js.map +0 -1
- package/dist/chunk-GZY66SDN.js.map +0 -1
- package/dist/chunk-ILWDXLUK.js.map +0 -1
- package/dist/chunk-JHZWYRSW.js.map +0 -1
- package/dist/chunk-JI77MGAK.js.map +0 -1
- package/dist/chunk-JOQYPRDZ.js.map +0 -1
- package/dist/chunk-OTKVFVL6.js.map +0 -1
- package/dist/chunk-PGGGKYWG.js +0 -1
- package/dist/chunk-PGGGKYWG.js.map +0 -1
- package/dist/chunk-Q7LROV2H.js.map +0 -1
- package/dist/chunk-QE7TWGVT.js.map +0 -1
- package/dist/chunk-QUUPYOSP.js.map +0 -1
- package/dist/chunk-R2GC6RLD.js +0 -344
- package/dist/chunk-R2GC6RLD.js.map +0 -1
- package/dist/chunk-R2YZTCLO.js.map +0 -1
- package/dist/chunk-S7A5D7ZJ.js +0 -174
- package/dist/chunk-S7A5D7ZJ.js.map +0 -1
- package/dist/chunk-TUWMK62B.js.map +0 -1
- package/dist/chunk-V543AI2F.js +0 -1
- package/dist/chunk-V543AI2F.js.map +0 -1
- package/dist/chunk-VR7UPJ7C.js.map +0 -1
- package/dist/chunk-VWCJ2WXC.js.map +0 -1
- package/dist/chunk-VYFRI7R6.js.map +0 -1
- package/dist/chunk-XNLB57UD.js.map +0 -1
- package/dist/chunk-ZLQKNOZQ.js +0 -1
- package/dist/chunk-ZLQKNOZQ.js.map +0 -1
- package/dist/doc/index.js.map +0 -1
- package/dist/generate/index.js.map +0 -1
- package/dist/icons/index.js.map +0 -1
- package/dist/icons/inlineIconMarker.js.map +0 -1
- package/dist/imageEdit/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/jsonForm/index.js.map +0 -1
- package/dist/markdown/index.js.map +0 -1
- package/dist/narration/index.js.map +0 -1
- package/dist/random/index.js.map +0 -1
- package/dist/recommend/index.js.map +0 -1
- package/dist/schemas/index.js.map +0 -1
- package/dist/spatial/index.js.map +0 -1
- package/dist/storage/index.js.map +0 -1
- package/dist/timing/index.js.map +0 -1
- package/dist/transform/index.js.map +0 -1
- package/dist/versions/index.js.map +0 -1
- package/src/__tests__/animationUtils.test.ts +0 -117
- package/src/__tests__/annotationCoercion.test.ts +0 -243
- package/src/__tests__/applyNarrationTiming.test.ts +0 -190
- package/src/__tests__/applyRenderStyle.test.ts +0 -146
- package/src/__tests__/asciiDiagramBattle.test.ts +0 -246
- package/src/__tests__/asciiDiagramDetect.test.ts +0 -162
- package/src/__tests__/asciiDiagramMapping.test.ts +0 -38
- package/src/__tests__/asciiDiagramParse.test.ts +0 -233
- package/src/__tests__/asciiDiagramPipeline.test.ts +0 -273
- package/src/__tests__/asciiDiagramRender.test.ts +0 -162
- package/src/__tests__/asciiDiagramRepair.test.ts +0 -84
- package/src/__tests__/asciiTimelineDetect.test.ts +0 -157
- package/src/__tests__/asciiTimelineParse.test.ts +0 -205
- package/src/__tests__/asciiTimelinePipeline.test.ts +0 -349
- package/src/__tests__/asciiTimelineRender.test.ts +0 -376
- package/src/__tests__/atmosphereLayers.test.ts +0 -108
- package/src/__tests__/attrTokens.test.ts +0 -167
- package/src/__tests__/colorUtils.test.ts +0 -112
- package/src/__tests__/contentContainer.test.ts +0 -325
- package/src/__tests__/contentExtractor.test.ts +0 -243
- package/src/__tests__/coverBlock.test.ts +0 -310
- package/src/__tests__/customTemplateSample.test.ts +0 -144
- package/src/__tests__/customTemplatesFrontmatter.test.ts +0 -221
- package/src/__tests__/customThemesFrontmatter.test.ts +0 -146
- package/src/__tests__/dataTable.test.ts +0 -145
- package/src/__tests__/diagramBlock.test.ts +0 -122
- package/src/__tests__/diagramLayout.test.ts +0 -134
- package/src/__tests__/diagramText.test.ts +0 -26
- package/src/__tests__/docToMarkdownMedia.test.ts +0 -83
- package/src/__tests__/drawing.test.ts +0 -109
- package/src/__tests__/drawingBlock.test.ts +0 -124
- package/src/__tests__/drawingLayout.test.ts +0 -171
- package/src/__tests__/fixtures/asciiDiagramBattle.ts +0 -512
- package/src/__tests__/fixtures/asciiDiagrams.ts +0 -287
- package/src/__tests__/fixtures/asciiTimelines.ts +0 -35
- package/src/__tests__/fixtures/treeviewFixtures.ts +0 -243
- package/src/__tests__/geohash.test.ts +0 -110
- package/src/__tests__/getLayers.test.ts +0 -243
- package/src/__tests__/getLayersFallback.test.ts +0 -103
- package/src/__tests__/haversine.test.ts +0 -63
- package/src/__tests__/iconResolve.test.ts +0 -122
- package/src/__tests__/imageEditExportSvg.test.ts +0 -70
- package/src/__tests__/imageEditState.test.ts +0 -74
- package/src/__tests__/imageEditVersions.test.ts +0 -243
- package/src/__tests__/inferDocumentTitle.test.ts +0 -50
- package/src/__tests__/inlineIconMarker.test.ts +0 -36
- package/src/__tests__/inputDescriptors.test.ts +0 -162
- package/src/__tests__/jsonForm.chooseControl.test.ts +0 -86
- package/src/__tests__/jsonForm.evaluateWhen.test.ts +0 -59
- package/src/__tests__/jsonForm.inferSchema.test.ts +0 -25
- package/src/__tests__/jsonForm.pointer.test.ts +0 -149
- package/src/__tests__/jsonForm.tokens.test.ts +0 -84
- package/src/__tests__/layoutBlock.test.ts +0 -83
- package/src/__tests__/layoutLayout.test.ts +0 -169
- package/src/__tests__/localForageAdapter.test.ts +0 -155
- package/src/__tests__/majorApiTypes.test.ts +0 -18
- package/src/__tests__/markdown.test.ts +0 -1009
- package/src/__tests__/markdownIcons.test.ts +0 -104
- package/src/__tests__/markdownSanitize.test.ts +0 -81
- package/src/__tests__/markdownToDoc.test.ts +0 -957
- package/src/__tests__/matchFontFamily.test.ts +0 -114
- package/src/__tests__/materializeBlockLayers.test.ts +0 -167
- package/src/__tests__/materializePageSections.test.ts +0 -404
- package/src/__tests__/materializeTestUtils.ts +0 -17
- package/src/__tests__/mediaAnnotations.test.ts +0 -91
- package/src/__tests__/mediaSchedule.test.ts +0 -118
- package/src/__tests__/narrationAlign.test.ts +0 -150
- package/src/__tests__/narrationFeatures.test.ts +0 -71
- package/src/__tests__/narrationNuclei.test.ts +0 -45
- package/src/__tests__/narrationPacing.test.ts +0 -189
- package/src/__tests__/narrationScript.test.ts +0 -149
- package/src/__tests__/narrationSessionRepro.test.ts +0 -62
- package/src/__tests__/narrationSidecar.test.ts +0 -88
- package/src/__tests__/narrationSyllables.test.ts +0 -65
- package/src/__tests__/narrationTestSignals.ts +0 -167
- package/src/__tests__/narrationVad.test.ts +0 -66
- package/src/__tests__/pageStyle.test.ts +0 -258
- package/src/__tests__/pandocAttrParse.test.ts +0 -187
- package/src/__tests__/recommendTemplates.test.ts +0 -183
- package/src/__tests__/resolveDocTheme.test.ts +0 -69
- package/src/__tests__/rootExports.test.ts +0 -61
- package/src/__tests__/scopedContentContainer.test.ts +0 -109
- package/src/__tests__/seededRandom.test.ts +0 -142
- package/src/__tests__/shapeGeometry.test.ts +0 -138
- package/src/__tests__/shapeVocabulary.test.ts +0 -133
- package/src/__tests__/storage.test.ts +0 -60
- package/src/__tests__/structuredData.test.ts +0 -249
- package/src/__tests__/surface.test.ts +0 -68
- package/src/__tests__/templateAnnotationParse.test.ts +0 -173
- package/src/__tests__/templateInputs.test.ts +0 -69
- package/src/__tests__/templateMetadata.test.ts +0 -32
- package/src/__tests__/templates.test.ts +0 -710
- package/src/__tests__/themeCompile.test.ts +0 -225
- package/src/__tests__/themeValidator.test.ts +0 -131
- package/src/__tests__/timing.test.ts +0 -167
- package/src/__tests__/transformProvenance.test.ts +0 -160
- package/src/__tests__/transformV2.test.ts +0 -163
- package/src/__tests__/transitionNormalize.test.ts +0 -61
- package/src/__tests__/treeviewBattle.test.ts +0 -76
- package/src/__tests__/treeviewDetect.test.ts +0 -168
- package/src/__tests__/treeviewParse.test.ts +0 -118
- package/src/__tests__/treeviewPipeline.test.ts +0 -183
- package/src/__tests__/treeviewRender.test.ts +0 -91
- package/src/__tests__/validateDoc.test.ts +0 -260
- package/src/__tests__/versions.test.ts +0 -459
- package/src/doc/annotationBlocks.ts +0 -117
- package/src/doc/applyNarrationTiming.ts +0 -244
- package/src/doc/asciiDiagram/chars.ts +0 -210
- package/src/doc/asciiDiagram/detect.ts +0 -175
- package/src/doc/asciiDiagram/index.ts +0 -38
- package/src/doc/asciiDiagram/mapping.ts +0 -225
- package/src/doc/asciiDiagram/parse.ts +0 -1095
- package/src/doc/asciiDiagram/render.ts +0 -963
- package/src/doc/asciiDiagram/repair.ts +0 -400
- package/src/doc/asciiDiagram/types.ts +0 -65
- package/src/doc/asciiTimeline/detect.ts +0 -138
- package/src/doc/asciiTimeline/index.ts +0 -26
- package/src/doc/asciiTimeline/mapping.ts +0 -43
- package/src/doc/asciiTimeline/parse.ts +0 -870
- package/src/doc/asciiTimeline/render.ts +0 -427
- package/src/doc/asciiTimeline/types.ts +0 -73
- package/src/doc/asciiTimeline/wrappedFlow.ts +0 -427
- package/src/doc/audioMapping.ts +0 -442
- package/src/doc/customTemplatesFrontmatter.ts +0 -273
- package/src/doc/customThemesFrontmatter.ts +0 -95
- package/src/doc/docToMarkdown.ts +0 -284
- package/src/doc/index.ts +0 -161
- package/src/doc/markdownToDoc.ts +0 -1054
- package/src/doc/materializeBlockLayers.ts +0 -465
- package/src/doc/mediaAnnotations.ts +0 -120
- package/src/doc/page/PageSection.ts +0 -174
- package/src/doc/page/materializePageSection.ts +0 -616
- package/src/doc/page/resolvePageBlock.ts +0 -108
- package/src/doc/page/sectionExtractors.ts +0 -466
- package/src/doc/pageCss.ts +0 -628
- package/src/doc/resolveDocTheme.ts +0 -56
- package/src/doc/standaloneAnnotation.ts +0 -58
- package/src/doc/structuredData.ts +0 -301
- package/src/doc/templateInputs.ts +0 -424
- package/src/doc/templates/__tests__/customTemplate.test.ts +0 -170
- package/src/doc/templates/__tests__/customTemplateRegistry.test.ts +0 -124
- package/src/doc/templates/__tests__/listBlock.test.ts +0 -64
- package/src/doc/templates/accentImage.ts +0 -362
- package/src/doc/templates/captionUtils.ts +0 -56
- package/src/doc/templates/comparisonBar.ts +0 -173
- package/src/doc/templates/coverBlock.ts +0 -255
- package/src/doc/templates/customTemplate.ts +0 -51
- package/src/doc/templates/dataTable.ts +0 -102
- package/src/doc/templates/dateEvent.ts +0 -147
- package/src/doc/templates/definitionCard.ts +0 -140
- package/src/doc/templates/diagramBlock.ts +0 -403
- package/src/doc/templates/diagramLayout.ts +0 -159
- package/src/doc/templates/drawingBlock.ts +0 -325
- package/src/doc/templates/drawingLayout.ts +0 -539
- package/src/doc/templates/factCard.ts +0 -146
- package/src/doc/templates/fallbackBlock.ts +0 -123
- package/src/doc/templates/featureBlock.ts +0 -209
- package/src/doc/templates/fullBleedQuote.ts +0 -83
- package/src/doc/templates/imageWithCaption.ts +0 -186
- package/src/doc/templates/index.ts +0 -642
- package/src/doc/templates/inputDescriptors.ts +0 -451
- package/src/doc/templates/layoutBlock.ts +0 -43
- package/src/doc/templates/layoutLayout.ts +0 -243
- package/src/doc/templates/listBlock.ts +0 -207
- package/src/doc/templates/mapBlock.ts +0 -138
- package/src/doc/templates/metadata.ts +0 -130
- package/src/doc/templates/persistentLayers.ts +0 -526
- package/src/doc/templates/photoGrid.ts +0 -190
- package/src/doc/templates/pullQuote.ts +0 -141
- package/src/doc/templates/quoteBlock.ts +0 -141
- package/src/doc/templates/registry.ts +0 -88
- package/src/doc/templates/sectionHeader.ts +0 -120
- package/src/doc/templates/statHighlight.ts +0 -146
- package/src/doc/templates/templateNames.ts +0 -22
- package/src/doc/templates/timelineBlock.ts +0 -613
- package/src/doc/templates/titleBlock.ts +0 -150
- package/src/doc/templates/tokens/__tests__/resolveTokens.test.ts +0 -487
- package/src/doc/templates/tokens/resolveTokens.ts +0 -453
- package/src/doc/templates/treeBlock.ts +0 -131
- package/src/doc/templates/twoColumn.ts +0 -263
- package/src/doc/templates/videoPullQuote.ts +0 -142
- package/src/doc/templates/videoWithCaption.ts +0 -135
- package/src/doc/treeview/chars.ts +0 -72
- package/src/doc/treeview/detect.ts +0 -145
- package/src/doc/treeview/index.ts +0 -30
- package/src/doc/treeview/mapping.ts +0 -95
- package/src/doc/treeview/parse.ts +0 -201
- package/src/doc/treeview/render.ts +0 -41
- package/src/doc/treeview/types.ts +0 -43
- package/src/doc/utils/animationUtils.ts +0 -399
- package/src/doc/utils/applyRenderStyle.ts +0 -106
- package/src/doc/utils/diagramText.ts +0 -78
- package/src/doc/utils/imageTreatment.ts +0 -70
- package/src/doc/utils/nearest.ts +0 -59
- package/src/doc/utils/shapeGeometry.ts +0 -614
- package/src/doc/utils/themeUtils.ts +0 -243
- package/src/doc/validate.ts +0 -575
- package/src/generate/contentExtractor.ts +0 -921
- package/src/generate/index.ts +0 -18
- package/src/generate/templateMapper.ts +0 -177
- package/src/icons/iconData.ts +0 -31
- package/src/icons/index.ts +0 -26
- package/src/icons/inlineIconMarker.ts +0 -73
- package/src/icons/resolve.ts +0 -139
- package/src/imageEdit/ImageEditVersionManager.ts +0 -73
- package/src/imageEdit/export.ts +0 -410
- package/src/imageEdit/index.ts +0 -72
- package/src/imageEdit/persistence.ts +0 -113
- package/src/imageEdit/state.ts +0 -112
- package/src/imageEdit/versionPaths.ts +0 -44
- package/src/imageEdit/versions.ts +0 -152
- package/src/index.ts +0 -15
- package/src/internal/immutable.ts +0 -58
- package/src/jsonForm/chooseControl.ts +0 -88
- package/src/jsonForm/evaluateWhen.ts +0 -59
- package/src/jsonForm/index.ts +0 -32
- package/src/jsonForm/inferSchema.ts +0 -25
- package/src/jsonForm/pointer.ts +0 -154
- package/src/jsonForm/tokens.ts +0 -78
- package/src/jsonForm/types.ts +0 -167
- package/src/markdown/annotationCoercion.ts +0 -295
- package/src/markdown/attrTokens.ts +0 -243
- package/src/markdown/convert.ts +0 -1353
- package/src/markdown/htmlParse.ts +0 -212
- package/src/markdown/index.ts +0 -152
- package/src/markdown/parse.ts +0 -103
- package/src/markdown/sanitize.ts +0 -318
- package/src/markdown/stringify.ts +0 -207
- package/src/markdown/types.ts +0 -710
- package/src/markdown/utils.ts +0 -459
- package/src/narration/align.ts +0 -514
- package/src/narration/features.ts +0 -231
- package/src/narration/index.ts +0 -86
- package/src/narration/nuclei.ts +0 -118
- package/src/narration/pacing.ts +0 -211
- package/src/narration/script.ts +0 -239
- package/src/narration/session.ts +0 -100
- package/src/narration/sidecar.ts +0 -187
- package/src/narration/syllables.ts +0 -85
- package/src/narration/trace.ts +0 -50
- package/src/narration/types.ts +0 -299
- package/src/narration/vad.ts +0 -131
- package/src/ngeohash.d.ts +0 -11
- package/src/random/SeededRandom.ts +0 -127
- package/src/random/index.ts +0 -1
- package/src/recommend/index.ts +0 -16
- package/src/recommend/numberHighlight.ts +0 -25
- package/src/recommend/templates.ts +0 -393
- package/src/schemas/BlockTemplates.ts +0 -1046
- package/src/schemas/CustomTemplates.ts +0 -126
- package/src/schemas/Doc.ts +0 -1073
- package/src/schemas/ImageEditDoc.ts +0 -102
- package/src/schemas/LayoutStrategy.ts +0 -178
- package/src/schemas/Media.ts +0 -179
- package/src/schemas/MediaProvider.ts +0 -70
- package/src/schemas/PageStyle.ts +0 -213
- package/src/schemas/Theme.ts +0 -413
- package/src/schemas/Transitions.ts +0 -224
- package/src/schemas/Types.ts +0 -15
- package/src/schemas/Viewport.ts +0 -91
- package/src/schemas/colorUtils.ts +0 -219
- package/src/schemas/fontStacks.ts +0 -339
- package/src/schemas/index.ts +0 -31
- package/src/schemas/pageStyleDefaults.ts +0 -204
- package/src/schemas/themeCompile.ts +0 -244
- package/src/schemas/themeConstants.ts +0 -2
- package/src/schemas/themeLibrary.ts +0 -60
- package/src/schemas/themeValidator.ts +0 -609
- package/src/schemas/themes/bold.json +0 -77
- package/src/schemas/themes/cinematic.json +0 -143
- package/src/schemas/themes/documentary.json +0 -125
- package/src/schemas/themes/gezellig.json +0 -123
- package/src/schemas/themes/index.ts +0 -53
- package/src/schemas/themes/magazine.json +0 -126
- package/src/schemas/themes/minimalist.json +0 -74
- package/src/schemas/themes/morning-light.json +0 -117
- package/src/schemas/themes/standard-dark.json +0 -109
- package/src/schemas/themes/standard.json +0 -98
- package/src/schemas/themes/tech-dark.json +0 -143
- package/src/schemas/themes/warm-earth.json +0 -74
- package/src/spatial/Geohash.ts +0 -196
- package/src/spatial/Haversine.ts +0 -59
- package/src/spatial/index.ts +0 -2
- package/src/storage/ContentContainer.ts +0 -220
- package/src/storage/LocalForageAdapter.ts +0 -103
- package/src/storage/LocalStorageAdapter.ts +0 -57
- package/src/storage/MediaProviderFromContainer.ts +0 -92
- package/src/storage/MemoryStorageAdapter.ts +0 -37
- package/src/storage/ScopedContentContainer.ts +0 -143
- package/src/storage/Storage.ts +0 -28
- package/src/storage/index.ts +0 -9
- package/src/timing/index.ts +0 -17
- package/src/timing/narrationTiming.ts +0 -220
- package/src/timing/readingTime.ts +0 -94
- package/src/transform/applyTransform.ts +0 -122
- package/src/transform/blockAnalyzer.ts +0 -181
- package/src/transform/index.ts +0 -23
- package/src/transform/registry.ts +0 -217
- package/src/transform/styles/dataDriven.ts +0 -18
- package/src/transform/styles/documentary.ts +0 -18
- package/src/transform/styles/index.ts +0 -5
- package/src/transform/styles/magazine.ts +0 -19
- package/src/transform/styles/minimal.ts +0 -18
- package/src/transform/styles/narrative.ts +0 -19
- package/src/transform/templateSelector.ts +0 -389
- package/src/transform/timingAllocator.ts +0 -257
- package/src/transform/types.ts +0 -158
- package/src/versions/DocumentVersionManager.ts +0 -70
- package/src/versions/gitignore.ts +0 -34
- package/src/versions/index.ts +0 -56
- package/src/versions/operations.ts +0 -144
- package/src/versions/paths.ts +0 -51
- package/src/versions/snapshotStore.ts +0 -202
- package/src/versions/timestamp.ts +0 -48
- package/src/versions/types.ts +0 -93
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Photo Grid Template
|
|
3
|
-
*
|
|
4
|
-
* Displays 2-4 images in a tiled layout for visual variety.
|
|
5
|
-
* Layout adapts based on image count and viewport orientation:
|
|
6
|
-
*
|
|
7
|
-
* Landscape:
|
|
8
|
-
* - 2 images: side-by-side 50/50
|
|
9
|
-
* - 3 images: one large left (60%) + two stacked right
|
|
10
|
-
* - 4 images: 2x2 grid
|
|
11
|
-
*
|
|
12
|
-
* Portrait (9:16): images stack horizontally (top/bottom) instead of
|
|
13
|
-
* side-by-side, giving each image full width on narrow screens.
|
|
14
|
-
*
|
|
15
|
-
* This is shared code used by both site and efb-app doc renderers.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import type { Layer } from '../../schemas/Doc.js';
|
|
19
|
-
import type { PhotoGridInput, TemplateContext } from '../../schemas/BlockTemplates.js';
|
|
20
|
-
import { getThemeFont, themedFontSize, themedImageTreatment } from '../utils/themeUtils.js';
|
|
21
|
-
import { withAlpha } from '../../schemas/colorUtils.js';
|
|
22
|
-
import { cleanCaption } from './captionUtils.js';
|
|
23
|
-
|
|
24
|
-
/** Gap between images as percentage */
|
|
25
|
-
const GAP = 1.2;
|
|
26
|
-
|
|
27
|
-
export function photoGrid(input: PhotoGridInput, context: TemplateContext): Layer[] {
|
|
28
|
-
const { images, caption: rawCaption, ambientMotion } = input;
|
|
29
|
-
|
|
30
|
-
// Guard: images array is required
|
|
31
|
-
if (!images || images.length === 0) return [];
|
|
32
|
-
|
|
33
|
-
const caption = rawCaption ? cleanCaption(rawCaption) : rawCaption;
|
|
34
|
-
const { theme, layout } = context;
|
|
35
|
-
|
|
36
|
-
const treatment = themedImageTreatment(context, input.imageTreatment);
|
|
37
|
-
|
|
38
|
-
const layers: Layer[] = [
|
|
39
|
-
// Theme surface background (visible in gaps between images)
|
|
40
|
-
{
|
|
41
|
-
type: 'shape',
|
|
42
|
-
id: 'bg',
|
|
43
|
-
content: { shape: 'rect', fill: theme.colors.background },
|
|
44
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
45
|
-
},
|
|
46
|
-
];
|
|
47
|
-
|
|
48
|
-
const gridHeight = 100;
|
|
49
|
-
|
|
50
|
-
// Generate image positions based on count; stack vertically in portrait
|
|
51
|
-
const positions = getGridPositions(images.length, gridHeight, layout.stackColumns);
|
|
52
|
-
|
|
53
|
-
for (let i = 0; i < Math.min(images.length, 4); i++) {
|
|
54
|
-
const img = images[i];
|
|
55
|
-
const pos = positions[i];
|
|
56
|
-
|
|
57
|
-
// Placeholder behind image (visible if image fails to load)
|
|
58
|
-
layers.push({
|
|
59
|
-
type: 'shape',
|
|
60
|
-
id: `grid-placeholder-${i}`,
|
|
61
|
-
content: { shape: 'rect', fill: theme.colors.background },
|
|
62
|
-
position: { x: `${pos.x}%`, y: `${pos.y}%`, width: `${pos.w}%`, height: `${pos.h}%` },
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// Image layer (covers placeholder when loaded)
|
|
66
|
-
layers.push({
|
|
67
|
-
type: 'image',
|
|
68
|
-
id: `grid-img-${i}`,
|
|
69
|
-
content: {
|
|
70
|
-
src: img.src,
|
|
71
|
-
alt: img.alt,
|
|
72
|
-
fit: 'cover',
|
|
73
|
-
credit: img.credit,
|
|
74
|
-
license: img.license,
|
|
75
|
-
...(treatment ? { treatment } : {}),
|
|
76
|
-
},
|
|
77
|
-
position: {
|
|
78
|
-
x: `${pos.x}%`,
|
|
79
|
-
y: `${pos.y}%`,
|
|
80
|
-
width: `${pos.w}%`,
|
|
81
|
-
height: `${pos.h}%`,
|
|
82
|
-
},
|
|
83
|
-
// Apply ambient motion to the first (largest) image only
|
|
84
|
-
animation:
|
|
85
|
-
i === 0 && ambientMotion
|
|
86
|
-
? { type: ambientMotion, duration: 15 }
|
|
87
|
-
: { type: 'fadeIn', duration: 1, delay: 0.2 * i },
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Caption in a compact translucent chip above player controls. Long
|
|
92
|
-
// archival/Wikimedia descriptions are intentionally clamped.
|
|
93
|
-
if (caption) {
|
|
94
|
-
const captionFontSize = themedFontSize(layout.stackColumns ? 24 : 26, context, false);
|
|
95
|
-
const captionY = layout.stackColumns ? '78%' : '74%';
|
|
96
|
-
const captionBgY = layout.stackColumns ? '72%' : '68%';
|
|
97
|
-
const captionHeight = layout.stackColumns ? '13%' : '16%';
|
|
98
|
-
const bg = theme.colors.background;
|
|
99
|
-
|
|
100
|
-
layers.push({
|
|
101
|
-
type: 'shape',
|
|
102
|
-
id: 'caption-bg',
|
|
103
|
-
content: {
|
|
104
|
-
shape: 'rect',
|
|
105
|
-
fill: `linear-gradient(90deg, ${withAlpha(bg, 0)}, ${withAlpha(bg, 0.78)} 16%, ${withAlpha(bg, 0.78)} 84%, ${withAlpha(bg, 0)})`,
|
|
106
|
-
},
|
|
107
|
-
position: { x: 0, y: captionBgY, width: '100%', height: captionHeight },
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
layers.push({
|
|
111
|
-
type: 'text',
|
|
112
|
-
id: 'caption',
|
|
113
|
-
content: {
|
|
114
|
-
text: caption,
|
|
115
|
-
style: {
|
|
116
|
-
fontSize: captionFontSize,
|
|
117
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
118
|
-
color: theme.colors.text,
|
|
119
|
-
textAlign: 'center',
|
|
120
|
-
shadow: true,
|
|
121
|
-
lineHeight: 1.18,
|
|
122
|
-
maxLines: layout.stackColumns ? 2 : 1,
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
position: {
|
|
126
|
-
x: '50%',
|
|
127
|
-
y: captionY,
|
|
128
|
-
anchor: 'center',
|
|
129
|
-
width: '78%',
|
|
130
|
-
},
|
|
131
|
-
animation: { type: 'fadeIn', duration: 1, delay: 0.5 },
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return layers;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
interface GridPos {
|
|
139
|
-
x: number;
|
|
140
|
-
y: number;
|
|
141
|
-
w: number;
|
|
142
|
-
h: number;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function getGridPositions(count: number, gridHeight: number, stacked: boolean): GridPos[] {
|
|
146
|
-
const halfW = 50 - GAP / 2;
|
|
147
|
-
const halfH = gridHeight / 2 - GAP / 2;
|
|
148
|
-
|
|
149
|
-
switch (count) {
|
|
150
|
-
case 2:
|
|
151
|
-
if (stacked) {
|
|
152
|
-
// Portrait: stack top/bottom
|
|
153
|
-
return [
|
|
154
|
-
{ x: 0, y: 0, w: 100, h: halfH },
|
|
155
|
-
{ x: 0, y: gridHeight / 2 + GAP / 2, w: 100, h: halfH },
|
|
156
|
-
];
|
|
157
|
-
}
|
|
158
|
-
return [
|
|
159
|
-
{ x: 0, y: 0, w: halfW, h: gridHeight },
|
|
160
|
-
{ x: 50 + GAP / 2, y: 0, w: halfW, h: gridHeight },
|
|
161
|
-
];
|
|
162
|
-
case 3: {
|
|
163
|
-
if (stacked) {
|
|
164
|
-
// Portrait: stack all three vertically
|
|
165
|
-
const thirdH = gridHeight / 3 - (GAP * 2) / 3;
|
|
166
|
-
return [
|
|
167
|
-
{ x: 0, y: 0, w: 100, h: thirdH },
|
|
168
|
-
{ x: 0, y: gridHeight / 3 + GAP / 3, w: 100, h: thirdH },
|
|
169
|
-
{ x: 0, y: (gridHeight * 2) / 3 + (GAP * 2) / 3, w: 100, h: thirdH },
|
|
170
|
-
];
|
|
171
|
-
}
|
|
172
|
-
const leftW = 60 - GAP / 2;
|
|
173
|
-
const rightW = 40 - GAP / 2;
|
|
174
|
-
return [
|
|
175
|
-
{ x: 0, y: 0, w: leftW, h: gridHeight },
|
|
176
|
-
{ x: 60 + GAP / 2, y: 0, w: rightW, h: halfH },
|
|
177
|
-
{ x: 60 + GAP / 2, y: gridHeight / 2 + GAP / 2, w: rightW, h: halfH },
|
|
178
|
-
];
|
|
179
|
-
}
|
|
180
|
-
case 4:
|
|
181
|
-
default:
|
|
182
|
-
// 2x2 grid works well in both orientations
|
|
183
|
-
return [
|
|
184
|
-
{ x: 0, y: 0, w: halfW, h: halfH },
|
|
185
|
-
{ x: 50 + GAP / 2, y: 0, w: halfW, h: halfH },
|
|
186
|
-
{ x: 0, y: gridHeight / 2 + GAP / 2, w: halfW, h: halfH },
|
|
187
|
-
{ x: 50 + GAP / 2, y: gridHeight / 2 + GAP / 2, w: halfW, h: halfH },
|
|
188
|
-
];
|
|
189
|
-
}
|
|
190
|
-
}
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pull Quote Template
|
|
3
|
-
*
|
|
4
|
-
* Quote text over a full-bleed background image with dark overlay.
|
|
5
|
-
* Cinematic alternative to quoteBlock when a high-quality image is available.
|
|
6
|
-
* Combines the visual impact of imageWithCaption with the text focus of quoteBlock.
|
|
7
|
-
*
|
|
8
|
-
* This is shared code used by both site and efb-app doc renderers.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import type { Layer } from '../../schemas/Doc.js';
|
|
12
|
-
import type { PullQuoteInput, TemplateContext } from '../../schemas/BlockTemplates.js';
|
|
13
|
-
import {
|
|
14
|
-
getThemeFont,
|
|
15
|
-
themedEntrance,
|
|
16
|
-
themedFontSize,
|
|
17
|
-
themedImageTreatment,
|
|
18
|
-
} from '../utils/themeUtils.js';
|
|
19
|
-
import { estimateTextHeight } from './captionUtils.js';
|
|
20
|
-
|
|
21
|
-
export function pullQuote(input: PullQuoteInput, context: TemplateContext): Layer[] {
|
|
22
|
-
const { text, attribution, backgroundImage, ambientMotion } = input;
|
|
23
|
-
const { viewport } = context;
|
|
24
|
-
|
|
25
|
-
const treatment = themedImageTreatment(context, input.imageTreatment);
|
|
26
|
-
|
|
27
|
-
// Guard: backgroundImage is required
|
|
28
|
-
if (!backgroundImage?.src) return [];
|
|
29
|
-
|
|
30
|
-
const quoteFontSize = themedFontSize(52, context, true);
|
|
31
|
-
const attrFontSize = themedFontSize(26, context, false);
|
|
32
|
-
const decoFontSize = themedFontSize(200, context, true);
|
|
33
|
-
const quoteLineHeight = 1.4;
|
|
34
|
-
const quoteYPct = attribution ? 45 : 50;
|
|
35
|
-
|
|
36
|
-
const layers: Layer[] = [
|
|
37
|
-
// Full-bleed background image
|
|
38
|
-
{
|
|
39
|
-
type: 'image',
|
|
40
|
-
id: 'bg-image',
|
|
41
|
-
content: {
|
|
42
|
-
src: backgroundImage.src,
|
|
43
|
-
alt: backgroundImage.alt,
|
|
44
|
-
fit: 'cover',
|
|
45
|
-
credit: backgroundImage.credit,
|
|
46
|
-
license: backgroundImage.license,
|
|
47
|
-
...(treatment ? { treatment } : {}),
|
|
48
|
-
},
|
|
49
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
50
|
-
animation: ambientMotion ? { type: ambientMotion, duration: 15 } : undefined,
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
// Dark overlay for text readability
|
|
54
|
-
{
|
|
55
|
-
type: 'shape',
|
|
56
|
-
id: 'overlay',
|
|
57
|
-
content: {
|
|
58
|
-
shape: 'rect',
|
|
59
|
-
fill: 'rgba(0, 0, 0, 0.55)',
|
|
60
|
-
},
|
|
61
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
// Decorative quotation mark
|
|
65
|
-
{
|
|
66
|
-
type: 'text',
|
|
67
|
-
id: 'deco-quote',
|
|
68
|
-
content: {
|
|
69
|
-
text: '\u201C',
|
|
70
|
-
style: {
|
|
71
|
-
fontSize: decoFontSize,
|
|
72
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
73
|
-
color: 'rgba(255, 255, 255, 0.08)',
|
|
74
|
-
textAlign: 'center',
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
position: {
|
|
78
|
-
x: '50%',
|
|
79
|
-
y: '20%',
|
|
80
|
-
anchor: 'center',
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
|
|
84
|
-
// Quote text
|
|
85
|
-
{
|
|
86
|
-
type: 'text',
|
|
87
|
-
id: 'quote-text',
|
|
88
|
-
content: {
|
|
89
|
-
text,
|
|
90
|
-
style: {
|
|
91
|
-
fontSize: quoteFontSize,
|
|
92
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
93
|
-
color: '#ffffff',
|
|
94
|
-
textAlign: 'center',
|
|
95
|
-
lineHeight: quoteLineHeight,
|
|
96
|
-
shadow: true,
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
position: {
|
|
100
|
-
x: '50%',
|
|
101
|
-
y: `${quoteYPct}%`,
|
|
102
|
-
anchor: 'center',
|
|
103
|
-
width: '72%',
|
|
104
|
-
},
|
|
105
|
-
animation: themedEntrance(context, 'text', { type: 'fadeIn', duration: 2 }),
|
|
106
|
-
},
|
|
107
|
-
];
|
|
108
|
-
|
|
109
|
-
// Attribution \u2014 hangs just below the quote's estimated bottom edge so
|
|
110
|
-
// the two read as one lockup instead of stranding near the bottom.
|
|
111
|
-
if (attribution) {
|
|
112
|
-
const quoteWidthPx = 0.72 * viewport.width;
|
|
113
|
-
const quoteHeightPx = estimateTextHeight(text, quoteFontSize, quoteWidthPx, quoteLineHeight);
|
|
114
|
-
const attrYPct = Math.min(
|
|
115
|
-
82,
|
|
116
|
-
quoteYPct + ((quoteHeightPx / 2 + quoteFontSize * 1.7) / viewport.height) * 100,
|
|
117
|
-
);
|
|
118
|
-
layers.push({
|
|
119
|
-
type: 'text',
|
|
120
|
-
id: 'attribution',
|
|
121
|
-
content: {
|
|
122
|
-
text: `\u2014 ${attribution}`,
|
|
123
|
-
style: {
|
|
124
|
-
fontSize: attrFontSize,
|
|
125
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
126
|
-
color: 'rgba(255, 255, 255, 0.85)',
|
|
127
|
-
textAlign: 'center',
|
|
128
|
-
shadow: true,
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
position: {
|
|
132
|
-
x: '50%',
|
|
133
|
-
y: `${attrYPct}%`,
|
|
134
|
-
anchor: 'center',
|
|
135
|
-
},
|
|
136
|
-
animation: { type: 'fadeIn', duration: 1, delay: 1.5 },
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return layers;
|
|
141
|
-
}
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Quote Block Template
|
|
3
|
-
*
|
|
4
|
-
* Large centered quote with optional attribution, composed as one
|
|
5
|
-
* vertically-centered lockup: the attribution hangs a fixed distance
|
|
6
|
-
* below the quote's estimated bottom edge instead of being pinned to a
|
|
7
|
-
* far-away layout slot.
|
|
8
|
-
* Adapts font sizes and positioning for different viewports.
|
|
9
|
-
*
|
|
10
|
-
* Supports optional accent images that appear as tasteful side/bottom strips.
|
|
11
|
-
*
|
|
12
|
-
* This is shared code used by both site and efb-app doc renderers.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import type { Layer } from '../../schemas/Doc.js';
|
|
16
|
-
import type { QuoteBlockInput, TemplateContext } from '../../schemas/BlockTemplates.js';
|
|
17
|
-
import {
|
|
18
|
-
getThemeFont,
|
|
19
|
-
shouldUseShadow,
|
|
20
|
-
themedEntrance,
|
|
21
|
-
themedFontSize,
|
|
22
|
-
themedSurfaceGradient,
|
|
23
|
-
themedImageTreatment,
|
|
24
|
-
} from '../utils/themeUtils.js';
|
|
25
|
-
import { withAlpha } from '../../schemas/colorUtils.js';
|
|
26
|
-
import { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';
|
|
27
|
-
import { createBackgroundLayer, estimateTextHeight } from './captionUtils.js';
|
|
28
|
-
|
|
29
|
-
export function quoteBlock(input: QuoteBlockInput, context: TemplateContext): Layer[] {
|
|
30
|
-
const { quote, attribution, accentImage } = input;
|
|
31
|
-
const { theme, viewport } = context;
|
|
32
|
-
|
|
33
|
-
// Get layout adjustments if accent image is present
|
|
34
|
-
const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;
|
|
35
|
-
|
|
36
|
-
// Scale font sizes for viewport
|
|
37
|
-
const quoteFontSize = themedFontSize(48, context, true);
|
|
38
|
-
const attrFontSize = themedFontSize(26, context, false);
|
|
39
|
-
const quoteLineHeight = Math.max(theme.typography.titleLineHeight ?? 1.4, 1.25);
|
|
40
|
-
|
|
41
|
-
// Decorative quotation mark font size
|
|
42
|
-
const decorativeQuoteFontSize = themedFontSize(280, context, true);
|
|
43
|
-
|
|
44
|
-
const layers: Layer[] = [createBackgroundLayer('bg', themedSurfaceGradient(context, 160))];
|
|
45
|
-
|
|
46
|
-
// Add accent image layers (behind text, after background)
|
|
47
|
-
if (accentImage) {
|
|
48
|
-
layers.push(
|
|
49
|
-
...createAccentLayers(
|
|
50
|
-
accentImage,
|
|
51
|
-
input.id,
|
|
52
|
-
themedImageTreatment(context, input.imageTreatment),
|
|
53
|
-
),
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Decorative opening quotation mark — oversized, low-opacity behind the
|
|
58
|
-
// quote. Derived from the theme text color so it stays a subtle ornament
|
|
59
|
-
// on light and dark surfaces alike (a hard-coded white glyph was
|
|
60
|
-
// invisible on both).
|
|
61
|
-
layers.push({
|
|
62
|
-
type: 'text',
|
|
63
|
-
id: 'deco-quote',
|
|
64
|
-
content: {
|
|
65
|
-
text: '“',
|
|
66
|
-
style: {
|
|
67
|
-
fontSize: decorativeQuoteFontSize,
|
|
68
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
69
|
-
color: withAlpha(theme.colors.text, 0.09),
|
|
70
|
-
textAlign: 'center',
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
position: {
|
|
74
|
-
x: accentLayout.textCenterX,
|
|
75
|
-
y: adjustY('26%', accentLayout),
|
|
76
|
-
anchor: 'center',
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Quote text — optically centered, nudged up slightly when an
|
|
81
|
-
// attribution hangs below it.
|
|
82
|
-
const quoteYPct = attribution ? 45 : 50;
|
|
83
|
-
layers.push({
|
|
84
|
-
type: 'text',
|
|
85
|
-
id: 'quote',
|
|
86
|
-
content: {
|
|
87
|
-
text: quote,
|
|
88
|
-
style: {
|
|
89
|
-
fontSize: quoteFontSize,
|
|
90
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
91
|
-
color: theme.colors.text,
|
|
92
|
-
textAlign: 'center',
|
|
93
|
-
lineHeight: quoteLineHeight,
|
|
94
|
-
shadow: shouldUseShadow(context),
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
position: {
|
|
98
|
-
x: accentLayout.textCenterX,
|
|
99
|
-
y: adjustY(`${quoteYPct}%`, accentLayout),
|
|
100
|
-
anchor: 'center',
|
|
101
|
-
width: accentLayout.textWidth,
|
|
102
|
-
},
|
|
103
|
-
animation: themedEntrance(context, 'text', { type: 'fadeIn', duration: 2 }),
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
// Attribution hangs just below the quote's estimated bottom edge, so
|
|
107
|
-
// the two read as one lockup instead of the attribution stranding near
|
|
108
|
-
// the bottom of the block.
|
|
109
|
-
if (attribution) {
|
|
110
|
-
const quoteWidthPx = (parseFloat(accentLayout.textWidth) / 100) * viewport.width;
|
|
111
|
-
const quoteHeightPx = estimateTextHeight(quote, quoteFontSize, quoteWidthPx, quoteLineHeight);
|
|
112
|
-
const gapPx = quoteFontSize * 1.7;
|
|
113
|
-
const attrYPct = Math.min(
|
|
114
|
-
82,
|
|
115
|
-
quoteYPct + ((quoteHeightPx / 2 + gapPx) / viewport.height) * 100,
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
layers.push({
|
|
119
|
-
type: 'text',
|
|
120
|
-
id: 'attribution',
|
|
121
|
-
content: {
|
|
122
|
-
text: `— ${attribution}`,
|
|
123
|
-
style: {
|
|
124
|
-
fontSize: attrFontSize,
|
|
125
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
126
|
-
color: theme.colors.textMuted,
|
|
127
|
-
textAlign: 'center',
|
|
128
|
-
shadow: shouldUseShadow(context),
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
position: {
|
|
132
|
-
x: accentLayout.textCenterX,
|
|
133
|
-
y: adjustY(`${attrYPct}%`, accentLayout),
|
|
134
|
-
anchor: 'center',
|
|
135
|
-
},
|
|
136
|
-
animation: { type: 'fadeIn', duration: 1, delay: 1.5 },
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return layers;
|
|
141
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/** Runtime registry composition for built-in and document-scoped templates. */
|
|
2
|
-
|
|
3
|
-
import type { Layer } from '../../schemas/Doc.js';
|
|
4
|
-
import type {
|
|
5
|
-
TemplateBlock,
|
|
6
|
-
TemplateContext,
|
|
7
|
-
TemplateRegistry,
|
|
8
|
-
} from '../../schemas/BlockTemplates.js';
|
|
9
|
-
import type { CustomTemplateDefinition } from '../../schemas/CustomTemplates.js';
|
|
10
|
-
import { makeCustomTemplateFn } from './customTemplate.js';
|
|
11
|
-
|
|
12
|
-
import { titleBlock } from './titleBlock.js';
|
|
13
|
-
import { sectionHeader } from './sectionHeader.js';
|
|
14
|
-
import { statHighlight } from './statHighlight.js';
|
|
15
|
-
import { quoteBlock } from './quoteBlock.js';
|
|
16
|
-
import { factCard } from './factCard.js';
|
|
17
|
-
import { twoColumn } from './twoColumn.js';
|
|
18
|
-
import { dateEvent } from './dateEvent.js';
|
|
19
|
-
import { imageWithCaption } from './imageWithCaption.js';
|
|
20
|
-
import { leftFeature, rightFeature } from './featureBlock.js';
|
|
21
|
-
import { mapBlock } from './mapBlock.js';
|
|
22
|
-
import { fullBleedQuote } from './fullBleedQuote.js';
|
|
23
|
-
import { listBlock } from './listBlock.js';
|
|
24
|
-
import { photoGrid } from './photoGrid.js';
|
|
25
|
-
import { definitionCard } from './definitionCard.js';
|
|
26
|
-
import { comparisonBar } from './comparisonBar.js';
|
|
27
|
-
import { pullQuote } from './pullQuote.js';
|
|
28
|
-
import { videoWithCaption } from './videoWithCaption.js';
|
|
29
|
-
import { videoPullQuote } from './videoPullQuote.js';
|
|
30
|
-
import { dataTable } from './dataTable.js';
|
|
31
|
-
import { diagramBlock } from './diagramBlock.js';
|
|
32
|
-
import { treeBlock } from './treeBlock.js';
|
|
33
|
-
import { timelineBlock } from './timelineBlock.js';
|
|
34
|
-
import { drawingBlock } from './drawingBlock.js';
|
|
35
|
-
import { layoutBlock } from './layoutBlock.js';
|
|
36
|
-
|
|
37
|
-
/** Built-in templates keyed by the ids used in document annotations. */
|
|
38
|
-
export const templateRegistry: TemplateRegistry = {
|
|
39
|
-
title: titleBlock,
|
|
40
|
-
sectionHeader,
|
|
41
|
-
statHighlight,
|
|
42
|
-
quote: quoteBlock,
|
|
43
|
-
factCard,
|
|
44
|
-
twoColumn,
|
|
45
|
-
dateEvent,
|
|
46
|
-
imageWithCaption,
|
|
47
|
-
leftFeature,
|
|
48
|
-
rightFeature,
|
|
49
|
-
map: mapBlock,
|
|
50
|
-
fullBleedQuote,
|
|
51
|
-
list: listBlock,
|
|
52
|
-
photoGrid,
|
|
53
|
-
definitionCard,
|
|
54
|
-
comparisonBar,
|
|
55
|
-
pullQuote,
|
|
56
|
-
videoWithCaption,
|
|
57
|
-
videoPullQuote,
|
|
58
|
-
dataTable,
|
|
59
|
-
diagram: diagramBlock,
|
|
60
|
-
tree: treeBlock,
|
|
61
|
-
timeline: timelineBlock,
|
|
62
|
-
layout: layoutBlock,
|
|
63
|
-
drawing: drawingBlock,
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
/** Broad runtime view used after a template name has selected its function. */
|
|
67
|
-
export type RuntimeTemplateRegistry = Record<
|
|
68
|
-
string,
|
|
69
|
-
(input: TemplateBlock, context: TemplateContext) => Layer[]
|
|
70
|
-
>;
|
|
71
|
-
|
|
72
|
-
/** Merge document-scoped templates without mutating the built-in registry. */
|
|
73
|
-
export function buildRegistry(
|
|
74
|
-
custom?: readonly CustomTemplateDefinition[],
|
|
75
|
-
): RuntimeTemplateRegistry {
|
|
76
|
-
const merged: RuntimeTemplateRegistry = {
|
|
77
|
-
...(templateRegistry as unknown as RuntimeTemplateRegistry),
|
|
78
|
-
};
|
|
79
|
-
if (custom) {
|
|
80
|
-
for (const definition of custom) {
|
|
81
|
-
if (merged[definition.name]) continue;
|
|
82
|
-
merged[definition.name] = makeCustomTemplateFn(
|
|
83
|
-
definition,
|
|
84
|
-
) as unknown as RuntimeTemplateRegistry[string];
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return merged;
|
|
88
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Section Header Template
|
|
3
|
-
*
|
|
4
|
-
* Section title card with optional background image.
|
|
5
|
-
* Used to introduce new sections of a story.
|
|
6
|
-
* When an image is provided, displays like a title slide with the image as background.
|
|
7
|
-
* Without an image, falls back to a colored background.
|
|
8
|
-
*
|
|
9
|
-
* This is shared code used by both site and efb-app doc renderers.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import type { Layer, AnimationType } from '../../schemas/Doc.js';
|
|
13
|
-
import type { SectionHeaderInput, TemplateContext } from '../../schemas/BlockTemplates.js';
|
|
14
|
-
import {
|
|
15
|
-
resolveColorScheme,
|
|
16
|
-
getThemeFont,
|
|
17
|
-
shouldUseShadow,
|
|
18
|
-
themedEntrance,
|
|
19
|
-
themedFontSize,
|
|
20
|
-
themedScrim,
|
|
21
|
-
themedImageTreatment,
|
|
22
|
-
} from '../utils/themeUtils.js';
|
|
23
|
-
|
|
24
|
-
export function sectionHeader(input: SectionHeaderInput, context: TemplateContext): Layer[] {
|
|
25
|
-
const { title = '', colorScheme = 'blue', imageSrc, imageAlt, ambientMotion } = input;
|
|
26
|
-
const { theme, layout } = context;
|
|
27
|
-
|
|
28
|
-
const treatment = themedImageTreatment(context, input.imageTreatment);
|
|
29
|
-
const colors = resolveColorScheme(context, colorScheme);
|
|
30
|
-
|
|
31
|
-
// Scale font sizes for viewport. Section dividers are the loudest
|
|
32
|
-
// interstitial in a doc, so the title sits a step above ordinary
|
|
33
|
-
// content-block headings.
|
|
34
|
-
const titleFontSize = themedFontSize(84, context, true);
|
|
35
|
-
|
|
36
|
-
const layers: Layer[] = [];
|
|
37
|
-
|
|
38
|
-
// Background - either image or solid color
|
|
39
|
-
if (imageSrc) {
|
|
40
|
-
// Image background with Ken Burns effect
|
|
41
|
-
layers.push({
|
|
42
|
-
type: 'image',
|
|
43
|
-
id: 'bg-image',
|
|
44
|
-
content: {
|
|
45
|
-
src: imageSrc,
|
|
46
|
-
alt: imageAlt || title,
|
|
47
|
-
fit: 'cover',
|
|
48
|
-
...(treatment ? { treatment } : {}),
|
|
49
|
-
},
|
|
50
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
51
|
-
animation: ambientMotion
|
|
52
|
-
? { type: ambientMotion as AnimationType, duration: 8 }
|
|
53
|
-
: { type: 'slowZoom', duration: 8, direction: 'in' },
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// Theme-tinted overlay for text readability — light themes get a
|
|
57
|
-
// light scrim with dark theme text, dark themes the familiar dark one.
|
|
58
|
-
layers.push({
|
|
59
|
-
type: 'shape',
|
|
60
|
-
id: 'overlay',
|
|
61
|
-
content: {
|
|
62
|
-
shape: 'rect',
|
|
63
|
-
fill: themedScrim(context),
|
|
64
|
-
},
|
|
65
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
66
|
-
});
|
|
67
|
-
} else {
|
|
68
|
-
// Solid color background
|
|
69
|
-
layers.push({
|
|
70
|
-
type: 'shape',
|
|
71
|
-
id: 'bg',
|
|
72
|
-
content: {
|
|
73
|
-
shape: 'rect',
|
|
74
|
-
fill: colors.bg,
|
|
75
|
-
},
|
|
76
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// Decorative lines above and below title
|
|
80
|
-
layers.push({
|
|
81
|
-
type: 'shape',
|
|
82
|
-
id: 'line-top',
|
|
83
|
-
content: { shape: 'rect', fill: `${colors.text}33` },
|
|
84
|
-
position: { x: '50%', y: '40%', width: '20%', height: '2px', anchor: 'center' },
|
|
85
|
-
});
|
|
86
|
-
layers.push({
|
|
87
|
-
type: 'shape',
|
|
88
|
-
id: 'line-bottom',
|
|
89
|
-
content: { shape: 'rect', fill: `${colors.text}33` },
|
|
90
|
-
position: { x: '50%', y: '60%', width: '20%', height: '2px', anchor: 'center' },
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Section title — theme text over the theme-tinted scrim (readable by
|
|
95
|
-
// construction), scheme text on the solid-color fallback
|
|
96
|
-
layers.push({
|
|
97
|
-
type: 'text',
|
|
98
|
-
id: 'title',
|
|
99
|
-
content: {
|
|
100
|
-
text: title,
|
|
101
|
-
style: {
|
|
102
|
-
fontSize: titleFontSize,
|
|
103
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
104
|
-
fontWeight: 'bold',
|
|
105
|
-
color: imageSrc ? theme.colors.text : colors.text,
|
|
106
|
-
textAlign: 'center',
|
|
107
|
-
shadow: shouldUseShadow(context),
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
position: {
|
|
111
|
-
x: '50%',
|
|
112
|
-
y: '50%',
|
|
113
|
-
anchor: 'center',
|
|
114
|
-
width: layout.maxTextWidth,
|
|
115
|
-
},
|
|
116
|
-
animation: themedEntrance(context, 'text', { type: 'fadeIn', duration: 1.5 }),
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
return layers;
|
|
120
|
-
}
|