kasaframe 0.1.1 → 0.1.4
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/NOTICE +10 -8
- package/README.md +16 -1
- package/app/server/engine.ts +133 -15
- package/app/server/main.ts +7 -3
- package/app/web/main.ts +218 -36
- package/app/web/style.css +37 -4
- package/bin/hooks.mjs +14 -1
- package/bin/kf.mjs +20 -2
- package/docs/AGENTS.md +64 -16
- package/music/README.md +31 -7
- package/package.json +2 -2
- package/packages/adapters/src/project.ts +5 -1
- package/packages/adapters/src/texture.ts +94 -0
- package/packages/check/src/check.ts +10 -3
- package/packages/check/src/rules/assets.ts +4 -1
- package/packages/check/src/rules/frames.ts +2 -1
- package/packages/check/src/rules/layout.ts +30 -6
- package/packages/cli/package.json +2 -1
- package/packages/cli/src/blur.ts +15 -3
- package/packages/cli/src/cells.ts +227 -0
- package/packages/cli/src/commands/bench.ts +123 -0
- package/packages/cli/src/commands/blender.ts +72 -49
- package/packages/cli/src/commands/direct.ts +210 -0
- package/packages/cli/src/commands/doctor.ts +9 -1
- package/packages/cli/src/commands/look.ts +9 -2
- package/packages/cli/src/commands/lyrics.ts +47 -1
- package/packages/cli/src/commands/make.ts +797 -150
- package/packages/cli/src/commands/music.ts +78 -0
- package/packages/cli/src/commands/narrate.ts +238 -0
- package/packages/cli/src/commands/new.ts +15 -6
- package/packages/cli/src/commands/render.ts +94 -60
- package/packages/cli/src/commands/series.ts +110 -0
- package/packages/cli/src/commands/setup.ts +42 -3
- package/packages/cli/src/commands/theme.ts +222 -4
- package/packages/cli/src/deps.ts +6 -6
- package/packages/cli/src/kf.ts +14 -3
- package/packages/cli/src/lock.ts +8 -6
- package/packages/cli/src/mix.ts +131 -0
- package/packages/cli/src/pick.ts +110 -0
- package/packages/cli/src/pool.ts +34 -0
- package/packages/cli/src/segments.ts +402 -0
- package/packages/cli/src/vary.ts +124 -0
- package/packages/core/src/index.ts +1 -1
- package/packages/core/src/project.ts +26 -0
- package/packages/director/package.json +23 -0
- package/packages/director/src/assemble.ts +364 -0
- package/packages/director/src/brief.ts +122 -0
- package/packages/director/src/catalog.ts +49 -0
- package/packages/director/src/content.ts +343 -0
- package/packages/director/src/fallback.ts +58 -0
- package/packages/director/src/index.ts +13 -0
- package/packages/director/src/pattern.ts +90 -0
- package/packages/director/src/patterns/fill/cells.ts +115 -0
- package/packages/director/src/patterns/formula/stack.ts +93 -0
- package/packages/director/src/patterns/util.ts +58 -0
- package/packages/director/src/scene.ts +62 -0
- package/packages/director/src/select.ts +163 -0
- package/packages/director/src/transitions.ts +115 -0
- package/packages/gen/PROVIDERS.md +39 -4
- package/packages/gen/src/ask.ts +132 -0
- package/packages/gen/src/audio.ts +91 -0
- package/packages/gen/src/blender.ts +54 -0
- package/packages/gen/src/capabilities.ts +151 -0
- package/packages/gen/src/generate.ts +4 -2
- package/packages/gen/src/image/codex.ts +117 -0
- package/packages/gen/src/index.ts +10 -2
- package/packages/gen/src/keys.ts +26 -0
- package/packages/gen/src/music/elevenlabs.ts +41 -0
- package/packages/gen/src/music/index.ts +120 -0
- package/packages/gen/src/music/library.ts +73 -0
- package/packages/gen/src/music/lyria.ts +52 -0
- package/packages/gen/src/music/types.ts +28 -0
- package/packages/gen/src/registry.ts +6 -3
- package/packages/gen/src/tts/dashscope.ts +64 -0
- package/packages/gen/src/tts/elevenlabs.ts +84 -0
- package/packages/gen/src/tts/gemini.ts +73 -0
- package/packages/gen/src/tts/index.ts +241 -0
- package/packages/gen/src/tts/local.ts +42 -0
- package/packages/gen/src/tts/types.ts +44 -0
- package/packages/gen/src/types.ts +4 -0
- package/packages/gen/src/video/h3.ts +5 -0
- package/packages/gen/src/video/http.ts +1 -1
- package/packages/jizura/src/index.ts +2 -2
- package/packages/jizura/src/install.ts +198 -155
- package/packages/jizura/src/layer.ts +75 -32
- package/packages/jizura/src/pin.ts +4 -1
- package/packages/jizura/src/vendor.ts +140 -0
- package/packages/jizura/src/vite.ts +34 -7
- package/packages/jizura/vendor/JIZURA_LICENSE.txt +21 -0
- package/packages/jizura/vendor/NOTICE +43 -0
- package/packages/jizura/vendor/engine.json +47 -0
- package/packages/jizura/vendor/fonts/BlackHanSans-Regular.woff2 +0 -0
- package/packages/jizura/vendor/fonts/DotGothic16-Regular.woff2 +0 -0
- package/packages/jizura/vendor/fonts/GowunBatang-Bold.woff2 +0 -0
- package/packages/jizura/vendor/fonts/IBMPlexMono-Medium.ttf +0 -0
- package/packages/jizura/vendor/fonts/IBMPlexMono-SemiBold.ttf +0 -0
- package/packages/jizura/vendor/fonts/NotoSansKR-VF.woff2 +0 -0
- package/packages/jizura/vendor/fonts/NotoSerifKR-VF.woff2 +0 -0
- package/packages/jizura/vendor/fonts/OFL-blackhansans.txt +93 -0
- package/packages/jizura/vendor/fonts/OFL-dotgothic16.txt +93 -0
- package/packages/jizura/vendor/fonts/OFL-gowunbatang.txt +94 -0
- package/packages/jizura/vendor/fonts/OFL-ibmplexmono.txt +93 -0
- package/packages/jizura/vendor/fonts/OFL-notosanskr.txt +93 -0
- package/packages/jizura/vendor/fonts/OFL-notoserifkr.txt +94 -0
- package/packages/jizura/vendor/fonts/fonts.json +52 -0
- package/packages/jizura/vendor/jizura_engine.js +35024 -0
- package/packages/motion/README.md +11 -0
- package/packages/motion/package.json +1 -0
- package/packages/motion/src/captions.ts +32 -24
- package/packages/motion/src/moves/brushWipe.ts +14 -1
- package/packages/motion/src/moves/dress.ts +191 -0
- package/packages/motion/src/moves/echoStack.ts +3 -3
- package/packages/motion/src/moves/fit.ts +36 -0
- package/packages/motion/src/moves/ghostStack.ts +14 -5
- package/packages/motion/src/moves/imageSwarm.ts +8 -4
- package/packages/motion/src/moves/index.ts +23 -4
- package/packages/motion/src/moves/karaokeLine.ts +17 -3
- package/packages/motion/src/moves/menu.ts +139 -0
- package/packages/motion/src/moves/neonSign.ts +2 -1
- package/packages/motion/src/moves/slamWords.ts +14 -7
- package/packages/motion/src/moves/sparkTrail.ts +16 -0
- package/packages/motion/src/moves/splitFlap.ts +4 -2
- package/packages/motion/src/moves/stepWords.ts +19 -8
- package/packages/motion/src/moves/tickerRows.ts +13 -9
- package/packages/motion/src/moves/tokenPicker.ts +4 -3
- package/packages/motion/src/moves/wordWall.ts +23 -21
- package/packages/motion/src/moves/worldRoll.ts +2 -1
- package/packages/motion/src/transition3d/index.ts +10 -3
- package/packages/motion/src/transition3d/rig.ts +107 -9
- package/packages/motion/src/transition3d/shatter.ts +5 -2
- package/packages/motion/src/transition3d/space.ts +173 -0
- package/packages/motion/src/transition3d/whip.ts +19 -6
- package/packages/motion/src/transition3d/world.ts +54 -0
- package/packages/motion/src/transitions2d/catalog.ts +1 -1
- package/packages/patterns/package.json +15 -0
- package/packages/patterns/src/bars/rank.ts +119 -0
- package/packages/patterns/src/before-after/shrink.ts +127 -0
- package/packages/patterns/src/before-after/strike.ts +125 -0
- package/packages/patterns/src/code/terminal.ts +133 -0
- package/packages/patterns/src/compare/bars.ts +142 -0
- package/packages/patterns/src/compare/duel.ts +103 -0
- package/packages/patterns/src/end/lockup.ts +85 -0
- package/packages/patterns/src/end/slam.ts +91 -0
- package/packages/patterns/src/flow/graph.ts +250 -0
- package/packages/patterns/src/hook-number/counter.ts +101 -0
- package/packages/patterns/src/hook-number/roll.ts +179 -0
- package/packages/patterns/src/hook-number/slam.ts +91 -0
- package/packages/patterns/src/index.ts +38 -0
- package/packages/patterns/src/kit.ts +450 -0
- package/packages/patterns/src/limit/gauge.ts +117 -0
- package/packages/patterns/src/list/cards.ts +131 -0
- package/packages/patterns/src/list/cycle.ts +22 -0
- package/packages/patterns/src/media/panels.ts +100 -0
- package/packages/patterns/src/objects.ts +234 -0
- package/packages/patterns/src/quote/karaoke.ts +126 -0
- package/packages/patterns/src/quote/slam.ts +22 -0
- package/packages/patterns/src/screen/focus.ts +85 -0
- package/packages/patterns/src/steps/path.ts +137 -0
- package/packages/patterns/src/steps/stack.ts +111 -0
- package/packages/patterns/src/term-reveal/chips.ts +92 -0
- package/packages/patterns/src/term-reveal/expand.ts +127 -0
- package/packages/patterns/src/timeline/axis.ts +144 -0
- package/packages/patterns/src/title/mask.ts +85 -0
- package/packages/patterns/src/title/slam.ts +23 -0
- package/packages/patterns/src/toggle-sim/switch.ts +92 -0
- package/packages/patterns/src/trend/columns.ts +108 -0
- package/packages/patterns/src/trend/draw.ts +140 -0
- package/packages/patterns/src/types.ts +67 -0
- package/packages/patterns/src/words/moves.ts +42 -0
- package/packages/patterns/src/words/slam.ts +4 -0
- package/packages/plan/src/asks.ts +265 -0
- package/packages/plan/src/brief.ts +136 -7
- package/packages/plan/src/captions.ts +5 -2
- package/packages/plan/src/index.ts +7 -3
- package/packages/plan/src/llm.ts +64 -2
- package/packages/plan/src/look.ts +3 -1
- package/packages/plan/src/plan.ts +70 -14
- package/packages/plan/src/series.ts +76 -0
- package/packages/plan/src/themes.ts +65 -9
- package/packages/plan/src/types.ts +56 -2
- package/packages/themes/kit/THEME-MAKE.md +1 -0
- package/packages/themes/kit/fonts.json +743 -0
- package/packages/themes/package.json +10 -2
- package/packages/themes/src/color.ts +152 -0
- package/packages/themes/src/fx.ts +4 -2
- package/packages/themes/src/index.ts +74 -1
- package/packages/themes/src/look.ts +223 -0
- package/packages/themes/src/name.ts +9 -0
- package/packages/themes/src/palette.ts +194 -0
- package/packages/themes/src/slotkit.ts +92 -0
- package/packages/themes/src/slots.ts +61 -0
- package/packages/themes/src/stage3d.ts +20 -0
- package/packages/themes/src/types.ts +84 -0
- package/packages/themes/src/vary.ts +290 -0
- package/series/og-shorts.json +14 -0
- package/skills/kasaframe/SKILL.md +4 -3
- package/templates/_shared/project/lib/stage.ts +70 -50
- package/templates/_shared/scenes/default.ts +10 -7
- package/templates/_shared/scenes/drop.ts +11 -8
- package/templates/_shared/scenes/end.ts +9 -6
- package/templates/_shared/scenes/hook.ts +8 -6
- package/templates/_shared/scenes/step.ts +13 -4
- package/templates/ad/template.json +20 -1
- package/templates/demo/template.json +11 -0
- package/templates/explainer/template.json +54 -3
- package/templates/launch/template.json +34 -1
- package/templates/mv/scenes/default.ts +11 -8
- package/templates/mv/template.json +4 -2
- package/templates/promo/template.json +42 -1
- package/templates/shorts/scenes/hook.ts +8 -5
- package/templates/shorts/template.json +72 -3
- package/templates/square/template.json +21 -1
- package/themes/blueprint/THEME.md +64 -0
- package/themes/blueprint/effects.ts +570 -0
- package/themes/blueprint/sample/assets/og/logo.svg +12 -0
- package/themes/blueprint/sample/beats.json +1005 -0
- package/themes/blueprint/sample/index.html +11 -0
- package/themes/blueprint/sample/kf.json +59 -0
- package/themes/blueprint/sample/lib/facts.ts +29 -0
- package/themes/blueprint/sample/lib/sheet.ts +55 -0
- package/themes/blueprint/sample/main.ts +9 -0
- package/themes/blueprint/sample/scenes/end.ts +91 -0
- package/themes/blueprint/sample/scenes/gather.ts +75 -0
- package/themes/blueprint/sample/scenes/models.ts +117 -0
- package/themes/blueprint/sample/scenes/price.ts +94 -0
- package/themes/blueprint/sample/style.json +114 -0
- package/themes/blueprint/slots.ts +88 -0
- package/themes/blueprint/still.png +0 -0
- package/themes/blueprint/style.json +114 -0
- package/themes/blueprint/theme.json +137 -0
- package/themes/blueprint/variants/deep-rose-2.json +90 -0
- package/themes/blueprint/variants/deep-rose-suit.json +117 -0
- package/themes/blueprint/variants/deep-rose.json +117 -0
- package/themes/blueprint/variants/navy-coral-2.json +118 -0
- package/themes/blueprint/variants/navy-coral-suit.json +118 -0
- package/themes/blueprint/variants/navy-coral.json +128 -0
- package/themes/blueprint/variants/navy-orange-2.json +118 -0
- package/themes/blueprint/variants/navy-orange-3.json +91 -0
- package/themes/blueprint/variants/navy-orange-4.json +128 -0
- package/themes/blueprint/variants/navy-orange-mono.json +128 -0
- package/themes/blueprint/variants/navy-orange-plex.json +128 -0
- package/themes/blueprint/variants/navy-orange-suit.json +118 -0
- package/themes/blueprint/variants/navy-orange.json +118 -0
- package/themes/blueprint/variants/navy-rose-plex.json +127 -0
- package/themes/blueprint/variants/navy-rose.json +127 -0
- package/themes/cartography/THEME.md +61 -0
- package/themes/cartography/effects.ts +845 -0
- package/themes/cartography/sample/assets/og/logo.svg +12 -0
- package/themes/cartography/sample/beats.json +1005 -0
- package/themes/cartography/sample/index.html +11 -0
- package/themes/cartography/sample/kf.json +59 -0
- package/themes/cartography/sample/lib/facts.ts +29 -0
- package/themes/cartography/sample/lib/map.ts +39 -0
- package/themes/cartography/sample/main.ts +9 -0
- package/themes/cartography/sample/scenes/end.ts +56 -0
- package/themes/cartography/sample/scenes/gather.ts +46 -0
- package/themes/cartography/sample/scenes/models.ts +43 -0
- package/themes/cartography/sample/scenes/price.ts +73 -0
- package/themes/cartography/sample/style.json +103 -0
- package/themes/cartography/slots.ts +87 -0
- package/themes/cartography/still.png +0 -0
- package/themes/cartography/style.json +103 -0
- package/themes/cartography/theme.json +160 -0
- package/themes/cartography/variants/blush-amber.json +128 -0
- package/themes/cartography/variants/blush-indigo.json +128 -0
- package/themes/cartography/variants/blush-pink.json +136 -0
- package/themes/cartography/variants/chalk-plum.json +137 -0
- package/themes/cartography/variants/chalk-sky.json +100 -0
- package/themes/cartography/variants/cocoa-amber.json +128 -0
- package/themes/cartography/variants/deep-plum.json +125 -0
- package/themes/cartography/variants/dusk-coral.json +128 -0
- package/themes/cartography/variants/forest-lime.json +131 -0
- package/themes/cartography/variants/frost-teal.json +128 -0
- package/themes/cartography/variants/navy-green.json +131 -0
- package/themes/cartography/variants/navy-indigo.json +138 -0
- package/themes/cartography/variants/navy-sky.json +100 -0
- package/themes/cartography/variants/sage-green.json +127 -0
- package/themes/cartography/variants/wine-teal.json +128 -0
- package/themes/circuit-board/THEME.md +61 -0
- package/themes/circuit-board/effects.ts +576 -0
- package/themes/circuit-board/pcb.ts +103 -0
- package/themes/circuit-board/sample/assets/og/logo.svg +12 -0
- package/themes/circuit-board/sample/beats.json +1005 -0
- package/themes/circuit-board/sample/index.html +11 -0
- package/themes/circuit-board/sample/kf.json +59 -0
- package/themes/circuit-board/sample/lib/facts.ts +29 -0
- package/themes/circuit-board/sample/lib/kit.ts +45 -0
- package/themes/circuit-board/sample/main.ts +9 -0
- package/themes/circuit-board/sample/scenes/end.ts +102 -0
- package/themes/circuit-board/sample/scenes/gather.ts +76 -0
- package/themes/circuit-board/sample/scenes/models.ts +101 -0
- package/themes/circuit-board/sample/scenes/price.ts +109 -0
- package/themes/circuit-board/sample/style.json +104 -0
- package/themes/circuit-board/slots.ts +108 -0
- package/themes/circuit-board/still.png +0 -0
- package/themes/circuit-board/style.json +104 -0
- package/themes/circuit-board/theme.json +149 -0
- package/themes/circuit-board/variants/deep-gold-plex.json +133 -0
- package/themes/circuit-board/variants/deep-gold.json +123 -0
- package/themes/circuit-board/variants/dusk-gold-grain.json +138 -0
- package/themes/circuit-board/variants/dusk-gold-pretendard.json +118 -0
- package/themes/circuit-board/variants/dusk-gold.json +97 -0
- package/themes/circuit-board/variants/forest-gold-2.json +96 -0
- package/themes/circuit-board/variants/forest-gold-grain.json +129 -0
- package/themes/circuit-board/variants/forest-gold-mono.json +124 -0
- package/themes/circuit-board/variants/forest-gold.json +128 -0
- package/themes/circuit-board/variants/navy-gold-grain.json +124 -0
- package/themes/circuit-board/variants/navy-gold.json +101 -0
- package/themes/circuit-board/variants/wine-gold-grain.json +128 -0
- package/themes/circuit-board/variants/wine-gold-plex.json +133 -0
- package/themes/circuit-board/variants/wine-gold-pretendard.json +118 -0
- package/themes/circuit-board/variants/wine-gold.json +128 -0
- package/themes/clay-toy/THEME.md +73 -0
- package/themes/clay-toy/effects.ts +643 -0
- package/themes/clay-toy/glyphs.ts +32 -0
- package/themes/clay-toy/sample/assets/og/logo.svg +12 -0
- package/themes/clay-toy/sample/beats.json +1005 -0
- package/themes/clay-toy/sample/index.html +11 -0
- package/themes/clay-toy/sample/kf.json +59 -0
- package/themes/clay-toy/sample/lib/clay.ts +20 -0
- package/themes/clay-toy/sample/lib/facts.ts +29 -0
- package/themes/clay-toy/sample/main.ts +9 -0
- package/themes/clay-toy/sample/scenes/end.ts +81 -0
- package/themes/clay-toy/sample/scenes/gather.ts +53 -0
- package/themes/clay-toy/sample/scenes/models.ts +77 -0
- package/themes/clay-toy/sample/scenes/price.ts +91 -0
- package/themes/clay-toy/sample/style.json +101 -0
- package/themes/clay-toy/slots.ts +132 -0
- package/themes/clay-toy/still.png +0 -0
- package/themes/clay-toy/style.json +101 -0
- package/themes/clay-toy/theme.json +146 -0
- package/themes/clay-toy/variants/blush-coral-grain.json +126 -0
- package/themes/clay-toy/variants/blush-coral.json +123 -0
- package/themes/clay-toy/variants/chalk-indigo.json +97 -0
- package/themes/clay-toy/variants/chalk-jade.json +125 -0
- package/themes/clay-toy/variants/chalk-teal.json +120 -0
- package/themes/clay-toy/variants/frost-orange.json +125 -0
- package/themes/clay-toy/variants/frost-sky-grain.json +126 -0
- package/themes/clay-toy/variants/frost-sky.json +121 -0
- package/themes/clay-toy/variants/frost-teal.json +120 -0
- package/themes/clay-toy/variants/lilac-green.json +120 -0
- package/themes/clay-toy/variants/lilac-plum-round.json +120 -0
- package/themes/clay-toy/variants/lilac-plum.json +124 -0
- package/themes/clay-toy/variants/sage-indigo.json +125 -0
- package/themes/clay-toy/variants/sage-magenta.json +119 -0
- package/themes/clay-toy/variants/sand-amber.json +125 -0
- package/themes/conveyor-factory/THEME.md +71 -0
- package/themes/conveyor-factory/effects.ts +744 -0
- package/themes/conveyor-factory/sample/assets/og/logo.svg +12 -0
- package/themes/conveyor-factory/sample/beats.json +1005 -0
- package/themes/conveyor-factory/sample/index.html +11 -0
- package/themes/conveyor-factory/sample/kf.json +59 -0
- package/themes/conveyor-factory/sample/lib/factory.ts +48 -0
- package/themes/conveyor-factory/sample/lib/facts.ts +29 -0
- package/themes/conveyor-factory/sample/main.ts +9 -0
- package/themes/conveyor-factory/sample/scenes/end.ts +44 -0
- package/themes/conveyor-factory/sample/scenes/gather.ts +47 -0
- package/themes/conveyor-factory/sample/scenes/models.ts +91 -0
- package/themes/conveyor-factory/sample/scenes/price.ts +77 -0
- package/themes/conveyor-factory/sample/style.json +107 -0
- package/themes/conveyor-factory/slots.ts +121 -0
- package/themes/conveyor-factory/still.png +0 -0
- package/themes/conveyor-factory/style.json +107 -0
- package/themes/conveyor-factory/theme.json +142 -0
- package/themes/conveyor-factory/variants/cocoa-gold.json +125 -0
- package/themes/conveyor-factory/variants/dusk-gold.json +135 -0
- package/themes/conveyor-factory/variants/forest-gold.json +135 -0
- package/themes/conveyor-factory/variants/navy-amber.json +93 -0
- package/themes/conveyor-factory/variants/navy-gold.json +120 -0
- package/themes/conveyor-factory/variants/slate-amber-2.json +120 -0
- package/themes/conveyor-factory/variants/slate-amber-grain.json +125 -0
- package/themes/conveyor-factory/variants/slate-amber-suit.json +120 -0
- package/themes/conveyor-factory/variants/slate-amber.json +125 -0
- package/themes/conveyor-factory/variants/slate-gold-bold.json +120 -0
- package/themes/conveyor-factory/variants/slate-gold.json +120 -0
- package/themes/data-journal/THEME.md +74 -0
- package/themes/data-journal/effects.ts +570 -0
- package/themes/data-journal/sample/assets/og/logo.svg +12 -0
- package/themes/data-journal/sample/beats.json +1005 -0
- package/themes/data-journal/sample/index.html +11 -0
- package/themes/data-journal/sample/kf.json +59 -0
- package/themes/data-journal/sample/lib/facts.ts +29 -0
- package/themes/data-journal/sample/lib/page.ts +25 -0
- package/themes/data-journal/sample/main.ts +9 -0
- package/themes/data-journal/sample/scenes/end.ts +69 -0
- package/themes/data-journal/sample/scenes/gather.ts +58 -0
- package/themes/data-journal/sample/scenes/models.ts +51 -0
- package/themes/data-journal/sample/scenes/price.ts +73 -0
- package/themes/data-journal/sample/style.json +114 -0
- package/themes/data-journal/slots.ts +119 -0
- package/themes/data-journal/still.png +0 -0
- package/themes/data-journal/style.json +114 -0
- package/themes/data-journal/theme.json +140 -0
- package/themes/data-journal/variants/blush-green.json +129 -0
- package/themes/data-journal/variants/chalk-magenta.json +138 -0
- package/themes/data-journal/variants/cocoa-amber.json +140 -0
- package/themes/data-journal/variants/cocoa-sky.json +130 -0
- package/themes/data-journal/variants/deep-coral.json +135 -0
- package/themes/data-journal/variants/dusk-plum.json +132 -0
- package/themes/data-journal/variants/forest-green.json +138 -0
- package/themes/data-journal/variants/frost-indigo.json +141 -0
- package/themes/data-journal/variants/lilac-amber.json +141 -0
- package/themes/data-journal/variants/navy-indigo.json +131 -0
- package/themes/data-journal/variants/navy-lime.json +128 -0
- package/themes/data-journal/variants/snow-sky.json +125 -0
- package/themes/data-journal/variants/wine-indigo.json +129 -0
- package/themes/data-journal/variants/wine-magenta.json +138 -0
- package/themes/data-journal/variants/wine-teal.json +97 -0
- package/themes/debug-hud/slots.ts +99 -0
- package/themes/debug-hud/theme.json +56 -0
- package/themes/debug-hud/variants/cocoa-gold.json +113 -0
- package/themes/debug-hud/variants/cocoa-teal.json +119 -0
- package/themes/debug-hud/variants/deep-cyan.json +85 -0
- package/themes/debug-hud/variants/deep-teal-scan.json +118 -0
- package/themes/debug-hud/variants/deep-teal.json +112 -0
- package/themes/debug-hud/variants/dusk-plum.json +116 -0
- package/themes/debug-hud/variants/dusk-violet.json +112 -0
- package/themes/debug-hud/variants/forest-amber.json +86 -0
- package/themes/debug-hud/variants/forest-lime.json +117 -0
- package/themes/debug-hud/variants/forest-magenta.json +111 -0
- package/themes/debug-hud/variants/navy-jade.json +79 -0
- package/themes/debug-hud/variants/slate-green.json +112 -0
- package/themes/debug-hud/variants/wine-gold.json +119 -0
- package/themes/debug-hud/variants/wine-jade.json +83 -0
- package/themes/debug-hud/variants/wine-sky.json +112 -0
- package/themes/depth-flight/THEME.md +54 -0
- package/themes/depth-flight/effects.ts +396 -0
- package/themes/depth-flight/sample/assets/og/logo.svg +12 -0
- package/themes/depth-flight/sample/beats.json +1005 -0
- package/themes/depth-flight/sample/index.html +11 -0
- package/themes/depth-flight/sample/kf.json +59 -0
- package/themes/depth-flight/sample/lib/facts.ts +29 -0
- package/themes/depth-flight/sample/lib/fly.ts +15 -0
- package/themes/depth-flight/sample/main.ts +9 -0
- package/themes/depth-flight/sample/scenes/end.ts +51 -0
- package/themes/depth-flight/sample/scenes/gather.ts +40 -0
- package/themes/depth-flight/sample/scenes/models.ts +75 -0
- package/themes/depth-flight/sample/scenes/price.ts +50 -0
- package/themes/depth-flight/sample/style.json +94 -0
- package/themes/depth-flight/slots.ts +196 -0
- package/themes/depth-flight/still.png +0 -0
- package/themes/depth-flight/style.json +94 -0
- package/themes/depth-flight/theme.json +119 -0
- package/themes/depth-flight/variants/cocoa-cyan.json +121 -0
- package/themes/depth-flight/variants/cocoa-indigo.json +121 -0
- package/themes/depth-flight/variants/cocoa-violet.json +122 -0
- package/themes/depth-flight/variants/deep-sky.json +126 -0
- package/themes/depth-flight/variants/dusk-violet-bold.json +117 -0
- package/themes/depth-flight/variants/dusk-violet.json +132 -0
- package/themes/depth-flight/variants/forest-blue.json +116 -0
- package/themes/depth-flight/variants/forest-cyan.json +122 -0
- package/themes/depth-flight/variants/navy-sky-grain.json +122 -0
- package/themes/depth-flight/variants/navy-sky.json +116 -0
- package/themes/depth-flight/variants/night-teal.json +116 -0
- package/themes/depth-flight/variants/slate-cyan.json +127 -0
- package/themes/depth-flight/variants/slate-indigo.json +116 -0
- package/themes/depth-flight/variants/slate-sky.json +94 -0
- package/themes/depth-flight/variants/slate-violet.json +121 -0
- package/themes/film-reel/THEME.md +60 -0
- package/themes/film-reel/effects.ts +477 -0
- package/themes/film-reel/sample/assets/og/logo.svg +12 -0
- package/themes/film-reel/sample/beats.json +1005 -0
- package/themes/film-reel/sample/index.html +11 -0
- package/themes/film-reel/sample/kf.json +59 -0
- package/themes/film-reel/sample/lib/facts.ts +29 -0
- package/themes/film-reel/sample/lib/reel.ts +9 -0
- package/themes/film-reel/sample/main.ts +9 -0
- package/themes/film-reel/sample/scenes/end.ts +31 -0
- package/themes/film-reel/sample/scenes/gather.ts +40 -0
- package/themes/film-reel/sample/scenes/models.ts +37 -0
- package/themes/film-reel/sample/scenes/price.ts +63 -0
- package/themes/film-reel/sample/style.json +103 -0
- package/themes/film-reel/slots.ts +75 -0
- package/themes/film-reel/still.png +0 -0
- package/themes/film-reel/style.json +103 -0
- package/themes/film-reel/theme.json +142 -0
- package/themes/film-reel/variants/chalk-amber.json +124 -0
- package/themes/film-reel/variants/chalk-pink.json +123 -0
- package/themes/film-reel/variants/cream-violet.json +121 -0
- package/themes/film-reel/variants/frost-blue.json +126 -0
- package/themes/film-reel/variants/frost-green.json +123 -0
- package/themes/film-reel/variants/frost-indigo.json +121 -0
- package/themes/film-reel/variants/frost-jade.json +120 -0
- package/themes/film-reel/variants/frost-plum.json +120 -0
- package/themes/film-reel/variants/frost-teal.json +93 -0
- package/themes/film-reel/variants/lilac-gold.json +120 -0
- package/themes/film-reel/variants/lilac-jade.json +123 -0
- package/themes/film-reel/variants/lilac-magenta.json +125 -0
- package/themes/film-reel/variants/lilac-violet.json +122 -0
- package/themes/film-reel/variants/sand-cyan.json +124 -0
- package/themes/film-reel/variants/sand-lime.json +96 -0
- package/themes/glass-light/THEME.md +55 -0
- package/themes/glass-light/effects.ts +433 -0
- package/themes/glass-light/sample/assets/og/logo.svg +12 -0
- package/themes/glass-light/sample/beats.json +1005 -0
- package/themes/glass-light/sample/index.html +11 -0
- package/themes/glass-light/sample/kf.json +59 -0
- package/themes/glass-light/sample/lib/facts.ts +29 -0
- package/themes/glass-light/sample/lib/glass.ts +81 -0
- package/themes/glass-light/sample/main.ts +9 -0
- package/themes/glass-light/sample/scenes/end.ts +43 -0
- package/themes/glass-light/sample/scenes/gather.ts +38 -0
- package/themes/glass-light/sample/scenes/models.ts +46 -0
- package/themes/glass-light/sample/scenes/price.ts +46 -0
- package/themes/glass-light/sample/style.json +94 -0
- package/themes/glass-light/slots.ts +198 -0
- package/themes/glass-light/still.png +0 -0
- package/themes/glass-light/style.json +94 -0
- package/themes/glass-light/theme.json +119 -0
- package/themes/glass-light/variants/blush-coral.json +116 -0
- package/themes/glass-light/variants/blush-orange.json +115 -0
- package/themes/glass-light/variants/blush-pink.json +119 -0
- package/themes/glass-light/variants/blush-plum.json +115 -0
- package/themes/glass-light/variants/blush-teal.json +115 -0
- package/themes/glass-light/variants/cream-blue.json +125 -0
- package/themes/glass-light/variants/cream-pink.json +87 -0
- package/themes/glass-light/variants/cream-violet.json +119 -0
- package/themes/glass-light/variants/frost-green.json +115 -0
- package/themes/glass-light/variants/frost-sky-suit.json +115 -0
- package/themes/glass-light/variants/frost-sky.json +121 -0
- package/themes/glass-light/variants/lilac-gold.json +126 -0
- package/themes/glass-light/variants/lilac-plum.json +114 -0
- package/themes/glass-light/variants/sage-green.json +119 -0
- package/themes/glass-light/variants/sage-rose.json +114 -0
- package/themes/ink-wash/THEME.md +59 -0
- package/themes/ink-wash/effects.ts +574 -0
- package/themes/ink-wash/sample/assets/og/logo.svg +12 -0
- package/themes/ink-wash/sample/beats.json +1005 -0
- package/themes/ink-wash/sample/index.html +11 -0
- package/themes/ink-wash/sample/kf.json +59 -0
- package/themes/ink-wash/sample/lib/facts.ts +29 -0
- package/themes/ink-wash/sample/lib/ink.ts +35 -0
- package/themes/ink-wash/sample/main.ts +9 -0
- package/themes/ink-wash/sample/scenes/end.ts +72 -0
- package/themes/ink-wash/sample/scenes/gather.ts +53 -0
- package/themes/ink-wash/sample/scenes/models.ts +58 -0
- package/themes/ink-wash/sample/scenes/price.ts +85 -0
- package/themes/ink-wash/sample/style.json +108 -0
- package/themes/ink-wash/slots.ts +150 -0
- package/themes/ink-wash/still.png +0 -0
- package/themes/ink-wash/style.json +108 -0
- package/themes/ink-wash/theme.json +131 -0
- package/themes/ink-wash/variants/blush-orange.json +125 -0
- package/themes/ink-wash/variants/blush-rose.json +124 -0
- package/themes/ink-wash/variants/chalk-coral-grain.json +125 -0
- package/themes/ink-wash/variants/chalk-coral-serif.json +118 -0
- package/themes/ink-wash/variants/chalk-coral.json +120 -0
- package/themes/ink-wash/variants/chalk-orange-grain.json +97 -0
- package/themes/ink-wash/variants/chalk-orange-serif.json +120 -0
- package/themes/ink-wash/variants/chalk-orange.json +120 -0
- package/themes/ink-wash/variants/frost-coral.json +119 -0
- package/themes/ink-wash/variants/frost-rose.json +91 -0
- package/themes/ink-wash/variants/lilac-coral.json +96 -0
- package/themes/ink-wash/variants/sage-coral.json +119 -0
- package/themes/ink-wash/variants/sage-rose.json +119 -0
- package/themes/ink-wash/variants/sand-coral.json +125 -0
- package/themes/ink-wash/variants/sand-orange.json +120 -0
- package/themes/iso-diorama/THEME.md +54 -0
- package/themes/iso-diorama/effects.ts +374 -0
- package/themes/iso-diorama/sample/assets/og/logo.svg +12 -0
- package/themes/iso-diorama/sample/beats.json +1005 -0
- package/themes/iso-diorama/sample/index.html +11 -0
- package/themes/iso-diorama/sample/kf.json +59 -0
- package/themes/iso-diorama/sample/lib/facts.ts +29 -0
- package/themes/iso-diorama/sample/lib/iso.ts +22 -0
- package/themes/iso-diorama/sample/main.ts +9 -0
- package/themes/iso-diorama/sample/scenes/end.ts +41 -0
- package/themes/iso-diorama/sample/scenes/gather.ts +39 -0
- package/themes/iso-diorama/sample/scenes/models.ts +55 -0
- package/themes/iso-diorama/sample/scenes/price.ts +49 -0
- package/themes/iso-diorama/sample/style.json +98 -0
- package/themes/iso-diorama/slots.ts +222 -0
- package/themes/iso-diorama/still.png +0 -0
- package/themes/iso-diorama/style.json +98 -0
- package/themes/iso-diorama/theme.json +131 -0
- package/themes/iso-diorama/variants/chalk-plum.json +121 -0
- package/themes/iso-diorama/variants/cocoa-gold.json +93 -0
- package/themes/iso-diorama/variants/cocoa-indigo.json +122 -0
- package/themes/iso-diorama/variants/cocoa-rose.json +125 -0
- package/themes/iso-diorama/variants/deep-green.json +125 -0
- package/themes/iso-diorama/variants/deep-plum.json +120 -0
- package/themes/iso-diorama/variants/dusk-blue.json +126 -0
- package/themes/iso-diorama/variants/dusk-coral.json +122 -0
- package/themes/iso-diorama/variants/dusk-jade.json +121 -0
- package/themes/iso-diorama/variants/forest-cyan.json +127 -0
- package/themes/iso-diorama/variants/frost-blue.json +126 -0
- package/themes/iso-diorama/variants/frost-green.json +126 -0
- package/themes/iso-diorama/variants/frost-orange.json +125 -0
- package/themes/iso-diorama/variants/frost-teal.json +123 -0
- package/themes/iso-diorama/variants/navy-amber.json +125 -0
- package/themes/isotype/THEME.md +58 -0
- package/themes/isotype/effects.ts +297 -0
- package/themes/isotype/kit.ts +102 -0
- package/themes/isotype/sample/assets/og/logo.svg +12 -0
- package/themes/isotype/sample/beats.json +1005 -0
- package/themes/isotype/sample/index.html +11 -0
- package/themes/isotype/sample/kf.json +59 -0
- package/themes/isotype/sample/lib/chart.ts +47 -0
- package/themes/isotype/sample/lib/facts.ts +29 -0
- package/themes/isotype/sample/main.ts +9 -0
- package/themes/isotype/sample/scenes/end.ts +80 -0
- package/themes/isotype/sample/scenes/gather.ts +65 -0
- package/themes/isotype/sample/scenes/models.ts +75 -0
- package/themes/isotype/sample/scenes/price.ts +90 -0
- package/themes/isotype/sample/style.json +101 -0
- package/themes/isotype/slots.ts +74 -0
- package/themes/isotype/still.png +0 -0
- package/themes/isotype/style.json +101 -0
- package/themes/isotype/theme.json +140 -0
- package/themes/isotype/variants/blush-rose.json +127 -0
- package/themes/isotype/variants/chalk-amber.json +123 -0
- package/themes/isotype/variants/chalk-coral-bold.json +118 -0
- package/themes/isotype/variants/chalk-coral.json +117 -0
- package/themes/isotype/variants/chalk-orange.json +128 -0
- package/themes/isotype/variants/frost-amber-plex.json +128 -0
- package/themes/isotype/variants/frost-amber.json +123 -0
- package/themes/isotype/variants/frost-coral-grain.json +95 -0
- package/themes/isotype/variants/frost-coral.json +123 -0
- package/themes/isotype/variants/frost-orange.json +123 -0
- package/themes/isotype/variants/lilac-rose.json +127 -0
- package/themes/isotype/variants/sage-coral.json +90 -0
- package/themes/isotype/variants/sand-amber.json +118 -0
- package/themes/isotype/variants/sand-orange.json +128 -0
- package/themes/kawaii-sticker/THEME.md +44 -0
- package/themes/kawaii-sticker/effects.ts +412 -0
- package/themes/kawaii-sticker/sample/assets/stickers/bolt.png +0 -0
- package/themes/kawaii-sticker/sample/assets/stickers/bubble.png +0 -0
- package/themes/kawaii-sticker/sample/assets/stickers/clock.png +0 -0
- package/themes/kawaii-sticker/sample/assets/stickers/coin.png +0 -0
- package/themes/kawaii-sticker/sample/assets/stickers/moon.png +0 -0
- package/themes/kawaii-sticker/sample/assets/stickers/og-logo.svg +12 -0
- package/themes/kawaii-sticker/sample/assets/stickers/server.png +0 -0
- package/themes/kawaii-sticker/sample/beats.json +1 -0
- package/themes/kawaii-sticker/sample/index.html +11 -0
- package/themes/kawaii-sticker/sample/kf.json +66 -0
- package/themes/kawaii-sticker/sample/lib/og.ts +54 -0
- package/themes/kawaii-sticker/sample/main.ts +9 -0
- package/themes/kawaii-sticker/sample/scenes/end.ts +37 -0
- package/themes/kawaii-sticker/sample/scenes/gather.ts +50 -0
- package/themes/kawaii-sticker/sample/scenes/models.ts +43 -0
- package/themes/kawaii-sticker/sample/scenes/one.ts +45 -0
- package/themes/kawaii-sticker/sample/scenes/price.ts +47 -0
- package/themes/kawaii-sticker/sample/style.json +99 -0
- package/themes/kawaii-sticker/slots.ts +95 -0
- package/themes/kawaii-sticker/still.png +0 -0
- package/themes/kawaii-sticker/style.json +99 -0
- package/themes/kawaii-sticker/theme.json +145 -0
- package/themes/kawaii-sticker/variants/blush-coral.json +134 -0
- package/themes/kawaii-sticker/variants/blush-teal.json +129 -0
- package/themes/kawaii-sticker/variants/blush-violet.json +134 -0
- package/themes/kawaii-sticker/variants/cream-gold.json +135 -0
- package/themes/kawaii-sticker/variants/deep-jade.json +134 -0
- package/themes/kawaii-sticker/variants/dusk-green.json +134 -0
- package/themes/kawaii-sticker/variants/dusk-indigo.json +130 -0
- package/themes/kawaii-sticker/variants/dusk-sky.json +135 -0
- package/themes/kawaii-sticker/variants/dusk-teal.json +134 -0
- package/themes/kawaii-sticker/variants/frost-blue.json +135 -0
- package/themes/kawaii-sticker/variants/frost-plum.json +133 -0
- package/themes/kawaii-sticker/variants/lilac-violet.json +133 -0
- package/themes/kawaii-sticker/variants/navy-gold.json +134 -0
- package/themes/kawaii-sticker/variants/navy-plum.json +134 -0
- package/themes/kawaii-sticker/variants/sage-sky.json +107 -0
- package/themes/lab-notebook/THEME.md +56 -0
- package/themes/lab-notebook/effects.ts +423 -0
- package/themes/lab-notebook/kit.ts +84 -0
- package/themes/lab-notebook/sample/assets/og/logo.svg +12 -0
- package/themes/lab-notebook/sample/beats.json +1005 -0
- package/themes/lab-notebook/sample/index.html +11 -0
- package/themes/lab-notebook/sample/kf.json +59 -0
- package/themes/lab-notebook/sample/lib/facts.ts +29 -0
- package/themes/lab-notebook/sample/lib/note.ts +53 -0
- package/themes/lab-notebook/sample/main.ts +9 -0
- package/themes/lab-notebook/sample/scenes/end.ts +127 -0
- package/themes/lab-notebook/sample/scenes/gather.ts +83 -0
- package/themes/lab-notebook/sample/scenes/models.ts +73 -0
- package/themes/lab-notebook/sample/scenes/price.ts +89 -0
- package/themes/lab-notebook/sample/style.json +109 -0
- package/themes/lab-notebook/slots.ts +75 -0
- package/themes/lab-notebook/still.png +0 -0
- package/themes/lab-notebook/style.json +109 -0
- package/themes/lab-notebook/theme.json +141 -0
- package/themes/lab-notebook/variants/blush-orange.json +125 -0
- package/themes/lab-notebook/variants/chalk-coral.json +126 -0
- package/themes/lab-notebook/variants/chalk-orange.json +129 -0
- package/themes/lab-notebook/variants/chalk-rose-2.json +96 -0
- package/themes/lab-notebook/variants/chalk-rose.json +125 -0
- package/themes/lab-notebook/variants/frost-orange.json +101 -0
- package/themes/lab-notebook/variants/frost-rose-grain.json +101 -0
- package/themes/lab-notebook/variants/frost-rose.json +96 -0
- package/themes/lab-notebook/variants/lilac-rose-2.json +96 -0
- package/themes/lab-notebook/variants/lilac-rose.json +128 -0
- package/themes/lab-notebook/variants/sage-rose.json +124 -0
- package/themes/lab-notebook/variants/sand-orange-grain.json +101 -0
- package/themes/lab-notebook/variants/sand-orange.json +129 -0
- package/themes/lab-notebook/variants/snow-orange.json +129 -0
- package/themes/lab-notebook/variants/snow-rose.json +124 -0
- package/themes/manga-panel/THEME.md +60 -0
- package/themes/manga-panel/effects.ts +791 -0
- package/themes/manga-panel/sample/assets/og/logo.svg +12 -0
- package/themes/manga-panel/sample/beats.json +1005 -0
- package/themes/manga-panel/sample/index.html +11 -0
- package/themes/manga-panel/sample/kf.json +59 -0
- package/themes/manga-panel/sample/lib/facts.ts +29 -0
- package/themes/manga-panel/sample/lib/manga.ts +58 -0
- package/themes/manga-panel/sample/main.ts +9 -0
- package/themes/manga-panel/sample/scenes/end.ts +96 -0
- package/themes/manga-panel/sample/scenes/gather.ts +100 -0
- package/themes/manga-panel/sample/scenes/models.ts +96 -0
- package/themes/manga-panel/sample/scenes/price.ts +154 -0
- package/themes/manga-panel/sample/style.json +105 -0
- package/themes/manga-panel/slots.ts +127 -0
- package/themes/manga-panel/still.png +0 -0
- package/themes/manga-panel/style.json +105 -0
- package/themes/manga-panel/theme.json +148 -0
- package/themes/manga-panel/variants/chalk-cyan-dots.json +122 -0
- package/themes/manga-panel/variants/chalk-cyan.json +122 -0
- package/themes/manga-panel/variants/chalk-magenta.json +121 -0
- package/themes/manga-panel/variants/chalk-orange-bold.json +117 -0
- package/themes/manga-panel/variants/chalk-orange.json +122 -0
- package/themes/manga-panel/variants/chalk-rose-dots.json +121 -0
- package/themes/manga-panel/variants/chalk-rose.json +116 -0
- package/themes/manga-panel/variants/chalk-sky-bold.json +117 -0
- package/themes/manga-panel/variants/chalk-sky.json +117 -0
- package/themes/manga-panel/variants/snow-cyan.json +117 -0
- package/themes/manga-panel/variants/snow-magenta-dots.json +121 -0
- package/themes/manga-panel/variants/snow-magenta.json +116 -0
- package/themes/manga-panel/variants/snow-rose-dots.json +121 -0
- package/themes/manga-panel/variants/snow-rose.json +116 -0
- package/themes/manga-panel/variants/snow-sky.json +95 -0
- package/themes/marble-run/THEME.md +73 -0
- package/themes/marble-run/effects.ts +678 -0
- package/themes/marble-run/sample/assets/og/logo.svg +12 -0
- package/themes/marble-run/sample/beats.json +1005 -0
- package/themes/marble-run/sample/index.html +11 -0
- package/themes/marble-run/sample/kf.json +59 -0
- package/themes/marble-run/sample/lib/facts.ts +29 -0
- package/themes/marble-run/sample/lib/run.ts +30 -0
- package/themes/marble-run/sample/main.ts +9 -0
- package/themes/marble-run/sample/scenes/end.ts +58 -0
- package/themes/marble-run/sample/scenes/gather.ts +51 -0
- package/themes/marble-run/sample/scenes/models.ts +73 -0
- package/themes/marble-run/sample/scenes/price.ts +51 -0
- package/themes/marble-run/sample/style.json +109 -0
- package/themes/marble-run/slots.ts +116 -0
- package/themes/marble-run/still.png +0 -0
- package/themes/marble-run/style.json +109 -0
- package/themes/marble-run/theme.json +145 -0
- package/themes/marble-run/variants/cocoa-amber.json +128 -0
- package/themes/marble-run/variants/cocoa-orange.json +142 -0
- package/themes/marble-run/variants/dusk-orange.json +133 -0
- package/themes/marble-run/variants/forest-gold.json +128 -0
- package/themes/marble-run/variants/navy-gold.json +137 -0
- package/themes/marble-run/variants/night-gold-grain.json +105 -0
- package/themes/marble-run/variants/night-gold.json +137 -0
- package/themes/marble-run/variants/slate-gold-grain.json +133 -0
- package/themes/marble-run/variants/slate-gold.json +133 -0
- package/themes/marble-run/variants/slate-orange-grain.json +105 -0
- package/themes/marble-run/variants/slate-orange-mono.json +128 -0
- package/themes/marble-run/variants/slate-orange-serif.json +128 -0
- package/themes/marble-run/variants/slate-orange.json +131 -0
- package/themes/neon-sign/THEME.md +59 -0
- package/themes/neon-sign/effects.ts +424 -0
- package/themes/neon-sign/sample/assets/og/logo.svg +12 -0
- package/themes/neon-sign/sample/beats.json +1005 -0
- package/themes/neon-sign/sample/index.html +11 -0
- package/themes/neon-sign/sample/kf.json +59 -0
- package/themes/neon-sign/sample/lib/facts.ts +29 -0
- package/themes/neon-sign/sample/lib/neon.ts +50 -0
- package/themes/neon-sign/sample/main.ts +9 -0
- package/themes/neon-sign/sample/scenes/end.ts +62 -0
- package/themes/neon-sign/sample/scenes/gather.ts +59 -0
- package/themes/neon-sign/sample/scenes/models.ts +63 -0
- package/themes/neon-sign/sample/scenes/price.ts +74 -0
- package/themes/neon-sign/sample/style.json +104 -0
- package/themes/neon-sign/slots.ts +110 -0
- package/themes/neon-sign/still.png +0 -0
- package/themes/neon-sign/style.json +104 -0
- package/themes/neon-sign/theme.json +136 -0
- package/themes/neon-sign/variants/deep-plum.json +121 -0
- package/themes/neon-sign/variants/deep-violet.json +121 -0
- package/themes/neon-sign/variants/dusk-plum.json +121 -0
- package/themes/neon-sign/variants/forest-magenta.json +126 -0
- package/themes/neon-sign/variants/forest-plum.json +98 -0
- package/themes/neon-sign/variants/night-coral.json +122 -0
- package/themes/neon-sign/variants/night-magenta-round.json +121 -0
- package/themes/neon-sign/variants/night-magenta.json +126 -0
- package/themes/neon-sign/variants/night-pink.json +125 -0
- package/themes/neon-sign/variants/night-violet.json +126 -0
- package/themes/neon-sign/variants/slate-plum.json +120 -0
- package/themes/neon-sign/variants/slate-violet.json +127 -0
- package/themes/neon-sign/variants/wine-coral.json +127 -0
- package/themes/neon-sign/variants/wine-pink.json +125 -0
- package/themes/neon-sign/variants/wine-plum.json +126 -0
- package/themes/newspaper/THEME.md +67 -0
- package/themes/newspaper/effects.ts +347 -0
- package/themes/newspaper/sample/assets/og/logo.svg +12 -0
- package/themes/newspaper/sample/beats.json +1005 -0
- package/themes/newspaper/sample/index.html +11 -0
- package/themes/newspaper/sample/kf.json +59 -0
- package/themes/newspaper/sample/lib/facts.ts +29 -0
- package/themes/newspaper/sample/lib/page.ts +27 -0
- package/themes/newspaper/sample/main.ts +9 -0
- package/themes/newspaper/sample/scenes/end.ts +62 -0
- package/themes/newspaper/sample/scenes/gather.ts +66 -0
- package/themes/newspaper/sample/scenes/models.ts +61 -0
- package/themes/newspaper/sample/scenes/price.ts +103 -0
- package/themes/newspaper/sample/style.json +100 -0
- package/themes/newspaper/slots.ts +73 -0
- package/themes/newspaper/still.png +0 -0
- package/themes/newspaper/style.json +100 -0
- package/themes/newspaper/theme.json +140 -0
- package/themes/newspaper/variants/blush-amber.json +123 -0
- package/themes/newspaper/variants/blush-orange.json +125 -0
- package/themes/newspaper/variants/chalk-cyan.json +119 -0
- package/themes/newspaper/variants/chalk-indigo.json +124 -0
- package/themes/newspaper/variants/chalk-jade.json +95 -0
- package/themes/newspaper/variants/chalk-magenta.json +127 -0
- package/themes/newspaper/variants/frost-plum.json +123 -0
- package/themes/newspaper/variants/frost-sky.json +129 -0
- package/themes/newspaper/variants/frost-violet.json +96 -0
- package/themes/newspaper/variants/lilac-coral.json +124 -0
- package/themes/newspaper/variants/lilac-green.json +127 -0
- package/themes/newspaper/variants/sage-blue.json +124 -0
- package/themes/newspaper/variants/sage-lime.json +117 -0
- package/themes/newspaper/variants/sand-gold.json +124 -0
- package/themes/newspaper/variants/sand-jade.json +123 -0
- package/themes/og-measure/slots.ts +88 -0
- package/themes/og-measure/theme.json +62 -0
- package/themes/og-measure/variants/chalk-orange.json +102 -0
- package/themes/og-measure/variants/cocoa-amber.json +138 -0
- package/themes/og-measure/variants/cocoa-cyan.json +138 -0
- package/themes/og-measure/variants/cocoa-gold.json +129 -0
- package/themes/og-measure/variants/cream-lime.json +137 -0
- package/themes/og-measure/variants/deep-jade.json +100 -0
- package/themes/og-measure/variants/dusk-violet.json +133 -0
- package/themes/og-measure/variants/forest-cyan.json +123 -0
- package/themes/og-measure/variants/frost-amber.json +129 -0
- package/themes/og-measure/variants/frost-cyan.json +133 -0
- package/themes/og-measure/variants/lilac-plum.json +127 -0
- package/themes/og-measure/variants/lilac-violet.json +139 -0
- package/themes/og-measure/variants/sage-green.json +137 -0
- package/themes/og-measure/variants/wine-jade.json +127 -0
- package/themes/og-measure/variants/wine-plum.json +127 -0
- package/themes/orbit-system/THEME.md +77 -0
- package/themes/orbit-system/effects.ts +665 -0
- package/themes/orbit-system/sample/assets/og/logo.svg +12 -0
- package/themes/orbit-system/sample/beats.json +1005 -0
- package/themes/orbit-system/sample/index.html +11 -0
- package/themes/orbit-system/sample/kf.json +59 -0
- package/themes/orbit-system/sample/lib/facts.ts +29 -0
- package/themes/orbit-system/sample/lib/orbit.ts +84 -0
- package/themes/orbit-system/sample/main.ts +9 -0
- package/themes/orbit-system/sample/scenes/end.ts +50 -0
- package/themes/orbit-system/sample/scenes/gather.ts +35 -0
- package/themes/orbit-system/sample/scenes/models.ts +49 -0
- package/themes/orbit-system/sample/scenes/price.ts +57 -0
- package/themes/orbit-system/sample/style.json +108 -0
- package/themes/orbit-system/slots.ts +174 -0
- package/themes/orbit-system/still.png +0 -0
- package/themes/orbit-system/style.json +108 -0
- package/themes/orbit-system/theme.json +142 -0
- package/themes/orbit-system/variants/cocoa-amber.json +122 -0
- package/themes/orbit-system/variants/cocoa-coral.json +127 -0
- package/themes/orbit-system/variants/cocoa-cyan.json +127 -0
- package/themes/orbit-system/variants/deep-cyan.json +132 -0
- package/themes/orbit-system/variants/deep-sky.json +122 -0
- package/themes/orbit-system/variants/dusk-magenta.json +121 -0
- package/themes/orbit-system/variants/dusk-plum-pretendard.json +121 -0
- package/themes/orbit-system/variants/dusk-plum.json +127 -0
- package/themes/orbit-system/variants/dusk-violet.json +122 -0
- package/themes/orbit-system/variants/forest-coral.json +126 -0
- package/themes/orbit-system/variants/forest-plum.json +94 -0
- package/themes/orbit-system/variants/navy-amber.json +127 -0
- package/themes/orbit-system/variants/wine-amber.json +127 -0
- package/themes/orbit-system/variants/wine-coral.json +123 -0
- package/themes/orbit-system/variants/wine-magenta.json +126 -0
- package/themes/origami-fold/THEME.md +74 -0
- package/themes/origami-fold/effects.ts +535 -0
- package/themes/origami-fold/sample/assets/og/logo.svg +12 -0
- package/themes/origami-fold/sample/beats.json +1005 -0
- package/themes/origami-fold/sample/index.html +11 -0
- package/themes/origami-fold/sample/kf.json +59 -0
- package/themes/origami-fold/sample/lib/facts.ts +29 -0
- package/themes/origami-fold/sample/lib/fold.ts +53 -0
- package/themes/origami-fold/sample/main.ts +9 -0
- package/themes/origami-fold/sample/scenes/end.ts +51 -0
- package/themes/origami-fold/sample/scenes/gather.ts +37 -0
- package/themes/origami-fold/sample/scenes/models.ts +46 -0
- package/themes/origami-fold/sample/scenes/price.ts +54 -0
- package/themes/origami-fold/sample/style.json +108 -0
- package/themes/origami-fold/slots.ts +176 -0
- package/themes/origami-fold/still.png +0 -0
- package/themes/origami-fold/style.json +108 -0
- package/themes/origami-fold/theme.json +123 -0
- package/themes/origami-fold/variants/deep-amber-sunflower.json +122 -0
- package/themes/origami-fold/variants/deep-amber.json +122 -0
- package/themes/origami-fold/variants/deep-orange.json +128 -0
- package/themes/origami-fold/variants/forest-coral.json +127 -0
- package/themes/origami-fold/variants/forest-pink.json +123 -0
- package/themes/origami-fold/variants/forest-rose.json +100 -0
- package/themes/origami-fold/variants/frost-amber-grain.json +127 -0
- package/themes/origami-fold/variants/frost-amber-paper.json +128 -0
- package/themes/origami-fold/variants/frost-amber.json +95 -0
- package/themes/origami-fold/variants/sage-coral-grain.json +100 -0
- package/themes/origami-fold/variants/sage-coral-sunflower.json +122 -0
- package/themes/origami-fold/variants/sage-coral.json +128 -0
- package/themes/origami-fold/variants/sage-pink-grain.json +127 -0
- package/themes/origami-fold/variants/sage-pink-round.json +124 -0
- package/themes/origami-fold/variants/sage-pink.json +127 -0
- package/themes/paper-cutout/THEME.md +63 -0
- package/themes/paper-cutout/effects.ts +609 -0
- package/themes/paper-cutout/sample/assets/og/logo.svg +12 -0
- package/themes/paper-cutout/sample/beats.json +1005 -0
- package/themes/paper-cutout/sample/index.html +11 -0
- package/themes/paper-cutout/sample/kf.json +59 -0
- package/themes/paper-cutout/sample/lib/facts.ts +29 -0
- package/themes/paper-cutout/sample/lib/paper.ts +91 -0
- package/themes/paper-cutout/sample/main.ts +9 -0
- package/themes/paper-cutout/sample/scenes/end.ts +54 -0
- package/themes/paper-cutout/sample/scenes/gather.ts +63 -0
- package/themes/paper-cutout/sample/scenes/models.ts +93 -0
- package/themes/paper-cutout/sample/scenes/price.ts +100 -0
- package/themes/paper-cutout/sample/style.json +104 -0
- package/themes/paper-cutout/slots.ts +87 -0
- package/themes/paper-cutout/still.png +0 -0
- package/themes/paper-cutout/style.json +104 -0
- package/themes/paper-cutout/theme.json +144 -0
- package/themes/paper-cutout/variants/blush-coral.json +122 -0
- package/themes/paper-cutout/variants/blush-violet.json +122 -0
- package/themes/paper-cutout/variants/chalk-teal.json +122 -0
- package/themes/paper-cutout/variants/cream-gold.json +122 -0
- package/themes/paper-cutout/variants/frost-blue.json +123 -0
- package/themes/paper-cutout/variants/frost-lime.json +121 -0
- package/themes/paper-cutout/variants/frost-plum.json +122 -0
- package/themes/paper-cutout/variants/lilac-blue.json +123 -0
- package/themes/paper-cutout/variants/lilac-gold.json +122 -0
- package/themes/paper-cutout/variants/sage-cyan.json +122 -0
- package/themes/paper-cutout/variants/sage-green.json +122 -0
- package/themes/paper-cutout/variants/sage-pink.json +122 -0
- package/themes/paper-cutout/variants/sand-blue.json +123 -0
- package/themes/paper-cutout/variants/sand-green.json +121 -0
- package/themes/paper-cutout/variants/sand-plum.json +120 -0
- package/themes/pixel-quest/THEME.md +57 -0
- package/themes/pixel-quest/effects.ts +491 -0
- package/themes/pixel-quest/kit.ts +232 -0
- package/themes/pixel-quest/sample/assets/og/logo.svg +12 -0
- package/themes/pixel-quest/sample/beats.json +1005 -0
- package/themes/pixel-quest/sample/index.html +11 -0
- package/themes/pixel-quest/sample/kf.json +59 -0
- package/themes/pixel-quest/sample/lib/facts.ts +29 -0
- package/themes/pixel-quest/sample/lib/game.ts +71 -0
- package/themes/pixel-quest/sample/lib/logo.ts +51 -0
- package/themes/pixel-quest/sample/main.ts +9 -0
- package/themes/pixel-quest/sample/scenes/end.ts +75 -0
- package/themes/pixel-quest/sample/scenes/gather.ts +65 -0
- package/themes/pixel-quest/sample/scenes/models.ts +104 -0
- package/themes/pixel-quest/sample/scenes/price.ts +118 -0
- package/themes/pixel-quest/sample/style.json +115 -0
- package/themes/pixel-quest/slots.ts +94 -0
- package/themes/pixel-quest/still.png +0 -0
- package/themes/pixel-quest/style.json +115 -0
- package/themes/pixel-quest/theme.json +143 -0
- package/themes/pixel-quest/variants/navy-gold-2.json +98 -0
- package/themes/pixel-quest/variants/navy-gold-3.json +127 -0
- package/themes/pixel-quest/variants/navy-gold-4.json +95 -0
- package/themes/pixel-quest/variants/navy-gold-pixel.json +132 -0
- package/themes/pixel-quest/variants/navy-gold-scan.json +99 -0
- package/themes/pixel-quest/variants/navy-gold.json +131 -0
- package/themes/pixel-quest/variants/navy-lime-2.json +93 -0
- package/themes/pixel-quest/variants/navy-lime-3.json +124 -0
- package/themes/pixel-quest/variants/navy-lime-pixel.json +126 -0
- package/themes/pixel-quest/variants/navy-lime-scan.json +97 -0
- package/themes/pixel-quest/variants/navy-lime.json +130 -0
- package/themes/receipt/THEME.md +72 -0
- package/themes/receipt/effects.ts +257 -0
- package/themes/receipt/sample/assets/og/logo.svg +12 -0
- package/themes/receipt/sample/beats.json +1005 -0
- package/themes/receipt/sample/index.html +11 -0
- package/themes/receipt/sample/kf.json +59 -0
- package/themes/receipt/sample/lib/facts.ts +29 -0
- package/themes/receipt/sample/lib/sheet.ts +52 -0
- package/themes/receipt/sample/main.ts +9 -0
- package/themes/receipt/sample/scenes/end.ts +44 -0
- package/themes/receipt/sample/scenes/gather.ts +57 -0
- package/themes/receipt/sample/scenes/models.ts +48 -0
- package/themes/receipt/sample/scenes/price.ts +64 -0
- package/themes/receipt/sample/style.json +104 -0
- package/themes/receipt/slots.ts +89 -0
- package/themes/receipt/still.png +0 -0
- package/themes/receipt/style.json +104 -0
- package/themes/receipt/theme.json +133 -0
- package/themes/receipt/variants/blush-coral.json +89 -0
- package/themes/receipt/variants/sand-coral-2.json +89 -0
- package/themes/receipt/variants/sand-coral-3.json +89 -0
- package/themes/receipt/variants/sand-coral-4.json +90 -0
- package/themes/receipt/variants/sand-coral-5.json +89 -0
- package/themes/receipt/variants/sand-coral-6.json +88 -0
- package/themes/receipt/variants/sand-coral-7.json +88 -0
- package/themes/receipt/variants/sand-coral-8.json +89 -0
- package/themes/receipt/variants/sand-coral-9.json +89 -0
- package/themes/receipt/variants/sand-coral.json +88 -0
- package/themes/receipt/variants/sand-orange-2.json +89 -0
- package/themes/receipt/variants/sand-orange-3.json +90 -0
- package/themes/receipt/variants/sand-orange-4.json +89 -0
- package/themes/receipt/variants/sand-orange-5.json +89 -0
- package/themes/receipt/variants/sand-orange.json +89 -0
- package/themes/riso-zine/slots.ts +81 -0
- package/themes/riso-zine/theme.json +66 -0
- package/themes/riso-zine/variants/blush-coral.json +120 -0
- package/themes/riso-zine/variants/blush-gold.json +120 -0
- package/themes/riso-zine/variants/blush-pink.json +115 -0
- package/themes/riso-zine/variants/chalk-cyan.json +120 -0
- package/themes/riso-zine/variants/chalk-lime.json +119 -0
- package/themes/riso-zine/variants/cream-amber.json +89 -0
- package/themes/riso-zine/variants/frost-blue.json +119 -0
- package/themes/riso-zine/variants/frost-coral.json +118 -0
- package/themes/riso-zine/variants/frost-cyan.json +120 -0
- package/themes/riso-zine/variants/frost-green.json +120 -0
- package/themes/riso-zine/variants/lilac-plum.json +118 -0
- package/themes/riso-zine/variants/lilac-violet.json +123 -0
- package/themes/riso-zine/variants/sage-green.json +119 -0
- package/themes/riso-zine/variants/sand-jade.json +120 -0
- package/themes/riso-zine/variants/sand-plum.json +113 -0
- package/themes/server-hall/THEME.md +58 -0
- package/themes/server-hall/effects.ts +455 -0
- package/themes/server-hall/kit.ts +138 -0
- package/themes/server-hall/sample/assets/og/logo.svg +12 -0
- package/themes/server-hall/sample/beats.json +1005 -0
- package/themes/server-hall/sample/index.html +11 -0
- package/themes/server-hall/sample/kf.json +59 -0
- package/themes/server-hall/sample/lib/facts.ts +29 -0
- package/themes/server-hall/sample/lib/hall.ts +81 -0
- package/themes/server-hall/sample/main.ts +9 -0
- package/themes/server-hall/sample/scenes/end.ts +57 -0
- package/themes/server-hall/sample/scenes/gather.ts +38 -0
- package/themes/server-hall/sample/scenes/models.ts +49 -0
- package/themes/server-hall/sample/scenes/price.ts +65 -0
- package/themes/server-hall/sample/style.json +107 -0
- package/themes/server-hall/slots.ts +106 -0
- package/themes/server-hall/still.png +0 -0
- package/themes/server-hall/style.json +107 -0
- package/themes/server-hall/theme.json +143 -0
- package/themes/server-hall/variants/navy-indigo.json +140 -0
- package/themes/server-hall/variants/night-indigo.json +120 -0
- package/themes/server-hall/variants/wine-plum.json +130 -0
- package/themes/server-hall/variants/wine-violet.json +103 -0
- package/themes/subway-map/THEME.md +64 -0
- package/themes/subway-map/effects.ts +662 -0
- package/themes/subway-map/sample/assets/og/logo.svg +12 -0
- package/themes/subway-map/sample/beats.json +1005 -0
- package/themes/subway-map/sample/index.html +11 -0
- package/themes/subway-map/sample/kf.json +59 -0
- package/themes/subway-map/sample/lib/facts.ts +29 -0
- package/themes/subway-map/sample/lib/map.ts +58 -0
- package/themes/subway-map/sample/main.ts +9 -0
- package/themes/subway-map/sample/scenes/end.ts +94 -0
- package/themes/subway-map/sample/scenes/gather.ts +64 -0
- package/themes/subway-map/sample/scenes/models.ts +117 -0
- package/themes/subway-map/sample/scenes/price.ts +119 -0
- package/themes/subway-map/sample/style.json +108 -0
- package/themes/subway-map/slots.ts +66 -0
- package/themes/subway-map/still.png +0 -0
- package/themes/subway-map/style.json +108 -0
- package/themes/subway-map/theme.json +161 -0
- package/themes/subway-map/variants/blush-jade.json +131 -0
- package/themes/subway-map/variants/chalk-jade.json +141 -0
- package/themes/subway-map/variants/deep-green.json +131 -0
- package/themes/subway-map/variants/deep-teal.json +132 -0
- package/themes/subway-map/variants/dusk-teal-bold.json +132 -0
- package/themes/subway-map/variants/dusk-teal.json +105 -0
- package/themes/subway-map/variants/forest-green.json +141 -0
- package/themes/subway-map/variants/forest-jade.json +131 -0
- package/themes/subway-map/variants/frost-jade.json +131 -0
- package/themes/subway-map/variants/frost-teal.json +137 -0
- package/themes/subway-map/variants/sage-teal.json +132 -0
- package/themes/subway-map/variants/slate-green.json +136 -0
- package/themes/subway-map/variants/slate-jade.json +131 -0
- package/themes/subway-map/variants/snow-jade.json +136 -0
- package/themes/subway-map/variants/wine-green.json +104 -0
- package/themes/swiss-poster/THEME.md +59 -0
- package/themes/swiss-poster/effects.ts +339 -0
- package/themes/swiss-poster/grid.ts +35 -0
- package/themes/swiss-poster/sample/assets/og/logo.svg +12 -0
- package/themes/swiss-poster/sample/beats.json +1005 -0
- package/themes/swiss-poster/sample/index.html +11 -0
- package/themes/swiss-poster/sample/kf.json +59 -0
- package/themes/swiss-poster/sample/lib/facts.ts +29 -0
- package/themes/swiss-poster/sample/lib/poster.ts +36 -0
- package/themes/swiss-poster/sample/main.ts +9 -0
- package/themes/swiss-poster/sample/scenes/end.ts +70 -0
- package/themes/swiss-poster/sample/scenes/gather.ts +68 -0
- package/themes/swiss-poster/sample/scenes/models.ts +63 -0
- package/themes/swiss-poster/sample/scenes/price.ts +74 -0
- package/themes/swiss-poster/sample/style.json +100 -0
- package/themes/swiss-poster/slots.ts +69 -0
- package/themes/swiss-poster/still.png +0 -0
- package/themes/swiss-poster/style.json +100 -0
- package/themes/swiss-poster/theme.json +131 -0
- package/themes/swiss-poster/variants/blush-green.json +116 -0
- package/themes/swiss-poster/variants/chalk-plum.json +121 -0
- package/themes/swiss-poster/variants/chalk-sky.json +90 -0
- package/themes/swiss-poster/variants/cocoa-cyan.json +117 -0
- package/themes/swiss-poster/variants/dusk-coral.json +89 -0
- package/themes/swiss-poster/variants/dusk-magenta.json +117 -0
- package/themes/swiss-poster/variants/forest-amber.json +127 -0
- package/themes/swiss-poster/variants/forest-blue.json +118 -0
- package/themes/swiss-poster/variants/forest-jade.json +89 -0
- package/themes/swiss-poster/variants/frost-gold.json +128 -0
- package/themes/swiss-poster/variants/frost-indigo.json +117 -0
- package/themes/swiss-poster/variants/sand-magenta.json +126 -0
- package/themes/swiss-poster/variants/slate-orange.json +122 -0
- package/themes/swiss-poster/variants/slate-pink.json +126 -0
- package/themes/swiss-poster/variants/slate-violet.json +89 -0
- package/themes/water-works/THEME.md +61 -0
- package/themes/water-works/effects.ts +609 -0
- package/themes/water-works/sample/assets/og/logo.svg +12 -0
- package/themes/water-works/sample/beats.json +1005 -0
- package/themes/water-works/sample/index.html +11 -0
- package/themes/water-works/sample/kf.json +59 -0
- package/themes/water-works/sample/lib/facts.ts +29 -0
- package/themes/water-works/sample/lib/hall.ts +22 -0
- package/themes/water-works/sample/main.ts +9 -0
- package/themes/water-works/sample/scenes/end.ts +55 -0
- package/themes/water-works/sample/scenes/gather.ts +42 -0
- package/themes/water-works/sample/scenes/models.ts +51 -0
- package/themes/water-works/sample/scenes/price.ts +66 -0
- package/themes/water-works/sample/style.json +105 -0
- package/themes/water-works/slots.ts +140 -0
- package/themes/water-works/still.png +0 -0
- package/themes/water-works/style.json +105 -0
- package/themes/water-works/theme.json +138 -0
- package/themes/water-works/variants/blush-rose.json +123 -0
- package/themes/water-works/variants/chalk-blue.json +124 -0
- package/themes/water-works/variants/chalk-cyan-2.json +96 -0
- package/themes/water-works/variants/chalk-cyan.json +123 -0
- package/themes/water-works/variants/chalk-gold-mono.json +122 -0
- package/themes/water-works/variants/chalk-gold.json +123 -0
- package/themes/water-works/variants/chalk-green.json +123 -0
- package/themes/water-works/variants/frost-indigo.json +123 -0
- package/themes/water-works/variants/frost-rose.json +132 -0
- package/themes/water-works/variants/lilac-violet-mono.json +124 -0
- package/themes/water-works/variants/lilac-violet.json +133 -0
- package/themes/water-works/variants/sage-amber.json +133 -0
- package/themes/water-works/variants/sage-green.json +133 -0
- package/themes/water-works/variants/sand-amber.json +123 -0
- package/themes/water-works/variants/sand-plum.json +121 -0
- package/themes/whiteboard/THEME.md +78 -0
- package/themes/whiteboard/effects.ts +561 -0
- package/themes/whiteboard/sample/assets/og/logo.svg +12 -0
- package/themes/whiteboard/sample/beats.json +1005 -0
- package/themes/whiteboard/sample/index.html +11 -0
- package/themes/whiteboard/sample/kf.json +59 -0
- package/themes/whiteboard/sample/lib/board.ts +93 -0
- package/themes/whiteboard/sample/lib/facts.ts +29 -0
- package/themes/whiteboard/sample/main.ts +9 -0
- package/themes/whiteboard/sample/scenes/end.ts +59 -0
- package/themes/whiteboard/sample/scenes/gather.ts +50 -0
- package/themes/whiteboard/sample/scenes/models.ts +56 -0
- package/themes/whiteboard/sample/scenes/price.ts +79 -0
- package/themes/whiteboard/sample/style.json +106 -0
- package/themes/whiteboard/slots.ts +152 -0
- package/themes/whiteboard/still.png +0 -0
- package/themes/whiteboard/style.json +106 -0
- package/themes/whiteboard/theme.json +143 -0
- package/themes/whiteboard/variants/chalk-coral-do.json +126 -0
- package/themes/whiteboard/variants/chalk-coral.json +132 -0
- package/themes/whiteboard/variants/cream-lime.json +131 -0
- package/themes/whiteboard/variants/cream-plum.json +103 -0
- package/themes/whiteboard/variants/frost-teal-do.json +127 -0
- package/themes/whiteboard/variants/frost-teal.json +127 -0
- package/themes/whiteboard/variants/lilac-indigo.json +132 -0
- package/themes/whiteboard/variants/lilac-jade.json +103 -0
- package/themes/whiteboard/variants/sage-green.json +130 -0
- package/themes/whiteboard/variants/sage-plum.json +126 -0
- package/themes/whiteboard/variants/snow-amber.json +99 -0
- package/themes/whiteboard/variants/snow-cyan.json +132 -0
- package/themes/whiteboard/variants/snow-green.json +126 -0
- package/themes/whiteboard/variants/snow-magenta.json +126 -0
- package/themes/whiteboard/variants/snow-plum.json +130 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// 테마 견본 칸 — 같은 문장 한 장면(쇼츠 첫 장면 hook-number)을 테마·변주마다 찍은 한 장. kf theme sheet·vary 와 kf make 테마 질문이 같이 쓴다.
|
|
2
|
+
// 변주는 세계 기본 판 표준 장면을 한 번 지어 두고 style.json 만 갈아 찍는다 — 감독이 고른 장면 문법이 같아야 겉모습만 견줄 수 있다.
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { dirname, join } from "node:path";
|
|
7
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
|
+
import type { KfStyle } from "@kasaframe/core";
|
|
9
|
+
import { cellPath, loadTheme, themeDims, themesDir, type Theme } from "@kasaframe/themes";
|
|
10
|
+
import { launch } from "./browser.ts";
|
|
11
|
+
|
|
12
|
+
const kfBin = new URL("./kf.ts", import.meta.url).pathname;
|
|
13
|
+
const kf = (...a: string[]) => spawnSync(process.execPath, [kfBin, ...a], { encoding: "utf8" });
|
|
14
|
+
const tail = (r: { stdout?: string; stderr?: string }, n = 3) => `${r.stderr ?? ""}${r.stdout ?? ""}`.trim().split("\n").slice(-n).join(" / ");
|
|
15
|
+
|
|
16
|
+
export const SAMPLE = {
|
|
17
|
+
title: "kasaframe",
|
|
18
|
+
request: "테마 견본 — 같은 문장을 테마마다",
|
|
19
|
+
scenes: [{ id: "hook", type: "hook-number", value: 57, unit: "×", label: "KV 캐시가 이만큼 작아진다", source: "DeepSeek-V2 기술 보고서", dur: 4 }],
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export interface Frame {
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
safe: { top: number; bottom: number; left: number; right: number };
|
|
26
|
+
/** 장면 끝 프레임 — 움직임이 다 앉은 자리 */
|
|
27
|
+
at: number;
|
|
28
|
+
dur: number;
|
|
29
|
+
pattern?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const readJson = (p: string) => JSON.parse(readFileSync(p, "utf8"));
|
|
33
|
+
|
|
34
|
+
function frameOf(dir: string): Frame {
|
|
35
|
+
const p = readJson(join(dir, "kf.json"));
|
|
36
|
+
const scene = p.scenes.find((x: { id: string }) => x.id === SAMPLE.scenes[0].id);
|
|
37
|
+
const d = existsSync(join(dir, "director.json")) ? readJson(join(dir, "director.json")) : null;
|
|
38
|
+
return { width: p.width, height: p.height, safe: p.safeArea, at: +(scene.from + scene.dur - 1 / p.fps).toFixed(4), dur: scene.dur, pattern: d?.scenes?.find((s: { id: string }) => s.id === scene.id)?.pattern };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** 표준 장면 프로젝트 — 감독이 짓고, check 면 검사 고리까지(떨어진 패턴은 감독이 다음 후보로). 1 = 다시 지어도 검사 오류가 남음 */
|
|
42
|
+
export function standardProject(theme: string, dir: string, o: { check: boolean }): { status: number; why: string; frame: Frame | null } {
|
|
43
|
+
rmSync(dir, { recursive: true, force: true });
|
|
44
|
+
let r = kf("new", dir, "--template", "shorts", "--theme", theme, "--title", SAMPLE.title, "--series", "none");
|
|
45
|
+
if (r.status === 0) {
|
|
46
|
+
writeFileSync(join(dir, "content.json"), `${JSON.stringify(SAMPLE, null, 2)}\n`);
|
|
47
|
+
r = kf("direct", dir, "--no-narrate", "--no-lock", ...(o.check ? [] : ["--no-check"]));
|
|
48
|
+
}
|
|
49
|
+
const built = r.status === 0 || r.status === 1;
|
|
50
|
+
return { status: r.status ?? 1, why: r.status === 0 ? "" : tail(r), frame: built && existsSync(join(dir, "director.json")) ? frameOf(dir) : null };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** 지어 둔 표준 장면에 테마(변주) style 만 갈아 끼운 복사본 — 장면 파일·패턴은 그대로 */
|
|
54
|
+
export function restyle(from: string, dir: string, id: string, style: KfStyle = loadTheme(id).style): void {
|
|
55
|
+
rmSync(dir, { recursive: true, force: true });
|
|
56
|
+
cpSync(from, dir, { recursive: true, filter: (src) => !src.startsWith(join(from, "out")) });
|
|
57
|
+
const was = readJson(join(from, "style.json"));
|
|
58
|
+
style = structuredClone(style);
|
|
59
|
+
// 틀의 움직임 규칙은 kf new 가 덮은 그대로 — 변주가 바꾸는 건 빠르기(durations)뿐
|
|
60
|
+
style.motion = { ...was.motion, ...(style.motion.durations ? { durations: style.motion.durations } : {}) };
|
|
61
|
+
writeFileSync(join(dir, "style.json"), `${JSON.stringify(style, null, 2)}\n`);
|
|
62
|
+
const p = readJson(join(dir, "kf.json"));
|
|
63
|
+
writeFileSync(join(dir, "kf.json"), `${JSON.stringify({ ...p, theme: id }, null, 2)}\n`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface Verdict {
|
|
67
|
+
ok: boolean;
|
|
68
|
+
/** 오류 규칙·한 줄 */
|
|
69
|
+
errors: string[];
|
|
70
|
+
ran: boolean;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** kf check — 잠금은 부르는 쪽이 쥔다. from·to 를 주면 그 구간만(입체 세계는 무거워 끝 구간만) */
|
|
74
|
+
export function checkProject(dir: string, win?: { from: number; to: number }): Verdict {
|
|
75
|
+
const file = join(dir, "out", "check.json");
|
|
76
|
+
rmSync(file, { force: true });
|
|
77
|
+
const r = kf("check", dir, "--no-lock", "--tabs", "2", ...(win ? ["--from", String(win.from), "--to", String(win.to)] : []));
|
|
78
|
+
if (!existsSync(file)) return { ok: false, ran: false, errors: [`kf check 를 못 돌렸다(종료 ${r.status}) — ${tail(r)}`] };
|
|
79
|
+
const rep = readJson(file);
|
|
80
|
+
const errors = (rep.findings ?? []).filter((f: { severity: string }) => f.severity === "error").map((f: { rule: string; message: string }) => `${f.rule}: ${f.message}`);
|
|
81
|
+
return { ok: r.status === 0 && !errors.length, ran: true, errors };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function still(dir: string, at: number, out: string): string | null {
|
|
85
|
+
mkdirSync(dirname(out), { recursive: true });
|
|
86
|
+
const r = kf("still", dir, "--t", String(at), "--out", out);
|
|
87
|
+
return r.status === 0 ? null : tail(r);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** 칸 그림을 36×64 로 줄인 RGB — 판끼리 얼마나 다른지 잰다 */
|
|
91
|
+
export function thumb(png: string): Uint8Array {
|
|
92
|
+
const r = spawnSync("ffmpeg", ["-v", "error", "-i", png, "-vf", "scale=36:64:flags=area", "-f", "rawvideo", "-pix_fmt", "rgb24", "-"], { maxBuffer: 1 << 20 });
|
|
93
|
+
return new Uint8Array(r.stdout ?? []);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** 0..1 — 평균 화소 차. 0.04 아래면 사람 눈에 같은 판 */
|
|
97
|
+
export function imageDiff(a: Uint8Array, b: Uint8Array): number {
|
|
98
|
+
if (!a.length || a.length !== b.length) return 1;
|
|
99
|
+
let s = 0;
|
|
100
|
+
for (let i = 0; i < a.length; i++) s += Math.abs(a[i] - b[i]);
|
|
101
|
+
return s / a.length / 255;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 칸 캐시 열쇠 — 겉모습(style)·견본 내용·세계 코드·견본 장면 문법(hook-number 패턴과 그 도구)이 같으면 같은 칸
|
|
105
|
+
const patternsDir = fileURLToPath(new URL("../../patterns/src/", import.meta.url));
|
|
106
|
+
const SAMPLE_CODE = [join(patternsDir, "kit.ts"), ...readdirSync(join(patternsDir, "hook-number")).sort().map((f) => join(patternsDir, "hook-number", f))];
|
|
107
|
+
|
|
108
|
+
export function cellKey(t: Theme): string {
|
|
109
|
+
const h = createHash("sha256");
|
|
110
|
+
h.update(JSON.stringify(t.style));
|
|
111
|
+
h.update(JSON.stringify(SAMPLE));
|
|
112
|
+
for (const f of ["effects.ts", "slots.ts"]) if (existsSync(join(themesDir, t.world, f))) h.update(readFileSync(join(themesDir, t.world, f)));
|
|
113
|
+
for (const f of SAMPLE_CODE) if (existsSync(f)) h.update(readFileSync(f));
|
|
114
|
+
return h.digest("hex").slice(0, 16);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const metaOf = (id: string) => cellPath(id).replace(/\.png$/, ".json");
|
|
118
|
+
|
|
119
|
+
export function cellFresh(t: Theme): boolean {
|
|
120
|
+
const m = metaOf(t.id);
|
|
121
|
+
return existsSync(cellPath(t.id)) && existsSync(m) && readJson(m).key === cellKey(t);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function markCell(t: Theme, frame: Frame): void {
|
|
125
|
+
writeFileSync(metaOf(t.id), `${JSON.stringify({ key: cellKey(t), at: frame.at, width: frame.width, height: frame.height, safe: frame.safe, pattern: frame.pattern ?? null }, null, 2)}\n`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export const cellFrame = (id: string): Frame | null => (existsSync(metaOf(id)) ? readJson(metaOf(id)) : null);
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* 칸이 없거나 낡은 테마만 찍는다(검사 없이 — 변주는 뽑을 때 검사를 넘었다). 세계마다 표준 장면을 한 번 짓고 변주는 style 만 갈아 찍는다.
|
|
132
|
+
* 돌려주는 것: id → 칸 경로(못 찍은 것은 빠진다)
|
|
133
|
+
*/
|
|
134
|
+
export function ensureCells(ids: string[], tmp: string, log: (l: string) => void = () => {}): Map<string, string> {
|
|
135
|
+
const out = new Map<string, string>();
|
|
136
|
+
const byWorld = new Map<string, Theme[]>();
|
|
137
|
+
for (const id of ids) {
|
|
138
|
+
const t = loadTheme(id);
|
|
139
|
+
if (cellFresh(t)) out.set(id, cellPath(id));
|
|
140
|
+
else byWorld.set(t.world, [...(byWorld.get(t.world) ?? []), t]);
|
|
141
|
+
}
|
|
142
|
+
for (const [world, list] of byWorld) {
|
|
143
|
+
const base = join(tmp, `${world}-base`);
|
|
144
|
+
const b = standardProject(world, base, { check: false });
|
|
145
|
+
if (!b.frame) {
|
|
146
|
+
log(`견본 칸 ${world}: 표준 장면을 못 지었다 — ${b.why}`);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
for (const t of list) {
|
|
150
|
+
const dir = t.variant ? join(tmp, t.id.replace("/", "--")) : base;
|
|
151
|
+
if (t.variant) restyle(base, dir, t.id);
|
|
152
|
+
const bad = still(dir, b.frame.at, cellPath(t.id));
|
|
153
|
+
if (bad) {
|
|
154
|
+
log(`견본 칸 ${t.id}: 못 찍음 — ${bad}`);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
markCell(t, b.frame);
|
|
158
|
+
out.set(t.id, cellPath(t.id));
|
|
159
|
+
log(`견본 칸 ${t.id}: ${cellPath(t.id)}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return out;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface GridCell {
|
|
166
|
+
png: string;
|
|
167
|
+
title: string;
|
|
168
|
+
sub?: string;
|
|
169
|
+
note?: string;
|
|
170
|
+
swatches?: string[];
|
|
171
|
+
badge?: string;
|
|
172
|
+
bad?: boolean;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const esc = (s: string) => s.replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[c]!);
|
|
176
|
+
|
|
177
|
+
/** 칸 격자 한 장 — 안전 영역 점선, 이름·설명·색 견본 */
|
|
178
|
+
export async function gridSheet(cells: GridCell[], out: string, o: { heading: string; cols: number; w: number; frame: Pick<Frame, "width" | "height" | "safe"> }): Promise<string> {
|
|
179
|
+
const { w, cols, frame } = o;
|
|
180
|
+
const h = Math.round((w * frame.height) / frame.width);
|
|
181
|
+
const k = w / frame.width;
|
|
182
|
+
const html = `<!doctype html><meta charset="utf-8"><style>
|
|
183
|
+
body { margin: 0; padding: 24px; background: #111; font: 15px/1.35 -apple-system, "Apple SD Gothic Neo", sans-serif; color: #ddd; width: ${cols * w + (cols - 1) * 16}px; }
|
|
184
|
+
h1 { margin: 0 0 16px; font-size: 18px; font-weight: 600; color: #fff; }
|
|
185
|
+
main { display: grid; grid-template-columns: repeat(${cols}, ${w}px); gap: 22px 16px; }
|
|
186
|
+
figure { margin: 0; position: relative; }
|
|
187
|
+
.safe { position: absolute; left: 0; width: ${w}px; border-top: 2px dashed #ff4d4d; opacity: .8; }
|
|
188
|
+
img { display: block; width: ${w}px; height: ${h}px; outline: 1px solid #333; object-fit: cover; }
|
|
189
|
+
figcaption { padding: 8px 2px 0; }
|
|
190
|
+
b { color: #fff; }
|
|
191
|
+
.d { display: inline-block; margin-left: 6px; padding: 0 6px; border: 1px solid #666; border-radius: 4px; font-size: 12px; }
|
|
192
|
+
small { display: block; color: #999; font-size: 12.5px; word-break: keep-all; }
|
|
193
|
+
.sw { display: flex; gap: 3px; margin-top: 5px; }
|
|
194
|
+
.sw i { width: 18px; height: 12px; border-radius: 2px; outline: 1px solid #444; }
|
|
195
|
+
.bad { color: #ff6b6b; }
|
|
196
|
+
</style><h1>${esc(o.heading)}</h1><main>${cells
|
|
197
|
+
.map(
|
|
198
|
+
(c) =>
|
|
199
|
+
`<figure><img src="${pathToFileURL(c.png).href}"><div class="safe" style="top:${Math.round(frame.safe.top * k)}px"></div><div class="safe" style="top:${Math.round((frame.height - frame.safe.bottom) * k)}px"></div><figcaption><b>${esc(c.title)}</b>${c.badge ? `<span class="d">${esc(c.badge)}</span>` : ""}${c.sub ? `<small>${esc(c.sub)}</small>` : ""}${c.note ? `<small class="${c.bad ? "bad" : ""}">${esc(c.note)}</small>` : ""}${c.swatches ? `<div class="sw">${c.swatches.map((s) => `<i style="background:${s}"></i>`).join("")}</div>` : ""}</figcaption></figure>`,
|
|
200
|
+
)
|
|
201
|
+
.join("")}</main>`;
|
|
202
|
+
mkdirSync(dirname(out), { recursive: true });
|
|
203
|
+
const page = out.replace(/\.png$/, ".html");
|
|
204
|
+
writeFileSync(page, html);
|
|
205
|
+
const browser = await launch();
|
|
206
|
+
try {
|
|
207
|
+
const p = await browser.newPage({ viewport: { width: 48 + cols * w + (cols - 1) * 16, height: 400 } });
|
|
208
|
+
await p.goto(pathToFileURL(page).href, { waitUntil: "load" });
|
|
209
|
+
writeFileSync(out, await p.screenshot({ fullPage: true, type: "png" }));
|
|
210
|
+
} finally {
|
|
211
|
+
await browser.close();
|
|
212
|
+
rmSync(page, { force: true });
|
|
213
|
+
}
|
|
214
|
+
return out;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** 격자 칸 글 — 이름·2D/3D·설명·색 견본 */
|
|
218
|
+
export function cellOf(t: Theme, png: string): GridCell {
|
|
219
|
+
const c = t.style.colors;
|
|
220
|
+
return {
|
|
221
|
+
png,
|
|
222
|
+
title: t.variant ? t.variant.name : `${t.name} · 기본`,
|
|
223
|
+
badge: themeDims(t),
|
|
224
|
+
sub: t.variant ? `${t.id} — ${t.variant.desc}` : `${t.id} — 세계 그대로`,
|
|
225
|
+
swatches: [c.bg, c.surface, c.ink, c.accent, c.success, c.danger],
|
|
226
|
+
};
|
|
227
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import type { Command } from "../command.ts";
|
|
7
|
+
import { num, parseFlags } from "../command.ts";
|
|
8
|
+
|
|
9
|
+
const kfBin = fileURLToPath(new URL("../kf.ts", import.meta.url));
|
|
10
|
+
|
|
11
|
+
const USAGE = `kf bench "<대충 한 요청>" [--runs 3] [--model claude-code|<OG 모델>] [--out 폴더] [kf make 에 넘길 플래그…]
|
|
12
|
+
|
|
13
|
+
같은 요청으로 kf make 를 여러 번 돌려 나란히 본다 — 「대충 말해도 같은 결과」를 재는 시험 틀.
|
|
14
|
+
같아야 할 것: 용도·시리즈·테마·스타일·목소리·곡·자막·길이·장면 수·장면 시간표·장면 연출·생성 거리·3D 샷·고른 답·물을 것
|
|
15
|
+
달라도 되는 것: 검사 점수·장면 모음(모델이 장면을 쓰는 OG 모드에서만 나온다)
|
|
16
|
+
claude-code 모드(기본)는 kf make 가 지시서에서 멈추니 계획까지 본다. --model <OG 모델> 이면 끝까지 굽고 검사·장면 모음까지(실행마다 렌더 — 오래 걸린다)
|
|
17
|
+
결과: <out>/report.md · report.json · (OG) sheets.png. 같아야 할 것이 달라지면 빨간 「다름」, 종료 코드 1`;
|
|
18
|
+
|
|
19
|
+
const RED = (s: string) => (process.stdout.isTTY ? `\x1b[31m${s}\x1b[0m` : s);
|
|
20
|
+
const DIM = (s: string) => (process.stdout.isTTY ? `\x1b[2m${s}\x1b[0m` : s);
|
|
21
|
+
|
|
22
|
+
const read = (f: string) => (existsSync(f) ? JSON.parse(readFileSync(f, "utf8")) : null);
|
|
23
|
+
const short = (v: unknown) => createHash("sha256").update(JSON.stringify(v ?? null)).digest("hex").slice(0, 8);
|
|
24
|
+
|
|
25
|
+
interface Run {
|
|
26
|
+
dir: string;
|
|
27
|
+
code: number;
|
|
28
|
+
same: Record<string, string>;
|
|
29
|
+
vary: Record<string, string>;
|
|
30
|
+
sheet?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 실행 하나에서 비교할 값 — 긴 것(시간표·연출·생성 거리)은 지문으로 줄이고 report.json 에 원본을 둔다
|
|
34
|
+
function measure(dir: string, code: number): Run {
|
|
35
|
+
const plan = read(join(dir, "plan.json")) ?? {};
|
|
36
|
+
const kf = read(join(dir, "kf.json")) ?? {};
|
|
37
|
+
const scenes: { id: string; from: number; dur: number; dress?: unknown }[] = kf.scenes ?? plan.scenes ?? [];
|
|
38
|
+
const same: Record<string, string> = {
|
|
39
|
+
용도: plan.purpose ?? "-",
|
|
40
|
+
시리즈: plan.series ?? "-",
|
|
41
|
+
테마: plan.theme ?? "-",
|
|
42
|
+
스타일: plan.style ?? "-",
|
|
43
|
+
목소리: plan.voice ?? plan.answers?.voice ?? "-",
|
|
44
|
+
곡: (kf.music ?? plan.music ?? plan.answers?.music ?? "-").toString().split("/").pop(),
|
|
45
|
+
자막: kf.captions ?? plan.captions ?? "-",
|
|
46
|
+
길이: String(kf.duration ?? plan.duration ?? "-"),
|
|
47
|
+
"장면 수": String(scenes.length),
|
|
48
|
+
시간표: short(scenes.map((s) => [s.id, s.from, s.dur])),
|
|
49
|
+
연출: short(scenes.map((s) => s.dress ?? null)),
|
|
50
|
+
"생성 거리": (plan.gen ?? []).map((g: { kind: string; id: string; provider?: string }) => `${g.kind}:${g.id}${g.provider ? `@${g.provider}` : ""}`).join(" ") || "-",
|
|
51
|
+
"3D 샷": (plan.shots ?? []).map((s: { id: string; tool: string }) => `${s.id}@${s.tool}`).join(" ") || "-",
|
|
52
|
+
"고른 답": Object.entries(plan.answers ?? {}).map(([k, v]) => `${k}=${String(v).split("/").pop()}`).sort().join(" ") || "-",
|
|
53
|
+
"물을 것": (plan.asks ?? []).map((q: { id: string }) => q.id).join(" ") || "-",
|
|
54
|
+
};
|
|
55
|
+
const check = read(join(dir, "out", "check.json"));
|
|
56
|
+
const vary: Record<string, string> = {};
|
|
57
|
+
if (check) {
|
|
58
|
+
const fs: { severity: string }[] = check.findings ?? [];
|
|
59
|
+
vary["검사"] = `오류 ${fs.filter((f) => f.severity === "error").length} · 경고 ${fs.filter((f) => f.severity === "warn").length}`;
|
|
60
|
+
}
|
|
61
|
+
vary["종료 코드"] = String(code);
|
|
62
|
+
const sheet = join(dir, "out", "look-sheet.png");
|
|
63
|
+
return { dir, code, same, vary, ...(existsSync(sheet) ? { sheet } : {}) };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function table(runs: Run[]): { lines: string[]; diff: string[] } {
|
|
67
|
+
const keys = Object.keys(runs[0].same);
|
|
68
|
+
const diff = keys.filter((k) => new Set(runs.map((r) => r.same[k])).size > 1);
|
|
69
|
+
const w = Math.max(...keys.map((k) => [...k].length * 2)) + 2;
|
|
70
|
+
const pad = (s: string, n: number) => s + " ".repeat(Math.max(0, n - [...s].reduce((a, c) => a + (/[ㄱ-]/.test(c) ? 2 : 1), 0)));
|
|
71
|
+
const lines = [pad("", w) + runs.map((_, i) => `실행 ${i + 1}`).join(" | ")];
|
|
72
|
+
for (const k of keys) {
|
|
73
|
+
const row = `${pad(k, w)}${runs.map((r) => r.same[k]).join(" | ")}`;
|
|
74
|
+
lines.push(diff.includes(k) ? RED(`${row} 다름`) : row);
|
|
75
|
+
}
|
|
76
|
+
for (const k of Object.keys(runs[0].vary)) lines.push(DIM(`${pad(k, w)}${runs.map((r) => r.vary[k] ?? "-").join(" | ")}`));
|
|
77
|
+
return { lines, diff };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const cmd: Command = {
|
|
81
|
+
summary: "일관성 시험 — 같은 요청으로 kf make 를 여러 번, 같아야 할 것이 달라지면 빨갛게",
|
|
82
|
+
usage: USAGE,
|
|
83
|
+
async run(argv) {
|
|
84
|
+
const { args, opts } = parseFlags(argv);
|
|
85
|
+
const request = args.join(" ").trim();
|
|
86
|
+
if (!request) {
|
|
87
|
+
console.error(USAGE);
|
|
88
|
+
return 2;
|
|
89
|
+
}
|
|
90
|
+
const runs = Math.max(2, Math.round(num(opts.runs, 3)));
|
|
91
|
+
const model = typeof opts.model === "string" ? opts.model : "claude-code";
|
|
92
|
+
const out = resolve(typeof opts.out === "string" ? opts.out : `bench-${new Date().toISOString().slice(0, 16).replace(/[-:T]/g, "")}`);
|
|
93
|
+
mkdirSync(out, { recursive: true });
|
|
94
|
+
// kf make 로 그대로 넘길 플래그(--yes·--no-gen·--allow·--image 등) — bench 자신의 것은 뺀다
|
|
95
|
+
const pass: string[] = [];
|
|
96
|
+
for (const [k, v] of Object.entries(opts)) {
|
|
97
|
+
if (["runs", "model", "out"].includes(k)) continue;
|
|
98
|
+
pass.push(`--${k}`, ...(v === true ? [] : [String(v)]));
|
|
99
|
+
}
|
|
100
|
+
const done: Run[] = [];
|
|
101
|
+
for (let i = 1; i <= runs; i++) {
|
|
102
|
+
const dir = join(out, `run-${i}`);
|
|
103
|
+
console.error(`실행 ${i}/${runs} — kf make (${model}) → ${dir}`);
|
|
104
|
+
const r = spawnSync(process.execPath, [kfBin, "make", request, "--out", dir, "--model", model, "--force", ...pass], { stdio: ["ignore", "ignore", "inherit"] });
|
|
105
|
+
done.push(measure(dir, r.status ?? 1));
|
|
106
|
+
}
|
|
107
|
+
const { lines, diff } = table(done);
|
|
108
|
+
console.log(`\n「${request}」 × ${runs} (${model})\n`);
|
|
109
|
+
console.log(lines.join("\n"));
|
|
110
|
+
const sheets = done.filter((r) => r.sheet).map((r) => r.sheet!);
|
|
111
|
+
if (sheets.length > 1) {
|
|
112
|
+
const png = join(out, "sheets.png");
|
|
113
|
+
const r = spawnSync("ffmpeg", ["-v", "error", "-y", ...sheets.flatMap((s) => ["-i", s]), "-filter_complex", `${sheets.map((_, i) => `[${i}]scale=-2:900[s${i}]`).join(";")};${sheets.map((_, i) => `[s${i}]`).join("")}hstack=${sheets.length}`, png]);
|
|
114
|
+
if (r.status === 0) console.log(`\n장면 모음 나란히: ${png}`);
|
|
115
|
+
}
|
|
116
|
+
const md = [`# kf bench — 「${request}」 × ${runs} (${model})`, "", "```", ...lines.map((l) => l.replace(/\x1b\[[0-9;]*m/g, "")), "```", "", diff.length ? `같아야 하는데 달라진 것: ${diff.join(" · ")}` : "같아야 할 것이 모두 같다.", ""].join("\n");
|
|
117
|
+
writeFileSync(join(out, "report.md"), md);
|
|
118
|
+
writeFileSync(join(out, "report.json"), `${JSON.stringify({ request, runs, model, diff, results: done.map((r) => ({ ...r, plan: read(join(r.dir, "plan.json")), scenes: read(join(r.dir, "kf.json"))?.scenes })) }, null, 2)}\n`);
|
|
119
|
+
console.log(`\n${diff.length ? RED(`다름 ${diff.length}가지: ${diff.join(" · ")}`) : "같아야 할 것이 모두 같다"}\n보고서: ${join(out, "report.md")}`);
|
|
120
|
+
return diff.length ? 1 : 0;
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
export default cmd;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { spawn
|
|
2
|
-
import {
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { blenderLibDir, findBlender, hasBlenderLib } from "@kasaframe/gen";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
3
4
|
import { basename, dirname, join, relative, resolve } from "node:path";
|
|
4
5
|
import type { Command } from "../command.ts";
|
|
5
6
|
import { num, parseFlags } from "../command.ts";
|
|
7
|
+
import { openSession } from "../browser.ts";
|
|
6
8
|
import { encoder } from "../ffmpeg.ts";
|
|
7
9
|
import { acquireRenderLock } from "../lock.ts";
|
|
8
10
|
import { fmtTime } from "../out.ts";
|
|
9
|
-
import { repoRoot } from "../serve.ts";
|
|
10
11
|
|
|
11
12
|
// 이 파일은 Blender 를 바깥 프로그램으로 띄우기만 한다(bpy 를 가져오지 않는다). bpy 를 쓰는 헬퍼·샷은 GPL 로 갈라 둔
|
|
12
13
|
// tools/blender 에 있고 npm 묶음에는 없다 — 근거는 tools/blender/README.md.
|
|
@@ -20,11 +21,9 @@ interface KfJson {
|
|
|
20
21
|
scenes?: { id: string; from: number; dur: number }[];
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
const MIN = [4, 3]; // Grease Pencil v3(라인아트가 일반 모디파이어)가 4.3 부터
|
|
24
|
-
|
|
25
24
|
function blenderLib(): string {
|
|
26
|
-
const dir =
|
|
27
|
-
if (!
|
|
25
|
+
const dir = blenderLibDir();
|
|
26
|
+
if (!hasBlenderLib(dir)) {
|
|
28
27
|
throw new Error(
|
|
29
28
|
`Blender 헬퍼(kfb.py·run.py)가 없다: ${dir}\n` +
|
|
30
29
|
"헬퍼는 bpy 를 써서 GPL-3.0 으로 갈라 두었고 npm 묶음에는 넣지 않았다 — 레포의 tools/blender 를 받아 KF_BLENDER_LIB=<그 폴더> 로 가리켜라.",
|
|
@@ -33,46 +32,6 @@ function blenderLib(): string {
|
|
|
33
32
|
return dir;
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
function candidates(given?: string): string[] {
|
|
37
|
-
const out: string[] = [];
|
|
38
|
-
if (given) out.push(given);
|
|
39
|
-
if (process.env.BLENDER) out.push(process.env.BLENDER);
|
|
40
|
-
const which = spawnSync(process.platform === "win32" ? "where" : "which", ["blender"], { encoding: "utf8" });
|
|
41
|
-
if (which.status === 0) out.push(...which.stdout.split(/\r?\n/).filter(Boolean));
|
|
42
|
-
if (process.platform === "darwin") {
|
|
43
|
-
const apps = existsSync("/Applications") ? readdirSync("/Applications").filter((n) => /^Blender.*\.app$/.test(n)) : [];
|
|
44
|
-
// 이름에 판 번호를 붙여 여러 개 깔아 둔 기계면 높은 판부터
|
|
45
|
-
apps.sort((a, b) => b.localeCompare(a, undefined, { numeric: true }));
|
|
46
|
-
out.push(...apps.map((a) => `/Applications/${a}/Contents/MacOS/Blender`));
|
|
47
|
-
}
|
|
48
|
-
if (process.platform === "win32") {
|
|
49
|
-
const base = "C:\\Program Files\\Blender Foundation";
|
|
50
|
-
if (existsSync(base)) {
|
|
51
|
-
const dirs = readdirSync(base).sort((a, b) => b.localeCompare(a, undefined, { numeric: true }));
|
|
52
|
-
out.push(...dirs.map((d) => join(base, d, "blender.exe")));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return out;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function findBlender(given?: string): { exe: string; version: number[] } {
|
|
59
|
-
const tried: string[] = [];
|
|
60
|
-
for (const exe of candidates(given)) {
|
|
61
|
-
if (tried.includes(exe)) continue;
|
|
62
|
-
tried.push(exe);
|
|
63
|
-
const r = spawnSync(exe, ["--version"], { encoding: "utf8", timeout: 30_000 });
|
|
64
|
-
const m = /Blender (\d+)\.(\d+)(?:\.(\d+))?/.exec(r.stdout ?? "");
|
|
65
|
-
if (r.status !== 0 || !m) continue;
|
|
66
|
-
const version = [Number(m[1]), Number(m[2]), Number(m[3] ?? 0)];
|
|
67
|
-
if (version[0] < MIN[0] || (version[0] === MIN[0] && version[1] < MIN[1])) {
|
|
68
|
-
console.error(`kf blender: ${exe} 는 ${version.join(".")} — ${MIN.join(".")} 이상이 필요해 건너뛴다`);
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
return { exe, version };
|
|
72
|
-
}
|
|
73
|
-
throw new Error(`Blender ${MIN.join(".")} 이상을 못 찾았다 — --blender <실행 파일> 또는 BLENDER=<경로>. 본 곳: ${tried.join(", ") || "(없음)"}`);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
35
|
function findProject(given: string | undefined, shot: string): string {
|
|
77
36
|
if (given) {
|
|
78
37
|
if (!existsSync(join(resolve(given), "kf.json"))) throw new Error(`kf.json 이 없다: ${resolve(given)}`);
|
|
@@ -98,6 +57,8 @@ const cmd: Command = {
|
|
|
98
57
|
--step 1 N 프레임마다 한 장만 찍고 그 사이는 붙든다(2 = 애니메이션 「2코마」, 시간 반)
|
|
99
58
|
--still 1.2,4.5 그 시각들만 PNG 로(out/blender/<id>/still-<t>.png) — 굽기 전에 그림부터 본다
|
|
100
59
|
--blend 만든 장면을 out/blender/<id>.blend 로 저장(Blender 에서 열어 보기)
|
|
60
|
+
--match 앞 장면 마지막 화면·뒤 장면 첫 화면과 그 주인공 상자를 찍어 샷에 넘긴다 — 샷이 kfb.match_start·match_end 로
|
|
61
|
+
첫·끝 프레임을 그 2D 화면과 같은 구도로 맞추면(투영 일치) 경계가 컷이어도 공간이 이어진다. --scene 과 함께
|
|
101
62
|
--blender <실행 파일> 기본: BLENDER 환경 변수 → PATH 의 blender → /Applications/Blender*.app (4.3 이상)
|
|
102
63
|
--keep 다 묶은 뒤에도 PNG 를 out/blender/<id>/ 에 남긴다
|
|
103
64
|
--no-lock · --lock-wait 900 렌더 잠금(kf render 와 같은 것 — 무거운 일은 한 번에 하나)
|
|
@@ -160,12 +121,13 @@ const cmd: Command = {
|
|
|
160
121
|
blend: opts.blend ? join(proj, "out", "blender", `${id}.blend`) : null,
|
|
161
122
|
};
|
|
162
123
|
const cfgPath = join(proj, "out", "blender", `${id}.cfg.json`);
|
|
163
|
-
writeFileSync(cfgPath, JSON.stringify(cfg, null, 2));
|
|
164
124
|
|
|
165
|
-
const { exe, version } = findBlender(typeof opts.blender === "string" ? opts.blender : undefined);
|
|
125
|
+
const { exe, version } = findBlender(typeof opts.blender === "string" ? opts.blender : undefined, (l) => console.error(`kf blender: ${l}`));
|
|
166
126
|
const release = opts["no-lock"] ? () => {} : await acquireRenderLock(proj, num(opts["lock-wait"], 900));
|
|
167
127
|
const started = Date.now();
|
|
168
128
|
try {
|
|
129
|
+
const match = opts.match && typeof opts.scene === "string" ? await matchFrames(proj, kf, opts.scene, work) : null;
|
|
130
|
+
writeFileSync(cfgPath, JSON.stringify({ ...cfg, match }, null, 2));
|
|
169
131
|
console.error(
|
|
170
132
|
`Blender ${version.join(".")} · ${relative(process.cwd(), shot)} · ${fmtTime(t0)}–${fmtTime(endF / fps)}초 · ` +
|
|
171
133
|
`${stills ? `스틸 ${frames.length}장` : `${count}프레임${step > 1 ? ` (${step}장마다 찍음 ${frames.length}장)` : ""}`} · ${Math.round((kf.width * res) / 100)}x${Math.round((kf.height * res) / 100)}`,
|
|
@@ -176,6 +138,8 @@ const cmd: Command = {
|
|
|
176
138
|
for (const n of names) console.log(join(work, `${n}.png`));
|
|
177
139
|
return 0;
|
|
178
140
|
}
|
|
141
|
+
const usedFile = join(work, "match-used.json");
|
|
142
|
+
const used: string[] = existsSync(usedFile) ? JSON.parse(readFileSync(usedFile, "utf8")) : [];
|
|
179
143
|
|
|
180
144
|
const outDir = join(proj, "assets", "blender");
|
|
181
145
|
mkdirSync(outDir, { recursive: true });
|
|
@@ -205,9 +169,20 @@ const cmd: Command = {
|
|
|
205
169
|
secPerFrame: Number(perFrame.toFixed(3)),
|
|
206
170
|
elapsedSec: Number(elapsed.toFixed(1)),
|
|
207
171
|
dataKfFrom: kfFrom,
|
|
172
|
+
...(used.length ? { match: { in: used.includes("in"), out: used.includes("out") } } : {}),
|
|
208
173
|
renderedAt: new Date().toISOString(),
|
|
209
174
|
};
|
|
210
175
|
writeFileSync(join(outDir, `${id}.json`), `${JSON.stringify(meta, null, 2)}\n`);
|
|
176
|
+
// 첫·끝 프레임을 앞뒤 2D 화면과 투영 일치로 맞췄으면 그 장면에 적는다 — 감독은 matched 장면 경계에 이음매를 넣지 않는다(컷으로 이어진다)
|
|
177
|
+
if (used.length && typeof opts.scene === "string") {
|
|
178
|
+
const file = join(proj, "kf.json");
|
|
179
|
+
const doc = JSON.parse(readFileSync(file, "utf8"));
|
|
180
|
+
const sc = doc.scenes?.find((x: { id: string }) => x.id === opts.scene);
|
|
181
|
+
if (sc) {
|
|
182
|
+
sc.matched = true;
|
|
183
|
+
writeFileSync(file, `${JSON.stringify(doc, null, 2)}\n`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
211
186
|
if (!opts.keep) rmSync(work, { recursive: true, force: true });
|
|
212
187
|
console.error(`${count}프레임 · 한 장 ${perFrame.toFixed(2)}초 · 모두 ${Math.round(elapsed)}초`);
|
|
213
188
|
console.error(`장면에서: <video src="\${ctx.asset("blender/${id}.mp4")}" data-kf-from="${kfFrom}" muted playsinline>`);
|
|
@@ -220,6 +195,54 @@ const cmd: Command = {
|
|
|
220
195
|
};
|
|
221
196
|
export default cmd;
|
|
222
197
|
|
|
198
|
+
interface Rect {
|
|
199
|
+
x: number;
|
|
200
|
+
y: number;
|
|
201
|
+
w: number;
|
|
202
|
+
h: number;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// 샷 앞 장면의 마지막 프레임·뒤 장면의 첫 프레임과 그 장면이 짚은 주인공([data-kf-hero]) 상자(화면 비율, 왼쪽 위 0).
|
|
206
|
+
// 샷 자리의 장면은 찍지 않으니 샷 영상이 아직 없어도 된다
|
|
207
|
+
async function matchFrames(proj: string, kf: KfJson, sceneId: string, work: string): Promise<{ in?: string; inHero?: Rect; out?: string; outHero?: Rect } | null> {
|
|
208
|
+
const list = kf.scenes ?? [];
|
|
209
|
+
const i = list.findIndex((s) => s.id === sceneId);
|
|
210
|
+
const prev = list[i - 1];
|
|
211
|
+
const next = list[i + 1];
|
|
212
|
+
if (i < 0 || (!prev && !next)) return null;
|
|
213
|
+
const s = await openSession(proj);
|
|
214
|
+
try {
|
|
215
|
+
const grab = async (t: number, id: string, file: string) => {
|
|
216
|
+
await s.first.seek(t);
|
|
217
|
+
writeFileSync(file, await s.first.capture());
|
|
218
|
+
const hero = await s.first.page.evaluate((sid) => {
|
|
219
|
+
const stage = document.getElementById("stage") ?? document.body;
|
|
220
|
+
const el = document.querySelector(`[data-kf-scene="${sid}"] [data-kf-hero]`);
|
|
221
|
+
if (!el) return null;
|
|
222
|
+
const b = stage.getBoundingClientRect();
|
|
223
|
+
const r = el.getBoundingClientRect();
|
|
224
|
+
return { x: (r.left - b.left) / b.width, y: (r.top - b.top) / b.height, w: r.width / b.width, h: r.height / b.height };
|
|
225
|
+
}, id);
|
|
226
|
+
return { file, hero: hero ?? undefined };
|
|
227
|
+
};
|
|
228
|
+
const out: { in?: string; inHero?: Rect; out?: string; outHero?: Rect } = {};
|
|
229
|
+
if (prev) {
|
|
230
|
+
const g = await grab(prev.from + prev.dur - 1 / kf.fps, prev.id, join(work, "match-in.png"));
|
|
231
|
+
out.in = g.file;
|
|
232
|
+
out.inHero = g.hero;
|
|
233
|
+
}
|
|
234
|
+
if (next) {
|
|
235
|
+
const g = await grab(next.from, next.id, join(work, "match-out.png"));
|
|
236
|
+
out.out = g.file;
|
|
237
|
+
out.outHero = g.hero;
|
|
238
|
+
}
|
|
239
|
+
console.error(`kf blender: 맞출 화면 — ${prev ? `앞 ${prev.id} 끝` : ""}${prev && next ? " · " : ""}${next ? `뒤 ${next.id} 처음` : ""}`);
|
|
240
|
+
return out;
|
|
241
|
+
} finally {
|
|
242
|
+
await s.close();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
223
246
|
// Blender 를 헤드리스로 돌리고 KFB 줄로 진행을 센다. 평균 한 장 시간(첫 장의 셰이더 컴파일 빼고)을 돌려준다.
|
|
224
247
|
function runBlender(exe: string, lib: string, cfgPath: string): Promise<number> {
|
|
225
248
|
return new Promise((resolveRun, reject) => {
|