pxt-core 8.4.1 → 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.
- package/built/backendutils.js +1 -0
- package/built/cli.js +83 -75
- package/built/pxt.js +1274 -179
- package/built/pxtblockly.js +323 -40
- package/built/pxtblocks.d.ts +30 -7
- package/built/pxtblocks.js +324 -41
- package/built/pxteditor.d.ts +2 -0
- package/built/pxtlib.d.ts +91 -5
- package/built/pxtlib.js +1183 -101
- package/built/pxtsim.js +8 -3
- package/built/server.js +4 -0
- package/built/target.js +1 -1
- package/built/web/main.js +1 -1
- package/built/web/multiplayer/css/main.2dd69ed8.css +4 -0
- package/built/web/multiplayer/js/main.f3b8f930.js +2 -0
- package/built/web/pxtapp.js +1 -1
- package/built/web/pxtasseteditor.js +1 -1
- package/built/web/pxtblockly.js +1 -1
- package/built/web/pxtblocks.js +1 -1
- package/built/web/pxtembed.js +2 -2
- package/built/web/pxtlib.js +1 -1
- package/built/web/pxtsim.js +1 -1
- package/built/web/pxtworker.js +2 -2
- package/built/web/react-common-authcode.css +4 -6993
- package/built/web/react-common-multiplayer.css +13 -0
- package/built/web/react-common-skillmap.css +1 -1
- package/built/web/rtlreact-common-authcode.css +13 -0
- package/built/web/rtlreact-common-multiplayer.css +13 -0
- package/built/web/rtlreact-common-skillmap.css +1 -1
- package/built/web/rtlsemantic.css +1 -1
- package/built/web/semantic.css +1 -1
- package/built/web/skillmap/js/main.a6cf40e1.chunk.js +1 -0
- package/common-docs/identity/sign-in.md +17 -3
- package/common-docs/static/music-editor/apple.png +0 -0
- package/common-docs/static/music-editor/burger.png +0 -0
- package/common-docs/static/music-editor/cake.png +0 -0
- package/common-docs/static/music-editor/car.png +0 -0
- package/common-docs/static/music-editor/cat.png +0 -0
- package/common-docs/static/music-editor/cherry.png +0 -0
- package/common-docs/static/music-editor/clam.png +0 -0
- package/common-docs/static/music-editor/computer.png +0 -0
- package/common-docs/static/music-editor/crab.png +0 -0
- package/common-docs/static/music-editor/dog.png +0 -0
- package/common-docs/static/music-editor/duck.png +0 -0
- package/common-docs/static/music-editor/egg.png +0 -0
- package/common-docs/static/music-editor/explosion.png +0 -0
- package/common-docs/static/music-editor/fish.png +0 -0
- package/common-docs/static/music-editor/ice-cream.png +0 -0
- package/common-docs/static/music-editor/lemon.png +0 -0
- package/common-docs/static/music-editor/metronomeWorker.js +35 -0
- package/common-docs/static/music-editor/snake.png +0 -0
- package/common-docs/static/music-editor/star.png +0 -0
- package/common-docs/static/music-editor/strawberry.png +0 -0
- package/common-docs/static/music-editor/taco.png +0 -0
- package/common-docs/static/music-editor/treble-clef.svg +1 -0
- package/localtypings/projectheader.d.ts +1 -0
- package/package.json +4 -2
- package/react-common/components/controls/Input.tsx +7 -3
- package/react-common/components/share/Share.tsx +6 -2
- package/react-common/components/share/ShareInfo.tsx +12 -3
- package/react-common/styles/controls/Button.less +9 -0
- package/react-common/styles/react-common-authcode-core.less +1 -1
- package/react-common/styles/react-common-authcode.less +1 -1
- package/react-common/styles/react-common-multiplayer-core.less +10 -0
- package/react-common/styles/react-common-multiplayer.less +12 -0
- package/theme/highcontrast.less +14 -0
- package/theme/music-editor/EditControls.less +22 -0
- package/theme/music-editor/MusicEditor.less +25 -0
- package/theme/music-editor/Note.less +16 -0
- package/theme/music-editor/NoteGroup.less +7 -0
- package/theme/music-editor/PlaybackControls.less +55 -0
- package/theme/music-editor/ScrollableWorkspace.less +3 -0
- package/theme/music-editor/Staff.less +31 -0
- package/theme/music-editor/Track.less +0 -0
- package/theme/music-editor/TrackSelector.less +48 -0
- package/theme/music-editor/Workspace.less +3 -0
- package/theme/pxt.less +1 -0
- package/theme/tutorial-sidebar.less +19 -3
- package/theme/tutorial.less +2 -2
- package/webapp/public/multiplayer.html +1 -1
- package/webapp/public/skillmap.html +1 -1
- package/built/web/skillmap/js/main.6fa0eaff.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);
|
|
@@ -7536,6 +7544,7 @@ var pxt;
|
|
|
7536
7544
|
.then(resp => handleResponseAsync(resp));
|
|
7537
7545
|
}
|
|
7538
7546
|
function handleResponseAsync(resp) {
|
|
7547
|
+
var _a, _b, _c;
|
|
7539
7548
|
const code = resp.statusCode;
|
|
7540
7549
|
const errorData = pxt.Util.jsonTryParse(resp.text) || {};
|
|
7541
7550
|
pxt.debug(`upload result: ${code}`);
|
|
@@ -7543,16 +7552,22 @@ var pxt;
|
|
|
7543
7552
|
pxt.log(`create new translation file: ${filename}`);
|
|
7544
7553
|
return uploadAsync("add-file", {});
|
|
7545
7554
|
}
|
|
7546
|
-
else if (code == 404 && errorData.error
|
|
7555
|
+
else if (code == 404 && ((_a = errorData.error) === null || _a === void 0 ? void 0 : _a.code) == 17) {
|
|
7547
7556
|
return createDirectoryAsync(branch, prj, key, filename.replace(/\/[^\/]+$/, ""), incr)
|
|
7548
7557
|
.then(() => startAsync());
|
|
7549
7558
|
}
|
|
7550
|
-
else if (!errorData.success && errorData.error
|
|
7559
|
+
else if (!errorData.success && ((_b = errorData.error) === null || _b === void 0 ? void 0 : _b.code) == 53) {
|
|
7551
7560
|
// file is being updated
|
|
7552
7561
|
pxt.log(`${filename} being updated, waiting 5s and retry...`);
|
|
7553
7562
|
return pxt.U.delay(5000) // wait 5s and try again
|
|
7554
7563
|
.then(() => uploadTranslationAsync(branch, prj, key, filename, data));
|
|
7555
7564
|
}
|
|
7565
|
+
else if (code == 429 && ((_c = errorData.error) === null || _c === void 0 ? void 0 : _c.code) == 55) {
|
|
7566
|
+
// Too many concurrent requests
|
|
7567
|
+
pxt.log(`Maximum concurrent requests reached, waiting 10s and retry...`);
|
|
7568
|
+
return pxt.U.delay(10 * 1000) // wait 10s and try again
|
|
7569
|
+
.then(() => uploadTranslationAsync(branch, prj, key, filename, data));
|
|
7570
|
+
}
|
|
7556
7571
|
else if (code == 200 || errorData.success) {
|
|
7557
7572
|
// something crowdin reports 500 with success=true
|
|
7558
7573
|
return Promise.resolve();
|
|
@@ -8735,6 +8750,7 @@ var pxt;
|
|
|
8735
8750
|
const url = new URL(`https://${endpointName}.streaming.media.azure.net/${videoID}/manifest(format=mpd-time-csf).mpd`);
|
|
8736
8751
|
if (startTime) {
|
|
8737
8752
|
url.hash = `t=${startTime}`;
|
|
8753
|
+
url.searchParams.append("startTime", startTime);
|
|
8738
8754
|
}
|
|
8739
8755
|
if (endTime) {
|
|
8740
8756
|
url.searchParams.append("endTime", endTime);
|
|
@@ -12626,6 +12642,8 @@ var pxt;
|
|
|
12626
12642
|
sprite_1.IMAGE_PREFIX = "image";
|
|
12627
12643
|
sprite_1.ANIMATION_NAMESPACE = "myAnimations";
|
|
12628
12644
|
sprite_1.ANIMATION_PREFIX = "anim";
|
|
12645
|
+
sprite_1.SONG_NAMESPACE = "mySongs";
|
|
12646
|
+
sprite_1.SONG_PREFIX = "song";
|
|
12629
12647
|
/**
|
|
12630
12648
|
* 16-color sprite
|
|
12631
12649
|
*/
|
|
@@ -13681,6 +13699,1044 @@ var pxt;
|
|
|
13681
13699
|
})(shared = storage.shared || (storage.shared = {}));
|
|
13682
13700
|
})(storage = pxt.storage || (pxt.storage = {}));
|
|
13683
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 = {}));
|
|
13684
14740
|
/// <reference path="../localtypings/pxtpackage.d.ts"/>
|
|
13685
14741
|
/// <reference path="../localtypings/pxtparts.d.ts"/>
|
|
13686
14742
|
/// <reference path="../localtypings/pxtarget.d.ts"/>
|
|
@@ -17745,6 +18801,7 @@ var pxt;
|
|
|
17745
18801
|
pxt.IMAGE_MIME_TYPE = "image/x-mkcd-f4";
|
|
17746
18802
|
pxt.TILEMAP_MIME_TYPE = "application/mkcd-tilemap";
|
|
17747
18803
|
pxt.ANIMATION_MIME_TYPE = "application/mkcd-animation";
|
|
18804
|
+
pxt.SONG_MIME_TYPE = "application/mkcd-song";
|
|
17748
18805
|
class AssetCollection {
|
|
17749
18806
|
constructor() {
|
|
17750
18807
|
this.assets = [];
|
|
@@ -17931,21 +18988,24 @@ var pxt;
|
|
|
17931
18988
|
tilemaps: new AssetCollection(),
|
|
17932
18989
|
tiles: new AssetCollection(),
|
|
17933
18990
|
animations: new AssetCollection(),
|
|
17934
|
-
images: new AssetCollection()
|
|
18991
|
+
images: new AssetCollection(),
|
|
18992
|
+
songs: new AssetCollection(),
|
|
17935
18993
|
};
|
|
17936
18994
|
this.state = {
|
|
17937
18995
|
revision: this.nextID++,
|
|
17938
18996
|
tilemaps: new AssetCollection(),
|
|
17939
18997
|
tiles: new AssetCollection(),
|
|
17940
18998
|
animations: new AssetCollection(),
|
|
17941
|
-
images: new AssetCollection()
|
|
18999
|
+
images: new AssetCollection(),
|
|
19000
|
+
songs: new AssetCollection(),
|
|
17942
19001
|
};
|
|
17943
19002
|
this.gallery = {
|
|
17944
19003
|
revision: 0,
|
|
17945
19004
|
tilemaps: new AssetCollection(),
|
|
17946
19005
|
tiles: new AssetCollection(),
|
|
17947
19006
|
animations: new AssetCollection(),
|
|
17948
|
-
images: new AssetCollection()
|
|
19007
|
+
images: new AssetCollection(),
|
|
19008
|
+
songs: new AssetCollection(),
|
|
17949
19009
|
};
|
|
17950
19010
|
this.undoStack = [];
|
|
17951
19011
|
this.redoStack = [];
|
|
@@ -18047,6 +19107,19 @@ var pxt;
|
|
|
18047
19107
|
};
|
|
18048
19108
|
return this.state.images.add(newImage);
|
|
18049
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
|
+
}
|
|
18050
19123
|
updateTile(tile) {
|
|
18051
19124
|
this.onChange();
|
|
18052
19125
|
const existing = this.resolveProjectTileByInternalID(tile.internalID);
|
|
@@ -18083,6 +19156,7 @@ var pxt;
|
|
|
18083
19156
|
const blob = {};
|
|
18084
19157
|
this.state.images.serializeToJRes(blob);
|
|
18085
19158
|
this.state.animations.serializeToJRes(blob);
|
|
19159
|
+
this.state.songs.serializeToJRes(blob);
|
|
18086
19160
|
blob["*"] = {
|
|
18087
19161
|
"mimeType": "image/x-mkcd-f4",
|
|
18088
19162
|
"dataEncoding": "base64",
|
|
@@ -18164,6 +19238,7 @@ var pxt;
|
|
|
18164
19238
|
tilemaps: this.state.tilemaps.clone(),
|
|
18165
19239
|
animations: this.state.animations.clone(),
|
|
18166
19240
|
tiles: this.state.tiles.clone(),
|
|
19241
|
+
songs: this.state.songs.clone(),
|
|
18167
19242
|
};
|
|
18168
19243
|
}
|
|
18169
19244
|
undo() {
|
|
@@ -18176,6 +19251,7 @@ var pxt;
|
|
|
18176
19251
|
this.state.images.applyDiff(undo.images, true);
|
|
18177
19252
|
this.state.tilemaps.applyDiff(undo.tilemaps, true);
|
|
18178
19253
|
this.state.animations.applyDiff(undo.animations, true);
|
|
19254
|
+
this.state.songs.applyDiff(undo.songs, true);
|
|
18179
19255
|
this.state.revision = undo.beforeRevision;
|
|
18180
19256
|
this.redoStack.push(undo);
|
|
18181
19257
|
this.committedState = this.cloneState();
|
|
@@ -18189,6 +19265,7 @@ var pxt;
|
|
|
18189
19265
|
this.state.images.applyDiff(redo.images);
|
|
18190
19266
|
this.state.tilemaps.applyDiff(redo.tilemaps);
|
|
18191
19267
|
this.state.animations.applyDiff(redo.animations);
|
|
19268
|
+
this.state.songs.applyDiff(redo.songs);
|
|
18192
19269
|
this.state.revision = redo.afterRevision;
|
|
18193
19270
|
this.undoStack.push(redo);
|
|
18194
19271
|
this.committedState = this.cloneState();
|
|
@@ -18205,7 +19282,8 @@ var pxt;
|
|
|
18205
19282
|
tiles: this.state.tiles.diff(this.committedState.tiles),
|
|
18206
19283
|
images: this.state.images.diff(this.committedState.images),
|
|
18207
19284
|
tilemaps: this.state.tilemaps.diff(this.committedState.tilemaps),
|
|
18208
|
-
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)
|
|
18209
19287
|
});
|
|
18210
19288
|
this.committedState = this.cloneState();
|
|
18211
19289
|
this.cleanupTemporaryAssets();
|
|
@@ -18235,16 +19313,8 @@ var pxt;
|
|
|
18235
19313
|
}
|
|
18236
19314
|
isNameTaken(assetType, name) {
|
|
18237
19315
|
const isTaken = (id) => {
|
|
18238
|
-
|
|
18239
|
-
|
|
18240
|
-
return this.state.images.isIDTaken(id) || this.gallery.images.isIDTaken(id);
|
|
18241
|
-
case "tile" /* AssetType.Tile */:
|
|
18242
|
-
return this.state.tiles.isIDTaken(id) || this.gallery.tiles.isIDTaken(id);
|
|
18243
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
18244
|
-
return this.state.tilemaps.isIDTaken(id) || this.gallery.tilemaps.isIDTaken(id);
|
|
18245
|
-
case "animation" /* AssetType.Animation */:
|
|
18246
|
-
return this.state.animations.isIDTaken(id) || this.gallery.animations.isIDTaken(id);
|
|
18247
|
-
}
|
|
19316
|
+
return getAssetCollection(this.state, assetType).isIDTaken(id) ||
|
|
19317
|
+
getAssetCollection(this.gallery, assetType).isIDTaken(id);
|
|
18248
19318
|
};
|
|
18249
19319
|
const shortId = getShortIDCore(assetType, name);
|
|
18250
19320
|
const checkShortId = shortId && shortId !== name;
|
|
@@ -18270,6 +19340,10 @@ var pxt;
|
|
|
18270
19340
|
* assets.animation`shortId`
|
|
18271
19341
|
* assets.animation`displayName`
|
|
18272
19342
|
*
|
|
19343
|
+
* SONGS:
|
|
19344
|
+
* assets.song`shortId`
|
|
19345
|
+
* assets.song`displayName`
|
|
19346
|
+
*
|
|
18273
19347
|
* TILEMAPS:
|
|
18274
19348
|
* tilemap`shortId`
|
|
18275
19349
|
*
|
|
@@ -18308,6 +19382,11 @@ var pxt;
|
|
|
18308
19382
|
if (displayName)
|
|
18309
19383
|
assetTsRefs += `|assets.animation\`${displayName}\``;
|
|
18310
19384
|
break;
|
|
19385
|
+
case "song" /* pxt.AssetType.Song */:
|
|
19386
|
+
assetTsRefs = `assets.song\`${shortId}\``;
|
|
19387
|
+
if (displayName)
|
|
19388
|
+
assetTsRefs += `|assets.song\`${displayName}\``;
|
|
19389
|
+
break;
|
|
18311
19390
|
default:
|
|
18312
19391
|
assetTsRefs = `assets.image\`${shortId}\``;
|
|
18313
19392
|
if (displayName)
|
|
@@ -18330,6 +19409,11 @@ var pxt;
|
|
|
18330
19409
|
if (displayName)
|
|
18331
19410
|
assetPyRefs += `|assets.animation\("""${displayName}"""\)`;
|
|
18332
19411
|
break;
|
|
19412
|
+
case "song" /* pxt.AssetType.Song */:
|
|
19413
|
+
assetPyRefs = `assets.song\("""${shortId}"""\)`;
|
|
19414
|
+
if (displayName)
|
|
19415
|
+
assetPyRefs += `|assets.song\("""${displayName}"""\)`;
|
|
19416
|
+
break;
|
|
18333
19417
|
default:
|
|
18334
19418
|
assetPyRefs = `assets.image\("""${shortId}"""\)`;
|
|
18335
19419
|
if (displayName)
|
|
@@ -18355,65 +19439,29 @@ var pxt;
|
|
|
18355
19439
|
return false;
|
|
18356
19440
|
}
|
|
18357
19441
|
lookupAsset(assetType, name) {
|
|
18358
|
-
|
|
18359
|
-
|
|
18360
|
-
return this.state.images.getByID(name) || this.gallery.images.getByID(name);
|
|
18361
|
-
case "tile" /* AssetType.Tile */:
|
|
18362
|
-
return this.state.tiles.getByID(name) || this.gallery.tiles.getByID(name);
|
|
18363
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
18364
|
-
return this.state.tilemaps.getByID(name) || this.gallery.tilemaps.getByID(name);
|
|
18365
|
-
case "animation" /* AssetType.Animation */:
|
|
18366
|
-
return this.state.animations.getByID(name) || this.gallery.animations.getByID(name);
|
|
18367
|
-
}
|
|
19442
|
+
return getAssetCollection(this.state, assetType).getByID(name) ||
|
|
19443
|
+
getAssetCollection(this.gallery, assetType).getByID(name);
|
|
18368
19444
|
}
|
|
18369
19445
|
lookupAssetByName(assetType, name) {
|
|
18370
|
-
|
|
18371
|
-
case "image" /* AssetType.Image */:
|
|
18372
|
-
return this.state.images.getByDisplayName(name);
|
|
18373
|
-
case "tile" /* AssetType.Tile */:
|
|
18374
|
-
return this.state.tiles.getByDisplayName(name);
|
|
18375
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
18376
|
-
return this.state.tilemaps.getByDisplayName(name);
|
|
18377
|
-
case "animation" /* AssetType.Animation */:
|
|
18378
|
-
return this.state.animations.getByDisplayName(name);
|
|
18379
|
-
}
|
|
19446
|
+
return getAssetCollection(this.state, assetType).getByDisplayName(name);
|
|
18380
19447
|
}
|
|
18381
19448
|
getAssets(type) {
|
|
18382
|
-
|
|
18383
|
-
case "image" /* AssetType.Image */: return this.state.images.getSnapshot();
|
|
18384
|
-
case "tile" /* AssetType.Tile */: return this.state.tiles.getSnapshot();
|
|
18385
|
-
case "tilemap" /* AssetType.Tilemap */: return this.state.tilemaps.getSnapshot();
|
|
18386
|
-
case "animation" /* AssetType.Animation */: return this.state.animations.getSnapshot();
|
|
18387
|
-
}
|
|
19449
|
+
return getAssetCollection(this.state, type).getSnapshot();
|
|
18388
19450
|
}
|
|
18389
19451
|
getGalleryAssets(type) {
|
|
18390
|
-
|
|
18391
|
-
case "image" /* AssetType.Image */: return this.gallery.images.getSnapshot();
|
|
18392
|
-
case "tile" /* AssetType.Tile */: return this.gallery.tiles.getSnapshot();
|
|
18393
|
-
case "tilemap" /* AssetType.Tilemap */: return this.gallery.tilemaps.getSnapshot();
|
|
18394
|
-
case "animation" /* AssetType.Animation */: return this.gallery.animations.getSnapshot();
|
|
18395
|
-
}
|
|
19452
|
+
return getAssetCollection(this.gallery, type).getSnapshot();
|
|
18396
19453
|
}
|
|
18397
19454
|
lookupBlockAsset(type, blockID) {
|
|
18398
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; };
|
|
18399
|
-
|
|
18400
|
-
case "image" /* AssetType.Image */: return this.state.images.getSnapshot(filter)[0];
|
|
18401
|
-
case "tile" /* AssetType.Tile */: return this.state.tiles.getSnapshot(filter)[0];
|
|
18402
|
-
case "tilemap" /* AssetType.Tilemap */: return this.state.tilemaps.getSnapshot(filter)[0];
|
|
18403
|
-
case "animation" /* AssetType.Animation */: return this.state.animations.getSnapshot(filter)[0];
|
|
18404
|
-
}
|
|
19456
|
+
return getAssetCollection(this.state, type).getSnapshot(filter)[0];
|
|
18405
19457
|
}
|
|
18406
19458
|
updateAsset(asset) {
|
|
18407
19459
|
this.onChange();
|
|
18408
19460
|
switch (asset.type) {
|
|
18409
|
-
case "image" /* AssetType.Image */:
|
|
18410
|
-
return this.state.images.update(asset.id, asset);
|
|
18411
19461
|
case "tile" /* AssetType.Tile */:
|
|
18412
19462
|
return this.updateTile(asset);
|
|
18413
|
-
|
|
18414
|
-
return this.state.
|
|
18415
|
-
case "animation" /* AssetType.Animation */:
|
|
18416
|
-
return this.state.animations.update(asset.id, asset);
|
|
19463
|
+
default:
|
|
19464
|
+
return getAssetCollection(this.state, asset.type).update(asset.id, asset);
|
|
18417
19465
|
}
|
|
18418
19466
|
}
|
|
18419
19467
|
duplicateAsset(asset, displayName) {
|
|
@@ -18435,53 +19483,22 @@ var pxt;
|
|
|
18435
19483
|
break;
|
|
18436
19484
|
case "animation" /* AssetType.Animation */:
|
|
18437
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;
|
|
18438
19490
|
}
|
|
18439
19491
|
return newAsset;
|
|
18440
19492
|
}
|
|
18441
19493
|
removeAsset(asset) {
|
|
18442
19494
|
this.onChange();
|
|
18443
|
-
|
|
18444
|
-
case "image" /* AssetType.Image */:
|
|
18445
|
-
return this.state.images.removeByID(asset.id);
|
|
18446
|
-
case "tile" /* AssetType.Tile */:
|
|
18447
|
-
return this.state.tiles.removeByID(asset.id);
|
|
18448
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
18449
|
-
return this.state.tilemaps.removeByID(asset.id);
|
|
18450
|
-
case "animation" /* AssetType.Animation */:
|
|
18451
|
-
return this.state.animations.removeByID(asset.id);
|
|
18452
|
-
}
|
|
19495
|
+
getAssetCollection(this.state, asset.type).removeByID(asset.id);
|
|
18453
19496
|
}
|
|
18454
19497
|
addChangeListener(asset, listener) {
|
|
18455
|
-
|
|
18456
|
-
case "image" /* AssetType.Image */:
|
|
18457
|
-
this.state.images.addListener(asset.internalID, listener);
|
|
18458
|
-
break;
|
|
18459
|
-
case "tile" /* AssetType.Tile */:
|
|
18460
|
-
this.state.tiles.addListener(asset.internalID, listener);
|
|
18461
|
-
break;
|
|
18462
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
18463
|
-
this.state.tilemaps.addListener(asset.internalID, listener);
|
|
18464
|
-
break;
|
|
18465
|
-
case "animation" /* AssetType.Animation */:
|
|
18466
|
-
this.state.animations.addListener(asset.internalID, listener);
|
|
18467
|
-
break;
|
|
18468
|
-
}
|
|
19498
|
+
getAssetCollection(this.state, asset.type).addListener(asset.internalID, listener);
|
|
18469
19499
|
}
|
|
18470
19500
|
removeChangeListener(type, listener) {
|
|
18471
|
-
|
|
18472
|
-
case "image" /* AssetType.Image */:
|
|
18473
|
-
this.state.images.removeListener(listener);
|
|
18474
|
-
break;
|
|
18475
|
-
case "tile" /* AssetType.Tile */:
|
|
18476
|
-
this.state.tiles.removeListener(listener);
|
|
18477
|
-
break;
|
|
18478
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
18479
|
-
this.state.tilemaps.removeListener(listener);
|
|
18480
|
-
break;
|
|
18481
|
-
case "animation" /* AssetType.Animation */:
|
|
18482
|
-
this.state.animations.removeListener(listener);
|
|
18483
|
-
break;
|
|
18484
|
-
}
|
|
19501
|
+
getAssetCollection(this.state, type).removeListener(listener);
|
|
18485
19502
|
}
|
|
18486
19503
|
loadPackage(pack) {
|
|
18487
19504
|
const allPackages = pack.sortedDeps();
|
|
@@ -18506,7 +19523,7 @@ var pxt;
|
|
|
18506
19523
|
this.gallery.images.add(image);
|
|
18507
19524
|
}
|
|
18508
19525
|
}
|
|
18509
|
-
else {
|
|
19526
|
+
else if (image.type === "animation" /* AssetType.Animation */) {
|
|
18510
19527
|
if (isProject) {
|
|
18511
19528
|
this.state.animations.add(image);
|
|
18512
19529
|
}
|
|
@@ -18514,6 +19531,14 @@ var pxt;
|
|
|
18514
19531
|
this.gallery.animations.add(image);
|
|
18515
19532
|
}
|
|
18516
19533
|
}
|
|
19534
|
+
else {
|
|
19535
|
+
if (isProject) {
|
|
19536
|
+
this.state.songs.add(image);
|
|
19537
|
+
}
|
|
19538
|
+
else {
|
|
19539
|
+
this.gallery.songs.add(image);
|
|
19540
|
+
}
|
|
19541
|
+
}
|
|
18517
19542
|
}
|
|
18518
19543
|
}
|
|
18519
19544
|
for (const tm of getTilemaps(pack.parseJRes())) {
|
|
@@ -18590,6 +19615,9 @@ var pxt;
|
|
|
18590
19615
|
this.state.animations.add(animation);
|
|
18591
19616
|
}
|
|
18592
19617
|
}
|
|
19618
|
+
else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
|
|
19619
|
+
this.state.songs.add(this.generateSong(entry));
|
|
19620
|
+
}
|
|
18593
19621
|
}
|
|
18594
19622
|
for (const animation of toInflate) {
|
|
18595
19623
|
this.state.animations.add(this.inflateAnimation(animation, this.state.images.getSnapshot()));
|
|
@@ -18600,6 +19628,7 @@ var pxt;
|
|
|
18600
19628
|
cleanupCollection(this.state.tiles);
|
|
18601
19629
|
cleanupCollection(this.state.tilemaps);
|
|
18602
19630
|
cleanupCollection(this.state.animations);
|
|
19631
|
+
cleanupCollection(this.state.songs);
|
|
18603
19632
|
function cleanupCollection(collection) {
|
|
18604
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)); });
|
|
18605
19634
|
const toRemove = [];
|
|
@@ -18629,6 +19658,17 @@ var pxt;
|
|
|
18629
19658
|
bitmap: pxt.sprite.getBitmapFromJResURL(`data:${pxt.IMAGE_MIME_TYPE};base64,${entry.data}`).data()
|
|
18630
19659
|
};
|
|
18631
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
|
+
}
|
|
18632
19672
|
generateAnimation(entry) {
|
|
18633
19673
|
if (entry.dataEncoding === "json") {
|
|
18634
19674
|
let data;
|
|
@@ -18682,6 +19722,8 @@ var pxt;
|
|
|
18682
19722
|
return this.generateNewIDInternal("tile" /* AssetType.Tile */, pxt.sprite.TILE_PREFIX, pxt.sprite.TILE_NAMESPACE);
|
|
18683
19723
|
case "tilemap" /* AssetType.Tilemap */:
|
|
18684
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);
|
|
18685
19727
|
}
|
|
18686
19728
|
}
|
|
18687
19729
|
generateNewIDInternal(type, varPrefix, namespaceString) {
|
|
@@ -18719,6 +19761,9 @@ var pxt;
|
|
|
18719
19761
|
assets.push(animation);
|
|
18720
19762
|
}
|
|
18721
19763
|
}
|
|
19764
|
+
else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
|
|
19765
|
+
assets.push(this.generateSong(entry));
|
|
19766
|
+
}
|
|
18722
19767
|
}
|
|
18723
19768
|
for (const animation of toInflate) {
|
|
18724
19769
|
assets.push(this.inflateAnimation(animation, assets));
|
|
@@ -18779,6 +19824,7 @@ var pxt;
|
|
|
18779
19824
|
let out = "";
|
|
18780
19825
|
const imageEntries = [];
|
|
18781
19826
|
const animationEntries = [];
|
|
19827
|
+
const songEntries = [];
|
|
18782
19828
|
for (const key of entries) {
|
|
18783
19829
|
if (key === "*")
|
|
18784
19830
|
continue;
|
|
@@ -18805,10 +19851,17 @@ var pxt;
|
|
|
18805
19851
|
expression: `[${animation.frames.map(f => pxt.sprite.bitmapToImageLiteral(pxt.sprite.Bitmap.fromData(f), "typescript")).join(", ")}]`
|
|
18806
19852
|
});
|
|
18807
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
|
+
}
|
|
18808
19860
|
}
|
|
18809
19861
|
const warning = lf("Auto-generated code. Do not edit.");
|
|
18810
19862
|
out += emitFactoryHelper("image", imageEntries);
|
|
18811
19863
|
out += emitFactoryHelper("animation", animationEntries);
|
|
19864
|
+
out += emitFactoryHelper("song", songEntries);
|
|
18812
19865
|
return `// ${warning}\nnamespace ${pxt.sprite.IMAGES_NAMESPACE} {\n${out}\n}\n// ${warning}\n`;
|
|
18813
19866
|
}
|
|
18814
19867
|
pxt.emitProjectImages = emitProjectImages;
|
|
@@ -18852,6 +19905,8 @@ var pxt;
|
|
|
18852
19905
|
return Object.assign(Object.assign({}, asset), { frames: asset.frames.map(frame => cloneBitmap(frame)) });
|
|
18853
19906
|
case "tilemap" /* AssetType.Tilemap */:
|
|
18854
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) });
|
|
18855
19910
|
}
|
|
18856
19911
|
}
|
|
18857
19912
|
pxt.cloneAsset = cloneAsset;
|
|
@@ -18885,6 +19940,13 @@ var pxt;
|
|
|
18885
19940
|
case "animation" /* AssetType.Animation */:
|
|
18886
19941
|
allJRes[id] = serializeAnimation(asset);
|
|
18887
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;
|
|
18888
19950
|
}
|
|
18889
19951
|
}
|
|
18890
19952
|
function assetEquals(a, b) {
|
|
@@ -18904,6 +19966,8 @@ var pxt;
|
|
|
18904
19966
|
return a.interval === bAnimation.interval && pxt.U.arrayEquals(a.frames, bAnimation.frames, pxt.sprite.bitmapEquals);
|
|
18905
19967
|
case "tilemap" /* AssetType.Tilemap */:
|
|
18906
19968
|
return a.data.equals(b.data);
|
|
19969
|
+
case "song" /* AssetType.Song */:
|
|
19970
|
+
return pxt.assets.music.songEquals(a.song, b.song);
|
|
18907
19971
|
}
|
|
18908
19972
|
}
|
|
18909
19973
|
pxt.assetEquals = assetEquals;
|
|
@@ -18943,11 +20007,13 @@ var pxt;
|
|
|
18943
20007
|
return `assets.animation${leftTick}${shortId}${rightTick}`;
|
|
18944
20008
|
case "tilemap" /* AssetType.Tilemap */:
|
|
18945
20009
|
return `tilemap${leftTick}${shortId}${rightTick}`;
|
|
20010
|
+
case "song" /* AssetType.Song */:
|
|
20011
|
+
return `assets.song${leftTick}${shortId}${rightTick}`;
|
|
18946
20012
|
}
|
|
18947
20013
|
}
|
|
18948
20014
|
pxt.getTSReferenceForAsset = getTSReferenceForAsset;
|
|
18949
20015
|
function parseAssetTSReference(ts) {
|
|
18950
|
-
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);
|
|
18951
20017
|
if (match) {
|
|
18952
20018
|
const type = match[1] || match[2];
|
|
18953
20019
|
const name = match[3].trim();
|
|
@@ -18971,6 +20037,8 @@ var pxt;
|
|
|
18971
20037
|
return project.lookupAssetByName("tilemap" /* AssetType.Tilemap */, name) || project.lookupAsset("tilemap" /* AssetType.Tilemap */, name);
|
|
18972
20038
|
case "animation":
|
|
18973
20039
|
return project.lookupAssetByName("animation" /* AssetType.Animation */, name);
|
|
20040
|
+
case "song":
|
|
20041
|
+
return project.lookupAssetByName("song" /* AssetType.Song */, name);
|
|
18974
20042
|
}
|
|
18975
20043
|
}
|
|
18976
20044
|
return undefined;
|
|
@@ -18986,6 +20054,8 @@ var pxt;
|
|
|
18986
20054
|
return lf("level");
|
|
18987
20055
|
case "animation" /* pxt.AssetType.Animation */:
|
|
18988
20056
|
return lf("myAnim");
|
|
20057
|
+
case "song" /* pxt.AssetType.Song */:
|
|
20058
|
+
return lf("mySong");
|
|
18989
20059
|
default:
|
|
18990
20060
|
return lf("asset");
|
|
18991
20061
|
}
|
|
@@ -19010,6 +20080,9 @@ var pxt;
|
|
|
19010
20080
|
case "animation" /* AssetType.Animation */:
|
|
19011
20081
|
prefix = pxt.sprite.ANIMATION_NAMESPACE + ".";
|
|
19012
20082
|
break;
|
|
20083
|
+
case "song" /* AssetType.Song */:
|
|
20084
|
+
prefix = pxt.sprite.SONG_NAMESPACE + ".";
|
|
20085
|
+
break;
|
|
19013
20086
|
}
|
|
19014
20087
|
if (prefix) {
|
|
19015
20088
|
if (id.startsWith(prefix)) {
|
|
@@ -19094,6 +20167,15 @@ var pxt;
|
|
|
19094
20167
|
function read16Bit(buf, offset) {
|
|
19095
20168
|
return buf[offset] | (buf[offset + 1] << 8);
|
|
19096
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
|
+
}
|
|
19097
20179
|
})(pxt || (pxt = {}));
|
|
19098
20180
|
var pxt;
|
|
19099
20181
|
(function (pxt) {
|
|
@@ -23038,7 +24120,7 @@ var pxt;
|
|
|
23038
24120
|
return undefined;
|
|
23039
24121
|
if (scriptid[0] == "_" && scriptid.length == 13)
|
|
23040
24122
|
return scriptid;
|
|
23041
|
-
if (scriptid.length == 23 && /^[0-9\-]+$/.test(scriptid))
|
|
24123
|
+
if (scriptid.length == 23 && /^[0-9\-]+$/.test(scriptid) || scriptid.length == 24 && /^S[0-9\-]+$/.test(scriptid))
|
|
23042
24124
|
return scriptid;
|
|
23043
24125
|
return undefined;
|
|
23044
24126
|
}
|