@cardstack/choreo 0.0.0 → 0.1.0-unstable.1

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.
Files changed (165) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/LICENSE +21 -0
  3. package/README.md +55 -6
  4. package/addon-main.cjs +4 -0
  5. package/declarations/anchors.d.ts +26 -0
  6. package/declarations/anchors.d.ts.map +1 -0
  7. package/declarations/arming.d.ts +33 -0
  8. package/declarations/arming.d.ts.map +1 -0
  9. package/declarations/beacon.d.ts +9 -0
  10. package/declarations/beacon.d.ts.map +1 -0
  11. package/declarations/beacons.d.ts +23 -0
  12. package/declarations/beacons.d.ts.map +1 -0
  13. package/declarations/changeset.d.ts +46 -0
  14. package/declarations/changeset.d.ts.map +1 -0
  15. package/declarations/choreo.d.ts +261 -0
  16. package/declarations/choreo.d.ts.map +1 -0
  17. package/declarations/compile.d.ts +45 -0
  18. package/declarations/compile.d.ts.map +1 -0
  19. package/declarations/deliver.d.ts +44 -0
  20. package/declarations/deliver.d.ts.map +1 -0
  21. package/declarations/easings.d.ts +20 -0
  22. package/declarations/easings.d.ts.map +1 -0
  23. package/declarations/far.d.ts +33 -0
  24. package/declarations/far.d.ts.map +1 -0
  25. package/declarations/film/clip.d.ts +51 -0
  26. package/declarations/film/clip.d.ts.map +1 -0
  27. package/declarations/film/clips.d.ts +155 -0
  28. package/declarations/film/clips.d.ts.map +1 -0
  29. package/declarations/film/film.d.ts +1208 -0
  30. package/declarations/film/film.d.ts.map +1 -0
  31. package/declarations/film/graph/adjust.d.ts +112 -0
  32. package/declarations/film/graph/adjust.d.ts.map +1 -0
  33. package/declarations/film/graph/compile.d.ts +140 -0
  34. package/declarations/film/graph/compile.d.ts.map +1 -0
  35. package/declarations/film/graph/host.d.ts +67 -0
  36. package/declarations/film/graph/host.d.ts.map +1 -0
  37. package/declarations/film/graph/nodes.d.ts +287 -0
  38. package/declarations/film/graph/nodes.d.ts.map +1 -0
  39. package/declarations/film/index.d.ts +24 -0
  40. package/declarations/film/index.d.ts.map +1 -0
  41. package/declarations/film/joins.d.ts +143 -0
  42. package/declarations/film/joins.d.ts.map +1 -0
  43. package/declarations/film/math.d.ts +15 -0
  44. package/declarations/film/math.d.ts.map +1 -0
  45. package/declarations/film/overlays.d.ts +54 -0
  46. package/declarations/film/overlays.d.ts.map +1 -0
  47. package/declarations/film/picture.d.ts +104 -0
  48. package/declarations/film/picture.d.ts.map +1 -0
  49. package/declarations/film/plate.d.ts +37 -0
  50. package/declarations/film/plate.d.ts.map +1 -0
  51. package/declarations/film/player.d.ts +120 -0
  52. package/declarations/film/player.d.ts.map +1 -0
  53. package/declarations/film/rail.d.ts +40 -0
  54. package/declarations/film/rail.d.ts.map +1 -0
  55. package/declarations/film/schedule.d.ts +93 -0
  56. package/declarations/film/schedule.d.ts.map +1 -0
  57. package/declarations/film/seam.d.ts +38 -0
  58. package/declarations/film/seam.d.ts.map +1 -0
  59. package/declarations/film/titles.d.ts +37 -0
  60. package/declarations/film/titles.d.ts.map +1 -0
  61. package/declarations/film/types.d.ts +544 -0
  62. package/declarations/film/types.d.ts.map +1 -0
  63. package/declarations/film.d.ts +3 -0
  64. package/declarations/film.d.ts.map +1 -0
  65. package/declarations/gesture.d.ts +33 -0
  66. package/declarations/gesture.d.ts.map +1 -0
  67. package/declarations/index.d.ts +26 -0
  68. package/declarations/index.d.ts.map +1 -0
  69. package/declarations/measure.d.ts +29 -0
  70. package/declarations/measure.d.ts.map +1 -0
  71. package/declarations/path.d.ts +73 -0
  72. package/declarations/path.d.ts.map +1 -0
  73. package/declarations/registry.d.ts +46 -0
  74. package/declarations/registry.d.ts.map +1 -0
  75. package/declarations/run.d.ts +406 -0
  76. package/declarations/run.d.ts.map +1 -0
  77. package/declarations/space.d.ts +31 -0
  78. package/declarations/space.d.ts.map +1 -0
  79. package/declarations/steps.d.ts +479 -0
  80. package/declarations/steps.d.ts.map +1 -0
  81. package/declarations/test-support/index.d.ts +30 -0
  82. package/declarations/test-support/index.d.ts.map +1 -0
  83. package/declarations/types.d.ts +761 -0
  84. package/declarations/types.d.ts.map +1 -0
  85. package/dist/anchors.js +34 -0
  86. package/dist/anchors.js.map +1 -0
  87. package/dist/arming.js +120 -0
  88. package/dist/arming.js.map +1 -0
  89. package/dist/beacon.js +25 -0
  90. package/dist/beacon.js.map +1 -0
  91. package/dist/beacons.js +77 -0
  92. package/dist/beacons.js.map +1 -0
  93. package/dist/changeset.js +129 -0
  94. package/dist/changeset.js.map +1 -0
  95. package/dist/choreo.js +1026 -0
  96. package/dist/choreo.js.map +1 -0
  97. package/dist/compile.js +1403 -0
  98. package/dist/compile.js.map +1 -0
  99. package/dist/deliver.js +326 -0
  100. package/dist/deliver.js.map +1 -0
  101. package/dist/easings.js +39 -0
  102. package/dist/easings.js.map +1 -0
  103. package/dist/far.js +147 -0
  104. package/dist/far.js.map +1 -0
  105. package/dist/film/clip.js +100 -0
  106. package/dist/film/clip.js.map +1 -0
  107. package/dist/film/clips.js +147 -0
  108. package/dist/film/clips.js.map +1 -0
  109. package/dist/film/film.js +4424 -0
  110. package/dist/film/film.js.map +1 -0
  111. package/dist/film/graph/adjust.js +160 -0
  112. package/dist/film/graph/adjust.js.map +1 -0
  113. package/dist/film/graph/compile.js +225 -0
  114. package/dist/film/graph/compile.js.map +1 -0
  115. package/dist/film/graph/host.js +77 -0
  116. package/dist/film/graph/host.js.map +1 -0
  117. package/dist/film/graph/nodes.js +500 -0
  118. package/dist/film/graph/nodes.js.map +1 -0
  119. package/dist/film/index.js +18 -0
  120. package/dist/film/index.js.map +1 -0
  121. package/dist/film/joins.js +260 -0
  122. package/dist/film/joins.js.map +1 -0
  123. package/dist/film/math.js +49 -0
  124. package/dist/film/math.js.map +1 -0
  125. package/dist/film/overlays.js +66 -0
  126. package/dist/film/overlays.js.map +1 -0
  127. package/dist/film/picture.js +58 -0
  128. package/dist/film/picture.js.map +1 -0
  129. package/dist/film/plate.js +36 -0
  130. package/dist/film/plate.js.map +1 -0
  131. package/dist/film/player.js +79 -0
  132. package/dist/film/player.js.map +1 -0
  133. package/dist/film/rail.js +38 -0
  134. package/dist/film/rail.js.map +1 -0
  135. package/dist/film/schedule.js +238 -0
  136. package/dist/film/schedule.js.map +1 -0
  137. package/dist/film/seam.js +64 -0
  138. package/dist/film/seam.js.map +1 -0
  139. package/dist/film/titles.js +45 -0
  140. package/dist/film/titles.js.map +1 -0
  141. package/dist/film/types.js +2 -0
  142. package/dist/film/types.js.map +1 -0
  143. package/dist/film.js +18 -0
  144. package/dist/film.js.map +1 -0
  145. package/dist/gesture.js +111 -0
  146. package/dist/gesture.js.map +1 -0
  147. package/dist/index.js +9 -0
  148. package/dist/index.js.map +1 -0
  149. package/dist/measure.js +99 -0
  150. package/dist/measure.js.map +1 -0
  151. package/dist/path.js +272 -0
  152. package/dist/path.js.map +1 -0
  153. package/dist/registry.js +55 -0
  154. package/dist/registry.js.map +1 -0
  155. package/dist/run.js +2423 -0
  156. package/dist/run.js.map +1 -0
  157. package/dist/space.js +57 -0
  158. package/dist/space.js.map +1 -0
  159. package/dist/steps.js +831 -0
  160. package/dist/steps.js.map +1 -0
  161. package/dist/test-support/index.js +150 -0
  162. package/dist/test-support/index.js.map +1 -0
  163. package/dist/types.js +2 -0
  164. package/dist/types.js.map +1 -0
  165. package/package.json +201 -6
@@ -0,0 +1,160 @@
1
+ import { ClipLookNode, PatchComponent } from './nodes.js';
2
+
3
+ /**
4
+ * ADJUSTMENTS — the picture's own knobs, held for a shot (or a chapter, or
5
+ * a group), as typed components the actor declares and the film yields.
6
+ *
7
+ * An adjustment is a value held on an actor for a window, applying to
8
+ * everything under it — After Effects' adjustment layer, FCPXML's
9
+ * `adjust-*`, Unity's volume overrides. A FILTER is the kind of adjustment
10
+ * that processes the frame — a grade, a stock, a look — Motion's word,
11
+ * MLT's, CSS's. Photoshop draws the line: a filter is a pixel operation,
12
+ * an adjustment is a parameter held above the stack.
13
+ *
14
+ * The package ships the two base classes and nothing named after weather.
15
+ * The set below is what the IFRAME PICTURE — the WebGL page behind both
16
+ * reference films, addressed through the `Picture` port — declares; a
17
+ * third picture declares its own and never sees `haze`. Today they
18
+ * compile to fields on the row the engine reads; when the picture becomes
19
+ * an actor with ports, they write the ports.
20
+ */
21
+
22
+ /** a value held on an actor for the window it is attached to */
23
+ class Adjustment extends PatchComponent {}
24
+ /** an adjustment whose target is the frame: applied before a seam's still is taken */
25
+ class Filter extends Adjustment {}
26
+ /* ---- the iframe picture's set ------------------------------------------- */ /** the mood, the named look, and the stock — a filter: it processes the frame */
27
+ class Look extends Filter {
28
+ patch() {
29
+ return {
30
+ grade: this.args.grade,
31
+ look: this.args.look,
32
+ lut: this.args.lut
33
+ };
34
+ }
35
+ }
36
+ /** the hour, the weather, the air */
37
+ class Weather extends Adjustment {
38
+ patch() {
39
+ const a = this.args;
40
+ return {
41
+ haze: a.haze,
42
+ hours: a.hours,
43
+ hoursOver: a.over,
44
+ lightning: a.lightning,
45
+ rain: a.rain,
46
+ theme: a.theme,
47
+ wx: a.wx,
48
+ wxCut: a.wxCut
49
+ };
50
+ }
51
+ }
52
+ /** settled snow and a pinned blizzard; `@off` clears them */
53
+ class Winter extends Adjustment {
54
+ patch() {
55
+ if (this.args.off) {
56
+ return {
57
+ winter: null
58
+ };
59
+ }
60
+ return {
61
+ winter: {
62
+ gust: this.args.gust ?? 0,
63
+ pack: this.args.pack ?? 0
64
+ }
65
+ };
66
+ }
67
+ }
68
+ /** where the sun is, degrees */
69
+ class Sun extends Adjustment {
70
+ patch() {
71
+ return {
72
+ sun: {
73
+ az: this.args.az,
74
+ el: this.args.el
75
+ }
76
+ };
77
+ }
78
+ }
79
+ /** a backlight, standing opposite the lens */
80
+ class Light extends Adjustment {
81
+ patch() {
82
+ return {
83
+ rim: this.args.rim
84
+ };
85
+ }
86
+ }
87
+ /** the surroundings: the city, the field */
88
+ class Set extends Adjustment {
89
+ patch() {
90
+ return {
91
+ city: this.args.city,
92
+ grass: this.args.grass
93
+ };
94
+ }
95
+ }
96
+ /** the construction clock, how far through the shot it finishes, and which subject stands */
97
+ class Build extends Adjustment {
98
+ patch() {
99
+ const a = this.args;
100
+ return {
101
+ build: a.clock,
102
+ buildBy: a.by,
103
+ settle: a.settle,
104
+ style: a.subject
105
+ };
106
+ }
107
+ }
108
+ /* ---- the sound actor's set ---------------------------------------------- */ /** trims on the page's buses for the window */
109
+ class Mix extends Adjustment {
110
+ patch() {
111
+ const {
112
+ music,
113
+ sfx,
114
+ voice,
115
+ wx
116
+ } = this.args;
117
+ const mix = {};
118
+ if (music !== undefined) {
119
+ mix.music = music;
120
+ }
121
+ if (sfx !== undefined) {
122
+ mix.sfx = sfx;
123
+ }
124
+ if (voice !== undefined) {
125
+ mix.voice = voice;
126
+ }
127
+ if (wx !== undefined) {
128
+ mix.wx = wx;
129
+ }
130
+ return {
131
+ mix
132
+ };
133
+ }
134
+ }
135
+ /** what the iframe picture yields as `f.picture` */
136
+ const IFRAME_PICTURE = {
137
+ Build,
138
+ Light,
139
+ Look,
140
+ Set,
141
+ Sun,
142
+ Weather,
143
+ Winter
144
+ };
145
+ /** what the sound actor yields as `f.sound` */
146
+ const SOUND = {
147
+ Mix
148
+ };
149
+ /* ---- the clip actor's set ------------------------------------------------ *
150
+ * The first adjustments that belong to something other than the picture. A
151
+ * clip is a DOM element, so what it can be given is what a browser can do
152
+ * to one without a texture — which is the honest half of a filter stack,
153
+ * and the half that needs no pixels.
154
+ */
155
+ const CLIP_LOOK = {
156
+ Look: ClipLookNode
157
+ };
158
+
159
+ export { Adjustment, Build, CLIP_LOOK, Filter, IFRAME_PICTURE, Light, Look, Mix, SOUND, Set, Sun, Weather, Winter };
160
+ //# sourceMappingURL=adjust.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adjust.js","sources":["../../../src/film/graph/adjust.gts"],"sourcesContent":["/**\n * ADJUSTMENTS — the picture's own knobs, held for a shot (or a chapter, or\n * a group), as typed components the actor declares and the film yields.\n *\n * An adjustment is a value held on an actor for a window, applying to\n * everything under it — After Effects' adjustment layer, FCPXML's\n * `adjust-*`, Unity's volume overrides. A FILTER is the kind of adjustment\n * that processes the frame — a grade, a stock, a look — Motion's word,\n * MLT's, CSS's. Photoshop draws the line: a filter is a pixel operation,\n * an adjustment is a parameter held above the stack.\n *\n * The package ships the two base classes and nothing named after weather.\n * The set below is what the IFRAME PICTURE — the WebGL page behind both\n * reference films, addressed through the `Picture` port — declares; a\n * third picture declares its own and never sees `haze`. Today they\n * compile to fields on the row the engine reads; when the picture becomes\n * an actor with ports, they write the ports.\n */\nimport type { Beat } from '../types.ts';\nimport type { Patch } from './compile.ts';\nimport { ClipLookNode, PatchComponent } from './nodes.gts';\n\n/** a value held on an actor for the window it is attached to */\nexport abstract class Adjustment<A extends object> extends PatchComponent<A> {}\n\n/** an adjustment whose target is the frame: applied before a seam's still is taken */\nexport abstract class Filter<A extends object> extends Adjustment<A> {}\n\n/* ---- the iframe picture's set ------------------------------------------- */\n\n/** the mood, the named look, and the stock — a filter: it processes the frame */\nexport class Look extends Filter<{\n grade?: string;\n look?: string;\n lut?: null | string;\n}> {\n patch(): Patch {\n return { grade: this.args.grade, look: this.args.look, lut: this.args.lut };\n }\n}\n\n/** the hour, the weather, the air */\nexport class Weather extends Adjustment<{\n haze?: number;\n hours?: number[];\n lightning?: number;\n over?: number;\n rain?: number;\n theme?: number;\n wx?: number;\n wxCut?: boolean;\n}> {\n patch(): Patch {\n const a = this.args;\n return {\n haze: a.haze,\n hours: a.hours,\n hoursOver: a.over,\n lightning: a.lightning,\n rain: a.rain,\n theme: a.theme,\n wx: a.wx,\n wxCut: a.wxCut,\n };\n }\n}\n\n/** settled snow and a pinned blizzard; `@off` clears them */\nexport class Winter extends Adjustment<{\n gust?: number;\n off?: boolean;\n pack?: number;\n}> {\n patch(): Patch {\n if (this.args.off) {\n return { winter: null };\n }\n return { winter: { gust: this.args.gust ?? 0, pack: this.args.pack ?? 0 } };\n }\n}\n\n/** where the sun is, degrees */\nexport class Sun extends Adjustment<{ az: number; el: number }> {\n patch(): Patch {\n return { sun: { az: this.args.az, el: this.args.el } };\n }\n}\n\n/** a backlight, standing opposite the lens */\nexport class Light extends Adjustment<{ rim?: number }> {\n patch(): Patch {\n return { rim: this.args.rim };\n }\n}\n\n/** the surroundings: the city, the field */\nexport class Set extends Adjustment<{\n city?: Beat['city'];\n grass?: boolean;\n}> {\n patch(): Patch {\n return { city: this.args.city, grass: this.args.grass };\n }\n}\n\n/** the construction clock, how far through the shot it finishes, and which subject stands */\nexport class Build extends Adjustment<{\n by?: number;\n clock?: Beat['build'];\n settle?: number;\n subject?: number;\n}> {\n patch(): Patch {\n const a = this.args;\n return {\n build: a.clock,\n buildBy: a.by,\n settle: a.settle,\n style: a.subject,\n };\n }\n}\n\n/* ---- the sound actor's set ---------------------------------------------- */\n\n/** trims on the page's buses for the window */\nexport class Mix extends Adjustment<{\n music?: number;\n sfx?: number;\n voice?: number;\n wx?: number;\n}> {\n patch(): Patch {\n const { music, sfx, voice, wx } = this.args;\n const mix: NonNullable<Beat['mix']> = {};\n if (music !== undefined) {\n mix.music = music;\n }\n if (sfx !== undefined) {\n mix.sfx = sfx;\n }\n if (voice !== undefined) {\n mix.voice = voice;\n }\n if (wx !== undefined) {\n mix.wx = wx;\n }\n return { mix };\n }\n}\n\n/** what the iframe picture yields as `f.picture` */\nexport const IFRAME_PICTURE = { Build, Light, Look, Set, Sun, Weather, Winter };\n/** what the sound actor yields as `f.sound` */\nexport const SOUND = { Mix };\n\n/* ---- the clip actor's set ------------------------------------------------ *\n * The first adjustments that belong to something other than the picture. A\n * clip is a DOM element, so what it can be given is what a browser can do\n * to one without a texture — which is the honest half of a filter stack,\n * and the half that needs no pixels.\n */\nexport const CLIP_LOOK = { Look: ClipLookNode } as const;\n"],"names":["Adjustment","PatchComponent","Filter","Look","patch","grade","args","look","lut","Weather","a","haze","hours","hoursOver","over","lightning","rain","theme","wx","wxCut","Winter","off","winter","gust","pack","Sun","sun","az","el","Light","rim","Set","city","grass","Build","build","clock","buildBy","by","settle","style","subject","Mix","music","sfx","voice","mix","undefined","IFRAME_PICTURE","SOUND","CLIP_LOOK","ClipLookNode"],"mappings":"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"}
@@ -0,0 +1,225 @@
1
+ /**
2
+ * THE GRAPH, COMPILED TO THE TABLE.
3
+ *
4
+ * A film written as a graph — a spine of chapters and shots, a join as a
5
+ * sibling between two shots, everything else attached under the shot it
6
+ * belongs to — compiles to the same `Beat[]` and `Chapter[]` the engine
7
+ * has always run. That is the whole claim of Phase 2, and it is what
8
+ * makes the migration measurable: the graph a film writes and the table
9
+ * it used to write produce the same rows, to the key
10
+ * (`tests/integration/film/graph-test.gts`), and therefore the same
11
+ * schedule (`tests/fixtures/film/*.json`).
12
+ *
13
+ * Pure: a tree of plain nodes in, rows out. The components in
14
+ * `nodes.gts` build the tree from the template; nothing here knows Ember.
15
+ */
16
+
17
+ /** a patch on the row the shot compiles to: an attachment says what it adds */
18
+
19
+ /** a spine, a chapter or a sequence: a run of items with defaults for its shots */
20
+
21
+ /** a sibling between two shots: the seam INTO the next one */
22
+ /** a look a clip holds: collected by its clip, never by the beat */
23
+
24
+ /** the tail pose */
25
+
26
+ /** an eye-level walk */
27
+
28
+ /** an attachment that says what it adds to the row: type, air, a stamp, a trace */
29
+
30
+ /** the narration: the line, and the measured read the film cuts to */
31
+
32
+ /** a window over a region the film does not own: a photograph, a freeze, a video */
33
+
34
+ /** drop undefined members, so a row compares equal to one that never had the key */
35
+ function tidy(o) {
36
+ const out = {};
37
+ for (const [k, v] of Object.entries(o)) {
38
+ if (v !== undefined) {
39
+ out[k] = v;
40
+ }
41
+ }
42
+ return out;
43
+ }
44
+ function compileGraph(root) {
45
+ const beats = [];
46
+ const chapters = [];
47
+ const voSecs = {};
48
+ const voGain = {};
49
+ const presentations = {};
50
+ let ch = 0;
51
+ const walk = (group, inherited, joinDefault, overDefault) => {
52
+ if (group.role === 'chapter' && group.chapter) {
53
+ chapters.push(tidy(group.chapter));
54
+ ch = chapters.length - 1;
55
+ }
56
+ const scope = [...inherited, group.defaults, ...group.patches];
57
+ const seam = group.role === 'spine' ? undefined : group.join ?? joinDefault;
58
+ /* the spine's own `@over` is the film's default, the way its `@join`
59
+ is: carried on the compiled graph and resolved by the film, never
60
+ baked into the rows — so a table-fed film and a graph-fed one give
61
+ the same table, and the fixtures stay honest. A chapter's or a
62
+ sequence's `@over` IS baked, because it is not the default. */
63
+ const deep = group.role === 'spine' ? undefined : group.over ?? overDefault;
64
+ let pending;
65
+ for (const node of group.children) {
66
+ if (node.kind === 'group') {
67
+ walk(node, scope, seam, deep);
68
+ pending = undefined;
69
+ } else if (node.kind === 'join') {
70
+ if (!node.presentation && node.secs !== undefined) {
71
+ /* `<f.Join @presentation="ridged-burn" @secs={{0.8}} />` — a
72
+ length for a seam the film does not know, which is how a
73
+ picture-declared one gets its clock. It also lets a score
74
+ retime one of the film's own. */
75
+ presentations[node.join] = {
76
+ secs: node.secs
77
+ };
78
+ pending = node;
79
+ } else if (node.presentation) {
80
+ // a brought presentation is named for the film by its place in
81
+ // the score, so the row can carry a string like any other seam
82
+ const name = `presentation:${Object.keys(presentations).length + 1}`;
83
+ presentations[name] = {
84
+ component: node.presentation,
85
+ over: node.over,
86
+ secs: node.secs ?? 1
87
+ };
88
+ pending = {
89
+ ...node,
90
+ join: name
91
+ };
92
+ } else {
93
+ pending = node;
94
+ }
95
+ } else if (node.kind === 'shot') {
96
+ beats.push(row(node, scope, pending ?? seam, deep, ch, voSecs, voGain));
97
+ pending = undefined;
98
+ }
99
+ }
100
+ };
101
+ walk(root, []);
102
+ return {
103
+ beats,
104
+ chapters,
105
+ defaultJoin: root.join,
106
+ defaultOver: root.over,
107
+ presentations,
108
+ voGain,
109
+ voSecs
110
+ };
111
+ }
112
+ function row(shot, scope, seam, deep, ch, voSecs, voGain) {
113
+ let beat = {
114
+ cam: shot.cam,
115
+ ch,
116
+ id: shot.id,
117
+ mode: 'clear',
118
+ ticks: shot.ticks
119
+ };
120
+ const merge = p => {
121
+ beat = {
122
+ ...beat,
123
+ ...tidy(p)
124
+ };
125
+ };
126
+ for (const p of scope) {
127
+ merge(p);
128
+ }
129
+ merge(shot.facts);
130
+ if (seam) {
131
+ if (typeof seam === 'string') {
132
+ merge({
133
+ join: seam,
134
+ over: deep
135
+ });
136
+ } else {
137
+ merge({
138
+ dipTo: seam.dipTo,
139
+ join: seam.join,
140
+ over: seam.over ?? deep
141
+ });
142
+ }
143
+ }
144
+ const traces = [];
145
+ const clips = [];
146
+ for (const node of shot.children) {
147
+ switch (node.kind) {
148
+ case 'patch':
149
+ if (node.patch.trace) {
150
+ traces.push(...node.patch.trace);
151
+ const {
152
+ trace: _trace,
153
+ ...rest
154
+ } = node.patch;
155
+ merge(rest);
156
+ } else {
157
+ merge(node.patch);
158
+ }
159
+ break;
160
+ case 'to':
161
+ merge({
162
+ toCam: node.cam
163
+ });
164
+ break;
165
+ case 'eye':
166
+ merge({
167
+ eye: node.eye
168
+ });
169
+ break;
170
+ case 'voice':
171
+ merge({
172
+ hush: node.hush,
173
+ vo: node.line
174
+ });
175
+ if (node.read !== undefined) {
176
+ voSecs[shot.id] = node.read;
177
+ }
178
+ if (node.gain !== undefined) {
179
+ voGain[shot.id] = node.gain;
180
+ }
181
+ break;
182
+ case 'attach':
183
+ if (node.media?.kind === 'photo') {
184
+ const {
185
+ kind: _kind,
186
+ ...photo
187
+ } = node.media;
188
+ merge({
189
+ photo
190
+ });
191
+ } else if (node.media) {
192
+ const {
193
+ kind,
194
+ ...rest
195
+ } = node.media;
196
+ /* ACCUMULATED, not merged. A beat used to carry one clip, so a
197
+ second attachment on the same shot overwrote the first
198
+ silently; they are lanes now, and a clip that names none takes
199
+ its own position among them. */
200
+ clips.push(tidy({
201
+ ...rest,
202
+ at: node.at,
203
+ end: node.end,
204
+ for: node.for,
205
+ kind
206
+ }));
207
+ }
208
+ break;
209
+ }
210
+ }
211
+ if (clips.length) {
212
+ merge({
213
+ clips
214
+ });
215
+ }
216
+ if (traces.length) {
217
+ merge({
218
+ trace: traces
219
+ });
220
+ }
221
+ return tidy(beat);
222
+ }
223
+
224
+ export { compileGraph };
225
+ //# sourceMappingURL=compile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.js","sources":["../../../src/film/graph/compile.ts"],"sourcesContent":["/**\n * THE GRAPH, COMPILED TO THE TABLE.\n *\n * A film written as a graph — a spine of chapters and shots, a join as a\n * sibling between two shots, everything else attached under the shot it\n * belongs to — compiles to the same `Beat[]` and `Chapter[]` the engine\n * has always run. That is the whole claim of Phase 2, and it is what\n * makes the migration measurable: the graph a film writes and the table\n * it used to write produce the same rows, to the key\n * (`tests/integration/film/graph-test.gts`), and therefore the same\n * schedule (`tests/fixtures/film/*.json`).\n *\n * Pure: a tree of plain nodes in, rows out. The components in\n * `nodes.gts` build the tree from the template; nothing here knows Ember.\n */\nimport type { ClipLook, ClipSpec } from '../clips.ts';\nimport type { PresentationComponent } from '../joins.gts';\nimport type { Beat, Cam, Chapter, Join, JoinName, Over } from '../types.ts';\n\n/** a patch on the row the shot compiles to: an attachment says what it adds */\nexport type Patch = Partial<Beat>;\n\nexport type GraphNode =\n | AttachNode\n | EyeNode\n | GroupNode\n | JoinNode\n | LookNode\n | PatchNode\n | ShotNode\n | ToNode\n | VoiceNode;\n\n/** a spine, a chapter or a sequence: a run of items with defaults for its shots */\nexport interface GroupNode {\n /** a chapter's row in the chapter table; only a `chapter` group has one */\n chapter?: Chapter;\n children: GraphNode[];\n /** shot facts every shot in the group inherits unless it says otherwise (`@cut`, `@hold`, `@bob`) */\n defaults: Patch;\n /** the seam every shot in the group is entered through unless a join sibling says otherwise */\n join?: Join;\n kind: 'group';\n name?: string;\n /** how deep those seams go, unless a join sibling says otherwise */\n over?: Over;\n /** attachments placed directly under the group: in force for every shot in it */\n patches: Patch[];\n role: 'chapter' | 'sequence' | 'spine';\n}\n\n/** a sibling between two shots: the seam INTO the next one */\n/** a look a clip holds: collected by its clip, never by the beat */\nexport interface LookNode {\n kind: 'look';\n look: ClipLook;\n}\n\nexport interface JoinNode {\n dipTo?: string;\n join: JoinName;\n kind: 'join';\n /** how deep this seam goes: over the picture alone, or over the furniture too */\n over?: Over;\n /** a presentation the score brought: named for the film, registered with it */\n presentation?: PresentationComponent;\n /** seconds the seam holds the picture; a brought presentation says */\n secs?: number;\n}\n\nexport interface ShotNode {\n /** the head pose */\n cam: Cam;\n children: GraphNode[];\n /** the shot's own facts: cut, lead, lift, bob, hold, follow, to, dissolve, quality */\n facts: Patch;\n id: string;\n kind: 'shot';\n ticks: number;\n}\n\n/** the tail pose */\nexport interface ToNode {\n cam: Cam;\n kind: 'to';\n}\n\n/** an eye-level walk */\nexport interface EyeNode {\n eye: NonNullable<Beat['eye']>;\n kind: 'eye';\n}\n\n/** an attachment that says what it adds to the row: type, air, a stamp, a trace */\nexport interface PatchNode {\n kind: 'patch';\n patch: Patch;\n}\n\n/** the narration: the line, and the measured read the film cuts to */\nexport interface VoiceNode {\n gain?: number;\n hush?: boolean;\n kind: 'voice';\n line?: string;\n read?: number;\n}\n\n/** a window over a region the film does not own: a photograph, a freeze, a video */\nexport interface AttachNode {\n at?: number;\n end?: ClipSpec['end'];\n for?: number;\n kind: 'attach';\n media?:\n | { caption: string; credit: string; kind: 'photo'; src: string }\n | {\n caption?: string;\n credit?: string;\n /** a pip's own fade, seconds */\n fade?: number;\n fit?: ClipSpec['fit'];\n in?: number;\n kind: 'freeze' | 'image' | 'video';\n look?: ClipLook;\n out?: number;\n /** a pip's corner radius, percent of its width */\n radius?: number;\n rate?: number;\n src?: string;\n volume?: number;\n /** a pip's width, percent of the frame */\n w?: number;\n /** a pip's left edge, percent of the frame */\n x?: number;\n /** a pip's top edge, percent of the frame */\n y?: number;\n };\n}\n\nexport interface CompiledGraph {\n beats: Beat[];\n chapters: Chapter[];\n /** the spine's own seam: what a shot gets when nothing names one */\n defaultJoin?: Join;\n /** the spine's own depth: how deep a seam goes when nothing says */\n defaultOver?: Over;\n /** presentations the score brought, by the names its rows use */\n presentations: Record<\n string,\n { component?: PresentationComponent; over?: Over; secs: number }\n >;\n voGain: Record<string, number>;\n voSecs: Record<string, number>;\n}\n\n/** drop undefined members, so a row compares equal to one that never had the key */\nfunction tidy<T extends object>(o: T): T {\n const out = {} as T;\n for (const [k, v] of Object.entries(o)) {\n if (v !== undefined) {\n (out as Record<string, unknown>)[k] = v;\n }\n }\n return out;\n}\n\nexport function compileGraph(root: GroupNode): CompiledGraph {\n const beats: Beat[] = [];\n const chapters: Chapter[] = [];\n const voSecs: Record<string, number> = {};\n const voGain: Record<string, number> = {};\n const presentations: CompiledGraph['presentations'] = {};\n let ch = 0;\n\n const walk = (\n group: GroupNode,\n inherited: Patch[],\n joinDefault?: Join,\n overDefault?: Over,\n ) => {\n if (group.role === 'chapter' && group.chapter) {\n chapters.push(tidy(group.chapter));\n ch = chapters.length - 1;\n }\n const scope = [...inherited, group.defaults, ...group.patches];\n const seam =\n group.role === 'spine' ? undefined : (group.join ?? joinDefault);\n /* the spine's own `@over` is the film's default, the way its `@join`\n is: carried on the compiled graph and resolved by the film, never\n baked into the rows — so a table-fed film and a graph-fed one give\n the same table, and the fixtures stay honest. A chapter's or a\n sequence's `@over` IS baked, because it is not the default. */\n const deep =\n group.role === 'spine' ? undefined : (group.over ?? overDefault);\n let pending: JoinNode | undefined;\n for (const node of group.children) {\n if (node.kind === 'group') {\n walk(node, scope, seam, deep);\n pending = undefined;\n } else if (node.kind === 'join') {\n if (!node.presentation && node.secs !== undefined) {\n /* `<f.Join @presentation=\"ridged-burn\" @secs={{0.8}} />` — a\n length for a seam the film does not know, which is how a\n picture-declared one gets its clock. It also lets a score\n retime one of the film's own. */\n presentations[node.join] = { secs: node.secs };\n pending = node;\n } else if (node.presentation) {\n // a brought presentation is named for the film by its place in\n // the score, so the row can carry a string like any other seam\n const name = `presentation:${Object.keys(presentations).length + 1}`;\n presentations[name] = {\n component: node.presentation,\n over: node.over,\n secs: node.secs ?? 1,\n };\n pending = { ...node, join: name };\n } else {\n pending = node;\n }\n } else if (node.kind === 'shot') {\n beats.push(row(node, scope, pending ?? seam, deep, ch, voSecs, voGain));\n pending = undefined;\n }\n }\n };\n walk(root, []);\n return {\n beats,\n chapters,\n defaultJoin: root.join,\n defaultOver: root.over,\n presentations,\n voGain,\n voSecs,\n };\n}\n\nfunction row(\n shot: ShotNode,\n scope: Patch[],\n seam: JoinNode | Join | undefined,\n deep: Over | undefined,\n ch: number,\n voSecs: Record<string, number>,\n voGain: Record<string, number>,\n): Beat {\n let beat: Beat = {\n cam: shot.cam,\n ch,\n id: shot.id,\n mode: 'clear',\n ticks: shot.ticks,\n };\n const merge = (p: Patch) => {\n beat = { ...beat, ...tidy(p) };\n };\n for (const p of scope) {\n merge(p);\n }\n merge(shot.facts);\n if (seam) {\n if (typeof seam === 'string') {\n merge({ join: seam, over: deep });\n } else {\n merge({\n dipTo: seam.dipTo,\n join: seam.join,\n over: seam.over ?? deep,\n });\n }\n }\n const traces: NonNullable<Beat['trace']> = [];\n const clips: NonNullable<Beat['clips']> = [];\n for (const node of shot.children) {\n switch (node.kind) {\n case 'patch':\n if (node.patch.trace) {\n traces.push(...node.patch.trace);\n const { trace: _trace, ...rest } = node.patch;\n merge(rest);\n } else {\n merge(node.patch);\n }\n break;\n case 'to':\n merge({ toCam: node.cam });\n break;\n case 'eye':\n merge({ eye: node.eye });\n break;\n case 'voice':\n merge({ hush: node.hush, vo: node.line });\n if (node.read !== undefined) {\n voSecs[shot.id] = node.read;\n }\n if (node.gain !== undefined) {\n voGain[shot.id] = node.gain;\n }\n break;\n case 'attach':\n if (node.media?.kind === 'photo') {\n const { kind: _kind, ...photo } = node.media;\n merge({ photo });\n } else if (node.media) {\n const { kind, ...rest } = node.media;\n /* ACCUMULATED, not merged. A beat used to carry one clip, so a\n second attachment on the same shot overwrote the first\n silently; they are lanes now, and a clip that names none takes\n its own position among them. */\n clips.push(\n tidy({\n ...rest,\n at: node.at,\n end: node.end,\n for: node.for,\n kind,\n }),\n );\n }\n break;\n default:\n break;\n }\n }\n if (clips.length) {\n merge({ clips });\n }\n if (traces.length) {\n merge({ trace: traces });\n }\n return tidy(beat);\n}\n"],"names":["tidy","o","out","k","v","Object","entries","undefined","compileGraph","root","beats","chapters","voSecs","voGain","presentations","ch","walk","group","inherited","joinDefault","overDefault","role","chapter","push","length","scope","defaults","patches","seam","join","deep","over","pending","node","children","kind","presentation","secs","name","keys","component","row","defaultJoin","defaultOver","shot","beat","cam","id","mode","ticks","merge","p","facts","dipTo","traces","clips","patch","trace","_trace","rest","toCam","eye","hush","vo","line","read","gain","media","_kind","photo","at","end","for"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAKA;;AAcA;;AAkBA;AACA;;AA6BA;;AAMA;;AAMA;;AAMA;;AASA;;AAgDA;AACA,SAASA,IAAIA,CAAmBC,CAAI,EAAK;EACvC,MAAMC,GAAG,GAAG,EAAO;AACnB,EAAA,KAAK,MAAM,CAACC,CAAC,EAAEC,CAAC,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACL,CAAC,CAAC,EAAE;IACtC,IAAIG,CAAC,KAAKG,SAAS,EAAE;AAClBL,MAAAA,GAAG,CAA6BC,CAAC,CAAC,GAAGC,CAAC;AACzC,IAAA;AACF,EAAA;AACA,EAAA,OAAOF,GAAG;AACZ;AAEO,SAASM,YAAYA,CAACC,IAAe,EAAiB;EAC3D,MAAMC,KAAa,GAAG,EAAE;EACxB,MAAMC,QAAmB,GAAG,EAAE;EAC9B,MAAMC,MAA8B,GAAG,EAAE;EACzC,MAAMC,MAA8B,GAAG,EAAE;EACzC,MAAMC,aAA6C,GAAG,EAAE;EACxD,IAAIC,EAAE,GAAG,CAAC;EAEV,MAAMC,IAAI,GAAGA,CACXC,KAAgB,EAChBC,SAAkB,EAClBC,WAAkB,EAClBC,WAAkB,KACf;IACH,IAAIH,KAAK,CAACI,IAAI,KAAK,SAAS,IAAIJ,KAAK,CAACK,OAAO,EAAE;MAC7CX,QAAQ,CAACY,IAAI,CAACvB,IAAI,CAACiB,KAAK,CAACK,OAAO,CAAC,CAAC;AAClCP,MAAAA,EAAE,GAAGJ,QAAQ,CAACa,MAAM,GAAG,CAAC;AAC1B,IAAA;AACA,IAAA,MAAMC,KAAK,GAAG,CAAC,GAAGP,SAAS,EAAED,KAAK,CAACS,QAAQ,EAAE,GAAGT,KAAK,CAACU,OAAO,CAAC;AAC9D,IAAA,MAAMC,IAAI,GACRX,KAAK,CAACI,IAAI,KAAK,OAAO,GAAGd,SAAS,GAAIU,KAAK,CAACY,IAAI,IAAIV,WAAY;AAClE;AACJ;AACA;AACA;AACA;AACI,IAAA,MAAMW,IAAI,GACRb,KAAK,CAACI,IAAI,KAAK,OAAO,GAAGd,SAAS,GAAIU,KAAK,CAACc,IAAI,IAAIX,WAAY;AAClE,IAAA,IAAIY,OAA6B;AACjC,IAAA,KAAK,MAAMC,IAAI,IAAIhB,KAAK,CAACiB,QAAQ,EAAE;AACjC,MAAA,IAAID,IAAI,CAACE,IAAI,KAAK,OAAO,EAAE;QACzBnB,IAAI,CAACiB,IAAI,EAAER,KAAK,EAAEG,IAAI,EAAEE,IAAI,CAAC;AAC7BE,QAAAA,OAAO,GAAGzB,SAAS;AACrB,MAAA,CAAC,MAAM,IAAI0B,IAAI,CAACE,IAAI,KAAK,MAAM,EAAE;QAC/B,IAAI,CAACF,IAAI,CAACG,YAAY,IAAIH,IAAI,CAACI,IAAI,KAAK9B,SAAS,EAAE;AACjD;AACV;AACA;AACA;AACUO,UAAAA,aAAa,CAACmB,IAAI,CAACJ,IAAI,CAAC,GAAG;YAAEQ,IAAI,EAAEJ,IAAI,CAACI;WAAM;AAC9CL,UAAAA,OAAO,GAAGC,IAAI;AAChB,QAAA,CAAC,MAAM,IAAIA,IAAI,CAACG,YAAY,EAAE;AAC5B;AACA;AACA,UAAA,MAAME,IAAI,GAAG,CAAA,aAAA,EAAgBjC,MAAM,CAACkC,IAAI,CAACzB,aAAa,CAAC,CAACU,MAAM,GAAG,CAAC,CAAA,CAAE;UACpEV,aAAa,CAACwB,IAAI,CAAC,GAAG;YACpBE,SAAS,EAAEP,IAAI,CAACG,YAAY;YAC5BL,IAAI,EAAEE,IAAI,CAACF,IAAI;AACfM,YAAAA,IAAI,EAAEJ,IAAI,CAACI,IAAI,IAAI;WACpB;AACDL,UAAAA,OAAO,GAAG;AAAE,YAAA,GAAGC,IAAI;AAAEJ,YAAAA,IAAI,EAAES;WAAM;AACnC,QAAA,CAAC,MAAM;AACLN,UAAAA,OAAO,GAAGC,IAAI;AAChB,QAAA;AACF,MAAA,CAAC,MAAM,IAAIA,IAAI,CAACE,IAAI,KAAK,MAAM,EAAE;QAC/BzB,KAAK,CAACa,IAAI,CAACkB,GAAG,CAACR,IAAI,EAAER,KAAK,EAAEO,OAAO,IAAIJ,IAAI,EAAEE,IAAI,EAAEf,EAAE,EAAEH,MAAM,EAAEC,MAAM,CAAC,CAAC;AACvEmB,QAAAA,OAAO,GAAGzB,SAAS;AACrB,MAAA;AACF,IAAA;EACF,CAAC;AACDS,EAAAA,IAAI,CAACP,IAAI,EAAE,EAAE,CAAC;EACd,OAAO;IACLC,KAAK;IACLC,QAAQ;IACR+B,WAAW,EAAEjC,IAAI,CAACoB,IAAI;IACtBc,WAAW,EAAElC,IAAI,CAACsB,IAAI;IACtBjB,aAAa;IACbD,MAAM;AACND,IAAAA;GACD;AACH;AAEA,SAAS6B,GAAGA,CACVG,IAAc,EACdnB,KAAc,EACdG,IAAiC,EACjCE,IAAsB,EACtBf,EAAU,EACVH,MAA8B,EAC9BC,MAA8B,EACxB;AACN,EAAA,IAAIgC,IAAU,GAAG;IACfC,GAAG,EAAEF,IAAI,CAACE,GAAG;IACb/B,EAAE;IACFgC,EAAE,EAAEH,IAAI,CAACG,EAAE;AACXC,IAAAA,IAAI,EAAE,OAAO;IACbC,KAAK,EAAEL,IAAI,CAACK;GACb;EACD,MAAMC,KAAK,GAAIC,CAAQ,IAAK;AAC1BN,IAAAA,IAAI,GAAG;AAAE,MAAA,GAAGA,IAAI;MAAE,GAAG7C,IAAI,CAACmD,CAAC;KAAG;EAChC,CAAC;AACD,EAAA,KAAK,MAAMA,CAAC,IAAI1B,KAAK,EAAE;IACrByB,KAAK,CAACC,CAAC,CAAC;AACV,EAAA;AACAD,EAAAA,KAAK,CAACN,IAAI,CAACQ,KAAK,CAAC;AACjB,EAAA,IAAIxB,IAAI,EAAE;AACR,IAAA,IAAI,OAAOA,IAAI,KAAK,QAAQ,EAAE;AAC5BsB,MAAAA,KAAK,CAAC;AAAErB,QAAAA,IAAI,EAAED,IAAI;AAAEG,QAAAA,IAAI,EAAED;AAAK,OAAC,CAAC;AACnC,IAAA,CAAC,MAAM;AACLoB,MAAAA,KAAK,CAAC;QACJG,KAAK,EAAEzB,IAAI,CAACyB,KAAK;QACjBxB,IAAI,EAAED,IAAI,CAACC,IAAI;AACfE,QAAAA,IAAI,EAAEH,IAAI,CAACG,IAAI,IAAID;AACrB,OAAC,CAAC;AACJ,IAAA;AACF,EAAA;EACA,MAAMwB,MAAkC,GAAG,EAAE;EAC7C,MAAMC,KAAiC,GAAG,EAAE;AAC5C,EAAA,KAAK,MAAMtB,IAAI,IAAIW,IAAI,CAACV,QAAQ,EAAE;IAChC,QAAQD,IAAI,CAACE,IAAI;AACf,MAAA,KAAK,OAAO;AACV,QAAA,IAAIF,IAAI,CAACuB,KAAK,CAACC,KAAK,EAAE;UACpBH,MAAM,CAAC/B,IAAI,CAAC,GAAGU,IAAI,CAACuB,KAAK,CAACC,KAAK,CAAC;UAChC,MAAM;AAAEA,YAAAA,KAAK,EAAEC,MAAM;YAAE,GAAGC;WAAM,GAAG1B,IAAI,CAACuB,KAAK;UAC7CN,KAAK,CAACS,IAAI,CAAC;AACb,QAAA,CAAC,MAAM;AACLT,UAAAA,KAAK,CAACjB,IAAI,CAACuB,KAAK,CAAC;AACnB,QAAA;AACA,QAAA;AACF,MAAA,KAAK,IAAI;AACPN,QAAAA,KAAK,CAAC;UAAEU,KAAK,EAAE3B,IAAI,CAACa;AAAI,SAAC,CAAC;AAC1B,QAAA;AACF,MAAA,KAAK,KAAK;AACRI,QAAAA,KAAK,CAAC;UAAEW,GAAG,EAAE5B,IAAI,CAAC4B;AAAI,SAAC,CAAC;AACxB,QAAA;AACF,MAAA,KAAK,OAAO;AACVX,QAAAA,KAAK,CAAC;UAAEY,IAAI,EAAE7B,IAAI,CAAC6B,IAAI;UAAEC,EAAE,EAAE9B,IAAI,CAAC+B;AAAK,SAAC,CAAC;AACzC,QAAA,IAAI/B,IAAI,CAACgC,IAAI,KAAK1D,SAAS,EAAE;UAC3BK,MAAM,CAACgC,IAAI,CAACG,EAAE,CAAC,GAAGd,IAAI,CAACgC,IAAI;AAC7B,QAAA;AACA,QAAA,IAAIhC,IAAI,CAACiC,IAAI,KAAK3D,SAAS,EAAE;UAC3BM,MAAM,CAAC+B,IAAI,CAACG,EAAE,CAAC,GAAGd,IAAI,CAACiC,IAAI;AAC7B,QAAA;AACA,QAAA;AACF,MAAA,KAAK,QAAQ;AACX,QAAA,IAAIjC,IAAI,CAACkC,KAAK,EAAEhC,IAAI,KAAK,OAAO,EAAE;UAChC,MAAM;AAAEA,YAAAA,IAAI,EAAEiC,KAAK;YAAE,GAAGC;WAAO,GAAGpC,IAAI,CAACkC,KAAK;AAC5CjB,UAAAA,KAAK,CAAC;AAAEmB,YAAAA;AAAM,WAAC,CAAC;AAClB,QAAA,CAAC,MAAM,IAAIpC,IAAI,CAACkC,KAAK,EAAE;UACrB,MAAM;YAAEhC,IAAI;YAAE,GAAGwB;WAAM,GAAG1B,IAAI,CAACkC,KAAK;AACpC;AACV;AACA;AACA;AACUZ,UAAAA,KAAK,CAAChC,IAAI,CACRvB,IAAI,CAAC;AACH,YAAA,GAAG2D,IAAI;YACPW,EAAE,EAAErC,IAAI,CAACqC,EAAE;YACXC,GAAG,EAAEtC,IAAI,CAACsC,GAAG;YACbC,GAAG,EAAEvC,IAAI,CAACuC,GAAG;AACbrC,YAAAA;AACF,WAAC,CACH,CAAC;AACH,QAAA;AACA,QAAA;AAGJ;AACF,EAAA;EACA,IAAIoB,KAAK,CAAC/B,MAAM,EAAE;AAChB0B,IAAAA,KAAK,CAAC;AAAEK,MAAAA;AAAM,KAAC,CAAC;AAClB,EAAA;EACA,IAAID,MAAM,CAAC9B,MAAM,EAAE;AACjB0B,IAAAA,KAAK,CAAC;AAAEO,MAAAA,KAAK,EAAEH;AAAO,KAAC,CAAC;AAC1B,EAAA;EACA,OAAOtD,IAAI,CAAC6C,IAAI,CAAC;AACnB;;;;"}
@@ -0,0 +1,77 @@
1
+ import Component from '@glimmer/component';
2
+ import { modifier } from 'ember-modifier';
3
+ import { SOUND, IFRAME_PICTURE, CLIP_LOOK } from './adjust.js';
4
+ import { compileGraph } from './compile.js';
5
+ import { collectGraph, setGraphHost, Voice, Video, Type, Trace, To, Stamp, Spine, Sky, Shot, Sequence, Mark, Lineup, JoinInto, Inset, Insert, Freeze, Eye, Chapter, Attach } from './nodes.js';
6
+ import { precompileTemplate } from '@ember/template-compilation';
7
+ import { setComponentTemplate } from '@ember/component';
8
+
9
+ const VOCABULARY = {
10
+ Attach,
11
+ Chapter,
12
+ Eye,
13
+ Freeze,
14
+ Insert,
15
+ Inset,
16
+ Join: JoinInto,
17
+ Lineup,
18
+ Mark,
19
+ Sequence,
20
+ Shot,
21
+ Sky,
22
+ Spine,
23
+ Stamp,
24
+ To,
25
+ Trace,
26
+ Type,
27
+ Video,
28
+ Voice,
29
+ clip: CLIP_LOOK,
30
+ picture: IFRAME_PICTURE,
31
+ sound: SOUND
32
+ };
33
+ class FilmGraph extends Component {
34
+ element;
35
+ pending = 0;
36
+ invalidate() {
37
+ if (this.pending || !this.element) {
38
+ return;
39
+ }
40
+ this.pending = requestAnimationFrame(() => {
41
+ this.pending = 0;
42
+ this.args.onCompile(this.compile());
43
+ });
44
+ }
45
+ /** the tree under the host, compiled; null without a spine */
46
+ compile() {
47
+ if (!this.element) {
48
+ return null;
49
+ }
50
+ const spine = collectGraph(this.element).find(n => n.kind === 'group' && n.role === 'spine');
51
+ return spine ? compileGraph(spine) : null;
52
+ }
53
+ host = modifier(el => {
54
+ this.element = el;
55
+ setGraphHost(el, this);
56
+ this.invalidate();
57
+ return () => {
58
+ if (this.pending) {
59
+ cancelAnimationFrame(this.pending);
60
+ this.pending = 0;
61
+ }
62
+ setGraphHost(el, undefined);
63
+ this.element = undefined;
64
+ };
65
+ });
66
+ static {
67
+ setComponentTemplate(precompileTemplate("{{!-- contents, not a box: the film page lays out what the block\n renders, and the host must not stand between them --}}\n<div data-film-graph style=\"display:contents\" {{this.host}}>\n {{yield VOCABULARY}}\n</div>", {
68
+ strictMode: true,
69
+ scope: () => ({
70
+ VOCABULARY
71
+ })
72
+ }), this);
73
+ }
74
+ }
75
+
76
+ export { FilmGraph, VOCABULARY };
77
+ //# sourceMappingURL=host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.js","sources":["../../../src/film/graph/host.gts"],"sourcesContent":["/**\n * THE GRAPH'S HOST. Yields the vocabulary (`f.Spine`, `f.Shot`, …), walks\n * its markers after each render, compiles the tree to the table, and hands\n * the rows up. `<Film>` wraps its default block in one of these; a test can\n * render one bare and read what a template compiles to.\n *\n * Collection is scheduled, never done in the render pass: a marker's\n * modifier calls `invalidate()` during render, and a tracked write there\n * would be a backtracking re-render. One frame later the tree is walked\n * once, however many markers moved.\n */\nimport Component from '@glimmer/component';\nimport { modifier } from 'ember-modifier';\n\nimport { CLIP_LOOK, IFRAME_PICTURE, SOUND } from './adjust.gts';\nimport { type CompiledGraph, compileGraph, type GroupNode } from './compile.ts';\nimport {\n Attach,\n Chapter,\n collectGraph,\n Eye,\n Freeze,\n type GraphHost,\n Insert,\n Inset,\n JoinInto,\n Lineup,\n Mark,\n Sequence,\n setGraphHost,\n Shot,\n Sky,\n Spine,\n Stamp,\n To,\n Trace,\n Type,\n Video,\n Voice,\n} from './nodes.gts';\n\n/** what `<Film as |f|>` and `<FilmGraph as |f|>` yield: the vocabulary */\nexport interface FilmVocabulary {\n Attach: typeof Attach;\n Chapter: typeof Chapter;\n Eye: typeof Eye;\n Freeze: typeof Freeze;\n Insert: typeof Insert;\n Inset: typeof Inset;\n Join: typeof JoinInto;\n Lineup: typeof Lineup;\n Mark: typeof Mark;\n Sequence: typeof Sequence;\n Shot: typeof Shot;\n Sky: typeof Sky;\n Spine: typeof Spine;\n Stamp: typeof Stamp;\n To: typeof To;\n Trace: typeof Trace;\n Type: typeof Type;\n Video: typeof Video;\n Voice: typeof Voice;\n /** the picture's adjustments, as the picture declares them */\n clip: typeof CLIP_LOOK;\n picture: typeof IFRAME_PICTURE;\n /** the sound actor's */\n sound: typeof SOUND;\n}\n\nexport const VOCABULARY: FilmVocabulary = {\n Attach,\n Chapter,\n Eye,\n Freeze,\n Insert,\n Inset,\n Join: JoinInto,\n Lineup,\n Mark,\n Sequence,\n Shot,\n Sky,\n Spine,\n Stamp,\n To,\n Trace,\n Type,\n Video,\n Voice,\n clip: CLIP_LOOK,\n picture: IFRAME_PICTURE,\n sound: SOUND,\n};\n\nexport interface FilmGraphSignature {\n Args: {\n /** the compiled table, a frame after the markers settle; null when the block holds no spine */\n onCompile: (compiled: CompiledGraph | null) => void;\n };\n Blocks: { default: [FilmVocabulary] };\n}\n\nexport class FilmGraph\n extends Component<FilmGraphSignature>\n implements GraphHost\n{\n private element?: Element;\n private pending = 0;\n\n invalidate() {\n if (this.pending || !this.element) {\n return;\n }\n this.pending = requestAnimationFrame(() => {\n this.pending = 0;\n this.args.onCompile(this.compile());\n });\n }\n\n /** the tree under the host, compiled; null without a spine */\n compile(): CompiledGraph | null {\n if (!this.element) {\n return null;\n }\n const spine = collectGraph(this.element).find(\n (n): n is GroupNode => n.kind === 'group' && n.role === 'spine',\n );\n return spine ? compileGraph(spine) : null;\n }\n\n host = modifier((el: Element) => {\n this.element = el;\n setGraphHost(el, this);\n this.invalidate();\n return () => {\n if (this.pending) {\n cancelAnimationFrame(this.pending);\n this.pending = 0;\n }\n setGraphHost(el, undefined);\n this.element = undefined;\n };\n });\n\n <template>\n {{! contents, not a box: the film page lays out what the block\n renders, and the host must not stand between them }}\n <div data-film-graph style='display:contents' {{this.host}}>\n {{yield VOCABULARY}}\n </div>\n </template>\n}\n"],"names":["VOCABULARY","Attach","Chapter","Eye","Freeze","Insert","Inset","Join","JoinInto","Lineup","Mark","Sequence","Shot","Sky","Spine","Stamp","To","Trace","Type","Video","Voice","clip","CLIP_LOOK","picture","IFRAME_PICTURE","sound","SOUND","FilmGraph","Component","element","pending","invalidate","requestAnimationFrame","args","onCompile","compile","spine","collectGraph","find","n","kind","role","compileGraph","host","modifier","el","setGraphHost","cancelAnimationFrame","undefined","setComponentTemplate","precompileTemplate","strictMode","scope"],"mappings":";;;;;;;;AAqEO,MAAMA,UAAY,GAAiB;EACxCC,MAAA;EACAC,OAAA;EACAC,GAAA;EACAC,MAAA;EACAC,MAAA;EACAC,KAAA;AACAC,EAAAA,IAAA,EAAMC,QAAA;EACNC,MAAA;EACAC,IAAA;EACAC,QAAA;EACAC,IAAA;EACAC,GAAA;EACAC,KAAA;EACAC,KAAA;EACAC,EAAA;EACAC,KAAA;EACAC,IAAA;EACAC,KAAA;EACAC,KAAA;AACAC,EAAAA,IAAA,EAAMC,SAAA;AACNC,EAAAA,OAAA,EAASC,cAAA;AACTC,EAAAA,KAAA,EAAOC;AACT;AAUO,MAAMC,SAAA,SACHC,SAAA,CACG;EAEHC;AACAC,EAAAA,UAAU,CAAA;AAElBC,EAAAA,UAAAA,GAAa;IACX,IAAI,IAAI,CAACD,OAAO,IAAI,CAAC,IAAI,CAACD,OAAO,EAAE;AACjC,MAAA;AACF,IAAA;AACA,IAAA,IAAI,CAACC,OAAO,GAAGE,qBAAA,CAAsB,MAAA;MACnC,IAAI,CAACF,OAAO,GAAG,CAAA;MACf,IAAI,CAACG,IAAI,CAACC,SAAS,CAAC,IAAI,CAACC,OAAO,EAAA,CAAA;AAClC,IAAA,CAAA,CAAA;AACF,EAAA;AAEA;AACAA,EAAAA,OAAAA,GAAgC;AAC9B,IAAA,IAAI,CAAC,IAAI,CAACN,OAAO,EAAE;AACjB,MAAA,OAAO,IAAA;AACT,IAAA;IACA,MAAMO,QAAQC,YAAA,CAAa,IAAI,CAACR,OAAO,CAAA,CAAES,IAAI,CAC1CC,CAAA,IAAsBA,CAAA,CAAEC,IAAI,KAAK,OAAA,IAAWD,CAAA,CAAEE,IAAI,KAAK,OAAA,CAAA;AAE1D,IAAA,OAAOL,KAAA,GAAQM,aAAaN,KAAA,CAAA,GAAS,IAAA;AACvC,EAAA;AAEAO,EAAAA,IAAA,GAAOC,QAAA,CAAUC,EAAI,IAAA;IACnB,IAAI,CAAChB,OAAO,GAAGgB,EAAA;AACfC,IAAAA,YAAA,CAAaD,IAAI,IAAI,CAAA;IACrB,IAAI,CAACd,UAAU,EAAA;AACf,IAAA,OAAO,MAAA;MACL,IAAI,IAAI,CAACD,OAAO,EAAE;AAChBiB,QAAAA,oBAAA,CAAqB,IAAI,CAACjB,OAAO,CAAA;QACjC,IAAI,CAACA,OAAO,GAAG,CAAA;AACjB,MAAA;AACAgB,MAAAA,YAAA,CAAaD,EAAA,EAAIG,SAAA,CAAA;MACjB,IAAI,CAACnB,OAAO,GAAGmB,SAAA;IACjB,CAAA;AACF,EAAA,CAAA,CAAA;AAEA,EAAA;IAAAC,oBAAA,CAAAC,kBAAA,CAAA,8NAAA,EAMA;MAAAC,UAAA,EAAA,IAAA;AAAAC,MAAAA,KAAA,EAAAA,OAAA;AAAApD,QAAAA;AAAA,OAAA;KAAU,CAAA,EAAV,IAAW,CAAA;AAAD;AACZ;;;;"}