create-aura3d 1.0.9 → 1.0.10
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/dist/cli.js +0 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/package.json +8 -4
- package/templates/cartoon-channel/package.json +1 -1
- package/templates/cartoon-studio/README.md +46 -0
- package/templates/cartoon-studio/index.html +13 -0
- package/templates/cartoon-studio/package.json +21 -0
- package/templates/cartoon-studio/playwright.config.ts +13 -0
- package/templates/cartoon-studio/src/aura-assets.ts +14 -0
- package/templates/cartoon-studio/src/characters.ts +28 -0
- package/templates/cartoon-studio/src/contract.ts +1 -0
- package/templates/cartoon-studio/src/episode.ts +300 -0
- package/templates/cartoon-studio/src/main.ts +265 -0
- package/templates/cartoon-studio/src/render-plan.ts +405 -0
- package/templates/cartoon-studio/src/sets.ts +14 -0
- package/templates/cartoon-studio/src/studio.ts +101 -0
- package/templates/cartoon-studio/tests/route-health.spec.ts +7 -0
- package/templates/cartoon-studio/tests/storyboard-playback.spec.ts +91 -0
- package/templates/cartoon-studio/tsconfig.json +12 -0
- package/templates/cinematic-scene/package.json +1 -1
- package/templates/episode-builder/README.md +46 -0
- package/templates/episode-builder/index.html +13 -0
- package/templates/episode-builder/package.json +21 -0
- package/templates/episode-builder/playwright.config.ts +13 -0
- package/templates/episode-builder/src/aura-assets.ts +14 -0
- package/templates/episode-builder/src/builder.ts +78 -0
- package/templates/episode-builder/src/characters.ts +28 -0
- package/templates/episode-builder/src/contract.ts +1 -0
- package/templates/episode-builder/src/episode.ts +300 -0
- package/templates/episode-builder/src/main.ts +265 -0
- package/templates/episode-builder/src/render-plan.ts +405 -0
- package/templates/episode-builder/src/sets.ts +14 -0
- package/templates/episode-builder/tests/route-health.spec.ts +7 -0
- package/templates/episode-builder/tests/storyboard-playback.spec.ts +98 -0
- package/templates/episode-builder/tsconfig.json +12 -0
- package/templates/fighting-game/package.json +1 -1
- package/templates/fighting-game/src/game/stage.ts +18 -4
- package/templates/fighting-game/src/main.ts +3 -2
- package/templates/mini-game/package.json +1 -1
- package/templates/product-viewer/package.json +1 -1
- package/templates/prompt-cartoon-channel/package.json +1 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { episode, publicCartoonAssetInstructions, typedCartoonAssetSummary } from "./episode";
|
|
2
|
+
import { publishReadiness, renderPlan } from "./render-plan";
|
|
3
|
+
|
|
4
|
+
export const cartoonStudioSupport = {
|
|
5
|
+
template: "cartoon-studio",
|
|
6
|
+
panels: ["timeline", "assets", "performance", "render"] as const,
|
|
7
|
+
timelineTracks: [
|
|
8
|
+
{
|
|
9
|
+
id: "shots",
|
|
10
|
+
label: "Shots",
|
|
11
|
+
clips: episode.shotTimeline.shots.map((shot) => ({
|
|
12
|
+
id: shot.shotId,
|
|
13
|
+
startTime: shot.startTime,
|
|
14
|
+
endTime: shot.endTime,
|
|
15
|
+
cameraMove: shot.camera.move,
|
|
16
|
+
transitionOut: shot.transitionOut ?? "cut"
|
|
17
|
+
}))
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "dialogue",
|
|
21
|
+
label: "Dialogue",
|
|
22
|
+
clips: episode.dialogueTrack.lines.map((line) => ({
|
|
23
|
+
id: line.lineId,
|
|
24
|
+
speakerId: line.speakerId,
|
|
25
|
+
startTime: line.startTime,
|
|
26
|
+
endTime: line.endTime,
|
|
27
|
+
text: line.text
|
|
28
|
+
}))
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "render",
|
|
32
|
+
label: "Render",
|
|
33
|
+
clips: renderPlan.items.map((item) => ({
|
|
34
|
+
id: item.id,
|
|
35
|
+
time: item.time,
|
|
36
|
+
outputIds: item.outputIds,
|
|
37
|
+
width: item.viewport.width,
|
|
38
|
+
height: item.viewport.height
|
|
39
|
+
}))
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
assetLibrary: {
|
|
43
|
+
requiredCharacters: typedCartoonAssetSummary.requiredCharacterAssets,
|
|
44
|
+
optionalProps: typedCartoonAssetSummary.optionalPropAssets,
|
|
45
|
+
missingCharacters: typedCartoonAssetSummary.missingCharacterAssets,
|
|
46
|
+
commands: publicCartoonAssetInstructions
|
|
47
|
+
},
|
|
48
|
+
renderPipeline: {
|
|
49
|
+
outputs: renderPlan.outputs.map((output) => output.kind),
|
|
50
|
+
itemCount: renderPlan.items.length,
|
|
51
|
+
publishReadyFromCurrentEvidence: publishReadiness.ready,
|
|
52
|
+
issueCount: publishReadiness.issues.length
|
|
53
|
+
}
|
|
54
|
+
} as const;
|
|
55
|
+
|
|
56
|
+
export function installCartoonStudioPanel(target: HTMLElement): void {
|
|
57
|
+
const panel = document.createElement("section");
|
|
58
|
+
panel.id = "cartoon-studio-panel";
|
|
59
|
+
panel.style.cssText = [
|
|
60
|
+
"position:fixed",
|
|
61
|
+
"left:18px",
|
|
62
|
+
"top:18px",
|
|
63
|
+
"width:min(360px,calc(100vw - 36px))",
|
|
64
|
+
"display:grid",
|
|
65
|
+
"grid-template-columns:repeat(4,1fr)",
|
|
66
|
+
"gap:6px",
|
|
67
|
+
"padding:10px",
|
|
68
|
+
"border:1px solid rgba(248,255,242,0.22)",
|
|
69
|
+
"border-radius:8px",
|
|
70
|
+
"background:rgba(3,12,20,0.78)",
|
|
71
|
+
"color:#f8fff2",
|
|
72
|
+
"font:600 12px/1.2 system-ui,sans-serif",
|
|
73
|
+
"z-index:9"
|
|
74
|
+
].join(";");
|
|
75
|
+
|
|
76
|
+
for (const name of cartoonStudioSupport.panels) {
|
|
77
|
+
const button = document.createElement("button");
|
|
78
|
+
button.type = "button";
|
|
79
|
+
button.textContent = name;
|
|
80
|
+
button.dataset.panel = name;
|
|
81
|
+
button.style.cssText = [
|
|
82
|
+
"min-width:0",
|
|
83
|
+
"height:30px",
|
|
84
|
+
"border:1px solid rgba(125,226,255,0.42)",
|
|
85
|
+
"border-radius:6px",
|
|
86
|
+
"background:rgba(24,45,63,0.84)",
|
|
87
|
+
"color:#f8fff2",
|
|
88
|
+
"font:inherit",
|
|
89
|
+
"text-transform:capitalize"
|
|
90
|
+
].join(";");
|
|
91
|
+
panel.appendChild(button);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const status = document.createElement("div");
|
|
95
|
+
status.id = "cartoon-studio-status";
|
|
96
|
+
status.textContent = `${episode.shotTimeline.shots.length} shots | ${episode.dialogueTrack.lines.length} lines | ${renderPlan.items.length} render cues`;
|
|
97
|
+
status.style.cssText = "grid-column:1 / -1;color:#7de2ff;white-space:normal";
|
|
98
|
+
panel.appendChild(status);
|
|
99
|
+
|
|
100
|
+
target.appendChild(panel);
|
|
101
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { expect, test } from "@playwright/test";
|
|
2
|
+
|
|
3
|
+
test("cartoon studio storyboard caption renders", async ({ page }) => {
|
|
4
|
+
await page.goto("/");
|
|
5
|
+
await expect(page.getByText(/Aura3D cartoon studio|moon|robot/i)).toBeVisible();
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
test("storyboard playback, character performance, caption timing, cuts, and nonblank cartoon frames are sourced", async ({
|
|
9
|
+
page
|
|
10
|
+
}) => {
|
|
11
|
+
await page.goto("/");
|
|
12
|
+
|
|
13
|
+
const routeProof = (await page.evaluate(() => {
|
|
14
|
+
const template = (window as unknown as {
|
|
15
|
+
__AURA3D_CARTOON_TEMPLATE__?: {
|
|
16
|
+
shotIds: readonly string[];
|
|
17
|
+
captionIds: readonly string[];
|
|
18
|
+
storyBible?: unknown;
|
|
19
|
+
studio?: unknown;
|
|
20
|
+
playbackProbeSamples: readonly unknown[];
|
|
21
|
+
sampleAt(time: number): unknown;
|
|
22
|
+
};
|
|
23
|
+
}).__AURA3D_CARTOON_TEMPLATE__;
|
|
24
|
+
return {
|
|
25
|
+
shotIds: template?.shotIds ?? [],
|
|
26
|
+
captionIds: template?.captionIds ?? [],
|
|
27
|
+
storyBible: template?.storyBible,
|
|
28
|
+
studio: template?.studio,
|
|
29
|
+
samples: [1, 21, 43].map((time) => template?.sampleAt(time)),
|
|
30
|
+
playbackProbeSamples: template?.playbackProbeSamples ?? [],
|
|
31
|
+
bodyShotCount: document.body.dataset.cartoonShotCount,
|
|
32
|
+
bodyCaptionCount: document.body.dataset.cartoonCaptionCount,
|
|
33
|
+
bodyPanels: document.body.dataset.cartoonStudioPanels
|
|
34
|
+
};
|
|
35
|
+
})) as {
|
|
36
|
+
shotIds: string[];
|
|
37
|
+
captionIds: string[];
|
|
38
|
+
storyBible?: {
|
|
39
|
+
props?: unknown[];
|
|
40
|
+
styleGuide?: { visualStyle?: string };
|
|
41
|
+
shotList?: unknown[];
|
|
42
|
+
};
|
|
43
|
+
studio?: {
|
|
44
|
+
panels?: readonly string[];
|
|
45
|
+
timelineTracks?: readonly { id: string; clips: readonly unknown[] }[];
|
|
46
|
+
assetLibrary?: { commands?: readonly string[] };
|
|
47
|
+
renderPipeline?: { itemCount?: number };
|
|
48
|
+
};
|
|
49
|
+
samples: Array<{
|
|
50
|
+
shotId?: string;
|
|
51
|
+
captionId?: string;
|
|
52
|
+
captionText?: string;
|
|
53
|
+
cameraMove?: string;
|
|
54
|
+
transitionOut?: string;
|
|
55
|
+
nodeUpdates?: Array<{ characterId?: string; action?: string; emotion?: string }>;
|
|
56
|
+
}>;
|
|
57
|
+
playbackProbeSamples: unknown[];
|
|
58
|
+
bodyShotCount?: string;
|
|
59
|
+
bodyCaptionCount?: string;
|
|
60
|
+
bodyPanels?: string;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
expect(routeProof.shotIds).toEqual([
|
|
64
|
+
"shot-moon-garden-open",
|
|
65
|
+
"shot-glow-stone-teamwork",
|
|
66
|
+
"shot-moon-garden-finish"
|
|
67
|
+
]);
|
|
68
|
+
expect(new Set(routeProof.samples.map((sample) => sample.shotId)).size).toBe(3);
|
|
69
|
+
expect(routeProof.captionIds).toHaveLength(6);
|
|
70
|
+
expect(routeProof.samples.every((sample) => sample.captionId && sample.captionText)).toBe(true);
|
|
71
|
+
expect(routeProof.samples.some((sample) => sample.cameraMove === "push-in" || sample.transitionOut === "cut")).toBe(true);
|
|
72
|
+
expect(routeProof.samples.flatMap((sample) => sample.nodeUpdates ?? []).some((update) => update.action === "speak")).toBe(true);
|
|
73
|
+
expect(routeProof.samples.flatMap((sample) => sample.nodeUpdates ?? []).some((update) => update.characterId === "miko")).toBe(true);
|
|
74
|
+
expect(routeProof.samples.flatMap((sample) => sample.nodeUpdates ?? []).some((update) => update.characterId === "luma")).toBe(true);
|
|
75
|
+
expect(routeProof.storyBible?.props?.length).toBeGreaterThanOrEqual(3);
|
|
76
|
+
expect(routeProof.storyBible?.styleGuide?.visualStyle).toMatch(/cartoon/i);
|
|
77
|
+
expect(routeProof.storyBible?.shotList).toHaveLength(3);
|
|
78
|
+
expect(routeProof.playbackProbeSamples).toHaveLength(3);
|
|
79
|
+
expect(routeProof.bodyShotCount).toBe("3");
|
|
80
|
+
expect(routeProof.bodyCaptionCount).toBe("6");
|
|
81
|
+
expect(routeProof.studio?.panels).toEqual(["timeline", "assets", "performance", "render"]);
|
|
82
|
+
expect(routeProof.studio?.timelineTracks?.map((track) => track.id)).toEqual(["shots", "dialogue", "render"]);
|
|
83
|
+
expect(routeProof.studio?.timelineTracks?.every((track) => track.clips.length > 0)).toBe(true);
|
|
84
|
+
expect(routeProof.studio?.assetLibrary?.commands?.some((command) => command.includes("assets validate-cartoon"))).toBe(true);
|
|
85
|
+
expect(routeProof.studio?.renderPipeline?.itemCount).toBeGreaterThan(0);
|
|
86
|
+
expect(routeProof.bodyPanels).toBe("timeline,assets,performance,render");
|
|
87
|
+
await expect(page.locator("#cartoon-studio-panel")).toBeVisible();
|
|
88
|
+
|
|
89
|
+
const screenshot = await page.screenshot();
|
|
90
|
+
expect(screenshot.byteLength).toBeGreaterThan(2048);
|
|
91
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Aura3D Episode Builder Template
|
|
2
|
+
|
|
3
|
+
This template demonstrates a guided prompt-to-episode builder on top of the
|
|
4
|
+
AuraVoice-to-Aura3D prompt-animation contract.
|
|
5
|
+
|
|
6
|
+
It uses:
|
|
7
|
+
|
|
8
|
+
- `compilePromptEpisodePlan(...)` for prompt-to-episode planning.
|
|
9
|
+
- Optional typed GLB characters from `./src/aura-assets` with primitive runtime fallbacks until assets are added.
|
|
10
|
+
- `createShotPlaybackPlan(...)` plus `installShotPlayback(...)` so `app.onFrame` updates nodes without recreating the app.
|
|
11
|
+
- `createAuraVoiceBridgePackage(...)`, `validateAuraVoiceBridgePackage(...)`, `collectPromptAnimationEvidence(...)`, and `evaluatePromptAnimationPublishReadiness(...)` for source-level AuraVoice/Aura3D handoff declarations.
|
|
12
|
+
- Caption HUD and caption timing proof metadata.
|
|
13
|
+
- Render queue metadata and three deterministic screenshot fixture records.
|
|
14
|
+
- Child-safe, reduced-motion, and high-contrast accessibility proof defaults.
|
|
15
|
+
- Primitive-mouth and typed-GLB viseme examples.
|
|
16
|
+
- Phoneme/viseme/dub source proof metadata for stable shot, storyboard, caption, line, and word timing ids.
|
|
17
|
+
- Episode format choices for short-form, standard, pilot, educational, and music-video structures.
|
|
18
|
+
- Wizard state that points at the compiled episode plan, beats, characters, and publish-evidence status.
|
|
19
|
+
- A compact builder panel for route tests and agent inspection.
|
|
20
|
+
|
|
21
|
+
Replace primitive characters with typed GLB assets by running:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx @aura3d/cli@latest assets add ./assets/miko.glb --name miko
|
|
25
|
+
npx @aura3d/cli@latest assets add ./assets/luma.glb --name luma
|
|
26
|
+
npx @aura3d/cli@latest assets validate-cartoon
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Then import `assets.miko` and `assets.luma` from `src/aura-assets.ts` and pass them to `model(assets.miko)` and `model(assets.luma)`.
|
|
30
|
+
|
|
31
|
+
The GLB path must keep typed assets:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { model } from "@aura3d/engine";
|
|
35
|
+
import { assets } from "./aura-assets";
|
|
36
|
+
|
|
37
|
+
model(assets.miko);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Do not replace this with a string asset id or a raw loader.
|
|
41
|
+
|
|
42
|
+
This scaffold intentionally does not claim publish readiness from source alone.
|
|
43
|
+
Before closing build, route, asset, screenshot, render, or visual-quality gates,
|
|
44
|
+
archive the matching `npm run build`, `assets validate-cartoon`, browser
|
|
45
|
+
evidence, screenshot hashes, render outputs, and human or automated review
|
|
46
|
+
artifacts.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Aura3D Episode Builder</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="/src/main.ts"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
13
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aura3d-episode-builder",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite --host 0.0.0.0",
|
|
8
|
+
"typecheck": "tsc --noEmit",
|
|
9
|
+
"build": "npm run typecheck && vite build",
|
|
10
|
+
"preview": "vite preview --host 0.0.0.0",
|
|
11
|
+
"test": "playwright test tests/route-health.spec.ts tests/storyboard-playback.spec.ts --workers=1"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@aura3d/engine": "1.0.10"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@playwright/test": "^1.52.0",
|
|
18
|
+
"typescript": "^5.9.3",
|
|
19
|
+
"vite": "^7.2.4"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineConfig } from "@playwright/test";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
webServer: {
|
|
5
|
+
command: "npm run dev -- --port 4181",
|
|
6
|
+
url: "http://127.0.0.1:4181",
|
|
7
|
+
reuseExistingServer: !process.env.CI
|
|
8
|
+
},
|
|
9
|
+
use: {
|
|
10
|
+
baseURL: "http://127.0.0.1:4181"
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineAuraAssets } from "@aura3d/engine";
|
|
2
|
+
import { AURAVOICE_AURA3D_PROMPT_ANIMATION_CONTRACT_ID } from "./contract";
|
|
3
|
+
|
|
4
|
+
export const assetContractId = AURAVOICE_AURA3D_PROMPT_ANIMATION_CONTRACT_ID;
|
|
5
|
+
|
|
6
|
+
export const assets = defineAuraAssets({
|
|
7
|
+
/*
|
|
8
|
+
* Add character GLBs with the Aura3D CLI, then keep these generated keys:
|
|
9
|
+
*
|
|
10
|
+
* npx @aura3d/cli@latest assets add ./assets/miko.glb --name miko
|
|
11
|
+
* npx @aura3d/cli@latest assets add ./assets/luma.glb --name luma
|
|
12
|
+
* npx @aura3d/cli@latest assets validate-cartoon
|
|
13
|
+
*/
|
|
14
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { episode, publicCartoonAssetInstructions, typedCartoonAssetSummary } from "./episode";
|
|
2
|
+
import { publishReadiness } from "./render-plan";
|
|
3
|
+
|
|
4
|
+
export const episodeBuilderSupport = {
|
|
5
|
+
template: "episode-builder",
|
|
6
|
+
formats: [
|
|
7
|
+
{ id: "short-form", label: "Short-form", targetMinutes: "1-3", beats: "3-5", locations: "single" },
|
|
8
|
+
{ id: "standard", label: "Standard", targetMinutes: "5-7", beats: "8-12", locations: "multi" },
|
|
9
|
+
{ id: "series-pilot", label: "Series pilot", targetMinutes: "10-15", beats: "12-20", locations: "multi" },
|
|
10
|
+
{ id: "educational", label: "Educational", targetMinutes: "3-5", beats: "topic segments", locations: "guided" },
|
|
11
|
+
{ id: "music-video", label: "Music video", targetMinutes: "2-4", beats: "song sections", locations: "choreographed" }
|
|
12
|
+
] as const,
|
|
13
|
+
wizardSteps: [
|
|
14
|
+
{ id: "prompt", label: "Prompt", complete: true },
|
|
15
|
+
{ id: "format", label: "Format", complete: true },
|
|
16
|
+
{ id: "characters", label: "Characters", complete: episode.episodePlan.characters.length >= 2 },
|
|
17
|
+
{ id: "beats", label: "Beats", complete: episode.shotTimeline.shots.length >= 3 },
|
|
18
|
+
{ id: "publish", label: "Publish", complete: publishReadiness.ready }
|
|
19
|
+
] as const,
|
|
20
|
+
compiledEpisode: {
|
|
21
|
+
episodeId: episode.episodePlan.episodeId,
|
|
22
|
+
title: episode.episodePlan.title,
|
|
23
|
+
sourcePrompt: episode.episodePlan.production.sourcePrompt,
|
|
24
|
+
shotCount: episode.shotTimeline.shots.length,
|
|
25
|
+
captionCount: episode.captionTrack.cues.length,
|
|
26
|
+
renderQueueItems: episode.renderQueue.items.length
|
|
27
|
+
},
|
|
28
|
+
typedAssets: {
|
|
29
|
+
requiredCharacters: typedCartoonAssetSummary.requiredCharacterAssets,
|
|
30
|
+
missingCharacters: typedCartoonAssetSummary.missingCharacterAssets,
|
|
31
|
+
commands: publicCartoonAssetInstructions
|
|
32
|
+
}
|
|
33
|
+
} as const;
|
|
34
|
+
|
|
35
|
+
export function installEpisodeBuilderPanel(target: HTMLElement): void {
|
|
36
|
+
const panel = document.createElement("section");
|
|
37
|
+
panel.id = "episode-builder-panel";
|
|
38
|
+
panel.style.cssText = [
|
|
39
|
+
"position:fixed",
|
|
40
|
+
"left:18px",
|
|
41
|
+
"top:18px",
|
|
42
|
+
"width:min(390px,calc(100vw - 36px))",
|
|
43
|
+
"display:grid",
|
|
44
|
+
"gap:8px",
|
|
45
|
+
"padding:12px",
|
|
46
|
+
"border:1px solid rgba(248,255,242,0.22)",
|
|
47
|
+
"border-radius:8px",
|
|
48
|
+
"background:rgba(3,12,20,0.78)",
|
|
49
|
+
"color:#f8fff2",
|
|
50
|
+
"font:600 12px/1.25 system-ui,sans-serif",
|
|
51
|
+
"z-index:9"
|
|
52
|
+
].join(";");
|
|
53
|
+
|
|
54
|
+
const format = document.createElement("select");
|
|
55
|
+
format.id = "episode-format";
|
|
56
|
+
format.style.cssText = "height:32px;border-radius:6px;background:#182d3f;color:#f8fff2;border:1px solid rgba(125,226,255,0.42)";
|
|
57
|
+
for (const option of episodeBuilderSupport.formats) {
|
|
58
|
+
const element = document.createElement("option");
|
|
59
|
+
element.value = option.id;
|
|
60
|
+
element.textContent = option.label;
|
|
61
|
+
format.appendChild(element);
|
|
62
|
+
}
|
|
63
|
+
panel.appendChild(format);
|
|
64
|
+
|
|
65
|
+
const steps = document.createElement("div");
|
|
66
|
+
steps.id = "episode-builder-steps";
|
|
67
|
+
steps.textContent = episodeBuilderSupport.wizardSteps.map((step) => `${step.label}:${step.complete ? "ready" : "needs evidence"}`).join(" | ");
|
|
68
|
+
steps.style.cssText = "color:#7de2ff;white-space:normal";
|
|
69
|
+
panel.appendChild(steps);
|
|
70
|
+
|
|
71
|
+
const compiled = document.createElement("div");
|
|
72
|
+
compiled.id = "episode-builder-compiled-plan";
|
|
73
|
+
compiled.textContent = `${episodeBuilderSupport.compiledEpisode.shotCount} shots | ${episodeBuilderSupport.compiledEpisode.captionCount} captions`;
|
|
74
|
+
compiled.style.cssText = "color:#f8fff2;white-space:normal";
|
|
75
|
+
panel.appendChild(compiled);
|
|
76
|
+
|
|
77
|
+
target.appendChild(panel);
|
|
78
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { AURAVOICE_AURA3D_PROMPT_ANIMATION_CONTRACT_ID } from "./contract";
|
|
2
|
+
|
|
3
|
+
export const characterContractId = AURAVOICE_AURA3D_PROMPT_ANIMATION_CONTRACT_ID;
|
|
4
|
+
|
|
5
|
+
export const characters = [
|
|
6
|
+
{
|
|
7
|
+
id: "miko",
|
|
8
|
+
name: "Miko",
|
|
9
|
+
palette: ["#7de2ff", "#f7ffe8"],
|
|
10
|
+
primitiveFallback: "round robot with antenna",
|
|
11
|
+
typedAssetKey: "miko",
|
|
12
|
+
runtimeNodeId: "miko",
|
|
13
|
+
primitiveMouthNodeId: "miko:mouth",
|
|
14
|
+
performanceChannels: ["body", "facial", "gesture", "blocking", "gaze"],
|
|
15
|
+
glbUpgrade: "After assets add, use model(assets.miko) and keep viseme blendshape metadata."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "luma",
|
|
19
|
+
name: "Luma",
|
|
20
|
+
palette: ["#ffe18e", "#40ffbf"],
|
|
21
|
+
primitiveFallback: "small moon-garden helper",
|
|
22
|
+
typedAssetKey: "luma",
|
|
23
|
+
runtimeNodeId: "luma",
|
|
24
|
+
primitiveMouthNodeId: "luma:mouth",
|
|
25
|
+
performanceChannels: ["body", "facial", "gesture", "blocking", "gaze"],
|
|
26
|
+
glbUpgrade: "After assets add, use model(assets.luma) and keep viseme blendshape metadata."
|
|
27
|
+
}
|
|
28
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const AURAVOICE_AURA3D_PROMPT_ANIMATION_CONTRACT_ID = "auravoice-aura3d-prompt-animation/v1" as const;
|