Michael Aschauer 2015-02-13 16:46:05 +01:00
commit df90429d44
35 zmienionych plików z 4623 dodań i 1076 usunięć

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 1.5 KiB

BIN
Costumes/alonzo.png 100644

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 4.3 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
Examples/vee.xml 100644

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -20,7 +20,7 @@ visual, blocks based programming language inspired by Scratch
written by Jens Mönig and Brian Harvey
Copyright (C) 2014 by Jens Mönig and Brian Harvey
Copyright (C) 2015 by Jens Mönig and Brian Harvey
This is free software: you can redistribute it and/or modify

Wyświetl plik

@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/
// Global stuff ////////////////////////////////////////////////////////
modules.blocks = '2014-October-01';
modules.blocks = '2014-November-21';
var SyntaxElementMorph;
@ -394,10 +394,10 @@ SyntaxElementMorph.prototype.allInputs = function () {
};
SyntaxElementMorph.prototype.allEmptySlots = function () {
/*
answer empty input slots of all children excluding myself,
but omit those in nested rings (lambdas) and JS-Function primitives
*/
// answer empty input slots of all children excluding myself,
// but omit those in nested rings (lambdas) and JS-Function primitives.
// Used by the evaluator when binding implicit formal parameters
// to empty input slots
var empty = [];
if (!(this instanceof RingMorph) &&
(this.selector !== 'reportJSFunction')) {
@ -412,6 +412,26 @@ SyntaxElementMorph.prototype.allEmptySlots = function () {
return empty;
};
SyntaxElementMorph.prototype.tagExitBlocks = function (stopTag, isCommand) {
// tag 'report' and 'stop this block' blocks of all children including
// myself, with either a stopTag (for "stop" blocks) or an indicator of
// being inside a command block definition, but omit those in nested
// rings (lambdas. Used by the evaluator when entering a procedure
if (this.selector === 'doReport') {
this.partOfCustomCommand = isCommand;
} else if (this.selector === 'doStopThis') {
this.exitTag = stopTag;
} else {
if (!(this instanceof RingMorph)) {
this.children.forEach(function (morph) {
if (morph.tagExitBlocks) {
morph.tagExitBlocks(stopTag, isCommand);
}
});
}
}
};
SyntaxElementMorph.prototype.replaceInput = function (oldArg, newArg) {
var scripts = this.parentThatIsA(ScriptsMorph),
replacement = newArg,
@ -3169,9 +3189,14 @@ BlockMorph.prototype.snap = function () {
I inherit from BlockMorph adding the following most important
public accessors:
nextBlock() - set / get the block attached to my bottom
bottomBlock() - answer the bottom block of my stack
blockSequence() - answer an array of blocks starting with myself
nextBlock() - set / get the block attached to my bottom
bottomBlock() - answer the bottom block of my stack
blockSequence() - answer an array of blocks starting with myself
and the following "lexical awareness" indicators:
partOfCustomCommand - temporary bool set by the evaluator
exitTag - temporary string or number set by the evaluator
*/
// CommandBlockMorph inherits from BlockMorph:
@ -3189,6 +3214,8 @@ function CommandBlockMorph() {
CommandBlockMorph.prototype.init = function () {
CommandBlockMorph.uber.init.call(this);
this.setExtent(new Point(200, 100));
this.partOfCustomCommand = false;
this.exitTag = null;
};
// CommandBlockMorph enumerating:

23
byob.js
Wyświetl plik

@ -9,7 +9,7 @@
written by Jens Mönig
jens@moenig.org
Copyright (C) 2014 by Jens Mönig
Copyright (C) 2015 by Jens Mönig
This file is part of Snap!.
@ -106,7 +106,7 @@ SymbolMorph, isNil*/
// Global stuff ////////////////////////////////////////////////////////
modules.byob = '2014-September-30';
modules.byob = '2015-January-21';
// Declarations
@ -209,12 +209,14 @@ CustomBlockDefinition.prototype.copyAndBindTo = function (sprite) {
c.receiver = sprite; // only for (kludgy) serialization
c.declarations = copy(this.declarations); // might have to go deeper
c.body = Process.prototype.reify.call(
null,
this.body.expression,
new List(this.inputNames())
);
c.body.outerContext = null;
if (c.body) {
c.body = Process.prototype.reify.call(
null,
this.body.expression,
new List(this.inputNames())
);
c.body.outerContext = null;
}
return c;
};
@ -688,7 +690,8 @@ CustomCommandBlockMorph.prototype.labelPart = function (spec) {
return CustomCommandBlockMorph.uber.labelPart.call(this, spec);
}
if ((spec[0] === '%') && (spec.length > 1)) {
part = new BlockInputFragmentMorph(spec.slice(1));
// part = new BlockInputFragmentMorph(spec.slice(1));
part = new BlockInputFragmentMorph(spec.replace(/%/g, ''));
} else {
part = new BlockLabelFragmentMorph(spec);
part.fontSize = this.fontSize;
@ -1648,7 +1651,7 @@ BlockEditorMorph.prototype.init = function (definition, target) {
scripts = new ScriptsMorph(target);
scripts.isDraggable = false;
scripts.color = IDE_Morph.prototype.groupColor;
scripts.texture = IDE_Morph.prototype.scriptsPaneTexture;
scripts.cachedTexture = IDE_Morph.prototype.scriptsPaneTexture;
scripts.cleanUpMargin = 10;
proto = new PrototypeHatBlockMorph(this.definition);

1281
cloud.js

Plik diff jest za duży Load Diff

BIN
favicon.ico 100644

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 7.9 KiB

137
gui.js
Wyświetl plik

@ -9,7 +9,7 @@
written by Jens Mönig
jens@moenig.org
Copyright (C) 2014 by Jens Mönig
Copyright (C) 2015 by Jens Mönig
This file is part of Snap!.
@ -69,7 +69,7 @@ SpeechBubbleMorph*/
// Global stuff ////////////////////////////////////////////////////////
modules.gui = '2014-October-06';
modules.gui = '2015-February-06';
// Declarations
@ -119,7 +119,7 @@ IDE_Morph.prototype.setDefaultDesign = function () {
];
IDE_Morph.prototype.rotationStyleColors = IDE_Morph.prototype.tabColors;
IDE_Morph.prototype.appModeColor = new Color();
IDE_Morph.prototype.scriptsPaneTexture = 'scriptsPaneTexture.gif';
IDE_Morph.prototype.scriptsPaneTexture = this.scriptsTexture();
IDE_Morph.prototype.padding = 5;
SpriteIconMorph.prototype.labelColor
@ -172,6 +172,22 @@ IDE_Morph.prototype.setFlatDesign = function () {
= IDE_Morph.prototype.buttonLabelColor;
};
IDE_Morph.prototype.scriptsTexture = function () {
var pic = newCanvas(new Point(100, 100)), // bigger scales faster
ctx = pic.getContext('2d'),
i;
for (i = 0; i < 100; i += 4) {
ctx.fillStyle = this.frameColor.toString();
ctx.fillRect(i, 0, 1, 100);
ctx.fillStyle = this.groupColor.lighter(6).toString();
ctx.fillRect(i + 1, 0, 1, 100);
ctx.fillRect(i + 3, 0, 1, 100);
ctx.fillStyle = this.groupColor.toString();
ctx.fillRect(i + 2, 0, 1, 100);
}
return pic;
};
IDE_Morph.prototype.setDefaultDesign();
// IDE_Morph instance creation:
@ -233,10 +249,6 @@ IDE_Morph.prototype.init = function (isAutoFill) {
IDE_Morph.prototype.openIn = function (world) {
var hash, usr, myself = this, urlLanguage = null;
this.buildPanes();
world.add(this);
world.userMenu = this.userMenu;
// get persistent user data, if any
if (localStorage) {
usr = localStorage['-snap-user'];
@ -245,10 +257,17 @@ IDE_Morph.prototype.openIn = function (world) {
if (usr) {
SnapCloud.username = usr.username || null;
SnapCloud.password = usr.password || null;
if (SnapCloud.username) {
this.source = 'cloud';
}
}
}
}
this.buildPanes();
world.add(this);
world.userMenu = this.userMenu;
// override SnapCloud's user message with Morphic
SnapCloud.message = function (string) {
var m = new MenuMorph(null, string),
@ -297,7 +316,6 @@ IDE_Morph.prototype.openIn = function (world) {
this.inform('Snap!', motd);
}
*/
function interpretUrlAnchors() {
var dict;
if (location.hash.substr(0, 6) === '#open:') {
@ -350,6 +368,7 @@ IDE_Morph.prototype.openIn = function (world) {
function () {
msg = myself.showMessage('Opening project...');
},
function () {nop(); }, // yield (bug in Chrome)
function () {
if (projectData.indexOf('<snapdata') === 0) {
myself.rawOpenCloudDataString(projectData);
@ -371,6 +390,46 @@ IDE_Morph.prototype.openIn = function (world) {
},
this.cloudError()
);
} else if (location.hash.substr(0, 7) === '#cloud:') {
this.shield = new Morph();
this.shield.alpha = 0;
this.shield.setExtent(this.parent.extent());
this.parent.add(this.shield);
myself.showMessage('Fetching project\nfrom the cloud...');
// make sure to lowercase the username
dict = SnapCloud.parseDict(location.hash.substr(7));
dict.Username = dict.Username.toLowerCase();
SnapCloud.getPublicProject(
SnapCloud.encodeDict(dict),
function (projectData) {
var msg;
myself.nextSteps([
function () {
msg = myself.showMessage('Opening project...');
},
function () {nop(); }, // yield (bug in Chrome)
function () {
if (projectData.indexOf('<snapdata') === 0) {
myself.rawOpenCloudDataString(projectData);
} else if (
projectData.indexOf('<project') === 0
) {
myself.rawOpenProjectString(projectData);
}
myself.hasChangedMedia = true;
},
function () {
myself.shield.destroy();
myself.shield = null;
msg.destroy();
myself.toggleAppMode(false);
}
]);
},
this.cloudError()
);
} else if (location.hash.substr(0, 6) === '#lang:') {
urlLanguage = location.hash.substr(6);
this.setLanguage(urlLanguage);
@ -1149,7 +1208,7 @@ IDE_Morph.prototype.createSpriteEditor = function () {
if (this.currentTab === 'scripts') {
scripts.isDraggable = false;
scripts.color = this.groupColor;
scripts.texture = this.scriptsPaneTexture;
scripts.cachedTexture = this.scriptsPaneTexture;
this.spriteEditor = new ScrollFrameMorph(
scripts,
@ -2043,6 +2102,7 @@ IDE_Morph.prototype.cloudMenu = function () {
'Opening project...'
);
},
function () {nop(); }, // yield (Chrome)
function () {
myself.rawOpenCloudDataString(
projectData
@ -2506,13 +2566,14 @@ IDE_Morph.prototype.aboutSnap = function () {
world = this.world();
aboutTxt = 'Snap! 4.0\nBuild Your Own Blocks\n\n--- beta ---\n\n'
+ 'Copyright \u24B8 2014 Jens M\u00F6nig and '
+ 'Copyright \u24B8 2015 Jens M\u00F6nig and '
+ 'Brian Harvey\n'
+ 'jens@moenig.org, bh@cs.berkeley.edu\n\n'
+ 'Snap! is developed by the University of California, Berkeley\n'
+ ' with support from the National Science Foundation '
+ 'and MioSoft. \n'
+ ' with support from the National Science Foundation, '
+ 'MioSoft, \n'
+ 'and the Communications Design Group at SAP Labs. \n'
+ 'The design of Snap! is influenced and inspired by Scratch,\n'
+ 'from the Lifelong Kindergarten group at the MIT Media Lab\n\n'
@ -2921,6 +2982,7 @@ IDE_Morph.prototype.openProjectString = function (str) {
function () {
msg = myself.showMessage('Opening project...');
},
function () {nop(); }, // yield (bug in Chrome)
function () {
myself.rawOpenProjectString(str);
},
@ -2939,12 +3001,18 @@ IDE_Morph.prototype.rawOpenProjectString = function (str) {
StageMorph.prototype.enableCodeMapping = false;
if (Process.prototype.isCatchingErrors) {
try {
this.serializer.openProject(this.serializer.load(str), this);
this.serializer.openProject(
this.serializer.load(str, this),
this
);
} catch (err) {
this.showMessage('Load failed: ' + err);
}
} else {
this.serializer.openProject(this.serializer.load(str), this);
this.serializer.openProject(
this.serializer.load(str, this),
this
);
}
this.stopFastTracking();
};
@ -2956,6 +3024,7 @@ IDE_Morph.prototype.openCloudDataString = function (str) {
function () {
msg = myself.showMessage('Opening project...');
},
function () {nop(); }, // yield (bug in Chrome)
function () {
myself.rawOpenCloudDataString(str);
},
@ -2976,7 +3045,10 @@ IDE_Morph.prototype.rawOpenCloudDataString = function (str) {
model = this.serializer.parse(str);
this.serializer.loadMediaModel(model.childNamed('media'));
this.serializer.openProject(
this.serializer.loadProjectModel(model.childNamed('project')),
this.serializer.loadProjectModel(
model.childNamed('project'),
this
),
this
);
} catch (err) {
@ -2986,7 +3058,10 @@ IDE_Morph.prototype.rawOpenCloudDataString = function (str) {
model = this.serializer.parse(str);
this.serializer.loadMediaModel(model.childNamed('media'));
this.serializer.openProject(
this.serializer.loadProjectModel(model.childNamed('project')),
this.serializer.loadProjectModel(
model.childNamed('project'),
this
),
this
);
}
@ -3000,6 +3075,7 @@ IDE_Morph.prototype.openBlocksString = function (str, name, silently) {
function () {
msg = myself.showMessage('Opening blocks...');
},
function () {nop(); }, // yield (bug in Chrome)
function () {
myself.rawOpenBlocksString(str, name, silently);
},
@ -3046,6 +3122,7 @@ IDE_Morph.prototype.openSpritesString = function (str) {
function () {
msg = myself.showMessage('Opening sprite...');
},
function () {nop(); }, // yield (bug in Chrome)
function () {
myself.rawOpenSpritesString(str);
},
@ -3322,6 +3399,15 @@ IDE_Morph.prototype.toggleAppMode = function (appMode) {
}).forEach(function (s) {
s.adjustScrollBars();
});
// prevent rotation and draggability controls from
// showing for the stage
if (this.currentSprite === this.stage) {
this.spriteBar.children.forEach(function (child) {
if (child instanceof PushButtonMorph) {
child.hide();
}
});
}
}
this.setExtent(this.world().extent()); // resume trackChanges
};
@ -3497,7 +3583,8 @@ IDE_Morph.prototype.userSetBlocksScale = function () {
sample = new FrameMorph();
sample.acceptsDrops = false;
sample.texture = this.scriptsPaneTexture;
sample.color = IDE_Morph.prototype.groupColor;
sample.cachedTexture = this.scriptsPaneTexture;
sample.setExtent(new Point(250, 180));
scrpt.setPosition(sample.position().add(10));
sample.add(scrpt);
@ -3970,6 +4057,9 @@ IDE_Morph.prototype.cloudResponse = function () {
IDE_Morph.prototype.cloudError = function () {
var myself = this;
// try finding an eplanation what's going on
// has some issues, commented out for now
/*
function getURL(url) {
try {
var request = new XMLHttpRequest();
@ -3983,13 +4073,15 @@ IDE_Morph.prototype.cloudError = function () {
return null;
}
}
*/
return function (responseText, url) {
// first, try to find out an explanation for the error
// and notify the user about it,
// if none is found, show an error dialog box
var response = responseText,
explanation = getURL('http://snap.berkeley.edu/cloudmsg.txt');
// explanation = getURL('http://snap.berkeley.edu/cloudmsg.txt'),
explanation = null;
if (myself.shield) {
myself.shield.destroy();
myself.shield = null;
@ -4040,14 +4132,7 @@ IDE_Morph.prototype.setCloudURL = function () {
null,
{
'Snap!Cloud' :
'https://snapcloud.miosoft.com/miocon/app/' +
'login?_app=SnapCloud',
'local network lab' :
'192.168.2.107:8087/miocon/app/login?_app=SnapCloud',
'local network office' :
'192.168.186.146:8087/miocon/app/login?_app=SnapCloud',
'localhost dev' :
'localhost/miocon/app/login?_app=SnapCloud'
'https://snap.apps.miosoft.com/SnapCloud'
}
);
};

Wyświetl plik

@ -2309,3 +2309,129 @@ ______
141008
------
* Objects: fixed #608, #610
141106
------
* Morphic: Enable mouseMove events with right button pressed
141114
------
* Threads, Store: Fix reporting out of nested custom C-shaped blocks
141117
------
* Threads, Blocks: Treat REPORT blocks inside custom command definitions as STOP THIS BLOCK / IGNORE INPUTS
141120
------
* Lists: Fixed #642 avoid “freezing” when calling CONS on non-list/null
* Threads: Fixed #364 avoid “freezing” when calling LAUNCH on empty ring
* Threads: Added optional “onComplete” callback to Process, thanks, @bromagosa!
* GUI: Set Default Save location to Cloud on load, thanks, @cycomachead!
* GUI: Updated the “About” Dialog with a mention of support from CDG (SAP Labs)
* BYOB: Percent sign fix for block labels, thanks, @natashasandy!
* Threads: fix line option in split block for Windows files, thanks, @brianharvey!
* Morphic: fix slider range 1, thanks, @tonychenr !
* translation update, thanks, Manuel!
141121
------
* Threads, Blocks: Fix STOP THIS BLOCKs lexical awareness
1411213
-------
* Threads: Fix “stop this block” primitive for tail-call-elimination
1411224
-------
* Threads: Fixed #318
* Objects: Fixed #416
* Objects: Fixed #372
* Threads: Fixed #644
* Store: Fixed #34
* Threads: Fixed #131
* snap.html, favicon.ico: new Favicon, thanks, Michael!
* Threads: improved whitespace detection for “split” primitive, thanks, Michael!
* Threads: tail-call-elimination for reporters experiment (commented out, under construction)
1411225
-------
* Threads: Evaluator optimizations (reducing the stack size for reporters)
* Threads: Full TCO (tail-call-elimination), now Snap! *is* Scheme :-)
1411225
-------
* Threads: Fixed #656
141201
------
* Objects: Hide hidden elements in the project thumbnail
* GUI: Point project dialog to cloud if already signed in, thanks, Michael!
* favicon: Transparent background, thanks, Michael!
141202
------
* New Kannada translation. Yay!! Thanks, Vinayakumar R!!
141203
------
* Morphic: Cache actual bounding box of the Pen arrow shape
* Threads, Objects: Improve edge-collision detection of default sprite “arrow” shape
141204
------
* Threads, Objects: Experimental “ForEach” primitive (hidden in dev mode)
* GUI: Another attempt at pointing the project dialog to the cloud if signed in
141205
------
* Morphic: Avoid auto-scaling artefacts in Safari on retina displays (resulting in “traces” when dragging items)
141206
------
* Store: Fixed #668
141211
------
* Threads: yield after each cycle in the experimental “forEach” primitive
141215
------
* New Swedish translation! Yay!! Thanks, Erik A Olsson!
141217
------
* Objects, Store: Experimental “processes” count watcher (hidden in dev mode)
* Threads: Remove terminated processes from expired clones
* Threads: Let “zombifying” scripts access receivers local vars
150112
------
* Cloud, GUI: Backend load balancing support, eliminate now obsolete authentication roundtrip, Cloud error message tweaks
* Store: notify users of potential incompatibilities when opening projects created in other forks (e.g. BeetleBlocks)
* Threads: Dont highlight scripts running inside clones (boosts performance), Thanks, @aranlunzer, for the hint!
* Objects: Disable clones from being edited via their context menus or double-click
* Italian translation update, thanks, Alberto Firpo!
* GUI: add additional yields to nextSteps() (work around a bug in Chrome)
150113
------
* BYOB: fixed #702
* GUI: fixed #680
150121
------
* Objects: Keep layering of nested sprites thru drag & drop
* GUI, Store, BYOB: Generate ScriptsPaneTexture programmatically
* GUI: Fix Zoom Dialogs sample background in “flat” design
* Updated Korean and Catalan translations, thanks, Yunjae Jang and Bernat Romagosa!
* Objects: Fix speech bubbles of dragged nested sprites
150128
------
* Objects: Fixed #710
150206
------
* GUI: Added url switch #cloud: to open a shared project in edit mode

Wyświetl plik

@ -6,7 +6,7 @@
written by Jens Mönig
Copyright (C) 2013 by Jens Mönig
Copyright (C) 2014 by Jens Mönig
This file is part of Snap!.
@ -183,9 +183,9 @@ SnapTranslator.dict.ca = {
'language_translator':
'Bernat Romagosa Carrasquer', // your name for the Translators tab
'translator_e-mail':
'tibabenfortlapalanca@gmail.com', // optional
'bromagosa@citilab.eu', // optional
'last_changed':
'2013-11-26', // this, too, will appear in the Translators tab
'2015-01-21', // this, too, will appear in the Translators tab
// GUI
// control bar:
@ -447,12 +447,20 @@ SnapTranslator.dict.ca = {
'si %b llavors %c si no %c',
'report %s':
'retorna %s',
'stop block':
'atura el bloc',
'stop script':
'atura aquest programa',
'stop all %stop':
'atura-ho tot %stop',
'stop %stopChoices':
'atura %stopChoices',
'all':
'tot',
'this script':
'aquest programa',
'this block':
'aquest block',
'stop %stopOthersChoices':
'atura %stopOthersChoices',
'all but this script':
'tot excepte aquest programa',
'other scripts in sprite':
'els altres programes d\'aquest objecte',
'pause all %pause':
'pausa-ho tot %pause',
'run %cmdRing %inputs':
@ -645,7 +653,7 @@ SnapTranslator.dict.ca = {
'Import...':
'Importar...',
'file menu import hint':
'pistes del menú d\'importació',
'carrega una llibreria de projecte\no de blocs exportada, un vestit\no un so',
'Export project as plain text...':
'Exportar projecte en text pla...',
'Export project...':
@ -676,6 +684,16 @@ SnapTranslator.dict.ca = {
'Idioma...',
'Zoom blocks...':
'Mida dels blocs...',
'Stage size...':
'Mida de l\'escenari...',
'Stage size':
'Mida de l\'escenari',
'Stage width':
'Amplada de l\'escenari',
'Stage height':
'Alçada de l\'escenari',
'Default':
'Per defecte',
'Blurred shadows':
'Ombres suavitzades',
'uncheck to use solid drop\nshadows and highlights':
@ -744,9 +762,9 @@ SnapTranslator.dict.ca = {
'marca\'m per habilitar\nles animacions de la interfície',
'Thread safe scripts':
'Fil d\'execució segur',
'uncheck to allow\nscript reentrancy':
'uncheck to allow\nscript reentrance':
'desmarca\'m per permetre\nla re-entrada als programes',
'check to disallow\nscript reentrancy':
'check to disallow\nscript reentrance':
'marca\'m per no permetre\nla re-entrada als programes',
'Prefer smooth animations':
'Suavitza les animacions',
@ -754,6 +772,12 @@ SnapTranslator.dict.ca = {
'desmarca\'m per augmentar la velocitat de\nles animacions fins la màxima capacitat d\'aquesta màquina',
'check for smooth, predictable\nanimations across computers':
'marca\'m per aconseguir unes animacions\nmés suaus i a velocitat predible en màquines diferents',
'Flat line ends':
'Línies del llapis rectes',
'check for flat ends of lines':
'marca\'m per fer que els\nextrems de les línies del\nllapis siguin rectes',
'uncheck for round ends of lines':
'desmarca\'m per fer que\nels extrems de les línies\ndel llapis siguin arrodonits',
// inputs
'with inputs':
@ -806,6 +830,8 @@ SnapTranslator.dict.ca = {
// sprites:
'edit':
'editar',
'move':
'moure',
'detach from':
'desenganxa de',
'detach all parts':
@ -878,9 +904,9 @@ SnapTranslator.dict.ca = {
// zoom blocks
'Zoom blocks':
'Canvia la mida dels blocs',
'Canvia la mida dels blocs',
'build':
'fes',
'construeix',
'your own':
'els teus propis',
'blocks':
@ -934,7 +960,7 @@ SnapTranslator.dict.ca = {
// save project
'Save Project As...':
'Anomena i desa projecte...',
'Anomena i desa projecte...',
// export blocks
'Export blocks':
@ -945,8 +971,6 @@ SnapTranslator.dict.ca = {
'aquest projecte encara no\nté cap bloc personalitzat',
'select':
'seleccionar',
'all':
'tots els blocs',
'none':
'cap bloc',
@ -1024,7 +1048,7 @@ SnapTranslator.dict.ca = {
'About Snap':
'Sobre Snap',
'Back...':
'Enrera...',
'Enrere...',
'License...':
'Llicència...',
'Modules...':
@ -1094,8 +1118,16 @@ SnapTranslator.dict.ca = {
'Buit',
// graphical effects
'brightness':
'brillantor',
'ghost':
'fantasma',
'negative':
'negatiu',
'comic':
'còmic',
'confetti':
'confeti',
// keys
'space':
@ -1187,7 +1219,7 @@ SnapTranslator.dict.ca = {
// math functions
'abs':
'abs',
'valor absolut',
'floor':
'part entera',
'sqrt':
@ -1210,6 +1242,8 @@ SnapTranslator.dict.ca = {
'e^',
// delimiters
'letter':
'lletra',
'whitespace':
'espai en blanc',
'line':

Wyświetl plik

@ -181,11 +181,11 @@ SnapTranslator.dict.it = {
'language_name':
'Italiano', // the name as it should appear in the language menu
'language_translator':
'Stefano Federici', // your name for the Translators tab
'Stefano Federici, Alberto Firpo', // your name for the Translators tab
'translator_e-mail':
's_federici@yahoo.com', // optional
's_federici@yahoo.com, albertofirpo12@gmail.com', // optional
'last_changed':
'2012-10-16', // this, too, will appear in the Translators tab
'2015-01-12', // this, too, will appear in the Translators tab
// GUI
// control bar:
@ -426,6 +426,10 @@ SnapTranslator.dict.it = {
'invia a tutti %msg e attendi',
'Message name':
'Nome messaggio',
'message':
'messaggio',
'any message':
'qualunque messaggio',
'wait %n secs':
'attendi %n secondi',
'wait until %b':
@ -444,10 +448,22 @@ SnapTranslator.dict.it = {
'risultato %s',
'stop block':
'ferma il blocco',
'all':
'tutti',
'this script':
'questo script',
'this block':
'questo Blocco',
'stop script':
'ferma lo script',
'stop all %stop':
'ferma tutto %stop',
'all but this script':
'tutto tranne questo script',
'other scripts in sprite':
'altri script dello sprite',
'pause all %pause':
'pausa tutto %pause',
'run %cmdRing %inputs':
'esegui %cmdRing %inputs',
'launch %cmdRing %inputs':
@ -533,6 +549,8 @@ SnapTranslator.dict.it = {
'falso',
'join %words':
'unione di %words',
'split %s by %delim':
'separa %s di %delim',
'hello':
'ciao',
'world':
@ -558,6 +576,8 @@ SnapTranslator.dict.it = {
'Nuova variabile',
'Variable name':
'Nome della variabile?',
'Script variable name':
'Nome della variabile locale?',
'Delete a variable':
'Cancella variabile',
@ -604,6 +624,8 @@ SnapTranslator.dict.it = {
// snap menu
'About...':
'Informazioni su Snap!...',
'Reference manual':
'Manuale',
'Snap! website':
'Sito web di Snap!',
'Download source':
@ -648,6 +670,10 @@ SnapTranslator.dict.it = {
'Importa tools',
'load the official library of\npowerful blocks':
'carica la libreria ufficiale di\nblocchi Snap',
'Libraries...':
'Modulo...',
'Import library':
'Importa modulo',
// cloud menu
'Login...':
@ -660,6 +686,16 @@ SnapTranslator.dict.it = {
'Lingua...',
'Zoom blocks...':
'Zoom dei blocchi...',
'Stage size...':
'Dimensione pannello...',
'Stage size':
'Dimensione pannello',
'Stage width':
'Larghezza pannello',
'Stage height':
'Altezza pannello',
'Default':
'Default',
'Blurred shadows':
'Ombreggiature attenuate',
'uncheck to use solid drop\nshadows and highlights':
@ -688,6 +724,13 @@ SnapTranslator.dict.it = {
'disabilitare per permettere agli slot di espellere\ni reporter inclusi al loro interno',
'Long form input dialog':
'Usa finestra degli input estesa',
'Plain prototype labels':
'Etichetta prototipo base',
'uncheck to always show (+) symbols\nin block prototype labels':
'disabilitare per visualizzare sempre (+) \nnelle etichette dei blocchi prototipo',
'check to hide (+) symbols\nin block prototype labels':
'abilitare per visualizzare sempre (+) \nnelle etichette dei blocchi prototipo',
'check to always show slot\ntypes in the input dialog':
'abilitare per mostrare sempre i tipi degli slot\nnella finestra di creazione degli input',
'uncheck to use the input\ndialog in short form':
@ -734,6 +777,13 @@ SnapTranslator.dict.it = {
'disabilitare per massima velocità\na framerate variabile',
'check for smooth, predictable\nanimations across computers':
'abilitare per avere animazioni\nfluide su tutti i computer',
'Flat line ends':
'fine linea piana',
'check for flat ends of lines':
'abilitare per fine linea netti',
'uncheck for round ends of lines':
'disabilitare per fine linea arrotondati',
// inputs
'with inputs':
@ -742,11 +792,20 @@ SnapTranslator.dict.it = {
'con variabili:',
'Input Names:':
'Con Variabili:',
'input list:':
'con liste:',
// context menus:
'help':
'aiuto',
// palette:
'hide primitives':
'nascondi primitive',
'show primitives':
'mostra primitive',
// blocks:
'help...':
'aiuto...',
@ -778,6 +837,12 @@ SnapTranslator.dict.it = {
// sprites:
'edit':
'modifica',
'move':
'muovi',
'detach from':
'stacca da',
'detach all parts':
'stacca tutte le parti',
'export...':
'esporta...',
@ -796,6 +861,15 @@ SnapTranslator.dict.it = {
'riordina gli script\nuno sotto l\'altro',
'add comment':
'aggiungi un commento',
'undrop':
'annulla cancellazione',
'undo the last\nblock drop\nin this pane':
'annulla ultima cancellazione\ndi blocco\n in questo pannello',
'scripts pic...':
'immagine script...',
'open a new window\nwith a picture of all scripts':
'apri una nuova finestra\ncon immagine dello script',
'make a block...':
'crea un blocco...',
@ -823,6 +897,8 @@ SnapTranslator.dict.it = {
// buttons
'OK':
'OK',
'Ok':
'OK',
'Cancel':
'Annulla',
'Yes':
@ -1057,8 +1133,17 @@ SnapTranslator.dict.it = {
'Vuoto',
// graphical effects
'brightness':
'Luminosita',
'ghost':
'fantasma',
'negative':
'negativo',
'comic':
'comic',
'confetti':
'confetti',
// keys
'space':
@ -1170,6 +1255,18 @@ SnapTranslator.dict.it = {
'e^':
'e^',
// delimiters
'letter':
'lettera',
'whitespace':
'spazio',
'line':
'linea',
'tab':
'tabulatore',
'cr':
'A capo',
// data types
'number':
'numero',

1273
lang-kn.js 100644

Plik diff jest za duży Load Diff

492
lang-ko.js 100644 → 100755
Wyświetl plik

@ -179,13 +179,13 @@ SnapTranslator.dict.ko = {
// translations meta information
'language_name':
'Korean', // the name as it should appear in the language menu
'한국어', // the name as it should appear in the language menu
'language_translator':
'Yunjae Jang', // your name for the Translators tab
'translator_e-mail':
'yunjae.jang@inc.korea.ac.kr', // optional
'janggoons@gmail.com', // optional
'last_changed':
'2012-11-18', // this, too, will appear in the Translators tab
'2015-01-21', // this, too, will appear in the Translators tab
// GUI
// control bar:
@ -218,7 +218,7 @@ SnapTranslator.dict.ko = {
// editor:
'draggable':
'드래그 가능?',
'마우스로 직접 움직이기',
// tabs:
'Scripts':
@ -243,8 +243,16 @@ SnapTranslator.dict.ko = {
'왼쪽에서 오른쪽으로만',
// new sprite button:
'add a new sprite':
'새로운 스프라이트 추가',
'add a new Turtle sprite':
'새로운 스프라이트 추가하기',
// new paint sprite button:
'paint a new sprite':
'새로운 스프라이트 그리기',
// new paint costume button:
'Paint a new costume':
'새로운 모양 그리기',
// tab help
'costumes tab help':
@ -300,19 +308,19 @@ SnapTranslator.dict.ko = {
'point towards %dst':
'%dst 쪽 보기',
'go to x: %n y: %n':
'x: %n 、y: %n 쪽으로 기',
'x: %n 、y: %n 쪽으로 이동하기',
'go to %dst':
'%dst 위치로 기',
'%dst 위치로 이동하기',
'glide %n secs to x: %n y: %n':
'%n 초 동안 x: %n 、y: %n 쪽으로 움직이기',
'%n 초 동안 x: %n 、y: %n 쪽으로 동하기',
'change x by %n':
'x좌표 %n 만큼 바꾸기',
'set x to %n':
'x좌표 %n 로 정하기',
'x좌표 %n (으)로 정하기',
'change y by %n':
'y좌표 %n 만큼 바꾸기',
'set y to %n':
'y좌표 %n 로 정하기',
'y좌표 %n (으)로 정하기',
'if on edge, bounce':
'벽에 닿으면 튕기기',
'x position':
@ -328,13 +336,13 @@ SnapTranslator.dict.ko = {
'next costume':
'다음 모양',
'costume #':
'모양 #',
'모양 번호',
'say %s for %n secs':
'%s %n 초 동안 말하기',
'%s 을(를) %n 초 동안 말하기',
'say %s':
'%s 말하기',
'think %s for %n secs':
'%s %n 초간 생각하기',
'%s 을(를) %n 초 동안 생각하기',
'think %s':
'%s 생각하기',
'Hello!':
@ -342,15 +350,15 @@ SnapTranslator.dict.ko = {
'Hmm...':
'흠…',
'change %eff effect by %n':
'%eff 효과 %n 만큼 바꾸기',
'%eff 효과 %n 만큼 바꾸기',
'set %eff effect to %n':
'%eff 효과 %n 만큼 주기',
'%eff 효과를 %n 만큼 정하기',
'clear graphic effects':
'그래픽 효과 지우기',
'change size by %n':
'크기 %n 만큼 바꾸기',
'크기 %n 만큼 바꾸기',
'set size to %n %':
'크기 %n % 로 정하기',
'크기 %n % 로 정하기',
'size':
'크기',
'show':
@ -373,82 +381,96 @@ SnapTranslator.dict.ko = {
'play sound %snd':
'%snd 소리내기',
'play sound %snd until done':
'끝날때까지 %snd 소리내기',
'%snd 을(를) 끝까지 소리내기',
'stop all sounds':
'모든 소리 끄기',
'rest for %n beats':
'%n 비트 동안 쉬기',
'%n 박자 동안 쉬기',
'play note %n for %n beats':
'%n 음을 %n 비트로 연주하기',
'%n 음을 %n 박자로 연주하기',
'change tempo by %n':
'템포를 %n 만큼 바꾸기',
'빠르기를 %n 만큼 바꾸기',
'set tempo to %n bpm':
'템포를 %n bpm으로 맞추기',
'빠르기를 %n bpm으로 정하기',
'tempo':
'템포',
'빠르기',
// pen:
'clear':
'지우기',
'펜 자국 지우기',
'pen down':
'펜 내리기',
'pen up':
'펜 올리기',
'set pen color to %clr':
'펜 색 %clr 으로 정하기',
'펜깔을 %clr 으로 정하기',
'change pen color by %n':
'펜 색 %n 만큼 바꾸기',
'펜깔을 %n 만큼 바꾸기',
'set pen color to %n':
'펜 색 %n 으로 정하기',
'펜깔을 %n ()로 정하기',
'change pen shade by %n':
'펜의 그림자 %n 만큼 바꾸기',
'펜 음영을 %n 만큼 바꾸기',
'set pen shade to %n':
'펜의 그림자 %n 으로 정하기',
'펜 음영을 %n 으로 정하기',
'change pen size by %n':
'펜의 크기 %n 만큼 바꾸기',
'펜 굵기를 %n 만큼 바꾸기',
'set pen size to %n':
'펜의 크기 %n 으로 정하기',
'펜 굵기를 %n (으)로 정하기',
'stamp':
'스탬프',
'도장찍기',
// control:
'when %greenflag clicked':
'%greenflag 클릭되었을 때',
'%greenflag 클릭을 때',
'when %keyHat key pressed':
'%keyHat 키 눌렀을 때',
'%keyHat 키 눌렀을 때',
'when I am clicked':
'자신이 클릭되었을 때',
'이 스프라이트를 클릭했을 때',
'when I receive %msgHat':
'%msgHat 받을 때',
'%msgHat 을(를) 을 때',
'broadcast %msg':
'%msg 방송하기',
'broadcast %msg and wait':
'%msg 방송하고 기다리기',
'Message name':
'메세지 이름',
'메시지 이름',
'message':
'메시지',
'any message':
'어떤 메시지',
'wait %n secs':
'%n 초 기다리기',
'wait until %b':
'%b 까지 기다리기',
'forever %c':
'무한반복 %c',
'무한 반복하기 %c',
'repeat %n %c':
'반복 %n 회 %c',
'%n 번 반복하기 %c',
'repeat until %b %c':
'반복 %b 계속 확인 %c',
'%b 까지 반복하기 %c',
'if %b %c':
'만약 %b 라면 %c',
'if %b %c else %c':
'만약 %b 라면 %c 아니면 %c',
'report %s':
'%s 출력하기',
'stop block':
'블록 멈추기',
'stop script':
'스크립트 멈추기',
'stop all %stop':
'모두 멈추기 %stop',
'stop %stopChoices':
'%stopChoices 멈추기',
'all':
'모두',
'this script':
'이 스크립트',
'this block':
'이 블록',
'stop %stopOthersChoices':
'%stopOthersChoices 멈추기',
'all but this script':
'이 스크립트를 제외한 모두',
'other scripts in sprite':
'이 스프라이트에 있는 다른 스크립트',
'pause all %pause':
'모두 잠시 멈추기 %pause',
'run %cmdRing %inputs':
'%cmdRing 을(를) %inputs 으로 실행하기',
'launch %cmdRing %inputs':
@ -461,14 +483,23 @@ SnapTranslator.dict.ko = {
'반복해서 %cmdRing 을(를) 호출하기',
'warp %c':
'워프 %c',
'when I start as a clone':
'복제되었을 때',
'create a clone of %cln':
'%cln 을(를) 복제하기',
'myself':
'나 자신',
'delete this clone':
'이 복제본 삭제하기',
// sensing:
'touching %col ?':
'%col 에 닿기?',
'%col 에 닿았는가?',
'touching %clr ?':
'%clr 색에 닿기?',
'%clr 색에 닿았는가?',
'color %clr is touching %clr ?':
'%clr 색이 %clr 색에 닿기?',
'%clr 색이 %clr 색에 닿았는가?',
'ask %s and wait':
'%s 을(를) 묻고 기다리기',
'what\'s your name?':
@ -476,36 +507,59 @@ SnapTranslator.dict.ko = {
'answer':
'대답',
'mouse x':
'마우스 x좌표',
'마우스 x좌표',
'mouse y':
'마우스 y좌표',
'마우스 y좌표',
'mouse down?':
'마우스 클릭하기?',
'마우스를 클릭했는가?',
'key %key pressed?':
'%key 키 클릭하기?',
'%key 키를 눌렀는가?',
'distance to %dst':
'%dst 까지 거리',
'reset timer':
'타이머 초기화',
'timer':
'타이머',
'%att of %spr':
'%att ( %spr 에 대한)',
'http:// %s':
'http:// %s',
'turbo mode?':
'터보 모드인가?',
'set turbo mode to %b':
'터보 모드 %b 으로 설정하기',
'filtered for %clr':
'%clr 색 추출하기',
'stack size':
'스택 크기',
'frames':
'프레임',
'current %dates':
'현재 %dates',
'year':
'연도',
'month':
'월',
'date':
'일',
'day of week':
'요일(1~7)',
'hour':
'시간',
'minute':
'분',
'second':
'초',
'time in milliseconds':
'밀리세컨드초',
// operators:
'%n mod %n':
'%n 나누기 %n 의 나머지',
'( %n / %n ) 의 나머지',
'round %n':
'%n 반올림',
'%fun of %n':
'%n 의 %fun',
'%fun ( %n 에 대한)',
'pick random %n to %n':
'%n 부터 %n 사이의 난수',
'%b and %b':
@ -520,12 +574,14 @@ SnapTranslator.dict.ko = {
'거짓',
'join %words':
'%words 결합하기',
'split %s by %delim':
'%s 를 %delim 기준으로 나누기',
'hello':
'안녕',
'world':
'세',
'세',
'letter %n of %s':
'%n 의 %s 번째 글자',
'%n 번째 글자 ( %s 에 대한)',
'length of %s':
'%s 의 길이',
'unicode of %s':
@ -533,9 +589,11 @@ SnapTranslator.dict.ko = {
'unicode %n as letter':
'유니코드 %n 에 대한 문자',
'is %s a %typ ?':
'%s 이(가) %typ 인가요?',
'%s 이(가) %typ 인가?',
'is %s identical to %s ?':
'%s 와(과) %s 가 동일한가?',
'type of %s':
'%s 타입',
'%s 타입',
// variables:
'Make a variable':
@ -543,12 +601,12 @@ SnapTranslator.dict.ko = {
'Variable name':
'변수 이름',
'Delete a variable':
'변수 삭제',
'변수 삭제하기',
'set %var to %s':
'%var 을(를) %s 로 저장',
'변수 %var 에 %s 저장하기',
'change %var by %n':
'%var 에 %n 씩 누적하기',
'변수 %var 을(를) %n 만큼 바꾸기',
'show variable %var':
'변수 %var 보이기',
'hide variable %var':
@ -560,38 +618,78 @@ SnapTranslator.dict.ko = {
'list %exp':
'리스트 %exp',
'%s in front of %l':
'%s 을(를) %l 처음에 추가하기 ',
'%s 을(를) 리스트 %l 의 맨 앞에 추가하기 ',
'item %idx of %l':
'%idx 항목 %l',
'%idx 번째 항목 (리스트 %l 에 대한)',
'all but first of %l':
'%l 첫번째 아이템 제외한 모든 아이템',
'리스트 %l 에서 첫 번째 항목 제외하기',
'length of %l':
'%l 의 크기',
'리스트 %l 의 항목 갯수',
'%l contains %s':
'%l 에 %s 포함?',
'리스트 %l 에 %s 포함되었는가?',
'thing':
'아이템',
'어떤 것',
'add %s to %l':
'%s 을(를) %l 마지막에 추가하기 ',
'%s 을(를) 리스트 %l 마지막에 추가하기 ',
'delete %ida of %l':
'%ida 을(를) %l 에서 삭제하기 ',
'%ida 번째 항목 삭제하기 (리스트 %l 에 대한)',
'insert %s at %idx of %l':
'%s 을(를) %idx 위치에 추가하기 %l',
'%s 을(를) %idx 위치에 추가하기 (리스트 %l 에 대한)',
'replace item %idx of %l with %s':
'%idx 항목 %l 에 %s 로 교체하기',
'%idx 번째 (리스트 %l 에 대한) 를 %s (으)로 바꾸기',
// other
'Make a block':
'블록 만들기',
// Paint Editor
'Paint Editor':
'그림 편집기',
'undo':
'되돌리기',
'grow':
'확대',
'shrink':
'축소',
'flip ↔':
'↔ 반전',
'flip ↕':
'↕ 반전',
'Brush size':
'펜 크기',
'Constrain proportions of shapes?\n(you can also hold shift)':
'도형 크기 비율을 고정하는가?\n(shift 키를 눌러서 사용할 수 있습니다.)',
'Paintbrush tool\n(free draw)':
'붓 도구',
'Stroked Rectangle\n(shift: square)':
'사각형 그리기 도구\n(shift: 정사각형)',
'Stroked Ellipse\n(shift: circle)':
'타원 그리기 도구\n(shift: 원)',
'Eraser tool':
'지우개 도구',
'Set the rotation center':
'회전축 설정하기',
'Line tool\n(shift: vertical/horizontal)':
'선 그리기 도구\n(shift: 수평/수직)',
'Filled Rectangle\n(shift: square)':
'채워진 사각형 그리기 도구\n(shift: 정사각형)',
'Filled Ellipse\n(shift: circle)':
'채워진 타원 그리기 도구\n(shift: 원)',
'Fill a region':
'색 채우기',
'Pipette tool\n(pick a color anywhere)':
'스포이드 도구\n(원하는 색 선택하기)',
// menus
// snap menu
'About...':
'Snap! 에 대해서...',
'Reference manual':
'참고자료 다운로드',
'Snap! website':
'Snap! 웹사이트',
'Download source':
'소스 다운로드',
'소스코드 다운로드',
'Switch back to user mode':
'사용자 모드로 전환',
'disable deep-Morphic\ncontext menus\nand show user-friendly ones':
@ -609,15 +707,18 @@ SnapTranslator.dict.ko = {
'Open...':
'열기...',
'Save':
'저장',
'저장하기',
'Save to disk':
'내 컴퓨터에 저장하기',
'experimental - store this project\nin your downloads folder':
'실험적 - 이 프로젝트를\n 다운로드 폴더에 저장합니다.',
'Save As...':
'다른 이름으로 저장...',
'다른 이름으로 저장하기...',
'Import...':
'가져오기...',
'file menu import hint':
'내보낸 프로젝트 파일, 블록 라이브러리\n'
+ '스프라이트 모양 또는 소리를 가져옵니다.\n\n'
+ '일부 웹브라우저에서는 지원되지 않습니다.',
+ '스프라이트 모양 또는 소리를 가져옵니다.',
'Export project as plain text...':
'프로젝트를 텍스트 파일로 내보내기...',
'Export project...':
@ -628,58 +729,171 @@ SnapTranslator.dict.ko = {
'블록 내보내기...',
'show global custom block definitions as XML\nin a new browser window':
'새롭게 정의한 전역 블록 데이터를\n새로운 윈도우에 XML 형태로 보여주기',
'Export all scripts as pic...':
'모든 스크립트를 그림파일로 내보내기',
'show a picture of all scripts\nand block definitions':
'모든 스크립트와 정의된 블록을 그림파일로 보여줍니다.',
'Import tools':
'추가 도구 가져오기',
'load the official library of\npowerful blocks':
'강력한 기능을 제공하는\n 블록들을 가져옵니다.',
'Libraries...':
'라이브러리...',
'Select categories of additional blocks to add to this project.':
'추가적인 블록을 선택해서\n 사용할 수 있습니다.',
'Import library':
'라이브러리 가져오기',
// cloud menu
'Login...':
'로그인...',
'Signup...':
'계정만들기...',
'Reset Password...':
'비밀번호 재설정...',
'url...':
'url...',
'export project media only...':
'export project media only...',
'export project without media...':
'export project without media...',
'export project as cloud data...':
'export project as cloud data...',
'open shared project from cloud...':
'open shared project from cloud...',
// settings menu
'Language...':
'언어선택...',
'Zoom blocks...':
'블록 크기 설정...',
'Stage size...':
'무대 크기 설정...',
'Stage size':
'무대 크기',
'Stage width':
'가로(너비)',
'Stage height':
'세로(높이)',
'Default':
'기본설정',
'Blurred shadows':
'반투명 그림자',
'uncheck to use solid drop\nshadows and highlights':
'체크해제하면, 그림자와 하이라이트가\n불투명 상태로 됩니다.',
'check to use blurred drop\nshadows and highlights':
'체크하면, 그림자와 하이라이트가\n반투명 상태로 됩니다.',
'Zebra coloring':
'중첩 블록 구분하기',
'check to enable alternating\ncolors for nested blocks':
'체크하면, 중첩된 블록을\n다른 색으로 구분할 수 있습니다.',
'uncheck to disable alternating\ncolors for nested block':
'체크해제하면, 중첩된 블록을\n다른 색으로 구분할 수 없습니다.',
'Dynamic input labels':
'Dynamic input labels',
'uncheck to disable dynamic\nlabels for variadic inputs':
'uncheck to disable dynamic\nlabels for variadic inputs',
'check to enable dynamic\nlabels for variadic inputs':
'check to enable dynamic\nlabels for variadic inputs',
'Prefer empty slot drops':
'빈 슬롯에 입력 가능',
'settings menu prefer empty slots hint':
'설정 메뉴에 빈 슬롯의\n힌트를 사용할 수 있습니다.',
'uncheck to allow dropped\nreporters to kick out others':
'체크해제하면, 기존 리포터 블록에\n새로운 리포터 블록으로 대체할 수 있습니다.',
'Long form input dialog':
'긴 형태의 입력 대화창',
'check to always show slot\ntypes in the input dialog':
'체크하면, 입력 대화창에\n항상 슬롯의 형태를 보여줍니다.',
'uncheck to use the input\ndialog in short form':
'체크해제하면, 입력 대화창을\n짧은 형태로 사용합니다.',
'Plain prototype labels':
'새로 만든 블록 인수 설정',
'uncheck to always show (+) symbols\nin block prototype labels':
'체크해제하면, 블록 편집기에서\n 블록 인수 추가 버튼(+)을\n 보입니다.',
'check to hide (+) symbols\nin block prototype labels':
'체크하면, 블록 편집기에서\n 블록 인수 추가 버튼(+)을\n 숨깁니다.',
'Virtual keyboard':
'가상 키보드',
'uncheck to disable\nvirtual keyboard support\nfor mobile devices':
'체크해제하면, 모바일 기기에서\n가상 키보드를 사용할 수 없습니다.',
'check to enable\nvirtual keyboard support\nfor mobile devices':
'체크하면, 모바일 기기에서\n가상 키보드를 사용할 수 있습니다.',
'Input sliders':
'입력창에서 슬라이더 사용',
'uncheck to disable\ninput sliders for\nentry fields':
'체크해제하면, 입력창에서\n슬라이더를 사용할 수 없습니다.',
'check to enable\ninput sliders for\nentry fields':
'체크하면, 입력창에서\n슬라이더를 사용할 수 있습니다.',
'Clicking sound':
'블록 클릭시 소리',
'uncheck to turn\nblock clicking\nsound off':
'체크해제하면, 블록 클릭시\n소리가 꺼집니다.',
'check to turn\nblock clicking\nsound on':
'체크하면, 블록 클릭시\n소리가 켜집니다.',
'Animations':
'애니메이션',
'uncheck to disable\nIDE animations':
'체크해제하면, IDE 애니메이션을\n 사용할 수 없습니다.',
'Turbo mode':
'터보 모드',
'check to prioritize\nscript execution':
'체크하면, 스크립트를\n 빠르게 실행합니다.',
'uncheck to run scripts\nat normal speed':
'체크해제하면, 스크립트 실행 속도를\n 보통으로 합니다.',
'Flat design':
'플랫(Flat) 디자인',
'uncheck for default\nGUI design':
'체크해제하면,\n 기본 GUI 디자인으로\n 변경합니다.',
'check for alternative\nGUI design':
'체크하면, 플랫(Flat)\n 디자인으로 변경합니다.',
'Sprite Nesting':
'Sprite Nesting',
'uncheck to disable\nsprite composition':
'uncheck to disable\nsprite composition',
'check to enable\nsprite composition':
'check to enable\nsprite composition',
'Thread safe scripts':
'스레드 안전 스크립트',
'uncheck to allow\nscript reentrancy':
'uncheck to allow\nscript reentrance':
'체크해제하면, 스크립트\n재진입성을 허락합니다.',
'check to disallow\nscript reentrancy':
'check to disallow\nscript reentrance':
'체크하면, 스크립트\n재진입성을 허락하지 않습니다.',
'Prefer smooth animations':
'자연스러운 애니메이션',
'uncheck for greater speed\nat variable frame rates':
'체크해제하면, 프레임\n 전환 비율이 빨라집니다.',
'check for smooth, predictable\nanimations across computers':
'체크하면, 애니메이션이\n 자연스러워 집니다.',
'Flat line ends':
'선 끝을 평평하게 만들기',
'check for flat ends of lines':
'체크하면, 선 끝을\n 평평하게 만듭니다.',
'uncheck for round ends of lines':
'체크해제하면, 선 끝을\n 둥글게 만듭니다.',
'Codification support':
'체계화 지원',
'uncheck to disable\nblock to text mapping features':
'uncheck to disable\nblock to text mapping features',
'check for block\nto text mapping features':
'체크하면, check for block\nto text mapping features',
// inputs
'with inputs':
@ -692,35 +906,55 @@ SnapTranslator.dict.ko = {
// context menus:
'help':
'도움말',
// palette:
'find blocks...':
'블록 찾기...',
'hide primitives':
'기본 블록 숨기기',
'show primitives':
'기본 블록 보이기',
// blocks:
'help...':
'블록 도움말...',
'relabel...':
'블록 바꾸기...',
'duplicate':
'복사',
'복사하기',
'make a copy\nand pick it up':
'복사해서\n그 블록을 들고 있습니다.',
'복사해서\n들고 있습니다.',
'delete':
'삭제',
'삭제하기',
'script pic...':
'스크립트 그림...',
'스크립트 그림파일로 내보내기...',
'open a new window\nwith a picture of this script':
'이 스크립트 그림을\n새로운 윈도우에서 엽니다.',
'ringify':
'형태변환',
'블록형태 변환하기',
'unringify':
'unringify',
// custom blocks:
'delete block definition...':
'블록 삭제',
'블록 삭제하기',
'edit...':
'편집…',
// sprites:
'edit':
'편집',
'스크립트 편집하기',
'export...':
'내보내기...',
// stage:
'show all':
'모든 스프라이트 나타내기',
'pic...':
'그림파일로 내보내기...',
'open a new window\nwith a picture of the stage':
'새로운 창을 열고\n무대의 화면을\n그림파일로 저장한다.',
// scripting area
'clean up':
'스크립트 정리하기',
@ -728,12 +962,20 @@ SnapTranslator.dict.ko = {
'스크립트를\n수직으로 정렬한다.',
'add comment':
'주석 추가하기',
'undrop':
'마지막으로 가져온 블록',
'undo the last\nblock drop\nin this pane':
'마지막으로\n 가져온 블록을\n 확인한다.',
'scripts pic...':
'모든 스크립트를 그림파일로 내보내기...',
'open a new window\nwith a picture of all scripts':
'새로운 창을 열어서\n 모든 스크립트를\n 그림으로 저장한다.',
'make a block...':
'블록 만들기...',
// costumes
'rename':
'이름수정',
'이름 수정하기',
'export':
'내보내기',
@ -750,7 +992,9 @@ SnapTranslator.dict.ko = {
// dialogs
// buttons
'OK':
'OK',
'확인',
'Ok':
'확인',
'Cancel':
'취소',
'Yes':
@ -762,6 +1006,31 @@ SnapTranslator.dict.ko = {
'Help':
'도움말',
// zoom blocks
'Zoom blocks':
'블록 크기 설정',
'build':
'만들기',
'your own':
'나만의',
'blocks':
'블록',
'normal (1x)':
'기본 크기 (1x)',
'demo (1.2x)':
'데모 크기 (1.2x)',
'presentation (1.4x)':
'발표용 크기 (1.4x)',
'big (2x)':
'큰 크기 (2x)',
'huge (4x)':
'매우 큰 크기(4x)',
'giant (8x)':
'정말 큰 크기 (8x)',
'monstrous (10x)':
'믿을 수 없는 크기 (10x)',
// costume editor
'Costume Editor':
'모양 편집기',
@ -822,7 +1091,7 @@ SnapTranslator.dict.ko = {
// block deletion dialog
'Delete Custom Block':
'블록 삭제',
'블록 삭제하기',
'block deletion dialog text':
'이 블록과 모든 인스턴스를\n 삭제해도 괜찮습니까?',
@ -911,6 +1180,8 @@ SnapTranslator.dict.ko = {
// coments
'add comment here...':
'여기에 주석 추가…',
'comment pic...':
'주석을 그림파일로 내보내기...',
// drow downs
// directions
@ -933,11 +1204,22 @@ SnapTranslator.dict.ko = {
// costumes
'Turtle':
'터틀',
'화살표',
'Empty':
'Leer',
// graphical effects
// graphical effects
'brightness':
'밝기',
'ghost':
'유령',
'negative':
'반전',
'comic':
'코믹',
'confetti':
'색종이',
// keys
'space':
@ -1029,9 +1311,11 @@ SnapTranslator.dict.ko = {
// math functions
'abs':
'절대값',
'절대값(abs)',
'sqrt':
'제곱근',
'제곱근(sqrt)',
'floor':
'바닥(floor)',
'sin':
'sin',
'cos':
@ -1049,11 +1333,23 @@ SnapTranslator.dict.ko = {
'e^':
'e^',
// delimiters
'letter':
'글자',
'whitespace':
'빈칸',
'line':
'줄',
'tab':
'탭',
'cr':
'새줄(cr)',
// data types
'number':
'숫자',
'text':
'텍스트',
'문자',
'Boolean':
'불리언',
'list':
@ -1087,12 +1383,12 @@ SnapTranslator.dict.ko = {
'Are you sure you want to delete':
'정말로 삭제합니까?',
'unringify':
'형태변환취소',
'블록형태변환 취소하기',
'rename...':
'이름수정...',
'(180) down':
'(180) 아래',
'Ok':
'OK'
'확인'
};

Wyświetl plik

@ -650,11 +650,12 @@ SnapTranslator.dict.pt = {
'Save As...':
'Guardar este projecto como…',
'Import...':
'Importar para este projecto…',
'Importar…',
'file menu import hint':
'Importar para este projecto\num projecto exportado,\n'
+ 'uma biblioteca de blocos,\n'
+ 'um traje ou um som.',
'Abrir um projecto exportado,\n'
+ 'substitundo o projecto corrente, ou\n'
+ 'importar uma biblioteca de blocos, um\n'
+ 'traje ou um som para o projecto corrente.',
'Export project as plain text...':
'Exportar este projecto como texto simples…',
'Export project...':
@ -1616,7 +1617,7 @@ SnapTranslator.dict.pt = {
'unshared.':
'deixado de partilhar.',
'Unshare':
'Deixar de Partilhar',
'Não Partilhar',
'password has been changed.':
'a sua palavra-passe foi alterada.',
'SVG costumes are\nnot yet fully supported\nin every browser':
@ -1641,6 +1642,18 @@ SnapTranslator.dict.pt = {
'Seleccionar um traje da biblioteca de média.',
'edit rotation point only...':
'editar apenas ponto de rotação…',
'Export Project As...':
'Exportar Projecto Como…',
'a variable of name \'':
'não existe uma variável «',
'\'\ndoes not exist in this context':
'»\nneste contexto',
'(temporary)':
'(temporária)',
'expecting':
'esperavam-se',
'input(s), but getting':
'argumento(s), mas foram passados',
// produção de código
'map %cmdRing to %codeKind %code':

1359
lang-sv.js 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -61,7 +61,7 @@ PushButtonMorph, SyntaxElementMorph, Color, Point, WatcherMorph,
StringMorph, SpriteMorph, ScrollFrameMorph, CellMorph, ArrowMorph,
MenuMorph, snapEquals, Morph, isNil, localize, MorphicPreferences*/
modules.lists = '2014-July-28';
modules.lists = '2014-November-20';
var List;
var ListWatcherMorph;
@ -125,6 +125,9 @@ List.prototype.changed = function () {
List.prototype.cons = function (car, cdr) {
var answer = new List();
if (!(cdr instanceof List || isNil(cdr))) {
throw new Error("cdr isn't a list: " + cdr);
}
answer.first = isNil(car) ? null : car;
answer.rest = cdr || null;
answer.isLinked = true;

Wyświetl plik

@ -6,7 +6,7 @@
written by Jens Mönig
Copyright (C) 2014 by Jens Mönig
Copyright (C) 2015 by Jens Mönig
This file is part of Snap!.
@ -42,7 +42,7 @@
/*global modules, contains*/
modules.locale = '2014-October-01';
modules.locale = '2015-January-21';
// Global stuff
@ -157,11 +157,11 @@ SnapTranslator.dict.it = {
'language_name':
'Italiano',
'language_translator':
'Stefano Federici',
'Stefano Federici, Alberto Firpo',
'translator_e-mail':
's_federici@yahoo.com',
's_federici@yahoo.com, albertofirpo12@gmail.com',
'last_changed':
'2013-04-08'
'2015-01-12'
};
SnapTranslator.dict.ja = {
@ -195,9 +195,9 @@ SnapTranslator.dict.ko = {
'language_translator':
'Yunjae Jang',
'translator_e-mail':
'yunjae.jang@inc.korea.ac.kr',
'janggoons@gmail.com',
'last_changed':
'2012-11-18'
'2015-01-21'
};
SnapTranslator.dict.pt = {
@ -375,9 +375,9 @@ SnapTranslator.dict.ca = {
'language_translator':
'Bernat Romagosa Carrasquer',
'translator_e-mail':
'tibabenfortlapalanca@gmail.com',
'bromagosa@citilab.eu',
'last_changed':
'2013-11-26'
'2015-01-21'
};
SnapTranslator.dict.fi = {
@ -392,6 +392,18 @@ SnapTranslator.dict.fi = {
'2014-04-18'
};
SnapTranslator.dict.sv = {
// meta information
'language_name':
'svenska',
'language_translator':
'Erik A. Olsson',
'translator_e-mail':
'eolsson@gmail.com',
'last_changed':
'2014-12-14'
};
SnapTranslator.dict.pt_BR = {
// meta information
'language_name':
@ -415,3 +427,15 @@ SnapTranslator.dict.bn = {
'last_changed':
'2014-07-02'
};
SnapTranslator.dict.kn = {
// translations meta information
'language_name':
'\u0C95\u0CA8\u0CCD\u0CA8\u0CA1',
'language_translator':
'Vinayakumar R',
'translator_e-mail':
'vnkmr7620@gmail.com',
'last_changed':
'2014-12-02'
};

Wyświetl plik

@ -10,5 +10,4 @@ threads.js
widgets.js
store.js
xml.js
scriptsPaneTexture.gif
snap_logo_sm.gif
snap_logo_sm.png

Wyświetl plik

@ -464,9 +464,15 @@
MyMorph.prototype.mouseMove = function(pos) {};
The only optional parameter of such a method is a Point object
All of these methods have as optional parameter a Point object
indicating the current position of the Hand inside the World's
coordinate system.
coordinate system. The
mouseMove(pos, button)
event method has an additional optional parameter indicating the
currently pressed mouse button, which is either 'left' or 'right'.
You can use this to let users interact with 3D environments.
Events may be "bubbled" up a morph's owner chain by calling
@ -1035,7 +1041,7 @@
/*global window, HTMLCanvasElement, getMinimumFontHeight, FileReader, Audio,
FileList, getBlurredShadowSupport*/
var morphicVersion = '2014-September-30';
var morphicVersion = '2014-December-05';
var modules = {}; // keep track of additional loaded modules
var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug
@ -1925,7 +1931,9 @@ Rectangle.prototype.round = function () {
Rectangle.prototype.spread = function () {
// round me by applying floor() to my origin and ceil() to my corner
return this.origin.floor().corner(this.corner.ceil());
// expand by 1 to be on the safe side, this eliminates rounding
// artefacts caused by Safari's auto-scaling on retina displays
return this.origin.floor().corner(this.corner.ceil()).expandBy(1);
};
Rectangle.prototype.amountToTranslateWithin = function (aRect) {
@ -3972,6 +3980,7 @@ PenMorph.prototype.init = function () {
this.size = 1;
this.wantsRedraw = false;
this.penPoint = 'tip'; // or 'center"
this.penBounds = null; // rect around the visible arrow shape
HandleMorph.uber.init.call(this);
this.setExtent(new Point(size, size));
@ -3994,11 +4003,9 @@ PenMorph.prototype.changed = function () {
// PenMorph display:
PenMorph.prototype.drawNew = function (facing) {
/*
my orientation can be overridden with the "facing" parameter to
implement Scratch-style rotation styles
// my orientation can be overridden with the "facing" parameter to
// implement Scratch-style rotation styles
*/
var context, start, dest, left, right, len,
direction = facing || this.heading;
@ -4021,6 +4028,15 @@ PenMorph.prototype.drawNew = function (facing) {
right = start.distanceAngle(len * 0.33, direction - 230);
}
// cache penBounds
this.penBounds = new Rectangle(
Math.min(start.x, dest.x, left.x, right.x),
Math.min(start.y, dest.y, left.y, right.y),
Math.max(start.x, dest.x, left.x, right.x),
Math.max(start.y, dest.y, left.y, right.y)
);
// draw arrow shape
context.fillStyle = this.color.toString();
context.beginPath();
@ -4037,7 +4053,6 @@ PenMorph.prototype.drawNew = function (facing) {
context.lineWidth = 1;
context.stroke();
context.fill();
};
// PenMorph access:
@ -5754,7 +5769,7 @@ SliderMorph.prototype.rangeSize = function () {
};
SliderMorph.prototype.ratio = function () {
return this.size / this.rangeSize();
return this.size / (this.rangeSize() + 1);
};
SliderMorph.prototype.unitSize = function () {
@ -9346,11 +9361,11 @@ HandMorph.prototype.init = function (aWorld) {
this.world = aWorld;
this.mouseButton = null;
this.mouseOverList = [];
this.mouseDownMorph = null;
this.morphToGrab = null;
this.grabOrigin = null;
this.temporaries = [];
this.touchHoldTimeout = null;
this.contextMenuEnabled = false;
};
HandMorph.prototype.changed = function () {
@ -9494,9 +9509,10 @@ HandMorph.prototype.drop = function () {
*/
HandMorph.prototype.processMouseDown = function (event) {
var morph, expectedClick, actualClick;
var morph, actualClick;
this.destroyTemporaries();
this.contextMenuEnabled = true;
this.morphToGrab = null;
if (this.children.length !== 0) {
this.drop();
@ -9529,15 +9545,9 @@ HandMorph.prototype.processMouseDown = function (event) {
if (event.button === 2 || event.ctrlKey) {
this.mouseButton = 'right';
actualClick = 'mouseDownRight';
expectedClick = 'mouseClickRight';
} else {
this.mouseButton = 'left';
actualClick = 'mouseDownLeft';
expectedClick = 'mouseClickLeft';
}
this.mouseDownMorph = morph;
while (!this.mouseDownMorph[expectedClick]) {
this.mouseDownMorph = this.mouseDownMorph.parent;
}
while (!morph[actualClick]) {
morph = morph.parent;
@ -9596,7 +9606,7 @@ HandMorph.prototype.processMouseUp = function () {
expectedClick = 'mouseClickLeft';
} else {
expectedClick = 'mouseClickRight';
if (this.mouseButton) {
if (this.mouseButton && this.contextMenuEnabled) {
context = morph;
contextMenu = context.contextMenu();
while ((!contextMenu) &&
@ -9654,16 +9664,18 @@ HandMorph.prototype.processMouseMove = function (event) {
// mouseOverNew = this.allMorphsAtPointer();
mouseOverNew = this.morphAtPointer().allParents();
if ((this.children.length === 0) &&
(this.mouseButton === 'left')) {
if (!this.children.length && this.mouseButton) {
topMorph = this.morphAtPointer();
morph = topMorph.rootForGrab();
if (topMorph.mouseMove) {
topMorph.mouseMove(pos);
topMorph.mouseMove(pos, this.mouseButton);
if (this.mouseButton === 'right') {
this.contextMenuEnabled = false;
}
}
// if a morph is marked for grabbing, just grab it
if (this.morphToGrab) {
if (this.mouseButton === 'left' && this.morphToGrab) {
if (this.morphToGrab.isDraggable) {
morph = this.morphToGrab;
this.grab(morph);

Wyświetl plik

@ -9,7 +9,7 @@
written by Jens Mönig
jens@moenig.org
Copyright (C) 2014 by Jens Mönig
Copyright (C) 2015 by Jens Mönig
This file is part of Snap!.
@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/
// Global stuff ////////////////////////////////////////////////////////
modules.objects = '2014-October-08';
modules.objects = '2015-January-28';
var SpriteMorph;
var StageMorph;
@ -793,6 +793,12 @@ SpriteMorph.prototype.initBlocks = function () {
category: 'sensing',
spec: 'frames'
},
reportThreadCount: {
dev: true,
type: 'reporter',
category: 'sensing',
spec: 'processes'
},
doAsk: {
type: 'command',
category: 'sensing',
@ -1151,6 +1157,13 @@ SpriteMorph.prototype.initBlocks = function () {
category: 'lists',
spec: 'map %repRing over %l'
},
doForEach: {
dev: true,
type: 'command',
category: 'lists',
spec: 'for %upvar in %l %cs',
defaults: [localize('each item')]
},
// Code mapping - experimental
doMapCodeOrHeader: { // experimental
@ -1302,6 +1315,7 @@ SpriteMorph.prototype.init = function (globals) {
this.anchor = null;
this.nestingScale = 1;
this.rotatesWithAnchor = true;
this.layers = null; // cache for dragging nested sprites, don't serialize
this.blocksCache = {}; // not to be serialized (!)
this.paletteCache = {}; // not to be serialized (!)
@ -1674,6 +1688,20 @@ SpriteMorph.prototype.blockTemplates = function (category) {
return menu;
}
function addVar(pair) {
if (pair) {
if (myself.variables.silentFind(pair[0])) {
myself.inform('that name is already in use');
} else {
myself.addVariable(pair[0], pair[1]);
myself.toggleVariableWatcher(pair[0], pair[1]);
myself.blocksCache[cat] = null;
myself.paletteCache[cat] = null;
myself.parentThatIsA(IDE_Morph).refreshPalette();
}
}
}
if (cat === 'motion') {
blocks.push(block('forward'));
@ -1897,6 +1925,8 @@ SpriteMorph.prototype.blockTemplates = function (category) {
txt.setColor(this.paletteTextColor);
blocks.push(txt);
blocks.push('-');
blocks.push(watcherToggle('reportThreadCount'));
blocks.push(block('reportThreadCount'));
blocks.push(block('colorFiltered'));
blocks.push(block('reportStackSize'));
blocks.push(block('reportFrameCount'));
@ -1967,15 +1997,7 @@ SpriteMorph.prototype.blockTemplates = function (category) {
function () {
new VariableDialogMorph(
null,
function (pair) {
if (pair && !myself.variables.silentFind(pair[0])) {
myself.addVariable(pair[0], pair[1]);
myself.toggleVariableWatcher(pair[0], pair[1]);
myself.blocksCache[cat] = null;
myself.paletteCache[cat] = null;
myself.parentThatIsA(IDE_Morph).refreshPalette();
}
},
addVar,
myself
).prompt(
'Variable name',
@ -2057,6 +2079,8 @@ SpriteMorph.prototype.blockTemplates = function (category) {
blocks.push(txt);
blocks.push('-');
blocks.push(block('reportMap'));
blocks.push('-');
blocks.push(block('doForEach'));
}
/////////////////////////////////
@ -2164,8 +2188,8 @@ SpriteMorph.prototype.freshPalette = function (category) {
var defs = SpriteMorph.prototype.blocks,
hiddens = StageMorph.prototype.hiddenPrimitives;
return Object.keys(hiddens).some(function (any) {
return defs[any].category === category ||
contains((more[category] || []), any);
return !isNil(defs[any]) && (defs[any].category === category
|| contains((more[category] || []), any));
});
}
@ -2204,7 +2228,7 @@ SpriteMorph.prototype.freshPalette = function (category) {
var hiddens = StageMorph.prototype.hiddenPrimitives,
defs = SpriteMorph.prototype.blocks;
Object.keys(hiddens).forEach(function (sel) {
if (defs[sel].category === category) {
if (defs[sel] && (defs[sel].category === category)) {
delete StageMorph.prototype.hiddenPrimitives[sel];
}
});
@ -2619,7 +2643,9 @@ SpriteMorph.prototype.userMenu = function () {
menu.addItem("duplicate", 'duplicate');
menu.addItem("delete", 'remove');
menu.addItem("move", 'move');
menu.addItem("edit", 'edit');
if (!this.isClone) {
menu.addItem("edit", 'edit');
}
menu.addLine();
if (this.anchor) {
menu.addItem(
@ -2635,6 +2661,7 @@ SpriteMorph.prototype.userMenu = function () {
};
SpriteMorph.prototype.exportSprite = function () {
if (this.isCoone) {return; }
var ide = this.parentThatIsA(IDE_Morph);
if (ide) {
ide.exportSprite(this);
@ -2731,7 +2758,7 @@ SpriteMorph.prototype.setColor = function (aColor) {
var x = this.xPosition(),
y = this.yPosition();
if (!this.color.eq(aColor)) {
this.color = aColor;
this.color = aColor.copy();
this.drawNew();
this.gotoXY(x, y);
}
@ -3128,13 +3155,11 @@ SpriteMorph.prototype.positionTalkBubble = function () {
bubble.changed();
};
// dragging and dropping adjustments b/c of talk bubbles
// dragging and dropping adjustments b/c of talk bubbles and parts
SpriteMorph.prototype.prepareToBeGrabbed = function (hand) {
var bubble = this.talkBubble();
if (!bubble) {return null; }
this.removeShadow();
bubble.hide();
this.recordLayers();
if (!this.bounds.containsPoint(hand.position())) {
this.setCenter(hand.position());
}
@ -3142,6 +3167,7 @@ SpriteMorph.prototype.prepareToBeGrabbed = function (hand) {
};
SpriteMorph.prototype.justDropped = function () {
this.restoreLayers();
this.positionTalkBubble();
};
@ -3232,8 +3258,11 @@ SpriteMorph.prototype.setCenter = function (aPoint, justMe) {
SpriteMorph.prototype.nestingBounds = function () {
// same as fullBounds(), except that it uses "parts" instead of children
var result;
result = this.bounds;
// and special cases the costume-less "arrow" shape's bounding box
var result = this.bounds;
if (!this.costume && this.penBounds) {
result = this.penBounds.translateBy(this.position());
}
this.parts.forEach(function (part) {
if (part.isVisible) {
result = result.merge(part.nestingBounds());
@ -3504,6 +3533,7 @@ SpriteMorph.prototype.mouseClickLeft = function () {
};
SpriteMorph.prototype.mouseDoubleClick = function () {
if (this.isClone) {return; }
this.edit();
};
@ -3561,6 +3591,16 @@ SpriteMorph.prototype.reportMouseY = function () {
return 0;
};
// SpriteMorph thread count (for debugging)
SpriteMorph.prototype.reportThreadCount = function () {
var stage = this.parentThatIsA(StageMorph);
if (stage) {
return stage.threads.processes.length;
}
return 0;
};
// SpriteMorph variable watchers (for palette checkbox toggling)
SpriteMorph.prototype.findVariableWatcher = function (varName) {
@ -4005,6 +4045,33 @@ SpriteMorph.prototype.allAnchors = function () {
return result;
};
SpriteMorph.prototype.recordLayers = function () {
var stage = this.parentThatIsA(StageMorph);
if (!stage) {
this.layerCache = null;
return;
}
this.layers = this.allParts();
this.layers.forEach(function (part) {
var bubble = part.talkBubble();
if (bubble) {bubble.hide(); }
});
this.layers.sort(function (x, y) {
return stage.children.indexOf(x) < stage.children.indexOf(y) ?
-1 : 1;
});
};
SpriteMorph.prototype.restoreLayers = function () {
if (this.layers && this.layers.length > 1) {
this.layers.forEach(function (sprite) {
sprite.comeToFront();
sprite.positionTalkBubble();
});
}
this.layers = null;
};
// SpriteMorph highlighting
SpriteMorph.prototype.addHighlight = function (oldHighlight) {
@ -4858,6 +4925,20 @@ StageMorph.prototype.blockTemplates = function (category) {
);
}
function addVar(pair) {
if (pair) {
if (myself.variables.silentFind(pair[0])) {
myself.inform('that name is already in use');
} else {
myself.addVariable(pair[0], pair[1]);
myself.toggleVariableWatcher(pair[0], pair[1]);
myself.blocksCache[cat] = null;
myself.paletteCache[cat] = null;
myself.parentThatIsA(IDE_Morph).refreshPalette();
}
}
}
if (cat === 'motion') {
txt = new TextMorph(localize(
@ -5027,6 +5108,8 @@ StageMorph.prototype.blockTemplates = function (category) {
txt.setColor(this.paletteTextColor);
blocks.push(txt);
blocks.push('-');
blocks.push(watcherToggle('reportThreadCount'));
blocks.push(block('reportThreadCount'));
blocks.push(block('colorFiltered'));
blocks.push(block('reportStackSize'));
blocks.push(block('reportFrameCount'));
@ -5099,15 +5182,7 @@ StageMorph.prototype.blockTemplates = function (category) {
function () {
new VariableDialogMorph(
null,
function (pair) {
if (pair && !myself.variables.silentFind(pair[0])) {
myself.addVariable(pair[0], pair[1]);
myself.toggleVariableWatcher(pair[0], pair[1]);
myself.blocksCache[cat] = null;
myself.paletteCache[cat] = null;
myself.parentThatIsA(IDE_Morph).refreshPalette();
}
},
addVar,
myself
).prompt(
'Variable name',
@ -5183,6 +5258,8 @@ StageMorph.prototype.blockTemplates = function (category) {
blocks.push(txt);
blocks.push('-');
blocks.push(block('reportMap'));
blocks.push('-');
blocks.push(block('doForEach'));
}
/////////////////////////////////
@ -5321,7 +5398,7 @@ StageMorph.prototype.thumbnail = function (extentPoint, excludedSprite) {
this.dimensions.y * this.scale
);
this.children.forEach(function (morph) {
if (morph !== excludedSprite) {
if (morph.isVisible && (morph !== excludedSprite)) {
fb = morph.fullBounds();
fimg = morph.fullImage();
if (fimg.width && fimg.height) {
@ -5483,6 +5560,9 @@ StageMorph.prototype.watcherFor =
StageMorph.prototype.getLastAnswer
= SpriteMorph.prototype.getLastAnswer;
StageMorph.prototype.reportThreadCount
= SpriteMorph.prototype.reportThreadCount;
// StageMorph message broadcasting
StageMorph.prototype.allMessageNames
@ -6731,7 +6811,7 @@ WatcherMorph.prototype.object = function () {
WatcherMorph.prototype.isGlobal = function (selector) {
return contains(
['getLastAnswer', 'getLastMessage', 'getTempo', 'getTimer',
'reportMouseX', 'reportMouseY'],
'reportMouseX', 'reportMouseY', 'reportThreadCount'],
selector
);
};

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 155 B

Wyświetl plik

@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Snap! Build Your Own Blocks. Beta</title>
<link rel="shortcut icon" href="http://snap.berkeley.edu/fav3.gif" type="image/gif">
<link rel="shortcut icon" href="favicon.ico">
<script type="text/javascript" src="morphic.js"></script>
<script type="text/javascript" src="widgets.js"></script>
<script type="text/javascript" src="blocks.js"></script>
@ -33,5 +33,5 @@
</head>
<body style="margin: 0;">
<canvas id="world" tabindex="1" style="position: absolute;" />
</body>
</body>
</html>

Wyświetl plik

@ -7,7 +7,7 @@
written by Jens Mönig
jens@moenig.org
Copyright (C) 2014 by Jens Mönig
Copyright (C) 2015 by Jens Mönig
This file is part of Snap!.
@ -61,7 +61,7 @@ SyntaxElementMorph, Variable*/
// Global stuff ////////////////////////////////////////////////////////
modules.store = '2014-October-01';
modules.store = '2015-January-21';
// XML_Serializer ///////////////////////////////////////////////////////
@ -261,11 +261,14 @@ SnapSerializer.prototype.watcherLabels = {
yPosition: 'y position',
direction: 'direction',
getScale: 'size',
getTempo: 'tempo',
getLastAnswer: 'answer',
getLastMessage: 'message',
getTimer: 'timer',
getCostumeIdx: 'costume #',
reportMouseX: 'mouse x',
reportMouseY: 'mouse y'
reportMouseY: 'mouse y',
reportThreadCount: 'processes'
};
// SnapSerializer instance creation:
@ -303,16 +306,33 @@ XML_Serializer.prototype.mediaXML = function (name) {
return xml + '</media>';
};
// SnapSerializer loading:
SnapSerializer.prototype.load = function (xmlString) {
SnapSerializer.prototype.load = function (xmlString, ide) {
// public - answer a new Project represented by the given XML String
return this.loadProjectModel(this.parse(xmlString));
return this.loadProjectModel(this.parse(xmlString), ide);
};
SnapSerializer.prototype.loadProjectModel = function (xmlNode) {
SnapSerializer.prototype.loadProjectModel = function (xmlNode, ide) {
// public - answer a new Project represented by the given XML top node
// show a warning if the origin apps differ
var appInfo = xmlNode.attributes.app,
app = appInfo ? appInfo.split(' ')[0] : null;
if (ide && app !== this.app.split(' ')[0]) {
ide.inform(
app + ' Project',
'This project has been created by a different app:\n\n' +
app +
'\n\nand may be incompatible or fail to load here.'
);
}
return this.rawLoadProjectModel(xmlNode);
};
SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode) {
// private
var myself = this,
project = {sprites: {}},
model,
@ -841,7 +861,7 @@ SnapSerializer.prototype.loadScripts = function (scripts, model) {
// private
var myself = this,
scale = SyntaxElementMorph.prototype.scale;
scripts.texture = 'scriptsPaneTexture.gif';
scripts.cachedTexture = IDE_Morph.prototype.scriptsPaneTexture;
model.children.forEach(function (child) {
var element;
if (child.tag === 'script') {
@ -1199,6 +1219,10 @@ SnapSerializer.prototype.loadValue = function (model) {
if (el) {
v.outerContext = this.loadValue(el);
}
if (v.outerContext && v.receiver &&
!v.outerContext.variables.parentFrame) {
v.outerContext.variables.parentFrame = v.receiver.variables;
}
return v;
case 'costume':
center = new Point();
@ -1824,9 +1848,8 @@ Context.prototype.toXML = function (serializer) {
return '';
}
return serializer.format(
'<context% ~><inputs>%</inputs><variables>%</variables>' +
'<context ~><inputs>%</inputs><variables>%</variables>' +
'%<receiver>%</receiver>%</context>',
this.isLambda ? ' lambda="lambda"' : '',
this.inputs.reduce(
function (xml, input) {
return xml + serializer.format('<input>$</input>', input);

Wyświetl plik

@ -9,7 +9,7 @@
written by Jens Mönig
jens@moenig.org
Copyright (C) 2014 by Jens Mönig
Copyright (C) 2015 by Jens Mönig
This file is part of Snap!.
@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/
// Global stuff ////////////////////////////////////////////////////////
modules.threads = '2014-October-01';
modules.threads = '2015-January-12';
var ThreadManager;
var Process;
@ -100,8 +100,18 @@ function snapEquals(a, b) {
var x = +a,
y = +b,
i,
specials = [true, false, ''];
// "zum Schneckengang verdorben, was Adlerflug geworden wäre"
// collecting edge-cases that somebody complained about
// on Github. Folks, take it easy and keep it fun, okay?
// Shit like this is patently ugly and slows Snap down. Tnx!
for (i = 9; i <= 13; i += 1) {
specials.push(String.fromCharCode(i));
}
specials.push(String.fromCharCode(160));
// check for special values before coercing to numbers
if (isNaN(x) || isNaN(y) ||
[a, b].some(function (any) {return contains(specials, any) ||
@ -110,7 +120,7 @@ function snapEquals(a, b) {
y = b;
}
// handle text comparision case-insensitive.
// handle text comparison case-insensitive.
if (isString(x) && isString(y)) {
return x.toLowerCase() === y.toLowerCase();
}
@ -136,7 +146,8 @@ ThreadManager.prototype.toggleProcess = function (block) {
ThreadManager.prototype.startProcess = function (
block,
isThreadSafe,
exportResult
exportResult,
callback
) {
var active = this.findProcess(block),
top = block.topBlock(),
@ -148,9 +159,11 @@ ThreadManager.prototype.startProcess = function (
active.stop();
this.removeTerminatedProcesses();
}
top.addHighlight();
newProc = new Process(block.topBlock());
newProc = new Process(block.topBlock(), callback);
newProc.exportResult = exportResult;
if (!newProc.homeContext.receiver.isClone) {
top.addHighlight();
}
this.processes.push(newProc);
return newProc;
};
@ -207,11 +220,10 @@ ThreadManager.prototype.resumeAll = function (stage) {
};
ThreadManager.prototype.step = function () {
/*
run each process until it gives up control, skipping processes
for sprites that are currently picked up, then filter out any
processes that have been terminated
*/
// run each process until it gives up control, skipping processes
// for sprites that are currently picked up, then filter out any
// processes that have been terminated
this.processes.forEach(function (proc) {
if (!proc.homeContext.receiver.isPickedUp() && !proc.isDead) {
proc.runStep();
@ -224,9 +236,10 @@ ThreadManager.prototype.removeTerminatedProcesses = function () {
// and un-highlight their scripts
var remaining = [];
this.processes.forEach(function (proc) {
if (!proc.isRunning() && !proc.errorFlag && !proc.isDead) {
proc.topBlock.removeHighlight();
if ((!proc.isRunning() && !proc.errorFlag) || proc.isDead) {
if (proc.topBlock instanceof BlockMorph) {
proc.topBlock.removeHighlight();
}
if (proc.prompter) {
proc.prompter.destroy();
if (proc.homeContext.receiver.stopTalking) {
@ -235,18 +248,22 @@ ThreadManager.prototype.removeTerminatedProcesses = function () {
}
if (proc.topBlock instanceof ReporterBlockMorph) {
if (proc.homeContext.inputs[0] instanceof List) {
proc.topBlock.showBubble(
new ListWatcherMorph(
proc.homeContext.inputs[0]
),
proc.exportResult
);
if (proc.onComplete instanceof Function) {
proc.onComplete(proc.homeContext.inputs[0]);
} else {
proc.topBlock.showBubble(
proc.homeContext.inputs[0],
proc.exportResult
);
if (proc.homeContext.inputs[0] instanceof List) {
proc.topBlock.showBubble(
new ListWatcherMorph(
proc.homeContext.inputs[0]
),
proc.exportResult
);
} else {
proc.topBlock.showBubble(
proc.homeContext.inputs[0],
proc.exportResult
);
}
}
}
} else {
@ -295,9 +312,9 @@ ThreadManager.prototype.findProcess = function (block) {
are children
receiver object (sprite) to which the process applies,
cached from the top block
context the Context describing the current state
context the Context describing the current state
of this process
homeContext stores information relevant to the whole process,
homeContext stores information relevant to the whole process,
i.e. its receiver, result etc.
isPaused boolean indicating whether to pause
readyToYield boolean indicating whether to yield control to
@ -305,15 +322,20 @@ ThreadManager.prototype.findProcess = function (block) {
readyToTerminate boolean indicating whether the stop method has
been called
isDead boolean indicating a terminated clone process
timeout msecs after which to force yield
lastYield msecs when the process last yielded
errorFlag boolean indicating whether an error was encountered
timeout msecs after which to force yield
lastYield msecs when the process last yielded
errorFlag boolean indicating whether an error was encountered
prompter active instance of StagePrompterMorph
httpRequest active instance of an HttpRequest or null
pauseOffset msecs between the start of an interpolated operation
and when the process was paused
exportResult boolean flag indicating whether a picture of the top
block along with the result bubble shoud be exported
onComplete an optional callback function to be executed when
the process is done
procedureCount number counting procedure call entries,
used to tag custom block calls, so "stop block"
invocations can catch them
*/
Process.prototype = {};
@ -321,7 +343,7 @@ Process.prototype.contructor = Process;
Process.prototype.timeout = 500; // msecs after which to force yield
Process.prototype.isCatchingErrors = true;
function Process(topBlock) {
function Process(topBlock, onComplete) {
this.topBlock = topBlock || null;
this.readyToYield = false;
@ -338,6 +360,8 @@ function Process(topBlock) {
this.pauseOffset = null;
this.frameCount = 0;
this.exportResult = false;
this.onComplete = onComplete || null;
this.procedureCount = 0;
if (topBlock) {
this.homeContext.receiver = topBlock.receiver();
@ -361,13 +385,13 @@ Process.prototype.isRunning = function () {
// Process entry points
Process.prototype.runStep = function () {
/*
a step is an an uninterruptable 'atom', it can consist
of several contexts, even of several blocks
*/
// a step is an an uninterruptable 'atom', it can consist
// of several contexts, even of several blocks
if (this.isPaused) { // allow pausing in between atomic steps:
return this.pauseStep();
}
this.readyToYield = false;
while (!this.readyToYield
&& this.context
@ -435,8 +459,10 @@ Process.prototype.pauseStep = function () {
Process.prototype.evaluateContext = function () {
var exp = this.context.expression;
this.frameCount += 1;
if (this.context.tag === 'exit') {
this.expectReport();
}
if (exp instanceof Array) {
return this.evaluateSequence(exp);
}
@ -460,7 +486,7 @@ Process.prototype.evaluateContext = function () {
Process.prototype.evaluateBlock = function (block, argCount) {
// check for special forms
if (contains(['reportOr', 'reportAnd'], block.selector)) {
if (contains(['reportOr', 'reportAnd', 'doReport'], block.selector)) {
return this[block.selector](block);
}
@ -526,6 +552,35 @@ Process.prototype.reportAnd = function (block) {
}
};
Process.prototype.doReport = function (block) {
var outer = this.context.outerContext;
if (this.context.expression.partOfCustomCommand) {
this.doStopCustomBlock();
this.popContext();
} else {
while (this.context && this.context.tag !== 'exit') {
if (this.context.expression === 'doStopWarping') {
this.doStopWarping();
} else {
this.popContext();
}
}
if (this.context) {
if (this.context.expression === 'expectReport') {
// pop off inserted top-level exit context
this.popContext();
} else {
// un-tag and preserve original caller
this.context.tag = null;
}
}
}
// in any case evaluate (and ignore)
// the input, because it could be
// and HTTP Request for a hardware extension
this.pushContext(block.inputs()[0], outer);
};
// Process: Non-Block evaluation
Process.prototype.evaluateMultiSlot = function (multiSlot, argCount) {
@ -586,7 +641,6 @@ Process.prototype.evaluateInput = function (input) {
) || (input instanceof CSlotMorph && !input.isStatic)) {
// I know, this still needs yet to be done right....
ans = this.reify(ans, new List());
ans.isImplicitLambda = true;
}
}
}
@ -597,8 +651,6 @@ Process.prototype.evaluateInput = function (input) {
Process.prototype.evaluateSequence = function (arr) {
var pc = this.context.pc,
outer = this.context.outerContext,
isLambda = this.context.isLambda,
isImplicitLambda = this.context.isImplicitLambda,
isCustomBlock = this.context.isCustomBlock;
if (pc === (arr.length - 1)) { // tail call elimination
this.context = new Context(
@ -607,8 +659,6 @@ Process.prototype.evaluateSequence = function (arr) {
this.context.outerContext,
this.context.receiver
);
this.context.isLambda = isLambda;
this.context.isImplicitLambda = isImplicitLambda;
this.context.isCustomBlock = isCustomBlock;
} else {
if (pc >= arr.length) {
@ -626,8 +676,8 @@ Process.prototype.evaluateSequence = function (arr) {
Caution: we cannot just revert to this version of the method, because to make
tail call elimination work many tweaks had to be done to various primitives.
For the most part these tweaks are about schlepping the outer context (for
the variable bindings) and the isLambda flag along, and are indicated by a
short comment in the code. But to really revert would take a good measure
the variable bindings) and the isCustomBlock flag along, and are indicated
by a short comment in the code. But to really revert would take a good measure
of trial and error as well as debugging. In the developers file archive there
is a version of threads.js dated 120119(2) which basically resembles the
last version before introducing tail call optimization on 120123.
@ -679,6 +729,10 @@ Process.prototype.doYield = function () {
}
};
Process.prototype.expectReport = function () {
this.handleError(new Error("reporter didn't report"));
};
// Process Exception Handling
Process.prototype.handleError = function (error, element) {
@ -757,8 +811,8 @@ Process.prototype.reportJSFunction = function (parmNames, body) {
);
};
Process.prototype.doRun = function (context, args, isCustomBlock) {
return this.evaluate(context, args, true, isCustomBlock);
Process.prototype.doRun = function (context, args) {
return this.evaluate(context, args, true);
};
Process.prototype.evaluate = function (
@ -781,8 +835,9 @@ Process.prototype.evaluate = function (
}
var outer = new Context(null, null, context.outerContext),
caller = this.context.parentContext,
exit,
runnable,
extra,
parms = args.asArray(),
i,
value;
@ -796,25 +851,13 @@ Process.prototype.evaluate = function (
outer,
context.receiver
);
extra = new Context(runnable, 'doYield');
this.context.parentContext = runnable;
/*
Note: if the context's expression is a ReporterBlockMorph,
the extra context gets popped off immediately without taking
effect (i.e. it doesn't yield within evaluating a stack of
nested reporters)
*/
if (isCommand || (context.expression instanceof ReporterBlockMorph)) {
this.context.parentContext = extra;
} else {
this.context.parentContext = runnable;
if (context.expression instanceof ReporterBlockMorph) {
// auto-"warp" nested reporters
this.readyToYield = (Date.now() - this.lastYield > this.timeout);
}
runnable.isLambda = true;
runnable.isImplicitLambda = context.isImplicitLambda;
runnable.isCustomBlock = false;
// assign parameters if any were passed
if (parms.length > 0) {
@ -849,8 +892,9 @@ Process.prototype.evaluate = function (
} else if (context.emptySlots !== 1) {
throw new Error(
'expecting ' + context.emptySlots + ' input(s), '
+ 'but getting ' + parms.length
localize('expecting') + ' ' + context.emptySlots + ' '
+ localize('input(s), but getting') + ' '
+ parms.length
);
}
}
@ -858,6 +902,23 @@ Process.prototype.evaluate = function (
if (runnable.expression instanceof CommandBlockMorph) {
runnable.expression = runnable.expression.blockSequence();
if (!isCommand) {
if (caller) {
// tag caller, so "report" can catch it later
caller.tag = 'exit';
} else {
// top-level context, insert a tagged exit context
// which "report" can catch later
exit = new Context(
runnable.parentContext,
'expectReport',
outer,
outer.receiver
);
exit.tag = 'exit';
runnable.parentContext = exit;
}
}
}
};
@ -867,6 +928,9 @@ Process.prototype.fork = function (context, args) {
'continuations cannot be forked'
);
}
if (!(context instanceof Context)) {
throw new Error('expecting a ring but getting ' + context);
}
var outer = new Context(null, null, context.outerContext),
runnable = new Context(null,
@ -879,8 +943,6 @@ Process.prototype.fork = function (context, args) {
stage = this.homeContext.receiver.parentThatIsA(StageMorph),
proc = new Process();
runnable.isLambda = true;
// assign parameters if any were passed
if (parms.length > 0) {
@ -915,8 +977,9 @@ Process.prototype.fork = function (context, args) {
} else if (context.emptySlots !== 1) {
throw new Error(
'expecting ' + context.emptySlots + ' input(s), '
+ 'but getting ' + parms.length
localize('expecting') + ' ' + context.emptySlots + ' '
+ localize('input(s), but getting') + ' '
+ parms.length
);
}
}
@ -933,68 +996,48 @@ Process.prototype.fork = function (context, args) {
stage.threads.processes.push(proc);
};
Process.prototype.doReport = function (value, isCSlot) {
while (this.context && !this.context.isLambda) {
if (this.context.expression === 'doStopWarping') {
this.doStopWarping();
} else {
this.popContext();
}
}
if (this.context && this.context.isImplicitLambda) {
if (this.context.expression === 'doStopWarping') {
this.doStopWarping();
} else {
this.popContext();
}
return this.doReport(value, true);
}
if (this.context && this.context.isCustomBlock) {
// now I'm back at the custom block sequence.
// advance my pc to my expression's length
this.context.pc = this.context.expression.length - 1;
}
if (isCSlot) {
if (this.context &&
this.context.parentContext &&
this.context.parentContext.expression instanceof Array) {
this.popContext();
}
}
return value;
};
// Process stopping blocks primitives
Process.prototype.doStopBlock = function () {
this.doReport();
var target = this.context.expression.exitTag;
if (isNil(target)) {
return this.doStopCustomBlock();
}
while (this.context &&
(isNil(this.context.tag) || (this.context.tag > target))) {
if (this.context.expression === 'doStopWarping') {
this.doStopWarping();
} else {
this.popContext();
}
}
this.pushContext();
};
// Process evaluation variants, commented out for now (redundant)
/*
Process.prototype.doRunWithInputList = function (context, args) {
// provide an extra selector for the palette
return this.doRun(context, args);
Process.prototype.doStopCustomBlock = function () {
// fallback solution for "report" blocks inside
// custom command definitions and untagged "stop" blocks
while (this.context && !this.context.isCustomBlock) {
if (this.context.expression === 'doStopWarping') {
this.doStopWarping();
} else {
this.popContext();
}
}
};
Process.prototype.evaluateWithInputList = function (context, args) {
// provide an extra selector for the palette
return this.evaluate(context, args);
};
Process.prototype.forkWithInputList = function (context, args) {
// provide an extra selector for the palette
return this.fork(context, args);
};
*/
// Process continuations primitives
Process.prototype.doCallCC = function (aContext) {
this.evaluate(aContext, new List([this.context.continuation()]));
Process.prototype.doCallCC = function (aContext, isReporter) {
this.evaluate(
aContext,
new List([this.context.continuation()]),
!isReporter
);
};
Process.prototype.reportCallCC = function (aContext) {
this.doCallCC(aContext);
this.doCallCC(aContext, true);
};
Process.prototype.runContinuation = function (aContext, args) {
@ -1012,19 +1055,21 @@ Process.prototype.runContinuation = function (aContext, args) {
// Process custom block primitives
Process.prototype.evaluateCustomBlock = function () {
var context = this.context.expression.definition.body,
var caller = this.context.parentContext,
context = this.context.expression.definition.body,
declarations = this.context.expression.definition.declarations,
args = new List(this.context.inputs),
parms = args.asArray(),
runnable,
extra,
exit,
i,
value,
outer;
if (!context) {return null; }
this.procedureCount += 1;
outer = new Context();
outer.receiver = this.context.receiver; // || this.homeContext.receiver;
outer.receiver = this.context.receiver;
outer.variables.parentFrame = outer.receiver ?
outer.receiver.variables : null;
@ -1032,15 +1077,10 @@ Process.prototype.evaluateCustomBlock = function () {
this.context.parentContext,
context.expression,
outer,
outer.receiver,
true // is custom block
outer.receiver
);
extra = new Context(runnable, 'doYield');
this.context.parentContext = extra;
runnable.isLambda = true;
runnable.isCustomBlock = true;
this.context.parentContext = runnable;
// passing parameters if any were passed
if (parms.length > 0) {
@ -1062,9 +1102,43 @@ Process.prototype.evaluateCustomBlock = function () {
}
}
if (runnable.expression instanceof CommandBlockMorph) {
runnable.expression = runnable.expression.blockSequence();
// tag return target
if (this.context.expression.definition.type !== 'command') {
if (caller) {
// tag caller, so "report" can catch it later
caller.tag = 'exit';
} else {
// top-level context, insert a tagged exit context
// which "report" can catch later
exit = new Context(
runnable.parentContext,
'expectReport',
outer,
outer.receiver
);
exit.tag = 'exit';
runnable.parentContext = exit;
}
// auto-"warp" nested reporters
this.readyToYield = (Date.now() - this.lastYield > this.timeout);
} else {
// tag all "stop this block" blocks with the current
// procedureCount as exitTag, and mark all "report" blocks
// as being inside a custom command definition
runnable.expression.tagExitBlocks(this.procedureCount, true);
// tag the caller with the current procedure count, so
// "stop this block" blocks can catch it, but only
// if the caller hasn't been tagged already
if (caller && !caller.tag) {
caller.tag = this.procedureCount;
}
// yield commands unless explicitly "warped"
if (!this.isAtomic) {
this.readyToYield = true;
}
}
runnable.expression = runnable.expression.blockSequence();
};
// Process variables primitives
@ -1148,7 +1222,7 @@ Process.prototype.doShowVar = function (varName) {
if (isGlobal || target.owner) {
label = name;
} else {
label = name + ' (temporary)';
label = name + ' ' + localize('(temporary)');
}
watcher = new WatcherMorph(
label,
@ -1259,7 +1333,7 @@ Process.prototype.doInsertInList = function (element, index, list) {
return null;
}
if (this.inputOption(index) === 'any') {
idx = this.reportRandom(1, list.length());
idx = this.reportRandom(1, list.length() + 1);
}
if (this.inputOption(index) === 'last') {
idx = list.length() + 1;
@ -1308,16 +1382,12 @@ Process.prototype.reportListContainsItem = function (list, element) {
Process.prototype.doIf = function () {
var args = this.context.inputs,
outer = this.context.outerContext, // for tail call elimination
isLambda = this.context.isLambda,
isImplicitLambda = this.context.isImplicitLambda,
isCustomBlock = this.context.isCustomBlock;
this.popContext();
if (args[0]) {
if (args[1]) {
this.pushContext(args[1].blockSequence(), outer);
this.context.isLambda = isLambda;
this.context.isImplicitLambda = isImplicitLambda;
this.context.isCustomBlock = isCustomBlock;
}
}
@ -1327,8 +1397,6 @@ Process.prototype.doIf = function () {
Process.prototype.doIfElse = function () {
var args = this.context.inputs,
outer = this.context.outerContext, // for tail call elimination
isLambda = this.context.isLambda,
isImplicitLambda = this.context.isImplicitLambda,
isCustomBlock = this.context.isCustomBlock;
this.popContext();
@ -1344,8 +1412,6 @@ Process.prototype.doIfElse = function () {
}
}
if (this.context) {
this.context.isLambda = isLambda;
this.context.isImplicitLambda = isImplicitLambda;
this.context.isCustomBlock = isCustomBlock;
}
@ -1420,8 +1486,6 @@ Process.prototype.doStopOthers = function (choice) {
Process.prototype.doWarp = function (body) {
// execute my contents block atomically (more or less)
var outer = this.context.outerContext, // for tail call elimination
isLambda = this.context.isLambda,
isImplicitLambda = this.context.isImplicitLambda,
isCustomBlock = this.context.isCustomBlock,
stage;
@ -1438,13 +1502,8 @@ Process.prototype.doWarp = function (body) {
stage.fps = 0; // variable frame rate
}
}
this.pushContext('doYield');
this.context.isLambda = isLambda;
this.context.isImplicitLambda = isImplicitLambda;
this.context.isCustomBlock = isCustomBlock;
if (!this.isAtomic) {
this.pushContext('doStopWarping');
}
@ -1523,28 +1582,19 @@ Process.prototype.doForever = function (body) {
Process.prototype.doRepeat = function (counter, body) {
var block = this.context.expression,
outer = this.context.outerContext, // for tail call elimination
isLambda = this.context.isLambda,
isImplicitLambda = this.context.isImplicitLambda,
isCustomBlock = this.context.isCustomBlock;
if (counter < 1) { // was '=== 0', which caused infinite loops on non-ints
return null;
}
this.popContext();
this.pushContext(block, outer);
this.context.isLambda = isLambda;
this.context.isImplicitLambda = isImplicitLambda;
this.context.isCustomBlock = isCustomBlock;
this.context.addInput(counter - 1);
this.pushContext('doYield');
if (body) {
this.pushContext(body.blockSequence());
}
this.pushContext();
};
@ -1631,6 +1681,27 @@ Process.prototype.reportMap = function (reporter, list) {
}
};
Process.prototype.doForEach = function (upvar, list, script) {
// perform a script for each element of a list, assigning the
// current iteration's element to a variable with the name
// specified in the "upvar" parameter, so it can be referenced
// within the script. Uses the context's - unused - fourth
// element as temporary storage for the current list index
if (isNil(this.context.inputs[3])) {this.context.inputs[3] = 1; }
var index = this.context.inputs[3];
this.context.outerContext.variables.addVar(upvar);
this.context.outerContext.variables.setVar(
upvar,
list.at(index)
);
if (index > list.length()) {return; }
this.context.inputs[3] += 1;
this.pushContext('doYield');
this.pushContext();
this.evaluate(script, new List(), true);
};
// Process interpolated primitives
Process.prototype.doWait = function (secs) {
@ -2134,15 +2205,17 @@ Process.prototype.reportTextSplit = function (string, delimiter) {
str,
del;
if (!contains(types, strType)) {
throw new Error('expecting a text instad of a ' + strType);
throw new Error('expecting text instead of a ' + strType);
}
if (!contains(types, delType)) {
throw new Error('expecting a text delimiter instad of a ' + delType);
throw new Error('expecting a text delimiter instead of a ' + delType);
}
str = (string || '').toString();
switch (this.inputOption(delimiter)) {
case 'line':
del = '\n';
// Unicode Compliant Line Splitting (Platform independent)
// http://www.unicode.org/reports/tr18/#Line_Boundaries
del = /\r\n|[\n\v\f\r\x85\u2028\u2029]/;
break;
case 'tab':
del = '\t';
@ -2151,7 +2224,9 @@ Process.prototype.reportTextSplit = function (string, delimiter) {
del = '\r';
break;
case 'whitespace':
return new List(str.trim().split(/[\t\r\n ]+/));
str = str.trim();
del = /\s+/;
break;
case 'letter':
del = '';
break;
@ -2316,6 +2391,7 @@ Process.prototype.objectTouchingObject = function (thisObj, name) {
var myself = this,
those,
stage,
box,
mouse;
if (this.inputOption(name) === 'mouse-pointer') {
@ -2327,9 +2403,14 @@ Process.prototype.objectTouchingObject = function (thisObj, name) {
} else {
stage = thisObj.parentThatIsA(StageMorph);
if (stage) {
if (this.inputOption(name) === 'edge' &&
!stage.bounds.containsRectangle(thisObj.bounds)) {
return true;
if (this.inputOption(name) === 'edge') {
box = thisObj.bounds;
if (!thisObj.costume && thisObj.penBounds) {
box = thisObj.penBounds.translateBy(thisObj.position());
}
if (!stage.bounds.containsRectangle(box)) {
return true;
}
}
if (this.inputOption(name) === 'pen trails' &&
thisObj.isTouching(stage.penTrailsMorph())) {
@ -2467,6 +2548,7 @@ Process.prototype.reportContextFor = function (context, otherObj) {
if (result.outerContext) {
result.outerContext = copy(result.outerContext);
result.outerContext.receiver = otherObj;
result.outerContext.variables.parentFrame = otherObj.variables;
}
return result;
};
@ -2760,25 +2842,25 @@ Process.prototype.reportFrameCount = function () {
structure:
parentContext the Context to return to when this one has
parentContext the Context to return to when this one has
been evaluated.
outerContext the Context holding my lexical scope
expression SyntaxElementMorph, an array of blocks to evaluate,
expression SyntaxElementMorph, an array of blocks to evaluate,
null or a String denoting a selector, e.g. 'doYield'
receiver the object to which the expression applies, if any
variables the current VariableFrame, if any
inputs an array of input values computed so far
variables the current VariableFrame, if any
inputs an array of input values computed so far
(if expression is a BlockMorph)
pc the index of the next block to evaluate
pc the index of the next block to evaluate
(if expression is an array)
startTime time when the context was first evaluated
startValue initial value for interpolated operations
startTime time when the context was first evaluated
startValue initial value for interpolated operations
activeAudio audio buffer for interpolated operations, don't persist
activeNote audio oscillator for interpolated ops, don't persist
isLambda marker for return ops
isImplicitLambda marker for return ops
isCustomBlock marker for return ops
emptySlots caches the number of empty slots for reification
emptySlots caches the number of empty slots for reification
tag string or number to optionally identify the Context,
as a "return" target (for the "stop block" primitive)
*/
function Context(
@ -2801,22 +2883,19 @@ function Context(
this.startTime = null;
this.activeAudio = null;
this.activeNote = null;
this.isLambda = false; // marks the end of a lambda
this.isImplicitLambda = false; // marks the end of a C-shaped slot
this.isCustomBlock = false; // marks the end of a custom block's stack
this.emptySlots = 0; // used for block reification
this.tag = null; // lexical catch-tag for custom blocks
}
Context.prototype.toString = function () {
var pref = this.isLambda ? '\u03BB-' : '',
expr = this.expression;
var expr = this.expression;
if (expr instanceof Array) {
if (expr.length > 0) {
expr = '[' + expr[0] + ']';
}
}
return pref + 'Context >> ' + expr + ' ' + this.variables;
return 'Context >> ' + expr + ' ' + this.variables;
};
Context.prototype.image = function () {
@ -2870,9 +2949,10 @@ Context.prototype.continuation = function () {
} else if (this.parentContext) {
cont = this.parentContext;
} else {
return new Context(null, 'doStop');
return new Context(null, 'doYield');
}
cont = cont.copyForContinuation();
cont.tag = null;
cont.isContinuation = true;
return cont;
};
@ -3003,9 +3083,9 @@ VariableFrame.prototype.find = function (name) {
var frame = this.silentFind(name);
if (frame) {return frame; }
throw new Error(
'a variable of name \''
localize('a variable of name \'')
+ name
+ '\'\ndoes not exist in this context'
+ localize('\'\ndoes not exist in this context')
);
};
@ -3070,9 +3150,9 @@ VariableFrame.prototype.getVar = function (name) {
return '';
}
throw new Error(
'a variable of name \''
localize('a variable of name \'')
+ name
+ '\'\ndoes not exist in this context'
+ localize('\'\ndoes not exist in this context')
);
};

File diff suppressed because one or more lines are too long