@marmooo/midy 0.0.5 → 0.0.7
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/esm/midy-GM1.d.ts +22 -10
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +126 -73
- package/esm/midy-GM2.d.ts +24 -10
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +145 -82
- package/esm/midy-GMLite.d.ts +16 -8
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +79 -60
- package/esm/midy.d.ts +24 -10
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +145 -111
- package/package.json +1 -1
- package/script/midy-GM1.d.ts +22 -10
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +126 -73
- package/script/midy-GM2.d.ts +24 -10
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +145 -82
- package/script/midy-GMLite.d.ts +16 -8
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +79 -60
- package/script/midy.d.ts +24 -10
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +145 -111
package/script/midy-GMLite.js
CHANGED
|
@@ -186,17 +186,16 @@ class MidyGMLite {
|
|
|
186
186
|
this.totalTime = this.calcTotalTime();
|
|
187
187
|
}
|
|
188
188
|
setChannelAudioNodes(audioContext) {
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
});
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
gainNode.connect(this.masterGain);
|
|
189
|
+
const { gainLeft, gainRight } = this.panToGain(MidyGMLite.channelSettings.pan);
|
|
190
|
+
const gainL = new GainNode(audioContext, { gain: gainLeft });
|
|
191
|
+
const gainR = new GainNode(audioContext, { gain: gainRight });
|
|
192
|
+
const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
|
|
193
|
+
gainL.connect(merger, 0, 0);
|
|
194
|
+
gainR.connect(merger, 0, 1);
|
|
195
|
+
merger.connect(this.masterGain);
|
|
197
196
|
return {
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
gainL,
|
|
198
|
+
gainR,
|
|
200
199
|
};
|
|
201
200
|
}
|
|
202
201
|
createChannels(audioContext) {
|
|
@@ -281,7 +280,7 @@ class MidyGMLite {
|
|
|
281
280
|
this.handleProgramChange(event.channel, event.programNumber);
|
|
282
281
|
break;
|
|
283
282
|
case "pitchBend":
|
|
284
|
-
this.
|
|
283
|
+
this.setPitchBend(event.channel, event.value);
|
|
285
284
|
break;
|
|
286
285
|
case "sysEx":
|
|
287
286
|
this.handleSysEx(event.data);
|
|
@@ -361,7 +360,6 @@ class MidyGMLite {
|
|
|
361
360
|
const tmpChannels = new Array(16);
|
|
362
361
|
for (let i = 0; i < tmpChannels.length; i++) {
|
|
363
362
|
tmpChannels[i] = {
|
|
364
|
-
durationTicks: new Map(),
|
|
365
363
|
programNumber: -1,
|
|
366
364
|
bank: this.channels[i].bank,
|
|
367
365
|
};
|
|
@@ -378,16 +376,6 @@ class MidyGMLite {
|
|
|
378
376
|
instruments.add(`${channel.bank}:0`);
|
|
379
377
|
channel.programNumber = 0;
|
|
380
378
|
}
|
|
381
|
-
channel.durationTicks.set(event.noteNumber, {
|
|
382
|
-
ticks: event.ticks,
|
|
383
|
-
noteOn: event,
|
|
384
|
-
});
|
|
385
|
-
break;
|
|
386
|
-
}
|
|
387
|
-
case "noteOff": {
|
|
388
|
-
const { ticks, noteOn } = tmpChannels[event.channel].durationTicks
|
|
389
|
-
.get(event.noteNumber);
|
|
390
|
-
noteOn.durationTicks = event.ticks - ticks;
|
|
391
379
|
break;
|
|
392
380
|
}
|
|
393
381
|
case "programChange": {
|
|
@@ -401,8 +389,8 @@ class MidyGMLite {
|
|
|
401
389
|
});
|
|
402
390
|
});
|
|
403
391
|
const priority = {
|
|
404
|
-
|
|
405
|
-
|
|
392
|
+
controller: 0,
|
|
393
|
+
sysEx: 1,
|
|
406
394
|
};
|
|
407
395
|
timeline.sort((a, b) => {
|
|
408
396
|
if (a.ticks !== b.ticks)
|
|
@@ -507,7 +495,8 @@ class MidyGMLite {
|
|
|
507
495
|
return noteList[0];
|
|
508
496
|
}
|
|
509
497
|
connectNoteEffects(channel, gainNode) {
|
|
510
|
-
gainNode.connect(channel.
|
|
498
|
+
gainNode.connect(channel.gainL);
|
|
499
|
+
gainNode.connect(channel.gainR);
|
|
511
500
|
}
|
|
512
501
|
cbToRatio(cb) {
|
|
513
502
|
return Math.pow(10, cb / 200);
|
|
@@ -524,9 +513,7 @@ class MidyGMLite {
|
|
|
524
513
|
}
|
|
525
514
|
setVolumeEnvelope(channel, note) {
|
|
526
515
|
const { instrumentKey, startTime, velocity } = note;
|
|
527
|
-
note.gainNode = new GainNode(this.audioContext, {
|
|
528
|
-
gain: 0,
|
|
529
|
-
});
|
|
516
|
+
note.gainNode = new GainNode(this.audioContext, { gain: 0 });
|
|
530
517
|
let volume = (velocity / 127) * channel.volume * channel.expression;
|
|
531
518
|
if (volume === 0)
|
|
532
519
|
volume = 1e-6; // exponentialRampToValueAtTime() requires a non-zero value
|
|
@@ -716,21 +703,15 @@ class MidyGMLite {
|
|
|
716
703
|
}
|
|
717
704
|
handlePitchBendMessage(channelNumber, lsb, msb) {
|
|
718
705
|
const pitchBend = msb * 128 + lsb;
|
|
719
|
-
this.
|
|
706
|
+
this.setPitchBend(channelNumber, pitchBend);
|
|
720
707
|
}
|
|
721
|
-
|
|
722
|
-
const now = this.audioContext.currentTime;
|
|
708
|
+
setPitchBend(channelNumber, pitchBend) {
|
|
723
709
|
const channel = this.channels[channelNumber];
|
|
710
|
+
const prevPitchBend = channel.pitchBend;
|
|
724
711
|
channel.pitchBend = (pitchBend - 8192) / 8192;
|
|
725
|
-
const
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
const { bufferSource, instrumentKey, noteNumber } = activeNote;
|
|
729
|
-
const playbackRate = calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
|
|
730
|
-
bufferSource.playbackRate
|
|
731
|
-
.cancelScheduledValues(now)
|
|
732
|
-
.setValueAtTime(playbackRate * pressure, now);
|
|
733
|
-
});
|
|
712
|
+
const detuneChange = (channel.pitchBend - prevPitchBend) *
|
|
713
|
+
channel.pitchBendRange * 100;
|
|
714
|
+
this.updateDetune(channel, detuneChange);
|
|
734
715
|
}
|
|
735
716
|
handleControlChange(channelNumber, controller, value) {
|
|
736
717
|
switch (controller) {
|
|
@@ -749,9 +730,9 @@ class MidyGMLite {
|
|
|
749
730
|
case 64:
|
|
750
731
|
return this.setSustainPedal(channelNumber, value);
|
|
751
732
|
case 100:
|
|
752
|
-
return this.setRPNMSB(channelNumber, value);
|
|
753
|
-
case 101:
|
|
754
733
|
return this.setRPNLSB(channelNumber, value);
|
|
734
|
+
case 101:
|
|
735
|
+
return this.setRPNMSB(channelNumber, value);
|
|
755
736
|
case 120:
|
|
756
737
|
return this.allSoundOff(channelNumber);
|
|
757
738
|
case 121:
|
|
@@ -783,12 +764,17 @@ class MidyGMLite {
|
|
|
783
764
|
channel.volume = volume / 127;
|
|
784
765
|
this.updateChannelGain(channel);
|
|
785
766
|
}
|
|
767
|
+
panToGain(pan) {
|
|
768
|
+
const theta = Math.PI / 2 * Math.max(0, pan - 1) / 126;
|
|
769
|
+
return {
|
|
770
|
+
gainLeft: Math.cos(theta),
|
|
771
|
+
gainRight: Math.sin(theta),
|
|
772
|
+
};
|
|
773
|
+
}
|
|
786
774
|
setPan(channelNumber, pan) {
|
|
787
|
-
const now = this.audioContext.currentTime;
|
|
788
775
|
const channel = this.channels[channelNumber];
|
|
789
|
-
channel.pan = pan
|
|
790
|
-
|
|
791
|
-
channel.pannerNode.pan.setValueAtTime(channel.pan, now);
|
|
776
|
+
channel.pan = pan;
|
|
777
|
+
this.updateChannelGain(channel);
|
|
792
778
|
}
|
|
793
779
|
setExpression(channelNumber, expression) {
|
|
794
780
|
const channel = this.channels[channelNumber];
|
|
@@ -798,8 +784,13 @@ class MidyGMLite {
|
|
|
798
784
|
updateChannelGain(channel) {
|
|
799
785
|
const now = this.audioContext.currentTime;
|
|
800
786
|
const volume = channel.volume * channel.expression;
|
|
801
|
-
channel.
|
|
802
|
-
channel.
|
|
787
|
+
const { gainLeft, gainRight } = this.panToGain(channel.pan);
|
|
788
|
+
channel.gainL.gain
|
|
789
|
+
.cancelScheduledValues(now)
|
|
790
|
+
.setValueAtTime(volume * gainLeft, now);
|
|
791
|
+
channel.gainR.gain
|
|
792
|
+
.cancelScheduledValues(now)
|
|
793
|
+
.setValueAtTime(volume * gainRight, now);
|
|
803
794
|
}
|
|
804
795
|
setSustainPedal(channelNumber, value) {
|
|
805
796
|
const isOn = value >= 64;
|
|
@@ -808,6 +799,17 @@ class MidyGMLite {
|
|
|
808
799
|
this.releaseSustainPedal(channelNumber, value);
|
|
809
800
|
}
|
|
810
801
|
}
|
|
802
|
+
handleRPN(channelNumber) {
|
|
803
|
+
const channel = this.channels[channelNumber];
|
|
804
|
+
const rpn = channel.rpnMSB * 128 + channel.rpnLSB;
|
|
805
|
+
switch (rpn) {
|
|
806
|
+
case 0:
|
|
807
|
+
this.handlePitchBendRangeMessage(channelNumber);
|
|
808
|
+
break;
|
|
809
|
+
default:
|
|
810
|
+
console.warn(`Channel ${channelNumber}: Unsupported RPN MSB=${channel.rpnMSB} LSB=${channel.rpnLSB}`);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
811
813
|
setRPNMSB(channelNumber, value) {
|
|
812
814
|
this.channels[channelNumber].rpnMSB = value;
|
|
813
815
|
}
|
|
@@ -816,16 +818,33 @@ class MidyGMLite {
|
|
|
816
818
|
}
|
|
817
819
|
setDataEntry(channelNumber, value, isMSB) {
|
|
818
820
|
const channel = this.channels[channelNumber];
|
|
819
|
-
const rpn = channel.rpnMSB * 128 + channel.rpnLSB;
|
|
820
821
|
isMSB ? channel.dataMSB = value : channel.dataLSB = value;
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
822
|
+
this.handleRPN(channelNumber);
|
|
823
|
+
}
|
|
824
|
+
updateDetune(channel, detuneChange) {
|
|
825
|
+
const now = this.audioContext.currentTime;
|
|
826
|
+
const activeNotes = this.getActiveNotes(channel, now);
|
|
827
|
+
activeNotes.forEach((activeNote) => {
|
|
828
|
+
const { bufferSource } = activeNote;
|
|
829
|
+
const detune = bufferSource.detune.value + detuneChange;
|
|
830
|
+
bufferSource.detune
|
|
831
|
+
.cancelScheduledValues(now)
|
|
832
|
+
.setValueAtTime(detune, now);
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
handlePitchBendRangeMessage(channelNumber) {
|
|
836
|
+
const channel = this.channels[channelNumber];
|
|
837
|
+
this.limitData(channel, 0, 127, 0, 99);
|
|
838
|
+
const pitchBendRange = channel.dataMSB + channel.dataLSB / 100;
|
|
839
|
+
this.setPitchBendRange(channelNumber, pitchBendRange);
|
|
840
|
+
}
|
|
841
|
+
setPitchBendRange(channelNumber, pitchBendRange) {
|
|
842
|
+
const channel = this.channels[channelNumber];
|
|
843
|
+
const prevPitchBendRange = channel.pitchBendRange;
|
|
844
|
+
channel.pitchBendRange = pitchBendRange;
|
|
845
|
+
const detuneChange = (channel.pitchBendRange - prevPitchBendRange) *
|
|
846
|
+
channel.pitchBend * 100;
|
|
847
|
+
this.updateDetune(channel, detuneChange);
|
|
829
848
|
}
|
|
830
849
|
allSoundOff(channelNumber) {
|
|
831
850
|
const now = this.audioContext.currentTime;
|
|
@@ -902,9 +921,9 @@ class MidyGMLite {
|
|
|
902
921
|
}
|
|
903
922
|
handleMasterVolumeSysEx(data) {
|
|
904
923
|
const volume = (data[5] * 128 + data[4]) / 16383;
|
|
905
|
-
this.
|
|
924
|
+
this.setMasterVolume(volume);
|
|
906
925
|
}
|
|
907
|
-
|
|
926
|
+
setMasterVolume(volume) {
|
|
908
927
|
if (volume < 0 && 1 < volume) {
|
|
909
928
|
console.error("Master Volume is out of range");
|
|
910
929
|
}
|
|
@@ -946,7 +965,7 @@ Object.defineProperty(MidyGMLite, "channelSettings", {
|
|
|
946
965
|
writable: true,
|
|
947
966
|
value: {
|
|
948
967
|
volume: 100 / 127,
|
|
949
|
-
pan:
|
|
968
|
+
pan: 64,
|
|
950
969
|
bank: 0,
|
|
951
970
|
dataMSB: 0,
|
|
952
971
|
dataLSB: 0,
|
package/script/midy.d.ts
CHANGED
|
@@ -84,8 +84,8 @@ export class Midy {
|
|
|
84
84
|
lfoFilterDepth: number;
|
|
85
85
|
lfoAmplitudeDepth: number;
|
|
86
86
|
};
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
gainL: any;
|
|
88
|
+
gainR: any;
|
|
89
89
|
reverbEffect: {
|
|
90
90
|
convolverNode: any;
|
|
91
91
|
dryGain: any;
|
|
@@ -131,8 +131,8 @@ export class Midy {
|
|
|
131
131
|
loadSoundFont(soundFontUrl: any): Promise<void>;
|
|
132
132
|
loadMIDI(midiUrl: any): Promise<void>;
|
|
133
133
|
setChannelAudioNodes(audioContext: any): {
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
gainL: any;
|
|
135
|
+
gainR: any;
|
|
136
136
|
reverbEffect: {
|
|
137
137
|
convolverNode: any;
|
|
138
138
|
dryGain: any;
|
|
@@ -164,8 +164,8 @@ export class Midy {
|
|
|
164
164
|
lfoFilterDepth: number;
|
|
165
165
|
lfoAmplitudeDepth: number;
|
|
166
166
|
};
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
gainL: any;
|
|
168
|
+
gainR: any;
|
|
169
169
|
reverbEffect: {
|
|
170
170
|
convolverNode: any;
|
|
171
171
|
dryGain: any;
|
|
@@ -261,12 +261,16 @@ export class Midy {
|
|
|
261
261
|
handleProgramChange(channelNumber: any, program: any): void;
|
|
262
262
|
handleChannelPressure(channelNumber: any, pressure: any): void;
|
|
263
263
|
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
264
|
-
|
|
264
|
+
setPitchBend(channelNumber: any, pitchBend: any): void;
|
|
265
265
|
handleControlChange(channelNumber: any, controller: any, value: any): any;
|
|
266
266
|
setBankMSB(channelNumber: any, msb: any): void;
|
|
267
267
|
setModulation(channelNumber: any, modulation: any): void;
|
|
268
268
|
setPortamentoTime(channelNumber: any, portamentoTime: any): void;
|
|
269
269
|
setVolume(channelNumber: any, volume: any): void;
|
|
270
|
+
panToGain(pan: any): {
|
|
271
|
+
gainLeft: number;
|
|
272
|
+
gainRight: number;
|
|
273
|
+
};
|
|
270
274
|
setPan(channelNumber: any, pan: any): void;
|
|
271
275
|
setExpression(channelNumber: any, expression: any): void;
|
|
272
276
|
setBankLSB(channelNumber: any, lsb: any): void;
|
|
@@ -280,11 +284,21 @@ export class Midy {
|
|
|
280
284
|
setVibratoRate(channelNumber: any, vibratoRate: any): void;
|
|
281
285
|
setVibratoDepth(channelNumber: any, vibratoDepth: any): void;
|
|
282
286
|
setVibratoDelay(channelNumber: any, vibratoDelay: any): void;
|
|
287
|
+
limitData(channel: any, minMSB: any, maxMSB: any, minLSB: any, maxLSB: any): void;
|
|
288
|
+
limitDataMSB(channel: any, minMSB: any, maxMSB: any): void;
|
|
289
|
+
handleRPN(channelNumber: any, value: any): void;
|
|
283
290
|
incrementRPNValue(channelNumber: any): void;
|
|
284
291
|
decrementRPNValue(channelNumber: any): void;
|
|
285
292
|
setRPNMSB(channelNumber: any, value: any): void;
|
|
286
293
|
setRPNLSB(channelNumber: any, value: any): void;
|
|
287
294
|
setDataEntry(channelNumber: any, value: any, isMSB: any): void;
|
|
295
|
+
updateDetune(channel: any, detuneChange: any): void;
|
|
296
|
+
handlePitchBendRangeMessage(channelNumber: any): void;
|
|
297
|
+
setPitchBendRange(channelNumber: any, pitchBendRange: any): void;
|
|
298
|
+
handleFineTuningMessage(channelNumber: any): void;
|
|
299
|
+
setFineTuning(channelNumber: any, fineTuning: any): void;
|
|
300
|
+
handleCoarseTuningMessage(channelNumber: any): void;
|
|
301
|
+
setCoarseTuning(channelNumber: any, coarseTuning: any): void;
|
|
288
302
|
allSoundOff(channelNumber: any): any[];
|
|
289
303
|
resetAllControllers(channelNumber: any): void;
|
|
290
304
|
allNotesOff(channelNumber: any): any[];
|
|
@@ -297,11 +311,11 @@ export class Midy {
|
|
|
297
311
|
GM2SystemOn(): void;
|
|
298
312
|
handleUniversalRealTimeExclusiveMessage(data: any): void;
|
|
299
313
|
handleMasterVolumeSysEx(data: any): void;
|
|
300
|
-
|
|
314
|
+
setMasterVolume(volume: any): void;
|
|
301
315
|
handleMasterFineTuningSysEx(data: any): void;
|
|
302
|
-
|
|
316
|
+
setMasterFineTuning(fineTuning: any): void;
|
|
303
317
|
handleMasterCoarseTuningSysEx(data: any): void;
|
|
304
|
-
|
|
318
|
+
setMasterCoarseTuning(coarseTuning: any): void;
|
|
305
319
|
handleExclusiveMessage(data: any): void;
|
|
306
320
|
handleSysEx(data: any): void;
|
|
307
321
|
scheduleTask(callback: any, startTime: any): Promise<any>;
|
package/script/midy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAuBA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAzED,qBAAmB;IACnB,kBAAc;IACd,qBAAmB;IACnB,yBAAqB;IACrB,2BAAuB;IACvB,cAAa;IACb,cAAa;IACb,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IA+ChB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAuBA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAzED,qBAAmB;IACnB,kBAAc;IACd,qBAAmB;IACnB,yBAAqB;IACrB,2BAAuB;IACvB,cAAa;IACb,cAAa;IACb,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IA+ChB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;MAqBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAiBC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EAyDC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgGC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED;;;;MAoCC;IAED;;;;;MAqCC;IAED,sDA6BC;IAED,2BAEC;IAED,4BAEC;IAED,sCAKC;IAED,mFAGC;IAED,iDAiBC;IAED,iDAiCC;IAED,0DAmBC;IAED,uDAcC;IAED,wHAqCC;IAED,gDAQC;IAED,kGAgCC;IAED,0EAGC;IAED,sIAwDC;IAED,0FAGC;IAED,kEAeC;IAED,oEAYC;IAED,gEAqBC;IAED,sFAcC;IAED,4DAIC;IAED,+DAcC;IAED,qEAGC;IAED,uDAOC;IAED,0EAkEC;IAED,+CAEC;IAED,yDAiBC;IAED,iEAEC;IAED,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,+CAEC;IAED,sCAUC;IAED,sDAMC;IAED,oDAEC;IAED,iDASC;IAED,iDAIC;IAED,wDAWC;IAED,uDAGC;IAED,2DAGC;IAED,6DAGC;IAED,6DASC;IAED,kFAeC;IAED,2DAMC;IAGD,gDAqBC;IAED,4CAEC;IAED,4CAEC;IAED,gDAEC;IAED,gDAEC;IAED,+DAIC;IAED,oDAUC;IAED,sDAKC;IAED,iEAOC;IAED,kDAKC;IAED,yDAGC;IAED,oDAKC;IAED,6DAGC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,gBAEC;IAED,eAEC;IAED,eAEC;IAED,eAEC;IAED,4DAmBC;IAED,oBAQC;IAED,oBAQC;IAED,yDAgDC;IAED,yCAGC;IAED,mCAQC;IAED,6CAGC;IAED,2CAMC;IAED,+CAGC;IAED,+CAMC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AA1hDD;IASE,gFAKC;IAbD,kBAAa;IACb,cAAS;IACT,gBAAW;IACX,YAAO;IACP,gBAAW;IACX,YAAO;IACP,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
|