@hyperframes/core 0.7.106 → 0.7.108

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 (97) hide show
  1. package/dist/audio/audioFxAutomation.d.ts +63 -0
  2. package/dist/audio/audioFxAutomation.d.ts.map +1 -0
  3. package/dist/audio/audioFxAutomation.js +219 -0
  4. package/dist/audio/audioFxAutomation.js.map +1 -0
  5. package/dist/audio/audioFxGraph.d.ts +73 -0
  6. package/dist/audio/audioFxGraph.d.ts.map +1 -0
  7. package/dist/audio/audioFxGraph.js +649 -0
  8. package/dist/audio/audioFxGraph.js.map +1 -0
  9. package/dist/audio/audioFxTail.d.ts +28 -0
  10. package/dist/audio/audioFxTail.d.ts.map +1 -0
  11. package/dist/audio/audioFxTail.js +95 -0
  12. package/dist/audio/audioFxTail.js.map +1 -0
  13. package/dist/audio/audioFxWorklets.d.ts +8 -0
  14. package/dist/audio/audioFxWorklets.d.ts.map +1 -0
  15. package/dist/audio/audioFxWorklets.js +263 -0
  16. package/dist/audio/audioFxWorklets.js.map +1 -0
  17. package/dist/audioAutomation.d.ts +191 -0
  18. package/dist/audioAutomation.d.ts.map +1 -0
  19. package/dist/audioAutomation.js +488 -0
  20. package/dist/audioAutomation.js.map +1 -0
  21. package/dist/audioCarve.d.ts +216 -0
  22. package/dist/audioCarve.d.ts.map +1 -0
  23. package/dist/audioCarve.js +608 -0
  24. package/dist/audioCarve.js.map +1 -0
  25. package/dist/audioFx.d.ts +182 -0
  26. package/dist/audioFx.d.ts.map +1 -0
  27. package/dist/audioFx.js +813 -0
  28. package/dist/audioFx.js.map +1 -0
  29. package/dist/audioFxCopy.d.ts +89 -0
  30. package/dist/audioFxCopy.d.ts.map +1 -0
  31. package/dist/audioFxCopy.js +340 -0
  32. package/dist/audioFxCopy.js.map +1 -0
  33. package/dist/audioFxEq.d.ts +75 -0
  34. package/dist/audioFxEq.d.ts.map +1 -0
  35. package/dist/audioFxEq.js +153 -0
  36. package/dist/audioFxEq.js.map +1 -0
  37. package/dist/audioFxJobs.d.ts +52 -0
  38. package/dist/audioFxJobs.d.ts.map +1 -0
  39. package/dist/audioFxJobs.js +92 -0
  40. package/dist/audioFxJobs.js.map +1 -0
  41. package/dist/audioFxPresets.d.ts +91 -0
  42. package/dist/audioFxPresets.d.ts.map +1 -0
  43. package/dist/audioFxPresets.js +320 -0
  44. package/dist/audioFxPresets.js.map +1 -0
  45. package/dist/audioFxProfiles.d.ts +65 -0
  46. package/dist/audioFxProfiles.d.ts.map +1 -0
  47. package/dist/audioFxProfiles.js +209 -0
  48. package/dist/audioFxProfiles.js.map +1 -0
  49. package/dist/audioLeveller.d.ts +62 -0
  50. package/dist/audioLeveller.d.ts.map +1 -0
  51. package/dist/audioLeveller.js +208 -0
  52. package/dist/audioLeveller.js.map +1 -0
  53. package/dist/canaryRegistry.d.ts.map +1 -1
  54. package/dist/canaryRegistry.js +8 -0
  55. package/dist/canaryRegistry.js.map +1 -1
  56. package/dist/compiler/compositionScoping.d.ts +3 -0
  57. package/dist/compiler/compositionScoping.d.ts.map +1 -1
  58. package/dist/compiler/compositionScoping.js +34 -11
  59. package/dist/compiler/compositionScoping.js.map +1 -1
  60. package/dist/compiler/htmlBundler.d.ts.map +1 -1
  61. package/dist/compiler/htmlBundler.js +42 -2
  62. package/dist/compiler/htmlBundler.js.map +1 -1
  63. package/dist/editing/affordances.d.ts +3 -0
  64. package/dist/editing/affordances.d.ts.map +1 -1
  65. package/dist/editing/affordances.js +1 -0
  66. package/dist/editing/affordances.js.map +1 -1
  67. package/dist/generated/audio-fx-runtime-inline.d.ts +3 -0
  68. package/dist/generated/audio-fx-runtime-inline.d.ts.map +1 -0
  69. package/dist/generated/audio-fx-runtime-inline.js +7 -0
  70. package/dist/generated/audio-fx-runtime-inline.js.map +1 -0
  71. package/dist/generated/runtime-inline.js +1 -1
  72. package/dist/generated/runtime-inline.js.map +1 -1
  73. package/dist/hyperframe.runtime.iife.js +238 -28
  74. package/dist/runtime/applyVariableBindings.d.ts +45 -0
  75. package/dist/runtime/applyVariableBindings.d.ts.map +1 -0
  76. package/dist/runtime/applyVariableBindings.js +194 -0
  77. package/dist/runtime/applyVariableBindings.js.map +1 -0
  78. package/dist/runtime/audioAutomationVolume.d.ts +17 -0
  79. package/dist/runtime/audioAutomationVolume.d.ts.map +1 -0
  80. package/dist/runtime/audioAutomationVolume.js +49 -0
  81. package/dist/runtime/audioAutomationVolume.js.map +1 -0
  82. package/dist/runtime/media.d.ts.map +1 -1
  83. package/dist/runtime/media.js +24 -2
  84. package/dist/runtime/media.js.map +1 -1
  85. package/dist/runtime/mediaVolumeEnvelope.d.ts +9 -2
  86. package/dist/runtime/mediaVolumeEnvelope.d.ts.map +1 -1
  87. package/dist/runtime/mediaVolumeEnvelope.js +13 -3
  88. package/dist/runtime/mediaVolumeEnvelope.js.map +1 -1
  89. package/dist/runtime/variableScope.d.ts +9 -0
  90. package/dist/runtime/variableScope.d.ts.map +1 -0
  91. package/dist/runtime/variableScope.js +21 -0
  92. package/dist/runtime/variableScope.js.map +1 -0
  93. package/dist/utils/richTextSanitize.d.ts +32 -0
  94. package/dist/utils/richTextSanitize.d.ts.map +1 -0
  95. package/dist/utils/richTextSanitize.js +227 -0
  96. package/dist/utils/richTextSanitize.js.map +1 -0
  97. package/package.json +55 -6
@@ -0,0 +1,320 @@
1
+ /**
2
+ * Named starting points for the FX rack.
3
+ *
4
+ * Voice carve turned a pile of effects into one understandable feature. These
5
+ * do the same for the cases an analysis cannot decide: a preset is a chain
6
+ * somebody already tuned, applied in one click and editable immediately
7
+ * afterwards.
8
+ *
9
+ * A preset is DATA, deliberately. Applying one writes ordinary nodes into
10
+ * `data-fx-chain` — the same nodes hand-building would produce — so there is no
11
+ * second code path to keep in agreement with the rack, nothing new in the
12
+ * render, and no failure mode the chain does not already have. The author can
13
+ * see everything that was written on their behalf and change any of it.
14
+ *
15
+ * Only the parameters a preset actually means are listed; `normalizeAudioFxParams`
16
+ * fills the rest from the effect's own defaults. That keeps each entry readable
17
+ * as an intent rather than a dump of every knob.
18
+ *
19
+ * Node ORDER is load-bearing — the chain is serial, so a limiter first and a
20
+ * limiter last are different sounds. Every preset below runs
21
+ * subtractive filtering → dynamics → tone → character → limiter, the order
22
+ * `skills/hyperframes-audio` already teaches.
23
+ */
24
+ import { HF_AUDIO_FX_CHAIN_VERSION, mintAudioFxNodeId, normalizeAudioFxParams, } from "./audioFx.js";
25
+ const preset = (id, family, label, description, nodes) => ({ id, label, family, description, nodes });
26
+ /**
27
+ * A 24 dB/oct skirt is two of these stacked: `poles` tops out at 2 (12 dB/oct)
28
+ * because a BiquadFilterNode is two-pole and that is the honest maximum for one
29
+ * node. The telephone band wants the steeper slope, so it pays for two.
30
+ */
31
+ const steep = (type, frequency, label) => [
32
+ { type, label, params: { frequency, q: 0.707, poles: "2" } },
33
+ { type, label, params: { frequency, q: 0.707, poles: "2" } },
34
+ ];
35
+ export const HF_AUDIO_FX_PRESETS = [
36
+ // ---------------------------------------------------------------- voice --
37
+ preset("voice-clean", "voice", "Clean Voice", "Cuts rumble and mud, evens out the level, adds a little clarity.", [
38
+ { type: "highpass", label: "Remove Rumble", params: { frequency: 80, q: 0.707, poles: "2" } },
39
+ { type: "peaking", label: "Reduce Mud", params: { frequency: 250, gain: -3, q: 1.2 } },
40
+ {
41
+ type: "compressor",
42
+ label: "Even Out Loudness",
43
+ params: { threshold: -20, ratio: 3, attack: 12, release: 180, makeup: 3 },
44
+ },
45
+ { type: "peaking", label: "Add Clarity", params: { frequency: 3000, gain: 2.5, q: 1 } },
46
+ { type: "limiter", label: "Peak Ceiling", params: { limit: -1, attack: 5, release: 50 } },
47
+ ]),
48
+ preset("voice-broadcast", "voice", "Broadcast", "Denser and more forward — a radio-presenter sound.", [
49
+ { type: "highpass", label: "Remove Rumble", params: { frequency: 90, q: 0.707, poles: "2" } },
50
+ { type: "peaking", label: "Reduce Boxiness", params: { frequency: 400, gain: -3, q: 1.4 } },
51
+ {
52
+ type: "compressor",
53
+ label: "Even Out Loudness",
54
+ params: { threshold: -24, ratio: 4, attack: 8, release: 150, makeup: 5 },
55
+ },
56
+ { type: "peaking", label: "Add Clarity", params: { frequency: 2500, gain: 3, q: 0.9 } },
57
+ { type: "highshelf", label: "Add Air", params: { frequency: 8000, gain: 2 } },
58
+ { type: "saturate", label: "Warmth", params: { type: "tanh", threshold: -12, output: 0 } },
59
+ { type: "limiter", label: "Peak Ceiling", params: { limit: -1, attack: 5, release: 60 } },
60
+ ]),
61
+ preset("voice-warm", "voice", "Close & Warm", "Intimate and lightly handled, for a voice close to the mic.", [
62
+ { type: "highpass", label: "Remove Rumble", params: { frequency: 70, q: 0.707, poles: "2" } },
63
+ { type: "lowshelf", label: "Add Weight", params: { frequency: 180, gain: 2 } },
64
+ {
65
+ type: "compressor",
66
+ label: "Even Out Loudness",
67
+ params: { threshold: -18, ratio: 2.5, attack: 20, release: 250, makeup: 2 },
68
+ },
69
+ { type: "peaking", label: "Add Clarity", params: { frequency: 3000, gain: 1.5, q: 0.8 } },
70
+ { type: "limiter", label: "Peak Ceiling", params: { limit: -1.5 } },
71
+ ]),
72
+ // --------------------------------------------------------------- repair --
73
+ // Named for what they DO. None of these is noise reduction: that needs
74
+ // spectral work this effect set does not have, and a preset implying
75
+ // otherwise would be a lie the author only discovers after trusting it.
76
+ preset("rumble-cut", "repair", "Cut Rumble", "Removes traffic, handling and air-conditioning from under a voice.", [{ type: "highpass", label: "Cut Rumble", params: { frequency: 100, q: 0.707, poles: "2" } }]),
77
+ preset("room-gate", "repair", "Quiet Between Phrases", "Silences the gaps between words. Room tone under speech stays — this closes the pauses, it does not remove noise.", [
78
+ {
79
+ type: "gate",
80
+ label: "Silence the Gaps",
81
+ params: { threshold: -45, range: -18, ratio: 10, attack: 2, release: 180 },
82
+ },
83
+ ]),
84
+ preset("boom-tame", "repair", "Tame Boominess", "Takes out the chestiness of a voice too close to the mic.", [{ type: "peaking", label: "Tame Boominess", params: { frequency: 200, gain: -4, q: 1.4 } }]),
85
+ preset("harsh-tame", "repair", "Soften Harshness", "Rounds off a brittle upper-mid. Broad and always-on; sibilance proper wants the measuring version.", [{ type: "peaking", label: "Soften Harshness", params: { frequency: 3200, gain: -3, q: 1.6 } }]),
86
+ // ------------------------------------------------------------ character --
87
+ preset("telephone", "character", "Telephone", "Down the line — the narrow band of a phone call.", [
88
+ ...steep("highpass", 300, "Strip the Bass"),
89
+ ...steep("lowpass", 3400, "Strip the Treble"),
90
+ { type: "peaking", label: "Phone Honk", params: { frequency: 1200, gain: 6, q: 1.2 } },
91
+ { type: "peaking", label: "De-mud", params: { frequency: 550, gain: -4, q: 1 } },
92
+ {
93
+ type: "saturate",
94
+ label: "Circuit Grit",
95
+ params: { type: "tanh", threshold: -9, output: -2 },
96
+ },
97
+ ]),
98
+ preset("radio-am", "character", "AM Radio", "Narrow, gritty and a little crushed.", [
99
+ // Narrower than the megaphone at BOTH ends, which is most of the difference
100
+ // between them: an AM channel is a few kHz wide and the receiver rolls off
101
+ // well before a horn does.
102
+ { type: "highpass", label: "Strip the Bass", params: { frequency: 220, q: 0.707, poles: "2" } },
103
+ {
104
+ type: "lowpass",
105
+ label: "Strip the Treble",
106
+ params: { frequency: 2200, q: 0.707, poles: "2" },
107
+ },
108
+ // Where the telephone honks, a receiver DIPS: the IF filter's droop, and the
109
+ // reason the two stop sounding alike. Telephone's band is its identity (it
110
+ // is the G.712 passband), so the radio is what moves.
111
+ { type: "peaking", label: "IF Droop", params: { frequency: 1200, gain: -5, q: 0.9 } },
112
+ // And a lift at the bottom of the band — AM is boxy where a phone is thin.
113
+ { type: "lowshelf", label: "Boxy", params: { frequency: 500, gain: 4 } },
114
+ // Soft — a receiver compressing, not a driver being overdriven. `tanh`
115
+ // rounds the peaks where the megaphone's `hard` clips them flat.
116
+ { type: "saturate", label: "Radio Grit", params: { type: "tanh", threshold: -8, output: -1 } },
117
+ // The crush is the AM signature: quantisation noise reads as carrier hiss,
118
+ // and it is the one thing the megaphone has none of.
119
+ { type: "bitcrush", label: "Carrier Hiss", params: { bits: 8, samples: 1, mix: 0.45 } },
120
+ ]),
121
+ preset("megaphone", "character", "Megaphone", "Shouted through a horn, with the slap that comes with it.", [
122
+ {
123
+ type: "highpass",
124
+ label: "Strip the Bass",
125
+ params: { frequency: 700, q: 0.707, poles: "2" },
126
+ },
127
+ {
128
+ type: "lowpass",
129
+ label: "Strip the Treble",
130
+ params: { frequency: 4000, q: 0.707, poles: "2" },
131
+ },
132
+ // A horn is a resonant tube and that resonance IS the sound: one narrow
133
+ // peak with a second ringing above it, where the radio has none at all.
134
+ { type: "peaking", label: "Horn Honk", params: { frequency: 1900, gain: 14, q: 3 } },
135
+ { type: "peaking", label: "Horn Ring", params: { frequency: 3200, gain: 6, q: 3 } },
136
+ // A driver pushed past its limit — flat-topped, not rounded. Measured on a
137
+ // log sweep, the threshold is the whole ballgame: at -14 the clipper
138
+ // flattened the response to a dead -19 dB line and ERASED the horn peaks
139
+ // above, leaving this indistinguishable from AM Radio. Backed off until
140
+ // the resonance survives the clipping that is supposed to sit on top of it.
141
+ {
142
+ type: "saturate",
143
+ label: "Overdrive",
144
+ params: { type: "hard", threshold: -5, output: -3 },
145
+ },
146
+ // The outdoor reflection that comes back off whatever is being shouted at.
147
+ // Far enough to be a slap rather than a thickening.
148
+ { type: "delay", label: "Horn Slap", params: { time: 65, feedback: 0.2, mix: 0.28 } },
149
+ ]),
150
+ preset("lofi-tape", "character", "Tape", "Worn, warm and slightly unsteady, like a played-out cassette.", [
151
+ { type: "lowpass", label: "Tape Rolloff", params: { frequency: 6500, q: 0.707, poles: "2" } },
152
+ { type: "lowshelf", label: "Add Weight", params: { frequency: 120, gain: 2 } },
153
+ {
154
+ type: "saturate",
155
+ label: "Tape Warmth",
156
+ params: { type: "tanh", threshold: -14, output: 0 },
157
+ },
158
+ { type: "bitcrush", label: "Tape Noise", params: { bits: 12, samples: 2, mix: 0.35 } },
159
+ // A slow, shallow chorus is what wow and flutter actually are.
160
+ {
161
+ type: "chorus",
162
+ label: "Wow & Flutter",
163
+ params: { delay: 6, depth: 0.6, speed: 0.4, mix: 0.15 },
164
+ },
165
+ ]),
166
+ preset("pa-system", "character", "Tannoy", "Announced across a concourse.", [
167
+ { type: "highpass", label: "Strip the Bass", params: { frequency: 250, q: 0.707, poles: "2" } },
168
+ {
169
+ type: "lowpass",
170
+ label: "Strip the Treble",
171
+ params: { frequency: 5000, q: 0.707, poles: "2" },
172
+ },
173
+ // Higher and harder than the telephone's honk, which is what a big horn
174
+ // does — and it keeps the top the phone throws away.
175
+ { type: "peaking", label: "Tannoy Honk", params: { frequency: 2400, gain: 9, q: 2 } },
176
+ {
177
+ type: "saturate",
178
+ label: "Driver Grit",
179
+ params: { type: "tanh", threshold: -10, output: -1 },
180
+ },
181
+ {
182
+ type: "reverb",
183
+ label: "Concourse",
184
+ params: { size: 0.54, damping: 0.48, wet: 0.25, dry: 0.8 },
185
+ },
186
+ ]),
187
+ preset("intercom", "character", "Intercom", "Buzzed through a door panel, squelch and all.", [
188
+ {
189
+ type: "gate",
190
+ label: "Squelch",
191
+ params: { threshold: -40, range: -30, ratio: 10, attack: 1, release: 120 },
192
+ },
193
+ { type: "highpass", label: "Strip the Bass", params: { frequency: 500, q: 0.707, poles: "2" } },
194
+ {
195
+ type: "lowpass",
196
+ label: "Strip the Treble",
197
+ params: { frequency: 3000, q: 0.707, poles: "2" },
198
+ },
199
+ { type: "peaking", label: "Panel Honk", params: { frequency: 2000, gain: 6, q: 2 } },
200
+ { type: "bitcrush", label: "Crunch", params: { bits: 11, samples: 1, mix: 0.3 } },
201
+ ]),
202
+ // The chorus with its wobble dialled up until it stops being width and starts
203
+ // being the effect: fast (10 Hz, the top of the range) and fully wet, so none
204
+ // of the straight signal is left to anchor the pitch.
205
+ preset("doofus-worble", "character", "Doofus Worble", "Seasick and wobbling — no straight signal left.", [
206
+ {
207
+ type: "chorus",
208
+ label: "Worble",
209
+ params: { delay: 14.6, depth: 2.57, speed: 10, mix: 1 },
210
+ },
211
+ ]),
212
+ // ---------------------------------------------------------------- space --
213
+ preset("room-tight", "space", "Tight Room", "A small hard room — presence without wash.", [
214
+ {
215
+ type: "reverb",
216
+ label: "Tight Room",
217
+ params: { size: 0.25, damping: 0.6, wet: 0.18, dry: 0.9 },
218
+ },
219
+ ]),
220
+ preset("room-natural", "space", "Natural Room", "Sounds recorded somewhere rather than nowhere.", [
221
+ {
222
+ type: "reverb",
223
+ label: "Natural Room",
224
+ params: { size: 0.5, damping: 0.5, wet: 0.25, dry: 0.85 },
225
+ },
226
+ ]),
227
+ preset("hall", "space", "Hall", "Long and open, for something that should sit far back.", [
228
+ { type: "reverb", label: "Hall", params: { size: 0.9, damping: 0.3, wet: 0.4, dry: 0.75 } },
229
+ ]),
230
+ preset("slap-echo", "space", "Slap Echo", "One quick repeat — rockabilly vocal, not a wash.", [
231
+ { type: "delay", label: "Slap Echo", params: { time: 110, feedback: 0.12, mix: 0.22 } },
232
+ ]),
233
+ preset("dub-throw", "space", "Dub Throw", "Repeats that trail off well behind the beat.", [
234
+ { type: "delay", label: "Dub Throw", params: { time: 375, feedback: 0.55, mix: 0.3 } },
235
+ ]),
236
+ ];
237
+ export const HF_AUDIO_FX_PRESET_IDS = HF_AUDIO_FX_PRESETS.map((p) => p.id);
238
+ const BY_ID = new Map(HF_AUDIO_FX_PRESETS.map((p) => [p.id, p]));
239
+ export function getAudioFxPreset(id) {
240
+ return BY_ID.get(id);
241
+ }
242
+ /** Menu order: the shelves, in the order the panel lists them. */
243
+ export const HF_AUDIO_FX_PRESET_FAMILIES = [
244
+ "voice",
245
+ "repair",
246
+ "character",
247
+ "space",
248
+ ];
249
+ export function audioFxPresetsByFamily(family) {
250
+ return HF_AUDIO_FX_PRESETS.filter((p) => p.family === family);
251
+ }
252
+ /**
253
+ * Realise a preset as nodes ready to splice into `chain`.
254
+ *
255
+ * Ids are minted against the chain the nodes are joining, not against the
256
+ * preset, so applying the same preset twice cannot collide — and every node
257
+ * gets one, because an automation lane addresses its effect by id and a node
258
+ * without one can never be automated.
259
+ *
260
+ * Params are normalised here rather than at apply time: a preset that names a
261
+ * value the effect would clamp should land in the file as the value that will
262
+ * actually be rendered, so the rack never shows a number the graph is not using.
263
+ */
264
+ export function audioFxPresetNodes(preset, chain) {
265
+ const out = [];
266
+ // Minted against a growing chain, so ids are unique within this batch too.
267
+ let running = { ...chain, nodes: [...chain.nodes] };
268
+ for (const node of preset.nodes) {
269
+ const made = {
270
+ type: node.type,
271
+ id: mintAudioFxNodeId(running),
272
+ fromPreset: preset.id,
273
+ ...(node.label ? { label: node.label } : {}),
274
+ enabled: true,
275
+ params: normalizeAudioFxParams(node.type, node.params),
276
+ };
277
+ out.push(made);
278
+ running = { ...running, nodes: [...running.nodes, made] };
279
+ }
280
+ return out;
281
+ }
282
+ /**
283
+ * The chain after applying a preset.
284
+ *
285
+ * Appends by default: stacking Telephone onto an already-cleaned voice is a
286
+ * real thing to want, and replacing silently would throw away work. Re-applying
287
+ * a preset that is already present replaces ITS OWN nodes in place instead of
288
+ * adding a second copy — which is what `fromPreset` is for, and mirrors how the
289
+ * carve replaces its own bands rather than stacking new ones on hand-added
290
+ * effects.
291
+ */
292
+ export function applyAudioFxPreset(chain, preset, options = {}) {
293
+ if (options.replaceChain) {
294
+ return {
295
+ version: HF_AUDIO_FX_CHAIN_VERSION,
296
+ nodes: audioFxPresetNodes(preset, { version: HF_AUDIO_FX_CHAIN_VERSION, nodes: [] }),
297
+ };
298
+ }
299
+ const existing = chain.nodes.findIndex((n) => n.fromPreset === preset.id);
300
+ if (existing === -1) {
301
+ return { ...chain, nodes: [...chain.nodes, ...audioFxPresetNodes(preset, chain)] };
302
+ }
303
+ // Re-apply: drop this preset's old nodes, then rebuild them where the first
304
+ // one stood, so the preset keeps its place in the signal order.
305
+ const kept = chain.nodes.filter((n) => n.fromPreset !== preset.id);
306
+ const before = kept.slice(0, existing);
307
+ const after = kept.slice(existing);
308
+ const made = audioFxPresetNodes(preset, { ...chain, nodes: kept });
309
+ return { ...chain, nodes: [...before, ...made, ...after] };
310
+ }
311
+ /** Every preset whose nodes are still present, for the rack's group braces. */
312
+ export function activeAudioFxPresetIds(chain) {
313
+ const seen = [];
314
+ for (const node of chain.nodes) {
315
+ if (node.fromPreset && !seen.includes(node.fromPreset))
316
+ seen.push(node.fromPreset);
317
+ }
318
+ return seen;
319
+ }
320
+ //# sourceMappingURL=audioFxPresets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audioFxPresets.js","sourceRoot":"","sources":["../src/audioFxPresets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * One knob over several, for the five effects that cannot honestly have one
3
+ * real parameter nominated as the control that matters.
4
+ *
5
+ * A compressor has seven controls and an author wants one. The rest of the rack
6
+ * opens on a single real parameter — a filter's frequency, a delay's mix — but
7
+ * these five have no such parameter: threshold means nothing without ratio,
8
+ * ratio means nothing without make-up gain, and picking any one of them as the
9
+ * face of the module would be a knob that lies about what it sets.
10
+ *
11
+ * So they get a derived one, exactly as the carve already does: `carveProfile`
12
+ * turns a single 0..1 into six numbers, and these do the same for the rest of
13
+ * the rack. `EFFECT_COPY[id].primary` is `"strength"` for precisely these five,
14
+ * which is what says a module wants this treatment.
15
+ *
16
+ * Continuous rather than the three-point tables the design proposed. A table
17
+ * makes gentle/middle/strong three settings an author picks between, and the
18
+ * thing being modelled is not three settings — it is one axis, and the carve's
19
+ * knob has proved that reads. The proposal's figures survive as the anchors:
20
+ * each curve passes through them at 0, 0.5 and 1.
21
+ *
22
+ * Every number below is expressed in the parameter's own registry unit and then
23
+ * clamped by `normalizeAudioFxParams` on the way into the chain, so a profile
24
+ * cannot ship a value the effect would refuse.
25
+ */
26
+ import { type HfAudioFxParamValues } from "./audioFx.js";
27
+ export interface HfAudioFxProfile {
28
+ /** What the one knob is called. Never the DSP name of anything it drives. */
29
+ label: string;
30
+ /** What the two ends sound like — the question an author actually has. */
31
+ ends: {
32
+ low: string;
33
+ high: string;
34
+ };
35
+ /** The parameters it sets. Everything else keeps the effect's own default. */
36
+ derives: readonly string[];
37
+ /** The mechanism values at a given strength. */
38
+ at(strength: number): HfAudioFxParamValues;
39
+ }
40
+ export declare const HF_AUDIO_FX_PROFILES: Record<string, HfAudioFxProfile>;
41
+ export declare function getAudioFxProfile(type: string): HfAudioFxProfile | undefined;
42
+ /**
43
+ * The parameters a profile sets at this strength, merged over what is there.
44
+ *
45
+ * Merged rather than replacing: a profile names only the parameters it derives,
46
+ * and the rest — a compressor's knee, a saturation's curve type — are the
47
+ * author's to set under Details and must survive the knob moving.
48
+ */
49
+ export declare function applyAudioFxProfile(type: string, strength: number, params: HfAudioFxParamValues): HfAudioFxParamValues;
50
+ /**
51
+ * The strength a set of parameters reads as, by inverting the profile's own
52
+ * curve on its most characteristic parameter.
53
+ *
54
+ * A chain stores mechanism values, not the knob — the same contract
55
+ * `normalizeCarveSettings` has, and for the same reason: the mechanism is what
56
+ * renders, so it is what must be authoritative. Reading the knob back means one
57
+ * parameter has to be nominated as the one that says most about intent.
58
+ *
59
+ * A hand-edited chain therefore lands the knob at the nearest strength that
60
+ * would have produced its most telling value, which is the honest answer — the
61
+ * alternative is a knob parked at a default while the effect is set to
62
+ * something else entirely.
63
+ */
64
+ export declare function audioFxProfileStrength(type: string, params: HfAudioFxParamValues): number;
65
+ //# sourceMappingURL=audioFxProfiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audioFxProfiles.d.ts","sourceRoot":"","sources":["../src/audioFxProfiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAA0B,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAYjF,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,8EAA8E;IAC9E,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,gDAAgD;IAChD,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,CAAC;CAC5C;AAED,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CA+GjE,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAE5E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,oBAAoB,GAC3B,oBAAoB,CAItB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,MAAM,CA+BzF"}
@@ -0,0 +1,209 @@
1
+ /**
2
+ * One knob over several, for the five effects that cannot honestly have one
3
+ * real parameter nominated as the control that matters.
4
+ *
5
+ * A compressor has seven controls and an author wants one. The rest of the rack
6
+ * opens on a single real parameter — a filter's frequency, a delay's mix — but
7
+ * these five have no such parameter: threshold means nothing without ratio,
8
+ * ratio means nothing without make-up gain, and picking any one of them as the
9
+ * face of the module would be a knob that lies about what it sets.
10
+ *
11
+ * So they get a derived one, exactly as the carve already does: `carveProfile`
12
+ * turns a single 0..1 into six numbers, and these do the same for the rest of
13
+ * the rack. `EFFECT_COPY[id].primary` is `"strength"` for precisely these five,
14
+ * which is what says a module wants this treatment.
15
+ *
16
+ * Continuous rather than the three-point tables the design proposed. A table
17
+ * makes gentle/middle/strong three settings an author picks between, and the
18
+ * thing being modelled is not three settings — it is one axis, and the carve's
19
+ * knob has proved that reads. The proposal's figures survive as the anchors:
20
+ * each curve passes through them at 0, 0.5 and 1.
21
+ *
22
+ * Every number below is expressed in the parameter's own registry unit and then
23
+ * clamped by `normalizeAudioFxParams` on the way into the chain, so a profile
24
+ * cannot ship a value the effect would refuse.
25
+ */
26
+ import { normalizeAudioFxParams } from "./audioFx.js";
27
+ /** 0..1, whatever arrives. NaN reads as the middle rather than as silence. */
28
+ function clamp01(strength) {
29
+ return Number.isFinite(strength) ? Math.min(1, Math.max(0, strength)) : 0.5;
30
+ }
31
+ /** Two decimal places, so a derived value reads as a setting and not as float noise. */
32
+ function to2(value) {
33
+ return Number(value.toFixed(2));
34
+ }
35
+ export const HF_AUDIO_FX_PROFILES = {
36
+ compressor: {
37
+ label: "Evenness",
38
+ ends: { low: "Barely touched", high: "Very even, quite squashed" },
39
+ derives: ["threshold", "ratio", "attack", "release", "makeup"],
40
+ at(strength) {
41
+ const s = clamp01(strength);
42
+ return {
43
+ // Lower threshold and higher ratio together: more of the signal is
44
+ // caught, and what is caught is held harder. Moving one without the
45
+ // other is the pair of knobs this exists to stop an author meeting.
46
+ threshold: to2(-12 - s * 18),
47
+ ratio: to2(2 + s * 4),
48
+ // Faster as it gets firmer, because a firm compressor that lets peaks
49
+ // through is doing the audible half of its job and not the useful half.
50
+ attack: to2(25 - s * 20),
51
+ release: to2(300 - s * 210),
52
+ // Compression makes things quieter; this is the level put back, and it
53
+ // has to rise with the amount taken off or the knob reads as a volume
54
+ // control that goes the wrong way.
55
+ //
56
+ // Solved from measurement rather than proposed, and it is not linear:
57
+ // gain reduction accelerates as the threshold drops and the ratio rises
58
+ // together, so a straight line is too loud in the middle and too quiet
59
+ // at the top. The design's 1/3/7 dB left the track +0.9 dB at rest,
60
+ // +1.3 dB at the middle and −2.5 dB at full. Numbers in
61
+ // `~/audio-fx-profiles-ab/README.md`.
62
+ makeup: to2(s * s * 9.5),
63
+ };
64
+ },
65
+ },
66
+ gate: {
67
+ label: "Tightness",
68
+ ends: { low: "Only true silence", high: "Cuts quiet parts too" },
69
+ derives: ["threshold", "range", "release"],
70
+ at(strength) {
71
+ const s = clamp01(strength);
72
+ return {
73
+ threshold: to2(-55 + s * 23),
74
+ // How far the gaps are ducked, never to silence: a room that stops dead
75
+ // between sentences sounds broken rather than clean.
76
+ range: to2(-10 - s * 20),
77
+ // Release has to come along, which the design did not have — and it
78
+ // dominates: swept against a fixed threshold and range, the gaps move
79
+ // 0.2 dB at 140 ms and 13.4 dB at 10 ms. Left at the effect's 100 ms
80
+ // default the gate was very nearly inaudible whatever else it was told.
81
+ //
82
+ // Measured on narration, speech level is unmoved (−24.0 dB) at every
83
+ // release down to 10 ms, so the usual reason to stay slow — clipping
84
+ // word endings — does not bite on this material at these thresholds.
85
+ release: to2(120 - s * 105),
86
+ };
87
+ },
88
+ },
89
+ saturate: {
90
+ label: "Warmth",
91
+ ends: { low: "Just a sheen", high: "Openly distorted" },
92
+ derives: ["threshold", "output"],
93
+ at(strength) {
94
+ const s = clamp01(strength);
95
+ return {
96
+ // Drive: the lower the threshold, the more of the signal meets the
97
+ // curve.
98
+ threshold: to2(-3 - s * 15),
99
+ // Up, not down — which reverses the design's figure, on the measurement
100
+ // that motivated taking one. A soft clipper at -18 dB threshold IS a
101
+ // limiter at -18 dB: peak fell to 0.089 from 0.496 and RMS almost
102
+ // halved, so the proposed trim of −3 dB made "warmer" mean "much
103
+ // quieter" and an author would have heard the level, not the warmth.
104
+ // Accelerating for the same reason as the compressor's make-up.
105
+ output: to2(s * s * 2.8),
106
+ };
107
+ },
108
+ },
109
+ reverb: {
110
+ label: "Space",
111
+ ends: { low: "A small tight room", high: "A big open hall" },
112
+ derives: ["size", "wet", "dry"],
113
+ at(strength) {
114
+ const s = clamp01(strength);
115
+ return {
116
+ // Anchored at the design's three figures — 0.25 / 0.55 / 0.90 — which a
117
+ // single linear run cannot hit, because 0.55 is not their midpoint.
118
+ size: to2(s <= 0.5 ? 0.25 + s * 0.6 : 0.55 + (s - 0.5) * 0.7),
119
+ wet: to2(0.15 + s * 0.3),
120
+ // Dry comes down as wet goes up, but not by the same amount: the two
121
+ // legs sum, and matching them exactly makes a big room quieter than a
122
+ // small one instead of further away.
123
+ dry: to2(0.92 - s * 0.2),
124
+ };
125
+ },
126
+ },
127
+ bitcrush: {
128
+ label: "Crush",
129
+ ends: { low: "Slightly gritty", high: "Destroyed" },
130
+ derives: ["bits", "samples", "mix"],
131
+ at(strength) {
132
+ const s = clamp01(strength);
133
+ return {
134
+ // Fewer steps and longer holds. `bits` runs DOWN as the knob runs up,
135
+ // which is why it cannot be the module's face on its own.
136
+ bits: to2(14 - s * 8),
137
+ samples: Math.max(1, Math.round(1 + s * 3)),
138
+ mix: to2(0.25 + s * 0.75),
139
+ };
140
+ },
141
+ },
142
+ };
143
+ export function getAudioFxProfile(type) {
144
+ return HF_AUDIO_FX_PROFILES[type];
145
+ }
146
+ /**
147
+ * The parameters a profile sets at this strength, merged over what is there.
148
+ *
149
+ * Merged rather than replacing: a profile names only the parameters it derives,
150
+ * and the rest — a compressor's knee, a saturation's curve type — are the
151
+ * author's to set under Details and must survive the knob moving.
152
+ */
153
+ export function applyAudioFxProfile(type, strength, params) {
154
+ const profile = getAudioFxProfile(type);
155
+ if (!profile)
156
+ return params;
157
+ return normalizeAudioFxParams(type, { ...params, ...profile.at(strength) });
158
+ }
159
+ /**
160
+ * The strength a set of parameters reads as, by inverting the profile's own
161
+ * curve on its most characteristic parameter.
162
+ *
163
+ * A chain stores mechanism values, not the knob — the same contract
164
+ * `normalizeCarveSettings` has, and for the same reason: the mechanism is what
165
+ * renders, so it is what must be authoritative. Reading the knob back means one
166
+ * parameter has to be nominated as the one that says most about intent.
167
+ *
168
+ * A hand-edited chain therefore lands the knob at the nearest strength that
169
+ * would have produced its most telling value, which is the honest answer — the
170
+ * alternative is a knob parked at a default while the effect is set to
171
+ * something else entirely.
172
+ */
173
+ export function audioFxProfileStrength(type, params) {
174
+ const profile = getAudioFxProfile(type);
175
+ if (!profile)
176
+ return 0.5;
177
+ const key = profile.derives[0];
178
+ if (key === undefined)
179
+ return 0.5;
180
+ const value = params[key];
181
+ if (typeof value !== "number")
182
+ return 0.5;
183
+ // Searched, not inverted algebraically: a curve is free to be piecewise — the
184
+ // reverb's `size` is, because the design's three anchors are not evenly
185
+ // spaced — and a straight line between the endpoints reads such a curve back
186
+ // at the wrong place. Setting Space to 0.5 wrote size 0.55 and reopening the
187
+ // project drew the knob at 0.46, so every reopen nudged the sound.
188
+ //
189
+ // The grid IS the knob's own resolution (0.01), not something finer: a finer
190
+ // grid lands between two settable positions and rounds to a neighbour, which
191
+ // is how a search can be off by a step even where the curve is exact.
192
+ // Searching only reachable values makes the round trip exact.
193
+ const STEPS = 100;
194
+ let best = 0.5;
195
+ let bestErr = Infinity;
196
+ for (let i = 0; i <= STEPS; i += 1) {
197
+ const s = to2(i / STEPS);
198
+ const at = profile.at(s)[key];
199
+ if (typeof at !== "number")
200
+ continue;
201
+ const err = Math.abs(at - value);
202
+ if (err < bestErr) {
203
+ bestErr = err;
204
+ best = s;
205
+ }
206
+ }
207
+ return bestErr === Infinity ? 0.5 : to2(best);
208
+ }
209
+ //# sourceMappingURL=audioFxProfiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audioFxProfiles.js","sourceRoot":"","sources":["../src/audioFxProfiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,sBAAsB,EAA6B,MAAM,cAAc,CAAC;AAEjF,8EAA8E;AAC9E,SAAS,OAAO,CAAC,QAAgB;IAC/B,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9E,CAAC;AAED,wFAAwF;AACxF,SAAS,GAAG,CAAC,KAAa;IACxB,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC;AAaD,MAAM,CAAC,MAAM,oBAAoB,GAAqC;IACpE,UAAU,EAAE;QACV,KAAK,EAAE,UAAU;QACjB,IAAI,EAAE,EAAE,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,2BAA2B,EAAE;QAClE,OAAO,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;QAC9D,EAAE,CAAC,QAAQ;YACT,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC5B,OAAO;gBACL,mEAAmE;gBACnE,oEAAoE;gBACpE,oEAAoE;gBACpE,SAAS,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;gBAC5B,KAAK,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACrB,sEAAsE;gBACtE,wEAAwE;gBACxE,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;gBACxB,OAAO,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;gBAC3B,uEAAuE;gBACvE,sEAAsE;gBACtE,mCAAmC;gBACnC,EAAE;gBACF,sEAAsE;gBACtE,wEAAwE;gBACxE,uEAAuE;gBACvE,oEAAoE;gBACpE,wDAAwD;gBACxD,sCAAsC;gBACtC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;aACzB,CAAC;QACJ,CAAC;KACF;IAED,IAAI,EAAE;QACJ,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,EAAE,GAAG,EAAE,mBAAmB,EAAE,IAAI,EAAE,sBAAsB,EAAE;QAChE,OAAO,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,SAAS,CAAC;QAC1C,EAAE,CAAC,QAAQ;YACT,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC5B,OAAO;gBACL,SAAS,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;gBAC5B,wEAAwE;gBACxE,qDAAqD;gBACrD,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;gBACxB,oEAAoE;gBACpE,sEAAsE;gBACtE,qEAAqE;gBACrE,wEAAwE;gBACxE,EAAE;gBACF,qEAAqE;gBACrE,qEAAqE;gBACrE,qEAAqE;gBACrE,OAAO,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;aAC5B,CAAC;QACJ,CAAC;KACF;IAED,QAAQ,EAAE;QACR,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,kBAAkB,EAAE;QACvD,OAAO,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC;QAChC,EAAE,CAAC,QAAQ;YACT,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC5B,OAAO;gBACL,mEAAmE;gBACnE,SAAS;gBACT,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;gBAC3B,wEAAwE;gBACxE,qEAAqE;gBACrE,kEAAkE;gBAClE,iEAAiE;gBACjE,qEAAqE;gBACrE,gEAAgE;gBAChE,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;aACzB,CAAC;QACJ,CAAC;KACF;IAED,MAAM,EAAE;QACN,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,EAAE,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE,iBAAiB,EAAE;QAC5D,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC;QAC/B,EAAE,CAAC,QAAQ;YACT,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC5B,OAAO;gBACL,wEAAwE;gBACxE,oEAAoE;gBACpE,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;gBAC7D,GAAG,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC;gBACxB,qEAAqE;gBACrE,sEAAsE;gBACtE,qCAAqC;gBACrC,GAAG,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC;aACzB,CAAC;QACJ,CAAC;KACF;IAED,QAAQ,EAAE;QACR,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,EAAE,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW,EAAE;QACnD,OAAO,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC;QACnC,EAAE,CAAC,QAAQ;YACT,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC5B,OAAO;gBACL,sEAAsE;gBACtE,0DAA0D;gBAC1D,IAAI,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;gBACrB,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC3C,GAAG,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC;aAC1B,CAAC;QACJ,CAAC;KACF;CACF,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,QAAgB,EAChB,MAA4B;IAE5B,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC;IAC5B,OAAO,sBAAsB,CAAC,IAAI,EAAE,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,MAA4B;IAC/E,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO;QAAE,OAAO,GAAG,CAAC;IACzB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IAClC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IAC1C,8EAA8E;IAC9E,wEAAwE;IACxE,6EAA6E;IAC7E,6EAA6E;IAC7E,mEAAmE;IACnE,EAAE;IACF,6EAA6E;IAC7E,6EAA6E;IAC7E,sEAAsE;IACtE,8DAA8D;IAC9D,MAAM,KAAK,GAAG,GAAG,CAAC;IAClB,IAAI,IAAI,GAAG,GAAG,CAAC;IACf,IAAI,OAAO,GAAG,QAAQ,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;QACzB,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,OAAO,EAAE,KAAK,QAAQ;YAAE,SAAS;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC;QACjC,IAAI,GAAG,GAAG,OAAO,EAAE,CAAC;YAClB,OAAO,GAAG,GAAG,CAAC;YACd,IAAI,GAAG,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IACD,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC"}