Merge remote-tracking branch 'LLK/develop' into develop

# Conflicts:
#	src/index.js
#	src/sprites/clone.js
#	src/worker.js
This commit is contained in:
Eric Rosenbaum committed 2016-09-13 18:09:43 -04:00
1 parent d9a703b4ad
commit e19c1942c3
31 files changed
+7363 -5025

No files matched your search

+42
View File
@@ -0,0 +1,42 @@
<svg version="1.1" id="cat" x="0px" y="0px" width="95px" height="111px" viewBox="0 0 95 111" enable-background="new 0 0 95 111" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<g id="Layer_3">
<path fill="#FAA51D" stroke="#000000" d="M22.462,79.039c-2.415-0.451-5.304-1.309-7.742-3.503&#xD;&#xA;&#x9;&#x9;C9.268,70.629,7.526,62.535,3.672,64.622c-3.856,2.088-3.782,15.165,8.353,19.194c4.182,1.391,7.998,1.396,11.091,1.312&#xD;&#xA;&#x9;&#x9;c0.811-0.025,7.717-0.654,10.079-4.074c2.361-3.42,0.719-4.272-0.09-4.744C32.295,75.838,25.878,79.677,22.462,79.039z"/>
<path fill="#FFFFFF" d="M4.236,64.877c-1.989,0.613-3.075,4.998-2.076,8.484c0.998,3.49,2.634,5.022,3.863,6.398&#xD;&#xA;&#x9;&#x9;c1.528,1.038-0.72-2.402,1.361-4.15c2.075-1.744,5.733-0.914,5.733-0.914s-2.909-3.987-4.57-6.396&#xD;&#xA;&#x9;&#x9;C6.975,65.988,6.359,64.375,4.236,64.877z"/>
</g>
<g>
<path fill="#FAA51D" d="M38.217,86.756c0,0-8.832,6.2-17.071,8.412l0.086,0.215c1.247,1.824,5.87,7.497-0.334,9.496&#xD;&#xA;&#x9;&#x9;c-5.333,1.717-15.12-13.104-10.821-15.902c2.626-1.713,4.892-0.252,4.892-0.252s3.474-1.07,6.001-2.345&#xD;&#xA;&#x9;&#x9;c4.303-2.161,5.784-3.453,5.784-3.453s4.184-4.306,6.856-4.137C36.281,78.96,41.669,83.504,38.217,86.756z"/>
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M21.232,95.383c1.247,1.824,5.87,7.497-0.334,9.496&#xD;&#xA;&#x9;&#x9;c-5.333,1.717-15.329-13.344-11.03-16.145c2.626-1.713,5.101-0.01,5.101-0.01s3.474-1.072,6.001-2.348&#xD;&#xA;&#x9;&#x9;c4.303-2.161,5.784-3.453,5.784-3.453"/>
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M38.217,86.756c0,0-10.123,7.107-18.804,8.819"/>
</g>
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M52.169,74.885c0,0,1.235,0.165,4.744,3.676&#xD;&#xA;&#x9;c3.509,3.508,6.026,2.16,8.911,0.724c2.877-1.443,10.537-6.126,6.49-9.817c-4.049-3.688-6.207,1.146-9.715,2.405&#xD;&#xA;&#x9;c-3.512,1.26-5.061-2.487-6.858-4.287c-0.589-0.593-1.188-1.099-1.729-1.505c0,0-0.971-0.76-1.906,2.79&#xD;&#xA;&#x9;C51.172,72.412,50.162,73.415,52.169,74.885z"/>
<g id="Layer_2_1_">
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M46.753,82.012c1.188-0.912,2.397-2.402,3.951-4.713&#xD;&#xA;&#x9;&#x9;c1.296-1.927,2.7-5.578,2.7-5.578c0.875-2.521,1.934-6.576-1.902-7.296c-1.553-0.291-4.079-0.098-7.67-0.776&#xD;&#xA;&#x9;&#x9;c-3.593-0.681-6.798-2.522-9.517,2.233c-2.718,4.757-9.59,8.271-1.056,16.563c0,0,4.901,3.842,10.764,9.639&#xD;&#xA;&#x9;&#x9;c4.831,4.775,12.045,10.602,12.045,10.602s18.972,2.188,19.535-0.693c1.922-9.79-14.777-6.911-14.777-6.911&#xD;&#xA;&#x9;&#x9;s-4.605-3.933-6.725-5.794c-3.478-3.059-11.125-10.771-11.125-10.771"/>
<path fill="#FFFFFF" d="M51.253,75.434c0,0,2.47-2.66-2.469-5.317c-4.939-2.657-7.213-0.017-8.739,1.521&#xD;&#xA;&#x9;&#x9;c-2.644,2.655,3.443,6.611,3.443,6.611l3.176,3.204c0,0,1.738-1.647,2.499-2.979C50.036,77.26,51.253,75.434,51.253,75.434"/>
</g>
<g id="Layer_8"/>
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M29.926,73.218c0.749-0.571,2.889-2.202,4.854-3.657&#xD;&#xA;&#x9;c2.428-1.799,6.117-5.849,1.077-7.646c-5.04-1.801-7.507,1.604-11.519,4.946c-2.159,1.801-5.308,2.699-4.319,6.209&#xD;&#xA;&#x9;c0.993,3.511,4.862,13.408,11.789,10.17c6.929-3.239-1.799-9.18-3.06-11.157"/>
<g id="Layer_2">
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M52.709,14.156c-1.54-0.143-4.75-0.316-6.518-0.231&#xD;&#xA;&#x9;&#x9;c-4.728,0.225-9.224,1.928-9.224,1.928L23.949,7.357l2.235,18.906c0.646-0.782-10.555,12.804-3.479,24.224&#xD;&#xA;&#x9;&#x9;c7.08,11.426,22.233,16.518,40.988,12.792c18.755-3.729,23.229-14.531,21.986-20.246c-1.242-5.714-8.322-7.823-8.322-7.823&#xD;&#xA;&#x9;&#x9;s-0.09-4.48-3.328-9.97c-1.926-3.268-8.348-8.041-8.348-8.041L62.822,5.647l-7.452,7.204L52.709,14.156z"/>
<path fill="#FFFFFF" d="M76.42,35.066l-2.482-2.064l-9.115,2.661c0,0,0,3.419-4.367,4.367c-4.37,0.951-11.211-2.277-11.211-2.277&#xD;&#xA;&#x9;&#x9;L41.46,41.17c0,0-8.437,0.928-8.739,6.081C32.048,58.704,46.1,63.479,51.425,63.783c2.905,0.167,8.235-0.338,12.277-1.141&#xD;&#xA;&#x9;&#x9;c17.752-3.234,22.551-13.919,21.31-19.635c-1.242-5.714-7.978-7.196-7.978-7.196L76.42,35.066z"/>
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M10.673,46.155c0,0,4.107,0.374,5.974,0.268&#xD;&#xA;&#x9;&#x9;c1.865-0.107,5.492-0.587,5.492-0.587"/>
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M81.656,40.671c0,0,4.549-0.743,6.859-1.549&#xD;&#xA;&#x9;&#x9;c2.715-0.942,4.543-2.545,4.543-2.545"/>
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M22.337,41.909c0,0-2.384-1.777-6.117-3.43&#xD;&#xA;&#x9;&#x9;c-4.134-1.831-6.405-2.303-6.405-2.303"/>
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M82.117,46.622c0,0,2.726,1.104,5.533,1.385&#xD;&#xA;&#x9;&#x9;c2.77,0.276,4.646,0.11,4.646,0.11"/>
<path fill="none" stroke="#000000" stroke-linecap="round" stroke-miterlimit="10" d="M52.35,14.212&#xD;&#xA;&#x9;&#x9;c2.84,0.7,3.887,1.469,3.887,1.469"/>
<line fill="none" stroke="#000000" x1="33.898" y1="13.684" x2="39.956" y2="18.042"/>
</g>
<g id="Layer_5">
<path fill="#FFFFFF" stroke="#231F20" d="M71.84,25.366c2.924,4.479,3.033,9.591,0.242,11.415&#xD;&#xA;&#x9;&#x9;c-2.793,1.825-7.426-0.332-10.354-4.813c-2.933-4.48-3.037-9.589-0.244-11.415C64.275,18.73,68.913,20.884,71.84,25.366z"/>
<path fill="#231F20" d="M71.089,32.522c0,1.08-0.802,1.956-1.8,1.956c-0.993,0-1.803-0.877-1.803-1.956&#xD;&#xA;&#x9;&#x9;c0-1.08,0.81-1.958,1.803-1.958C70.287,30.564,71.089,31.442,71.089,32.522"/>
</g>
<g id="Layer_7">
<path fill="#FFFFFF" stroke="#231F20" d="M47.867,28.619c2.926,4.48,2.619,9.862-0.681,12.015&#xD;&#xA;&#x9;&#x9;c-3.302,2.159-8.351,0.272-11.276-4.208c-2.928-4.48-2.624-9.86,0.678-12.017C39.891,22.253,44.938,24.137,47.867,28.619z"/>
<path fill="#231F20" d="M46.079,34.507c0,1.081-0.803,1.957-1.801,1.957c-0.992,0-1.803-0.878-1.803-1.957&#xD;&#xA;&#x9;&#x9;c0-1.08,0.811-1.957,1.803-1.957C45.274,32.55,46.079,33.427,46.079,34.507"/>
</g>
<path fill="#5E4A42" stroke="#000000" d="M59.766,37.926c1.854,0,4.555-0.284,4.697,0.569c0.143,0.855-1.709,4.203-2.988,4.345&#xD;&#xA;&#x9;c-1.283,0.142-6.125-2.353-6.195-3.919C55.206,37.355,58.055,37.926,59.766,37.926z"/>
<g id="Layer_4">
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M46.774,45.235c0,0,10.347,3.054,14.217,3.897&#xD;&#xA;&#x9;&#x9;c3.868,0.842,10.851,1.684,10.851,1.684s-7.99,10.245-17.328,7.644C45.176,55.863,45.345,49.975,46.774,45.235z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

+18 -15
View File
@@ -10,18 +10,21 @@
<body>
<div id="vm-devtools">
<h2>Scratch VM Playground</h2>
<button id="greenflag">Green flag</button>
<button id="stopall">Stop</button>
<select id="selectedTarget" multiple></select>
<p>
<a id="renderexplorer-link" href="#">Renderer</a><br />
<a id="threadexplorer-link" href="#">VM Threads</a><br />
<a id="blockexplorer-link" href="#">VM Block Representation</a><br />
<a id="importexport-link" href="#">Import/Export</a>
</p>
<div id="projectButtons">
<button id="greenflag">Green flag</button>
<button id="stopall">Stop</button>
</div>
<br />
<ul id="playgroundLinks">
<li><a id="renderexplorer-link" href="#">Renderer</a></li>
<li><a id="threadexplorer-link" href="#">Threads</a></li>
<li><a id="blockexplorer-link" href="#">Block Representation</a></li>
<li><a id="importexport-link" href="#">Import/Export</a></li>
</ul><br />
<div id="tab-renderexplorer">
Render<br />
<canvas id="scratch-stage" style="width: 480px; height: 360px;"></canvas>
Renderer<br />
<canvas id="scratch-stage" style="width: 480px; height: 360px;"></canvas><br />
</div>
<div id="tab-threadexplorer">
Thread explorer
@@ -32,14 +35,14 @@
<pre id="blockexplorer"></pre>
</div>
<div id="tab-importexport">
Import/Export
<input id="projectId" value="119615668" />
<button id="projectLoadButton">Load SB2</button><br />
Import/Export<br />
Project ID: <input id="projectId" value="119615668" />
<button id="projectLoadButton">Load</button><br />
<p>
<input type="button" value="Export to XML" onclick="toXml()">
&nbsp;
<input type="button" value="Import from XML" onclick="fromXml()" id="import">
<br><br>
<br /><br />
<textarea id="importExport"></textarea>
</p>
</div>
@@ -751,7 +754,7 @@
<script src="../audioLocal.js"></script>
<script src="../Tone.min.js"></script>
<!-- VM Worker -->
<script src="../vm.worker.js"></script>
<script src="../vm.js"></script>
<!-- Playground -->
<script src="./playground.js"></script>
<script>
+31 -5
View File
@@ -4,6 +4,9 @@ body {
a {
color: rgb(217,217,217);
}
h2 {
font-size: 1em;
}
#blocks {
position: absolute;
left: 40%;
@@ -16,13 +19,12 @@ a {
position: absolute;
left: 1%;
right: 60%;
top: 0;
top: 1%;
bottom: 0;
width: 35%;
}
#blockexplorer, #threadexplorer, #importexport {
position: absolute;
width: 100%;
height: 75%;
overflow: scroll;
border: 1px solid #fff;
@@ -30,17 +32,41 @@ a {
color: rgb(217,217,217);
font-family: monospace;
font-size: 10pt;
width: 480px;
height: 360px;
}
#tab-blockexplorer, #tab-threadexplorer, #tab-importexport {
display: none;
}
#importExport {
width: 400px;
width: 480px;
height: 360px;
background: rgb(36,36,36);
color: rgb(217,217,217);
}
#projectId {
background: rgb(36,36,36);
color: rgb(217,217,217);
font-family: monospace;
font-size: 10pt;
}
ul#playgroundLinks {
display: block;
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
#playgroundLinks li {
float: left;
}
#playgroundLinks li a {
display: block;
color: white;
text-align: center;
padding: 5px 10px;
}
#playgroundLinks li a:hover {
background-color: #111;
}
+35 -9
View File
@@ -1,11 +1,20 @@
var loadProject = function () {
var id = location.hash.substring(1) || 119615668;
var id = location.hash.substring(1);
if (id.length < 1) {
id = '119615668';
}
var url = 'https://projects.scratch.mit.edu/internalapi/project/' +
id + '/get/';
var r = new XMLHttpRequest();
r.addEventListener('load', function() {
window.vm.loadProject(this.responseText);
});
r.onreadystatechange = function() {
if (this.readyState === 4) {
if (r.status === 200) {
window.vm.loadProject(this.responseText);
} else {
window.vm.createEmptyProject();
}
}
};
r.open('GET', url);
r.send();
};
@@ -26,7 +35,6 @@ window.onload = function() {
// Instantiate the renderer and connect it to the VM.
var canvas = document.getElementById('scratch-stage');
window.renderer = new window.RenderWebGLLocal(canvas);
window.renderer.connectWorker(window.vm.vmWorker);
// Instantiate audio engine and connect it to the VM
window.audioLocal = new window.AudioLocal();
@@ -156,17 +164,35 @@ window.onload = function() {
document.addEventListener('mousemove', function (e) {
var rect = canvas.getBoundingClientRect();
var coordinates = {
x: e.clientX - rect.left - rect.width / 2,
y: e.clientY - rect.top - rect.height / 2
x: e.clientX - rect.left,
y: e.clientY - rect.top,
canvasWidth: rect.width,
canvasHeight: rect.height
};
window.vm.postIOData('mouse', coordinates);
});
canvas.addEventListener('mousedown', function (e) {
window.vm.postIOData('mouse', {isDown: true});
var rect = canvas.getBoundingClientRect();
var data = {
isDown: true,
x: e.clientX - rect.left,
y: e.clientY - rect.top,
canvasWidth: rect.width,
canvasHeight: rect.height
};
window.vm.postIOData('mouse', data);
e.preventDefault();
});
canvas.addEventListener('mouseup', function (e) {
window.vm.postIOData('mouse', {isDown: false});
var rect = canvas.getBoundingClientRect();
var data = {
isDown: false,
x: e.clientX - rect.left,
y: e.clientY - rect.top,
canvasWidth: rect.width,
canvasHeight: rect.height
};
window.vm.postIOData('mouse', data);
e.preventDefault();
});
+11 -5
View File
@@ -1,3 +1,4 @@
var Cast = require('../util/cast');
var Promise = require('promise');
function Scratch3ControlBlocks(runtime) {
@@ -25,9 +26,10 @@ Scratch3ControlBlocks.prototype.getPrimitives = function() {
};
Scratch3ControlBlocks.prototype.repeat = function(args, util) {
var times = Math.floor(Cast.toNumber(args.TIMES));
// Initialize loop
if (util.stackFrame.loopCounter === undefined) {
util.stackFrame.loopCounter = parseInt(args.TIMES);
util.stackFrame.loopCounter = times;
}
// Only execute once per frame.
// When the branch finishes, `repeat` will be executed again and
@@ -47,13 +49,14 @@ Scratch3ControlBlocks.prototype.repeat = function(args, util) {
};
Scratch3ControlBlocks.prototype.repeatUntil = function(args, util) {
var condition = Cast.toBoolean(args.CONDITION);
// Only execute once per frame.
// When the branch finishes, `repeat` will be executed again and
// the second branch will be taken, yielding for the rest of the frame.
if (!util.stackFrame.executedInFrame) {
util.stackFrame.executedInFrame = true;
// If the condition is true, start the branch.
if (!args.CONDITION) {
if (!condition) {
util.startBranch();
}
} else {
@@ -76,30 +79,33 @@ Scratch3ControlBlocks.prototype.forever = function(args, util) {
};
Scratch3ControlBlocks.prototype.wait = function(args) {
var duration = Cast.toNumber(args.DURATION);
return new Promise(function(resolve) {
setTimeout(function() {
resolve();
}, 1000 * args.DURATION);
}, 1000 * duration);
});
};
Scratch3ControlBlocks.prototype.if = function(args, util) {
var condition = Cast.toBoolean(args.CONDITION);
// Only execute one time. `if` will be returned to
// when the branch finishes, but it shouldn't execute again.
if (util.stackFrame.executedInFrame === undefined) {
util.stackFrame.executedInFrame = true;
if (args.CONDITION) {
if (condition) {
util.startBranch();
}
}
};
Scratch3ControlBlocks.prototype.ifElse = function(args, util) {
var condition = Cast.toBoolean(args.CONDITION);
// Only execute one time. `ifElse` will be returned to
// when the branch finishes, but it shouldn't execute again.
if (util.stackFrame.executedInFrame === undefined) {
util.stackFrame.executedInFrame = true;
if (args.CONDITION) {
if (condition) {
util.startBranch(1);
} else {
util.startBranch(2);
+11 -6
View File
@@ -1,3 +1,5 @@
var Cast = require('../util/cast');
function Scratch3EventBlocks(runtime) {
/**
* The runtime instantiating this block package.
@@ -29,10 +31,9 @@ Scratch3EventBlocks.prototype.getHats = function () {
'event_whenthisspriteclicked': {
restartExistingThreads: true
},
/*
'event_whenbackdropswitchesto': {
restartExistingThreads: true
},*/
},
'event_whengreaterthan': {
restartExistingThreads: false,
edgeActivated: true
@@ -44,26 +45,30 @@ Scratch3EventBlocks.prototype.getHats = function () {
};
Scratch3EventBlocks.prototype.hatGreaterThanPredicate = function (args, util) {
var option = Cast.toString(args.WHENGREATERTHANMENU).toLowerCase();
var value = Cast.toNumber(args.VALUE);
// @todo: Other cases :)
if (args.WHENGREATERTHANMENU == 'TIMER') {
return util.ioQuery('clock', 'projectTimer') > args.VALUE;
if (option == 'timer') {
return util.ioQuery('clock', 'projectTimer') > value;
}
return false;
};
Scratch3EventBlocks.prototype.broadcast = function(args, util) {
var broadcastOption = Cast.toString(args.BROADCAST_OPTION);
util.startHats('event_whenbroadcastreceived', {
'BROADCAST_OPTION': args.BROADCAST_OPTION
'BROADCAST_OPTION': broadcastOption
});
};
Scratch3EventBlocks.prototype.broadcastAndWait = function (args, util) {
var broadcastOption = Cast.toString(args.BROADCAST_OPTION);
// Have we run before, starting threads?
if (!util.stackFrame.startedThreads) {
// No - start hats for this broadcast.
util.stackFrame.startedThreads = util.startHats(
'event_whenbroadcastreceived', {
'BROADCAST_OPTION': args.BROADCAST_OPTION
'BROADCAST_OPTION': broadcastOption
}
);
if (util.stackFrame.startedThreads.length == 0) {
+122 -9
View File
@@ -1,3 +1,5 @@
var Cast = require('../util/cast');
function Scratch3LooksBlocks(runtime) {
/**
* The runtime instantiating this block package.
@@ -18,13 +20,20 @@ Scratch3LooksBlocks.prototype.getPrimitives = function() {
'looks_thinkforsecs': this.sayforsecs,
'looks_show': this.show,
'looks_hide': this.hide,
'looks_effectmenu': this.effectMenu,
'looks_switchcostumeto': this.switchCostume,
'looks_switchbackdropto': this.switchBackdrop,
'looks_switchbackdroptoandwait': this.switchBackdropAndWait,
'looks_nextcostume': this.nextCostume,
'looks_nextbackdrop': this.nextBackdrop,
'looks_changeeffectby': this.changeEffect,
'looks_seteffectto': this.setEffect,
'looks_cleargraphiceffects': this.clearEffects,
'looks_changesizeby': this.changeSize,
'looks_setsizeto': this.setSize,
'looks_size': this.getSize
'looks_size': this.getSize,
'looks_costumeorder': this.getCostumeIndex,
'looks_backdroporder': this.getBackdropIndex,
'looks_backdropname': this.getBackdropName
};
};
@@ -66,17 +75,105 @@ Scratch3LooksBlocks.prototype.hide = function (args, util) {
util.target.setVisible(false);
};
Scratch3LooksBlocks.prototype.effectMenu = function (args) {
return args.EFFECT.toLowerCase();
/**
* Utility function to set the costume or backdrop of a target.
* Matches the behavior of Scratch 2.0 for different types of arguments.
* @param {!Target} target Target to set costume/backdrop to.
* @param {Any} requestedCostume Costume requested, e.g., 0, 'name', etc.
* @param {boolean=} opt_zeroIndex Set to zero-index the requestedCostume.
* @return {Array.<!Thread>} Any threads started by this switch.
*/
Scratch3LooksBlocks.prototype._setCostumeOrBackdrop = function (target,
requestedCostume, opt_zeroIndex) {
if (typeof requestedCostume === 'number') {
target.setCostume(opt_zeroIndex ?
requestedCostume : requestedCostume - 1);
} else {
var costumeIndex = target.getCostumeIndexByName(requestedCostume);
if (costumeIndex > -1) {
target.setCostume(costumeIndex);
} else if (costumeIndex == 'previous costume' ||
costumeIndex == 'previous backdrop') {
target.setCostume(target.currentCostume - 1);
} else if (costumeIndex == 'next costume' ||
costumeIndex == 'next backdrop') {
target.setCostume(target.currentCostume + 1);
} else {
var forcedNumber = Cast.toNumber(requestedCostume);
if (!isNaN(forcedNumber)) {
target.setCostume(opt_zeroIndex ?
forcedNumber : forcedNumber - 1);
}
}
}
if (target == this.runtime.getTargetForStage()) {
// Target is the stage - start hats.
var newName = target.sprite.costumes[target.currentCostume].name;
return this.runtime.startHats('event_whenbackdropswitchesto', {
'BACKDROP': newName
});
}
return [];
};
Scratch3LooksBlocks.prototype.switchCostume = function (args, util) {
this._setCostumeOrBackdrop(util.target, args.COSTUME);
};
Scratch3LooksBlocks.prototype.nextCostume = function (args, util) {
this._setCostumeOrBackdrop(
util.target, util.target.currentCostume + 1, true
);
};
Scratch3LooksBlocks.prototype.switchBackdrop = function (args) {
this._setCostumeOrBackdrop(this.runtime.getTargetForStage(), args.BACKDROP);
};
Scratch3LooksBlocks.prototype.switchBackdropAndWait = function (args, util) {
// Have we run before, starting threads?
if (!util.stackFrame.startedThreads) {
// No - switch the backdrop.
util.stackFrame.startedThreads = (
this._setCostumeOrBackdrop(
this.runtime.getTargetForStage(),
args.BACKDROP
)
);
if (util.stackFrame.startedThreads.length == 0) {
// Nothing was started.
return;
}
}
// We've run before; check if the wait is still going on.
var instance = this;
var waiting = util.stackFrame.startedThreads.some(function(thread) {
return instance.runtime.isActiveThread(thread);
});
if (waiting) {
util.yieldFrame();
}
};
Scratch3LooksBlocks.prototype.nextBackdrop = function () {
var stage = this.runtime.getTargetForStage();
this._setCostumeOrBackdrop(
stage, stage.currentCostume + 1, true
);
};
Scratch3LooksBlocks.prototype.changeEffect = function (args, util) {
var newValue = args.CHANGE + util.target.effects[args.EFFECT];
util.target.setEffect(args.EFFECT, newValue);
var effect = Cast.toString(args.EFFECT).toLowerCase();
var change = Cast.toNumber(args.CHANGE);
if (!util.target.effects.hasOwnProperty(effect)) return;
var newValue = change + util.target.effects[effect];
util.target.setEffect(effect, newValue);
};
Scratch3LooksBlocks.prototype.setEffect = function (args, util) {
util.target.setEffect(args.EFFECT, args.VALUE);
var effect = Cast.toString(args.EFFECT).toLowerCase();
var value = Cast.toNumber(args.VALUE);
util.target.setEffect(effect, value);
};
Scratch3LooksBlocks.prototype.clearEffects = function (args, util) {
@@ -84,15 +181,31 @@ Scratch3LooksBlocks.prototype.clearEffects = function (args, util) {
};
Scratch3LooksBlocks.prototype.changeSize = function (args, util) {
util.target.setSize(util.target.size + args.CHANGE);
var change = Cast.toNumber(args.CHANGE);
util.target.setSize(util.target.size + change);
};
Scratch3LooksBlocks.prototype.setSize = function (args, util) {
util.target.setSize(args.SIZE);
var size = Cast.toNumber(args.SIZE);
util.target.setSize(size);
};
Scratch3LooksBlocks.prototype.getSize = function (args, util) {
return util.target.size;
};
Scratch3LooksBlocks.prototype.getBackdropIndex = function () {
var stage = this.runtime.getTargetForStage();
return stage.currentCostume + 1;
};
Scratch3LooksBlocks.prototype.getBackdropName = function () {
var stage = this.runtime.getTargetForStage();
return stage.sprite.costumes[stage.currentCostume].name;
};
Scratch3LooksBlocks.prototype.getCostumeIndex = function (args, util) {
return util.target.currentCostume + 1;
};
module.exports = Scratch3LooksBlocks;
+58 -10
View File
@@ -1,4 +1,6 @@
var Cast = require('../util/cast');
var MathUtil = require('../util/math-util');
var Timer = require('../util/timer');
function Scratch3MotionBlocks(runtime) {
/**
@@ -19,6 +21,7 @@ Scratch3MotionBlocks.prototype.getPrimitives = function() {
'motion_turnright': this.turnRight,
'motion_turnleft': this.turnLeft,
'motion_pointindirection': this.pointInDirection,
'motion_glidesecstoxy': this.glide,
'motion_changexby': this.changeX,
'motion_setx': this.setX,
'motion_changeyby': this.changeY,
@@ -30,42 +33,87 @@ Scratch3MotionBlocks.prototype.getPrimitives = function() {
};
Scratch3MotionBlocks.prototype.moveSteps = function (args, util) {
var steps = Cast.toNumber(args.STEPS);
var radians = MathUtil.degToRad(util.target.direction);
var dx = args.STEPS * Math.cos(radians);
var dy = args.STEPS * Math.sin(radians);
var dx = steps * Math.cos(radians);
var dy = steps * Math.sin(radians);
util.target.setXY(util.target.x + dx, util.target.y + dy);
};
Scratch3MotionBlocks.prototype.goToXY = function (args, util) {
util.target.setXY(args.X, args.Y);
var x = Cast.toNumber(args.X);
var y = Cast.toNumber(args.Y);
util.target.setXY(x, y);
};
Scratch3MotionBlocks.prototype.turnRight = function (args, util) {
util.target.setDirection(util.target.direction + args.DEGREES);
var degrees = Cast.toNumber(args.DEGREES);
util.target.setDirection(util.target.direction + degrees);
};
Scratch3MotionBlocks.prototype.turnLeft = function (args, util) {
util.target.setDirection(util.target.direction - args.DEGREES);
var degrees = Cast.toNumber(args.DEGREES);
util.target.setDirection(util.target.direction - degrees);
};
Scratch3MotionBlocks.prototype.pointInDirection = function (args, util) {
util.target.setDirection(args.DIRECTION);
var direction = Cast.toNumber(args.DIRECTION);
util.target.setDirection(direction);
};
Scratch3MotionBlocks.prototype.glide = function (args, util) {
if (!util.stackFrame.timer) {
// First time: save data for future use.
util.stackFrame.timer = new Timer();
util.stackFrame.timer.start();
util.stackFrame.duration = Cast.toNumber(args.SECS);
util.stackFrame.startX = util.target.x;
util.stackFrame.startY = util.target.y;
util.stackFrame.endX = Cast.toNumber(args.X);
util.stackFrame.endY = Cast.toNumber(args.Y);
if (util.stackFrame.duration <= 0) {
// Duration too short to glide.
util.target.setXY(util.stackFrame.endX, util.stackFrame.endY);
return;
}
util.yieldFrame();
} else {
var timeElapsed = util.stackFrame.timer.timeElapsed();
if (timeElapsed < util.stackFrame.duration * 1000) {
// In progress: move to intermediate position.
var frac = timeElapsed / (util.stackFrame.duration * 1000);
var dx = frac * (util.stackFrame.endX - util.stackFrame.startX);
var dy = frac * (util.stackFrame.endY - util.stackFrame.startY);
util.target.setXY(
util.stackFrame.startX + dx,
util.stackFrame.startY + dy
);
util.yieldFrame();
} else {
// Finished: move to final position.
util.target.setXY(util.stackFrame.endX, util.stackFrame.endY);
}
}
};
Scratch3MotionBlocks.prototype.changeX = function (args, util) {
util.target.setXY(util.target.x + args.DX, util.target.y);
var dx = Cast.toNumber(args.DX);
util.target.setXY(util.target.x + dx, util.target.y);
};
Scratch3MotionBlocks.prototype.setX = function (args, util) {
util.target.setXY(args.X, util.target.y);
var x = Cast.toNumber(args.X);
util.target.setXY(x, util.target.y);
};
Scratch3MotionBlocks.prototype.changeY = function (args, util) {
util.target.setXY(util.target.x, util.target.y + args.DY);
var dy = Cast.toNumber(args.DY);
util.target.setXY(util.target.x, util.target.y + dy);
};
Scratch3MotionBlocks.prototype.setY = function (args, util) {
util.target.setXY(util.target.x, args.Y);
var y = Cast.toNumber(args.Y);
util.target.setXY(util.target.x, y);
};
Scratch3MotionBlocks.prototype.getX = function (args, util) {
+7 -23
View File
@@ -14,11 +14,6 @@ function Scratch3OperatorsBlocks(runtime) {
*/
Scratch3OperatorsBlocks.prototype.getPrimitives = function() {
return {
'math_number': this.number,
'math_positive_number': this.number,
'math_whole_number': this.number,
'math_angle': this.number,
'text': this.text,
'operator_add': this.add,
'operator_subtract': this.subtract,
'operator_multiply': this.multiply,
@@ -35,19 +30,10 @@ Scratch3OperatorsBlocks.prototype.getPrimitives = function() {
'operator_length': this.length,
'operator_mod': this.mod,
'operator_round': this.round,
'operator_mathop_menu': this.mathopMenu,
'operator_mathop': this.mathop
};
};
Scratch3OperatorsBlocks.prototype.number = function (args) {
return Cast.toNumber(args.NUM);
};
Scratch3OperatorsBlocks.prototype.text = function (args) {
return Cast.toString(args.TEXT);
};
Scratch3OperatorsBlocks.prototype.add = function (args) {
return Cast.toNumber(args.NUM1) + Cast.toNumber(args.NUM2);
};
@@ -77,20 +63,22 @@ Scratch3OperatorsBlocks.prototype.gt = function (args) {
};
Scratch3OperatorsBlocks.prototype.and = function (args) {
return Cast.toBoolean(args.OPERAND1 && args.OPERAND2);
return Cast.toBoolean(args.OPERAND1) && Cast.toBoolean(args.OPERAND2);
};
Scratch3OperatorsBlocks.prototype.or = function (args) {
return Cast.toBoolean(args.OPERAND1 || args.OPERAND2);
return Cast.toBoolean(args.OPERAND1) || Cast.toBoolean(args.OPERAND2);
};
Scratch3OperatorsBlocks.prototype.not = function (args) {
return Cast.toBoolean(!args.OPERAND);
return !Cast.toBoolean(args.OPERAND);
};
Scratch3OperatorsBlocks.prototype.random = function (args) {
var low = args.FROM <= args.TO ? args.FROM : args.TO;
var high = args.FROM <= args.TO ? args.TO : args.FROM;
var nFrom = Cast.toNumber(args.FROM);
var nTo = Cast.toNumber(args.TO);
var low = nFrom <= nTo ? nFrom : nTo;
var high = nFrom <= nTo ? nTo : nFrom;
if (low == high) return low;
// If both low and high are ints, truncate the result to an int.
var lowInt = low == parseInt(low);
@@ -132,10 +120,6 @@ Scratch3OperatorsBlocks.prototype.round = function (args) {
return Math.round(Cast.toNumber(args.NUM));
};
Scratch3OperatorsBlocks.prototype.mathopMenu = function (args) {
return args.OPERATOR;
};
Scratch3OperatorsBlocks.prototype.mathop = function (args) {
var operator = Cast.toString(args.OPERATOR).toLowerCase();
var n = Cast.toNumber(args.NUM);
+20 -13
View File
@@ -1,3 +1,5 @@
var Cast = require('../util/cast');
function Scratch3SensingBlocks(runtime) {
/**
* The runtime instantiating this block package.
@@ -12,18 +14,29 @@ function Scratch3SensingBlocks(runtime) {
*/
Scratch3SensingBlocks.prototype.getPrimitives = function() {
return {
'sensing_touchingcolor': this.touchingColor,
'sensing_coloristouchingcolor': this.colorTouchingColor,
'sensing_timer': this.getTimer,
'sensing_resettimer': this.resetTimer,
'sensing_mousex': this.getMouseX,
'sensing_mousey': this.getMouseY,
'sensing_mousedown': this.getMouseDown,
'sensing_keyoptions': this.keyOptions,
'sensing_keypressed': this.getKeyPressed,
'sensing_current': this.current,
'sensing_currentmenu': this.currentMenu
'sensing_current': this.current
};
};
Scratch3SensingBlocks.prototype.touchingColor = function (args, util) {
var color = Cast.toRgbColorList(args.COLOR);
return util.target.isTouchingColor(color);
};
Scratch3SensingBlocks.prototype.colorTouchingColor = function (args, util) {
var maskColor = Cast.toRgbColorList(args.COLOR);
var targetColor = Cast.toRgbColorList(args.COLOR2);
return util.target.colorIsTouchingColor(targetColor, maskColor);
};
Scratch3SensingBlocks.prototype.getTimer = function (args, util) {
return util.ioQuery('clock', 'projectTimer');
};
@@ -45,8 +58,9 @@ Scratch3SensingBlocks.prototype.getMouseDown = function (args, util) {
};
Scratch3SensingBlocks.prototype.current = function (args) {
var menuOption = Cast.toString(args.CURRENTMENU).toLowerCase();
var date = new Date();
switch (args.CURRENTMENU) {
switch (menuOption) {
case 'year': return date.getFullYear();
case 'month': return date.getMonth() + 1; // getMonth is zero-based
case 'date': return date.getDate();
@@ -55,18 +69,11 @@ Scratch3SensingBlocks.prototype.current = function (args) {
case 'minute': return date.getMinutes();
case 'second': return date.getSeconds();
}
};
Scratch3SensingBlocks.prototype.currentMenu = function (args) {
return args.CURRENTMENU.toLowerCase();
};
Scratch3SensingBlocks.prototype.keyOptions = function (args) {
return args.KEY_OPTION.toLowerCase();
return 0;
};
Scratch3SensingBlocks.prototype.getKeyPressed = function (args, util) {
return util.ioQuery('keyboard', 'getKeyIsDown', args.KEY_OPTIONS);
return util.ioQuery('keyboard', 'getKeyIsDown', args.KEY_OPTION);
};
module.exports = Scratch3SensingBlocks;
+7 -5
View File
@@ -31,7 +31,7 @@ function domToBlocks (blocksDOM) {
}
var tagName = block.name.toLowerCase();
if (tagName == 'block' || tagName == 'shadow') {
domToBlock(block, blocks, true);
domToBlock(block, blocks, true, null);
}
}
// Flatten blocks object into a list.
@@ -48,8 +48,9 @@ function domToBlocks (blocksDOM) {
* @param {Element} blockDOM DOM tree for an individual block.
* @param {Object} blocks Collection of blocks to add to.
* @param {Boolean} isTopBlock Whether blocks at this level are "top blocks."
* @param {?string} parent Parent block ID.
*/
function domToBlock (blockDOM, blocks, isTopBlock) {
function domToBlock (blockDOM, blocks, isTopBlock, parent) {
// Block skeleton.
var block = {
id: blockDOM.attribs.id, // Block ID
@@ -58,6 +59,7 @@ function domToBlock (blockDOM, blocks, isTopBlock) {
fields: {}, // Fields on this block and their values.
next: null, // Next block in the stack, if one exists.
topLevel: isTopBlock, // If this block starts a stack.
parent: parent, // Parent block ID, if available.
shadow: blockDOM.name == 'shadow', // If this represents a shadow/slot.
x: blockDOM.attribs.x, // X position of script, if top-level.
y: blockDOM.attribs.y // Y position of script, if top-level.
@@ -113,10 +115,10 @@ function domToBlock (blockDOM, blocks, isTopBlock) {
case 'value':
case 'statement':
// Recursively generate block structure for input block.
domToBlock(childBlockNode, blocks, false);
domToBlock(childBlockNode, blocks, false, block.id);
if (childShadowNode && childBlockNode != childShadowNode) {
// Also generate the shadow block.
domToBlock(childShadowNode, blocks, false);
domToBlock(childShadowNode, blocks, false, block.id);
}
// Link this block's input to the child block.
var inputName = xmlChild.attribs.name;
@@ -132,7 +134,7 @@ function domToBlock (blockDOM, blocks, isTopBlock) {
continue;
}
// Recursively generate block structure for next block.
domToBlock(childBlockNode, blocks, false);
domToBlock(childBlockNode, blocks, false, block.id);
// Link next block to this block.
block.next = childBlockNode.attribs.id;
break;
+31 -4
View File
@@ -1,4 +1,5 @@
var adapter = require('./adapter');
var xmlEscape = require('../util/xml-escape');
/**
* @fileoverview
@@ -115,6 +116,20 @@ Blocks.prototype.getInputs = function (id) {
return inputs;
};
/**
* Get the top-level script for a given block.
* @param {?string} id ID of block to query.
* @return {?string} ID of top-level script block.
*/
Blocks.prototype.getTopLevelScript = function (id) {
if (typeof this._blocks[id] === 'undefined') return null;
var block = this._blocks[id];
while (block.parent !== null) {
block = this._blocks[block.parent];
}
return block.id;
};
// ---------------------------------------------------------------------
/**
@@ -237,6 +252,7 @@ Blocks.prototype.moveBlock = function (e) {
// This block was connected to the old parent's next connection.
oldParent.next = null;
}
this._blocks[e.id].parent = null;
}
// Has the block become a top-level block?
@@ -249,13 +265,20 @@ Blocks.prototype.moveBlock = function (e) {
if (e.newInput !== undefined) {
// Moved to the new parent's input.
// Don't obscure the shadow block.
var newInput = this._blocks[e.newParent].inputs[e.newInput];
newInput.name = e.newInput;
newInput.block = e.id;
var oldShadow = null;
if (this._blocks[e.newParent].inputs.hasOwnProperty(e.newInput)) {
oldShadow = this._blocks[e.newParent].inputs[e.newInput].shadow;
}
this._blocks[e.newParent].inputs[e.newInput] = {
name: e.newInput,
block: e.id,
shadow: oldShadow
};
} else {
// Moved to the new parent's next connection.
this._blocks[e.newParent].next = e.id;
}
this._blocks[e.id].parent = e.newParent;
}
};
@@ -347,8 +370,12 @@ Blocks.prototype.blockToXML = function (blockId) {
// Add any fields on this block.
for (var field in block.fields) {
var blockField = block.fields[field];
var value = blockField.value;
if (typeof value === 'string') {
value = xmlEscape(blockField.value);
}
xmlString += '<field name="' + blockField.name + '">' +
blockField.value + '</field>';
value + '</field>';
}
// Add blocks connected to the next connection.
if (block.next) {
+69 -49
View File
@@ -22,39 +22,91 @@ var execute = function (sequencer, thread) {
var currentBlockId = thread.peekStack();
var currentStackFrame = thread.peekStackFrame();
// Query info about the block.
var opcode = target.blocks.getOpcode(currentBlockId);
var blockFunction = runtime.getOpcodeFunction(opcode);
var isHat = runtime.getIsHat(opcode);
var fields = target.blocks.getFields(currentBlockId);
var inputs = target.blocks.getInputs(currentBlockId);
if (!opcode) {
console.warn('Could not get opcode for block: ' + currentBlockId);
return;
}
var blockFunction = runtime.getOpcodeFunction(opcode);
var isHat = runtime.getIsHat(opcode);
/**
* Handle any reported value from the primitive, either directly returned
* or after a promise resolves.
* @param {*} resolvedValue Value eventually returned from the primitive.
*/
var handleReport = function (resolvedValue) {
thread.pushReportedValue(resolvedValue);
if (isHat) {
// Hat predicate was evaluated.
if (runtime.getIsEdgeActivatedHat(opcode)) {
// If this is an edge-activated hat, only proceed if
// the value is true and used to be false.
var oldEdgeValue = runtime.updateEdgeActivatedValue(
currentBlockId,
resolvedValue
);
var edgeWasActivated = !oldEdgeValue && resolvedValue;
if (!edgeWasActivated) {
sequencer.retireThread(thread);
}
} else {
// Not an edge-activated hat: retire the thread
// if predicate was false.
if (!resolvedValue) {
sequencer.retireThread(thread);
}
}
} else {
// In a non-hat, report the value visually if necessary if
// at the top of the thread stack.
if (typeof resolvedValue !== 'undefined' && thread.atStackTop()) {
runtime.visualReport(currentBlockId, resolvedValue);
}
// Finished any yields.
thread.setStatus(Thread.STATUS_RUNNING);
}
};
// Hats are implemented slightly differently from regular blocks.
// If they have an associated block function, it's treated as a predicate;
// if not, execution will proceed right through it (as a no-op).
// Hats and single-field shadows are implemented slightly differently
// from regular blocks.
// For hats: if they have an associated block function,
// it's treated as a predicate; if not, execution will proceed as a no-op.
// For single-field shadows: If the block has a single field, and no inputs,
// immediately return the value of the field.
if (!blockFunction) {
if (!isHat) {
console.warn('Could not get implementation for opcode: ' + opcode);
if (isHat) {
// Skip through the block (hat with no predicate).
return;
} else {
if (Object.keys(fields).length == 1 &&
Object.keys(inputs).length == 0) {
// One field and no inputs - treat as arg.
for (var fieldKey in fields) { // One iteration.
handleReport(fields[fieldKey].value);
}
} else {
console.warn('Could not get implementation for opcode: ' +
opcode);
}
thread.requestScriptGlowInFrame = true;
return;
}
// Skip through the block.
// (either hat with no predicate, or missing op).
return;
}
// Generate values for arguments (inputs).
var argValues = {};
// Add all fields on this block to the argValues.
var fields = target.blocks.getFields(currentBlockId);
for (var fieldName in fields) {
argValues[fieldName] = fields[fieldName].value;
}
// Recursively evaluate input blocks.
var inputs = target.blocks.getInputs(currentBlockId);
for (var inputName in inputs) {
var input = inputs[inputName];
var inputBlockId = input.block;
@@ -110,43 +162,11 @@ var execute = function (sequencer, thread) {
}
});
/**
* Handle any reported value from the primitive, either directly returned
* or after a promise resolves.
* @param {*} resolvedValue Value eventually returned from the primitive.
*/
var handleReport = function (resolvedValue) {
thread.pushReportedValue(resolvedValue);
if (isHat) {
// Hat predicate was evaluated.
if (runtime.getIsEdgeActivatedHat(opcode)) {
// If this is an edge-activated hat, only proceed if
// the value is true and used to be false.
var oldEdgeValue = runtime.updateEdgeActivatedValue(
currentBlockId,
resolvedValue
);
var edgeWasActivated = !oldEdgeValue && resolvedValue;
if (!edgeWasActivated) {
sequencer.retireThread(thread);
}
} else {
// Not an edge-activated hat: retire the thread
// if predicate was false.
if (!resolvedValue) {
sequencer.retireThread(thread);
}
}
} else {
// In a non-hat, report the value visually if necessary if
// at the top of the thread stack.
if (typeof resolvedValue !== 'undefined' && thread.atStackTop()) {
runtime.visualReport(currentBlockId, resolvedValue);
}
// Finished any yields.
thread.setStatus(Thread.STATUS_RUNNING);
}
};
if (typeof primitiveReportedValue === 'undefined') {
// No value reported - potentially a command block.
// Edge-activated hats don't request a glow; all commands do.
thread.requestScriptGlowInFrame = true;
}
// If it's a promise, wait until promise resolves.
if (isPromise(primitiveReportedValue)) {
+69 -16
View File
@@ -56,30 +56,33 @@ function Runtime () {
this.ioDevices = {
'clock': new Clock(),
'keyboard': new Keyboard(this),
'mouse': new Mouse()
'mouse': new Mouse(this)
};
this._scriptGlowsPreviousFrame = [];
this._editingTarget = null;
}
/**
* Event name for glowing a stack
* Event name for glowing a script.
* @const {string}
*/
Runtime.STACK_GLOW_ON = 'STACK_GLOW_ON';
Runtime.SCRIPT_GLOW_ON = 'STACK_GLOW_ON';
/**
* Event name for unglowing a stack
* Event name for unglowing a script.
* @const {string}
*/
Runtime.STACK_GLOW_OFF = 'STACK_GLOW_OFF';
Runtime.SCRIPT_GLOW_OFF = 'STACK_GLOW_OFF';
/**
* Event name for glowing a block
* Event name for glowing a block.
* @const {string}
*/
Runtime.BLOCK_GLOW_ON = 'BLOCK_GLOW_ON';
/**
* Event name for unglowing a block
* Event name for unglowing a block.
* @const {string}
*/
Runtime.BLOCK_GLOW_OFF = 'BLOCK_GLOW_OFF';
@@ -197,7 +200,6 @@ Runtime.prototype.clearEdgeActivatedValues = function () {
*/
Runtime.prototype._pushThread = function (id) {
var thread = new Thread(id);
this.glowScript(id, true);
thread.pushStack(id);
this.threads.push(thread);
return thread;
@@ -210,7 +212,6 @@ Runtime.prototype._pushThread = function (id) {
Runtime.prototype._removeThread = function (thread) {
var i = this.threads.indexOf(thread);
if (i > -1) {
this.glowScript(thread.topBlock, false);
this.threads.splice(i, 1);
}
};
@@ -342,11 +343,6 @@ Runtime.prototype.stopAll = function () {
var threadsCopy = this.threads.slice();
while (threadsCopy.length > 0) {
var poppedThread = threadsCopy.pop();
// Unglow any blocks on this thread's stack.
for (var i = 0; i < poppedThread.stack.length; i++) {
this.glowBlock(poppedThread.stack[i], false);
}
// Actually remove the thread.
this._removeThread(poppedThread);
}
};
@@ -364,11 +360,55 @@ Runtime.prototype._step = function () {
}
}
var inactiveThreads = this.sequencer.stepThreads(this.threads);
this._updateScriptGlows();
for (var i = 0; i < inactiveThreads.length; i++) {
this._removeThread(inactiveThreads[i]);
}
};
Runtime.prototype.setEditingTarget = function (editingTarget) {
this._scriptGlowsPreviousFrame = [];
this._editingTarget = editingTarget;
this._updateScriptGlows();
};
Runtime.prototype._updateScriptGlows = function () {
// Set of scripts that request a glow this frame.
var requestedGlowsThisFrame = [];
// Final set of scripts glowing during this frame.
var finalScriptGlows = [];
// Find all scripts that should be glowing.
for (var i = 0; i < this.threads.length; i++) {
var thread = this.threads[i];
var target = this.targetForThread(thread);
if (thread.requestScriptGlowInFrame && target == this._editingTarget) {
var blockForThread = thread.peekStack() || thread.topBlock;
var script = target.blocks.getTopLevelScript(blockForThread);
requestedGlowsThisFrame.push(script);
}
}
// Compare to previous frame.
for (var j = 0; j < this._scriptGlowsPreviousFrame.length; j++) {
var previousFrameGlow = this._scriptGlowsPreviousFrame[j];
if (requestedGlowsThisFrame.indexOf(previousFrameGlow) < 0) {
// Glow turned off.
this.glowScript(previousFrameGlow, false);
} else {
// Still glowing.
finalScriptGlows.push(previousFrameGlow);
}
}
for (var k = 0; k < requestedGlowsThisFrame.length; k++) {
var currentFrameGlow = requestedGlowsThisFrame[k];
if (this._scriptGlowsPreviousFrame.indexOf(currentFrameGlow) < 0) {
// Glow turned on.
this.glowScript(currentFrameGlow, true);
finalScriptGlows.push(currentFrameGlow);
}
}
this._scriptGlowsPreviousFrame = finalScriptGlows;
};
/**
* Emit feedback for block glowing (used in the sequencer).
* @param {?string} blockId ID for the block to update glow
@@ -389,9 +429,9 @@ Runtime.prototype.glowBlock = function (blockId, isGlowing) {
*/
Runtime.prototype.glowScript = function (topBlockId, isGlowing) {
if (isGlowing) {
this.emit(Runtime.STACK_GLOW_ON, topBlockId);
this.emit(Runtime.SCRIPT_GLOW_ON, topBlockId);
} else {
this.emit(Runtime.STACK_GLOW_OFF, topBlockId);
this.emit(Runtime.SCRIPT_GLOW_OFF, topBlockId);
}
};
@@ -435,6 +475,19 @@ Runtime.prototype.getTargetById = function (targetId) {
}
};
/**
* Get a target representing the Scratch stage, if one exists.
* @return {?Target} The target, if found.
*/
Runtime.prototype.getTargetForStage = function () {
for (var i = 0; i < this.targets.length; i++) {
var target = this.targets[i];
if (target.isStage) {
return target;
}
}
};
/**
* Handle an animation frame from the main thread.
*/
+6
View File
@@ -28,6 +28,12 @@ function Thread (firstBlock) {
* @type {number}
*/
this.status = 0; /* Thread.STATUS_RUNNING */
/**
* Whether the thread requests its script to glow during this frame.
* @type {boolean}
*/
this.requestScriptGlowInFrame = false;
}
/**
+15 -5
View File
@@ -20,7 +20,8 @@ var specMap = require('./sb2specmap');
function sb2import (json, runtime) {
parseScratchObject(
JSON.parse(json),
runtime
runtime,
true
);
}
@@ -28,8 +29,9 @@ function sb2import (json, runtime) {
* Parse a single "Scratch object" and create all its in-memory VM objects.
* @param {!Object} object From-JSON "Scratch object:" sprite, stage, watcher.
* @param {!Runtime} runtime Runtime object to load all structures into.
* @param {boolean} topLevel Whether this is the top-level object (stage).
*/
function parseScratchObject (object, runtime) {
function parseScratchObject (object, runtime, topLevel) {
if (!object.hasOwnProperty('objName')) {
// Watcher/monitor - skip this object until those are implemented in VM.
// @todo
@@ -49,7 +51,8 @@ function parseScratchObject (object, runtime) {
var costume = object.costumes[i];
// @todo: Make sure all the relevant metadata is being pulled out.
sprite.costumes.push({
skin: costume.baseLayerMD5,
skin: 'https://cdn.assets.scratch.mit.edu/internalapi/asset/'
+ costume.baseLayerMD5 + '/get/',
name: costume.costumeName,
bitmapResolution: costume.bitmapResolution,
rotationCenterX: costume.rotationCenterX,
@@ -84,10 +87,11 @@ function parseScratchObject (object, runtime) {
if (object.currentCostumeIndex) {
target.currentCostume = object.currentCostumeIndex;
}
target.isStage = topLevel;
// The stage will have child objects; recursively process them.
if (object.children) {
for (var j = 0; j < object.children.length; j++) {
parseScratchObject(object.children[j], runtime);
parseScratchObject(object.children[j], runtime, false);
}
}
}
@@ -112,6 +116,7 @@ function parseScripts (scripts, blocks) {
parsedBlockList[0].x = scriptX * 1.1;
parsedBlockList[0].y = scriptY * 1.1;
parsedBlockList[0].topLevel = true;
parsedBlockList[0].parent = null;
}
// Flatten children and create add the blocks.
var convertedBlocks = flatten(parsedBlockList);
@@ -136,6 +141,7 @@ function parseBlockList (blockList) {
var block = blockList[i];
var parsedBlock = parseBlock(block);
if (previousBlock) {
parsedBlock.parent = previousBlock.id;
previousBlock.next = parsedBlock.id;
}
previousBlock = parsedBlock;
@@ -214,6 +220,9 @@ function parseBlock (sb2block) {
// Single block occupies the input.
innerBlocks = [parseBlock(providedArg)];
}
for (var j = 0; j < innerBlocks.length; j++) {
innerBlocks[j].parent = activeBlock.id;
}
// Obscures any shadow.
shadowObscured = true;
activeBlock.inputs[expectedArg.inputName].block = (
@@ -250,7 +259,7 @@ function parseBlock (sb2block) {
}
} else if (expectedArg.inputOp == 'colour_picker') {
// Convert SB2 color to hex.
fieldValue = Color.scratchColorToHex(providedArg);
fieldValue = Color.decimalToHex(providedArg);
fieldName = 'COLOUR';
if (shadowObscured) {
fieldValue = '#990000';
@@ -268,6 +277,7 @@ function parseBlock (sb2block) {
fields: fields,
next: null,
topLevel: false,
parent: activeBlock.id,
shadow: true
});
activeBlock.inputs[expectedArg.inputName].shadow = inputUid;
+72 -110
View File
@@ -4,13 +4,8 @@ var util = require('util');
var Runtime = require('./engine/runtime');
var sb2import = require('./import/sb2import');
var AudioWorker = require('../audioWorker');
/**
* Whether the environment is a WebWorker.
* @const{boolean}
*/
var ENV_WORKER = typeof importScripts === 'function';
var Sprite = require('./sprites/sprite');
var Blocks = require('./engine/blocks');
/**
* Handles connections between blocks, stage, and extensions.
@@ -33,11 +28,11 @@ function VirtualMachine () {
*/
instance.editingTarget = null;
// Runtime emits are passed along as VM emits.
instance.runtime.on(Runtime.STACK_GLOW_ON, function (id) {
instance.emit(Runtime.STACK_GLOW_ON, {id: id});
instance.runtime.on(Runtime.SCRIPT_GLOW_ON, function (id) {
instance.emit(Runtime.SCRIPT_GLOW_ON, {id: id});
});
instance.runtime.on(Runtime.STACK_GLOW_OFF, function (id) {
instance.emit(Runtime.STACK_GLOW_OFF, {id: id});
instance.runtime.on(Runtime.SCRIPT_GLOW_OFF, function (id) {
instance.emit(Runtime.SCRIPT_GLOW_OFF, {id: id});
});
instance.runtime.on(Runtime.BLOCK_GLOW_ON, function (id) {
instance.emit(Runtime.BLOCK_GLOW_ON, {id: id});
@@ -48,6 +43,8 @@ function VirtualMachine () {
instance.runtime.on(Runtime.VISUAL_REPORT, function (id, value) {
instance.emit(Runtime.VISUAL_REPORT, {id: id, value: value});
});
this.blockListener = this.blockListener.bind(this);
}
/**
@@ -106,7 +103,7 @@ VirtualMachine.prototype.postIOData = function (device, data) {
/**
* Load a project from a Scratch 2.0 JSON representation.
* @param {string} json JSON string representing the project.
* @param {?string} json JSON string representing the project.
*/
VirtualMachine.prototype.loadProject = function (json) {
// @todo: Handle other formats, e.g., Scratch 1.4, Scratch 3.0.
@@ -116,6 +113,68 @@ VirtualMachine.prototype.loadProject = function (json) {
// Update the VM user's knowledge of targets and blocks on the workspace.
this.emitTargetsUpdate();
this.emitWorkspaceUpdate();
this.runtime.setEditingTarget(this.editingTarget);
};
/**
* Temporary way to make an empty project, in case the desired project
* cannot be loaded from the online server.
*/
VirtualMachine.prototype.createEmptyProject = function () {
// Stage.
var blocks2 = new Blocks();
var stage = new Sprite(blocks2);
stage.name = 'Stage';
stage.costumes.push({
skin: '/assets/stage.png',
name: 'backdrop1',
bitmapResolution: 1,
rotationCenterX: 240,
rotationCenterY: 180
});
var target2 = stage.createClone();
this.runtime.targets.push(target2);
target2.x = 0;
target2.y = 0;
target2.direction = 90;
target2.size = 200;
target2.visible = true;
target2.isStage = true;
// Sprite1 (cat).
var blocks1 = new Blocks();
var sprite = new Sprite(blocks1);
sprite.name = 'Sprite1';
sprite.costumes.push({
skin: '/assets/scratch_cat.svg',
name: 'costume1',
bitmapResolution: 1,
rotationCenterX: 47,
rotationCenterY: 55
});
var target1 = sprite.createClone();
this.runtime.targets.push(target1);
target1.x = 0;
target1.y = 0;
target1.direction = 90;
target1.size = 100;
target1.visible = true;
this.editingTarget = this.runtime.targets[0];
this.emitTargetsUpdate();
this.emitWorkspaceUpdate();
};
/**
* Handle a Blockly event for the current editing target.
* @param {!Blockly.Event} e Any Blockly event.
*/
VirtualMachine.prototype.blockListener = function (e) {
if (this.editingTarget) {
this.editingTarget.blocks.blocklyListen(
e,
false,
this.runtime
);
}
};
/**
@@ -137,6 +196,7 @@ VirtualMachine.prototype.setEditingTarget = function (targetId) {
// Emit appropriate UI updates.
this.emitTargetsUpdate();
this.emitWorkspaceUpdate();
this.runtime.setEditingTarget(target);
}
};
@@ -166,104 +226,6 @@ VirtualMachine.prototype.emitWorkspaceUpdate = function () {
});
};
/*
* Worker handlers: for all public methods available above,
* we must also provide a message handler in case the VM is run
* from a worker environment.
*/
if (ENV_WORKER) {
self.importScripts(
'./node_modules/scratch-render/render-worker.js'
);
self.renderer = new self.RenderWebGLWorker();
self.audioWorker = new AudioWorker();
self.vmInstance = new VirtualMachine();
self.onmessage = function (e) {
var messageData = e.data;
switch (messageData.method) {
case 'start':
self.vmInstance.runtime.start();
break;
case 'greenFlag':
self.vmInstance.runtime.greenFlag();
break;
case 'stopAll':
self.vmInstance.runtime.stopAll();
break;
case 'blockListener':
if (self.vmInstance.editingTarget) {
self.vmInstance.editingTarget.blocks.blocklyListen(
messageData.args,
false,
self.vmInstance.runtime
);
}
break;
case 'flyoutBlockListener':
if (self.vmInstance.editingTarget) {
self.vmInstance.editingTarget.blocks.blocklyListen(
messageData.args,
true,
self.vmInstance.runtime
);
}
break;
case 'getPlaygroundData':
self.postMessage({
method: 'playgroundData',
blocks: self.vmInstance.editingTarget.blocks,
threads: self.vmInstance.runtime.threads
});
break;
case 'animationFrame':
self.vmInstance.animationFrame();
break;
case 'postIOData':
self.vmInstance.postIOData(messageData.device, messageData.data);
break;
case 'setEditingTarget':
self.vmInstance.setEditingTarget(messageData.targetId);
break;
case 'loadProject':
self.vmInstance.loadProject(messageData.json);
break;
default:
if (e.data.id == 'RendererConnected') {
//initRenderWorker();
}
self.renderer.onmessage(e);
break;
}
};
// Bind runtime's emitted events to postmessages.
self.vmInstance.runtime.on(Runtime.STACK_GLOW_ON, function (id) {
self.postMessage({method: Runtime.STACK_GLOW_ON, id: id});
});
self.vmInstance.runtime.on(Runtime.STACK_GLOW_OFF, function (id) {
self.postMessage({method: Runtime.STACK_GLOW_OFF, id: id});
});
self.vmInstance.runtime.on(Runtime.BLOCK_GLOW_ON, function (id) {
self.postMessage({method: Runtime.BLOCK_GLOW_ON, id: id});
});
self.vmInstance.runtime.on(Runtime.BLOCK_GLOW_OFF, function (id) {
self.postMessage({method: Runtime.BLOCK_GLOW_OFF, id: id});
});
self.vmInstance.runtime.on(Runtime.VISUAL_REPORT, function (id, value) {
self.postMessage({method: Runtime.VISUAL_REPORT, id: id, value: value});
});
self.vmInstance.on('workspaceUpdate', function(data) {
self.postMessage({method: 'workspaceUpdate',
xml: data.xml
});
});
self.vmInstance.on('targetsUpdate', function(data) {
self.postMessage({method: 'targetsUpdate',
targetList: data.targetList,
editingTarget: data.editingTarget
});
});
}
/**
* Export and bind to `window`
*/
+11 -14
View File
@@ -44,10 +44,10 @@ Keyboard.prototype._keyCodeToScratchKey = function (keyCode) {
}
switch (keyCode) {
case 32: return 'space';
case 37: return 'leftarrow';
case 38: return 'uparrow';
case 39: return 'rightarrow';
case 40: return 'downarrow';
case 37: return 'left arrow';
case 38: return 'up arrow';
case 39: return 'right arrow';
case 40: return 'down arrow';
}
return null;
};
@@ -59,17 +59,14 @@ Keyboard.prototype.postData = function (data) {
// If not already present, add to the list.
if (index < 0) {
this._keysPressed.push(data.keyCode);
this.runtime.startHats('event_whenkeypressed',
{
'KEY_OPTION': this._keyCodeToScratchKey(data.keyCode)
.toUpperCase()
});
this.runtime.startHats('event_whenkeypressed',
{
'KEY_OPTION': 'ANY'
});
}
// Always trigger hats, even if it was already pressed.
this.runtime.startHats('event_whenkeypressed', {
'KEY_OPTION': this._keyCodeToScratchKey(data.keyCode)
});
this.runtime.startHats('event_whenkeypressed', {
'KEY_OPTION': 'any'
});
} else if (index > -1) {
// If already present, remove from the list.
this._keysPressed.splice(index, 1);
+30 -3
View File
@@ -1,20 +1,47 @@
var MathUtil = require('../util/math-util');
function Mouse () {
function Mouse (runtime) {
this._x = 0;
this._y = 0;
this._isDown = false;
/**
* Reference to the owning Runtime.
* Can be used, for example, to activate hats.
* @type{!Runtime}
*/
this.runtime = runtime;
}
Mouse.prototype.postData = function(data) {
if (data.x) {
this._x = data.x;
this._x = data.x - data.canvasWidth / 2;
}
if (data.y) {
this._y = data.y;
this._y = data.y - data.canvasHeight / 2;
}
if (typeof data.isDown !== 'undefined') {
this._isDown = data.isDown;
if (this._isDown) {
this._activateClickHats(data.x, data.y);
}
}
};
Mouse.prototype._activateClickHats = function (x, y) {
if (self.renderer) {
var pickPromise = self.renderer.pick(x, y);
var instance = this;
pickPromise.then(function(drawableID) {
for (var i = 0; i < instance.runtime.targets.length; i++) {
var target = instance.runtime.targets[i];
if (target.hasOwnProperty('drawableID') &&
target.drawableID == drawableID) {
instance.runtime.startHats('event_whenthisspriteclicked',
null, target);
return;
}
}
});
}
};
+69 -1
View File
@@ -53,6 +53,12 @@ Clone.prototype.initDrawable = function () {
};
// Clone-level properties.
/**
* Whether this clone represents the Scratch stage.
* @type {boolean}
*/
Clone.prototype.isStage = false;
/**
* Scratch X coordinate. Currently should range from -240 to 240.
* @type {Number}
@@ -110,6 +116,9 @@ Clone.prototype.effects = {
* @param {!number} y New Y coordinate of clone, in Scratch coordinates.
*/
Clone.prototype.setXY = function (x, y) {
if (this.isStage) {
return;
}
this.x = x;
this.y = y;
if (this.renderer) {
@@ -124,6 +133,9 @@ Clone.prototype.setXY = function (x, y) {
* @param {!number} direction New direction of clone.
*/
Clone.prototype.setDirection = function (direction) {
if (this.isStage) {
return;
}
// Keep direction between -179 and +180.
this.direction = MathUtil.wrapClamp(direction, -179, 180);
if (this.renderer) {
@@ -139,6 +151,9 @@ Clone.prototype.setDirection = function (direction) {
* @param {?string} message Message to put in say bubble.
*/
Clone.prototype.setSay = function (type, message) {
if (this.isStage) {
return;
}
// @todo: Render to stage.
if (!type || !message) {
console.log('Clearing say bubble');
@@ -152,6 +167,9 @@ Clone.prototype.setSay = function (type, message) {
* @param {!boolean} visible True if the sprite should be shown.
*/
Clone.prototype.setVisible = function (visible) {
if (this.isStage) {
return;
}
this.visible = visible;
if (this.renderer) {
this.renderer.updateDrawableProperties(this.drawableID, {
@@ -165,6 +183,9 @@ Clone.prototype.setVisible = function (visible) {
* @param {!number} size Size of clone, from 5 to 535.
*/
Clone.prototype.setSize = function (size) {
if (this.isStage) {
return;
}
// Keep size between 5% and 535%.
this.size = MathUtil.clamp(size, 5, 535);
if (this.renderer) {
@@ -180,6 +201,7 @@ Clone.prototype.setSize = function (size) {
* @param {!number} value Numerical magnitude of effect.
*/
Clone.prototype.setEffect = function (effectName, value) {
if (!this.effects.hasOwnProperty(effectName)) return;
this.effects[effectName] = value;
if (this.renderer) {
var props = {};
@@ -205,7 +227,10 @@ Clone.prototype.clearEffects = function () {
* @param {number} index New index of costume.
*/
Clone.prototype.setCostume = function (index) {
this.currentCostume = index;
// Keep the costume index within possible values.
this.currentCostume = MathUtil.wrapClamp(
index, 0, this.sprite.costumes.length - 1
);
if (this.renderer) {
this.renderer.updateDrawableProperties(this.drawableID, {
skin: this.sprite.costumes[this.currentCostume].skin
@@ -213,6 +238,20 @@ Clone.prototype.setCostume = function (index) {
}
};
/**
* Get a costume index of this clone, by name of the costume.
* @param {?string} costumeName Name of a costume.
* @return {number} Index of the named costume, or -1 if not present.
*/
Clone.prototype.getCostumeIndexByName = function (costumeName) {
for (var i = 0; i < this.sprite.costumes.length; i++) {
if (this.sprite.costumes[i].name == costumeName) {
return i;
}
}
return -1;
};
/**
* Update all drawable properties for this clone.
* Use when a batch has changed, e.g., when the drawable is first created.
@@ -252,4 +291,33 @@ Clone.prototype.playNoteForBeats = function (note,beats) {
this.audioWorker.playNoteForBeats(note, beats);
}
/**
* Return whether the clone is touching a color.
* @param {Array.<number>} rgb [r,g,b], values between 0-255.
* @return {Promise.<Boolean>} True iff the clone is touching the color.
*/
Clone.prototype.isTouchingColor = function (rgb) {
if (this.renderer) {
return this.renderer.isTouchingColor(this.drawableID, rgb);
}
return false;
};
/**
* Return whether the clone's color is touching a color.
* @param {Object} targetRgb {Array.<number>} [r,g,b], values between 0-255.
* @param {Object} maskRgb {Array.<number>} [r,g,b], values between 0-255.
* @return {Promise.<Boolean>} True iff the clone's color is touching the color.
*/
Clone.prototype.colorIsTouchingColor = function (targetRgb, maskRgb) {
if (this.renderer) {
return this.renderer.isTouchingColor(
this.drawableID,
targetRgb,
maskRgb
);
}
return false;
};
module.exports = Clone;
+17
View File
@@ -1,3 +1,5 @@
var Color = require('../util/color');
function Cast () {}
/**
@@ -63,6 +65,21 @@ Cast.toString = function (value) {
return String(value);
};
/**
* Cast any Scratch argument to an RGB color object to be used for the renderer.
* @param {*} value Value to convert to RGB color object.
* @return {Array.<number>} [r,g,b], values between 0-255.
*/
Cast.toRgbColorList = function (value) {
var color;
if (typeof value == 'string' && value.substring(0, 1) == '#') {
color = Color.hexToRgb(value);
} else {
color = Color.decimalToRgb(Cast.toNumber(value));
}
return [color.r, color.g, color.b];
};
/**
* Compare two values, using Scratch cast, case-insensitive string compare, etc.
* In Scratch 2.0, this is captured by `interp.compare.`
+65 -6
View File
@@ -1,17 +1,76 @@
function Color () {}
/**
* Convert a Scratch color number to a hex string, #RRGGBB.
* @param {number} color RGB color as a decimal.
* Convert a Scratch decimal color to a hex string, #RRGGBB.
* @param {number} decimal RGB color as a decimal.
* @return {string} RGB color as #RRGGBB hex string.
*/
Color.scratchColorToHex = function (color) {
if (color < 0) {
color += 0xFFFFFF + 1;
Color.decimalToHex = function (decimal) {
if (decimal < 0) {
decimal += 0xFFFFFF + 1;
}
var hex = Number(color).toString(16);
var hex = Number(decimal).toString(16);
hex = '#' + '000000'.substr(0, 6 - hex.length) + hex;
return hex;
};
/**
* Convert a Scratch decimal color to an RGB color object.
* @param {number} decimal RGB color as decimal.
* @returns {Object} {r: R, g: G, b: B}, values between 0-255
*/
Color.decimalToRgb = function (decimal) {
var r = (decimal >> 16) & 0xFF;
var g = (decimal >> 8) & 0xFF;
var b = decimal & 0xFF;
return {r: r, g: g, b: b};
};
/**
* Convert a hex color (e.g., F00, #03F, #0033FF) to an RGB color object.
* CC-BY-SA Tim Down:
* https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
* @param {!string} hex Hex representation of the color.
* @return {Object} {r: R, g: G, b: B}, 0-255, or null.
*/
Color.hexToRgb = function (hex) {
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
};
/**
* Convert an RGB color object to a hex color.
* @param {Object} rgb {r: R, g: G, b: B}, values between 0-255.
* @return {!string} Hex representation of the color.
*/
Color.rgbToHex = function (rgb) {
return Color.decimalToHex(Color.rgbToDecimal(rgb));
};
/**
* Convert an RGB color object to a Scratch decimal color.
* @param {Object} rgb {r: R, g: G, b: B}, values between 0-255.
* @return {!number} Number representing the color.
*/
Color.rgbToDecimal = function (rgb) {
return (rgb.r << 16) + (rgb.g << 8) + rgb.b;
};
/**
* Convert a hex color (e.g., F00, #03F, #0033FF) to a decimal color number.
* @param {!string} hex Hex representation of the color.
* @return {!number} Number representing the color.
*/
Color.hexToDecimal = function (hex) {
return Color.rgbToDecimal(Color.hexToRgb(hex));
};
module.exports = Color;
+57 -7
View File
@@ -1,20 +1,70 @@
/**
* Constructor
* @fileoverview
* A utility for accurately measuring time.
* To use:
* ---
* var timer = new Timer();
* timer.start();
* ... pass some time ...
* var timeDifference = timer.timeElapsed();
* ---
* Or, you can use the `time` and `relativeTime`
* to do some measurement yourself.
*/
function Timer () {
this.startTime = 0;
}
/**
* @constructor
*/
function Timer () {}
/**
* Used to store the start time of a timer action.
* Updated when calling `timer.start`.
*/
Timer.prototype.startTime = 0;
/**
* Return the currently known absolute time, in ms precision.
* @returns {number} ms elapsed since 1 January 1970 00:00:00 UTC.
*/
Timer.prototype.time = function () {
return Date.now();
if (Date.now) {
return Date.now();
} else {
return new Date().getTime();
}
};
/**
* Returns a time accurate relative to other times produced by this function.
* If possible, will use sub-millisecond precision.
* If not, will use millisecond precision.
* Not guaranteed to produce the same absolute values per-system.
* @returns {number} ms-scale accurate time relative to other relative times.
*/
Timer.prototype.relativeTime = function () {
if (typeof self !== 'undefined' &&
self.performance && 'now' in self.performance) {
return self.performance.now();
} else {
return this.time();
}
};
/**
* Start a timer for measuring elapsed time,
* at the most accurate precision possible.
*/
Timer.prototype.start = function () {
this.startTime = this.time();
this.startTime = this.relativeTime();
};
/**
* Check time elapsed since `timer.start` was called.
* @returns {number} Time elapsed, in ms (possibly sub-ms precision).
*/
Timer.prototype.timeElapsed = function () {
return this.time() - this.startTime;
return this.relativeTime() - this.startTime;
};
module.exports = Timer;
+21
View File
@@ -0,0 +1,21 @@
/**
* Escape a string to be safe to use in XML content.
* CC-BY-SA: hgoebl
* https://stackoverflow.com/questions/7918868/
* how-to-escape-xml-entities-in-javascript
* @param {!string} unsafe Unsafe string.
* @return {string} XML-escaped string, for use within an XML tag.
*/
var xmlEscape = function (unsafe) {
return unsafe.replace(/[<>&'"]/g, function (c) {
switch (c) {
case '<': return '&lt;';
case '>': return '&gt;';
case '&': return '&amp;';
case '\'': return '&apos;';
case '"': return '&quot;';
}
});
};
module.exports = xmlEscape;
-276
View File
@@ -1,276 +0,0 @@
var EventEmitter = require('events');
var util = require('util');
// var Tone = require('tone');
function VirtualMachine () {
if (!window.Worker) {
console.error('WebWorkers not supported in this environment.' +
' Please use the non-worker version (vm.js or vm.min.js).');
return;
}
var instance = this;
EventEmitter.call(instance);
instance.vmWorker = new Worker('../vm.js');
/*
// MUSIC STUFF by ericr
// tone setup
var tone = new Tone();
Tone.Transport.start();
// var quantizeUnit = '@8n';
var quantizeUnit = '+0';
// effects
var delay = new Tone.FeedbackDelay(0.25, 0.5);
delay.wet.value = 0;
var pitchShift = new Tone.PitchShift();
var panner = new Tone.Panner();
var reverb = new Tone.Freeverb();
reverb.wet.value = 0;
Tone.Master.chain(delay, pitchShift, panner, reverb);
// synth setup for play note block
var synth = new Tone.PolySynth(6, Tone.Synth).toMaster();
// drum sounds
var drumFileNames = ['high_conga', 'small_cowbell', 'snare_drum', 'splash cymbal'];
var drumSamplers = loadSoundFiles(drumFileNames);
// sounds
var soundFileNames = ['meow','boing','this_is_a_test','who_put_the_bomp','cave','drip_drop','drum_machine','eggs','zoop'];
var soundSamplers = loadSoundFiles(soundFileNames);
// polyphonic samplers
function loadSoundFiles(filenames) {
var samplers = [];
for (var name of filenames) {
var myVoices = [];
for (var i=0; i<6; i++) {
var p = new Tone.Sampler('sounds/' + name + '.mp3').toMaster();
myVoices.push(p);
}
var polySampler = {
voices : myVoices,
currentVoice : 0,
nextVoice : function() {return this.voices[this.currentVoice++ % this.voices.length];},
stopAllVoices : function() {for (var i=0;i<this.voices.length;i++) {this.voices[i].triggerRelease()}},
};
samplers.push(polySampler);
}
return samplers;
}
// should fire once all sounds are loaded - seems to not work
Tone.Buffer.onload = function() {
console.log('loaded audio samples');
};
// scales and keys data
var scales = {
'MAJOR' : [0,2,4,5,7,9,11],
'MINOR' : [0,2,3,5,7,8,10],
'PENTATONIC': [0, 2, 4, 7, 9],
'CHROMATIC' : [0,1,2,3,4,5,6,7,8,9,10,11],
};
var currentScale = scales['MAJOR'];
var rootNote = 60;
function scaleNoteToMidiNote(scaleNote, scale, root) {
var scaleIndex = (Math.round(scaleNote) - 1) % scale.length;
if (scaleIndex < 0) {
scaleIndex += scale.length;
}
var octave = Math.floor((scaleNote - 1) / scale.length);
var midiNote = root + (octave * 12) + scale[scaleIndex];
return midiNote;
}
function midiToFreq(midiNote) {
var freq = tone.intervalToFrequencyRatio(midiNote - 60) * 261.63; // 60 is C4
return freq;
}
function clamp(input, min, max) {
return Math.min(Math.max(input, min), max);
};
function playNoteForBeats(note, beats) {
var midiNote = scaleNoteToMidiNote(note, currentScale, rootNote);
var freq = midiToFreq(midiNote);
synth.triggerAttackRelease(freq, beats, quantizeUnit);
}
*/
// onmessage calls are converted into emitted events.
instance.vmWorker.onmessage = function (e) {
/*
switch (e.data.method) {
case 'playsound':
soundSamplers[e.data.soundnum].nextVoice().triggerAttack(0, quantizeUnit);
break;
case 'playsoundwithpitch':
soundSamplers[e.data.soundnum].nextVoice().triggerAttack(e.data.pitch, quantizeUnit);
break;
case 'playnoteforbeats':
playNoteForBeats(e.data.note, e.data.beats);
break;
case 'playnote':
playNoteForBeats(e.data.note, 0.25);
break;
case 'setkey':
rootNote = parseInt(e.data.root) + 60;
currentScale = scales[e.data.scale];
break;
case 'playdrumforbeats':
case 'playdrum':
var drumNum = e.data.drum - 1; // one-indexing
drumSamplers[drumNum].nextVoice().triggerAttack(0, quantizeUnit);
break;
case 'seteffect' :
switch (e.data.effect) {
case 'ECHO':
delay.wet.value = (e.data.value / 100) / 2; // max 50% wet (need dry signal too)
break;
case 'PAN':
panner.pan.value = e.data.value / 100;
break;
case 'REVERB':
reverb.wet.value = e.data.value / 100;
break;
case 'PITCH':
pitchShift.pitch = e.data.value;
break;
}
break;
case 'changeeffect' :
switch (e.data.effect) {
case 'ECHO':
delay.wet.value += (e.data.value / 100) / 2; // max 50% wet (need dry signal too)
delay.wet.value = clamp(delay.wet.value, 0, 0.5);
break;
case 'PAN':
panner.pan.value += e.data.value / 100;
panner.pan.value = clamp(panner.pan.value, -1, 1);
break;
case 'REVERB':
reverb.wet.value += e.data.value / 100;
reverb.wet.value = clamp(reverb.wet.value, 0, 1);
break;
case 'PITCH':
pitchShift.pitch += e.data.value;
break;
}
break;
case 'cleareffects' :
delay.wet.value = 0;
panner.pan.value = 0;
reverb.wet.value = 0;
pitchShift.pitch = 0;
break;
case 'stopallsounds' :
// stop sounds from the play sound block
// to do: stop sounds from play note and play drum blocks
for (var i=0; i<soundSamplers.length; i++) {
soundSamplers[i].stopAllVoices();
}
break;
}
*/
instance.emit(e.data.method, e.data);
};
instance.blockListener = function (e) {
// Messages from Blockly are not serializable by default.
// Pull out the necessary, serializable components to pass across.
var serializableE = {
blockId: e.blockId,
element: e.element,
type: e.type,
name: e.name,
newValue: e.newValue,
oldParentId: e.oldParentId,
oldInputName: e.oldInputName,
newParentId: e.newParentId,
newInputName: e.newInputName,
newCoordinate: e.newCoordinate,
xml: {
outerHTML: (e.xml) ? e.xml.outerHTML : null
}
};
instance.vmWorker.postMessage({
method: 'blockListener',
args: serializableE
});
};
}
/**
* Inherit from EventEmitter
*/
util.inherits(VirtualMachine, EventEmitter);
// For documentation, please see index.js.
// These mirror the functionality provided there, with the worker wrapper.
VirtualMachine.prototype.getPlaygroundData = function () {
this.vmWorker.postMessage({method: 'getPlaygroundData'});
};
VirtualMachine.prototype.postIOData = function (device, data) {
this.vmWorker.postMessage({
method: 'postIOData',
device: device,
data: data
});
};
VirtualMachine.prototype.start = function () {
this.vmWorker.postMessage({method: 'start'});
};
VirtualMachine.prototype.greenFlag = function () {
this.vmWorker.postMessage({method: 'greenFlag'});
};
VirtualMachine.prototype.stopAll = function () {
this.vmWorker.postMessage({method: 'stopAll'});
};
VirtualMachine.prototype.animationFrame = function () {
this.vmWorker.postMessage({method: 'animationFrame'});
};
VirtualMachine.prototype.loadProject = function (json) {
this.vmWorker.postMessage({method: 'loadProject', json: json});
};
VirtualMachine.prototype.setEditingTarget = function (targetId) {
this.vmWorker.postMessage({method: 'setEditingTarget', targetId: targetId});
};
/**
* Export and bind to `window`
*/
module.exports = VirtualMachine;
if (typeof window !== 'undefined') window.VirtualMachine = module.exports;
+61
View File
@@ -291,6 +291,67 @@ test('move', function (t) {
t.end();
});
test('move into empty', function (t) {
var b = new Blocks();
b.createBlock({
id: 'foo',
opcode: 'TEST_BLOCK',
next: null,
fields: {},
inputs: {},
topLevel: true
});
b.createBlock({
id: 'bar',
opcode: 'TEST_BLOCK',
next: null,
fields: {},
inputs: {},
topLevel: true
});
b.moveBlock({
id: 'bar',
newInput: 'fooInput',
newParent: 'foo'
});
t.equal(b._blocks['foo'].inputs['fooInput'].block, 'bar');
t.end();
});
test('move no obscure shadow', function (t) {
var b = new Blocks();
b.createBlock({
id: 'foo',
opcode: 'TEST_BLOCK',
next: null,
fields: {},
inputs: {
'fooInput': {
name: 'fooInput',
block: 'x',
shadow: 'y'
}
},
topLevel: true
});
b.createBlock({
id: 'bar',
opcode: 'TEST_BLOCK',
next: null,
fields: {},
inputs: {},
topLevel: true
});
b.moveBlock({
id: 'bar',
newInput: 'fooInput',
newParent: 'foo'
});
t.equal(b._blocks['foo'].inputs['fooInput'].block, 'bar');
t.equal(b._blocks['foo'].inputs['fooInput'].shadow, 'y');
t.end();
});
test('change', function (t) {
var b = new Blocks();
b.createBlock({
+6401 -3257
View File
File diff suppressed because it is too large. Load diff
Vendored
+6 -6
View File
@@ -1,11 +1,11 @@
!function(t){function e(n){if(r[n])return r[n].exports;var i=r[n]={exports:{},id:n,loaded:!1};return t[n].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){function n(){var t=this;i.call(t);var e=new s;e.createClone();var r=[e.clones[0]];t.exampleSprite=e,t.runtime=new a(r),t.blockListener=e.blocks.generateBlockListener(!1,t.runtime),t.flyoutBlockListener=e.blocks.generateBlockListener(!0,t.runtime),t.runtime.on(a.STACK_GLOW_ON,function(e){t.emit(a.STACK_GLOW_ON,{id:e})}),t.runtime.on(a.STACK_GLOW_OFF,function(e){t.emit(a.STACK_GLOW_OFF,{id:e})}),t.runtime.on(a.BLOCK_GLOW_ON,function(e){t.emit(a.BLOCK_GLOW_ON,{id:e})}),t.runtime.on(a.BLOCK_GLOW_OFF,function(e){t.emit(a.BLOCK_GLOW_OFF,{id:e})}),t.runtime.on(a.VISUAL_REPORT,function(e,r){t.emit(a.VISUAL_REPORT,{id:e,value:r})})}var i=r(1),o=r(2),s=r(6),a=r(61),c="function"==typeof importScripts;o.inherits(n,i),n.prototype.start=function(){this.runtime.start()},n.prototype.greenFlag=function(){this.runtime.greenFlag()},n.prototype.stopAll=function(){this.runtime.stopAll()},n.prototype.getPlaygroundData=function(){this.emit("playgroundData",{blocks:this.exampleSprite.blocks,threads:this.runtime.threads})},n.prototype.animationFrame=function(){this.runtime.animationFrame()},n.prototype.postIOData=function(t,e){this.runtime.ioDevices[t]&&this.runtime.ioDevices[t].postData(e)},c&&(self.importScripts("./node_modules/scratch-render/render-worker.js"),self.renderer=new self.RenderWebGLWorker,self.vmInstance=new n,self.onmessage=function(t){var e=t.data;switch(e.method){case"start":self.vmInstance.runtime.start();break;case"greenFlag":self.vmInstance.runtime.greenFlag();break;case"stopAll":self.vmInstance.runtime.stopAll();break;case"blockListener":self.vmInstance.blockListener(e.args);break;case"flyoutBlockListener":self.vmInstance.flyoutBlockListener(e.args);break;case"getPlaygroundData":self.postMessage({method:"playgroundData",blocks:self.vmInstance.exampleSprite.blocks,threads:self.vmInstance.runtime.threads});break;case"animationFrame":self.vmInstance.animationFrame();break;case"postIOData":self.vmInstance.postIOData(e.device,e.data);break;default:"RendererConnected"==t.data.id,self.renderer.onmessage(t)}},self.vmInstance.runtime.on(a.STACK_GLOW_ON,function(t){self.postMessage({method:a.STACK_GLOW_ON,id:t})}),self.vmInstance.runtime.on(a.STACK_GLOW_OFF,function(t){self.postMessage({method:a.STACK_GLOW_OFF,id:t})}),self.vmInstance.runtime.on(a.BLOCK_GLOW_ON,function(t){self.postMessage({method:a.BLOCK_GLOW_ON,id:t})}),self.vmInstance.runtime.on(a.BLOCK_GLOW_OFF,function(t){self.postMessage({method:a.BLOCK_GLOW_OFF,id:t})}),self.vmInstance.runtime.on(a.VISUAL_REPORT,function(t,e){self.postMessage({method:a.VISUAL_REPORT,id:t,value:e})})),t.exports=n,"undefined"!=typeof window&&(window.VirtualMachine=t.exports)},function(t,e){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function n(t){return"function"==typeof t}function i(t){return"number"==typeof t}function o(t){return"object"==typeof t&&null!==t}function s(t){return void 0===t}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(t){if(!i(t)||0>t||isNaN(t))throw TypeError("n must be a positive number");return this._maxListeners=t,this},r.prototype.emit=function(t){var e,r,i,a,c,u;if(this._events||(this._events={}),"error"===t&&(!this._events.error||o(this._events.error)&&!this._events.error.length)){if(e=arguments[1],e instanceof Error)throw e;throw TypeError('Uncaught, unspecified "error" event.')}if(r=this._events[t],s(r))return!1;if(n(r))switch(arguments.length){case 1:r.call(this);break;case 2:r.call(this,arguments[1]);break;case 3:r.call(this,arguments[1],arguments[2]);break;default:a=Array.prototype.slice.call(arguments,1),r.apply(this,a)}else if(o(r))for(a=Array.prototype.slice.call(arguments,1),u=r.slice(),i=u.length,c=0;i>c;c++)u[c].apply(this,a);return!0},r.prototype.addListener=function(t,e){var i;if(!n(e))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",t,n(e.listener)?e.listener:e),this._events[t]?o(this._events[t])?this._events[t].push(e):this._events[t]=[this._events[t],e]:this._events[t]=e,o(this._events[t])&&!this._events[t].warned&&(i=s(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,i&&i>0&&this._events[t].length>i&&(this._events[t].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[t].length),"function"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(t,e){function r(){this.removeListener(t,r),i||(i=!0,e.apply(this,arguments))}if(!n(e))throw TypeError("listener must be a function");var i=!1;return r.listener=e,this.on(t,rLine truncated
this._index--)},a.prototype._stateBeforeSpecialEnd=function(t){this._special!==_t||"c"!==t&&"C"!==t?this._special!==mt||"t"!==t&&"T"!==t?this._state=f:this._state=ot:this._state=J},a.prototype._stateBeforeScript1=s("R",H),a.prototype._stateBeforeScript2=s("I",W),a.prototype._stateBeforeScript3=s("P",X),a.prototype._stateBeforeScript4=s("T",K),a.prototype._stateBeforeScript5=function(t){("/"===t||">"===t||n(t))&&(this._special=_t),this._state=g,this._index--},a.prototype._stateAfterScript1=o("R",Q,f),a.prototype._stateAfterScript2=o("I",Z,f),a.prototype._stateAfterScript3=o("P",$,f),a.prototype._stateAfterScript4=o("T",tt,f),a.prototype._stateAfterScript5=function(t){">"===t||n(t)?(this._special=gt,this._state=b,this._sectionStart=this._index-6,this._index--):this._state=f},a.prototype._stateBeforeStyle1=s("Y",rt),a.prototype._stateBeforeStyle2=s("L",nt),a.prototype._stateBeforeStyle3=s("E",it),a.prototype._stateBeforeStyle4=function(t){("/"===t||">"===t||n(t))&&(this._special=mt),this._state=g,this._index--},a.prototype._stateAfterStyle1=o("Y",st,f),a.prototype._stateAfterStyle2=o("L",at,f),a.prototype._stateAfterStyle3=o("E",ct,f),a.prototype._stateAfterStyle4=function(t){">"===t||n(t)?(this._special=gt,this._state=b,this._sectionStart=this._index-5,this._index--):this._state=f},a.prototype._stateBeforeEntity=o("#",ht,lt),a.prototype._stateBeforeNumericEntity=o("X",ft,pt),a.prototype._parseNamedEntityStrict=function(){if(this._sectionStart+1<this._index){var t=this._buffer.substring(this._sectionStart+1,this._index),e=this._xmlMode?l:u;e.hasOwnProperty(t)&&(this._emitPartial(e[t]),this._sectionStart=this._index+1)}},a.prototype._parseLegacyEntity=function(){var t=this._sectionStart+1,e=this._index-t;for(e>6&&(e=6);e>=2;){var r=this._buffer.substr(t,e);if(h.hasOwnProperty(r))return this._emitPartial(h[r]),void(this._sectionStart+=e+1);e--}},a.prototype._stateInNamedEntity=function(t){";"===t?(this._parseNamedEntityStrict(),this._sectionStart+1<this._index&&!this._xmlMode&&this._parseLegacyEntity(),this._state=this._baseState):("a">t||t>"z")&&("A">t||t>"Z")&&("0">t||t>"9")&&(this._xmlMode||this._sectionStart+1===this._index||(this._baseState!==f?"="!==t&&this._parseNamedEntityStrict():this._parseLegacyEntity()),this._state=this._baseState,this._index--)},a.prototype._decodeNumericEntity=function(t,e){var r=this._sectionStart+t;if(r!==this._index){var n=this._buffer.substring(r,this._index),i=parseInt(n,e);this._emitPartial(c(i)),this._sectionStart=this._index}else this._sectionStart--;this._state=this._baseState},a.prototype._stateInNumericEntity=function(t){";"===t?(this._decodeNumericEntity(2,10),this._sectionStart++):("0">t||t>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(2,10),this._index--)},a.prototype._stateInHexEntity=function(t){";"===t?(this._decodeNumericEntity(3,16),this._sectionStart++):("a">t||t>"f")&&("A">t||t>"F")&&("0">t||t>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(3,16),this._index--)},a.prototype._cleanup=function(){this._sectionStart<0?(this._buffer="",this._index=0,this._bufferOffset+=this._index):this._running&&(this._state===f?(this._sectionStart!==this._index&&this._cbs.ontext(this._buffer.substr(this._sectionStart)),this._buffer="",this._index=0,this._bufferOffset+=this._index):this._sectionStart===this._index?(this._buffer="",this._index=0,this._bufferOffset+=this._index):(this._buffer=this._buffer.substr(this._sectionStart),this._index-=this._sectionStart,this._bufferOffset+=this._sectionStart),this._sectionStart=0)},a.prototype.write=function(t){this._ended&&this._cbs.onerror(Error(".write() after done!")),this._buffer+=t,this._parse()},a.prototype._parse=function(){for(;this._index<this._buffer.length&&this._running;){var t=this._buffer.charAt(this._index);this._state===f?this._stateText(t):this._state===d?this._stateBeforeTagName(t):this._state===g?this._stateInTagName(t):this._state===m?this._stateBeforeCloseingTagName(t):this._state===b?this._stateInCloseingTagName(t):this._state===y?this._stateAfterCloseingTagName(t):this._state===_?this._stateInSelfClosingTag(t):this._state===v?this._stateBeforeAttributeName(t):this._state===w?this._stateInAttributeName(t):this._state===S?this._stateAfterAttributeName(t):this._state===E?this._stateBeforeAttributeValue(t):this._state===k?this._stateInAttributeValueDoubleQuotes(t):this._state===x?this._stateInAttributeValueSingleQuotes(t):this._state===T?this._stateInAttributeValueNoQuotes(t):this._state===A?this._stateBeforeDeclaration(t):this._state===L?this._stateInDeclaration(t):this._state===I?this._stateInProcessingInstruction(t):this._state===D?this._stateBeforeComment(t):this._state===R?this._stateInComment(t):this._state===N?this._stateAfterComment1(t):this._state===O?this._stateAfterComment2(t):this._state===B?this._stateBeforeCdata1(t):this._state===C?this._stateBeforeCdata2(t):this._state===M?this._stateBeforeCdata3(t):this._state===q?this._stateBeforeCdata4(t):this._stLine truncated
varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xharr:"⟷",xhArr:"⟺",Xi:"Ξ",xi:"ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",yuml:"ÿ",Yuml:"Ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",zfr:"𝔷",Zfr:"ℨ",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}},function(t,e){t.exports={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",amp:"&",AMP:"&",Aring:"Å",aring:"å",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",brvbar:"¦",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",iquest:"¿",Iuml:"Ï",iuml:"ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",Ntilde:"Ñ",ntilde:"ñ",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",Ograve:"Ò",ograve:"ò",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",Ouml:"Ö",ouml:"ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",THORN:"Þ",thorn:"þ",times:"×",Uacute:"Ú",uacute:"ú",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",Uuml:"Ü",uuml:"ü",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ"}},function(t,e){t.exports={amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}},function(t,e,r){function n(t,e,r){"object"==typeof t?(r=e,e=t,t=null):"function"==typeof e&&(r=e,e=c),this._callback=t,this._options=e||c,this._elementCB=r,this.dom=[],this._done=!1,this._tagStack=[],this._parser=this._parser||null}var i=r(21),o=/\s+/g,s=r(22),a=r(23),c={normalizeWhitespace:!1,withStartIndices:!1};n.prototype.onparserinit=function(t){this._parser=t},n.prototype.onreset=function(){n.call(this,this._callback,this._options,this._elementCB)},n.prototype.onend=function(){this._done||(this._done=!0,this._parser=null,this._handleCallback(null))},n.prototype._handleCallback=n.prototype.onerror=function(t){if("function"==typeof this._callback)this._callback(t,this.dom);else if(t)throw t},n.prototype.onclosetag=function(){var t=this._tagStack.pop();this._elementCB&&this._elementCB(t)},n.prototype._addDomElement=function(t){var e=this._tagStack[this._tagStack.length-1],r=e?e.children:this.dom,n=r[r.length-1];t.next=null,this._options.withStartIndices&&(t.startIndex=this._parser.startIndex),this._options.withDomLvl1&&(t.__proto__="tag"===t.type?a:s),n?(t.prev=n,n.next=t):t.prev=null,r.push(t),t.parent=e||null},n.prototype.onopentag=function(t,e){var r={type:"script"===t?i.Script:"style"===t?i.Style:i.Tag,name:t,attribs:e,children:[]};this._addDomElement(r),this._tagStack.push(r)},n.prototype.ontext=function(t){var e,r=this._options.normalizeWhitespace||this._options.ignoreWhitespace;!this._tagStack.length&&this.dom.length&&(e=this.dom[this.dom.length-1]).type===i.Text?r?e.data=(e.data+t).replace(o," "):e.data+=t:this._tagStack.length&&(e=this._tagStack[this._tagStack.length-1])&&(e=e.children[e.children.length-1])&&e.type===i.Text?r?e.data=(e.data+t).replace(o," "):e.data+=t:(r&&(t=t.replace(o," ")),this._addDomElement({data:t,type:i.Text}))},n.prototype.oncomment=function(t){var e=this._tagStack[this._tagStack.length-1];if(e&&e.type===i.Comment)return void(e.data+=t);var r={data:t,type:i.Comment};this.Line truncated
!function(t){function e(n){if(r[n])return r[n].exports;var i=r[n]={exports:{},id:n,loaded:!1};return t[n].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){function n(){var t=this;i.call(t),t.runtime=new s,t.editingTarget=null,t.runtime.on(s.SCRIPT_GLOW_ON,function(e){t.emit(s.SCRIPT_GLOW_ON,{id:e})}),t.runtime.on(s.SCRIPT_GLOW_OFF,function(e){t.emit(s.SCRIPT_GLOW_OFF,{id:e})}),t.runtime.on(s.BLOCK_GLOW_ON,function(e){t.emit(s.BLOCK_GLOW_ON,{id:e})}),t.runtime.on(s.BLOCK_GLOW_OFF,function(e){t.emit(s.BLOCK_GLOW_OFF,{id:e})}),t.runtime.on(s.VISUAL_REPORT,function(e,r){t.emit(s.VISUAL_REPORT,{id:e,value:r})}),this.blockListener=this.blockListener.bind(this)}var i=r(1),o=r(2),s=r(6),a=r(33),u=r(85),c=r(34);o.inherits(n,i),n.prototype.start=function(){this.runtime.start()},n.prototype.greenFlag=function(){this.runtime.greenFlag()},n.prototype.stopAll=function(){this.runtime.stopAll()},n.prototype.getPlaygroundData=function(){this.emit("playgroundData",{blocks:this.editingTarget.blocks,threads:this.runtime.threads})},n.prototype.animationFrame=function(){this.runtime.animationFrame()},n.prototype.postIOData=function(t,e){this.runtime.ioDevices[t]&&this.runtime.ioDevices[t].postData(e)},n.prototype.loadProject=function(t){a(t,this.runtime),this.editingTarget=this.runtime.targets[0],this.emitTargetsUpdate(),this.emitWorkspaceUpdate(),this.runtime.setEditingTarget(this.editingTarget)},n.prototype.createEmptyProject=function(){var t=new c,e=new u(t);e.name="Stage",e.costumes.push({skin:"/assets/stage.png",name:"backdrop1",bitmapResolution:1,rotationCenterX:240,rotationCenterY:180});var r=e.createClone();this.runtime.targets.push(r),r.x=0,r.y=0,r.direction=90,r.size=200,r.visible=!0,r.isStage=!0;var n=new c,i=new u(n);i.name="Sprite1",i.costumes.push({skin:"/assets/scratch_cat.svg",name:"costume1",bitmapResolution:1,rotationCenterX:47,rotationCenterY:55});var o=i.createClone();this.runtime.targets.push(o),o.x=0,o.y=0,o.direction=90,o.size=100,o.visible=!0,this.editingTarget=this.runtime.targets[0],this.emitTargetsUpdate(),this.emitWorkspaceUpdate()},n.prototype.blockListener=function(t){this.editingTarget&&this.editingTarget.blocks.blocklyListen(t,!1,this.runtime)},n.prototype.setEditingTarget=function(t){if(t!=this.editingTarget.id){var e=this.runtime.getTargetById(t);e&&(this.editingTarget=e,this.emitTargetsUpdate(),this.emitWorkspaceUpdate(),this.runtime.setEditingTarget(e))}},n.prototype.emitTargetsUpdate=function(){this.emit("targetsUpdate",{targetList:this.runtime.targets.map(function(t){return[t.id,t.getName()]}),editingTarget:this.editingTarget.id})},n.prototype.emitWorkspaceUpdate=function(){this.emit("workspaceUpdate",{xml:this.editingTarget.blocks.toXML()})},t.exports=n,"undefined"!=typeof window&&(window.VirtualMachine=t.exports)},function(t,e){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function n(t){return"function"==typeof t}function i(t){return"number"==typeof t}function o(t){return"object"==typeof t&&null!==t}function s(t){return void 0===t}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(t){if(!i(t)||t<0||isNaN(t))throw TypeError("n must be a positive number");return this._maxListeners=t,this},r.prototype.emit=function(t){var e,r,i,a,u,c;if(this._events||(this._events={}),"error"===t&&(!this._events.error||o(this._events.error)&&!this._events.error.length)){if(e=arguments[1],e instanceof Error)throw e;var p=new Error('Uncaught, unspecified "error" event. ('+e+")");throw p.context=e,p}if(r=this._events[t],s(r))return!1;if(n(r))switch(arguments.length){case 1:r.call(this);break;case 2:r.call(this,arguments[1]);break;case 3:r.call(this,arguments[1],arguments[2]);break;default:a=Array.prototype.slice.call(arguments,1),r.apply(this,a)}else if(o(r))for(a=Array.prototype.slice.call(arguments,1),c=r.slice(),i=c.length,u=0;u<i;u++)c[u].apply(this,a);return!0},r.prototype.addListener=function(t,e){var i;if(!n(e))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",t,n(e.listener)?e.listener:e),this._events[t]?o(this._events[t])?this._events[t].push(e):this._events[t]=[this._events[t],e]:this._events[t]=e,o(this._events[t])&&!this._events[t].warned&&(i=s(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,i&&i>0&&this._events[t].length>i&&(this._events[t].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[t].length),"function"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(t,e){function r(){this.removeListener(t,r),i||(i=!0,e.apply(this,arguments))}if(!n(e))throw TypeError("listener must be a function");var i=!1;return r.listener=e,this.Line truncated
"use strict";function n(t){var e=new i(i._61);return e._81=1,e._65=t,e}var i=r(20);t.exports=i;var o=n(!0),s=n(!1),a=n(null),u=n(void 0),c=n(0),p=n("");i.resolve=function(t){if(t instanceof i)return t;if(null===t)return a;if(void 0===t)return u;if(t===!0)return o;if(t===!1)return s;if(0===t)return c;if(""===t)return p;if("object"==typeof t||"function"==typeof t)try{var e=t.then;if("function"==typeof e)return new i(e.bind(t))}catch(r){return new i(function(t,e){e(r)})}return n(t)},i.all=function(t){var e=Array.prototype.slice.call(t);return new i(function(t,r){function n(s,a){if(a&&("object"==typeof a||"function"==typeof a)){if(a instanceof i&&a.then===i.prototype.then){for(;3===a._81;)a=a._65;return 1===a._81?n(s,a._65):(2===a._81&&r(a._65),void a.then(function(t){n(s,t)},r))}var u=a.then;if("function"==typeof u){var c=new i(u.bind(a));return void c.then(function(t){n(s,t)},r)}}e[s]=a,0===--o&&t(e)}if(0===e.length)return t([]);for(var o=e.length,s=0;s<e.length;s++)n(s,e[s])})},i.reject=function(t){return new i(function(e,r){r(t)})},i.race=function(t){return new i(function(e,r){t.forEach(function(t){i.resolve(t).then(e,r)})})},i.prototype["catch"]=function(t){return this.then(null,t)}},function(t,e,r){"use strict";function n(t,e){for(var r=[],n=0;n<e;n++)r.push("a"+n);var i=["return function ("+r.join(",")+") {","var self = this;","return new Promise(function (rs, rj) {","var res = fn.call(",["self"].concat(r).concat([a]).join(","),");","if (res &&",'(typeof res === "object" || typeof res === "function") &&','typeof res.then === "function"',") {rs(res);}","});","};"].join("");return Function(["Promise","fn"],i)(o,t)}function i(t){for(var e=Math.max(t.length-1,3),r=[],n=0;n<e;n++)r.push("a"+n);var i=["return function ("+r.join(",")+") {","var self = this;","var args;","var argLength = arguments.length;","if (arguments.length > "+e+") {","args = new Array(arguments.length + 1);","for (var i = 0; i < arguments.length; i++) {","args[i] = arguments[i];","}","}","return new Promise(function (rs, rj) {","var cb = "+a+";","var res;","switch (argLength) {",r.concat(["extra"]).map(function(t,e){return"case "+e+":res = fn.call("+["self"].concat(r.slice(0,e)).concat("cb").join(",")+");break;"}).join(""),"default:","args[argLength] = cb;","res = fn.apply(self, args);","}","if (res &&",'(typeof res === "object" || typeof res === "function") &&','typeof res.then === "function"',") {rs(res);}","});","};"].join("");return Function(["Promise","fn"],i)(o,t)}var o=r(20),s=r(26);t.exports=o,o.denodeify=function(t,e){return"number"==typeof e&&e!==1/0?n(t,e):i(t)};var a="function (err, res) {if (err) { rj(err); } else { rs(res); }}";o.nodeify=function(t){return function(){var e=Array.prototype.slice.call(arguments),r="function"==typeof e[e.length-1]?e.pop():null,n=this;try{return t.apply(this,arguments).nodeify(r,n)}catch(i){if(null===r||"undefined"==typeof r)return new o(function(t,e){e(i)});s(function(){r.call(n,i)})}}},o.prototype.nodeify=function(t,e){return"function"!=typeof t?this:void this.then(function(r){s(function(){t.call(e,null,r)})},function(r){s(function(){t.call(e,r)})})}},function(t,e,r){"use strict";function n(){if(u.length)throw u.shift()}function i(t){var e;e=a.length?a.pop():new o,e.task=t,s(e)}function o(){this.task=null}var s=r(21),a=[],u=[],c=s.makeRequestCallFromTimer(n);t.exports=i,o.prototype.call=function(){try{this.task.call()}catch(t){i.onerror?i.onerror(t):(u.push(t),c())}finally{this.task=null,a[a.length]=this}}},function(t,e,r){"use strict";var n=r(20);t.exports=n,n.enableSynchronous=function(){n.prototype.isPending=function(){return 0==this.getState()},n.prototype.isFulfilled=function(){return 1==this.getState()},n.prototype.isRejected=function(){return 2==this.getState()},n.prototype.getValue=function(){if(3===this._81)return this._65.getValue();if(!this.isFulfilled())throw new Error("Cannot get a value of an unfulfilled promise.");return this._65},n.prototype.getReason=function(){if(3===this._81)return this._65.getReason();if(!this.isRejected())throw new Error("Cannot get a rejection reason of a non-rejected promise.");return this._65},n.prototype.getState=function(){return 3===this._81?this._65.getState():this._81===-1||this._81===-2?0:this._81}},n.disableSynchronous=function(){n.prototype.isPending=void 0,n.prototype.isFulfilled=void 0,n.prototype.isRejected=void 0,n.prototype.getValue=void 0,n.prototype.getReason=void 0,n.prototype.getState=void 0}},function(t,e,r){function n(t){this.runtime=t}var i=r(13);n.prototype.getPrimitives=function(){return{event_broadcast:this.broadcast,event_broadcastandwait:this.broadcastAndWait,event_whengreaterthan:this.hatGreaterThanPredicate}},n.prototype.getHats=function(){return{event_whenflagclicked:{restartExistingThreads:!0},event_whenkeypressed:{restartExistingThreads:!1},event_whenthisspriteclicked:{restartExistingThreads:!0},event_whenbackdropswitchesto:{restartExistingThreads:!0},event_whengreaterthan:{restartExistingThreads:!1,edgeActivated:!0},event_Line truncated
this._index--):(this._state=y,this._sectionStart=this._index))},a.prototype._stateInCloseingTagName=function(t){(">"===t||n(t))&&(this._emitToken("onclosetag"),this._state=b,this._index--)},a.prototype._stateAfterCloseingTagName=function(t){">"===t&&(this._state=f,this._sectionStart=this._index+1)},a.prototype._stateBeforeAttributeName=function(t){">"===t?(this._cbs.onopentagend(),this._state=f,this._sectionStart=this._index+1):"/"===t?this._state=m:n(t)||(this._state=w,this._sectionStart=this._index)},a.prototype._stateInSelfClosingTag=function(t){">"===t?(this._cbs.onselfclosingtag(),this._state=f,this._sectionStart=this._index+1):n(t)||(this._state=v,this._index--)},a.prototype._stateInAttributeName=function(t){("="===t||"/"===t||">"===t||n(t))&&(this._cbs.onattribname(this._getSection()),this._sectionStart=-1,this._state=S,this._index--)},a.prototype._stateAfterAttributeName=function(t){"="===t?this._state=k:"/"===t||">"===t?(this._cbs.onattribend(),this._state=v,this._index--):n(t)||(this._cbs.onattribend(),this._state=w,this._sectionStart=this._index)},a.prototype._stateBeforeAttributeValue=function(t){'"'===t?(this._state=T,this._sectionStart=this._index+1):"'"===t?(this._state=E,this._sectionStart=this._index+1):n(t)||(this._state=x,this._sectionStart=this._index,this._index--)},a.prototype._stateInAttributeValueDoubleQuotes=function(t){'"'===t?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=v):this._decodeEntities&&"&"===t&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ct,this._sectionStart=this._index)},a.prototype._stateInAttributeValueSingleQuotes=function(t){"'"===t?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=v):this._decodeEntities&&"&"===t&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ct,this._sectionStart=this._index)},a.prototype._stateInAttributeValueNoQuotes=function(t){n(t)||">"===t?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=v,this._index--):this._decodeEntities&&"&"===t&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ct,this._sectionStart=this._index)},a.prototype._stateBeforeDeclaration=function(t){this._state="["===t?D:"-"===t?C:O},a.prototype._stateInDeclaration=function(t){">"===t&&(this._cbs.ondeclaration(this._getSection()),this._state=f,this._sectionStart=this._index+1)},a.prototype._stateInProcessingInstruction=function(t){">"===t&&(this._cbs.onprocessinginstruction(this._getSection()),this._state=f,this._sectionStart=this._index+1)},a.prototype._stateBeforeComment=function(t){"-"===t?(this._state=M,this._sectionStart=this._index+1):this._state=O},a.prototype._stateInComment=function(t){"-"===t&&(this._state=L)},a.prototype._stateAfterComment1=function(t){"-"===t?this._state=R:this._state=M},a.prototype._stateAfterComment2=function(t){">"===t?(this._cbs.oncomment(this._buffer.substring(this._sectionStart,this._index-2)),this._state=f,this._sectionStart=this._index+1):"-"!==t&&(this._state=M)},a.prototype._stateBeforeCdata1=o("C",I,O),a.prototype._stateBeforeCdata2=o("D",B,O),a.prototype._stateBeforeCdata3=o("A",P,O),a.prototype._stateBeforeCdata4=o("T",U,O),a.prototype._stateBeforeCdata5=o("A",q,O),a.prototype._stateBeforeCdata6=function(t){"["===t?(this._state=F,this._sectionStart=this._index+1):(this._state=O,this._index--)},a.prototype._stateInCdata=function(t){"]"===t&&(this._state=j)},a.prototype._stateAfterCdata1=i("]",G),a.prototype._stateAfterCdata2=function(t){">"===t?(this._cbs.oncdata(this._buffer.substring(this._sectionStart,this._index-2)),this._state=f,this._sectionStart=this._index+1):"]"!==t&&(this._state=F)},a.prototype._stateBeforeSpecial=function(t){"c"===t||"C"===t?this._state=Y:"t"===t||"T"===t?this._state=et:(this._state=g,this._index--)},a.prototype._stateBeforeSpecialEnd=function(t){this._special!==mt||"c"!==t&&"C"!==t?this._special!==_t||"t"!==t&&"T"!==t?this._state=f:this._state=ot:this._state=Q},a.prototype._stateBeforeScript1=s("R",z),a.prototype._stateBeforeScript2=s("I",X),a.prototype._stateBeforeScript3=s("P",W),a.prototype._stateBeforeScript4=s("T",K),a.prototype._stateBeforeScript5=function(t){("/"===t||">"===t||n(t))&&(this._special=mt),this._state=g,this._index--},a.prototype._stateAfterScript1=o("R",J,f),a.prototype._stateAfterScript2=o("I",Z,f),a.prototype._stateAfterScript3=o("P",$,f),a.prototype._stateAfterScript4=o("T",tt,f),a.prototype._stateAfterScript5=function(t){">"===t||n(t)?(this._special=gt,this._state=y,this._sectionStart=this._index-6,this._index--):this._state=f},a.prototype._stateBeforeStyle1=s("Y",rt),a.prototype._stateBeforeStyle2=s("L",nt),a.prototype._stateBeforeStyle3=s("E",it),a.prototype._stateBeforeStyle4=function(t){("/"===t||">"===t||n(t))&&(this._special=_t),this._state=g,this._index--},a.prototype._stateAfterStyle1=o("Y",st,f),a.prototype._stateAfterStyle2=o("L",at,f),a.prototype._stateAfterStyle3=o("E",ut,f),a.prototype._stateAfterStyle4=function(t){">"===t||n(t)?Line truncated
seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",solbar:"⌿",solb:"⧄",sol:"/",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squ:"□",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succapprox:"⪸",succ:"≻",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup1:"¹",sup2:"²",sup3:"³",sup:"⊃",Sup:"⋑",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",therefore:"∴",Therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",ThinSpace:" ",thinsp:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",timesbar:"⨱",timesb:"⊠",times:"×",timesd:"⨰",tint:"∭",toea:"⤨",topbot:"⌶",topcir:"⫱",top:"⊤",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",uarr:"↑",Uarr:"↟",uArr:"⇑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrowBar:"⤒",uparrow:"↑",UpArrow:"↑",Uparrow:"⇑",UpArrowDownArrow:"⇅",updownarrow:"↕",UpDownArrow:"↕",Updownarrow:"⇕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTeeArrow:"↥",UpTee:"⊥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltriLine truncated
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
"use strict";function i(){function t(){}try{var e=new Uint8Array(1);return e.foo=function(){return 42},e.constructor=t,42===e.foo()&&e.constructor===t&&"function"==typeof e.subarray&&0===e.subarray(1,1).byteLength}catch(r){return!1}}function o(){return t.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function t(e){return this instanceof t?(t.TYPED_ARRAY_SUPPORT||(this.length=0,this.parent=void 0),"number"==typeof e?s(this,e):"string"==typeof e?a(this,e,arguments.length>1?arguments[1]:"utf8"):c(this,e)):arguments.length>1?new t(e,arguments[1]):new t(e)}function s(e,r){if(e=g(e,0>r?0:0|_(r)),!t.TYPED_ARRAY_SUPPORT)for(var n=0;r>n;n++)e[n]=0;return e}function a(t,e,r){"string"==typeof r&&""!==r||(r="utf8");var n=0|b(e,r);return t=g(t,n),t.write(e,r),t}function c(e,r){if(t.isBuffer(r))return u(e,r);if(J(r))return h(e,r);if(null==r)throw new TypeError("must start with number, buffer, array or string");if("undefined"!=typeof ArrayBuffer){if(r.buffer instanceof ArrayBuffer)return l(e,r);if(r instanceof ArrayBuffer)return p(e,r)}return r.length?f(e,r):d(e,r)}function u(t,e){var r=0|_(e.length);return t=g(t,r),e.copy(t,0,0,r),t}function h(t,e){var r=0|_(e.length);t=g(t,r);for(var n=0;r>n;n+=1)t[n]=255&e[n];return t}function l(t,e){var r=0|_(e.length);t=g(t,r);for(var n=0;r>n;n+=1)t[n]=255&e[n];return t}function p(e,r){return t.TYPED_ARRAY_SUPPORT?(r.byteLength,e=t._augment(new Uint8Array(r))):e=l(e,new Uint8Array(r)),e}function f(t,e){var r=0|_(e.length);t=g(t,r);for(var n=0;r>n;n+=1)t[n]=255&e[n];return t}function d(t,e){var r,n=0;"Buffer"===e.type&&J(e.data)&&(r=e.data,n=0|_(r.length)),t=g(t,n);for(var i=0;n>i;i+=1)t[i]=255&r[i];return t}function g(e,r){t.TYPED_ARRAY_SUPPORT?(e=t._augment(new Uint8Array(r)),e.__proto__=t.prototype):(e.length=r,e._isBuffer=!0);var n=0!==r&&r<=t.poolSize>>>1;return n&&(e.parent=Q),e}function _(t){if(t>=o())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+o().toString(16)+" bytes");return 0|t}function m(e,r){if(!(this instanceof m))return new m(e,r);var n=new t(e,r);return delete n.parent,n}function b(t,e){"string"!=typeof t&&(t=""+t);var r=t.length;if(0===r)return 0;for(var n=!1;;)switch(e){case"ascii":case"binary":case"raw":case"raws":return r;case"utf8":case"utf-8":return Y(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return H(t).length;default:if(n)return Y(t).length;e=(""+e).toLowerCase(),n=!0}}function y(t,e,r){var n=!1;if(e=0|e,r=void 0===r||r===1/0?this.length:0|r,t||(t="utf8"),0>e&&(e=0),r>this.length&&(r=this.length),e>=r)return"";for(;;)switch(t){case"hex":return R(this,e,r);case"utf8":case"utf-8":return A(this,e,r);case"ascii":return I(this,e,r);case"binary":return D(this,e,r);case"base64":return T(this,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return N(this,e,r);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function v(t,e,r,n){r=Number(r)||0;var i=t.length-r;n?(n=Number(n),n>i&&(n=i)):n=i;var o=e.length;if(o%2!==0)throw new Error("Invalid hex string");n>o/2&&(n=o/2);for(var s=0;n>s;s++){var a=parseInt(e.substr(2*s,2),16);if(isNaN(a))throw new Error("Invalid hex string");t[r+s]=a}return s}function w(t,e,r,n){return W(Y(e,t.length-r),t,r,n)}function S(t,e,r,n){return W(V(e),t,r,n)}function E(t,e,r,n){return S(t,e,r,n)}function k(t,e,r,n){return W(H(e),t,r,n)}function x(t,e,r,n){return W(z(e,t.length-r),t,r,n)}function T(t,e,r){return 0===e&&r===t.length?X.fromByteArray(t):X.fromByteArray(t.slice(e,r))}function A(t,e,r){r=Math.min(t.length,r);for(var n=[],i=e;r>i;){var o=t[i],s=null,a=o>239?4:o>223?3:o>191?2:1;if(r>=i+a){var c,u,h,l;switch(a){case 1:128>o&&(s=o);break;case 2:c=t[i+1],128===(192&c)&&(l=(31&o)<<6|63&c,l>127&&(s=l));break;case 3:c=t[i+1],u=t[i+2],128===(192&c)&&128===(192&u)&&(l=(15&o)<<12|(63&c)<<6|63&u,l>2047&&(55296>l||l>57343)&&(s=l));break;case 4:c=t[i+1],u=t[i+2],h=t[i+3],128===(192&c)&&128===(192&u)&&128===(192&h)&&(l=(15&o)<<18|(63&c)<<12|(63&u)<<6|63&h,l>65535&&1114112>l&&(s=l))}}null===s?(s=65533,a=1):s>65535&&(s-=65536,n.push(s>>>10&1023|55296),s=56320|1023&s),n.push(s),i+=a}return L(n)}function L(t){var e=t.length;if(Z>=e)return String.fromCharCode.apply(String,t);for(var r="",n=0;e>n;)r+=String.fromCharCode.apply(String,t.slice(n,n+=Z));return r}function I(t,e,r){var n="";r=Math.min(t.length,r);for(var i=e;r>i;i++)n+=String.fromCharCode(127&t[i]);return n}function D(t,e,r){var n="";r=Math.min(t.length,r);for(var i=e;r>i;i++)n+=String.fromCharCode(t[i]);return n}function R(t,e,r){var n=t.length;(!e||0>e)&&(e=0),(!r||0>r||r>n)&&(r=n);for(var i="",o=e;r>o;o++)i+=G(t[o]);return i}function N(t,e,r){for(var n=t.slice(e,r),i="",o=0;o<n.length;o+=2)i+=String.fromCharCode(n[o]+256*n[o+1]);return i}function O(t,e,r){if(t%1!==0||0>t)throw new RangeError("offset is not uint");if(t+e>r)throw new RangeError("Trying to access beyond buffer length")}function B(e,r,n,i,o,s){if(!t.isBuffer(e))throw new TypeError("buffer muLine truncated
}},function(t,e,r){function n(t,e){if(t){var r,n="";for(var i in t)r=t[i],n&&(n+=" "),n+=!r&&l[i]?i:i+'="'+(e.decodeEntities?h.encodeXML(r):r)+'"';return n}}function i(t,e){"svg"===t.name&&(e={decodeEntities:e.decodeEntities,xmlMode:!0});var r="<"+t.name,i=n(t.attribs,e);return i&&(r+=" "+i),!e.xmlMode||t.children&&0!==t.children.length?(r+=">",t.children&&(r+=d(t.children,e)),f[t.name]&&!e.xmlMode||(r+="</"+t.name+">")):r+="/>",r}function o(t){return"<"+t.data+">"}function s(t,e){var r=t.data||"";return!e.decodeEntities||t.parent&&t.parent.name in p||(r=h.encodeXML(r)),r}function a(t){return"<![CDATA["+t.children[0].data+"]]>"}function c(t){return"<!--"+t.data+"-->"}var u=r(51),h=r(52),l={__proto__:null,allowfullscreen:!0,async:!0,autofocus:!0,autoplay:!0,checked:!0,controls:!0,"default":!0,defer:!0,disabled:!0,hidden:!0,ismap:!0,loop:!0,multiple:!0,muted:!0,open:!0,readonly:!0,required:!0,reversed:!0,scoped:!0,seamless:!0,selected:!0,typemustmatch:!0},p={__proto__:null,style:!0,script:!0,xmp:!0,iframe:!0,noembed:!0,noframes:!0,plaintext:!0,noscript:!0},f={__proto__:null,area:!0,base:!0,basefont:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,isindex:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},d=t.exports=function(t,e){Array.isArray(t)||t.cheerio||(t=[t]),e=e||{};for(var r="",n=0;n<t.length;n++){var h=t[n];r+="root"===h.type?d(h.children,e):u.isTag(h)?i(h,e):h.type===u.Directive?o(h):h.type===u.Comment?c(h):h.type===u.CDATA?a(h):s(h,e)}return r}},function(t,e){t.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",isTag:function(t){return"tag"===t.type||"script"===t.type||"style"===t.type}}},function(t,e,r){var n=r(53),i=r(54);e.decode=function(t,e){return(!e||0>=e?i.XML:i.HTML)(t)},e.decodeStrict=function(t,e){return(!e||0>=e?i.XML:i.HTMLStrict)(t)},e.encode=function(t,e){return(!e||0>=e?n.XML:n.HTML)(t)},e.encodeXML=n.XML,e.encodeHTML4=e.encodeHTML5=e.encodeHTML=n.HTML,e.decodeXML=e.decodeXMLStrict=i.XML,e.decodeHTML4=e.decodeHTML5=e.decodeHTML=i.HTML,e.decodeHTML4Strict=e.decodeHTML5Strict=e.decodeHTMLStrict=i.HTMLStrict,e.escape=n.escape},function(t,e,r){function n(t){return Object.keys(t).sort().reduce(function(e,r){return e[t[r]]="&"+r+";",e},{})}function i(t){var e=[],r=[];return Object.keys(t).forEach(function(t){1===t.length?e.push("\\"+t):r.push(t)}),r.unshift("["+e.join("")+"]"),new RegExp(r.join("|"),"g")}function o(t){return"&#x"+t.charCodeAt(0).toString(16).toUpperCase()+";"}function s(t){var e=t.charCodeAt(0),r=t.charCodeAt(1),n=1024*(e-55296)+r-56320+65536;return"&#x"+n.toString(16).toUpperCase()+";"}function a(t,e){function r(e){return t[e]}return function(t){return t.replace(e,r).replace(d,s).replace(f,o)}}function c(t){return t.replace(g,o).replace(d,s).replace(f,o)}var u=n(r(19)),h=i(u);e.XML=a(u,h);var l=n(r(17)),p=i(l);e.HTML=a(l,p);var f=/[^\0-\x7F]/g,d=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,g=i(u);e.escape=c},function(t,e,r){function n(t){var e=Object.keys(t).join("|"),r=o(t);e+="|#[xX][\\da-fA-F]+|#\\d+";var n=new RegExp("&(?:"+e+");","g");return function(t){return String(t).replace(n,r)}}function i(t,e){return e>t?1:-1}function o(t){return function(e){return"#"===e.charAt(1)?u("X"===e.charAt(2)||"x"===e.charAt(2)?parseInt(e.substr(3),16):parseInt(e.substr(2),10)):t[e.slice(1,-1)]}}var s=r(17),a=r(18),c=r(19),u=r(15),h=n(c),l=n(s),p=function(){function t(t){return";"!==t.substr(-1)&&(t+=";"),h(t)}for(var e=Object.keys(a).sort(i),r=Object.keys(s).sort(i),n=0,c=0;n<r.length;n++)e[c]===r[n]?(r[n]+=";?",c++):r[n]+=";";var u=new RegExp("&(?:"+r.join("|")+"|#[xX][\\da-fA-F]+;?|#\\d+;?)","g"),h=o(s);return function(e){return String(e).replace(u,t)}}();t.exports={XML:h,HTML:p,HTMLStrict:l}},function(t,e){var r=e.getChildren=function(t){return t.children},n=e.getParent=function(t){return t.parent};e.getSiblings=function(t){var e=n(t);return e?r(e):[t]},e.getAttributeValue=function(t,e){return t.attribs&&t.attribs[e]},e.hasAttrib=function(t,e){return!!t.attribs&&hasOwnProperty.call(t.attribs,e)},e.getName=function(t){return t.name}},function(t,e){e.removeElement=function(t){if(t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),t.parent){var e=t.parent.children;e.splice(e.lastIndexOf(t),1)}},e.replaceElement=function(t,e){var r=e.prev=t.prev;r&&(r.next=e);var n=e.next=t.next;n&&(n.prev=e);var i=e.parent=t.parent;if(i){var o=i.children;o[o.lastIndexOf(t)]=e}},e.appendChild=function(t,e){if(e.parent=t,1!==t.children.push(e)){var r=t.children[t.children.length-2];r.next=e,e.prev=r,e.next=null}},e.append=function(t,e){var r=t.parent,n=t.next;if(e.next=n,e.prev=t,t.next=e,e.parent=r,n){if(n.prev=e,r){var i=r.children;i.splice(i.lastIndexOf(n),0,e)}}else r&&r.children.push(e)},e.prepend=function(t,e){var r=t.parent;if(r){var n=r.children;n.splice(n.lastIndexOf(t),0,e)}t.prev&&(t.prev.next=e),e.parent=r,e.prev=t.prev,e.next=t,t.prev=e}},function(t,e,r){function n(t,e,r,n){return Array.isArray(e)|Line truncated
return e.ioQuery("mouse","getY")},r.prototype.getMouseDown=function(t,e){return e.ioQuery("mouse","getIsDown")},t.exports=r}]);
"use strict";function i(){try{var t=new Uint8Array(1);return t.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===t.foo()&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(e){return!1}}function o(){return t.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,r){if(o()<r)throw new RangeError("Invalid typed array length");return t.TYPED_ARRAY_SUPPORT?(e=new Uint8Array(r),e.__proto__=t.prototype):(null===e&&(e=new t(r)),e.length=r),e}function t(e,r,n){if(!(t.TYPED_ARRAY_SUPPORT||this instanceof t))return new t(e,r,n);if("number"==typeof e){if("string"==typeof r)throw new Error("If encoding is specified then the first argument must be a string");return p(this,e)}return a(this,e,r,n)}function a(t,e,r,n){if("number"==typeof e)throw new TypeError('"value" argument must not be a number');return"undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer?f(t,e,r,n):"string"==typeof e?h(t,e,r):d(t,e)}function u(t){if("number"!=typeof t)throw new TypeError('"size" argument must be a number');if(t<0)throw new RangeError('"size" argument must not be negative')}function c(t,e,r,n){return u(e),e<=0?s(t,e):void 0!==r?"string"==typeof n?s(t,e).fill(r,n):s(t,e).fill(r):s(t,e)}function p(e,r){if(u(r),e=s(e,r<0?0:0|g(r)),!t.TYPED_ARRAY_SUPPORT)for(var n=0;n<r;++n)e[n]=0;return e}function h(e,r,n){if("string"==typeof n&&""!==n||(n="utf8"),!t.isEncoding(n))throw new TypeError('"encoding" must be a valid string encoding');var i=0|_(r,n);e=s(e,i);var o=e.write(r,n);return o!==i&&(e=e.slice(0,o)),e}function l(t,e){var r=e.length<0?0:0|g(e.length);t=s(t,r);for(var n=0;n<r;n+=1)t[n]=255&e[n];return t}function f(e,r,n,i){if(r.byteLength,n<0||r.byteLength<n)throw new RangeError("'offset' is out of bounds");if(r.byteLength<n+(i||0))throw new RangeError("'length' is out of bounds");return r=void 0===n&&void 0===i?new Uint8Array(r):void 0===i?new Uint8Array(r,n):new Uint8Array(r,n,i),t.TYPED_ARRAY_SUPPORT?(e=r,e.__proto__=t.prototype):e=l(e,r),e}function d(e,r){if(t.isBuffer(r)){var n=0|g(r.length);return e=s(e,n),0===e.length?e:(r.copy(e,0,0,n),e)}if(r){if("undefined"!=typeof ArrayBuffer&&r.buffer instanceof ArrayBuffer||"length"in r)return"number"!=typeof r.length||Q(r.length)?s(e,0):l(e,r);if("Buffer"===r.type&&$(r.data))return l(e,r.data)}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}function g(t){if(t>=o())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+o().toString(16)+" bytes");return 0|t}function m(e){return+e!=e&&(e=0),t.alloc(+e)}function _(e,r){if(t.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var i=!1;;)switch(r){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return Y(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return W(e).length;default:if(i)return Y(e).length;r=(""+r).toLowerCase(),i=!0}}function y(t,e,r){var n=!1;if((void 0===e||e<0)&&(e=0),e>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if(r>>>=0,e>>>=0,r<=e)return"";for(t||(t="utf8");;)switch(t){case"hex":return R(this,e,r);case"utf8":case"utf-8":return A(this,e,r);case"ascii":return M(this,e,r);case"latin1":case"binary":return L(this,e,r);case"base64":return O(this,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return D(this,e,r);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function b(t,e,r){var n=t[e];t[e]=t[r],t[r]=n}function v(e,r,n,i,o){if(0===e.length)return-1;if("string"==typeof n?(i=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof r&&(r=t.from(r,i)),t.isBuffer(r))return 0===r.length?-1:w(e,r,n,i,o);if("number"==typeof r)return r=255&r,t.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,r,n):Uint8Array.prototype.lastIndexOf.call(e,r,n):w(e,[r],n,i,o);throw new TypeError("val must be string, number or Buffer")}function w(t,e,r,n,i){function o(t,e){return 1===s?t[e]:t.readUInt16BE(e*s)}var s=1,a=t.length,u=e.length;if(void 0!==n&&(n=String(n).toLowerCase(),"ucs2"===n||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||e.length<2)return-1;s=2,a/=2,u/=2,r/=2}var c;if(i){var p=-1;for(c=r;c<a;c++)if(o(t,c)===o(e,p===-1?0:c-p)){if(p===-1&&(p=c),c-p+1===u)return p*s}else p!==-1&&(c-=c-p),p=-1}else for(r+u>a&&(r=a-u),c=r;c>=0;c--){for(var h=!0,l=0;l<u;l++)if(o(t,c+l)!==o(e,l)){h=!1;break}if(h)return c}return-1}function S(t,e,r,n){r=Number(r)||0;var i=t.length-r;n?(n=Number(n),n>i&&(n=i)):n=i;var o=e.length;if(o%2!==0)throw new TypeError("InvalidLine truncated
}},function(t,e,r){function n(t){return this instanceof n?void i.call(this,t):new n(t)}t.exports=n;var i=r(64),o=r(59);o.inherits=r(5),o.inherits(n,i),n.prototype._transform=function(t,e,r){r(null,t)}},function(t,e,r){t.exports=r(62)},function(t,e,r){t.exports=r(61)},function(t,e,r){t.exports=r(64)},function(t,e,r){t.exports=r(65)},function(t,e){},function(t,e,r){function n(t){this._cbs=t||{}}t.exports=n;var i=r(36).EVENTS;Object.keys(i).forEach(function(t){if(0===i[t])t="on"+t,n.prototype[t]=function(){this._cbs[t]&&this._cbs[t]()};else if(1===i[t])t="on"+t,n.prototype[t]=function(e){this._cbs[t]&&this._cbs[t](e)};else{if(2!==i[t])throw Error("wrong number of arguments");t="on"+t,n.prototype[t]=function(e,r){this._cbs[t]&&this._cbs[t](e,r)}}})},function(t,e,r){var n=t.exports;[r(73),r(79),r(80),r(81),r(82),r(83)].forEach(function(t){Object.keys(t).forEach(function(e){n[e]=t[e].bind(n)})})},function(t,e,r){function n(t,e){return t.children?t.children.map(function(t){return s(t,e)}).join(""):""}function i(t){return Array.isArray(t)?t.map(i).join(""):a(t)||t.type===o.CDATA?i(t.children):t.type===o.Text?t.data:""}var o=r(45),s=r(74),a=o.isTag;t.exports={getInnerHTML:n,getOuterHTML:s,getText:i}},function(t,e,r){function n(t,e){if(t){var r,n="";for(var i in t)r=t[i],n&&(n+=" "),n+=!r&&h[i]?i:i+'="'+(e.decodeEntities?p.encodeXML(r):r)+'"';return n}}function i(t,e){"svg"===t.name&&(e={decodeEntities:e.decodeEntities,xmlMode:!0});var r="<"+t.name,i=n(t.attribs,e);return i&&(r+=" "+i),!e.xmlMode||t.children&&0!==t.children.length?(r+=">",t.children&&(r+=d(t.children,e)),f[t.name]&&!e.xmlMode||(r+="</"+t.name+">")):r+="/>",r}function o(t){return"<"+t.data+">"}function s(t,e){var r=t.data||"";return!e.decodeEntities||t.parent&&t.parent.name in l||(r=p.encodeXML(r)),r}function a(t){return"<![CDATA["+t.children[0].data+"]]>"}function u(t){return"<!--"+t.data+"-->"}var c=r(75),p=r(76),h={__proto__:null,allowfullscreen:!0,async:!0,autofocus:!0,autoplay:!0,checked:!0,controls:!0,"default":!0,defer:!0,disabled:!0,hidden:!0,ismap:!0,loop:!0,multiple:!0,muted:!0,open:!0,readonly:!0,required:!0,reversed:!0,scoped:!0,seamless:!0,selected:!0,typemustmatch:!0},l={__proto__:null,style:!0,script:!0,xmp:!0,iframe:!0,noembed:!0,noframes:!0,plaintext:!0,noscript:!0},f={__proto__:null,area:!0,base:!0,basefont:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,isindex:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},d=t.exports=function(t,e){Array.isArray(t)||t.cheerio||(t=[t]),e=e||{};for(var r="",n=0;n<t.length;n++){var p=t[n];r+="root"===p.type?d(p.children,e):c.isTag(p)?i(p,e):p.type===c.Directive?o(p):p.type===c.Comment?u(p):p.type===c.CDATA?a(p):s(p,e)}return r}},function(t,e){t.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",isTag:function(t){return"tag"===t.type||"script"===t.type||"style"===t.type}}},function(t,e,r){var n=r(77),i=r(78);e.decode=function(t,e){return(!e||e<=0?i.XML:i.HTML)(t)},e.decodeStrict=function(t,e){return(!e||e<=0?i.XML:i.HTMLStrict)(t)},e.encode=function(t,e){return(!e||e<=0?n.XML:n.HTML)(t)},e.encodeXML=n.XML,e.encodeHTML4=e.encodeHTML5=e.encodeHTML=n.HTML,e.decodeXML=e.decodeXMLStrict=i.XML,e.decodeHTML4=e.decodeHTML5=e.decodeHTML=i.HTML,e.decodeHTML4Strict=e.decodeHTML5Strict=e.decodeHTMLStrict=i.HTMLStrict,e.escape=n.escape},function(t,e,r){function n(t){return Object.keys(t).sort().reduce(function(e,r){return e[t[r]]="&"+r+";",e},{})}function i(t){var e=[],r=[];return Object.keys(t).forEach(function(t){1===t.length?e.push("\\"+t):r.push(t)}),r.unshift("["+e.join("")+"]"),new RegExp(r.join("|"),"g")}function o(t){return"&#x"+t.charCodeAt(0).toString(16).toUpperCase()+";"}function s(t){var e=t.charCodeAt(0),r=t.charCodeAt(1),n=1024*(e-55296)+r-56320+65536;return"&#x"+n.toString(16).toUpperCase()+";"}function a(t,e){function r(e){return t[e]}return function(t){return t.replace(e,r).replace(d,s).replace(f,o)}}function u(t){return t.replace(g,o).replace(d,s).replace(f,o)}var c=n(r(43)),p=i(c);e.XML=a(c,p);var h=n(r(41)),l=i(h);e.HTML=a(h,l);var f=/[^\0-\x7F]/g,d=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,g=i(c);e.escape=u},function(t,e,r){function n(t){var e=Object.keys(t).join("|"),r=o(t);e+="|#[xX][\\da-fA-F]+|#\\d+";var n=new RegExp("&(?:"+e+");","g");return function(t){return String(t).replace(n,r)}}function i(t,e){return t<e?1:-1}function o(t){return function(e){return"#"===e.charAt(1)?c("X"===e.charAt(2)||"x"===e.charAt(2)?parseInt(e.substr(3),16):parseInt(e.substr(2),10)):t[e.slice(1,-1)]}}var s=r(41),a=r(42),u=r(43),c=r(39),p=n(u),h=n(s),l=function(){function t(t){return";"!==t.substr(-1)&&(t+=";"),p(t)}for(var e=Object.keys(a).sort(i),r=Object.keys(s).sort(i),n=0,u=0;n<r.length;n++)e[u]===r[n]?(r[n]+=";?",u++):r[n]+=";";var c=new RegExp("&(?:"+r.join("|")+"|#[xX][\\da-fA-F]+;?|#\\d+;?)","g"),p=o(s);return function(e){return String(e).replace(c,t)}}();t.exports={XML:p,HTML:l,HTMLStrict:h}},function(t,e){var Line truncated
-1169
View File
File diff suppressed because it is too large. Load diff
+1 -2
View File
@@ -3,8 +3,7 @@ var webpack = require('webpack');
module.exports = {
entry: {
'vm': './src/index.js',
'vm.min': './src/index.js',
'vm.worker': './src/worker.js'
'vm.min': './src/index.js'
},
output: {
path: __dirname,