@bendyline/squisq 2.0.1 → 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-ylqWKDc_.d.ts → Doc-BubIpWsp.d.ts} +160 -3
- package/dist/{ImageEditDoc-D828IXJ1.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-2ZWIXGAC.js +214 -0
- package/dist/{chunk-2PWOO4ZE.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-X6DUONGT.js → chunk-7ARJZYQY.js} +280 -128
- 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-W4O2TX5I.js → chunk-C33GTPUZ.js} +579 -4
- package/dist/{chunk-MMPBOUK7.js → chunk-CB45YGAM.js} +7 -2
- package/dist/{chunk-CY2R2VPR.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-TFJVXUHH.js → chunk-I2O6W7DX.js} +1513 -79
- 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-PXLVXTLW.js → chunk-RS5AP3J4.js} +72 -15
- 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 +166 -12
- package/dist/doc/index.js +36 -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 +13 -12
- package/dist/index.js +118 -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-wSLA2A1g.d.ts +223 -0
- 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 +31 -6
- package/dist/schemas/index.js +43 -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-RjVgLpUi.d.ts → themeLibrary-DU9mUmVl.d.ts} +1 -1
- package/dist/timing/index.js +3 -4
- package/dist/transform/index.d.ts +9 -10
- 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-2PWOO4ZE.js.map +0 -1
- 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-CY2R2VPR.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-FVJUUTEM.js +0 -74
- package/dist/chunk-FVJUUTEM.js.map +0 -1
- package/dist/chunk-FVTQSNR7.js.map +0 -1
- package/dist/chunk-GZY66SDN.js.map +0 -1
- package/dist/chunk-JOQYPRDZ.js.map +0 -1
- package/dist/chunk-MMPBOUK7.js.map +0 -1
- package/dist/chunk-PGGGKYWG.js +0 -1
- package/dist/chunk-PGGGKYWG.js.map +0 -1
- package/dist/chunk-PXLVXTLW.js.map +0 -1
- package/dist/chunk-Q7LROV2H.js.map +0 -1
- package/dist/chunk-QE7TWGVT.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-TFJVXUHH.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-W4O2TX5I.js.map +0 -1
- package/dist/chunk-X6DUONGT.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 -135
- 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__/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 -160
- 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 -127
- package/src/doc/markdownToDoc.ts +0 -1054
- package/src/doc/materializeBlockLayers.ts +0 -304
- package/src/doc/mediaAnnotations.ts +0 -120
- 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 -423
- 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 -1052
- 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/Theme.ts +0 -406
- 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 -29
- package/src/schemas/themeCompile.ts +0 -237
- package/src/schemas/themeConstants.ts +0 -2
- package/src/schemas/themeLibrary.ts +0 -60
- package/src/schemas/themeValidator.ts +0 -426
- package/src/schemas/themes/bold.json +0 -48
- package/src/schemas/themes/cinematic.json +0 -111
- package/src/schemas/themes/documentary.json +0 -96
- package/src/schemas/themes/gezellig.json +0 -93
- package/src/schemas/themes/index.ts +0 -53
- package/src/schemas/themes/magazine.json +0 -89
- package/src/schemas/themes/minimalist.json +0 -45
- package/src/schemas/themes/morning-light.json +0 -85
- package/src/schemas/themes/standard-dark.json +0 -85
- package/src/schemas/themes/standard.json +0 -74
- package/src/schemas/themes/tech-dark.json +0 -101
- package/src/schemas/themes/warm-earth.json +0 -50
- 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 -198
- package/src/transform/styles/dataDriven.ts +0 -17
- package/src/transform/styles/documentary.ts +0 -17
- package/src/transform/styles/index.ts +0 -5
- package/src/transform/styles/magazine.ts +0 -18
- package/src/transform/styles/minimal.ts +0 -17
- package/src/transform/styles/narrative.ts +0 -18
- package/src/transform/templateSelector.ts +0 -389
- package/src/transform/timingAllocator.ts +0 -257
- package/src/transform/types.ts +0 -151
- 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,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fallback Block Rendering
|
|
3
|
-
*
|
|
4
|
-
* The graceful-degradation guarantee: a block whose template can't render —
|
|
5
|
-
* unknown template name, template function threw, or returned a non-array —
|
|
6
|
-
* still renders its heading and body text as a plain, readable card instead
|
|
7
|
-
* of a blank slide. A small notice line names the problem so authors (and
|
|
8
|
-
* agents reviewing screenshots) can see *why* the block degraded.
|
|
9
|
-
*
|
|
10
|
-
* This is intentionally not a registered template: it can't be requested by
|
|
11
|
-
* name, only reached when a requested template fails. See `materializeBlockLayers()`.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import type { Layer } from '../../schemas/Doc.js';
|
|
15
|
-
import type { Block } from '../../schemas/Doc.js';
|
|
16
|
-
import type { DocBlock, TemplateContext } from '../../schemas/BlockTemplates.js';
|
|
17
|
-
import { resolveColorScheme, getThemeFont, themedFontSize } from '../utils/themeUtils.js';
|
|
18
|
-
import { extractPlainText } from '../../markdown/utils.js';
|
|
19
|
-
|
|
20
|
-
/** Cap body text so a long section doesn't overflow the card. */
|
|
21
|
-
const MAX_BODY_CHARS = 600;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Render a block's heading + body text as plain layers, with a notice line
|
|
25
|
-
* describing why the requested template didn't render.
|
|
26
|
-
*
|
|
27
|
-
* @param block The block that failed to render via its template.
|
|
28
|
-
* @param context Template context (theme, viewport).
|
|
29
|
-
* @param notice Short problem description, e.g. `Unknown template "photGrid"`.
|
|
30
|
-
*/
|
|
31
|
-
export function fallbackBlockLayers(
|
|
32
|
-
block: DocBlock,
|
|
33
|
-
context: TemplateContext,
|
|
34
|
-
notice: string,
|
|
35
|
-
): Layer[] {
|
|
36
|
-
const colors = resolveColorScheme(context, 'blue');
|
|
37
|
-
const { layout } = context;
|
|
38
|
-
|
|
39
|
-
const title = (block as Block).title ?? (block as Block).id ?? '';
|
|
40
|
-
const body = extractBodyText(block as Block);
|
|
41
|
-
|
|
42
|
-
const layers: Layer[] = [
|
|
43
|
-
{
|
|
44
|
-
type: 'shape',
|
|
45
|
-
id: 'fallback-bg',
|
|
46
|
-
content: { shape: 'rect', fill: colors.bg },
|
|
47
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
48
|
-
},
|
|
49
|
-
];
|
|
50
|
-
|
|
51
|
-
if (title) {
|
|
52
|
-
layers.push({
|
|
53
|
-
type: 'text',
|
|
54
|
-
id: 'fallback-title',
|
|
55
|
-
content: {
|
|
56
|
-
text: title,
|
|
57
|
-
style: {
|
|
58
|
-
fontSize: themedFontSize(56, context, true),
|
|
59
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
60
|
-
fontWeight: 'bold',
|
|
61
|
-
color: colors.text,
|
|
62
|
-
textAlign: 'center',
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
position: {
|
|
66
|
-
x: '50%',
|
|
67
|
-
y: body ? '28%' : '50%',
|
|
68
|
-
anchor: 'center',
|
|
69
|
-
width: layout.maxTextWidth,
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (body) {
|
|
75
|
-
layers.push({
|
|
76
|
-
type: 'text',
|
|
77
|
-
id: 'fallback-body',
|
|
78
|
-
content: {
|
|
79
|
-
text: body,
|
|
80
|
-
style: {
|
|
81
|
-
fontSize: themedFontSize(28, context),
|
|
82
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
83
|
-
color: colors.text,
|
|
84
|
-
textAlign: 'center',
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
position: {
|
|
88
|
-
x: '50%',
|
|
89
|
-
y: '55%',
|
|
90
|
-
anchor: 'center',
|
|
91
|
-
width: layout.maxTextWidth,
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
layers.push({
|
|
97
|
-
type: 'text',
|
|
98
|
-
id: 'fallback-notice',
|
|
99
|
-
content: {
|
|
100
|
-
text: `⚠ ${notice}`,
|
|
101
|
-
style: {
|
|
102
|
-
fontSize: themedFontSize(18, context),
|
|
103
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
104
|
-
color: `${colors.text}99`,
|
|
105
|
-
textAlign: 'center',
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
position: { x: '50%', y: '92%', anchor: 'center', width: layout.maxTextWidth },
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
return layers;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/** Plain text of a block's body contents, truncated for card display. */
|
|
115
|
-
function extractBodyText(block: Block): string {
|
|
116
|
-
if (!block.contents || block.contents.length === 0) return '';
|
|
117
|
-
const text = block.contents
|
|
118
|
-
.map((node) => extractPlainText(node))
|
|
119
|
-
.join('\n')
|
|
120
|
-
.trim();
|
|
121
|
-
if (text.length <= MAX_BODY_CHARS) return text;
|
|
122
|
-
return `${text.slice(0, MAX_BODY_CHARS).trimEnd()}…`;
|
|
123
|
-
}
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Feature Block Templates — `leftFeature` and `rightFeature`
|
|
3
|
-
*
|
|
4
|
-
* Pairs a "feature" image on one side of the block with a title + body
|
|
5
|
-
* paragraph on the other. The two templates are mirror images, so the
|
|
6
|
-
* actual layer-builder lives here once and the per-side template files
|
|
7
|
-
* just call it with a `side` parameter.
|
|
8
|
-
*
|
|
9
|
-
* Used for editorial layouts like product highlights, profile cards,
|
|
10
|
-
* and section intros where a single image deserves to sit next to a
|
|
11
|
-
* short text block rather than behind it (which is what
|
|
12
|
-
* `imageWithCaption` does).
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import type { Layer } from '../../schemas/Doc.js';
|
|
16
|
-
import type {
|
|
17
|
-
LeftFeatureInput,
|
|
18
|
-
RightFeatureInput,
|
|
19
|
-
TemplateContext,
|
|
20
|
-
} from '../../schemas/BlockTemplates.js';
|
|
21
|
-
import {
|
|
22
|
-
getThemeFont,
|
|
23
|
-
themedEntrance,
|
|
24
|
-
themedFontSize,
|
|
25
|
-
themedImageTreatment,
|
|
26
|
-
} from '../utils/themeUtils.js';
|
|
27
|
-
|
|
28
|
-
type FeatureInput = LeftFeatureInput | RightFeatureInput;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Build the layer list for either feature template. Layers are in
|
|
32
|
-
* back-to-front order: background, image, then text.
|
|
33
|
-
*/
|
|
34
|
-
function buildFeatureLayers(
|
|
35
|
-
input: FeatureInput,
|
|
36
|
-
context: TemplateContext,
|
|
37
|
-
side: 'left' | 'right',
|
|
38
|
-
): Layer[] {
|
|
39
|
-
const { imageSrc, imageAlt, imageWidth, imageHeight, title, body } = input;
|
|
40
|
-
const { theme, layout } = context;
|
|
41
|
-
|
|
42
|
-
const treatment = themedImageTreatment(context, input.imageTreatment);
|
|
43
|
-
// Treat the image as "sized" when the host gave us an explicit width
|
|
44
|
-
// or height — that's our cue that the user resized the image in the
|
|
45
|
-
// editor and we should respect that as a sizing hint instead of
|
|
46
|
-
// stretching the image to fill the whole half.
|
|
47
|
-
const sized = (imageWidth ?? 0) > 0 || (imageHeight ?? 0) > 0;
|
|
48
|
-
// In portrait the image stacks above the text rather than splitting
|
|
49
|
-
// horizontally — same flag the twoColumn template uses, so the two
|
|
50
|
-
// behave consistently on narrow viewports.
|
|
51
|
-
const stack = layout.stackColumns;
|
|
52
|
-
|
|
53
|
-
const titleFontSize = themedFontSize(48, context, true);
|
|
54
|
-
const bodyFontSize = themedFontSize(24, context, false);
|
|
55
|
-
|
|
56
|
-
// Image takes the full left or right half. The text column gets the
|
|
57
|
-
// opposite half, with a comfortable inset so the text doesn't kiss
|
|
58
|
-
// the image edge or the card border. All values are percentages of
|
|
59
|
-
// the block viewport so they scale with the card size.
|
|
60
|
-
//
|
|
61
|
-
// When the image is "sized" we shrink it inside its half: the half
|
|
62
|
-
// still claims the space (so the text column stays the same width
|
|
63
|
-
// and the layout doesn't shift around when dimensions are toggled)
|
|
64
|
-
// but the image itself sits centered with padding around it. The
|
|
65
|
-
// sized box uses a square envelope sized to the smaller dimension of
|
|
66
|
-
// its half so the image breathes regardless of viewport aspect.
|
|
67
|
-
let imgX: string;
|
|
68
|
-
let imgY: string;
|
|
69
|
-
let imgW: string;
|
|
70
|
-
let imgH: string;
|
|
71
|
-
let imageFit: 'cover' | 'contain';
|
|
72
|
-
if (stack) {
|
|
73
|
-
imgX = '0';
|
|
74
|
-
imgY = '0';
|
|
75
|
-
imgW = '100%';
|
|
76
|
-
imgH = '50%';
|
|
77
|
-
imageFit = sized ? 'contain' : 'cover';
|
|
78
|
-
} else if (sized) {
|
|
79
|
-
// 90% of the half (with explicit aspect via fit='contain') so the
|
|
80
|
-
// image keeps its natural proportions and never touches the card
|
|
81
|
-
// edges. We don't try to honor the literal pixel value — block
|
|
82
|
-
// viewports are designed in their own coordinate space — but the
|
|
83
|
-
// *intent* (smaller image, padded, centered) is what comes through.
|
|
84
|
-
const halfStart = side === 'left' ? 5 : 55; // %
|
|
85
|
-
imgX = `${halfStart}%`;
|
|
86
|
-
imgY = '5%';
|
|
87
|
-
imgW = '40%';
|
|
88
|
-
imgH = '90%';
|
|
89
|
-
imageFit = 'contain';
|
|
90
|
-
} else {
|
|
91
|
-
imgX = side === 'left' ? '0' : '50%';
|
|
92
|
-
imgY = '0';
|
|
93
|
-
imgW = '50%';
|
|
94
|
-
imgH = '100%';
|
|
95
|
-
imageFit = 'cover';
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Text-column geometry. `textX` is the LEFT edge of the column when
|
|
99
|
-
// the side is "left" (image left, text right); when the side is
|
|
100
|
-
// "right" the column occupies the left half, inset from the card edge.
|
|
101
|
-
// The mirror lives in the layout only — fully right-aligned
|
|
102
|
-
// (ragged-left) running text on rightFeature was genuinely hard to read.
|
|
103
|
-
const COLUMN_INSET = 4; // % of block width — padding from card edge / divider
|
|
104
|
-
const textColumnWidth = stack ? 90 : 42;
|
|
105
|
-
const textX = stack
|
|
106
|
-
? `${(100 - textColumnWidth) / 2}%`
|
|
107
|
-
: side === 'left'
|
|
108
|
-
? `${50 + COLUMN_INSET}%` // text column starts just past the divider
|
|
109
|
-
: `${COLUMN_INSET + 2}%`; // left edge of the left-half text column
|
|
110
|
-
|
|
111
|
-
// Stack the title above the body, with the pair vertically centered
|
|
112
|
-
// in the text column. The title sits 8% above center; body sits 2%
|
|
113
|
-
// below — these offsets keep both lines visible at the small card
|
|
114
|
-
// sizes used by the inline preview gutter without overflowing.
|
|
115
|
-
const titleY = stack ? '60%' : body ? '42%' : '50%';
|
|
116
|
-
const bodyY = stack ? '78%' : title ? '55%' : '50%';
|
|
117
|
-
const textAnchor = 'top-left';
|
|
118
|
-
const textAlign = 'left' as const;
|
|
119
|
-
|
|
120
|
-
// Paint our own background so the text column has a theme-paired
|
|
121
|
-
// surface to sit on. The host wrapper's surface isn't always theme-
|
|
122
|
-
// aware (e.g. the InlinePreviewGutter card uses a fixed light SVG
|
|
123
|
-
// background), and `theme.colors.text` is only guaranteed legible
|
|
124
|
-
// against `theme.colors.background` — themes like Gezellig pair
|
|
125
|
-
// cream text with a dark warm-brown background, which would
|
|
126
|
-
// disappear on a light wrapper. Matching the convention every other
|
|
127
|
-
// text-bearing template uses (see twoColumn / listBlock).
|
|
128
|
-
const layers: Layer[] = [
|
|
129
|
-
{
|
|
130
|
-
type: 'shape',
|
|
131
|
-
id: 'feature-bg',
|
|
132
|
-
content: { shape: 'rect', fill: theme.colors.background },
|
|
133
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
134
|
-
},
|
|
135
|
-
];
|
|
136
|
-
|
|
137
|
-
if (imageSrc) {
|
|
138
|
-
layers.push({
|
|
139
|
-
type: 'image',
|
|
140
|
-
id: 'feature-image',
|
|
141
|
-
content: {
|
|
142
|
-
src: imageSrc,
|
|
143
|
-
alt: imageAlt ?? title ?? '',
|
|
144
|
-
fit: imageFit,
|
|
145
|
-
...(treatment ? { treatment } : {}),
|
|
146
|
-
},
|
|
147
|
-
position: { x: imgX, y: imgY, width: imgW, height: imgH },
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (title) {
|
|
152
|
-
layers.push({
|
|
153
|
-
type: 'text',
|
|
154
|
-
id: 'feature-title',
|
|
155
|
-
content: {
|
|
156
|
-
text: title,
|
|
157
|
-
style: {
|
|
158
|
-
fontSize: titleFontSize,
|
|
159
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
160
|
-
fontWeight: 'bold',
|
|
161
|
-
color: theme.colors.text,
|
|
162
|
-
textAlign,
|
|
163
|
-
lineHeight: 1.2,
|
|
164
|
-
},
|
|
165
|
-
},
|
|
166
|
-
position: {
|
|
167
|
-
x: textX,
|
|
168
|
-
y: titleY,
|
|
169
|
-
anchor: textAnchor,
|
|
170
|
-
width: `${textColumnWidth}%`,
|
|
171
|
-
},
|
|
172
|
-
animation: themedEntrance(context, 'text', { type: 'fadeIn', duration: 0.8 }),
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (body) {
|
|
177
|
-
layers.push({
|
|
178
|
-
type: 'text',
|
|
179
|
-
id: 'feature-body',
|
|
180
|
-
content: {
|
|
181
|
-
text: body,
|
|
182
|
-
style: {
|
|
183
|
-
fontSize: bodyFontSize,
|
|
184
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
185
|
-
color: theme.colors.textMuted,
|
|
186
|
-
textAlign,
|
|
187
|
-
lineHeight: 1.5,
|
|
188
|
-
},
|
|
189
|
-
},
|
|
190
|
-
position: {
|
|
191
|
-
x: textX,
|
|
192
|
-
y: bodyY,
|
|
193
|
-
anchor: textAnchor,
|
|
194
|
-
width: `${textColumnWidth}%`,
|
|
195
|
-
},
|
|
196
|
-
animation: themedEntrance(context, 'text', { type: 'fadeIn', duration: 0.8, delay: 0.2 }),
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return layers;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export function leftFeature(input: LeftFeatureInput, context: TemplateContext): Layer[] {
|
|
204
|
-
return buildFeatureLayers(input, context, 'left');
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
export function rightFeature(input: RightFeatureInput, context: TemplateContext): Layer[] {
|
|
208
|
-
return buildFeatureLayers(input, context, 'right');
|
|
209
|
-
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Full Bleed Quote Template
|
|
3
|
-
*
|
|
4
|
-
* Short dramatic text filling the viewport like a movie title card.
|
|
5
|
-
* Designed for punchy text under 60 characters. Uses massive font
|
|
6
|
-
* centered on a dark vignette background.
|
|
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 { FullBleedQuoteInput, TemplateContext } from '../../schemas/BlockTemplates.js';
|
|
13
|
-
import {
|
|
14
|
-
resolveColorScheme,
|
|
15
|
-
getTemplateHint,
|
|
16
|
-
getThemeFont,
|
|
17
|
-
shouldUseShadow,
|
|
18
|
-
themedFontSize,
|
|
19
|
-
} from '../utils/themeUtils.js';
|
|
20
|
-
import { oklchDarken } from '../../schemas/colorUtils.js';
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Hint schema published for the theme validator + future customizer hint UI.
|
|
24
|
-
* Themes may set `templateHints.fullBleedQuote` entries matching these keys.
|
|
25
|
-
*/
|
|
26
|
-
export const fullBleedQuoteHintSchema = {
|
|
27
|
-
/** Entrance style for the quote text. 'subtle' or 'dramatic'. */
|
|
28
|
-
entrance: {
|
|
29
|
-
type: 'string' as const,
|
|
30
|
-
options: ['subtle', 'dramatic'] as const,
|
|
31
|
-
default: 'subtle',
|
|
32
|
-
},
|
|
33
|
-
} as const;
|
|
34
|
-
|
|
35
|
-
export function fullBleedQuote(input: FullBleedQuoteInput, context: TemplateContext): Layer[] {
|
|
36
|
-
const { text, colorScheme = 'blue' } = input;
|
|
37
|
-
const colors = resolveColorScheme(context, colorScheme);
|
|
38
|
-
|
|
39
|
-
// Massive font for dramatic impact
|
|
40
|
-
const textFontSize = themedFontSize(120, context, true);
|
|
41
|
-
|
|
42
|
-
return [
|
|
43
|
-
// Background — radial vignette built from the color scheme's own
|
|
44
|
-
// surface, so the card takes on the scheme (and the theme behind it)
|
|
45
|
-
// instead of vignetting every theme into hard black.
|
|
46
|
-
{
|
|
47
|
-
type: 'shape',
|
|
48
|
-
id: 'bg',
|
|
49
|
-
content: {
|
|
50
|
-
shape: 'rect',
|
|
51
|
-
fill: `radial-gradient(ellipse at 50% 50%, ${colors.bg} 0%, ${oklchDarken(colors.bg, 0.12)} 100%)`,
|
|
52
|
-
},
|
|
53
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
54
|
-
},
|
|
55
|
-
// The text — massive, centered
|
|
56
|
-
{
|
|
57
|
-
type: 'text',
|
|
58
|
-
id: 'impact-text',
|
|
59
|
-
content: {
|
|
60
|
-
text,
|
|
61
|
-
style: {
|
|
62
|
-
fontSize: textFontSize,
|
|
63
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
64
|
-
fontWeight: 'bold',
|
|
65
|
-
color: colors.text,
|
|
66
|
-
textAlign: 'center',
|
|
67
|
-
lineHeight: 1.2,
|
|
68
|
-
shadow: shouldUseShadow(context),
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
position: {
|
|
72
|
-
x: '50%',
|
|
73
|
-
y: '50%',
|
|
74
|
-
anchor: 'center',
|
|
75
|
-
width: '85%',
|
|
76
|
-
},
|
|
77
|
-
animation:
|
|
78
|
-
getTemplateHint<string>(context, 'fullBleedQuote', 'entrance', 'subtle') === 'dramatic'
|
|
79
|
-
? { type: 'zoomIn', duration: 0.8 }
|
|
80
|
-
: { type: 'fadeIn', duration: 1.5 },
|
|
81
|
-
},
|
|
82
|
-
];
|
|
83
|
-
}
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Image With Caption Template
|
|
3
|
-
*
|
|
4
|
-
* Full-screen background image with text overlay.
|
|
5
|
-
* Supports Ken Burns animation effects (zoom, pan).
|
|
6
|
-
* Adapts caption positioning and font sizes for different viewports.
|
|
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 { ImageWithCaptionInput, TemplateContext } from '../../schemas/BlockTemplates.js';
|
|
13
|
-
import {
|
|
14
|
-
getThemeFont,
|
|
15
|
-
shouldUseShadow,
|
|
16
|
-
themedFontSize,
|
|
17
|
-
themedImageTreatment,
|
|
18
|
-
} from '../utils/themeUtils.js';
|
|
19
|
-
import { withAlpha } from '../../schemas/colorUtils.js';
|
|
20
|
-
import { cleanCaption } from './captionUtils.js';
|
|
21
|
-
import { mapAmbientMotion } from './accentImage.js';
|
|
22
|
-
|
|
23
|
-
export function imageWithCaption(input: ImageWithCaptionInput, context: TemplateContext): Layer[] {
|
|
24
|
-
const {
|
|
25
|
-
imageSrc,
|
|
26
|
-
imageAlt,
|
|
27
|
-
caption: rawCaption,
|
|
28
|
-
captionPosition: _captionPosition = 'bottom',
|
|
29
|
-
ambientMotion,
|
|
30
|
-
isTitle,
|
|
31
|
-
subtitle,
|
|
32
|
-
imageCredit,
|
|
33
|
-
imageLicense,
|
|
34
|
-
} = input;
|
|
35
|
-
const caption = rawCaption ? cleanCaption(rawCaption) : rawCaption;
|
|
36
|
-
const { theme, layout } = context;
|
|
37
|
-
|
|
38
|
-
const treatment = themedImageTreatment(context, input.imageTreatment);
|
|
39
|
-
|
|
40
|
-
// Scale font sizes for viewport
|
|
41
|
-
const captionFontSize = themedFontSize(30, context, false);
|
|
42
|
-
const titleFontSize = themedFontSize(96, context, true);
|
|
43
|
-
const subtitleFontSize = themedFontSize(36, context, false);
|
|
44
|
-
|
|
45
|
-
// Determine animation based on ambientMotion setting
|
|
46
|
-
// Support both new 'ambientMotion' and legacy 'kenBurns' property
|
|
47
|
-
const legacyKenBurns = (input as unknown as Record<string, unknown>).kenBurns as
|
|
48
|
-
| string
|
|
49
|
-
| undefined;
|
|
50
|
-
const motion: string | undefined = ambientMotion || legacyKenBurns;
|
|
51
|
-
const imageAnimation = mapAmbientMotion(motion);
|
|
52
|
-
|
|
53
|
-
const layers: Layer[] = [
|
|
54
|
-
// Background image
|
|
55
|
-
{
|
|
56
|
-
type: 'image',
|
|
57
|
-
id: 'bg-image',
|
|
58
|
-
content: {
|
|
59
|
-
src: imageSrc,
|
|
60
|
-
alt: imageAlt,
|
|
61
|
-
fit: 'cover',
|
|
62
|
-
credit: imageCredit,
|
|
63
|
-
license: imageLicense,
|
|
64
|
-
...(treatment ? { treatment } : {}),
|
|
65
|
-
},
|
|
66
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
67
|
-
animation: imageAnimation,
|
|
68
|
-
},
|
|
69
|
-
];
|
|
70
|
-
|
|
71
|
-
// Scrim gradients are tinted from the theme background so the theme
|
|
72
|
-
// text color painted on top stays readable by construction — a fixed
|
|
73
|
-
// black scrim put dark theme text on a dark band in light themes.
|
|
74
|
-
const bg = theme.colors.background;
|
|
75
|
-
|
|
76
|
-
// TITLE MODE: Large centered title over hero image (like cover slide)
|
|
77
|
-
if (isTitle && caption) {
|
|
78
|
-
// Full gradient overlay for title readability (similar to cover slide)
|
|
79
|
-
layers.push({
|
|
80
|
-
type: 'shape',
|
|
81
|
-
id: 'title-gradient',
|
|
82
|
-
content: {
|
|
83
|
-
shape: 'rect',
|
|
84
|
-
fill: `linear-gradient(0deg, ${withAlpha(bg, 0.85)} 0%, ${withAlpha(bg, 0.45)} 40%, ${withAlpha(bg, 0.1)} 70%, ${withAlpha(bg, 0)} 100%)`,
|
|
85
|
-
},
|
|
86
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// Title text - large and centered in lower portion
|
|
90
|
-
layers.push({
|
|
91
|
-
type: 'text',
|
|
92
|
-
id: 'title',
|
|
93
|
-
content: {
|
|
94
|
-
text: caption,
|
|
95
|
-
style: {
|
|
96
|
-
fontSize: titleFontSize,
|
|
97
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
98
|
-
fontWeight: 'bold',
|
|
99
|
-
color: theme.colors.text,
|
|
100
|
-
textAlign: 'center',
|
|
101
|
-
shadow: shouldUseShadow(context),
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
position: {
|
|
105
|
-
x: '50%',
|
|
106
|
-
y: subtitle ? '70%' : '75%',
|
|
107
|
-
anchor: 'center',
|
|
108
|
-
width: layout.maxTextWidth,
|
|
109
|
-
},
|
|
110
|
-
animation: { type: 'fadeIn', duration: 0.8 },
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// Optional subtitle
|
|
114
|
-
if (subtitle) {
|
|
115
|
-
layers.push({
|
|
116
|
-
type: 'text',
|
|
117
|
-
id: 'subtitle',
|
|
118
|
-
content: {
|
|
119
|
-
text: subtitle,
|
|
120
|
-
style: {
|
|
121
|
-
fontSize: subtitleFontSize,
|
|
122
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
123
|
-
color: theme.colors.textMuted,
|
|
124
|
-
textAlign: 'center',
|
|
125
|
-
lineHeight: 1.5,
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
position: {
|
|
129
|
-
x: '50%',
|
|
130
|
-
y: '82%',
|
|
131
|
-
anchor: 'center',
|
|
132
|
-
width: layout.maxTextWidth,
|
|
133
|
-
},
|
|
134
|
-
animation: { type: 'fadeIn', duration: 0.8, delay: 0.2 },
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return layers;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// STANDARD MODE: Caption at bottom
|
|
142
|
-
if (caption) {
|
|
143
|
-
// Compact caption band raised above media controls. Long archival captions
|
|
144
|
-
// are clamped so they don't sprawl across the image.
|
|
145
|
-
layers.push({
|
|
146
|
-
type: 'shape',
|
|
147
|
-
id: 'caption-gradient',
|
|
148
|
-
content: {
|
|
149
|
-
shape: 'rect',
|
|
150
|
-
fill: `linear-gradient(90deg, ${withAlpha(bg, 0)}, ${withAlpha(bg, 0.78)} 16%, ${withAlpha(bg, 0.78)} 84%, ${withAlpha(bg, 0)})`,
|
|
151
|
-
},
|
|
152
|
-
position: {
|
|
153
|
-
x: 0,
|
|
154
|
-
y: '68%',
|
|
155
|
-
width: '100%',
|
|
156
|
-
height: '16%',
|
|
157
|
-
},
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
layers.push({
|
|
161
|
-
type: 'text',
|
|
162
|
-
id: 'caption',
|
|
163
|
-
content: {
|
|
164
|
-
text: caption,
|
|
165
|
-
style: {
|
|
166
|
-
fontSize: captionFontSize,
|
|
167
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
168
|
-
color: theme.colors.text,
|
|
169
|
-
textAlign: 'center',
|
|
170
|
-
shadow: shouldUseShadow(context),
|
|
171
|
-
lineHeight: 1.18,
|
|
172
|
-
maxLines: 2,
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
position: {
|
|
176
|
-
x: '50%',
|
|
177
|
-
y: '74%',
|
|
178
|
-
anchor: 'center',
|
|
179
|
-
width: '78%',
|
|
180
|
-
},
|
|
181
|
-
animation: { type: 'fadeIn', duration: 1.5, delay: 0.5 },
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return layers;
|
|
186
|
-
}
|