@litfamily/lithermes 1.0.8 → 1.0.9
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/README.md +299 -13
- package/README_Ko-KR.md +300 -14
- package/assets/lithermes-plugin/README.md +17 -6
- package/assets/lithermes-plugin/__init__.py +96 -21
- package/assets/lithermes-plugin/core.py +15 -6
- package/assets/lithermes-plugin/core_commands.py +140 -28
- package/assets/lithermes-plugin/core_contexts.py +88 -15
- package/assets/lithermes-plugin/core_contract.py +118 -9
- package/assets/lithermes-plugin/core_routing.py +197 -8
- package/assets/lithermes-plugin/deliverable_hedge_guard.py +378 -357
- package/assets/lithermes-plugin/diagnostics.py +53 -2
- package/assets/lithermes-plugin/humanizer_detector.py +348 -0
- package/assets/lithermes-plugin/humanizer_ko_metrics.py +108 -0
- package/assets/lithermes-plugin/humanizer_office.py +18 -0
- package/assets/lithermes-plugin/lit_mark.py +1 -1
- package/assets/lithermes-plugin/motion_receipts.py +80 -0
- package/assets/lithermes-plugin/payload-version.json +2240 -64
- package/assets/lithermes-plugin/plugin.yaml +1 -1
- package/assets/lithermes-plugin/rules/bundled-rules/lit-humanizer.md +14 -0
- package/assets/lithermes-plugin/skills/autoconference/assets/report_template.md +2 -1
- package/assets/lithermes-plugin/skills/autoconference/modes/ship/SKILL.md +11 -8
- package/assets/lithermes-plugin/skills/autoresearch/modes/ship/type-checklists.md +2 -2
- package/assets/lithermes-plugin/skills/browser-drive/ORIGIN.json +17 -0
- package/assets/lithermes-plugin/skills/browser-drive/SKILL.md +41 -16
- package/assets/lithermes-plugin/skills/browser-drive/scripts/capability_probe.py +122 -10
- package/assets/lithermes-plugin/skills/frontend-ui-ux/SKILL.md +45 -13
- package/assets/lithermes-plugin/skills/frontend-ui-ux/examples/phase-3-readme-ab/README.md +51 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/README.md +44 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/adaptive-layout.md +34 -62
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/brand-and-imagery.md +22 -70
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/complete-contract.md +18 -4
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/composition.md +27 -78
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/craft-floor.md +74 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/creative-directions.md +25 -69
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/evidence-review.md +18 -97
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/implementation-platforms.md +23 -83
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/inclusive-interface.md +22 -70
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/interaction-motion.md +34 -68
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/motion-guide.md +62 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/operating-lanes.md +14 -78
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/performance-delivery.md +22 -71
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/product-direction.md +17 -70
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/production.md +19 -7
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/redesign-playbook.md +23 -76
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/slop-register.md +69 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/system-foundations.md +22 -67
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/visual-language.md +16 -72
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/visual-reconstruction.md +16 -81
- package/assets/lithermes-plugin/skills/frontend-ui-ux/resources/THIRD-PARTY-NOTICE.txt +15 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe-page.js +311 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe-rules.json +46 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe.mjs +231 -0
- package/assets/lithermes-plugin/skills/lit-comprehend/SKILL.md +36 -25
- package/assets/lithermes-plugin/skills/lit-comprehend/references/artifact-template.md +45 -87
- package/assets/lithermes-plugin/skills/lit-comprehend/scripts/verify-explainer.py +3 -27
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/NOTICE +33 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/SKILL.md +308 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-architecture-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-architecture-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-architecture-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bar-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bar-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bar-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-beeswarm-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-beeswarm-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-beeswarm-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bubble-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bubble-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bubble-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bump-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bump-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bump-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-data-flow-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-data-flow-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-data-flow-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-datalake-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-datalake-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-datalake-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-db-schema-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-db-schema-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-db-schema-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dependency-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dependency-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dependency-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-deployment-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-deployment-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-deployment-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-integration-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-integration-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-integration-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-er-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-er-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-er-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-fishbone-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-fishbone-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-fishbone-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-flowchart-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-flowchart-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-flowchart-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-gantt-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-gantt-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-gantt-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-heatmap-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-heatmap-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-heatmap-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-drawio-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-drawio-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-drawio-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-it-state-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-it-state-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-it-state-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-journey-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-journey-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-journey-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-kanban-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-kanban-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-kanban-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-layers-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-layers-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-layers-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-line-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-line-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-line-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-marimekko-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-marimekko-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-marimekko-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-medallion-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-medallion-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-medallion-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-nested-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-nested-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-nested-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-org-chart-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-org-chart-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-org-chart-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-polar-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-polar-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-polar-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-process-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-process-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-process-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-pyramid-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-pyramid-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-pyramid-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-queue-animated-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-queue-animated-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-queue-animated-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-radar-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-radar-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-radar-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-ridgeline-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-ridgeline-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-ridgeline-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sankey-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sankey-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sankey-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-scatter-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-scatter-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-scatter-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-slopegraph-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-slopegraph-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-slopegraph-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-story-map-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-story-map-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-story-map-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-streamgraph-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-streamgraph-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-streamgraph-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-swimlane-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-swimlane-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-swimlane-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-timeline-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-timeline-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-timeline-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-treemap-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-treemap-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-treemap-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-uml-class-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-uml-class-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-uml-class-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-venn-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-venn-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-venn-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-wardley-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-wardley-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-wardley-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-waterfall-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-waterfall-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-waterfall-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/fonts/OFL.txt +94 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/fonts/PretendardVariable.woff2 +0 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/fonts/provenance.json +22 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/icons.html +231 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/index.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/devicon-MIT.txt +20 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/diagram-design-MIT.txt +21 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/log-z-MIT.txt +21 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/simple-icons-CC0.md +30 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/tabler-MIT.txt +21 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/01-service-architecture/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/01-service-architecture/brief.md +33 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/02-release-decision/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/02-release-decision/brief.md +18 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/03-data-retention/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/03-data-retention/brief.md +19 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/04-oauth-sequence/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/04-oauth-sequence/brief.md +17 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/05-review-lanes/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/05-review-lanes/brief.md +17 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/06-rollout-gates/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/06-rollout-gates/brief.md +17 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/07-deployment-boundary/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/07-deployment-boundary/brief.md +19 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/08-policy-traces/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/08-policy-traces/brief.md +20 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/accessibility.md +37 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/export.md +29 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-drawio.md +21 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-excalidraw.md +14 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-mermaid.md +18 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-schema.md +28 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/korean-typography.md +34 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/motion.md +29 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/office-pptx-docx.md +40 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/output-spec.md +48 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-annotation.md +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-icons.md +21 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-sketchy.md +11 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-terminal.md +11 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/profiles.md +24 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/semantic-patterns.md +27 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/style-guide.md +67 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-architecture.md +51 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-bar.md +51 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-beeswarm.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-bubble.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-bump.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-catalog.json +1433 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-data-flow.md +51 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-datalake.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-db-schema.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dependency.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-deployment.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dp-integration.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dp-security-matrix.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-er.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-fishbone.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-flowchart.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-gantt.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-heatmap.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-high-level-vertical.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-high-level.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-import-drawio.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-import-excalidraw.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-import-mermaid.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-it-state.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-journey.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-kanban.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-layers.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-line.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-loop-terminal.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-loop.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-marimekko.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-medallion.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-nested.md +59 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-org-chart.md +58 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-paved-road-animated.md +72 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-polar.md +67 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-policy-trace-animated.md +69 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-process.md +58 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-pyramid.md +59 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-quadrant-consultant.md +60 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-quadrant.md +57 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-queue-animated.md +63 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-radar.md +57 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-ridgeline.md +63 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-sankey.md +68 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-scatter.md +60 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-sequence-oauth.md +66 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-sequence.md +63 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-slopegraph.md +65 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-state-lifecycle.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-state.md +59 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-story-map.md +52 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-streamgraph.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-swimlane.md +52 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-timeline.md +52 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-tree-block-decomposition.md +57 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-tree.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-treemap.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-uml-class.md +52 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-venn.md +51 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-wardley.md +52 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-waterfall.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/verifier-guide.md +31 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/block-registry.mjs +43 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/browser-version.mjs +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/check-visible-text.py +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_brief.py +192 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_catalog.py +135 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_checks.py +123 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_cli.py +94 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_geometry.py +130 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_metrics.py +166 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_quality.py +293 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_quality_geometry.py +200 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_records.py +205 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_sequence.py +55 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/doctor.mjs +24 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/drawio_extract.py +209 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/drawio_source.py +188 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/excalidraw_extract.py +233 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/excalidraw_support.py +64 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/export.mjs +125 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/mermaid_extract.py +240 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/mermaid_source.py +39 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/office-safety.mjs +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-all.py +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-brief.py +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-diagram.py +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-motion.py +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-type.py +12 -0
- package/assets/lithermes-plugin/skills/lit-docx/NOTICE +1 -0
- package/assets/lithermes-plugin/skills/lit-docx/SKILL.md +97 -0
- package/assets/lithermes-plugin/skills/lit-docx/references/frontmatter_schema.md +42 -0
- package/assets/lithermes-plugin/skills/lit-docx/references/journal_style_spec.md +17 -0
- package/assets/lithermes-plugin/skills/lit-docx/references/markdown_quality_checklist.md +37 -0
- package/assets/lithermes-plugin/skills/lit-docx/references/slop_phrase_list.yaml +58 -0
- package/assets/lithermes-plugin/skills/lit-docx/references/slop_rules.md +35 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/clean_markdown.py +95 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/convert_md_to_docx.py +1041 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/convert_md_to_pdf.py +281 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/convert_pdf.py +130 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/edit_docx.py +297 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/embed_images.py +78 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/generate_docx_templates.py +491 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/slop_lint.py +536 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/visual_audit.py +41 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/docx/acs.docx +0 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/docx/elsevier.docx +0 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/docx/ieee.docx +0 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/docx/korean-generic.docx +0 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/docx/nature.docx +0 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/acs/README.md +5 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/acs/template.tex +37 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/elsevier/README.md +5 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/elsevier/template.tex +38 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/ieee/README.md +5 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/ieee/template.tex +37 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/korean-generic/README.md +5 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/korean-generic/template.tex +37 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/nature/README.md +5 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/nature/template.tex +37 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/registry.yaml +1366 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/NOTICE +170 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/SKILL.md +125 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/assets/report-skeleton.md +26 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/assets/slide-text-skeleton.md +30 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/accessibility-note/after.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/accessibility-note/before.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/api-reference/after.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/api-reference/before.md +15 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/changelog/after.md +5 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/changelog/before.md +12 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/code-comments/after.md +10 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/code-comments/before.md +19 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/commit/after.md +5 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/commit/before.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/data-release/after.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/data-release/before.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/detector-validation/ko-metrics-golden.json +49 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/detector-validation/pos-real.txt +26 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/detector-validation/rule-cases.json +306 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/english-essay/after.md +5 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/english-essay/before.md +5 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/incident-update/after.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/incident-update/before.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-essay/after.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-essay/before.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-report/after.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-report/before.md +13 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-slide/after.md +19 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-slide/before.md +21 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/meeting-brief/after.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/meeting-brief/before.md +11 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/policy-faq/after.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/policy-faq/before.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/pr/after.md +15 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/pr/before.md +17 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/project-update/after.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/project-update/before.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/readme/after.md +12 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/readme/before.md +14 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/report/after.md +13 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/report/before.md +11 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/research-abstract/after.md +5 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/research-abstract/before.md +5 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/slides/after.md +19 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/slides/before.md +19 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/troubleshooting/after.md +11 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/troubleshooting/before.md +11 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/README.md +16 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/always-on-rule.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/code-patterns.md +468 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/deliverable-channels.md +111 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns-checklist.md +43 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns-content.md +243 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns-structure.md +375 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns.md +57 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-metrics.md +33 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-patterns-a-d.md +659 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-patterns-e-j.md +387 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-patterns.md +31 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/rewrite-playbook.md +54 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/taxonomy.md +153 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/rules.json +884 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/scripts/detect.py +17 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/scripts/extract_office_text.py +114 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/scripts/ko_metrics.py +35 -0
- package/assets/lithermes-plugin/skills/lit-pptx/NOTICE +1 -0
- package/assets/lithermes-plugin/skills/lit-pptx/SKILL.md +109 -0
- package/assets/lithermes-plugin/skills/lit-pptx/agents/analyst.md +49 -0
- package/assets/lithermes-plugin/skills/lit-pptx/agents/antithesis.md +65 -0
- package/assets/lithermes-plugin/skills/lit-pptx/agents/architect.md +44 -0
- package/assets/lithermes-plugin/skills/lit-pptx/agents/critic.md +42 -0
- package/assets/lithermes-plugin/skills/lit-pptx/agents/synthesizer.md +47 -0
- package/assets/lithermes-plugin/skills/lit-pptx/agents/thesis.md +33 -0
- package/assets/lithermes-plugin/skills/lit-pptx/assets/azure/circle-lg.png +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/assets/azure/circle-md.png +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/assets/azure/circle-sm.png +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/bin/office.mjs +77 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/PRETENDARD-OFL.txt +94 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Black.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Bold.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-ExtraBold.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-ExtraLight.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Light.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Medium.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Regular.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-SemiBold.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Thin.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/OFL.txt +94 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/SOURCE.md +29 -0
- package/assets/lithermes-plugin/skills/lit-pptx/pretendard-font/public/static/PretendardGOV-Bold.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/pretendard-font/public/static/PretendardGOV-Regular.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/anti-slop-checklist.md +71 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/authoring-guide.md +139 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/consensus-protocol.md +125 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/data-display-cookbook.md +45 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/design-system-azure.md +58 -0
- package/assets/lithermes-plugin/skills/lit-pptx/runtime/package-lock.json +750 -0
- package/assets/lithermes-plugin/skills/lit-pptx/runtime/package.json +15 -0
- package/assets/lithermes-plugin/skills/lit-pptx/runtime/requirements.in +7 -0
- package/assets/lithermes-plugin/skills/lit-pptx/runtime/requirements.lock +391 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/compile-deck.js +447 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/craft_extras.py +215 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/embed_fonts.py +199 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/integrity.py +60 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/inventory.py +64 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/learn_template.py +433 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/derive-palette.js +176 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/directive-parser.js +244 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/font-map.js +79 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/gen-bg.js +85 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/gen-gradient-assets.js +36 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/layout-resolver.js +736 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/markdown-loader.js +136 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/render-adapter-html.js +357 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/render-adapter-pptx.js +1864 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/slide-ast.js +539 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/spec-validator.js +94 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/template-registry.js +355 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/qa_deck.py +791 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/validate_pptx.py +206 -0
- package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/markdown-slide-spec-v1.md +251 -0
- package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/markdown-slide-spec-v2.md +221 -0
- package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/slide-ast-v1.schema.json +229 -0
- package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/slide-ast-v2.schema.json +144 -0
- package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/template-enrollment-contract.md +228 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-A2Z/capabilities.yaml +146 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-A2Z/layout-mapping.yaml +384 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-A2Z/template.yaml +37 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-PRO/capabilities.yaml +154 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-PRO/layout-mapping.yaml +405 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-PRO/template.yaml +37 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/capabilities.yaml +179 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/layout-mapping.yaml +299 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/template.yaml +45 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/capabilities.yaml +181 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/layout-mapping.yaml +299 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/template.yaml +44 -0
- package/assets/lithermes-plugin/skills/lit-scientific-visualization/SKILL.md +2 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/SKILL.md +71 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/audio.py +45 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/motion.mjs +690 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/runtime.mjs +299 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/NOTICE +23 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/THIRD_PARTY_NOTICES +55 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/browser.mjs +169 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/completion.mjs +52 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/constants.mjs +162 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/director.mjs +33 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/encode.mjs +191 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/flash.mjs +163 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/frame.mjs +428 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/gate.mjs +483 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/look.mjs +223 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/page.js +622 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/presets.mjs +170 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/scenes.mjs +242 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/sound.mjs +382 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-gate.mjs +97 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-init.js +186 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-kit.js +389 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-qa.mjs +358 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-worker.mjs +33 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage.mjs +691 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stills.mjs +71 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stroke.mjs +231 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/timeline.mjs +177 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/treatment.mjs +244 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/type.mjs +183 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/util.mjs +152 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/craft-loop.md +175 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/engine-contract.md +166 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/runtime.md +122 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/stage.md +261 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/style-bibles.md +122 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/treatment.md +164 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/type-craft.md +92 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/fonts.json +154 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/licenses/CREDITS +20 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/licenses/EMS-OFL.txt +91 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/package-lock.json +88 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/package.json +12 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/requirements.in +1 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/requirements.lock +727 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/word-timing.json +9 -0
- package/assets/lithermes-plugin/skills/litresearch/SKILL.md +19 -18
- package/assets/lithermes-plugin/skills/litwork/SKILL.md +28 -0
- package/assets/lithermes-plugin/skills/visual-qa/references/complete-contract.md +3 -3
- package/package.json +1 -1
- package/readme-assets/ab-simple/s11-ui-baseline-desktop.webp +0 -0
- package/readme-assets/ab-simple/s11-ui-lithermes-desktop.webp +0 -0
- package/readme-assets/ab-simple/s3-ui-baseline-desktop.webp +0 -0
- package/readme-assets/ab-simple/s3-ui-lithermes-desktop.webp +0 -0
- package/readme-assets/ab-simple/s4-ui-baseline-desktop.webp +0 -0
- package/readme-assets/ab-simple/s4-ui-lithermes-desktop.webp +0 -0
- package/readme-assets/ab-simple/s5-office-baseline-slides.webp +0 -0
- package/readme-assets/ab-simple/s5-office-lithermes-slides.webp +0 -0
- package/readme-assets/ab-simple/s7-lithermes-diagram.webp +0 -0
- package/readme-assets/ab-simple/s8-office-baseline-slides.webp +0 -0
- package/readme-assets/ab-simple/s8-office-lithermes-slides.webp +0 -0
- package/readme-assets/ab-simple/s9-office-lithermes-pages.webp +0 -0
- package/readme-assets/badge-version.svg +1 -1
- package/readme-assets/cover-motion-still.webp +0 -0
- package/readme-assets/cover-motion.webp +0 -0
- package/readme-assets/skills/autoconference.webp +0 -0
- package/readme-assets/skills/autoresearch.webp +0 -0
- package/readme-assets/skills/browser-drive.webp +0 -0
- package/readme-assets/skills/comment-checker.webp +0 -0
- package/readme-assets/skills/debugging.webp +0 -0
- package/readme-assets/skills/deep-interview.webp +0 -0
- package/readme-assets/skills/frontend-ui-ux.webp +0 -0
- package/readme-assets/skills/lit-burnoff-file.webp +0 -0
- package/readme-assets/skills/lit-burnoff.webp +0 -0
- package/readme-assets/skills/lit-code.webp +0 -0
- package/readme-assets/skills/lit-commit.webp +0 -0
- package/readme-assets/skills/lit-comprehend.webp +0 -0
- package/readme-assets/skills/lit-crucible.webp +0 -0
- package/readme-assets/skills/lit-diagram-drawer.webp +0 -0
- package/readme-assets/skills/lit-docx.webp +0 -0
- package/readme-assets/skills/lit-handoff.webp +0 -0
- package/readme-assets/skills/lit-humanizer.webp +0 -0
- package/readme-assets/skills/lit-init.webp +0 -0
- package/readme-assets/skills/lit-plan.webp +0 -0
- package/readme-assets/skills/lit-pptx.webp +0 -0
- package/readme-assets/skills/lit-recap.webp +0 -0
- package/readme-assets/skills/lit-scientific-visualization.webp +0 -0
- package/readme-assets/skills/lit-typographic-motion.webp +0 -0
- package/readme-assets/skills/litgoal.webp +0 -0
- package/readme-assets/skills/litresearch.webp +0 -0
- package/readme-assets/skills/litwork.webp +0 -0
- package/readme-assets/skills/lsp-setup.webp +0 -0
- package/readme-assets/skills/lsp.webp +0 -0
- package/readme-assets/skills/readme-studio.webp +0 -0
- package/readme-assets/skills/refactor.webp +0 -0
- package/readme-assets/skills/review-work.webp +0 -0
- package/readme-assets/skills/rules.webp +0 -0
- package/readme-assets/skills/start-work.webp +0 -0
- package/readme-assets/skills/structural-search.webp +0 -0
- package/readme-assets/skills/visual-qa.webp +0 -0
- package/readme-assets/skills/wikify.webp +0 -0
- package/src/cli.js +40 -1
- package/src/lib/check.js +21 -0
- package/src/lib/install.js +262 -7
- package/src/lib/skillPayload.js +3 -3
- package/assets/lithermes-plugin/skills/lit-korean/SKILL.md +0 -237
- package/assets/lithermes-plugin/skills/lit-korean/references/quick-rules.md +0 -24
- package/assets/lithermes-plugin/skills/lit-korean/references/safety-checklist.md +0 -23
- package/readme-assets/cover.webp +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// The stills set every render writes, on both paths: each beat's midpoint, a
|
|
2
|
+
// transition strip per cut (6 frames before, the cut, 6 after), a 12-frame
|
|
3
|
+
// contact sheet and the poster frame, listed with their SHA-256 in
|
|
4
|
+
// stills/stills.json. `look` accepts only frames from the latest set.
|
|
5
|
+
import { createHash } from 'node:crypto';
|
|
6
|
+
import { mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { areaResize, contactSheet, pngEncode } from './encode.mjs';
|
|
9
|
+
import { writeJson } from './director.mjs';
|
|
10
|
+
|
|
11
|
+
const sha = (data) => createHash('sha256').update(data).digest('hex');
|
|
12
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
13
|
+
|
|
14
|
+
// beats: [{ index, first, last, mid }] in frames.
|
|
15
|
+
export function stillsPlan({ totalFrames, beats }) {
|
|
16
|
+
const clamp = (f) => Math.max(0, Math.min(totalFrames - 1, f));
|
|
17
|
+
const mids = beats.map((b) => ({ index: b.index, frame: clamp(b.mid) }));
|
|
18
|
+
const cuts = beats.slice(1).map((b, i) => ({ index: i + 1, frame: clamp(b.first), frames: [clamp(b.first - 6), clamp(b.first), clamp(b.first + 6)] }));
|
|
19
|
+
const contact = Array.from({ length: 12 }, (_, i) => Math.round((i * (totalFrames - 1)) / 11));
|
|
20
|
+
const poster = clamp(beats[Math.floor(beats.length / 2)].mid);
|
|
21
|
+
const reduced = clamp(beats[beats.length - 1].mid);
|
|
22
|
+
const frames = [...new Set([...mids.map((m) => m.frame), ...cuts.flatMap((c) => c.frames), ...contact, poster, reduced])].sort((a, b) => a - b);
|
|
23
|
+
return { mids, cuts, contact, poster, reduced, frames };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function strip(PNG, images, width, height) {
|
|
27
|
+
const portrait = height > width;
|
|
28
|
+
const cellW = portrait ? 360 : 640;
|
|
29
|
+
const tiles = images.map((rgba) => areaResize(rgba, width, height, cellW));
|
|
30
|
+
const cellH = tiles[0].height, gap = 6;
|
|
31
|
+
const W = tiles.length * cellW + (tiles.length + 1) * gap, H = cellH + 2 * gap;
|
|
32
|
+
const buf = Buffer.alloc(W * H * 4);
|
|
33
|
+
for (let i = 0; i < buf.length; i += 4) { buf[i] = 30; buf[i + 1] = 32; buf[i + 2] = 36; buf[i + 3] = 255; }
|
|
34
|
+
tiles.forEach((tile, k) => {
|
|
35
|
+
const left = gap + k * (cellW + gap);
|
|
36
|
+
for (let y = 0; y < cellH; y++) tile.data.copy(buf, ((gap + y) * W + left) * 4, y * cellW * 4, (y + 1) * cellW * 4);
|
|
37
|
+
});
|
|
38
|
+
return pngEncode(PNG, buf, W, H);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// pngs: Map frame -> PNG bytes of the full-size capture (or a function frame -> PNG bytes).
|
|
42
|
+
export function writeStillsSet({ out, PNG, pngs, plan, size, round, mode, posterPng = null }) {
|
|
43
|
+
const [W, H] = size;
|
|
44
|
+
const get = (f) => (typeof pngs === 'function' ? pngs(f) : pngs.get(f));
|
|
45
|
+
const decoded = new Map();
|
|
46
|
+
const rgba = (f) => { if (!decoded.has(f)) decoded.set(f, PNG.sync.read(get(f)).data); return decoded.get(f); };
|
|
47
|
+
rmSync(join(out, 'stills'), { recursive: true, force: true });
|
|
48
|
+
mkdirSync(join(out, 'stills'), { recursive: true });
|
|
49
|
+
mkdirSync(join(out, 'sheet'), { recursive: true });
|
|
50
|
+
const files = [];
|
|
51
|
+
const put = (rel, bytes, entry) => { writeFileSync(join(out, rel), bytes); files.push({ file: rel, sha256: sha(bytes), ...entry }); };
|
|
52
|
+
for (const m of plan.mids) put(`stills/beat-${pad(m.index + 1)}-f${m.frame}.png`, get(m.frame), { kind: 'beat-mid', beat: m.index, frame: m.frame });
|
|
53
|
+
for (const c of plan.cuts) put(`stills/strip-${pad(c.index)}-f${c.frame}.png`, strip(PNG, c.frames.map(rgba), W, H), { kind: 'strip', cut: c.index, frames: c.frames });
|
|
54
|
+
if (posterPng) put('stills/poster.png', posterPng, { kind: 'poster', frame: plan.poster });
|
|
55
|
+
else put(`stills/poster-f${plan.poster}.png`, get(plan.poster), { kind: 'poster', frame: plan.poster });
|
|
56
|
+
const sheetFile = join(out, 'sheet', 'contact.png');
|
|
57
|
+
contactSheet(PNG, plan.contact.map((f) => ({ data: rgba(f), width: W, height: H, frame: f })), sheetFile);
|
|
58
|
+
const sheetBytes = readFileSync(sheetFile);
|
|
59
|
+
files.push({ file: 'sheet/contact.png', sha256: sha(sheetBytes), kind: 'contact', frames: plan.contact });
|
|
60
|
+
const set = { schema: 'lithermes.stills/v1', round, mode, size, files, required: files.map((f) => f.file), manifestSha256: null };
|
|
61
|
+
writeJson(join(out, 'stills', 'stills.json'), set);
|
|
62
|
+
return { file: 'stills/stills.json', files, set };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Once manifest.json exists, the stills set records its hash; `look` checks it.
|
|
66
|
+
export function stampStills(out) {
|
|
67
|
+
const file = join(out, 'stills', 'stills.json');
|
|
68
|
+
const set = JSON.parse(readFileSync(file, 'utf8'));
|
|
69
|
+
set.manifestSha256 = sha(readFileSync(join(out, 'manifest.json')));
|
|
70
|
+
writeJson(file, set);
|
|
71
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
// Single-stroke plotter type from the five OFL EMS SVG fonts (MO-FT-08), laid
|
|
2
|
+
// out as polylines so a pen can write text progressively. Adapted from
|
|
3
|
+
// mexicat/pdoom-video app/src/engine/stroke.ts (MIT, see NOTICE): the optical
|
|
4
|
+
// pair-kerning and writtenLength() method are kept; SVG parsing runs in Node
|
|
5
|
+
// with a small attribute reader instead of the browser DOMParser.
|
|
6
|
+
import { polylineLengths } from './util.mjs';
|
|
7
|
+
|
|
8
|
+
export const STROKE_FONTS = Object.freeze({
|
|
9
|
+
readable: 'EMSReadability.svg',
|
|
10
|
+
script: 'EMSAllure.svg',
|
|
11
|
+
tech: 'EMSTech.svg',
|
|
12
|
+
osmotron: 'EMSOsmotron.svg',
|
|
13
|
+
felix: 'EMSFelix.svg',
|
|
14
|
+
});
|
|
15
|
+
const CONNECTED = new Set(['script']);
|
|
16
|
+
|
|
17
|
+
const attr = (tag, name) => {
|
|
18
|
+
const match = tag.match(new RegExp(`\\s${name}="([^"]*)"`));
|
|
19
|
+
return match ? match[1] : null;
|
|
20
|
+
};
|
|
21
|
+
const decodeEntity = (value) => value
|
|
22
|
+
.replace(/&#x([0-9a-f]+);/gi, (_, hex) => String.fromCodePoint(parseInt(hex, 16)))
|
|
23
|
+
.replace(/&#(\d+);/g, (_, dec) => String.fromCodePoint(Number(dec)))
|
|
24
|
+
.replace(/"/g, '"').replace(/'/g, "'").replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&');
|
|
25
|
+
|
|
26
|
+
function parsePath(d) {
|
|
27
|
+
const out = [];
|
|
28
|
+
const tokens = String(d || '').match(/[MLml]|-?\d*\.?\d+(?:e-?\d+)?/g) || [];
|
|
29
|
+
let current = null, command = 'M';
|
|
30
|
+
for (let i = 0; i < tokens.length;) {
|
|
31
|
+
const token = tokens[i];
|
|
32
|
+
if (/[MLml]/.test(token)) { command = token.toUpperCase(); i++; continue; }
|
|
33
|
+
const x = parseFloat(tokens[i]), y = parseFloat(tokens[i + 1]);
|
|
34
|
+
i += 2;
|
|
35
|
+
if (command === 'M') { current = [{ x, y }]; out.push(current); command = 'L'; }
|
|
36
|
+
else current?.push({ x, y });
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const inkBox = (strokes) => {
|
|
42
|
+
let x0 = Infinity, x1 = -Infinity, y0 = Infinity, y1 = -Infinity;
|
|
43
|
+
for (const s of strokes) for (const p of s) { x0 = Math.min(x0, p.x); x1 = Math.max(x1, p.x); y0 = Math.min(y0, p.y); y1 = Math.max(y1, p.y); }
|
|
44
|
+
return { x0, x1, y0, y1 };
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const ROWS = 90, SHADE = 0.4, CLEAR = 0.1, STRENGTH = 0.6;
|
|
48
|
+
const OPEN_R = new Set("AFLPTVWYKXfrvwyk7'\"’”".split(''));
|
|
49
|
+
const OPEN_L = new Set("AJTVWYXvwyj.,'\"’”…".split(''));
|
|
50
|
+
|
|
51
|
+
export function parseStrokeFont(svgText, name = 'readable') {
|
|
52
|
+
const fontFace = svgText.match(/<font-face\b[^>]*>/)?.[0] || '';
|
|
53
|
+
const fontTag = svgText.match(/<font\b[^>]*>/)?.[0] || '';
|
|
54
|
+
const defaultAdvance = parseFloat(attr(fontTag, 'horiz-adv-x') || '500');
|
|
55
|
+
const glyphs = new Map();
|
|
56
|
+
for (const tag of svgText.match(/<glyph\b[^>]*>/g) || []) {
|
|
57
|
+
const unicode = attr(tag, 'unicode');
|
|
58
|
+
if (unicode == null) continue;
|
|
59
|
+
glyphs.set(decodeEntity(unicode), {
|
|
60
|
+
adv: parseFloat(attr(tag, 'horiz-adv-x') || String(defaultAdvance)),
|
|
61
|
+
strokes: parsePath(attr(tag, 'd')),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
let yLo = Infinity, yHi = -Infinity;
|
|
65
|
+
for (const g of glyphs.values()) for (const s of g.strokes) for (const p of s) { yLo = Math.min(yLo, p.y); yHi = Math.max(yHi, p.y + 1); }
|
|
66
|
+
const H = inkBox(glyphs.get('H')?.strokes ?? [[{ x: 0, y: 0 }, { x: 0, y: 700 }]]);
|
|
67
|
+
const X = inkBox(glyphs.get('x')?.strokes ?? [[{ x: 0, y: 0 }, { x: 0, y: 450 }]]);
|
|
68
|
+
return {
|
|
69
|
+
name,
|
|
70
|
+
upm: parseFloat(attr(fontFace, 'units-per-em') || '1000'),
|
|
71
|
+
glyphs, missingAdv: defaultAdvance,
|
|
72
|
+
base: H.y0, xTop: X.y1, capTop: H.y1,
|
|
73
|
+
yLo, dy: (yHi - yLo) / ROWS,
|
|
74
|
+
profiles: new Map(), kerns: new Map(), target: null,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function profile(font, ch) {
|
|
79
|
+
if (font.profiles.has(ch)) return font.profiles.get(ch);
|
|
80
|
+
const g = font.glyphs.get(ch);
|
|
81
|
+
let result = null;
|
|
82
|
+
if (g && g.strokes.length) {
|
|
83
|
+
const l = new Float64Array(ROWS).fill(NaN), r = new Float64Array(ROWS).fill(NaN);
|
|
84
|
+
const put = (x, y) => {
|
|
85
|
+
const i = Math.floor((y - font.yLo) / font.dy);
|
|
86
|
+
if (i < 0 || i >= ROWS) return;
|
|
87
|
+
if (!(l[i] <= x)) l[i] = x;
|
|
88
|
+
if (!(r[i] >= x)) r[i] = x;
|
|
89
|
+
};
|
|
90
|
+
for (const s of g.strokes) {
|
|
91
|
+
if (s.length === 1) put(s[0].x, s[0].y);
|
|
92
|
+
for (let k = 1; k < s.length; k++) {
|
|
93
|
+
const a = s[k - 1], b = s[k];
|
|
94
|
+
const n = Math.max(1, Math.ceil(Math.hypot(b.x - a.x, b.y - a.y) / (font.dy * 0.35)));
|
|
95
|
+
for (let j = 0; j <= n; j++) put(a.x + ((b.x - a.x) * j) / n, a.y + ((b.y - a.y) * j) / n);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const widen = (k) => {
|
|
99
|
+
const lw = new Float64Array(ROWS).fill(NaN), rw = new Float64Array(ROWS).fill(NaN);
|
|
100
|
+
for (let i = 0; i < ROWS; i++) for (let j = 0; j < ROWS; j++) {
|
|
101
|
+
const d = Math.abs(i - j) * font.dy * k;
|
|
102
|
+
if (!Number.isNaN(l[j]) && !(lw[i] <= l[j] + d)) lw[i] = l[j] + d;
|
|
103
|
+
if (!Number.isNaN(r[j]) && !(rw[i] >= r[j] - d)) rw[i] = r[j] - d;
|
|
104
|
+
}
|
|
105
|
+
return [lw, rw];
|
|
106
|
+
};
|
|
107
|
+
const [lw, rw] = widen(SHADE), [l45, r45] = widen(1);
|
|
108
|
+
result = { l: lw, r: rw, l45, r45 };
|
|
109
|
+
}
|
|
110
|
+
font.profiles.set(ch, result);
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const isLower = (ch) => ch !== ch.toUpperCase() && ch === ch.toLowerCase();
|
|
115
|
+
const isLetter = (ch) => /[\p{L}\p{N}]/u.test(ch);
|
|
116
|
+
|
|
117
|
+
function approach(font, a, b) {
|
|
118
|
+
const pa = profile(font, a), pb = profile(font, b);
|
|
119
|
+
if (!pa || !pb) return null;
|
|
120
|
+
const adv = font.glyphs.get(a).adv;
|
|
121
|
+
const lower = isLower(a) || isLower(b) || !isLetter(a) || !isLetter(b);
|
|
122
|
+
const top = lower ? font.xTop : font.capTop;
|
|
123
|
+
const i0 = Math.max(0, Math.floor((font.base - font.yLo) / font.dy));
|
|
124
|
+
const i1 = Math.min(ROWS - 1, Math.floor((top - font.yLo) / font.dy));
|
|
125
|
+
let m = Infinity;
|
|
126
|
+
for (let i = i0; i <= i1; i++) {
|
|
127
|
+
const ra = pa.r[i], lb = pb.l[i];
|
|
128
|
+
if (!Number.isNaN(ra) && !Number.isNaN(lb)) m = Math.min(m, adv + lb - ra);
|
|
129
|
+
}
|
|
130
|
+
return m === Infinity ? null : m;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function pairKern(font, a, b) {
|
|
134
|
+
if (a === ' ' || b === ' ' || !(OPEN_R.has(a) || OPEN_L.has(b))) return 0;
|
|
135
|
+
if (!isLetter(a) && !isLetter(b)) return 0;
|
|
136
|
+
const key = a + b;
|
|
137
|
+
if (font.kerns.has(key)) return font.kerns.get(key);
|
|
138
|
+
if (!font.target) {
|
|
139
|
+
const mean = (pairs) => pairs.map((p) => approach(font, p[0], p[1]) ?? 0).reduce((x, y) => x + y, 0) / pairs.length;
|
|
140
|
+
font.target = { lc: mean(['nn', 'oo', 'no', 'on']), uc: mean(['HH', 'OO', 'HO', 'OH']) };
|
|
141
|
+
}
|
|
142
|
+
const m = approach(font, a, b);
|
|
143
|
+
let k = 0;
|
|
144
|
+
if (m !== null) {
|
|
145
|
+
const lower = isLower(a) || isLower(b) || !isLetter(a) || !isLetter(b);
|
|
146
|
+
k = Math.max(-0.15 * font.upm, Math.min(0, STRENGTH * ((lower ? font.target.lc : font.target.uc) - m)));
|
|
147
|
+
const pa = profile(font, a), pb = profile(font, b), adv = font.glyphs.get(a).adv;
|
|
148
|
+
let near = Infinity;
|
|
149
|
+
for (let i = 0; i < ROWS; i++) {
|
|
150
|
+
const ra = pa.r45[i], lb = pb.l45[i];
|
|
151
|
+
if (!Number.isNaN(ra) && !Number.isNaN(lb)) near = Math.min(near, adv + lb - ra);
|
|
152
|
+
}
|
|
153
|
+
k = Math.max(k, Math.min(0, CLEAR * font.upm - near));
|
|
154
|
+
}
|
|
155
|
+
font.kerns.set(key, k);
|
|
156
|
+
return k;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Polylines in px (origin left baseline, y down) with cumulative lengths for writing.
|
|
160
|
+
export function strokeText(font, text, size, tracking = 0) {
|
|
161
|
+
const s = size / font.upm;
|
|
162
|
+
const kern = !CONNECTED.has(font.name);
|
|
163
|
+
const strokes = [], charOf = [];
|
|
164
|
+
let x = 0;
|
|
165
|
+
const chars = Array.from(text);
|
|
166
|
+
chars.forEach((ch, ci) => {
|
|
167
|
+
const g = font.glyphs.get(ch);
|
|
168
|
+
for (const st of g?.strokes ?? []) {
|
|
169
|
+
strokes.push(st.map((p) => ({ x: x + p.x * s, y: -p.y * s })));
|
|
170
|
+
charOf.push(ci);
|
|
171
|
+
}
|
|
172
|
+
x += (g?.adv ?? font.missingAdv) * s + tracking;
|
|
173
|
+
if (kern && ci + 1 < chars.length) x += pairKern(font, ch, chars[ci + 1]) * s;
|
|
174
|
+
});
|
|
175
|
+
const lens = strokes.map((p) => polylineLengths(p));
|
|
176
|
+
const startLen = [];
|
|
177
|
+
let acc = 0;
|
|
178
|
+
for (const L of lens) { startLen.push(acc); acc += L[L.length - 1] ?? 0; }
|
|
179
|
+
const charRange = chars.map(() => [Infinity, -Infinity]);
|
|
180
|
+
strokes.forEach((_, i) => {
|
|
181
|
+
const r = charRange[charOf[i]];
|
|
182
|
+
r[0] = Math.min(r[0], startLen[i]);
|
|
183
|
+
r[1] = Math.max(r[1], startLen[i] + (lens[i][lens[i].length - 1] ?? 0));
|
|
184
|
+
});
|
|
185
|
+
let last = 0;
|
|
186
|
+
for (const r of charRange) {
|
|
187
|
+
if (r[0] === Infinity) { r[0] = last; r[1] = last; }
|
|
188
|
+
last = r[1];
|
|
189
|
+
}
|
|
190
|
+
return { strokes, startLen, lens, total: acc, width: x - tracking, charRange, size, missing: chars.filter((ch) => ch.trim() && !font.glyphs.has(ch)) };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Pen distance at time t from each character's own [start, end] window, so the
|
|
194
|
+
// pen follows the timeline's word timing instead of a fixed px/s constant.
|
|
195
|
+
export function writtenLength(layout, charTimes, t) {
|
|
196
|
+
let len = 0;
|
|
197
|
+
for (let i = 0; i < layout.charRange.length; i++) {
|
|
198
|
+
const [a, b] = layout.charRange[i];
|
|
199
|
+
const [t0, t1] = charTimes[i] ?? [Infinity, Infinity];
|
|
200
|
+
if (t >= t1) len = b;
|
|
201
|
+
else if (t > t0) { len = a + (b - a) * ((t - t0) / Math.max(1e-3, t1 - t0)); break; }
|
|
202
|
+
else break;
|
|
203
|
+
}
|
|
204
|
+
return len;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// The written prefix of each polyline as flat coordinate arrays for the page.
|
|
208
|
+
export function writtenStrokes(layout, len) {
|
|
209
|
+
const out = [];
|
|
210
|
+
for (let i = 0; i < layout.strokes.length; i++) {
|
|
211
|
+
const s0 = layout.startLen[i];
|
|
212
|
+
if (s0 >= len) break;
|
|
213
|
+
const pts = layout.strokes[i], L = layout.lens[i], remain = len - s0;
|
|
214
|
+
const flat = [pts[0].x, pts[0].y];
|
|
215
|
+
let j = 1;
|
|
216
|
+
for (; j < pts.length && L[j] <= remain; j++) flat.push(pts[j].x, pts[j].y);
|
|
217
|
+
if (j < pts.length) {
|
|
218
|
+
const a = pts[j - 1], b = pts[j];
|
|
219
|
+
const u = (remain - L[j - 1]) / Math.max(1e-6, L[j] - L[j - 1]);
|
|
220
|
+
flat.push(a.x + (b.x - a.x) * u, a.y + (b.y - a.y) * u);
|
|
221
|
+
}
|
|
222
|
+
out.push(flat);
|
|
223
|
+
}
|
|
224
|
+
return out;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export function strokeBounds(layout) {
|
|
228
|
+
let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;
|
|
229
|
+
for (const s of layout.strokes) for (const p of s) { x0 = Math.min(x0, p.x); x1 = Math.max(x1, p.x); y0 = Math.min(y0, p.y); y1 = Math.max(y1, p.y); }
|
|
230
|
+
return Number.isFinite(x0) ? [x0, y0, x1, y1] : null;
|
|
231
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// Brief -> canonical timeline (§A4, §A10). Tier 1 paces each unit at 1.25x its
|
|
2
|
+
// reading floor and snaps every cut FORWARD to the beat grid, never shortening a
|
|
3
|
+
// hold (MO-A-06/09/10/14/15/16). Tier 2 swaps the fixed-BPM grid for the beats a
|
|
4
|
+
// pre-warmed librosa venv detected in the user's own audio. The anchor-and-snap
|
|
5
|
+
// idea is the only thing taken from pdoom's timeline method; nothing of its
|
|
6
|
+
// content is used.
|
|
7
|
+
import { FRAME, OUTPUT, READING, TIMING } from './constants.mjs';
|
|
8
|
+
import { eojeols, readingCounts, readingFloor, scriptOf, smart, plain } from './type.mjs';
|
|
9
|
+
|
|
10
|
+
export const SCENES = Object.freeze(['title-slam', 'karaoke-line', 'kinetic-list', 'number-counter', 'stroke-signature', 'end-card']);
|
|
11
|
+
const LIST_SPLIT = /\s*(?:·|•|\||;|,|\/)\s*/u;
|
|
12
|
+
|
|
13
|
+
export function listItems(text) {
|
|
14
|
+
return String(text).split(LIST_SPLIT).map((item) => item.trim()).filter(Boolean);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function defaultScene(text, index, count) {
|
|
18
|
+
if (index === 0) return 'title-slam';
|
|
19
|
+
if (count >= 2 && index === count - 1) return 'end-card';
|
|
20
|
+
if (/\d/.test(text)) return 'number-counter';
|
|
21
|
+
if (listItems(text).length >= 3) return 'kinetic-list';
|
|
22
|
+
return 'karaoke-line';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Grid of beat times starting at 0 (the film start is always an anchor).
|
|
26
|
+
export function makeGrid({ bpm, beats }) {
|
|
27
|
+
if (beats?.length) {
|
|
28
|
+
const sorted = [...new Set(beats.filter((b) => Number.isFinite(b) && b > 0))].sort((a, b) => a - b);
|
|
29
|
+
const gaps = sorted.slice(1).map((b, i) => b - sorted[i]).sort((a, b) => a - b);
|
|
30
|
+
const step = gaps.length ? gaps[Math.floor(gaps.length / 2)] : 60 / bpm;
|
|
31
|
+
return { beat: step, at: (target) => {
|
|
32
|
+
const hit = sorted.find((b) => b >= target - 1e-9);
|
|
33
|
+
if (target <= 1e-9) return 0;
|
|
34
|
+
if (hit !== undefined) return hit;
|
|
35
|
+
const last = sorted.at(-1) ?? 0;
|
|
36
|
+
return last + Math.ceil((target - last - 1e-9) / step) * step;
|
|
37
|
+
} };
|
|
38
|
+
}
|
|
39
|
+
const beat = 60 / bpm;
|
|
40
|
+
return { beat, at: (target) => Math.ceil((target - 1e-9) / beat) * beat };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const frameRound = (t, fps) => Math.round(t * fps) / fps;
|
|
44
|
+
const fix = (x) => Math.round(x * 1e6) / 1e6;
|
|
45
|
+
|
|
46
|
+
function revealSteps(parts, lineFloor, quarter) {
|
|
47
|
+
const weights = parts.map((p) => {
|
|
48
|
+
const { H, W } = readingCounts(p);
|
|
49
|
+
return Math.max(0.05, READING.hangulSecPerSyllable * H + W / READING.englishWordsPerSec);
|
|
50
|
+
});
|
|
51
|
+
const total = weights.reduce((a, b) => a + b, 0);
|
|
52
|
+
return parts.map((_, j) => {
|
|
53
|
+
const share = TIMING.paceMargin * lineFloor * (weights[j] / total);
|
|
54
|
+
return Math.ceil(Math.max(READING.revealFloor, share) / quarter - 1e-9) * quarter;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function normalizeBrief(raw) {
|
|
59
|
+
if (!raw || typeof raw !== 'object') throw Object.assign(new Error('brief must be a JSON object'), { userError: true });
|
|
60
|
+
const text = Array.isArray(raw.text) ? raw.text : typeof raw.text === 'string' ? [raw.text] : null;
|
|
61
|
+
if (!text || !text.length || !text.every((line) => typeof line === 'string' && line.trim())) {
|
|
62
|
+
throw Object.assign(new Error('brief.text must be a non-empty list of display lines'), { userError: true });
|
|
63
|
+
}
|
|
64
|
+
if (raw.scenes && (!Array.isArray(raw.scenes) || raw.scenes.some((s) => s != null && !SCENES.includes(s)))) {
|
|
65
|
+
throw Object.assign(new Error(`brief.scenes entries must be one of ${SCENES.join(', ')}`), { userError: true });
|
|
66
|
+
}
|
|
67
|
+
const bpm = raw.bpm == null ? TIMING.defaultBpm : Number(raw.bpm);
|
|
68
|
+
if (!Number.isFinite(bpm) || bpm < TIMING.minBpm || bpm > TIMING.maxBpm) {
|
|
69
|
+
throw Object.assign(new Error(`brief.bpm must be ${TIMING.minBpm}..${TIMING.maxBpm}`), { userError: true });
|
|
70
|
+
}
|
|
71
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
72
|
+
for (const item of Array.isArray(value) ? value : [value]) {
|
|
73
|
+
if (typeof item === 'string' && /<[^<>\n]{1,80}>/u.test(item)) throw Object.assign(new Error(`brief.${key} still holds an example placeholder (${item}); write this film's own value`), { userError: true });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (raw.durationSec != null && !(Number(raw.durationSec) >= 4 && Number(raw.durationSec) <= 90)) {
|
|
77
|
+
throw Object.assign(new Error('brief.durationSec must be 4..90'), { userError: true });
|
|
78
|
+
}
|
|
79
|
+
return { ...raw, text: text.map((line) => line.trim()), bpm, seed: Number.isInteger(raw.seed) ? raw.seed >>> 0 : 20260926 };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function buildTimeline(brief, { presetId, fps = FRAME.fps, audioGrid = null } = {}) {
|
|
83
|
+
const grid = makeGrid(audioGrid ? { bpm: audioGrid.bpm, beats: audioGrid.beats } : { bpm: brief.bpm });
|
|
84
|
+
const beat = grid.beat, quarter = beat / 4;
|
|
85
|
+
const typed = presetId === 'terminalcore';
|
|
86
|
+
const warnings = [];
|
|
87
|
+
const lines = brief.text.map((line) => (typed ? plain(line) : smart(line)));
|
|
88
|
+
const plan = lines.map((text, index) => {
|
|
89
|
+
let sceneId = brief.scenes?.[index] || defaultScene(text, index, lines.length);
|
|
90
|
+
if (sceneId === 'stroke-signature' && /[가-힣ᄀ-ᇿ-]/u.test(text)) {
|
|
91
|
+
warnings.push(`line ${index + 1}: the stroke fonts have no Hangul, so it uses title-slam instead of stroke-signature`);
|
|
92
|
+
sceneId = 'title-slam';
|
|
93
|
+
}
|
|
94
|
+
if (sceneId === 'number-counter' && !/\d/.test(text)) sceneId = 'karaoke-line';
|
|
95
|
+
if (sceneId === 'kinetic-list' && listItems(text).length < 2) sceneId = 'karaoke-line';
|
|
96
|
+
return { text, sceneId };
|
|
97
|
+
});
|
|
98
|
+
const lay = (scale) => {
|
|
99
|
+
const uses = new Map();
|
|
100
|
+
const units = [];
|
|
101
|
+
let cursor = 0, gridBeat = 0;
|
|
102
|
+
plan.forEach(({ text, sceneId }) => {
|
|
103
|
+
const shotIndex = uses.get(sceneId) ?? 0;
|
|
104
|
+
uses.set(sceneId, shotIndex + 1);
|
|
105
|
+
const id = shotIndex === 0 ? sceneId : `${sceneId}-${shotIndex + 1}`;
|
|
106
|
+
const floor = readingFloor(text, 'line');
|
|
107
|
+
const { C } = readingCounts(text);
|
|
108
|
+
let need = Math.max(TIMING.paceMargin * floor, C / READING.englishCps + 1 / fps, TIMING.minSceneBeats * beat);
|
|
109
|
+
let parts = [], steps = [];
|
|
110
|
+
if (sceneId === 'karaoke-line') parts = eojeols(text);
|
|
111
|
+
if (sceneId === 'kinetic-list') parts = listItems(text);
|
|
112
|
+
if (parts.length > 1) {
|
|
113
|
+
steps = revealSteps(parts, floor, quarter);
|
|
114
|
+
need = Math.max(need, steps.reduce((a, b) => a + b, 0) + beat);
|
|
115
|
+
}
|
|
116
|
+
if (sceneId === 'number-counter') need = Math.max(need, 1.2 + beat);
|
|
117
|
+
if (sceneId === 'stroke-signature') need = Math.max(need, 0.11 * Array.from(text).length + beat);
|
|
118
|
+
if (sceneId === 'end-card') need = Math.max(need, TIMING.paceMargin * floor + beat);
|
|
119
|
+
need *= scale;
|
|
120
|
+
const start = cursor;
|
|
121
|
+
const endBeat = grid.at(gridBeat + need);
|
|
122
|
+
const end = frameRound(endBeat, fps);
|
|
123
|
+
units.push({ id, sceneId, shotIndex, start: fix(start), end: fix(end), holdSec: fix(end - start), kind: 'line', text, script: scriptOf(text), beatSec: fix(gridBeat) });
|
|
124
|
+
let t = gridBeat;
|
|
125
|
+
parts.forEach((part, j) => {
|
|
126
|
+
if (parts.length < 2) return;
|
|
127
|
+
const rs = frameRound(t, fps), re = frameRound(t + steps[j], fps);
|
|
128
|
+
units.push({ id: `${id}/r${j}`, sceneId, shotIndex, start: fix(rs), end: fix(re), holdSec: fix(re - rs), kind: 'reveal', text: part, script: scriptOf(part), beatSec: fix(t) });
|
|
129
|
+
t += steps[j];
|
|
130
|
+
});
|
|
131
|
+
cursor = end;
|
|
132
|
+
gridBeat = endBeat;
|
|
133
|
+
});
|
|
134
|
+
return units;
|
|
135
|
+
};
|
|
136
|
+
// A treatment length scales every hold up (reveal steps stay on their floors)
|
|
137
|
+
// until the film reaches it; the floors are never cut to meet a shorter one.
|
|
138
|
+
let units = lay(1);
|
|
139
|
+
const target = Number(brief.durationSec);
|
|
140
|
+
if (Number.isFinite(target) && target > 0) {
|
|
141
|
+
const endOf = (list) => list.filter((u) => u.kind === 'line').at(-1).end;
|
|
142
|
+
const natural = endOf(units);
|
|
143
|
+
if (natural < target - 1e-9) {
|
|
144
|
+
let lo = 1, hi = 2 * target / natural;
|
|
145
|
+
for (let i = 0; i < 40; i++) {
|
|
146
|
+
const mid = (lo + hi) / 2;
|
|
147
|
+
if (endOf(lay(mid)) >= target - 1e-9) hi = mid; else lo = mid;
|
|
148
|
+
}
|
|
149
|
+
units = lay(hi);
|
|
150
|
+
} else if (natural > target + beat) {
|
|
151
|
+
warnings.push(`the reading floors force a ${natural} s film, longer than the requested ${target} s`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const shots = units.filter((u) => u.kind === 'line');
|
|
155
|
+
const last = shots.at(-1);
|
|
156
|
+
if (last.end < OUTPUT.minDurationSec) {
|
|
157
|
+
const endBeat = grid.at(OUTPUT.minDurationSec);
|
|
158
|
+
last.end = fix(frameRound(endBeat, fps));
|
|
159
|
+
last.holdSec = fix(last.end - last.start);
|
|
160
|
+
warnings.push(`film extended to ${last.end} s to reach the 3 s duration floor`);
|
|
161
|
+
}
|
|
162
|
+
if (last.end > OUTPUT.warnDurationSec) warnings.push(`film runs ${last.end} s, past the 90 s advisory length`);
|
|
163
|
+
return { timeline: units, durationSec: last.end, beat, warnings };
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function shotsOf(timeline) {
|
|
167
|
+
return timeline.filter((u) => u.kind === 'line' || u.kind === 'scene');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function shotAt(timeline, t) {
|
|
171
|
+
const shots = shotsOf(timeline);
|
|
172
|
+
return shots.find((s) => t >= s.start - 1e-6 && t < s.end - 1e-6) || shots.at(-1);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function revealsOf(timeline, shot) {
|
|
176
|
+
return timeline.filter((u) => u.kind === 'reveal' && u.sceneId === shot.sceneId && u.shotIndex === shot.shotIndex);
|
|
177
|
+
}
|