pxt-core 8.4.2 → 8.4.3

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 (77) hide show
  1. package/built/backendutils.js +1 -0
  2. package/built/cli.js +83 -75
  3. package/built/pxt.js +1264 -176
  4. package/built/pxtblockly.js +323 -40
  5. package/built/pxtblocks.d.ts +30 -7
  6. package/built/pxtblocks.js +324 -41
  7. package/built/pxtlib.d.ts +91 -5
  8. package/built/pxtlib.js +1173 -98
  9. package/built/pxtsim.js +8 -3
  10. package/built/server.js +4 -0
  11. package/built/target.js +1 -1
  12. package/built/web/main.js +1 -1
  13. package/built/web/multiplayer/css/main.2dd69ed8.css +4 -0
  14. package/built/web/multiplayer/js/main.f3b8f930.js +2 -0
  15. package/built/web/pxtapp.js +1 -1
  16. package/built/web/pxtasseteditor.js +1 -1
  17. package/built/web/pxtblockly.js +1 -1
  18. package/built/web/pxtblocks.js +1 -1
  19. package/built/web/pxtembed.js +2 -2
  20. package/built/web/pxtlib.js +1 -1
  21. package/built/web/pxtsim.js +1 -1
  22. package/built/web/pxtworker.js +2 -2
  23. package/built/web/react-common-authcode.css +4 -6993
  24. package/built/web/react-common-multiplayer.css +13 -0
  25. package/built/web/react-common-skillmap.css +1 -1
  26. package/built/web/rtlreact-common-authcode.css +13 -0
  27. package/built/web/rtlreact-common-multiplayer.css +13 -0
  28. package/built/web/rtlreact-common-skillmap.css +1 -1
  29. package/built/web/rtlsemantic.css +1 -1
  30. package/built/web/semantic.css +1 -1
  31. package/built/web/skillmap/js/main.a6cf40e1.chunk.js +1 -0
  32. package/common-docs/identity/sign-in.md +17 -3
  33. package/common-docs/static/music-editor/apple.png +0 -0
  34. package/common-docs/static/music-editor/burger.png +0 -0
  35. package/common-docs/static/music-editor/cake.png +0 -0
  36. package/common-docs/static/music-editor/car.png +0 -0
  37. package/common-docs/static/music-editor/cat.png +0 -0
  38. package/common-docs/static/music-editor/cherry.png +0 -0
  39. package/common-docs/static/music-editor/clam.png +0 -0
  40. package/common-docs/static/music-editor/computer.png +0 -0
  41. package/common-docs/static/music-editor/crab.png +0 -0
  42. package/common-docs/static/music-editor/dog.png +0 -0
  43. package/common-docs/static/music-editor/duck.png +0 -0
  44. package/common-docs/static/music-editor/egg.png +0 -0
  45. package/common-docs/static/music-editor/explosion.png +0 -0
  46. package/common-docs/static/music-editor/fish.png +0 -0
  47. package/common-docs/static/music-editor/ice-cream.png +0 -0
  48. package/common-docs/static/music-editor/lemon.png +0 -0
  49. package/common-docs/static/music-editor/metronomeWorker.js +35 -0
  50. package/common-docs/static/music-editor/snake.png +0 -0
  51. package/common-docs/static/music-editor/star.png +0 -0
  52. package/common-docs/static/music-editor/strawberry.png +0 -0
  53. package/common-docs/static/music-editor/taco.png +0 -0
  54. package/common-docs/static/music-editor/treble-clef.svg +1 -0
  55. package/package.json +4 -2
  56. package/react-common/components/controls/Input.tsx +7 -3
  57. package/react-common/styles/controls/Button.less +9 -0
  58. package/react-common/styles/react-common-authcode-core.less +1 -1
  59. package/react-common/styles/react-common-authcode.less +1 -1
  60. package/react-common/styles/react-common-multiplayer-core.less +10 -0
  61. package/react-common/styles/react-common-multiplayer.less +12 -0
  62. package/theme/highcontrast.less +6 -0
  63. package/theme/music-editor/EditControls.less +22 -0
  64. package/theme/music-editor/MusicEditor.less +25 -0
  65. package/theme/music-editor/Note.less +16 -0
  66. package/theme/music-editor/NoteGroup.less +7 -0
  67. package/theme/music-editor/PlaybackControls.less +55 -0
  68. package/theme/music-editor/ScrollableWorkspace.less +3 -0
  69. package/theme/music-editor/Staff.less +31 -0
  70. package/theme/music-editor/Track.less +0 -0
  71. package/theme/music-editor/TrackSelector.less +48 -0
  72. package/theme/music-editor/Workspace.less +3 -0
  73. package/theme/pxt.less +1 -0
  74. package/theme/tutorial-sidebar.less +3 -0
  75. package/webapp/public/multiplayer.html +1 -0
  76. package/webapp/public/skillmap.html +1 -1
  77. package/built/web/skillmap/js/main.6eec9e0f.chunk.js +0 -1
package/built/pxtlib.js CHANGED
@@ -216,6 +216,9 @@ var pxt;
216
216
  this.setUserProfileAsync(this.state$.profile);
217
217
  this.setUserPreferencesAsync(this.state$.preferences);
218
218
  }
219
+ async authTokenAsync() {
220
+ return await pxt.storage.shared.getAsync(AUTH_CONTAINER, CSRF_TOKEN_KEY);
221
+ }
219
222
  /**
220
223
  * Starts the process of authenticating the user against the given identity
221
224
  * provider. Upon success the backend will write an http-only session cookie
@@ -700,6 +703,11 @@ var pxt;
700
703
  return (_d = (_b = (_a = user === null || user === void 0 ? void 0 : user.idp) === null || _a === void 0 ? void 0 : _a.displayName) !== null && _b !== void 0 ? _b : (_c = user === null || user === void 0 ? void 0 : user.idp) === null || _c === void 0 ? void 0 : _c.username) !== null && _d !== void 0 ? _d : EMPTY_USERNAME;
701
704
  }
702
705
  auth.userName = userName;
706
+ function firstName(user) {
707
+ const userName = pxt.auth.userName(user);
708
+ return (userName === null || userName === void 0 ? void 0 : userName.split(" ").shift()) || userName;
709
+ }
710
+ auth.firstName = firstName;
703
711
  function userInitials(user) {
704
712
  const username = pxt.auth.userName(user);
705
713
  return ts.pxtc.Util.initials(username);
@@ -8742,6 +8750,7 @@ var pxt;
8742
8750
  const url = new URL(`https://${endpointName}.streaming.media.azure.net/${videoID}/manifest(format=mpd-time-csf).mpd`);
8743
8751
  if (startTime) {
8744
8752
  url.hash = `t=${startTime}`;
8753
+ url.searchParams.append("startTime", startTime);
8745
8754
  }
8746
8755
  if (endTime) {
8747
8756
  url.searchParams.append("endTime", endTime);
@@ -12633,6 +12642,8 @@ var pxt;
12633
12642
  sprite_1.IMAGE_PREFIX = "image";
12634
12643
  sprite_1.ANIMATION_NAMESPACE = "myAnimations";
12635
12644
  sprite_1.ANIMATION_PREFIX = "anim";
12645
+ sprite_1.SONG_NAMESPACE = "mySongs";
12646
+ sprite_1.SONG_PREFIX = "song";
12636
12647
  /**
12637
12648
  * 16-color sprite
12638
12649
  */
@@ -13688,6 +13699,1044 @@ var pxt;
13688
13699
  })(shared = storage.shared || (storage.shared = {}));
13689
13700
  })(storage = pxt.storage || (pxt.storage = {}));
13690
13701
  })(pxt || (pxt = {}));
13702
+ var pxt;
13703
+ (function (pxt) {
13704
+ var assets;
13705
+ (function (assets) {
13706
+ var music;
13707
+ (function (music) {
13708
+ const BUFFER_SIZE = 12;
13709
+ function renderInstrument(instrument, noteFrequency, gateLength, volume) {
13710
+ var _a, _b, _c, _d, _e;
13711
+ const totalDuration = gateLength + instrument.ampEnvelope.release;
13712
+ const ampLFOInterval = ((_a = instrument.ampLFO) === null || _a === void 0 ? void 0 : _a.amplitude) ? Math.max(500 / instrument.ampLFO.frequency, 50) : 50;
13713
+ const pitchLFOInterval = ((_b = instrument.pitchLFO) === null || _b === void 0 ? void 0 : _b.amplitude) ? Math.max(500 / instrument.pitchLFO.frequency, 50) : 50;
13714
+ let timePoints = [0];
13715
+ let nextAETime = instrument.ampEnvelope.attack;
13716
+ let nextPETime = ((_c = instrument.pitchEnvelope) === null || _c === void 0 ? void 0 : _c.amplitude) ? instrument.pitchEnvelope.attack : totalDuration;
13717
+ let nextPLTime = ((_d = instrument.pitchLFO) === null || _d === void 0 ? void 0 : _d.amplitude) ? pitchLFOInterval : totalDuration;
13718
+ let nextALTime = ((_e = instrument.ampLFO) === null || _e === void 0 ? void 0 : _e.amplitude) ? ampLFOInterval : totalDuration;
13719
+ let time = 0;
13720
+ while (time < totalDuration) {
13721
+ if (nextAETime <= nextPETime && nextAETime <= nextPLTime && nextAETime <= nextALTime) {
13722
+ time = nextAETime;
13723
+ timePoints.push(nextAETime);
13724
+ if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {
13725
+ nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;
13726
+ }
13727
+ else if (time < gateLength) {
13728
+ nextAETime = gateLength;
13729
+ }
13730
+ else {
13731
+ nextAETime = totalDuration;
13732
+ }
13733
+ }
13734
+ else if (nextPETime <= nextPLTime && nextPETime <= nextALTime && nextPETime < totalDuration) {
13735
+ time = nextPETime;
13736
+ timePoints.push(nextPETime);
13737
+ if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {
13738
+ nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;
13739
+ }
13740
+ else if (time < gateLength) {
13741
+ nextPETime = gateLength;
13742
+ }
13743
+ else if (time < gateLength + instrument.pitchEnvelope.release) {
13744
+ nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);
13745
+ }
13746
+ else {
13747
+ nextPETime = totalDuration;
13748
+ }
13749
+ }
13750
+ else if (nextPLTime <= nextALTime && nextPLTime < totalDuration) {
13751
+ time = nextPLTime;
13752
+ timePoints.push(nextPLTime);
13753
+ nextPLTime += pitchLFOInterval;
13754
+ }
13755
+ else if (nextALTime < totalDuration) {
13756
+ time = nextALTime;
13757
+ timePoints.push(nextALTime);
13758
+ nextALTime += ampLFOInterval;
13759
+ }
13760
+ if (time >= totalDuration) {
13761
+ break;
13762
+ }
13763
+ if (nextAETime <= time) {
13764
+ if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {
13765
+ nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;
13766
+ }
13767
+ else if (time < gateLength) {
13768
+ nextAETime = gateLength;
13769
+ }
13770
+ else {
13771
+ nextAETime = totalDuration;
13772
+ }
13773
+ }
13774
+ if (nextPETime <= time) {
13775
+ if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {
13776
+ nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;
13777
+ }
13778
+ else if (time < gateLength) {
13779
+ nextPETime = gateLength;
13780
+ }
13781
+ else if (time < gateLength + instrument.pitchEnvelope.release) {
13782
+ nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);
13783
+ }
13784
+ else {
13785
+ nextPETime = totalDuration;
13786
+ }
13787
+ }
13788
+ while (nextALTime <= time) {
13789
+ nextALTime += ampLFOInterval;
13790
+ }
13791
+ while (nextPLTime <= time) {
13792
+ nextPLTime += pitchLFOInterval;
13793
+ }
13794
+ }
13795
+ let prevAmp = instrumentVolumeAtTime(instrument, gateLength, 0, volume) | 0;
13796
+ let prevPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, 0) | 0;
13797
+ let prevTime = 0;
13798
+ let nextAmp;
13799
+ let nextPitch;
13800
+ const out = new Uint8Array(BUFFER_SIZE * (timePoints.length + 1));
13801
+ for (let i = 1; i < timePoints.length; i++) {
13802
+ if (timePoints[i] - prevTime < 5) {
13803
+ prevTime = timePoints[i];
13804
+ continue;
13805
+ }
13806
+ nextAmp = instrumentVolumeAtTime(instrument, gateLength, timePoints[i], volume) | 0;
13807
+ nextPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, timePoints[i]) | 0;
13808
+ addNote(out, (i - 1) * 12, (timePoints[i] - prevTime) | 0, prevAmp, nextAmp, instrument.waveform, prevPitch, nextPitch);
13809
+ prevAmp = nextAmp;
13810
+ prevPitch = nextPitch;
13811
+ prevTime = timePoints[i];
13812
+ }
13813
+ addNote(out, timePoints.length * 12, 10, prevAmp, 0, instrument.waveform, prevPitch, prevPitch);
13814
+ return out;
13815
+ }
13816
+ music.renderInstrument = renderInstrument;
13817
+ function renderDrumInstrument(sound, volume) {
13818
+ let prevAmp = sound.startVolume;
13819
+ let prevFreq = sound.startFrequency;
13820
+ const scaleVolume = (value) => (value / 1024) * volume;
13821
+ let out = new Uint8Array((sound.steps.length + 1) * BUFFER_SIZE);
13822
+ for (let i = 0; i < sound.steps.length; i++) {
13823
+ addNote(out, i * BUFFER_SIZE, sound.steps[i].duration, scaleVolume(prevAmp), scaleVolume(sound.steps[i].volume), sound.steps[i].waveform, prevFreq, sound.steps[i].frequency);
13824
+ prevAmp = sound.steps[i].volume;
13825
+ prevFreq = sound.steps[i].frequency;
13826
+ }
13827
+ addNote(out, sound.steps.length * BUFFER_SIZE, 10, scaleVolume(prevAmp), 0, sound.steps[sound.steps.length - 1].waveform, prevFreq, prevFreq);
13828
+ return out;
13829
+ }
13830
+ music.renderDrumInstrument = renderDrumInstrument;
13831
+ function instrumentPitchAtTime(instrument, noteFrequency, gateLength, time) {
13832
+ var _a, _b;
13833
+ let mod = 0;
13834
+ if ((_a = instrument.pitchEnvelope) === null || _a === void 0 ? void 0 : _a.amplitude) {
13835
+ mod += envelopeValueAtTime(instrument.pitchEnvelope, time, gateLength);
13836
+ }
13837
+ if ((_b = instrument.pitchLFO) === null || _b === void 0 ? void 0 : _b.amplitude) {
13838
+ mod += lfoValueAtTime(instrument.pitchLFO, time);
13839
+ }
13840
+ return Math.max(noteFrequency + mod, 0);
13841
+ }
13842
+ function instrumentVolumeAtTime(instrument, gateLength, time, maxVolume) {
13843
+ var _a;
13844
+ let mod = 0;
13845
+ if (instrument.ampEnvelope.amplitude) {
13846
+ mod += envelopeValueAtTime(instrument.ampEnvelope, time, gateLength);
13847
+ }
13848
+ if ((_a = instrument.ampLFO) === null || _a === void 0 ? void 0 : _a.amplitude) {
13849
+ mod += lfoValueAtTime(instrument.ampLFO, time);
13850
+ }
13851
+ return ((Math.max(Math.min(mod, instrument.ampEnvelope.amplitude), 0) / 1024) * maxVolume) | 0;
13852
+ }
13853
+ function envelopeValueAtTime(envelope, time, gateLength) {
13854
+ const adjustedSustain = (envelope.sustain / 1024) * envelope.amplitude;
13855
+ if (time > gateLength) {
13856
+ if (time - gateLength > envelope.release)
13857
+ return 0;
13858
+ else if (time < envelope.attack) {
13859
+ const height = (envelope.amplitude / envelope.attack) * gateLength;
13860
+ return height - ((height / envelope.release) * (time - gateLength));
13861
+ }
13862
+ else if (time < envelope.attack + envelope.decay) {
13863
+ const height2 = envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (gateLength - envelope.attack);
13864
+ return height2 - ((height2 / envelope.release) * (time - gateLength));
13865
+ }
13866
+ else {
13867
+ return adjustedSustain - (adjustedSustain / envelope.release) * (time - gateLength);
13868
+ }
13869
+ }
13870
+ else if (time < envelope.attack) {
13871
+ return (envelope.amplitude / envelope.attack) * time;
13872
+ }
13873
+ else if (time < envelope.attack + envelope.decay) {
13874
+ return envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (time - envelope.attack);
13875
+ }
13876
+ else {
13877
+ return adjustedSustain;
13878
+ }
13879
+ }
13880
+ function lfoValueAtTime(lfo, time) {
13881
+ return Math.cos(((time / 1000) * lfo.frequency) * 2 * Math.PI) * lfo.amplitude;
13882
+ }
13883
+ function set16BitNumber(buf, offset, value) {
13884
+ const temp = new Uint8Array(2);
13885
+ new Uint16Array(temp.buffer)[0] = value | 0;
13886
+ buf[offset] = temp[0];
13887
+ buf[offset + 1] = temp[1];
13888
+ }
13889
+ function get16BitNumber(buf, offset) {
13890
+ const temp = new Uint8Array(2);
13891
+ temp[0] = buf[offset];
13892
+ temp[1] = buf[offset + 1];
13893
+ return new Uint16Array(temp.buffer)[0];
13894
+ }
13895
+ function addNote(sndInstr, sndInstrPtr, ms, beg, end, soundWave, hz, endHz) {
13896
+ if (ms > 0) {
13897
+ sndInstr[sndInstrPtr] = soundWave;
13898
+ sndInstr[sndInstrPtr + 1] = 0;
13899
+ set16BitNumber(sndInstr, sndInstrPtr + 2, hz);
13900
+ set16BitNumber(sndInstr, sndInstrPtr + 4, ms);
13901
+ set16BitNumber(sndInstr, sndInstrPtr + 6, (beg * 255) >> 6);
13902
+ set16BitNumber(sndInstr, sndInstrPtr + 8, (end * 255) >> 6);
13903
+ set16BitNumber(sndInstr, sndInstrPtr + 10, endHz);
13904
+ sndInstrPtr += BUFFER_SIZE;
13905
+ }
13906
+ sndInstr[sndInstrPtr] = 0;
13907
+ return sndInstrPtr;
13908
+ }
13909
+ function encodeSongToHex(song) {
13910
+ const encoded = encodeSong(song);
13911
+ return pxt.U.toHex(encoded);
13912
+ }
13913
+ music.encodeSongToHex = encodeSongToHex;
13914
+ function decodeSongFromHex(hex) {
13915
+ const bytes = pxt.U.fromHex(hex);
13916
+ return decodeSong(bytes);
13917
+ }
13918
+ music.decodeSongFromHex = decodeSongFromHex;
13919
+ /**
13920
+ * Byte encoding format for songs
13921
+ * FIXME: should this all be word aligned?
13922
+ *
13923
+ * song(7 + length of all tracks bytes)
13924
+ * 0 version
13925
+ * 1 beats per minute
13926
+ * 3 beats per measure
13927
+ * 4 ticks per beat
13928
+ * 5 measures
13929
+ * 6 number of tracks
13930
+ * ...tracks
13931
+ *
13932
+ * track(6 + instrument length + note length bytes)
13933
+ * 0 id
13934
+ * 1 flags
13935
+ * 2 instruments byte length
13936
+ * 4...instrument
13937
+ * notes byte length
13938
+ * ...note events
13939
+ *
13940
+ * instrument(27 bytes)
13941
+ * 0 waveform
13942
+ * 1 amp attack
13943
+ * 3 amp decay
13944
+ * 5 amp sustain
13945
+ * 7 amp release
13946
+ * 9 amp amp
13947
+ * 11 pitch attack
13948
+ * 13 pitch decay
13949
+ * 15 pitch sustain
13950
+ * 17 pitch release
13951
+ * 19 pitch amp
13952
+ * 21 amp lfo freq
13953
+ * 22 amp lfo amp
13954
+ * 24 pitch lfo freq
13955
+ * 25 pitch lfo amp
13956
+ *
13957
+ * drum(5 + 7 * steps bytes)
13958
+ * 0 steps
13959
+ * 1 start freq
13960
+ * 3 start amp
13961
+ * 5...steps
13962
+ *
13963
+ * drum step(7 bytes)
13964
+ * 0 waveform
13965
+ * 1 freq
13966
+ * 3 volume
13967
+ * 5 duration
13968
+ *
13969
+ * note event(5 + 1 * polyphony bytes)
13970
+ * 0 start tick
13971
+ * 2 end tick
13972
+ * 4 polyphony
13973
+ * 5...notes(1 byte each)
13974
+ *
13975
+ */
13976
+ function encodeSong(song) {
13977
+ const encodedTracks = song.tracks
13978
+ .filter((track) => track.notes.length > 0)
13979
+ .map(encodeTrack);
13980
+ const trackLength = encodedTracks.reduce((d, c) => c.length + d, 0);
13981
+ const out = new Uint8Array(7 + trackLength);
13982
+ out[0] = 0; // encoding version
13983
+ set16BitNumber(out, 1, song.beatsPerMinute);
13984
+ out[3] = song.beatsPerMeasure;
13985
+ out[4] = song.ticksPerBeat;
13986
+ out[5] = song.measures;
13987
+ out[6] = encodedTracks.length;
13988
+ let current = 7;
13989
+ for (const track of encodedTracks) {
13990
+ out.set(track, current);
13991
+ current += track.length;
13992
+ }
13993
+ return out;
13994
+ }
13995
+ function decodeSong(buf) {
13996
+ const res = {
13997
+ beatsPerMinute: get16BitNumber(buf, 1),
13998
+ beatsPerMeasure: buf[3],
13999
+ ticksPerBeat: buf[4],
14000
+ measures: buf[5],
14001
+ tracks: []
14002
+ };
14003
+ let current = 7;
14004
+ while (current < buf.length) {
14005
+ const [track, pointer] = decodeTrack(buf, current);
14006
+ current = pointer;
14007
+ res.tracks.push(track);
14008
+ }
14009
+ return res;
14010
+ }
14011
+ function encodeInstrument(instrument) {
14012
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
14013
+ const out = new Uint8Array(28);
14014
+ out[0] = instrument.waveform;
14015
+ set16BitNumber(out, 1, instrument.ampEnvelope.attack);
14016
+ set16BitNumber(out, 3, instrument.ampEnvelope.decay);
14017
+ set16BitNumber(out, 5, instrument.ampEnvelope.sustain);
14018
+ set16BitNumber(out, 7, instrument.ampEnvelope.release);
14019
+ set16BitNumber(out, 9, instrument.ampEnvelope.amplitude);
14020
+ set16BitNumber(out, 11, ((_a = instrument.pitchEnvelope) === null || _a === void 0 ? void 0 : _a.attack) || 0);
14021
+ set16BitNumber(out, 13, ((_b = instrument.pitchEnvelope) === null || _b === void 0 ? void 0 : _b.decay) || 0);
14022
+ set16BitNumber(out, 15, ((_c = instrument.pitchEnvelope) === null || _c === void 0 ? void 0 : _c.sustain) || 0);
14023
+ set16BitNumber(out, 17, ((_d = instrument.pitchEnvelope) === null || _d === void 0 ? void 0 : _d.release) || 0);
14024
+ set16BitNumber(out, 19, ((_e = instrument.pitchEnvelope) === null || _e === void 0 ? void 0 : _e.amplitude) || 0);
14025
+ out[21] = ((_f = instrument.ampLFO) === null || _f === void 0 ? void 0 : _f.frequency) || 0;
14026
+ set16BitNumber(out, 22, ((_g = instrument.ampLFO) === null || _g === void 0 ? void 0 : _g.amplitude) || 0);
14027
+ out[24] = ((_h = instrument.pitchLFO) === null || _h === void 0 ? void 0 : _h.frequency) || 0;
14028
+ set16BitNumber(out, 25, ((_j = instrument.pitchLFO) === null || _j === void 0 ? void 0 : _j.amplitude) || 0);
14029
+ return out;
14030
+ }
14031
+ function decodeInstrument(buf, offset) {
14032
+ return {
14033
+ waveform: buf[offset],
14034
+ ampEnvelope: {
14035
+ attack: get16BitNumber(buf, offset + 1),
14036
+ decay: get16BitNumber(buf, offset + 3),
14037
+ sustain: get16BitNumber(buf, offset + 5),
14038
+ release: get16BitNumber(buf, offset + 7),
14039
+ amplitude: get16BitNumber(buf, offset + 9),
14040
+ },
14041
+ pitchEnvelope: {
14042
+ attack: get16BitNumber(buf, offset + 11),
14043
+ decay: get16BitNumber(buf, offset + 13),
14044
+ sustain: get16BitNumber(buf, offset + 15),
14045
+ release: get16BitNumber(buf, offset + 17),
14046
+ amplitude: get16BitNumber(buf, offset + 19),
14047
+ },
14048
+ ampLFO: {
14049
+ frequency: buf[offset + 21],
14050
+ amplitude: get16BitNumber(buf, 22)
14051
+ },
14052
+ pitchLFO: {
14053
+ frequency: buf[offset + 24],
14054
+ amplitude: get16BitNumber(buf, 25)
14055
+ }
14056
+ };
14057
+ }
14058
+ function decodeTrack(buf, offset) {
14059
+ if (buf[offset + 1]) {
14060
+ return decodeDrumTrack(buf, offset);
14061
+ }
14062
+ return decodeMelodicTrack(buf, offset);
14063
+ }
14064
+ function encodeDrumInstrument(drum) {
14065
+ const out = new Uint8Array(5 + 7 * drum.steps.length);
14066
+ out[0] = drum.steps.length;
14067
+ set16BitNumber(out, 1, drum.startFrequency);
14068
+ set16BitNumber(out, 3, drum.startVolume);
14069
+ for (let i = 0; i < drum.steps.length; i++) {
14070
+ const start = 5 + i * 7;
14071
+ out[start] = drum.steps[i].waveform;
14072
+ set16BitNumber(out, start + 1, drum.steps[i].frequency);
14073
+ set16BitNumber(out, start + 3, drum.steps[i].volume);
14074
+ set16BitNumber(out, start + 5, drum.steps[i].duration);
14075
+ }
14076
+ return out;
14077
+ }
14078
+ function decodeDrumInstrument(buf, offset) {
14079
+ const res = {
14080
+ startFrequency: get16BitNumber(buf, offset + 1),
14081
+ startVolume: get16BitNumber(buf, offset + 3),
14082
+ steps: []
14083
+ };
14084
+ for (let i = 0; i < buf[offset]; i++) {
14085
+ const start = offset + 5 + i * 7;
14086
+ res.steps.push({
14087
+ waveform: buf[start],
14088
+ frequency: get16BitNumber(buf, start + 1),
14089
+ volume: get16BitNumber(buf, start + 3),
14090
+ duration: get16BitNumber(buf, start + 5)
14091
+ });
14092
+ }
14093
+ return res;
14094
+ }
14095
+ function encodeNoteEvent(event) {
14096
+ const out = new Uint8Array(5 + event.notes.length);
14097
+ set16BitNumber(out, 0, event.startTick);
14098
+ set16BitNumber(out, 2, event.endTick);
14099
+ out[4] = event.notes.length;
14100
+ for (let i = 0; i < event.notes.length; i++) {
14101
+ out[5 + i] = event.notes[i];
14102
+ }
14103
+ return out;
14104
+ }
14105
+ function decodeNoteEvent(buf, offset) {
14106
+ const res = {
14107
+ startTick: get16BitNumber(buf, offset),
14108
+ endTick: get16BitNumber(buf, offset + 2),
14109
+ notes: []
14110
+ };
14111
+ for (let i = 0; i < buf[offset + 4]; i++) {
14112
+ res.notes.push(buf[offset + 5 + i]);
14113
+ }
14114
+ return res;
14115
+ }
14116
+ function encodeTrack(track) {
14117
+ if (track.drums)
14118
+ return encodeDrumTrack(track);
14119
+ return encodeMelodicTrack(track);
14120
+ }
14121
+ function encodeMelodicTrack(track) {
14122
+ const encodedInstrument = encodeInstrument(track.instrument);
14123
+ const encodedNotes = track.notes.map(encodeNoteEvent);
14124
+ const noteLength = encodedNotes.reduce((d, c) => c.length + d, 0);
14125
+ const out = new Uint8Array(6 + encodedInstrument.length + noteLength);
14126
+ out[0] = track.id;
14127
+ out[1] = 0;
14128
+ set16BitNumber(out, 2, encodedInstrument.length);
14129
+ let current = 4;
14130
+ out.set(encodedInstrument, current);
14131
+ current += encodedInstrument.length;
14132
+ set16BitNumber(out, current, noteLength);
14133
+ current += 2;
14134
+ for (const note of encodedNotes) {
14135
+ out.set(note, current);
14136
+ current += note.length;
14137
+ }
14138
+ return out;
14139
+ }
14140
+ function decodeMelodicTrack(buf, offset) {
14141
+ const res = {
14142
+ id: buf[offset],
14143
+ instrument: decodeInstrument(buf, offset + 4),
14144
+ notes: []
14145
+ };
14146
+ const noteStart = offset + 4 + get16BitNumber(buf, offset + 2);
14147
+ const noteLength = get16BitNumber(buf, noteStart);
14148
+ let currentOffset = noteStart + 2;
14149
+ while (currentOffset < noteStart + 2 + noteLength) {
14150
+ res.notes.push(decodeNoteEvent(buf, currentOffset));
14151
+ currentOffset += 5 + res.notes[res.notes.length - 1].notes.length;
14152
+ }
14153
+ return [res, currentOffset];
14154
+ }
14155
+ function encodeDrumTrack(track) {
14156
+ const encodedDrums = track.drums.map(encodeDrumInstrument);
14157
+ const drumLength = encodedDrums.reduce((d, c) => c.length + d, 0);
14158
+ const encodedNotes = track.notes.map(encodeNoteEvent);
14159
+ const noteLength = encodedNotes.reduce((d, c) => c.length + d, 0);
14160
+ const out = new Uint8Array(6 + drumLength + noteLength);
14161
+ out[0] = track.id;
14162
+ out[1] = 1;
14163
+ set16BitNumber(out, 2, drumLength);
14164
+ let current = 4;
14165
+ for (const drum of encodedDrums) {
14166
+ out.set(drum, current);
14167
+ current += drum.length;
14168
+ }
14169
+ set16BitNumber(out, current, noteLength);
14170
+ current += 2;
14171
+ for (const note of encodedNotes) {
14172
+ out.set(note, current);
14173
+ current += note.length;
14174
+ }
14175
+ return out;
14176
+ }
14177
+ function decodeDrumTrack(buf, offset) {
14178
+ const res = {
14179
+ id: buf[offset],
14180
+ instrument: { ampEnvelope: { attack: 0, decay: 0, sustain: 0, release: 0, amplitude: 0 }, waveform: 0 },
14181
+ notes: [],
14182
+ drums: []
14183
+ };
14184
+ const drumByteLength = get16BitNumber(buf, offset + 2);
14185
+ let currentOffset = offset + 4;
14186
+ while (currentOffset < offset + 4 + drumByteLength) {
14187
+ res.drums.push(decodeDrumInstrument(buf, currentOffset));
14188
+ currentOffset += 5 + 7 * res.drums[res.drums.length - 1].steps.length;
14189
+ }
14190
+ const noteLength = get16BitNumber(buf, currentOffset);
14191
+ currentOffset += 2;
14192
+ while (currentOffset < offset + 4 + drumByteLength + noteLength) {
14193
+ res.notes.push(decodeNoteEvent(buf, currentOffset));
14194
+ currentOffset += 5 + res.notes[res.notes.length - 1].notes.length;
14195
+ }
14196
+ return [res, currentOffset];
14197
+ }
14198
+ function cloneSong(song) {
14199
+ return Object.assign(Object.assign({}, song), { tracks: song.tracks.map(track => (Object.assign(Object.assign({}, track), { instrument: track.instrument && Object.assign(Object.assign({}, track.instrument), { ampEnvelope: Object.assign({}, track.instrument.ampEnvelope), pitchEnvelope: track.instrument.pitchEnvelope && Object.assign({}, track.instrument.pitchEnvelope), ampLFO: track.instrument.ampLFO && Object.assign({}, track.instrument.ampLFO), pitchLFO: track.instrument.pitchLFO && Object.assign({}, track.instrument.pitchLFO) }), drums: track.drums && track.drums.map(drum => (Object.assign(Object.assign({}, drum), { steps: drum.steps.map(step => (Object.assign({}, step))) }))), notes: track.notes.map(noteEvent => (Object.assign(Object.assign({}, noteEvent), { notes: noteEvent.notes.slice() }))) }))) });
14200
+ }
14201
+ music.cloneSong = cloneSong;
14202
+ function songEquals(a, b) {
14203
+ return naiveEqualCheck(a, b);
14204
+ }
14205
+ music.songEquals = songEquals;
14206
+ function naiveEqualCheck(a, b) {
14207
+ if (typeof a !== typeof b)
14208
+ return false;
14209
+ else if (typeof a !== "object")
14210
+ return a === b;
14211
+ else if (Array.isArray(a)) {
14212
+ if (a.length !== b.length)
14213
+ return false;
14214
+ for (let i = 0; i < a.length; i++) {
14215
+ if (!naiveEqualCheck(a[i], b[i]))
14216
+ return false;
14217
+ }
14218
+ return true;
14219
+ }
14220
+ const aKeys = Object.keys(a);
14221
+ const bKeys = Object.keys(b);
14222
+ if (aKeys.length !== bKeys.length)
14223
+ return false;
14224
+ for (const key of aKeys) {
14225
+ if (bKeys.indexOf(key) === -1)
14226
+ return false;
14227
+ if (!naiveEqualCheck(a[key], b[key]))
14228
+ return false;
14229
+ }
14230
+ return true;
14231
+ }
14232
+ function inflateSong(song) {
14233
+ const base = getEmptySong(1);
14234
+ song.tracks = base.tracks.map((track, index) => {
14235
+ const existing = song.tracks.find(t => t.id === index);
14236
+ if (existing)
14237
+ track.notes = existing.notes;
14238
+ return track;
14239
+ });
14240
+ }
14241
+ music.inflateSong = inflateSong;
14242
+ function getEmptySong(measures) {
14243
+ return {
14244
+ ticksPerBeat: 8,
14245
+ beatsPerMeasure: 4,
14246
+ beatsPerMinute: 120,
14247
+ measures,
14248
+ tracks: [
14249
+ {
14250
+ id: 0,
14251
+ name: lf("Duck"),
14252
+ notes: [],
14253
+ iconURI: "/static/music-editor/duck.png",
14254
+ instrument: {
14255
+ waveform: 15,
14256
+ octave: 4,
14257
+ ampEnvelope: {
14258
+ attack: 5,
14259
+ decay: 530,
14260
+ sustain: 705,
14261
+ release: 450,
14262
+ amplitude: 1024
14263
+ },
14264
+ pitchEnvelope: {
14265
+ attack: 5,
14266
+ decay: 40,
14267
+ sustain: 0,
14268
+ release: 100,
14269
+ amplitude: 40
14270
+ },
14271
+ ampLFO: {
14272
+ frequency: 3,
14273
+ amplitude: 20
14274
+ },
14275
+ pitchLFO: {
14276
+ frequency: 6,
14277
+ amplitude: 2
14278
+ }
14279
+ }
14280
+ },
14281
+ {
14282
+ id: 1,
14283
+ name: lf("Cat"),
14284
+ notes: [],
14285
+ iconURI: "/static/music-editor/cat.png",
14286
+ instrument: {
14287
+ waveform: 12,
14288
+ octave: 5,
14289
+ ampEnvelope: {
14290
+ attack: 150,
14291
+ decay: 100,
14292
+ sustain: 365,
14293
+ release: 400,
14294
+ amplitude: 1024
14295
+ },
14296
+ pitchEnvelope: {
14297
+ attack: 120,
14298
+ decay: 300,
14299
+ sustain: 0,
14300
+ release: 100,
14301
+ amplitude: 50
14302
+ },
14303
+ pitchLFO: {
14304
+ frequency: 10,
14305
+ amplitude: 6
14306
+ }
14307
+ }
14308
+ },
14309
+ {
14310
+ id: 2,
14311
+ name: lf("Dog"),
14312
+ notes: [],
14313
+ iconURI: "/static/music-editor/dog.png",
14314
+ instrument: {
14315
+ waveform: 1,
14316
+ octave: 4,
14317
+ ampEnvelope: {
14318
+ attack: 10,
14319
+ decay: 100,
14320
+ sustain: 500,
14321
+ release: 100,
14322
+ amplitude: 1024
14323
+ },
14324
+ pitchLFO: {
14325
+ frequency: 5,
14326
+ amplitude: 0
14327
+ }
14328
+ }
14329
+ },
14330
+ {
14331
+ id: 3,
14332
+ name: lf("Fish"),
14333
+ notes: [],
14334
+ iconURI: "/static/music-editor/fish.png",
14335
+ instrument: {
14336
+ waveform: 1,
14337
+ octave: 3,
14338
+ ampEnvelope: {
14339
+ attack: 220,
14340
+ decay: 105,
14341
+ sustain: 1024,
14342
+ release: 350,
14343
+ amplitude: 1024
14344
+ },
14345
+ ampLFO: {
14346
+ frequency: 5,
14347
+ amplitude: 100
14348
+ },
14349
+ pitchLFO: {
14350
+ frequency: 1,
14351
+ amplitude: 4
14352
+ }
14353
+ }
14354
+ },
14355
+ {
14356
+ id: 4,
14357
+ name: lf("Car"),
14358
+ notes: [],
14359
+ iconURI: "/static/music-editor/car.png",
14360
+ instrument: {
14361
+ waveform: 16,
14362
+ octave: 4,
14363
+ ampEnvelope: {
14364
+ attack: 5,
14365
+ decay: 100,
14366
+ sustain: 1024,
14367
+ release: 30,
14368
+ amplitude: 1024
14369
+ },
14370
+ pitchLFO: {
14371
+ frequency: 10,
14372
+ amplitude: 4
14373
+ }
14374
+ }
14375
+ },
14376
+ {
14377
+ id: 5,
14378
+ name: lf("Computer"),
14379
+ notes: [],
14380
+ iconURI: "/static/music-editor/computer.png",
14381
+ instrument: {
14382
+ waveform: 15,
14383
+ octave: 1,
14384
+ ampEnvelope: {
14385
+ attack: 10,
14386
+ decay: 100,
14387
+ sustain: 500,
14388
+ release: 10,
14389
+ amplitude: 1024
14390
+ }
14391
+ }
14392
+ },
14393
+ {
14394
+ id: 6,
14395
+ name: lf("Burger"),
14396
+ notes: [],
14397
+ iconURI: "/static/music-editor/burger.png",
14398
+ instrument: {
14399
+ waveform: 1,
14400
+ octave: 1,
14401
+ ampEnvelope: {
14402
+ attack: 10,
14403
+ decay: 100,
14404
+ sustain: 500,
14405
+ release: 100,
14406
+ amplitude: 1024
14407
+ }
14408
+ }
14409
+ },
14410
+ {
14411
+ id: 7,
14412
+ name: lf("Cherry"),
14413
+ notes: [],
14414
+ iconURI: "/static/music-editor/cherry.png",
14415
+ instrument: {
14416
+ waveform: 2,
14417
+ octave: 3,
14418
+ ampEnvelope: {
14419
+ attack: 10,
14420
+ decay: 100,
14421
+ sustain: 500,
14422
+ release: 100,
14423
+ amplitude: 1024
14424
+ }
14425
+ }
14426
+ },
14427
+ {
14428
+ id: 8,
14429
+ name: lf("Lemon"),
14430
+ notes: [],
14431
+ iconURI: "/static/music-editor/lemon.png",
14432
+ instrument: {
14433
+ waveform: 15,
14434
+ octave: 2,
14435
+ ampEnvelope: {
14436
+ attack: 10,
14437
+ decay: 100,
14438
+ sustain: 500,
14439
+ release: 10,
14440
+ amplitude: 1024
14441
+ }
14442
+ }
14443
+ },
14444
+ {
14445
+ id: 9,
14446
+ name: lf("Explosion"),
14447
+ notes: [],
14448
+ iconURI: "/static/music-editor/explosion.png",
14449
+ instrument: {
14450
+ waveform: 11,
14451
+ octave: 4,
14452
+ ampEnvelope: {
14453
+ attack: 10,
14454
+ decay: 100,
14455
+ sustain: 500,
14456
+ release: 100,
14457
+ amplitude: 1024
14458
+ }
14459
+ },
14460
+ drums: [
14461
+ {
14462
+ startFrequency: 100,
14463
+ startVolume: 1024,
14464
+ steps: [
14465
+ {
14466
+ waveform: 3,
14467
+ frequency: 120,
14468
+ duration: 10,
14469
+ volume: 1024
14470
+ },
14471
+ {
14472
+ waveform: 3,
14473
+ frequency: 1,
14474
+ duration: 100,
14475
+ volume: 0
14476
+ }
14477
+ ]
14478
+ },
14479
+ {
14480
+ startFrequency: 1,
14481
+ startVolume: 1024,
14482
+ steps: [
14483
+ {
14484
+ waveform: 5,
14485
+ frequency: 1,
14486
+ duration: 20,
14487
+ volume: 0
14488
+ }
14489
+ ]
14490
+ },
14491
+ {
14492
+ startFrequency: 1,
14493
+ startVolume: 1024,
14494
+ steps: [
14495
+ {
14496
+ waveform: 5,
14497
+ frequency: 1,
14498
+ duration: 20,
14499
+ volume: 480
14500
+ },
14501
+ {
14502
+ waveform: 5,
14503
+ frequency: 1,
14504
+ duration: 20,
14505
+ volume: 260
14506
+ },
14507
+ {
14508
+ waveform: 5,
14509
+ frequency: 1,
14510
+ duration: 20,
14511
+ volume: 200
14512
+ },
14513
+ {
14514
+ waveform: 5,
14515
+ frequency: 1,
14516
+ duration: 200,
14517
+ volume: 0
14518
+ },
14519
+ ]
14520
+ },
14521
+ {
14522
+ startFrequency: 175,
14523
+ startVolume: 1024,
14524
+ steps: [
14525
+ {
14526
+ waveform: 1,
14527
+ frequency: 200,
14528
+ duration: 10,
14529
+ volume: 1024
14530
+ },
14531
+ {
14532
+ waveform: 1,
14533
+ frequency: 150,
14534
+ duration: 20,
14535
+ volume: 1024
14536
+ },
14537
+ {
14538
+ waveform: 5,
14539
+ frequency: 1,
14540
+ duration: 20,
14541
+ volume: 100
14542
+ },
14543
+ {
14544
+ waveform: 5,
14545
+ frequency: 1,
14546
+ duration: 300,
14547
+ volume: 0
14548
+ },
14549
+ ]
14550
+ },
14551
+ {
14552
+ startFrequency: 100,
14553
+ startVolume: 1024,
14554
+ steps: [
14555
+ {
14556
+ waveform: 3,
14557
+ frequency: 120,
14558
+ duration: 10,
14559
+ volume: 1024
14560
+ },
14561
+ {
14562
+ waveform: 1,
14563
+ frequency: 120,
14564
+ duration: 100,
14565
+ volume: 0
14566
+ }
14567
+ ]
14568
+ },
14569
+ {
14570
+ startFrequency: 1,
14571
+ startVolume: 1024,
14572
+ steps: [
14573
+ {
14574
+ waveform: 5,
14575
+ frequency: 1,
14576
+ duration: 20,
14577
+ volume: 0
14578
+ }
14579
+ ]
14580
+ },
14581
+ {
14582
+ startFrequency: 1,
14583
+ startVolume: 1024,
14584
+ steps: [
14585
+ {
14586
+ waveform: 5,
14587
+ frequency: 1,
14588
+ duration: 20,
14589
+ volume: 480
14590
+ },
14591
+ {
14592
+ waveform: 5,
14593
+ frequency: 1,
14594
+ duration: 20,
14595
+ volume: 260
14596
+ },
14597
+ {
14598
+ waveform: 5,
14599
+ frequency: 1,
14600
+ duration: 20,
14601
+ volume: 200
14602
+ },
14603
+ {
14604
+ waveform: 5,
14605
+ frequency: 1,
14606
+ duration: 200,
14607
+ volume: 0
14608
+ },
14609
+ ]
14610
+ },
14611
+ {
14612
+ startFrequency: 175,
14613
+ startVolume: 1024,
14614
+ steps: [
14615
+ {
14616
+ waveform: 1,
14617
+ frequency: 200,
14618
+ duration: 10,
14619
+ volume: 1024
14620
+ },
14621
+ {
14622
+ waveform: 1,
14623
+ frequency: 150,
14624
+ duration: 20,
14625
+ volume: 1024
14626
+ },
14627
+ {
14628
+ waveform: 5,
14629
+ frequency: 1,
14630
+ duration: 20,
14631
+ volume: 100
14632
+ },
14633
+ {
14634
+ waveform: 5,
14635
+ frequency: 1,
14636
+ duration: 300,
14637
+ volume: 0
14638
+ },
14639
+ ]
14640
+ },
14641
+ {
14642
+ startFrequency: 100,
14643
+ startVolume: 1024,
14644
+ steps: [
14645
+ {
14646
+ waveform: 3,
14647
+ frequency: 120,
14648
+ duration: 10,
14649
+ volume: 1024
14650
+ },
14651
+ {
14652
+ waveform: 1,
14653
+ frequency: 120,
14654
+ duration: 100,
14655
+ volume: 0
14656
+ }
14657
+ ]
14658
+ },
14659
+ {
14660
+ startFrequency: 1,
14661
+ startVolume: 1024,
14662
+ steps: [
14663
+ {
14664
+ waveform: 5,
14665
+ frequency: 1,
14666
+ duration: 20,
14667
+ volume: 0
14668
+ }
14669
+ ]
14670
+ },
14671
+ {
14672
+ startFrequency: 1,
14673
+ startVolume: 1024,
14674
+ steps: [
14675
+ {
14676
+ waveform: 5,
14677
+ frequency: 1,
14678
+ duration: 20,
14679
+ volume: 480
14680
+ },
14681
+ {
14682
+ waveform: 5,
14683
+ frequency: 1,
14684
+ duration: 20,
14685
+ volume: 260
14686
+ },
14687
+ {
14688
+ waveform: 5,
14689
+ frequency: 1,
14690
+ duration: 20,
14691
+ volume: 200
14692
+ },
14693
+ {
14694
+ waveform: 5,
14695
+ frequency: 1,
14696
+ duration: 200,
14697
+ volume: 0
14698
+ },
14699
+ ]
14700
+ },
14701
+ {
14702
+ startFrequency: 175,
14703
+ startVolume: 1024,
14704
+ steps: [
14705
+ {
14706
+ waveform: 1,
14707
+ frequency: 200,
14708
+ duration: 10,
14709
+ volume: 1024
14710
+ },
14711
+ {
14712
+ waveform: 1,
14713
+ frequency: 150,
14714
+ duration: 20,
14715
+ volume: 1024
14716
+ },
14717
+ {
14718
+ waveform: 5,
14719
+ frequency: 1,
14720
+ duration: 20,
14721
+ volume: 100
14722
+ },
14723
+ {
14724
+ waveform: 5,
14725
+ frequency: 1,
14726
+ duration: 300,
14727
+ volume: 0
14728
+ },
14729
+ ]
14730
+ }
14731
+ ]
14732
+ }
14733
+ ]
14734
+ };
14735
+ }
14736
+ music.getEmptySong = getEmptySong;
14737
+ })(music = assets.music || (assets.music = {}));
14738
+ })(assets = pxt.assets || (pxt.assets = {}));
14739
+ })(pxt || (pxt = {}));
13691
14740
  /// <reference path="../localtypings/pxtpackage.d.ts"/>
13692
14741
  /// <reference path="../localtypings/pxtparts.d.ts"/>
13693
14742
  /// <reference path="../localtypings/pxtarget.d.ts"/>
@@ -17752,6 +18801,7 @@ var pxt;
17752
18801
  pxt.IMAGE_MIME_TYPE = "image/x-mkcd-f4";
17753
18802
  pxt.TILEMAP_MIME_TYPE = "application/mkcd-tilemap";
17754
18803
  pxt.ANIMATION_MIME_TYPE = "application/mkcd-animation";
18804
+ pxt.SONG_MIME_TYPE = "application/mkcd-song";
17755
18805
  class AssetCollection {
17756
18806
  constructor() {
17757
18807
  this.assets = [];
@@ -17938,21 +18988,24 @@ var pxt;
17938
18988
  tilemaps: new AssetCollection(),
17939
18989
  tiles: new AssetCollection(),
17940
18990
  animations: new AssetCollection(),
17941
- images: new AssetCollection()
18991
+ images: new AssetCollection(),
18992
+ songs: new AssetCollection(),
17942
18993
  };
17943
18994
  this.state = {
17944
18995
  revision: this.nextID++,
17945
18996
  tilemaps: new AssetCollection(),
17946
18997
  tiles: new AssetCollection(),
17947
18998
  animations: new AssetCollection(),
17948
- images: new AssetCollection()
18999
+ images: new AssetCollection(),
19000
+ songs: new AssetCollection(),
17949
19001
  };
17950
19002
  this.gallery = {
17951
19003
  revision: 0,
17952
19004
  tilemaps: new AssetCollection(),
17953
19005
  tiles: new AssetCollection(),
17954
19006
  animations: new AssetCollection(),
17955
- images: new AssetCollection()
19007
+ images: new AssetCollection(),
19008
+ songs: new AssetCollection(),
17956
19009
  };
17957
19010
  this.undoStack = [];
17958
19011
  this.redoStack = [];
@@ -18054,6 +19107,19 @@ var pxt;
18054
19107
  };
18055
19108
  return this.state.images.add(newImage);
18056
19109
  }
19110
+ createNewSong(data, displayName) {
19111
+ this.onChange();
19112
+ const newSong = {
19113
+ internalID: this.getNewInternalId(),
19114
+ id: this.generateNewID("song" /* AssetType.Song */),
19115
+ type: "song" /* AssetType.Song */,
19116
+ song: pxt.assets.music.cloneSong(data),
19117
+ meta: {
19118
+ displayName
19119
+ },
19120
+ };
19121
+ return this.state.songs.add(newSong);
19122
+ }
18057
19123
  updateTile(tile) {
18058
19124
  this.onChange();
18059
19125
  const existing = this.resolveProjectTileByInternalID(tile.internalID);
@@ -18090,6 +19156,7 @@ var pxt;
18090
19156
  const blob = {};
18091
19157
  this.state.images.serializeToJRes(blob);
18092
19158
  this.state.animations.serializeToJRes(blob);
19159
+ this.state.songs.serializeToJRes(blob);
18093
19160
  blob["*"] = {
18094
19161
  "mimeType": "image/x-mkcd-f4",
18095
19162
  "dataEncoding": "base64",
@@ -18171,6 +19238,7 @@ var pxt;
18171
19238
  tilemaps: this.state.tilemaps.clone(),
18172
19239
  animations: this.state.animations.clone(),
18173
19240
  tiles: this.state.tiles.clone(),
19241
+ songs: this.state.songs.clone(),
18174
19242
  };
18175
19243
  }
18176
19244
  undo() {
@@ -18183,6 +19251,7 @@ var pxt;
18183
19251
  this.state.images.applyDiff(undo.images, true);
18184
19252
  this.state.tilemaps.applyDiff(undo.tilemaps, true);
18185
19253
  this.state.animations.applyDiff(undo.animations, true);
19254
+ this.state.songs.applyDiff(undo.songs, true);
18186
19255
  this.state.revision = undo.beforeRevision;
18187
19256
  this.redoStack.push(undo);
18188
19257
  this.committedState = this.cloneState();
@@ -18196,6 +19265,7 @@ var pxt;
18196
19265
  this.state.images.applyDiff(redo.images);
18197
19266
  this.state.tilemaps.applyDiff(redo.tilemaps);
18198
19267
  this.state.animations.applyDiff(redo.animations);
19268
+ this.state.songs.applyDiff(redo.songs);
18199
19269
  this.state.revision = redo.afterRevision;
18200
19270
  this.undoStack.push(redo);
18201
19271
  this.committedState = this.cloneState();
@@ -18212,7 +19282,8 @@ var pxt;
18212
19282
  tiles: this.state.tiles.diff(this.committedState.tiles),
18213
19283
  images: this.state.images.diff(this.committedState.images),
18214
19284
  tilemaps: this.state.tilemaps.diff(this.committedState.tilemaps),
18215
- animations: this.state.animations.diff(this.committedState.animations)
19285
+ animations: this.state.animations.diff(this.committedState.animations),
19286
+ songs: this.state.songs.diff(this.committedState.songs)
18216
19287
  });
18217
19288
  this.committedState = this.cloneState();
18218
19289
  this.cleanupTemporaryAssets();
@@ -18242,16 +19313,8 @@ var pxt;
18242
19313
  }
18243
19314
  isNameTaken(assetType, name) {
18244
19315
  const isTaken = (id) => {
18245
- switch (assetType) {
18246
- case "image" /* AssetType.Image */:
18247
- return this.state.images.isIDTaken(id) || this.gallery.images.isIDTaken(id);
18248
- case "tile" /* AssetType.Tile */:
18249
- return this.state.tiles.isIDTaken(id) || this.gallery.tiles.isIDTaken(id);
18250
- case "tilemap" /* AssetType.Tilemap */:
18251
- return this.state.tilemaps.isIDTaken(id) || this.gallery.tilemaps.isIDTaken(id);
18252
- case "animation" /* AssetType.Animation */:
18253
- return this.state.animations.isIDTaken(id) || this.gallery.animations.isIDTaken(id);
18254
- }
19316
+ return getAssetCollection(this.state, assetType).isIDTaken(id) ||
19317
+ getAssetCollection(this.gallery, assetType).isIDTaken(id);
18255
19318
  };
18256
19319
  const shortId = getShortIDCore(assetType, name);
18257
19320
  const checkShortId = shortId && shortId !== name;
@@ -18277,6 +19340,10 @@ var pxt;
18277
19340
  * assets.animation`shortId`
18278
19341
  * assets.animation`displayName`
18279
19342
  *
19343
+ * SONGS:
19344
+ * assets.song`shortId`
19345
+ * assets.song`displayName`
19346
+ *
18280
19347
  * TILEMAPS:
18281
19348
  * tilemap`shortId`
18282
19349
  *
@@ -18315,6 +19382,11 @@ var pxt;
18315
19382
  if (displayName)
18316
19383
  assetTsRefs += `|assets.animation\`${displayName}\``;
18317
19384
  break;
19385
+ case "song" /* pxt.AssetType.Song */:
19386
+ assetTsRefs = `assets.song\`${shortId}\``;
19387
+ if (displayName)
19388
+ assetTsRefs += `|assets.song\`${displayName}\``;
19389
+ break;
18318
19390
  default:
18319
19391
  assetTsRefs = `assets.image\`${shortId}\``;
18320
19392
  if (displayName)
@@ -18337,6 +19409,11 @@ var pxt;
18337
19409
  if (displayName)
18338
19410
  assetPyRefs += `|assets.animation\("""${displayName}"""\)`;
18339
19411
  break;
19412
+ case "song" /* pxt.AssetType.Song */:
19413
+ assetPyRefs = `assets.song\("""${shortId}"""\)`;
19414
+ if (displayName)
19415
+ assetPyRefs += `|assets.song\("""${displayName}"""\)`;
19416
+ break;
18340
19417
  default:
18341
19418
  assetPyRefs = `assets.image\("""${shortId}"""\)`;
18342
19419
  if (displayName)
@@ -18362,65 +19439,29 @@ var pxt;
18362
19439
  return false;
18363
19440
  }
18364
19441
  lookupAsset(assetType, name) {
18365
- switch (assetType) {
18366
- case "image" /* AssetType.Image */:
18367
- return this.state.images.getByID(name) || this.gallery.images.getByID(name);
18368
- case "tile" /* AssetType.Tile */:
18369
- return this.state.tiles.getByID(name) || this.gallery.tiles.getByID(name);
18370
- case "tilemap" /* AssetType.Tilemap */:
18371
- return this.state.tilemaps.getByID(name) || this.gallery.tilemaps.getByID(name);
18372
- case "animation" /* AssetType.Animation */:
18373
- return this.state.animations.getByID(name) || this.gallery.animations.getByID(name);
18374
- }
19442
+ return getAssetCollection(this.state, assetType).getByID(name) ||
19443
+ getAssetCollection(this.gallery, assetType).getByID(name);
18375
19444
  }
18376
19445
  lookupAssetByName(assetType, name) {
18377
- switch (assetType) {
18378
- case "image" /* AssetType.Image */:
18379
- return this.state.images.getByDisplayName(name);
18380
- case "tile" /* AssetType.Tile */:
18381
- return this.state.tiles.getByDisplayName(name);
18382
- case "tilemap" /* AssetType.Tilemap */:
18383
- return this.state.tilemaps.getByDisplayName(name);
18384
- case "animation" /* AssetType.Animation */:
18385
- return this.state.animations.getByDisplayName(name);
18386
- }
19446
+ return getAssetCollection(this.state, assetType).getByDisplayName(name);
18387
19447
  }
18388
19448
  getAssets(type) {
18389
- switch (type) {
18390
- case "image" /* AssetType.Image */: return this.state.images.getSnapshot();
18391
- case "tile" /* AssetType.Tile */: return this.state.tiles.getSnapshot();
18392
- case "tilemap" /* AssetType.Tilemap */: return this.state.tilemaps.getSnapshot();
18393
- case "animation" /* AssetType.Animation */: return this.state.animations.getSnapshot();
18394
- }
19449
+ return getAssetCollection(this.state, type).getSnapshot();
18395
19450
  }
18396
19451
  getGalleryAssets(type) {
18397
- switch (type) {
18398
- case "image" /* AssetType.Image */: return this.gallery.images.getSnapshot();
18399
- case "tile" /* AssetType.Tile */: return this.gallery.tiles.getSnapshot();
18400
- case "tilemap" /* AssetType.Tilemap */: return this.gallery.tilemaps.getSnapshot();
18401
- case "animation" /* AssetType.Animation */: return this.gallery.animations.getSnapshot();
18402
- }
19452
+ return getAssetCollection(this.gallery, type).getSnapshot();
18403
19453
  }
18404
19454
  lookupBlockAsset(type, blockID) {
18405
19455
  let filter = (a) => { var _a, _b; return ((_b = (_a = a.meta) === null || _a === void 0 ? void 0 : _a.blockIDs) === null || _b === void 0 ? void 0 : _b.indexOf(blockID)) !== -1; };
18406
- switch (type) {
18407
- case "image" /* AssetType.Image */: return this.state.images.getSnapshot(filter)[0];
18408
- case "tile" /* AssetType.Tile */: return this.state.tiles.getSnapshot(filter)[0];
18409
- case "tilemap" /* AssetType.Tilemap */: return this.state.tilemaps.getSnapshot(filter)[0];
18410
- case "animation" /* AssetType.Animation */: return this.state.animations.getSnapshot(filter)[0];
18411
- }
19456
+ return getAssetCollection(this.state, type).getSnapshot(filter)[0];
18412
19457
  }
18413
19458
  updateAsset(asset) {
18414
19459
  this.onChange();
18415
19460
  switch (asset.type) {
18416
- case "image" /* AssetType.Image */:
18417
- return this.state.images.update(asset.id, asset);
18418
19461
  case "tile" /* AssetType.Tile */:
18419
19462
  return this.updateTile(asset);
18420
- case "tilemap" /* AssetType.Tilemap */:
18421
- return this.state.tilemaps.update(asset.id, asset);
18422
- case "animation" /* AssetType.Animation */:
18423
- return this.state.animations.update(asset.id, asset);
19463
+ default:
19464
+ return getAssetCollection(this.state, asset.type).update(asset.id, asset);
18424
19465
  }
18425
19466
  }
18426
19467
  duplicateAsset(asset, displayName) {
@@ -18442,53 +19483,22 @@ var pxt;
18442
19483
  break;
18443
19484
  case "animation" /* AssetType.Animation */:
18444
19485
  newAsset = this.createNewAnimationFromData(clone.frames, clone.interval, name);
19486
+ break;
19487
+ case "song" /* AssetType.Song */:
19488
+ newAsset = this.createNewSong(asset.song, name);
19489
+ break;
18445
19490
  }
18446
19491
  return newAsset;
18447
19492
  }
18448
19493
  removeAsset(asset) {
18449
19494
  this.onChange();
18450
- switch (asset.type) {
18451
- case "image" /* AssetType.Image */:
18452
- return this.state.images.removeByID(asset.id);
18453
- case "tile" /* AssetType.Tile */:
18454
- return this.state.tiles.removeByID(asset.id);
18455
- case "tilemap" /* AssetType.Tilemap */:
18456
- return this.state.tilemaps.removeByID(asset.id);
18457
- case "animation" /* AssetType.Animation */:
18458
- return this.state.animations.removeByID(asset.id);
18459
- }
19495
+ getAssetCollection(this.state, asset.type).removeByID(asset.id);
18460
19496
  }
18461
19497
  addChangeListener(asset, listener) {
18462
- switch (asset.type) {
18463
- case "image" /* AssetType.Image */:
18464
- this.state.images.addListener(asset.internalID, listener);
18465
- break;
18466
- case "tile" /* AssetType.Tile */:
18467
- this.state.tiles.addListener(asset.internalID, listener);
18468
- break;
18469
- case "tilemap" /* AssetType.Tilemap */:
18470
- this.state.tilemaps.addListener(asset.internalID, listener);
18471
- break;
18472
- case "animation" /* AssetType.Animation */:
18473
- this.state.animations.addListener(asset.internalID, listener);
18474
- break;
18475
- }
19498
+ getAssetCollection(this.state, asset.type).addListener(asset.internalID, listener);
18476
19499
  }
18477
19500
  removeChangeListener(type, listener) {
18478
- switch (type) {
18479
- case "image" /* AssetType.Image */:
18480
- this.state.images.removeListener(listener);
18481
- break;
18482
- case "tile" /* AssetType.Tile */:
18483
- this.state.tiles.removeListener(listener);
18484
- break;
18485
- case "tilemap" /* AssetType.Tilemap */:
18486
- this.state.tilemaps.removeListener(listener);
18487
- break;
18488
- case "animation" /* AssetType.Animation */:
18489
- this.state.animations.removeListener(listener);
18490
- break;
18491
- }
19501
+ getAssetCollection(this.state, type).removeListener(listener);
18492
19502
  }
18493
19503
  loadPackage(pack) {
18494
19504
  const allPackages = pack.sortedDeps();
@@ -18513,7 +19523,7 @@ var pxt;
18513
19523
  this.gallery.images.add(image);
18514
19524
  }
18515
19525
  }
18516
- else {
19526
+ else if (image.type === "animation" /* AssetType.Animation */) {
18517
19527
  if (isProject) {
18518
19528
  this.state.animations.add(image);
18519
19529
  }
@@ -18521,6 +19531,14 @@ var pxt;
18521
19531
  this.gallery.animations.add(image);
18522
19532
  }
18523
19533
  }
19534
+ else {
19535
+ if (isProject) {
19536
+ this.state.songs.add(image);
19537
+ }
19538
+ else {
19539
+ this.gallery.songs.add(image);
19540
+ }
19541
+ }
18524
19542
  }
18525
19543
  }
18526
19544
  for (const tm of getTilemaps(pack.parseJRes())) {
@@ -18597,6 +19615,9 @@ var pxt;
18597
19615
  this.state.animations.add(animation);
18598
19616
  }
18599
19617
  }
19618
+ else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
19619
+ this.state.songs.add(this.generateSong(entry));
19620
+ }
18600
19621
  }
18601
19622
  for (const animation of toInflate) {
18602
19623
  this.state.animations.add(this.inflateAnimation(animation, this.state.images.getSnapshot()));
@@ -18607,6 +19628,7 @@ var pxt;
18607
19628
  cleanupCollection(this.state.tiles);
18608
19629
  cleanupCollection(this.state.tilemaps);
18609
19630
  cleanupCollection(this.state.animations);
19631
+ cleanupCollection(this.state.songs);
18610
19632
  function cleanupCollection(collection) {
18611
19633
  const inactiveAssets = collection.getSnapshot(asset => { var _a; return !asset.meta.displayName && ((_a = asset.meta.blockIDs) === null || _a === void 0 ? void 0 : _a.some(id => activeBlockIDs.indexOf(id) === -1)); });
18612
19634
  const toRemove = [];
@@ -18636,6 +19658,17 @@ var pxt;
18636
19658
  bitmap: pxt.sprite.getBitmapFromJResURL(`data:${pxt.IMAGE_MIME_TYPE};base64,${entry.data}`).data()
18637
19659
  };
18638
19660
  }
19661
+ generateSong(entry) {
19662
+ return {
19663
+ internalID: this.getNewInternalId(),
19664
+ type: "song" /* AssetType.Song */,
19665
+ id: entry.id,
19666
+ meta: {
19667
+ displayName: entry.displayName
19668
+ },
19669
+ song: pxt.assets.music.decodeSongFromHex(entry.data)
19670
+ };
19671
+ }
18639
19672
  generateAnimation(entry) {
18640
19673
  if (entry.dataEncoding === "json") {
18641
19674
  let data;
@@ -18689,6 +19722,8 @@ var pxt;
18689
19722
  return this.generateNewIDInternal("tile" /* AssetType.Tile */, pxt.sprite.TILE_PREFIX, pxt.sprite.TILE_NAMESPACE);
18690
19723
  case "tilemap" /* AssetType.Tilemap */:
18691
19724
  return this.generateNewIDInternal("tilemap" /* AssetType.Tilemap */, lf("level"));
19725
+ case "song" /* AssetType.Song */:
19726
+ return this.generateNewIDInternal("song" /* AssetType.Song */, pxt.sprite.SONG_PREFIX, pxt.sprite.SONG_NAMESPACE);
18692
19727
  }
18693
19728
  }
18694
19729
  generateNewIDInternal(type, varPrefix, namespaceString) {
@@ -18726,6 +19761,9 @@ var pxt;
18726
19761
  assets.push(animation);
18727
19762
  }
18728
19763
  }
19764
+ else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
19765
+ assets.push(this.generateSong(entry));
19766
+ }
18729
19767
  }
18730
19768
  for (const animation of toInflate) {
18731
19769
  assets.push(this.inflateAnimation(animation, assets));
@@ -18786,6 +19824,7 @@ var pxt;
18786
19824
  let out = "";
18787
19825
  const imageEntries = [];
18788
19826
  const animationEntries = [];
19827
+ const songEntries = [];
18789
19828
  for (const key of entries) {
18790
19829
  if (key === "*")
18791
19830
  continue;
@@ -18812,10 +19851,17 @@ var pxt;
18812
19851
  expression: `[${animation.frames.map(f => pxt.sprite.bitmapToImageLiteral(pxt.sprite.Bitmap.fromData(f), "typescript")).join(", ")}]`
18813
19852
  });
18814
19853
  }
19854
+ else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
19855
+ songEntries.push({
19856
+ keys: [getShortIDCore("song" /* AssetType.Song */, key, true), entry.displayName],
19857
+ expression: `hex\`${entry.data}\``
19858
+ });
19859
+ }
18815
19860
  }
18816
19861
  const warning = lf("Auto-generated code. Do not edit.");
18817
19862
  out += emitFactoryHelper("image", imageEntries);
18818
19863
  out += emitFactoryHelper("animation", animationEntries);
19864
+ out += emitFactoryHelper("song", songEntries);
18819
19865
  return `// ${warning}\nnamespace ${pxt.sprite.IMAGES_NAMESPACE} {\n${out}\n}\n// ${warning}\n`;
18820
19866
  }
18821
19867
  pxt.emitProjectImages = emitProjectImages;
@@ -18859,6 +19905,8 @@ var pxt;
18859
19905
  return Object.assign(Object.assign({}, asset), { frames: asset.frames.map(frame => cloneBitmap(frame)) });
18860
19906
  case "tilemap" /* AssetType.Tilemap */:
18861
19907
  return Object.assign(Object.assign({}, asset), { data: asset.data.cloneData() });
19908
+ case "song" /* AssetType.Song */:
19909
+ return Object.assign(Object.assign({}, asset), { song: pxt.assets.music.cloneSong(asset.song) });
18862
19910
  }
18863
19911
  }
18864
19912
  pxt.cloneAsset = cloneAsset;
@@ -18892,6 +19940,13 @@ var pxt;
18892
19940
  case "animation" /* AssetType.Animation */:
18893
19941
  allJRes[id] = serializeAnimation(asset);
18894
19942
  break;
19943
+ case "song" /* AssetType.Song */:
19944
+ allJRes[id] = {
19945
+ data: pxt.assets.music.encodeSongToHex(asset.song),
19946
+ mimeType: pxt.SONG_MIME_TYPE,
19947
+ displayName: asset.meta.displayName
19948
+ };
19949
+ break;
18895
19950
  }
18896
19951
  }
18897
19952
  function assetEquals(a, b) {
@@ -18911,6 +19966,8 @@ var pxt;
18911
19966
  return a.interval === bAnimation.interval && pxt.U.arrayEquals(a.frames, bAnimation.frames, pxt.sprite.bitmapEquals);
18912
19967
  case "tilemap" /* AssetType.Tilemap */:
18913
19968
  return a.data.equals(b.data);
19969
+ case "song" /* AssetType.Song */:
19970
+ return pxt.assets.music.songEquals(a.song, b.song);
18914
19971
  }
18915
19972
  }
18916
19973
  pxt.assetEquals = assetEquals;
@@ -18950,11 +20007,13 @@ var pxt;
18950
20007
  return `assets.animation${leftTick}${shortId}${rightTick}`;
18951
20008
  case "tilemap" /* AssetType.Tilemap */:
18952
20009
  return `tilemap${leftTick}${shortId}${rightTick}`;
20010
+ case "song" /* AssetType.Song */:
20011
+ return `assets.song${leftTick}${shortId}${rightTick}`;
18953
20012
  }
18954
20013
  }
18955
20014
  pxt.getTSReferenceForAsset = getTSReferenceForAsset;
18956
20015
  function parseAssetTSReference(ts) {
18957
- const match = /^\s*(?:(?:assets\s*\.\s*(image|tile|animation|tilemap))|(tilemap))\s*(?:`|\(""")([^`"]+)(?:`|"""\))\s*$/m.exec(ts);
20016
+ const match = /^\s*(?:(?:assets\s*\.\s*(image|tile|animation|tilemap|song))|(tilemap))\s*(?:`|\(""")([^`"]+)(?:`|"""\))\s*$/m.exec(ts);
18958
20017
  if (match) {
18959
20018
  const type = match[1] || match[2];
18960
20019
  const name = match[3].trim();
@@ -18978,6 +20037,8 @@ var pxt;
18978
20037
  return project.lookupAssetByName("tilemap" /* AssetType.Tilemap */, name) || project.lookupAsset("tilemap" /* AssetType.Tilemap */, name);
18979
20038
  case "animation":
18980
20039
  return project.lookupAssetByName("animation" /* AssetType.Animation */, name);
20040
+ case "song":
20041
+ return project.lookupAssetByName("song" /* AssetType.Song */, name);
18981
20042
  }
18982
20043
  }
18983
20044
  return undefined;
@@ -18993,6 +20054,8 @@ var pxt;
18993
20054
  return lf("level");
18994
20055
  case "animation" /* pxt.AssetType.Animation */:
18995
20056
  return lf("myAnim");
20057
+ case "song" /* pxt.AssetType.Song */:
20058
+ return lf("mySong");
18996
20059
  default:
18997
20060
  return lf("asset");
18998
20061
  }
@@ -19017,6 +20080,9 @@ var pxt;
19017
20080
  case "animation" /* AssetType.Animation */:
19018
20081
  prefix = pxt.sprite.ANIMATION_NAMESPACE + ".";
19019
20082
  break;
20083
+ case "song" /* AssetType.Song */:
20084
+ prefix = pxt.sprite.SONG_NAMESPACE + ".";
20085
+ break;
19020
20086
  }
19021
20087
  if (prefix) {
19022
20088
  if (id.startsWith(prefix)) {
@@ -19101,6 +20167,15 @@ var pxt;
19101
20167
  function read16Bit(buf, offset) {
19102
20168
  return buf[offset] | (buf[offset + 1] << 8);
19103
20169
  }
20170
+ function getAssetCollection(snapshot, type) {
20171
+ switch (type) {
20172
+ case "animation" /* AssetType.Animation */: return snapshot.animations;
20173
+ case "image" /* AssetType.Image */: return snapshot.images;
20174
+ case "tile" /* AssetType.Tile */: return snapshot.tiles;
20175
+ case "tilemap" /* AssetType.Tilemap */: return snapshot.tilemaps;
20176
+ case "song" /* AssetType.Song */: return snapshot.songs;
20177
+ }
20178
+ }
19104
20179
  })(pxt || (pxt = {}));
19105
20180
  var pxt;
19106
20181
  (function (pxt) {