@opendaw/studio-adapters 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/AudioData.d.ts +7 -0
- package/dist/AudioData.d.ts.map +1 -0
- package/dist/AudioData.js +1 -0
- package/dist/AudioFileBoxAdapter.d.ts +22 -0
- package/dist/AudioFileBoxAdapter.d.ts.map +1 -0
- package/dist/AudioFileBoxAdapter.js +19 -0
- package/dist/AudioLoader.d.ts +26 -0
- package/dist/AudioLoader.d.ts.map +1 -0
- package/dist/AudioLoader.js +1 -0
- package/dist/AudioMetaData.d.ts +8 -0
- package/dist/AudioMetaData.d.ts.map +1 -0
- package/dist/AudioMetaData.js +1 -0
- package/dist/AudioSample.d.ts +5 -0
- package/dist/AudioSample.d.ts.map +1 -0
- package/dist/AudioSample.js +1 -0
- package/dist/AutomatableParameterFieldAdapter.d.ts +35 -0
- package/dist/AutomatableParameterFieldAdapter.d.ts.map +1 -0
- package/dist/AutomatableParameterFieldAdapter.js +161 -0
- package/dist/BoxAdapter.d.ts +7 -0
- package/dist/BoxAdapter.d.ts.map +1 -0
- package/dist/BoxAdapter.js +1 -0
- package/dist/BoxAdapterCollection.d.ts +19 -0
- package/dist/BoxAdapterCollection.d.ts.map +1 -0
- package/dist/BoxAdapterCollection.js +35 -0
- package/dist/BoxAdapters.d.ts +11 -0
- package/dist/BoxAdapters.d.ts.map +1 -0
- package/dist/BoxAdapters.js +129 -0
- package/dist/BoxAdaptersContext.d.ts +24 -0
- package/dist/BoxAdaptersContext.d.ts.map +1 -0
- package/dist/BoxAdaptersContext.js +1 -0
- package/dist/ClipNotifications.d.ts +14 -0
- package/dist/ClipNotifications.d.ts.map +1 -0
- package/dist/ClipNotifications.js +1 -0
- package/dist/ClipSequencing.d.ts +12 -0
- package/dist/ClipSequencing.d.ts.map +1 -0
- package/dist/ClipSequencing.js +1 -0
- package/dist/EngineProcessorOptions.d.ts +18 -0
- package/dist/EngineProcessorOptions.d.ts.map +1 -0
- package/dist/EngineProcessorOptions.js +26 -0
- package/dist/EngineStateSchema.d.ts +7 -0
- package/dist/EngineStateSchema.d.ts.map +1 -0
- package/dist/EngineStateSchema.js +5 -0
- package/dist/FieldAdapter.d.ts +26 -0
- package/dist/FieldAdapter.d.ts.map +1 -0
- package/dist/FieldAdapter.js +59 -0
- package/dist/IconSymbol.d.ts +119 -0
- package/dist/IconSymbol.d.ts.map +1 -0
- package/dist/IconSymbol.js +119 -0
- package/dist/IndexComparator.d.ts +3 -0
- package/dist/IndexComparator.d.ts.map +1 -0
- package/dist/IndexComparator.js +11 -0
- package/dist/ManadatoryBoxes.d.ts +9 -0
- package/dist/ManadatoryBoxes.d.ts.map +1 -0
- package/dist/ManadatoryBoxes.js +1 -0
- package/dist/NoteBroadcaster.d.ts +14 -0
- package/dist/NoteBroadcaster.d.ts.map +1 -0
- package/dist/NoteBroadcaster.js +23 -0
- package/dist/NoteSender.d.ts +9 -0
- package/dist/NoteSender.d.ts.map +1 -0
- package/dist/NoteSender.js +15 -0
- package/dist/NoteStreamReceiver.d.ts +12 -0
- package/dist/NoteStreamReceiver.d.ts.map +1 -0
- package/dist/NoteStreamReceiver.js +23 -0
- package/dist/ParameterAdapterSet.d.ts +14 -0
- package/dist/ParameterAdapterSet.d.ts.map +1 -0
- package/dist/ParameterAdapterSet.js +27 -0
- package/dist/ParameterFieldAdapters.d.ts +11 -0
- package/dist/ParameterFieldAdapters.d.ts.map +1 -0
- package/dist/ParameterFieldAdapters.js +13 -0
- package/dist/PeakMeterProcessorOptions.d.ts +8 -0
- package/dist/PeakMeterProcessorOptions.d.ts.map +1 -0
- package/dist/PeakMeterProcessorOptions.js +1 -0
- package/dist/PianoModeAdapter.d.ts +15 -0
- package/dist/PianoModeAdapter.d.ts.map +1 -0
- package/dist/PianoModeAdapter.js +28 -0
- package/dist/ProjectDecoder.d.ts +13 -0
- package/dist/ProjectDecoder.d.ts.map +1 -0
- package/dist/ProjectDecoder.js +27 -0
- package/dist/RecordingProcessorOptions.d.ts +4 -0
- package/dist/RecordingProcessorOptions.d.ts.map +1 -0
- package/dist/RecordingProcessorOptions.js +1 -0
- package/dist/RingBuffer.d.ts +19 -0
- package/dist/RingBuffer.d.ts.map +1 -0
- package/dist/RingBuffer.js +92 -0
- package/dist/RootBoxAdapter.d.ts +30 -0
- package/dist/RootBoxAdapter.d.ts.map +1 -0
- package/dist/RootBoxAdapter.js +43 -0
- package/dist/SortedBoxAdapterCollection.d.ts +29 -0
- package/dist/SortedBoxAdapterCollection.d.ts.map +1 -0
- package/dist/SortedBoxAdapterCollection.js +100 -0
- package/dist/UnionAdapterTypes.d.ts +15 -0
- package/dist/UnionAdapterTypes.d.ts.map +1 -0
- package/dist/UnionAdapterTypes.js +5 -0
- package/dist/UpdateClockRate.d.ts +2 -0
- package/dist/UpdateClockRate.d.ts.map +1 -0
- package/dist/UpdateClockRate.js +2 -0
- package/dist/audio-unit/AudioBusBoxAdapter.d.ts +28 -0
- package/dist/audio-unit/AudioBusBoxAdapter.d.ts.map +1 -0
- package/dist/audio-unit/AudioBusBoxAdapter.js +33 -0
- package/dist/audio-unit/AudioUnitBoxAdapter.d.ts +55 -0
- package/dist/audio-unit/AudioUnitBoxAdapter.d.ts.map +1 -0
- package/dist/audio-unit/AudioUnitBoxAdapter.js +97 -0
- package/dist/audio-unit/AudioUnitInput.d.ts +21 -0
- package/dist/audio-unit/AudioUnitInput.d.ts.map +1 -0
- package/dist/audio-unit/AudioUnitInput.js +74 -0
- package/dist/audio-unit/AudioUnitInputAdapter.d.ts +4 -0
- package/dist/audio-unit/AudioUnitInputAdapter.d.ts.map +1 -0
- package/dist/audio-unit/AudioUnitInputAdapter.js +1 -0
- package/dist/audio-unit/AudioUnitOutput.d.ts +14 -0
- package/dist/audio-unit/AudioUnitOutput.d.ts.map +1 -0
- package/dist/audio-unit/AudioUnitOutput.js +42 -0
- package/dist/audio-unit/AudioUnitTracks.d.ts +21 -0
- package/dist/audio-unit/AudioUnitTracks.d.ts.map +1 -0
- package/dist/audio-unit/AudioUnitTracks.js +62 -0
- package/dist/audio-unit/AuxSendBoxAdapter.d.ts +23 -0
- package/dist/audio-unit/AuxSendBoxAdapter.d.ts.map +1 -0
- package/dist/audio-unit/AuxSendBoxAdapter.js +58 -0
- package/dist/devices/audio-effects/DelayDeviceBoxAdapter.d.ts +35 -0
- package/dist/devices/audio-effects/DelayDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/audio-effects/DelayDeviceBoxAdapter.js +50 -0
- package/dist/devices/audio-effects/ModularDeviceBoxAdapter.d.ts +31 -0
- package/dist/devices/audio-effects/ModularDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/audio-effects/ModularDeviceBoxAdapter.js +38 -0
- package/dist/devices/audio-effects/RevampDeviceBoxAdapter.d.ts +52 -0
- package/dist/devices/audio-effects/RevampDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/audio-effects/RevampDeviceBoxAdapter.js +66 -0
- package/dist/devices/audio-effects/ReverbDeviceBoxAdapter.d.ts +35 -0
- package/dist/devices/audio-effects/ReverbDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/audio-effects/ReverbDeviceBoxAdapter.js +44 -0
- package/dist/devices/audio-effects/StereoToolDeviceBoxAdapter.d.ts +33 -0
- package/dist/devices/audio-effects/StereoToolDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/audio-effects/StereoToolDeviceBoxAdapter.js +41 -0
- package/dist/devices/instruments/NanoDeviceBoxAdapter.d.ts +32 -0
- package/dist/devices/instruments/NanoDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/instruments/NanoDeviceBoxAdapter.js +40 -0
- package/dist/devices/instruments/Playfield/Gate.d.ts +6 -0
- package/dist/devices/instruments/Playfield/Gate.d.ts.map +1 -0
- package/dist/devices/instruments/Playfield/Gate.js +6 -0
- package/dist/devices/instruments/Playfield/PlayfieldSampleBoxAdapter.d.ts +63 -0
- package/dist/devices/instruments/Playfield/PlayfieldSampleBoxAdapter.d.ts.map +1 -0
- package/dist/devices/instruments/Playfield/PlayfieldSampleBoxAdapter.js +128 -0
- package/dist/devices/instruments/PlayfieldDeviceBoxAdapter.d.ts +35 -0
- package/dist/devices/instruments/PlayfieldDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/instruments/PlayfieldDeviceBoxAdapter.js +40 -0
- package/dist/devices/instruments/TapeDeviceBoxAdapter.d.ts +34 -0
- package/dist/devices/instruments/TapeDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/instruments/TapeDeviceBoxAdapter.js +42 -0
- package/dist/devices/instruments/VaporisateurDeviceBoxAdapter.d.ts +39 -0
- package/dist/devices/instruments/VaporisateurDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/instruments/VaporisateurDeviceBoxAdapter.js +47 -0
- package/dist/devices/midi-effects/ArpeggioDeviceBoxAdapter.d.ts +37 -0
- package/dist/devices/midi-effects/ArpeggioDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/midi-effects/ArpeggioDeviceBoxAdapter.js +51 -0
- package/dist/devices/midi-effects/PitchDeviceBoxAdapter.d.ts +32 -0
- package/dist/devices/midi-effects/PitchDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/midi-effects/PitchDeviceBoxAdapter.js +39 -0
- package/dist/devices/midi-effects/ZeitgeistDeviceBoxAdapter.d.ts +28 -0
- package/dist/devices/midi-effects/ZeitgeistDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/midi-effects/ZeitgeistDeviceBoxAdapter.js +35 -0
- package/dist/devices.d.ts +68 -0
- package/dist/devices.d.ts.map +1 -0
- package/dist/devices.js +55 -0
- package/dist/editing/UserEditing.d.ts +15 -0
- package/dist/editing/UserEditing.d.ts.map +1 -0
- package/dist/editing/UserEditing.js +39 -0
- package/dist/editing/UserEditingManager.d.ts +14 -0
- package/dist/editing/UserEditingManager.d.ts.map +1 -0
- package/dist/editing/UserEditingManager.js +23 -0
- package/dist/grooves/GrooveBoxAdapter.d.ts +10 -0
- package/dist/grooves/GrooveBoxAdapter.d.ts.map +1 -0
- package/dist/grooves/GrooveBoxAdapter.js +4 -0
- package/dist/grooves/GrooveShuffleBoxAdapter.d.ts +27 -0
- package/dist/grooves/GrooveShuffleBoxAdapter.d.ts.map +1 -0
- package/dist/grooves/GrooveShuffleBoxAdapter.js +43 -0
- package/dist/index.d.ts +98 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +99 -0
- package/dist/modular/abstract.d.ts +30 -0
- package/dist/modular/abstract.d.ts.map +1 -0
- package/dist/modular/abstract.js +39 -0
- package/dist/modular/connection.d.ts +15 -0
- package/dist/modular/connection.d.ts.map +1 -0
- package/dist/modular/connection.js +12 -0
- package/dist/modular/connector.d.ts +21 -0
- package/dist/modular/connector.d.ts.map +1 -0
- package/dist/modular/connector.js +42 -0
- package/dist/modular/modular.d.ts +30 -0
- package/dist/modular/modular.d.ts.map +1 -0
- package/dist/modular/modular.js +68 -0
- package/dist/modular/module.d.ts +21 -0
- package/dist/modular/module.d.ts.map +1 -0
- package/dist/modular/module.js +23 -0
- package/dist/modular/modules/audio-input.d.ts +14 -0
- package/dist/modular/modules/audio-input.d.ts.map +1 -0
- package/dist/modular/modules/audio-input.js +17 -0
- package/dist/modular/modules/audio-output.d.ts +14 -0
- package/dist/modular/modules/audio-output.d.ts.map +1 -0
- package/dist/modular/modules/audio-output.js +17 -0
- package/dist/modular/modules/delay.d.ts +17 -0
- package/dist/modular/modules/delay.d.ts.map +1 -0
- package/dist/modular/modules/delay.js +23 -0
- package/dist/modular/modules/gain.d.ts +17 -0
- package/dist/modular/modules/gain.d.ts.map +1 -0
- package/dist/modular/modules/gain.js +23 -0
- package/dist/modular/modules/multiplier.d.ts +13 -0
- package/dist/modular/modules/multiplier.d.ts.map +1 -0
- package/dist/modular/modules/multiplier.js +19 -0
- package/dist/modular/user-interface.d.ts +21 -0
- package/dist/modular/user-interface.d.ts.map +1 -0
- package/dist/modular/user-interface.js +23 -0
- package/dist/protocols.d.ts +25 -0
- package/dist/protocols.d.ts.map +1 -0
- package/dist/protocols.js +1 -0
- package/dist/selection/FilteredSelection.d.ts +20 -0
- package/dist/selection/FilteredSelection.d.ts.map +1 -0
- package/dist/selection/FilteredSelection.js +58 -0
- package/dist/selection/SelectableVertex.d.ts +4 -0
- package/dist/selection/SelectableVertex.d.ts.map +1 -0
- package/dist/selection/SelectableVertex.js +1 -0
- package/dist/selection/SelectionEntry.d.ts +7 -0
- package/dist/selection/SelectionEntry.d.ts.map +1 -0
- package/dist/selection/SelectionEntry.js +1 -0
- package/dist/selection/VertexSelection.d.ts +29 -0
- package/dist/selection/VertexSelection.d.ts.map +1 -0
- package/dist/selection/VertexSelection.js +120 -0
- package/dist/selection/isVertexOfBox.d.ts +5 -0
- package/dist/selection/isVertexOfBox.d.ts.map +1 -0
- package/dist/selection/isVertexOfBox.js +1 -0
- package/dist/timeline/ClipBoxAdapter.d.ts +38 -0
- package/dist/timeline/ClipBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/ClipBoxAdapter.js +11 -0
- package/dist/timeline/MarkerBoxAdapter.d.ts +24 -0
- package/dist/timeline/MarkerBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/MarkerBoxAdapter.js +41 -0
- package/dist/timeline/MarkerTrackAdapter.d.ts +19 -0
- package/dist/timeline/MarkerTrackAdapter.d.ts.map +1 -0
- package/dist/timeline/MarkerTrackAdapter.js +45 -0
- package/dist/timeline/RegionBoxAdapter.d.ts +48 -0
- package/dist/timeline/RegionBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/RegionBoxAdapter.js +12 -0
- package/dist/timeline/RegionEditing.d.ts +7 -0
- package/dist/timeline/RegionEditing.d.ts.map +1 -0
- package/dist/timeline/RegionEditing.js +40 -0
- package/dist/timeline/TimelineBoxAdapter.d.ts +16 -0
- package/dist/timeline/TimelineBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/TimelineBoxAdapter.js +14 -0
- package/dist/timeline/TrackBoxAdapter.d.ts +32 -0
- package/dist/timeline/TrackBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/TrackBoxAdapter.js +167 -0
- package/dist/timeline/TrackClips.d.ts +16 -0
- package/dist/timeline/TrackClips.d.ts.map +1 -0
- package/dist/timeline/TrackClips.js +26 -0
- package/dist/timeline/TrackRegions.d.ts +17 -0
- package/dist/timeline/TrackRegions.d.ts.map +1 -0
- package/dist/timeline/TrackRegions.js +41 -0
- package/dist/timeline/TrackType.d.ts +12 -0
- package/dist/timeline/TrackType.d.ts.map +1 -0
- package/dist/timeline/TrackType.js +37 -0
- package/dist/timeline/clip/AudioClipBoxAdapter.d.ts +39 -0
- package/dist/timeline/clip/AudioClipBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/clip/AudioClipBoxAdapter.js +87 -0
- package/dist/timeline/clip/NoteClipBoxAdapter.d.ts +39 -0
- package/dist/timeline/clip/NoteClipBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/clip/NoteClipBoxAdapter.js +92 -0
- package/dist/timeline/clip/ValueClipBoxAdapter.d.ts +40 -0
- package/dist/timeline/clip/ValueClipBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/clip/ValueClipBoxAdapter.js +98 -0
- package/dist/timeline/collection/NoteEventCollectionBoxAdapter.d.ts +40 -0
- package/dist/timeline/collection/NoteEventCollectionBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/collection/NoteEventCollectionBoxAdapter.js +136 -0
- package/dist/timeline/collection/ValueEventCollectionBoxAdapter.d.ts +33 -0
- package/dist/timeline/collection/ValueEventCollectionBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/collection/ValueEventCollectionBoxAdapter.js +139 -0
- package/dist/timeline/event/InterpolationFieldAdapter.d.ts +8 -0
- package/dist/timeline/event/InterpolationFieldAdapter.d.ts.map +1 -0
- package/dist/timeline/event/InterpolationFieldAdapter.js +47 -0
- package/dist/timeline/event/NoteEventBoxAdapter.d.ts +45 -0
- package/dist/timeline/event/NoteEventBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/event/NoteEventBoxAdapter.js +106 -0
- package/dist/timeline/event/ValueEventBoxAdapter.d.ts +39 -0
- package/dist/timeline/event/ValueEventBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/event/ValueEventBoxAdapter.js +113 -0
- package/dist/timeline/region/AudioRegionBoxAdapter.d.ts +53 -0
- package/dist/timeline/region/AudioRegionBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/region/AudioRegionBoxAdapter.js +143 -0
- package/dist/timeline/region/NoteRegionBoxAdapter.d.ts +53 -0
- package/dist/timeline/region/NoteRegionBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/region/NoteRegionBoxAdapter.js +186 -0
- package/dist/timeline/region/ValueRegionBoxAdapter.d.ts +59 -0
- package/dist/timeline/region/ValueRegionBoxAdapter.d.ts.map +1 -0
- package/dist/timeline/region/ValueRegionBoxAdapter.js +193 -0
- package/dist/unions.d.ts +11 -0
- package/dist/unions.d.ts.map +1 -0
- package/dist/unions.js +17 -0
- package/package.json +38 -0
@@ -0,0 +1,167 @@
|
|
1
|
+
import { asInstanceOf, DefaultObservableValue, isInstanceOf, Option, panic, Terminable, Terminator } from "@opendaw/lib-std";
|
2
|
+
import { StringField } from "@opendaw/lib-box";
|
3
|
+
import { TrackClips } from "./TrackClips";
|
4
|
+
import { TrackRegions } from "./TrackRegions";
|
5
|
+
import { AudioUnitBoxAdapter } from "../audio-unit/AudioUnitBoxAdapter";
|
6
|
+
import { TrackType } from "./TrackType";
|
7
|
+
import { UpdateClockRate } from "../UpdateClockRate";
|
8
|
+
import { ValueClipBoxAdapter } from "./clip/ValueClipBoxAdapter";
|
9
|
+
import { ValueRegionBoxAdapter } from "./region/ValueRegionBoxAdapter";
|
10
|
+
import { AudioUnitBox } from "@opendaw/studio-boxes";
|
11
|
+
export class TrackBoxAdapter {
|
12
|
+
#context;
|
13
|
+
#box;
|
14
|
+
#terminator;
|
15
|
+
#clips;
|
16
|
+
#regions;
|
17
|
+
#listIndex;
|
18
|
+
constructor(context, box) {
|
19
|
+
this.#context = context;
|
20
|
+
this.#box = box;
|
21
|
+
this.#terminator = new Terminator();
|
22
|
+
this.#clips = this.#terminator.own(new TrackClips(this, context.boxAdapters));
|
23
|
+
this.#regions = this.#terminator.own(new TrackRegions(this, context.boxAdapters));
|
24
|
+
this.#listIndex = this.#terminator.own(new DefaultObservableValue(-1));
|
25
|
+
}
|
26
|
+
catchupAndSubscribePath(observer) {
|
27
|
+
const path = [Option.None, Option.None];
|
28
|
+
const updater = () => {
|
29
|
+
if (path.every(option => option.nonEmpty())) {
|
30
|
+
observer(Option.wrap(path.map(option => option.unwrap())));
|
31
|
+
}
|
32
|
+
else {
|
33
|
+
observer(Option.None);
|
34
|
+
}
|
35
|
+
};
|
36
|
+
return Terminable.many(this.#catchupAndSubscribeTargetDeviceName(option => {
|
37
|
+
if (path[0].equals(option)) {
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
path[0] = option;
|
41
|
+
updater();
|
42
|
+
}), this.#catchupAndSubscribeTargetControlName(option => {
|
43
|
+
if (path[1].equals(option)) {
|
44
|
+
return;
|
45
|
+
}
|
46
|
+
path[1] = option;
|
47
|
+
updater();
|
48
|
+
}));
|
49
|
+
}
|
50
|
+
#catchupAndSubscribeTargetDeviceName(observer) {
|
51
|
+
const targetVertex = this.#box.target.targetVertex;
|
52
|
+
if (targetVertex.nonEmpty()) {
|
53
|
+
const vertex = targetVertex.unwrap().box;
|
54
|
+
if (vertex instanceof AudioUnitBox) {
|
55
|
+
const adapter = this.#context.boxAdapters.adapterFor(vertex, AudioUnitBoxAdapter);
|
56
|
+
return adapter.input.catchupAndSubscribeLabelChange(option => observer(option));
|
57
|
+
}
|
58
|
+
else if ("label" in vertex && vertex.label instanceof StringField) {
|
59
|
+
return vertex.label.catchupAndSubscribe(owner => observer(Option.wrap(owner.getValue())));
|
60
|
+
}
|
61
|
+
else {
|
62
|
+
// TODO This is a workaround. We need to find a way to dig into the box for a name
|
63
|
+
observer(Option.wrap(vertex.name));
|
64
|
+
return Terminable.Empty;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
observer(Option.None);
|
68
|
+
return Terminable.Empty;
|
69
|
+
}
|
70
|
+
#catchupAndSubscribeTargetControlName(observer) {
|
71
|
+
const type = this.type;
|
72
|
+
switch (type) {
|
73
|
+
case TrackType.Audio:
|
74
|
+
case TrackType.Notes: {
|
75
|
+
observer(Option.wrap(TrackType[type]));
|
76
|
+
return Terminable.Empty;
|
77
|
+
}
|
78
|
+
case TrackType.Value: {
|
79
|
+
const target = this.#box.target.targetVertex.unwrap();
|
80
|
+
if (target.isField()) {
|
81
|
+
observer(this.#context.parameterFieldAdapters.opt(target.address).map(vertex => vertex.name));
|
82
|
+
}
|
83
|
+
else if (target.isBox()) {
|
84
|
+
// I cannot think of a scenario where target is a box, but at least the UI shows the box's name
|
85
|
+
observer(Option.wrap(target.name));
|
86
|
+
}
|
87
|
+
else {
|
88
|
+
return panic("Illegal State. Vertex is not a field nor box.");
|
89
|
+
}
|
90
|
+
return Terminable.Empty;
|
91
|
+
}
|
92
|
+
case TrackType.Undefined: {
|
93
|
+
observer(Option.wrap(""));
|
94
|
+
return Terminable.Empty;
|
95
|
+
}
|
96
|
+
default: {
|
97
|
+
observer(Option.None);
|
98
|
+
return Terminable.Empty;
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}
|
102
|
+
terminate() { this.#terminator.terminate(); }
|
103
|
+
get audioUnit() { return asInstanceOf(this.#box.tracks.targetVertex.unwrap().box, AudioUnitBox); }
|
104
|
+
get target() { return this.#box.target; }
|
105
|
+
get clips() { return this.#clips; }
|
106
|
+
get regions() { return this.#regions; }
|
107
|
+
get enabled() { return this.#box.enabled; }
|
108
|
+
get indexField() { return this.#box.index; }
|
109
|
+
get type() { return this.#box.type.getValue(); }
|
110
|
+
get box() { return this.#box; }
|
111
|
+
get uuid() { return this.#box.address.uuid; }
|
112
|
+
get address() { return this.#box.address; }
|
113
|
+
get listIndex() { return this.#listIndex.getValue(); }
|
114
|
+
set listIndex(value) { this.#listIndex.setValue(value); }
|
115
|
+
accepts(subject) {
|
116
|
+
switch (subject.type) {
|
117
|
+
case "audio-clip":
|
118
|
+
return this.type === TrackType.Audio;
|
119
|
+
case "note-clip":
|
120
|
+
return this.type === TrackType.Notes;
|
121
|
+
case "value-clip":
|
122
|
+
return this.type === TrackType.Value;
|
123
|
+
case "audio-region":
|
124
|
+
return this.type === TrackType.Audio;
|
125
|
+
case "note-region":
|
126
|
+
return this.type === TrackType.Notes;
|
127
|
+
case "value-region":
|
128
|
+
return this.type === TrackType.Value;
|
129
|
+
}
|
130
|
+
}
|
131
|
+
valueAt(position, fallback) {
|
132
|
+
if (!this.enabled.getValue()) {
|
133
|
+
return fallback;
|
134
|
+
}
|
135
|
+
let value = fallback;
|
136
|
+
const intervals = this.#context.clipSequencing.iterate(this.uuid, position, position + UpdateClockRate);
|
137
|
+
for (const { optClip, sectionFrom } of intervals) {
|
138
|
+
value = optClip.match({
|
139
|
+
none: () => {
|
140
|
+
const region = this.regions.collection.lowerEqual(position, region => !region.mute);
|
141
|
+
if (region === null) {
|
142
|
+
const firstRegion = this.regions.collection.optAt(0);
|
143
|
+
return isInstanceOf(firstRegion, ValueRegionBoxAdapter) ? firstRegion.incomingValue(fallback) : fallback;
|
144
|
+
}
|
145
|
+
else if (isInstanceOf(region, ValueRegionBoxAdapter)) {
|
146
|
+
if (position < region.complete) {
|
147
|
+
return region.valueAt(position, fallback);
|
148
|
+
}
|
149
|
+
else {
|
150
|
+
return region.outgoingValue(fallback);
|
151
|
+
}
|
152
|
+
}
|
153
|
+
return fallback;
|
154
|
+
},
|
155
|
+
some: clip => {
|
156
|
+
if (sectionFrom === position) {
|
157
|
+
if (isInstanceOf(clip, ValueClipBoxAdapter)) {
|
158
|
+
return clip.valueAt(position, fallback);
|
159
|
+
}
|
160
|
+
}
|
161
|
+
return fallback;
|
162
|
+
}
|
163
|
+
});
|
164
|
+
}
|
165
|
+
return value;
|
166
|
+
}
|
167
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { Pointers } from "@opendaw/studio-enums";
|
2
|
+
import { Observer, Subscription, Terminable } from "@opendaw/lib-std";
|
3
|
+
import { TrackBoxAdapter } from "./TrackBoxAdapter";
|
4
|
+
import { SortedBoxAdapterCollection } from "../SortedBoxAdapterCollection";
|
5
|
+
import { AnyClipBoxAdapter } from "../UnionAdapterTypes";
|
6
|
+
import { BoxAdapters } from "../BoxAdapters";
|
7
|
+
export declare class TrackClips implements Terminable {
|
8
|
+
#private;
|
9
|
+
constructor(adapter: TrackBoxAdapter, boxAdapters: BoxAdapters);
|
10
|
+
get trackBoxAdapter(): TrackBoxAdapter;
|
11
|
+
get collection(): SortedBoxAdapterCollection<AnyClipBoxAdapter, Pointers.ClipCollection>;
|
12
|
+
dispatchChange(): void;
|
13
|
+
subscribeChanges(observer: Observer<void>): Subscription;
|
14
|
+
terminate(): void;
|
15
|
+
}
|
16
|
+
//# sourceMappingURL=TrackClips.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"TrackClips.d.ts","sourceRoot":"","sources":["../../src/timeline/TrackClips.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAW,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAa,MAAM,kBAAkB,CAAA;AACzF,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAC,0BAA0B,EAAC,MAAM,+BAA+B,CAAA;AACxE,OAAO,EAAC,iBAAiB,EAAC,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAA;AAG1C,qBAAa,UAAW,YAAW,UAAU;;gBAM7B,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW;IAc9D,IAAI,eAAe,IAAI,eAAe,CAA+B;IACrE,IAAI,UAAU,IAAI,0BAA0B,CAAC,iBAAiB,EAAE,QAAQ,CAAC,cAAc,CAAC,CAA0B;IAElH,cAAc,IAAI,IAAI;IACtB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,YAAY;IACxD,SAAS,IAAI,IAAI;CACpB"}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { Pointers } from "@opendaw/studio-enums";
|
2
|
+
import { Notifier, Terminator } from "@opendaw/lib-std";
|
3
|
+
import { SortedBoxAdapterCollection } from "../SortedBoxAdapterCollection";
|
4
|
+
import { ClipAdapters } from "./ClipBoxAdapter";
|
5
|
+
export class TrackClips {
|
6
|
+
#trackBoxAdapter;
|
7
|
+
#terminator;
|
8
|
+
#changeNotifier;
|
9
|
+
#collection;
|
10
|
+
constructor(adapter, boxAdapters) {
|
11
|
+
this.#trackBoxAdapter = adapter;
|
12
|
+
this.#terminator = new Terminator();
|
13
|
+
this.#changeNotifier = this.#terminator.own(new Notifier());
|
14
|
+
this.#collection = this.#terminator.own(SortedBoxAdapterCollection.create(adapter.box.clips, box => ClipAdapters.for(boxAdapters, box), Pointers.ClipCollection));
|
15
|
+
this.#collection.subscribe({
|
16
|
+
onAdd: () => this.dispatchChange(),
|
17
|
+
onRemove: () => this.dispatchChange(),
|
18
|
+
onReorder: () => this.dispatchChange()
|
19
|
+
});
|
20
|
+
}
|
21
|
+
get trackBoxAdapter() { return this.#trackBoxAdapter; }
|
22
|
+
get collection() { return this.#collection; }
|
23
|
+
dispatchChange() { this.#changeNotifier.notify(); }
|
24
|
+
subscribeChanges(observer) { return this.#changeNotifier.subscribe(observer); }
|
25
|
+
terminate() { this.#terminator.terminate(); }
|
26
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { RegionCollection } from "@opendaw/lib-dsp";
|
2
|
+
import { Observer, SortedSet, Subscription } from "@opendaw/lib-std";
|
3
|
+
import { TrackBoxAdapter } from "./TrackBoxAdapter";
|
4
|
+
import { AnyRegionBoxAdapter } from "../UnionAdapterTypes";
|
5
|
+
import { BoxAdapters } from "../BoxAdapters";
|
6
|
+
export declare class TrackRegions {
|
7
|
+
#private;
|
8
|
+
constructor(adapter: TrackBoxAdapter, boxAdapters: BoxAdapters);
|
9
|
+
get trackBoxAdapter(): TrackBoxAdapter;
|
10
|
+
get collection(): RegionCollection<AnyRegionBoxAdapter>;
|
11
|
+
get adapters(): SortedSet<Readonly<Uint8Array>, AnyRegionBoxAdapter>;
|
12
|
+
onIndexingChanged(): void;
|
13
|
+
subscribeChanges(observer: Observer<void>): Subscription;
|
14
|
+
dispatchChange(): void;
|
15
|
+
terminate(): void;
|
16
|
+
}
|
17
|
+
//# sourceMappingURL=TrackRegions.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"TrackRegions.d.ts","sourceRoot":"","sources":["../../src/timeline/TrackRegions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAC,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAmB,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAmB,MAAM,kBAAkB,CAAA;AAEtG,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAC,mBAAmB,EAAC,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAA;AAG1C,qBAAa,YAAY;;gBAQT,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW;IAwB9D,IAAI,eAAe,IAAI,eAAe,CAA+B;IACrE,IAAI,UAAU,IAAI,gBAAgB,CAAC,mBAAmB,CAAC,CAA0B;IACjF,IAAI,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,mBAAmB,CAAC,CAAwB;IAE5F,iBAAiB,IAAI,IAAI;IAKzB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,YAAY;IACxD,cAAc,IAAI,IAAI;IACtB,SAAS;CACZ"}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { RegionCollection } from "@opendaw/lib-dsp";
|
2
|
+
import { assert, Notifier, Terminator, UUID } from "@opendaw/lib-std";
|
3
|
+
import { Pointers } from "@opendaw/studio-enums";
|
4
|
+
import { RegionAdapters, RegionComparator } from "./RegionBoxAdapter";
|
5
|
+
export class TrackRegions {
|
6
|
+
#trackBoxAdapter;
|
7
|
+
#terminator;
|
8
|
+
#changeNotifier;
|
9
|
+
#collection;
|
10
|
+
#adapters;
|
11
|
+
constructor(adapter, boxAdapters) {
|
12
|
+
this.#trackBoxAdapter = adapter;
|
13
|
+
this.#terminator = new Terminator();
|
14
|
+
this.#changeNotifier = this.#terminator.own(new Notifier());
|
15
|
+
this.#collection = RegionCollection.create(RegionComparator);
|
16
|
+
this.#adapters = UUID.newSet(adapter => adapter.uuid);
|
17
|
+
this.#terminator.ownAll(this.#trackBoxAdapter.box.regions.pointerHub.catchupAndSubscribeTransactual({
|
18
|
+
onAdd: ({ box }) => {
|
19
|
+
const adapter = RegionAdapters.for(boxAdapters, box);
|
20
|
+
const added = this.#adapters.add(adapter);
|
21
|
+
assert(added, `Cannot add ${box}`);
|
22
|
+
this.#collection.add(adapter);
|
23
|
+
this.dispatchChange();
|
24
|
+
},
|
25
|
+
onRemove: ({ box: { address: { uuid } } }) => {
|
26
|
+
this.#collection.remove(this.#adapters.removeByKey(uuid));
|
27
|
+
this.dispatchChange();
|
28
|
+
}
|
29
|
+
}, Pointers.RegionCollection));
|
30
|
+
}
|
31
|
+
get trackBoxAdapter() { return this.#trackBoxAdapter; }
|
32
|
+
get collection() { return this.#collection; }
|
33
|
+
get adapters() { return this.#adapters; }
|
34
|
+
onIndexingChanged() {
|
35
|
+
this.#collection.onIndexingChanged();
|
36
|
+
this.dispatchChange();
|
37
|
+
}
|
38
|
+
subscribeChanges(observer) { return this.#changeNotifier.subscribe(observer); }
|
39
|
+
dispatchChange() { this.#changeNotifier.notify(); }
|
40
|
+
terminate() { this.#terminator.terminate(); }
|
41
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { IconSymbol } from "../IconSymbol";
|
2
|
+
export declare enum TrackType {
|
3
|
+
Undefined = 0,
|
4
|
+
Notes = 1,
|
5
|
+
Audio = 2,
|
6
|
+
Value = 3
|
7
|
+
}
|
8
|
+
export declare namespace TrackType {
|
9
|
+
const toLabelString: (type: TrackType) => string;
|
10
|
+
const toIconSymbol: (type: TrackType) => IconSymbol.Waveform | IconSymbol.AudioBus | IconSymbol.Piano | IconSymbol.Automation | IconSymbol.Unknown;
|
11
|
+
}
|
12
|
+
//# sourceMappingURL=TrackType.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"TrackType.d.ts","sourceRoot":"","sources":["../../src/timeline/TrackType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAA;AAExC,oBAAY,SAAS;IAAE,SAAS,IAAA;IAAE,KAAK,IAAA;IAAE,KAAK,IAAA;IAAE,KAAK,IAAA;CAAC;AAEtD,yBAAiB,SAAS,CAAC;IAChB,MAAM,aAAa,GAAI,MAAM,SAAS,KAAG,MAY/C,CAAA;IACM,MAAM,YAAY,GAAI,MAAM,SAAS,8GAa3C,CAAA;CACJ"}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import { IconSymbol } from "../IconSymbol";
|
2
|
+
export var TrackType;
|
3
|
+
(function (TrackType) {
|
4
|
+
TrackType[TrackType["Undefined"] = 0] = "Undefined";
|
5
|
+
TrackType[TrackType["Notes"] = 1] = "Notes";
|
6
|
+
TrackType[TrackType["Audio"] = 2] = "Audio";
|
7
|
+
TrackType[TrackType["Value"] = 3] = "Value";
|
8
|
+
})(TrackType || (TrackType = {}));
|
9
|
+
(function (TrackType) {
|
10
|
+
TrackType.toLabelString = (type) => {
|
11
|
+
switch (type) {
|
12
|
+
case TrackType.Audio:
|
13
|
+
return "Audio";
|
14
|
+
case TrackType.Notes:
|
15
|
+
return "Notes";
|
16
|
+
case TrackType.Value:
|
17
|
+
return "Automation";
|
18
|
+
case TrackType.Undefined:
|
19
|
+
default:
|
20
|
+
return "N/A";
|
21
|
+
}
|
22
|
+
};
|
23
|
+
TrackType.toIconSymbol = (type) => {
|
24
|
+
switch (type) {
|
25
|
+
case TrackType.Audio:
|
26
|
+
return IconSymbol.Waveform;
|
27
|
+
case TrackType.Notes:
|
28
|
+
return IconSymbol.Piano;
|
29
|
+
case TrackType.Value:
|
30
|
+
return IconSymbol.Automation;
|
31
|
+
case TrackType.Undefined:
|
32
|
+
return IconSymbol.AudioBus;
|
33
|
+
default:
|
34
|
+
return IconSymbol.Unknown;
|
35
|
+
}
|
36
|
+
};
|
37
|
+
})(TrackType || (TrackType = {}));
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import { ppqn } from "@opendaw/lib-dsp";
|
2
|
+
import { int, Nullish, ObservableValue, Observer, Option, Subscription, UUID } from "@opendaw/lib-std";
|
3
|
+
import { AudioClipBox } from "@opendaw/studio-boxes";
|
4
|
+
import { Address, Int32Field } from "@opendaw/lib-box";
|
5
|
+
import { ClipBoxAdapter, ClipBoxAdapterVisitor } from "../ClipBoxAdapter";
|
6
|
+
import { TrackBoxAdapter } from "../TrackBoxAdapter";
|
7
|
+
import { BoxAdaptersContext } from "../../BoxAdaptersContext";
|
8
|
+
import { AudioFileBoxAdapter } from "../../AudioFileBoxAdapter";
|
9
|
+
export declare class AudioClipBoxAdapter implements ClipBoxAdapter<never> {
|
10
|
+
#private;
|
11
|
+
readonly type = "audio-clip";
|
12
|
+
constructor(context: BoxAdaptersContext, box: AudioClipBox);
|
13
|
+
catchupAndSubscribeSelected(observer: Observer<ObservableValue<boolean>>): Subscription;
|
14
|
+
subscribeChange(observer: Observer<void>): Subscription;
|
15
|
+
accept<R>(visitor: ClipBoxAdapterVisitor<R>): Nullish<R>;
|
16
|
+
consolidate(): void;
|
17
|
+
clone(_mirrored: boolean): void;
|
18
|
+
onSelected(): void;
|
19
|
+
onDeselected(): void;
|
20
|
+
get isSelected(): boolean;
|
21
|
+
terminate(): void;
|
22
|
+
get box(): AudioClipBox;
|
23
|
+
get uuid(): UUID.Format;
|
24
|
+
get address(): Address;
|
25
|
+
get indexField(): Int32Field;
|
26
|
+
get duration(): ppqn;
|
27
|
+
get mute(): boolean;
|
28
|
+
get hue(): int;
|
29
|
+
get gain(): number;
|
30
|
+
get file(): AudioFileBoxAdapter;
|
31
|
+
get hasCollection(): boolean;
|
32
|
+
get optCollection(): Option<never>;
|
33
|
+
get label(): string;
|
34
|
+
get trackBoxAdapter(): Option<TrackBoxAdapter>;
|
35
|
+
get isMirrowed(): boolean;
|
36
|
+
get canMirror(): boolean;
|
37
|
+
toString(): string;
|
38
|
+
}
|
39
|
+
//# sourceMappingURL=AudioClipBoxAdapter.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"AudioClipBoxAdapter.d.ts","sourceRoot":"","sources":["../../../src/timeline/clip/AudioClipBoxAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAEH,GAAG,EAEH,OAAO,EACP,eAAe,EACf,QAAQ,EACR,MAAM,EAEN,YAAY,EAEZ,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAC,OAAO,EAAE,UAAU,EAAoC,MAAM,kBAAkB,CAAA;AACvF,OAAO,EAAC,cAAc,EAAE,qBAAqB,EAAC,MAAM,mBAAmB,CAAA;AAEvE,OAAO,EAAC,eAAe,EAAC,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAA;AAC3D,OAAO,EAAC,mBAAmB,EAAC,MAAM,2BAA2B,CAAA;AAE7D,qBAAa,mBAAoB,YAAW,cAAc,CAAC,KAAK,CAAC;;IAC7D,QAAQ,CAAC,IAAI,gBAAe;gBAehB,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,YAAY;IA+B1D,2BAA2B,CAAC,QAAQ,EAAE,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,GAAG,YAAY;IAIvF,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,YAAY;IACvD,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAExD,WAAW,IAAI,IAAI;IACnB,KAAK,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAa/B,UAAU,IAAI,IAAI;IAClB,YAAY,IAAI,IAAI;IAEpB,IAAI,UAAU,IAAI,OAAO,CAAwC;IAEjE,SAAS,IAAI,IAAI;IAEjB,IAAI,GAAG,IAAI,YAAY,CAAmB;IAC1C,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,CAAgC;IACvD,IAAI,OAAO,IAAI,OAAO,CAA2B;IACjD,IAAI,UAAU,IAAI,UAAU,CAAyB;IACrD,IAAI,QAAQ,IAAI,IAAI,CAAuC;IAC3D,IAAI,IAAI,IAAI,OAAO,CAAmC;IACtD,IAAI,GAAG,IAAI,GAAG,CAAkC;IAChD,IAAI,IAAI,IAAI,MAAM,CAAmC;IACrD,IAAI,IAAI,IAAI,mBAAmB,CAAyD;IACxF,IAAI,aAAa,YAAyC;IAC1D,IAAI,aAAa,IAAI,MAAM,CAAC,KAAK,CAAC,CAAqB;IACvD,IAAI,KAAK,IAAI,MAAM,CAAoC;IACvD,IAAI,eAAe,IAAI,MAAM,CAAC,eAAe,CAAC,CAI7C;IACD,IAAI,UAAU,IAAI,OAAO,CAAe;IACxC,IAAI,SAAS,IAAI,OAAO,CAAe;IAEvC,QAAQ,IAAI,MAAM;CAMrB"}
|
@@ -0,0 +1,87 @@
|
|
1
|
+
import { PPQN } from "@opendaw/lib-dsp";
|
2
|
+
import { DefaultObservableValue, Notifier, Option, safeExecute, Terminator, UUID } from "@opendaw/lib-std";
|
3
|
+
import { AudioClipBox } from "@opendaw/studio-boxes";
|
4
|
+
import { Propagation } from "@opendaw/lib-box";
|
5
|
+
import { TrackBoxAdapter } from "../TrackBoxAdapter";
|
6
|
+
import { AudioFileBoxAdapter } from "../../AudioFileBoxAdapter";
|
7
|
+
export class AudioClipBoxAdapter {
|
8
|
+
type = "audio-clip";
|
9
|
+
#terminator = new Terminator();
|
10
|
+
#context;
|
11
|
+
#box;
|
12
|
+
#selectedValue;
|
13
|
+
#changeNotifier;
|
14
|
+
#isConstructing; // Prevents stack overflow due to infinite adapter queries
|
15
|
+
#fileAdapter = Option.None;
|
16
|
+
#fileSubscription = Option.None;
|
17
|
+
constructor(context, box) {
|
18
|
+
this.#context = context;
|
19
|
+
this.#box = box;
|
20
|
+
this.#isConstructing = true;
|
21
|
+
this.#selectedValue = this.#terminator.own(new DefaultObservableValue(false));
|
22
|
+
this.#changeNotifier = this.#terminator.own(new Notifier());
|
23
|
+
this.#terminator.ownAll(this.#box.pointerHub.subscribeImmediate({
|
24
|
+
onAdd: () => this.#dispatchChange(),
|
25
|
+
onRemove: () => this.#dispatchChange()
|
26
|
+
}), this.#box.file.catchupAndSubscribe((pointerField) => {
|
27
|
+
this.#fileAdapter = pointerField.targetVertex
|
28
|
+
.map(vertex => this.#context.boxAdapters.adapterFor(vertex.box, AudioFileBoxAdapter));
|
29
|
+
this.#fileSubscription.ifSome(subscription => subscription.terminate());
|
30
|
+
this.#fileSubscription = this.#fileAdapter.map(adapter => adapter.getOrCreateAudioLoader().subscribe(() => this.#dispatchChange()));
|
31
|
+
}), this.#box.subscribe(Propagation.Children, (_update) => this.#dispatchChange()), {
|
32
|
+
terminate: () => {
|
33
|
+
this.#fileSubscription.ifSome(subscription => subscription.terminate());
|
34
|
+
this.#fileSubscription = Option.None;
|
35
|
+
}
|
36
|
+
});
|
37
|
+
this.#isConstructing = false;
|
38
|
+
}
|
39
|
+
catchupAndSubscribeSelected(observer) {
|
40
|
+
return this.#selectedValue.catchupAndSubscribe(observer);
|
41
|
+
}
|
42
|
+
subscribeChange(observer) { return this.#changeNotifier.subscribe(observer); }
|
43
|
+
accept(visitor) { return safeExecute(visitor.visitAudioClipBoxAdapter, this); }
|
44
|
+
consolidate() { }
|
45
|
+
clone(_mirrored) {
|
46
|
+
AudioClipBox.create(this.#context.boxGraph, UUID.generate(), box => {
|
47
|
+
box.index.setValue(this.indexField.getValue());
|
48
|
+
box.gain.setValue(this.gain);
|
49
|
+
box.label.setValue(this.label);
|
50
|
+
box.hue.setValue(this.hue);
|
51
|
+
box.duration.setValue(this.duration);
|
52
|
+
box.mute.setValue(this.mute);
|
53
|
+
box.clips.refer(this.#box.clips.targetVertex.unwrap());
|
54
|
+
box.file.refer(this.#box.file.targetVertex.unwrap());
|
55
|
+
});
|
56
|
+
}
|
57
|
+
onSelected() { this.#selectedValue.setValue(true); }
|
58
|
+
onDeselected() { this.#selectedValue.setValue(false); }
|
59
|
+
get isSelected() { return this.#selectedValue.getValue(); }
|
60
|
+
terminate() { this.#terminator.terminate(); }
|
61
|
+
get box() { return this.#box; }
|
62
|
+
get uuid() { return this.#box.address.uuid; }
|
63
|
+
get address() { return this.#box.address; }
|
64
|
+
get indexField() { return this.#box.index; }
|
65
|
+
get duration() { return this.#box.duration.getValue(); }
|
66
|
+
get mute() { return this.#box.mute.getValue(); }
|
67
|
+
get hue() { return this.#box.hue.getValue(); }
|
68
|
+
get gain() { return this.#box.gain.getValue(); }
|
69
|
+
get file() { return this.#fileAdapter.unwrap("Cannot access file."); }
|
70
|
+
get hasCollection() { return !this.optCollection.isEmpty(); }
|
71
|
+
get optCollection() { return Option.None; }
|
72
|
+
get label() { return this.#box.label.getValue(); }
|
73
|
+
get trackBoxAdapter() {
|
74
|
+
if (this.#isConstructing) {
|
75
|
+
return Option.None;
|
76
|
+
}
|
77
|
+
return this.#box.clips.targetVertex
|
78
|
+
.map(vertex => this.#context.boxAdapters.adapterFor(vertex.box, TrackBoxAdapter));
|
79
|
+
}
|
80
|
+
get isMirrowed() { return false; }
|
81
|
+
get canMirror() { return false; }
|
82
|
+
toString() { return `{AudioClipBoxAdapter ${UUID.toString(this.#box.address.uuid)} d: ${PPQN.toString(this.duration)}}`; }
|
83
|
+
#dispatchChange() {
|
84
|
+
this.#changeNotifier.notify();
|
85
|
+
this.trackBoxAdapter.unwrapOrNull()?.clips?.dispatchChange();
|
86
|
+
}
|
87
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import { int, Nullish, ObservableValue, Observer, Option, Subscription, UUID } from "@opendaw/lib-std";
|
2
|
+
import { EventCollection, ppqn } from "@opendaw/lib-dsp";
|
3
|
+
import { Address, Int32Field } from "@opendaw/lib-box";
|
4
|
+
import { NoteClipBox } from "@opendaw/studio-boxes";
|
5
|
+
import { NoteEventCollectionBoxAdapter } from "../collection/NoteEventCollectionBoxAdapter";
|
6
|
+
import { ClipBoxAdapter, ClipBoxAdapterVisitor } from "../ClipBoxAdapter";
|
7
|
+
import { BoxAdaptersContext } from "../../BoxAdaptersContext";
|
8
|
+
import { NoteEventBoxAdapter } from "../event/NoteEventBoxAdapter";
|
9
|
+
import { TrackBoxAdapter } from "../TrackBoxAdapter";
|
10
|
+
export declare class NoteClipBoxAdapter implements ClipBoxAdapter<NoteEventCollectionBoxAdapter> {
|
11
|
+
#private;
|
12
|
+
readonly type = "note-clip";
|
13
|
+
constructor(context: BoxAdaptersContext, box: NoteClipBox);
|
14
|
+
catchupAndSubscribeSelected(observer: Observer<ObservableValue<boolean>>): Subscription;
|
15
|
+
subscribeChange(observer: Observer<void>): Subscription;
|
16
|
+
accept<R>(visitor: ClipBoxAdapterVisitor<R>): Nullish<R>;
|
17
|
+
consolidate(): void;
|
18
|
+
clone(consolidate: boolean): void;
|
19
|
+
onSelected(): void;
|
20
|
+
onDeselected(): void;
|
21
|
+
get isSelected(): boolean;
|
22
|
+
terminate(): void;
|
23
|
+
get box(): NoteClipBox;
|
24
|
+
get uuid(): UUID.Format;
|
25
|
+
get address(): Address;
|
26
|
+
get indexField(): Int32Field;
|
27
|
+
get duration(): ppqn;
|
28
|
+
get mute(): boolean;
|
29
|
+
get hue(): int;
|
30
|
+
get events(): Option<EventCollection<NoteEventBoxAdapter>>;
|
31
|
+
get hasCollection(): boolean;
|
32
|
+
get optCollection(): Option<NoteEventCollectionBoxAdapter>;
|
33
|
+
get label(): string;
|
34
|
+
get trackBoxAdapter(): Option<TrackBoxAdapter>;
|
35
|
+
get isMirrowed(): boolean;
|
36
|
+
get canMirror(): boolean;
|
37
|
+
toString(): string;
|
38
|
+
}
|
39
|
+
//# sourceMappingURL=NoteClipBoxAdapter.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"NoteClipBoxAdapter.d.ts","sourceRoot":"","sources":["../../../src/timeline/clip/NoteClipBoxAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,GAAG,EAEH,OAAO,EACP,eAAe,EACf,QAAQ,EACR,MAAM,EAEN,YAAY,EAGZ,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,eAAe,EAAE,IAAI,EAAO,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAC,OAAO,EAAE,UAAU,EAAsB,MAAM,kBAAkB,CAAA;AACzE,OAAO,EAAC,WAAW,EAAC,MAAM,uBAAuB,CAAA;AACjD,OAAO,EAAC,6BAA6B,EAAC,MAAM,6CAA6C,CAAA;AACzF,OAAO,EAAC,cAAc,EAAE,qBAAqB,EAAC,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAA;AAC3D,OAAO,EAAC,mBAAmB,EAAC,MAAM,8BAA8B,CAAA;AAChE,OAAO,EAAC,eAAe,EAAC,MAAM,oBAAoB,CAAA;AAElD,qBAAa,kBAAmB,YAAW,cAAc,CAAC,6BAA6B,CAAC;;IACpF,QAAQ,CAAC,IAAI,eAAc;gBAcf,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,WAAW;IA2BzD,2BAA2B,CAAC,QAAQ,EAAE,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,GAAG,YAAY;IAIvF,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,YAAY;IACvD,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAExD,WAAW,IAAI,IAAI;IACnB,KAAK,CAAC,WAAW,EAAE,OAAO,GAAG,IAAI;IAajC,UAAU,IAAI,IAAI;IAClB,YAAY,IAAI,IAAI;IAEpB,IAAI,UAAU,IAAI,OAAO,CAAwC;IAEjE,SAAS,IAAI,IAAI;IAKjB,IAAI,GAAG,IAAI,WAAW,CAAmB;IACzC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,CAAgC;IACvD,IAAI,OAAO,IAAI,OAAO,CAA2B;IACjD,IAAI,UAAU,IAAI,UAAU,CAAyB;IACrD,IAAI,QAAQ,IAAI,IAAI,CAAuC;IAC3D,IAAI,IAAI,IAAI,OAAO,CAAmC;IACtD,IAAI,GAAG,IAAI,GAAG,CAAkC;IAChD,IAAI,MAAM,IAAI,MAAM,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC,CAEzD;IACD,IAAI,aAAa,YAAyC;IAC1D,IAAI,aAAa,IAAI,MAAM,CAAC,6BAA6B,CAAC,CAGzD;IACD,IAAI,KAAK,IAAI,MAAM,CAAoC;IACvD,IAAI,eAAe,IAAI,MAAM,CAAC,eAAe,CAAC,CAI7C;IACD,IAAI,UAAU,IAAI,OAAO,CAA2E;IACpG,IAAI,SAAS,IAAI,OAAO,CAAc;IAEtC,QAAQ,IAAI,MAAM;CAMrB"}
|
@@ -0,0 +1,92 @@
|
|
1
|
+
import { DefaultObservableValue, Notifier, Option, safeExecute, Terminable, Terminator, UUID } from "@opendaw/lib-std";
|
2
|
+
import { PPQN } from "@opendaw/lib-dsp";
|
3
|
+
import { Propagation } from "@opendaw/lib-box";
|
4
|
+
import { NoteClipBox } from "@opendaw/studio-boxes";
|
5
|
+
import { NoteEventCollectionBoxAdapter } from "../collection/NoteEventCollectionBoxAdapter";
|
6
|
+
import { TrackBoxAdapter } from "../TrackBoxAdapter";
|
7
|
+
export class NoteClipBoxAdapter {
|
8
|
+
type = "note-clip";
|
9
|
+
#terminator = new Terminator();
|
10
|
+
#context;
|
11
|
+
#box;
|
12
|
+
#selectedValue;
|
13
|
+
#changeNotifier;
|
14
|
+
#isConstructing; // Prevents stack overflow due to infinite adapter queries
|
15
|
+
#eventCollectionSubscription = Terminable.Empty;
|
16
|
+
constructor(context, box) {
|
17
|
+
this.#context = context;
|
18
|
+
this.#box = box;
|
19
|
+
this.#isConstructing = true;
|
20
|
+
this.#selectedValue = this.#terminator.own(new DefaultObservableValue(false));
|
21
|
+
this.#changeNotifier = this.#terminator.own(new Notifier());
|
22
|
+
this.#terminator.ownAll(this.#box.pointerHub.subscribeImmediate({
|
23
|
+
onAdd: () => this.#dispatchChange(),
|
24
|
+
onRemove: () => this.#dispatchChange()
|
25
|
+
}), this.#box.subscribe(Propagation.Children, (_update) => this.#dispatchChange()), this.#box.events.catchupAndSubscribe(({ targetVertex }) => {
|
26
|
+
this.#eventCollectionSubscription.terminate();
|
27
|
+
this.#eventCollectionSubscription = targetVertex.match({
|
28
|
+
none: () => Terminable.Empty,
|
29
|
+
some: ({ box }) => this.#context.boxAdapters
|
30
|
+
.adapterFor(box, NoteEventCollectionBoxAdapter)
|
31
|
+
.subscribeChange(() => this.#dispatchChange())
|
32
|
+
});
|
33
|
+
this.#dispatchChange();
|
34
|
+
}));
|
35
|
+
this.#isConstructing = false;
|
36
|
+
}
|
37
|
+
catchupAndSubscribeSelected(observer) {
|
38
|
+
return this.#selectedValue.catchupAndSubscribe(observer);
|
39
|
+
}
|
40
|
+
subscribeChange(observer) { return this.#changeNotifier.subscribe(observer); }
|
41
|
+
accept(visitor) { return safeExecute(visitor.visitNoteClipBoxAdapter, this); }
|
42
|
+
consolidate() { this.#box.events.refer(this.optCollection.unwrap().copy().box.owners); }
|
43
|
+
clone(consolidate) {
|
44
|
+
const events = consolidate ? this.optCollection.unwrap().copy().box.owners : this.#box.events.targetVertex.unwrap();
|
45
|
+
NoteClipBox.create(this.#context.boxGraph, UUID.generate(), box => {
|
46
|
+
box.index.setValue(this.indexField.getValue());
|
47
|
+
box.label.setValue(this.label);
|
48
|
+
box.hue.setValue(this.hue);
|
49
|
+
box.duration.setValue(this.duration);
|
50
|
+
box.mute.setValue(this.mute);
|
51
|
+
box.clips.refer(this.#box.clips.targetVertex.unwrap());
|
52
|
+
box.events.refer(events);
|
53
|
+
});
|
54
|
+
}
|
55
|
+
onSelected() { this.#selectedValue.setValue(true); }
|
56
|
+
onDeselected() { this.#selectedValue.setValue(false); }
|
57
|
+
get isSelected() { return this.#selectedValue.getValue(); }
|
58
|
+
terminate() {
|
59
|
+
this.#eventCollectionSubscription.terminate();
|
60
|
+
this.#terminator.terminate();
|
61
|
+
}
|
62
|
+
get box() { return this.#box; }
|
63
|
+
get uuid() { return this.#box.address.uuid; }
|
64
|
+
get address() { return this.#box.address; }
|
65
|
+
get indexField() { return this.#box.index; }
|
66
|
+
get duration() { return this.#box.duration.getValue(); }
|
67
|
+
get mute() { return this.#box.mute.getValue(); }
|
68
|
+
get hue() { return this.#box.hue.getValue(); }
|
69
|
+
get events() {
|
70
|
+
return this.optCollection.map(collection => collection.events);
|
71
|
+
}
|
72
|
+
get hasCollection() { return !this.optCollection.isEmpty(); }
|
73
|
+
get optCollection() {
|
74
|
+
return this.#box.events.targetVertex
|
75
|
+
.map(vertex => this.#context.boxAdapters.adapterFor(vertex.box, NoteEventCollectionBoxAdapter));
|
76
|
+
}
|
77
|
+
get label() { return this.#box.label.getValue(); }
|
78
|
+
get trackBoxAdapter() {
|
79
|
+
if (this.#isConstructing) {
|
80
|
+
return Option.None;
|
81
|
+
}
|
82
|
+
return this.#box.clips.targetVertex
|
83
|
+
.map(vertex => this.#context.boxAdapters.adapterFor(vertex.box, TrackBoxAdapter));
|
84
|
+
}
|
85
|
+
get isMirrowed() { return this.optCollection.mapOr(adapter => adapter.numOwners > 1, false); }
|
86
|
+
get canMirror() { return true; }
|
87
|
+
toString() { return `{NoteClipBoxAdapter ${UUID.toString(this.#box.address.uuid)} d: ${PPQN.toString(this.duration)}}`; }
|
88
|
+
#dispatchChange() {
|
89
|
+
this.#changeNotifier.notify();
|
90
|
+
this.trackBoxAdapter.unwrapOrNull()?.clips?.dispatchChange();
|
91
|
+
}
|
92
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import { EventCollection, ppqn } from "@opendaw/lib-dsp";
|
2
|
+
import { int, Nullish, ObservableValue, Observer, Option, Subscription, unitValue, UUID } from "@opendaw/lib-std";
|
3
|
+
import { Address, Int32Field } from "@opendaw/lib-box";
|
4
|
+
import { ClipBoxAdapter, ClipBoxAdapterVisitor } from "../ClipBoxAdapter";
|
5
|
+
import { TrackBoxAdapter } from "../TrackBoxAdapter";
|
6
|
+
import { ValueEventCollectionBoxAdapter } from "../collection/ValueEventCollectionBoxAdapter";
|
7
|
+
import { BoxAdaptersContext } from "../../BoxAdaptersContext";
|
8
|
+
import { ValueClipBox } from "@opendaw/studio-boxes";
|
9
|
+
import { ValueEventBoxAdapter } from "../event/ValueEventBoxAdapter";
|
10
|
+
export declare class ValueClipBoxAdapter implements ClipBoxAdapter<ValueEventCollectionBoxAdapter> {
|
11
|
+
#private;
|
12
|
+
readonly type = "value-clip";
|
13
|
+
constructor(context: BoxAdaptersContext, box: ValueClipBox);
|
14
|
+
valueAt(position: ppqn, fallback: unitValue): unitValue;
|
15
|
+
catchupAndSubscribeSelected(observer: Observer<ObservableValue<boolean>>): Subscription;
|
16
|
+
subscribeChange(observer: Observer<void>): Subscription;
|
17
|
+
accept<R>(visitor: ClipBoxAdapterVisitor<R>): Nullish<R>;
|
18
|
+
consolidate(): void;
|
19
|
+
clone(consolidate: boolean): void;
|
20
|
+
onSelected(): void;
|
21
|
+
onDeselected(): void;
|
22
|
+
get isSelected(): boolean;
|
23
|
+
terminate(): void;
|
24
|
+
get box(): ValueClipBox;
|
25
|
+
get uuid(): UUID.Format;
|
26
|
+
get address(): Address;
|
27
|
+
get indexField(): Int32Field;
|
28
|
+
get duration(): ppqn;
|
29
|
+
get mute(): boolean;
|
30
|
+
get hue(): int;
|
31
|
+
get hasCollection(): boolean;
|
32
|
+
get events(): Option<EventCollection<ValueEventBoxAdapter>>;
|
33
|
+
get optCollection(): Option<ValueEventCollectionBoxAdapter>;
|
34
|
+
get label(): string;
|
35
|
+
get trackBoxAdapter(): Option<TrackBoxAdapter>;
|
36
|
+
get isMirrowed(): boolean;
|
37
|
+
get canMirror(): boolean;
|
38
|
+
toString(): string;
|
39
|
+
}
|
40
|
+
//# sourceMappingURL=ValueClipBoxAdapter.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ValueClipBoxAdapter.d.ts","sourceRoot":"","sources":["../../../src/timeline/clip/ValueClipBoxAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAE,IAAI,EAAO,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAEH,GAAG,EAEH,OAAO,EACP,eAAe,EACf,QAAQ,EACR,MAAM,EAEN,YAAY,EAGZ,SAAS,EACT,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,OAAO,EAAE,UAAU,EAAsB,MAAM,kBAAkB,CAAA;AACzE,OAAO,EAAC,cAAc,EAAE,qBAAqB,EAAC,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAC,eAAe,EAAC,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAC,8BAA8B,EAAC,MAAM,8CAA8C,CAAA;AAC3F,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAA;AAC3D,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAC,oBAAoB,EAAC,MAAM,+BAA+B,CAAA;AAElE,qBAAa,mBAAoB,YAAW,cAAc,CAAC,8BAA8B,CAAC;;IACtF,QAAQ,CAAC,IAAI,gBAAe;gBAahB,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,YAAY;IA4B1D,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,GAAG,SAAS;IAKvD,2BAA2B,CAAC,QAAQ,EAAE,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,GAAG,YAAY;IAGvF,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,YAAY;IACvD,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAExD,WAAW,IAAI,IAAI;IACnB,KAAK,CAAC,WAAW,EAAE,OAAO,GAAG,IAAI;IAajC,UAAU,IAAI,IAAI;IAClB,YAAY,IAAI,IAAI;IAEpB,IAAI,UAAU,IAAI,OAAO,CAAwC;IAEjE,SAAS,IAAI,IAAI;IAKjB,IAAI,GAAG,IAAI,YAAY,CAAmB;IAC1C,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,CAAgC;IACvD,IAAI,OAAO,IAAI,OAAO,CAA2B;IACjD,IAAI,UAAU,IAAI,UAAU,CAAyB;IACrD,IAAI,QAAQ,IAAI,IAAI,CAAuC;IAC3D,IAAI,IAAI,IAAI,OAAO,CAAmC;IACtD,IAAI,GAAG,IAAI,GAAG,CAAkC;IAChD,IAAI,aAAa,YAAyC;IAC1D,IAAI,MAAM,IAAI,MAAM,CAAC,eAAe,CAAC,oBAAoB,CAAC,CAAC,CAE1D;IACD,IAAI,aAAa,IAAI,MAAM,CAAC,8BAA8B,CAAC,CAG1D;IACD,IAAI,KAAK,IAAI,MAAM,CAAoC;IACvD,IAAI,eAAe,IAAI,MAAM,CAAC,eAAe,CAAC,CAI7C;IACD,IAAI,UAAU,IAAI,OAAO,CAA2E;IACpG,IAAI,SAAS,IAAI,OAAO,CAAc;IAEtC,QAAQ,IAAI,MAAM;CAMrB"}
|