@marmooo/midy 0.2.9 → 0.3.0

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.
@@ -103,6 +103,19 @@ class Note {
103
103
  this.voiceParams = voiceParams;
104
104
  }
105
105
  }
106
+ const drumExclusiveClasses = new Uint8Array(128);
107
+ drumExclusiveClasses[42] = 1;
108
+ drumExclusiveClasses[44] = 1;
109
+ drumExclusiveClasses[46] = 1, // HH
110
+ drumExclusiveClasses[71] = 2;
111
+ drumExclusiveClasses[72] = 2; // Whistle
112
+ drumExclusiveClasses[73] = 3;
113
+ drumExclusiveClasses[74] = 3; // Guiro
114
+ drumExclusiveClasses[78] = 4;
115
+ drumExclusiveClasses[79] = 4; // Cuica
116
+ drumExclusiveClasses[80] = 5;
117
+ drumExclusiveClasses[81] = 5; // Triangle
118
+ const drumExclusiveClassCount = 5;
106
119
  // normalized to 0-1 for use with the SF2 modulator model
107
120
  const defaultControllerState = {
108
121
  noteOnVelocity: { type: 2, defaultValue: 0 },
@@ -176,6 +189,12 @@ export class MidyGMLite {
176
189
  writable: true,
177
190
  value: "GM1"
178
191
  });
192
+ Object.defineProperty(this, "numChannels", {
193
+ enumerable: true,
194
+ configurable: true,
195
+ writable: true,
196
+ value: 16
197
+ });
179
198
  Object.defineProperty(this, "ticksPerBeat", {
180
199
  enumerable: true,
181
200
  configurable: true,
@@ -290,11 +309,17 @@ export class MidyGMLite {
290
309
  writable: true,
291
310
  value: []
292
311
  });
293
- Object.defineProperty(this, "exclusiveClassMap", {
312
+ Object.defineProperty(this, "exclusiveClassNotes", {
313
+ enumerable: true,
314
+ configurable: true,
315
+ writable: true,
316
+ value: new Array(128)
317
+ });
318
+ Object.defineProperty(this, "drumExclusiveClassNotes", {
294
319
  enumerable: true,
295
320
  configurable: true,
296
321
  writable: true,
297
- value: new SparseMap(128)
322
+ value: new Array(this.numChannels * drumExclusiveClassCount)
298
323
  });
299
324
  this.audioContext = audioContext;
300
325
  this.masterVolume = new GainNode(audioContext);
@@ -361,8 +386,10 @@ export class MidyGMLite {
361
386
  };
362
387
  }
363
388
  createChannels(audioContext) {
364
- const channels = Array.from({ length: 16 }, () => {
389
+ const channels = Array.from({ length: this.numChannels }, () => {
365
390
  return {
391
+ currentBufferSource: null,
392
+ isDrum: false,
366
393
  ...this.constructor.channelSettings,
367
394
  state: new ControllerState(),
368
395
  ...this.setChannelAudioNodes(audioContext),
@@ -401,18 +428,10 @@ export class MidyGMLite {
401
428
  return audioBuffer;
402
429
  }
403
430
  }
404
- calcLoopMode(channel, voiceParams) {
405
- if (channel.isDrum) {
406
- return false;
407
- }
408
- else {
409
- return voiceParams.sampleModes % 2 !== 0;
410
- }
411
- }
412
- createBufferSource(channel, voiceParams, audioBuffer) {
431
+ createBufferSource(voiceParams, audioBuffer) {
413
432
  const bufferSource = new AudioBufferSourceNode(this.audioContext);
414
433
  bufferSource.buffer = audioBuffer;
415
- bufferSource.loop = this.calcLoopMode(channel, voiceParams);
434
+ bufferSource.loop = voiceParams.sampleModes % 2 !== 0;
416
435
  if (bufferSource.loop) {
417
436
  bufferSource.loopStart = voiceParams.loopStart / voiceParams.sampleRate;
418
437
  bufferSource.loopEnd = voiceParams.loopEnd / voiceParams.sampleRate;
@@ -475,7 +494,7 @@ export class MidyGMLite {
475
494
  if (queueIndex >= this.timeline.length) {
476
495
  await Promise.all(this.notePromises);
477
496
  this.notePromises = [];
478
- this.exclusiveClassMap.clear();
497
+ this.exclusiveClassNotes.flll(undefined);
479
498
  this.audioBufferCache.clear();
480
499
  resolve();
481
500
  return;
@@ -494,7 +513,7 @@ export class MidyGMLite {
494
513
  else if (this.isStopping) {
495
514
  await this.stopNotes(0, true, now);
496
515
  this.notePromises = [];
497
- this.exclusiveClassMap.clear();
516
+ this.exclusiveClassNotes.fill(undefined);
498
517
  this.audioBufferCache.clear();
499
518
  resolve();
500
519
  this.isStopping = false;
@@ -503,7 +522,7 @@ export class MidyGMLite {
503
522
  }
504
523
  else if (this.isSeeking) {
505
524
  this.stopNotes(0, true, now);
506
- this.exclusiveClassMap.clear();
525
+ this.exclusiveClassNotes.fill(undefined);
507
526
  this.startTime = this.audioContext.currentTime;
508
527
  queueIndex = this.getQueueIndex(this.resumeTime);
509
528
  offset = this.resumeTime - this.startTime;
@@ -531,7 +550,7 @@ export class MidyGMLite {
531
550
  extractMidiData(midi) {
532
551
  const instruments = new Set();
533
552
  const timeline = [];
534
- const tmpChannels = new Array(16);
553
+ const tmpChannels = new Array(this.channels.length);
535
554
  for (let i = 0; i < tmpChannels.length; i++) {
536
555
  tmpChannels[i] = {
537
556
  programNumber: -1,
@@ -623,6 +642,9 @@ export class MidyGMLite {
623
642
  if (!this.isPlaying)
624
643
  return;
625
644
  this.isStopping = true;
645
+ for (let i = 0; i < this.channels.length; i++) {
646
+ this.resetAllStates(i);
647
+ }
626
648
  }
627
649
  pause() {
628
650
  if (!this.isPlaying || this.isPaused)
@@ -798,8 +820,8 @@ export class MidyGMLite {
798
820
  note.modulationLFO.connect(note.volumeDepth);
799
821
  note.volumeDepth.connect(note.volumeEnvelopeNode.gain);
800
822
  }
801
- async getAudioBuffer(program, noteNumber, velocity, voiceParams, isSF3) {
802
- const audioBufferId = this.getAudioBufferId(program, noteNumber, velocity);
823
+ async getAudioBuffer(programNumber, noteNumber, velocity, voiceParams, isSF3) {
824
+ const audioBufferId = this.getAudioBufferId(programNumber, noteNumber, velocity);
803
825
  const cache = this.audioBufferCache.get(audioBufferId);
804
826
  if (cache) {
805
827
  cache.counter += 1;
@@ -822,8 +844,8 @@ export class MidyGMLite {
822
844
  const controllerState = this.getControllerState(channel, noteNumber, velocity);
823
845
  const voiceParams = voice.getAllParams(controllerState);
824
846
  const note = new Note(noteNumber, velocity, startTime, voice, voiceParams);
825
- const audioBuffer = await this.getAudioBuffer(channel.program, noteNumber, velocity, voiceParams, isSF3);
826
- note.bufferSource = this.createBufferSource(channel, voiceParams, audioBuffer);
847
+ const audioBuffer = await this.getAudioBuffer(channel.programNumber, noteNumber, velocity, voiceParams, isSF3);
848
+ note.bufferSource = this.createBufferSource(voiceParams, audioBuffer);
827
849
  note.volumeEnvelopeNode = new GainNode(this.audioContext);
828
850
  note.filterNode = new BiquadFilterNode(this.audioContext, {
829
851
  type: "lowpass",
@@ -840,14 +862,43 @@ export class MidyGMLite {
840
862
  note.bufferSource.start(startTime);
841
863
  return note;
842
864
  }
865
+ handleExclusiveClass(note, channelNumber, startTime) {
866
+ const exclusiveClass = note.voiceParams.exclusiveClass;
867
+ if (exclusiveClass === 0)
868
+ return;
869
+ const prev = this.exclusiveClassNotes[exclusiveClass];
870
+ if (prev) {
871
+ const [prevNote, prevChannelNumber] = prev;
872
+ if (prevNote && !prevNote.ending) {
873
+ this.scheduleNoteOff(prevChannelNumber, prevNote.noteNumber, 0, // velocity,
874
+ startTime, true);
875
+ }
876
+ }
877
+ this.exclusiveClassNotes[exclusiveClass] = [note, channelNumber];
878
+ }
879
+ handleDrumExclusiveClass(note, channelNumber, startTime) {
880
+ const channel = this.channels[channelNumber];
881
+ if (!channel.isDrum)
882
+ return;
883
+ const drumExclusiveClass = drumExclusiveClasses[noteNumber];
884
+ if (drumExclusiveClass === 0)
885
+ return;
886
+ const index = drumExclusiveClass * this.channels.length + channelNumber;
887
+ const prevNote = this.drumExclusiveClassNotes[index];
888
+ if (prevNote && !prevNote.ending) {
889
+ this.scheduleNoteOff(channelNumber, prevNote.noteNumber, 0, // velocity,
890
+ startTime, true);
891
+ }
892
+ this.drumExclusiveClassNotes[index] = note;
893
+ }
843
894
  async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime) {
844
895
  const channel = this.channels[channelNumber];
845
896
  const bankNumber = channel.bank;
846
- const soundFontIndex = this.soundFontTable[channel.program].get(bankNumber);
897
+ const soundFontIndex = this.soundFontTable[channel.programNumber].get(bankNumber);
847
898
  if (soundFontIndex === undefined)
848
899
  return;
849
900
  const soundFont = this.soundFonts[soundFontIndex];
850
- const voice = soundFont.getVoice(bankNumber, channel.program, noteNumber, velocity);
901
+ const voice = soundFont.getVoice(bankNumber, channel.programNumber, noteNumber, velocity);
851
902
  if (!voice)
852
903
  return;
853
904
  const isSF3 = soundFont.parsed.info.version.major === 3;
@@ -857,30 +908,45 @@ export class MidyGMLite {
857
908
  if (0.5 <= channel.state.sustainPedal) {
858
909
  channel.sustainNotes.push(note);
859
910
  }
860
- const exclusiveClass = note.voiceParams.exclusiveClass;
861
- if (exclusiveClass !== 0) {
862
- if (this.exclusiveClassMap.has(exclusiveClass)) {
863
- const prevEntry = this.exclusiveClassMap.get(exclusiveClass);
864
- const [prevNote, prevChannelNumber] = prevEntry;
865
- if (prevNote && !prevNote.ending) {
866
- this.scheduleNoteOff(prevChannelNumber, prevNote.noteNumber, 0, // velocity,
867
- startTime, true);
868
- }
869
- }
870
- this.exclusiveClassMap.set(exclusiveClass, [note, channelNumber]);
871
- }
911
+ this.handleExclusiveClass(note, channelNumber, startTime);
912
+ this.handleDrumExclusiveClass(note, channelNumber, startTime);
872
913
  const scheduledNotes = channel.scheduledNotes;
873
- if (scheduledNotes.has(noteNumber)) {
874
- scheduledNotes.get(noteNumber).push(note);
914
+ let notes = scheduledNotes.get(noteNumber);
915
+ if (notes) {
916
+ notes.push(note);
875
917
  }
876
918
  else {
877
- scheduledNotes.set(noteNumber, [note]);
919
+ notes = [note];
920
+ scheduledNotes.set(noteNumber, notes);
921
+ }
922
+ if (this.isDrumNoteOffException(channel, noteNumber)) {
923
+ const stopTime = startTime + note.bufferSource.buffer.duration;
924
+ const index = notes.length - 1;
925
+ const promise = new Promise((resolve) => {
926
+ note.bufferSource.onended = () => {
927
+ this.disconnectNote(note, scheduledNotes, index);
928
+ resolve();
929
+ };
930
+ note.bufferSource.stop(stopTime);
931
+ });
932
+ this.notePromises.push(promise);
878
933
  }
879
934
  }
880
935
  noteOn(channelNumber, noteNumber, velocity, scheduleTime) {
881
936
  scheduleTime ??= this.audioContext.currentTime;
882
937
  return this.scheduleNoteOn(channelNumber, noteNumber, velocity, scheduleTime);
883
938
  }
939
+ disconnectNote(note, scheduledNotes, index) {
940
+ scheduledNotes[index] = null;
941
+ note.bufferSource.disconnect();
942
+ note.filterNode.disconnect();
943
+ note.volumeEnvelopeNode.disconnect();
944
+ if (note.modulationDepth) {
945
+ note.volumeDepth.disconnect();
946
+ note.modulationDepth.disconnect();
947
+ note.modulationLFO.stop();
948
+ }
949
+ }
884
950
  stopNote(endTime, stopTime, scheduledNotes, index) {
885
951
  const note = scheduledNotes[index];
886
952
  note.volumeEnvelopeNode.gain
@@ -892,15 +958,7 @@ export class MidyGMLite {
892
958
  }, stopTime);
893
959
  return new Promise((resolve) => {
894
960
  note.bufferSource.onended = () => {
895
- scheduledNotes[index] = null;
896
- note.bufferSource.disconnect();
897
- note.filterNode.disconnect();
898
- note.volumeEnvelopeNode.disconnect();
899
- if (note.modulationDepth) {
900
- note.volumeDepth.disconnect();
901
- note.modulationDepth.disconnect();
902
- note.modulationLFO.stop();
903
- }
961
+ this.disconnectNote(note, scheduledNotes, index);
904
962
  resolve();
905
963
  };
906
964
  note.bufferSource.stop(stopTime);
@@ -908,6 +966,8 @@ export class MidyGMLite {
908
966
  }
909
967
  scheduleNoteOff(channelNumber, noteNumber, _velocity, endTime, force) {
910
968
  const channel = this.channels[channelNumber];
969
+ if (channel.isDrum)
970
+ return;
911
971
  if (!force && 0.5 <= channel.state.sustainPedal)
912
972
  return;
913
973
  if (!channel.scheduledNotes.has(noteNumber))
@@ -961,9 +1021,9 @@ export class MidyGMLite {
961
1021
  console.warn(`Unsupported MIDI message: ${messageType.toString(16)}`);
962
1022
  }
963
1023
  }
964
- handleProgramChange(channelNumber, program, _scheduleTime) {
1024
+ handleProgramChange(channelNumber, programNumber, _scheduleTime) {
965
1025
  const channel = this.channels[channelNumber];
966
- channel.program = program;
1026
+ channel.programNumber = programNumber;
967
1027
  }
968
1028
  handlePitchBendMessage(channelNumber, lsb, msb, scheduleTime) {
969
1029
  const pitchBend = msb * 128 + lsb;
@@ -971,8 +1031,6 @@ export class MidyGMLite {
971
1031
  }
972
1032
  setPitchBend(channelNumber, value, scheduleTime) {
973
1033
  const channel = this.channels[channelNumber];
974
- if (channel.isDrum)
975
- return;
976
1034
  scheduleTime ??= this.audioContext.currentTime;
977
1035
  const state = channel.state;
978
1036
  const prev = state.pitchWheel * 2 - 1;
@@ -1135,8 +1193,6 @@ export class MidyGMLite {
1135
1193
  }
1136
1194
  setModulationDepth(channelNumber, modulation, scheduleTime) {
1137
1195
  const channel = this.channels[channelNumber];
1138
- if (channel.isDrum)
1139
- return;
1140
1196
  scheduleTime ??= this.audioContext.currentTime;
1141
1197
  channel.state.modulationDepth = modulation / 127;
1142
1198
  this.updateModulation(channel, scheduleTime);
@@ -1183,8 +1239,6 @@ export class MidyGMLite {
1183
1239
  }
1184
1240
  setSustainPedal(channelNumber, value, scheduleTime) {
1185
1241
  const channel = this.channels[channelNumber];
1186
- if (channel.isDrum)
1187
- return;
1188
1242
  scheduleTime ??= this.audioContext.currentTime;
1189
1243
  channel.state.sustainPedal = value / 127;
1190
1244
  if (64 <= value) {
@@ -1243,8 +1297,6 @@ export class MidyGMLite {
1243
1297
  }
1244
1298
  setPitchBendRange(channelNumber, value, scheduleTime) {
1245
1299
  const channel = this.channels[channelNumber];
1246
- if (channel.isDrum)
1247
- return;
1248
1300
  scheduleTime ??= this.audioContext.currentTime;
1249
1301
  const state = channel.state;
1250
1302
  const prev = state.pitchWheelSensitivity;
@@ -1258,12 +1310,24 @@ export class MidyGMLite {
1258
1310
  scheduleTime ??= this.audioContext.currentTime;
1259
1311
  return this.stopChannelNotes(channelNumber, 0, true, scheduleTime);
1260
1312
  }
1313
+ resetAllStates(channelNumber) {
1314
+ const channel = this.channels[channelNumber];
1315
+ const state = channel.state;
1316
+ for (const type of Object.keys(defaultControllerState)) {
1317
+ state[type] = defaultControllerState[type].defaultValue;
1318
+ }
1319
+ for (const type of Object.keys(this.constructor.channelSettings)) {
1320
+ channel[type] = this.constructor.channelSettings[type];
1321
+ }
1322
+ this.mode = "GM1";
1323
+ }
1324
+ // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/rp15.pdf
1261
1325
  resetAllControllers(channelNumber) {
1262
1326
  const stateTypes = [
1327
+ "pitchWheel",
1263
1328
  "expression",
1264
1329
  "modulationDepth",
1265
1330
  "sustainPedal",
1266
- "pitchWheelSensitivity",
1267
1331
  ];
1268
1332
  const channel = this.channels[channelNumber];
1269
1333
  const state = channel.state;
@@ -1352,6 +1416,7 @@ export class MidyGMLite {
1352
1416
  console.warn(`Unsupported Exclusive Message: ${data}`);
1353
1417
  }
1354
1418
  }
1419
+ // https://github.com/marmooo/js-timer-benchmark
1355
1420
  scheduleTask(callback, scheduleTime) {
1356
1421
  return new Promise((resolve) => {
1357
1422
  const bufferSource = new AudioBufferSourceNode(this.audioContext, {
@@ -1376,10 +1441,8 @@ Object.defineProperty(MidyGMLite, "channelSettings", {
1376
1441
  configurable: true,
1377
1442
  writable: true,
1378
1443
  value: {
1379
- currentBufferSource: null,
1380
- isDrum: false,
1381
1444
  detune: 0,
1382
- program: 0,
1445
+ programNumber: 0,
1383
1446
  bank: 0,
1384
1447
  dataMSB: 0,
1385
1448
  dataLSB: 0,
package/esm/midy.d.ts CHANGED
@@ -1,9 +1,7 @@
1
1
  export class Midy {
2
2
  static channelSettings: {
3
- currentBufferSource: null;
4
- isDrum: boolean;
5
3
  detune: number;
6
- program: number;
4
+ programNumber: number;
7
5
  bank: number;
8
6
  bankMSB: number;
9
7
  bankLSB: number;
@@ -23,8 +21,6 @@ export class Midy {
23
21
  };
24
22
  });
25
23
  mode: string;
26
- ticksPerBeat: number;
27
- totalTime: number;
28
24
  masterFineTuning: number;
29
25
  masterCoarseTuning: number;
30
26
  reverb: {
@@ -38,6 +34,9 @@ export class Midy {
38
34
  sendToReverb: number;
39
35
  delayTimes: any[];
40
36
  };
37
+ numChannels: number;
38
+ ticksPerBeat: number;
39
+ totalTime: number;
41
40
  noteCheckInterval: number;
42
41
  lookAhead: number;
43
42
  startDelay: number;
@@ -55,7 +54,8 @@ export class Midy {
55
54
  timeline: any[];
56
55
  instruments: any[];
57
56
  notePromises: any[];
58
- exclusiveClassMap: SparseMap;
57
+ exclusiveClassNotes: any[];
58
+ drumExclusiveClassNotes: any[];
59
59
  defaultOptions: {
60
60
  reverbAlgorithm: (audioContext: any) => {
61
61
  input: any;
@@ -145,8 +145,7 @@ export class Midy {
145
145
  };
146
146
  createChannels(audioContext: any): any[];
147
147
  createNoteBuffer(voiceParams: any, isSF3: any): Promise<any>;
148
- calcLoopMode(channel: any, note: any, voiceParams: any): boolean;
149
- createBufferSource(channel: any, note: any, voiceParams: any, audioBuffer: any): any;
148
+ createBufferSource(voiceParams: any, audioBuffer: any): any;
150
149
  findPortamentoTarget(queueIndex: any): any;
151
150
  scheduleTimelineEvents(t: any, offset: any, queueIndex: any): Promise<any>;
152
151
  getQueueIndex(second: any): number;
@@ -209,11 +208,15 @@ export class Midy {
209
208
  setFilterEnvelope(channel: any, note: any, scheduleTime: any): void;
210
209
  startModulation(channel: any, note: any, scheduleTime: any): void;
211
210
  startVibrato(channel: any, note: any, scheduleTime: any): void;
212
- getAudioBuffer(program: any, noteNumber: any, velocity: any, voiceParams: any, isSF3: any): Promise<any>;
211
+ getAudioBuffer(programNumber: any, noteNumber: any, velocity: any, voiceParams: any, isSF3: any): Promise<any>;
213
212
  createNote(channel: any, voice: any, noteNumber: any, velocity: any, startTime: any, portamento: any, isSF3: any): Promise<Note>;
214
213
  calcBank(channel: any): any;
214
+ handleExclusiveClass(note: any, channelNumber: any, startTime: any): void;
215
+ handleDrumExclusiveClass(note: any, channelNumber: any, startTime: any): void;
216
+ isDrumNoteOffException(channel: any, noteNumber: any): boolean;
215
217
  scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any, portamento: any): Promise<void>;
216
218
  noteOn(channelNumber: any, noteNumber: any, velocity: any, scheduleTime: any): Promise<void>;
219
+ disconnectNote(note: any, scheduledNotes: any, index: any): void;
217
220
  stopNote(endTime: any, stopTime: any, scheduledNotes: any, index: any): Promise<any>;
218
221
  scheduleNoteOff(channelNumber: any, noteNumber: any, _velocity: any, endTime: any, force: any, portamentoNoteNumber: any): Promise<any> | undefined;
219
222
  noteOff(channelNumber: any, noteNumber: any, velocity: any, scheduleTime: any): Promise<any> | undefined;
@@ -221,7 +224,7 @@ export class Midy {
221
224
  releaseSostenutoPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): any[];
222
225
  handleMIDIMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): void | Promise<any>;
223
226
  handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any, scheduleTime: any): void;
224
- handleProgramChange(channelNumber: any, program: any, _scheduleTime: any): void;
227
+ handleProgramChange(channelNumber: any, programNumber: any, _scheduleTime: any): void;
225
228
  handleChannelPressure(channelNumber: any, value: any, scheduleTime: any): void;
226
229
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any, scheduleTime: any): void;
227
230
  setPitchBend(channelNumber: any, value: any, scheduleTime: any): void;
@@ -332,6 +335,7 @@ export class Midy {
332
335
  handleModulationDepthRangeRPN(channelNumber: any, scheduleTime: any): void;
333
336
  setModulationDepthRange(channelNumber: any, modulationDepthRange: any, scheduleTime: any): void;
334
337
  allSoundOff(channelNumber: any, _value: any, scheduleTime: any): Promise<any[]>;
338
+ resetAllStates(channelNumber: any): void;
335
339
  resetAllControllers(channelNumber: any): void;
336
340
  allNotesOff(channelNumber: any, _value: any, scheduleTime: any): Promise<any[]>;
337
341
  omniOff(channelNumber: any, value: any, scheduleTime: any): void;
package/esm/midy.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}