summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorViraj Mahesh <virajmahesh@gmail.com>2014-07-13 09:47:30 +0400
committerViraj Mahesh <virajmahesh@gmail.com>2014-07-13 09:47:30 +0400
commita7f0de880f691ef32553713187a1b2f3d0cf3756 (patch)
treefd51b3fffa40e04876a7e414f3a995c6a5afb96c
parent7daaf1252a651271f170abc0a7a0f532778aad51 (diff)
parentec8b14a3758acfc852a6f02010394bd5814d7272 (diff)
downloadsnap-a7f0de880f691ef32553713187a1b2f3d0cf3756.tar.gz
snap-a7f0de880f691ef32553713187a1b2f3d0cf3756.zip
Merge branch 'master' into extensions
Conflicts: objects.js
-rw-r--r--blocks.js58
-rw-r--r--byob.js97
-rw-r--r--cloud.js15
-rw-r--r--gui.js123
-rwxr-xr-xhistory.txt63
-rw-r--r--lang-de.js10
-rw-r--r--lang-fi.js1280
-rwxr-xr-xlang-pt.js208
-rwxr-xr-xlang-pt_BR.js1389
-rw-r--r--lang-ru.js71
-rw-r--r--lists.js4
-rw-r--r--locale.js33
-rw-r--r--morphic.js5
-rw-r--r--objects.js524
-rw-r--r--paint.js62
-rwxr-xr-xsnap.html1
-rw-r--r--store.js16
-rw-r--r--threads.js24
18 files changed, 3851 insertions, 132 deletions
diff --git a/blocks.js b/blocks.js
index 21c4326..3402e22 100644
--- a/blocks.js
+++ b/blocks.js
@@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/
// Global stuff ////////////////////////////////////////////////////////
-modules.blocks = '2014-February-11';
+modules.blocks = '2014-June-06';
var SyntaxElementMorph;
@@ -925,17 +925,13 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
part = new InputSlotMorph(
null,
false,
- {
- /*
- color : 'color',
- fisheye : 'fisheye',
- whirl : 'whirl',
- pixelate : 'pixelate',
- mosaic : 'mosaic',
- brightness : 'brightness',
- */
- ghost : ['ghost']
- },
+ { brightness : ['brightness'],
+ ghost : ['ghost'],
+ negative : ['negative'],
+ comic: ['comic'],
+ duplicate: ['duplicate'],
+ confetti: ['confetti']
+ },
true
);
part.setContents(['ghost']);
@@ -1647,6 +1643,12 @@ SyntaxElementMorph.prototype.showBubble = function (value) {
morphToShow.silentSetWidth(img.width);
morphToShow.silentSetHeight(img.height);
morphToShow.image = img;
+ } else if (value instanceof Costume) {
+ img = value.thumbnail(new Point(40, 40));
+ morphToShow = new Morph();
+ morphToShow.silentSetWidth(img.width);
+ morphToShow.silentSetHeight(img.height);
+ morphToShow.image = img;
} else if (value instanceof Context) {
img = value.image();
morphToShow = new Morph();
@@ -2019,6 +2021,7 @@ BlockMorph.prototype.userMenu = function () {
var menu = new MenuMorph(this),
world = this.world(),
myself = this,
+ alternatives,
blck;
menu.addItem(
@@ -2076,6 +2079,14 @@ BlockMorph.prototype.userMenu = function () {
);
}
);
+ } else if (this.definition && this.alternatives) { // custom block
+ alternatives = this.alternatives();
+ if (alternatives.length > 0) {
+ menu.addItem(
+ 'relabel...',
+ function () {myself.relabel(alternatives); }
+ );
+ }
}
menu.addItem(
@@ -2274,6 +2285,7 @@ BlockMorph.prototype.relabel = function (alternativeSelectors) {
alternativeSelectors.forEach(function (sel) {
var block = SpriteMorph.prototype.blockForSelector(sel);
block.restoreInputs(oldInputs);
+ block.fixBlockColor(null, true);
block.addShadow(new Point(3, 3));
menu.addItem(
block,
@@ -2293,7 +2305,7 @@ BlockMorph.prototype.setSelector = function (aSelector) {
var oldInputs = this.inputs(),
info;
info = SpriteMorph.prototype.blocks[aSelector];
- this.category = info.category;
+ this.setCategory(info.category);
this.selector = aSelector;
this.setSpec(localize(info.spec));
this.restoreInputs(oldInputs);
@@ -2305,6 +2317,7 @@ BlockMorph.prototype.restoreInputs = function (oldInputs) {
// try to restore my previous inputs when my spec has been changed
var i = 0,
old,
+ nb,
myself = this;
this.inputs().forEach(function (inp) {
@@ -2315,7 +2328,14 @@ BlockMorph.prototype.restoreInputs = function (oldInputs) {
// original - turns empty numberslots to 0:
// inp.setContents(old.evaluate());
// "fix" may be wrong b/c constants
- inp.setContents(old.contents().text);
+ if (old.contents) {
+ inp.setContents(old.contents().text);
+ }
+ } else if (old instanceof CSlotMorph && inp instanceof CSlotMorph) {
+ nb = old.nestedBlock();
+ if (nb) {
+ inp.nestedBlock(nb.fullCopy());
+ }
}
i += 1;
});
@@ -4963,6 +4983,14 @@ ScriptsMorph.prototype.cleanUp = function () {
};
ScriptsMorph.prototype.exportScriptsPicture = function () {
+ var pic = this.scriptsPicture();
+ if (pic) {
+ window.open(pic.toDataURL());
+ }
+};
+
+ScriptsMorph.prototype.scriptsPicture = function () {
+ // private - answer a canvas containing the pictures of all scripts
var boundingBox, pic, ctx;
if (this.children.length === 0) {return; }
boundingBox = this.children[0].fullBounds();
@@ -4983,7 +5011,7 @@ ScriptsMorph.prototype.exportScriptsPicture = function () {
);
}
});
- window.open(pic.toDataURL());
+ return pic;
};
ScriptsMorph.prototype.addComment = function () {
diff --git a/byob.js b/byob.js
index 4b581e1..a17f976 100644
--- a/byob.js
+++ b/byob.js
@@ -106,7 +106,7 @@ SymbolMorph, isNil*/
// Global stuff ////////////////////////////////////////////////////////
-modules.byob = '2014-January-10';
+modules.byob = '2014-Jun-06';
// Declarations
@@ -336,6 +336,43 @@ CustomBlockDefinition.prototype.parseSpec = function (spec) {
return parts;
};
+// CustomBlockDefinition picturing
+
+CustomBlockDefinition.prototype.scriptsPicture = function () {
+ var scripts, proto, block, comment;
+
+ scripts = new ScriptsMorph();
+ scripts.cleanUpMargin = 10;
+ proto = new PrototypeHatBlockMorph(this);
+ proto.setPosition(scripts.position().add(10));
+ if (this.comment !== null) {
+ comment = this.comment.fullCopy();
+ proto.comment = comment;
+ comment.block = proto;
+ }
+ if (this.body !== null) {
+ proto.nextBlock(this.body.expression.fullCopy());
+ }
+ scripts.add(proto);
+ proto.fixBlockColor(null, true);
+ this.scripts.forEach(function (element) {
+ block = element.fullCopy();
+ block.setPosition(scripts.position().add(element.position()));
+ scripts.add(block);
+ if (block instanceof BlockMorph) {
+ block.allComments().forEach(function (comment) {
+ comment.align(block);
+ });
+ }
+ });
+ proto.allComments().forEach(function (comment) {
+ comment.align(proto);
+ });
+ proto.children[0].fixLayout();
+ scripts.fixMultiArgs();
+ return scripts.scriptsPicture();
+};
+
// CustomCommandBlockMorph /////////////////////////////////////////////
// CustomCommandBlockMorph inherits from CommandBlockMorph:
@@ -372,8 +409,12 @@ CustomCommandBlockMorph.prototype.refresh = function () {
this.setCategory(def.category);
if (this.blockSpec !== newSpec) {
oldInputs = this.inputs();
+ if (!this.zebraContrast) {
+ this.forceNormalColoring();
+ } else {
+ this.fixBlockColor();
+ }
this.setSpec(newSpec);
- this.fixBlockColor();
this.fixLabelColor();
this.restoreInputs(oldInputs);
} else { // update all input slots' drop-downs
@@ -704,6 +745,7 @@ CustomCommandBlockMorph.prototype.userMenu = function () {
} else {
menu.addLine();
}
+
// menu.addItem("export definition...", 'exportBlockDefinition');
menu.addItem("delete block definition...", 'deleteBlockDefinition');
}
@@ -805,6 +847,44 @@ CustomCommandBlockMorph.prototype.popUpbubbleHelp = function (
).popUp(this.world(), this.rightCenter().add(new Point(-8, 0)));
};
+// CustomCommandBlockMorph relabelling
+
+CustomCommandBlockMorph.prototype.relabel = function (alternatives) {
+ var menu = new MenuMorph(this),
+ oldInputs = this.inputs().map(
+ function (each) {return each.fullCopy(); }
+ ),
+ myself = this;
+ alternatives.forEach(function (def) {
+ var block = def.blockInstance();
+ block.restoreInputs(oldInputs);
+ block.fixBlockColor(null, true);
+ block.addShadow(new Point(3, 3));
+ menu.addItem(
+ block,
+ function () {
+ myself.definition = def;
+ myself.refresh();
+ }
+ );
+ });
+ menu.popup(this.world(), this.bottomLeft().subtract(new Point(
+ 8,
+ this instanceof CommandBlockMorph ? this.corner : 0
+ )));
+};
+
+CustomCommandBlockMorph.prototype.alternatives = function () {
+ var rcvr = this.receiver(),
+ stage = rcvr.parentThatIsA(StageMorph),
+ allDefs = rcvr.customBlocks.concat(stage.globalBlocks),
+ myself = this;
+ return allDefs.filter(function (each) {
+ return each !== myself.definition &&
+ each.type === myself.definition.type;
+ });
+};
+
// CustomReporterBlockMorph ////////////////////////////////////////////
// CustomReporterBlockMorph inherits from ReporterBlockMorph:
@@ -920,6 +1000,14 @@ CustomReporterBlockMorph.prototype.bubbleHelp
CustomReporterBlockMorph.prototype.popUpbubbleHelp
= CustomCommandBlockMorph.prototype.popUpbubbleHelp;
+// CustomReporterBlockMorph relabelling
+
+CustomReporterBlockMorph.prototype.relabel
+ = CustomCommandBlockMorph.prototype.relabel;
+
+CustomReporterBlockMorph.prototype.alternatives
+ = CustomCommandBlockMorph.prototype.alternatives;
+
// JaggedBlockMorph ////////////////////////////////////////////////////
/*
@@ -2579,7 +2667,10 @@ InputSlotDialogMorph.prototype.symbolMenu = function () {
myself = this;
SymbolMorph.prototype.names.forEach(function (symbol) {
symbols.push([
- [new SymbolMorph(symbol, myself.fontSize, symbolColor), symbol],
+ [
+ new SymbolMorph(symbol, myself.fontSize, symbolColor),
+ localize(symbol)
+ ],
'$' + symbol
]);
});
diff --git a/cloud.js b/cloud.js
index 17fc76b..54189d8 100644
--- a/cloud.js
+++ b/cloud.js
@@ -27,9 +27,10 @@
// Global settings /////////////////////////////////////////////////////
-/*global modules, IDE_Morph, SnapSerializer, hex_sha512, alert, nop*/
+/*global modules, IDE_Morph, SnapSerializer, hex_sha512, alert, nop,
+localize*/
-modules.cloud = '2014-January-09';
+modules.cloud = '2014-May-26';
// Global stuff
@@ -107,7 +108,7 @@ Cloud.prototype.signup = function (
errorCall.call(
null,
myself.url + 'SignUp',
- 'could not connect to:'
+ localize('could not connect to:')
);
}
}
@@ -164,7 +165,7 @@ Cloud.prototype.getPublicProject = function (
errorCall.call(
null,
myself.url + 'Public',
- 'could not connect to:'
+ localize('could not connect to:')
);
}
}
@@ -217,7 +218,7 @@ Cloud.prototype.resetPassword = function (
errorCall.call(
null,
myself.url + 'ResetPW',
- 'could not connect to:'
+ localize('could not connect to:')
);
}
}
@@ -264,7 +265,7 @@ Cloud.prototype.connect = function (
errorCall.call(
null,
myself.url,
- 'could not connect to:'
+ localize('could not connect to:')
);
}
}
@@ -533,7 +534,7 @@ Cloud.prototype.callService = function (
errorCall.call(
this,
request.responseText,
- 'Service: ' + serviceName
+ localize('Service:') + ' ' + localize(serviceName)
);
return;
}
diff --git a/gui.js b/gui.js
index 0f4f2eb..d12453b 100644
--- a/gui.js
+++ b/gui.js
@@ -64,11 +64,12 @@ standardSettings, Sound, BlockMorph, ToggleMorph, InputSlotDialogMorph,
ScriptsMorph, isNil, SymbolMorph, BlockExportDialogMorph,
BlockImportDialogMorph, SnapTranslator, localize, List, InputSlotMorph,
SnapCloud, Uint8Array, HandleMorph, SVG_Costume, fontHeight, hex_sha512,
-sb, CommentMorph, CommandBlockMorph, BlockLabelPlaceHolderMorph, Audio*/
+sb, CommentMorph, CommandBlockMorph, BlockLabelPlaceHolderMorph, Audio,
+SpeechBubbleMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.gui = '2014-February-13';
+modules.gui = '2014-Jun-04';
// Declarations
@@ -848,7 +849,7 @@ IDE_Morph.prototype.createCategories = function () {
this.add(this.categories);
};
-IDE_Morph.prototype.createPalette = function () {
+IDE_Morph.prototype.createPalette = function (forSearching) {
// assumes that the logo pane has already been created
// needs the categories pane for layout
var myself = this;
@@ -857,7 +858,15 @@ IDE_Morph.prototype.createPalette = function () {
this.palette.destroy();
}
- this.palette = this.currentSprite.palette(this.currentCategory);
+ if (forSearching) {
+ this.palette = new ScrollFrameMorph(
+ null,
+ null,
+ this.currentSprite.sliderColor
+ );
+ } else {
+ this.palette = this.currentSprite.palette(this.currentCategory);
+ }
this.palette.isDraggable = false;
this.palette.acceptsDrops = true;
this.palette.contents.acceptsDrops = false;
@@ -882,6 +891,7 @@ IDE_Morph.prototype.createPalette = function () {
this.add(this.palette);
this.palette.scrollX(this.palette.padding);
this.palette.scrollY(this.palette.padding);
+ return this.palette;
};
IDE_Morph.prototype.createStage = function () {
@@ -2273,23 +2283,7 @@ IDE_Morph.prototype.projectMenu = function () {
}
);
menu.addItem('Open...', 'openProjectsBrowser');
- menu.addItem(
- 'Save',
- function () {
- if (myself.source === 'examples') {
- myself.source = 'local'; // cannot save to examples
- }
- if (myself.projectName) {
- if (myself.source === 'local') { // as well as 'examples'
- myself.saveProject(myself.projectName);
- } else { // 'cloud'
- myself.saveProjectToCloud(myself.projectName);
- }
- } else {
- myself.saveProjectsBrowser();
- }
- }
- );
+ menu.addItem('Save', "save");
if (shiftClicked) {
menu.addItem(
'Save to disk',
@@ -2356,6 +2350,15 @@ IDE_Morph.prototype.projectMenu = function () {
'show global custom block definitions as XML\nin a new browser window'
);
+ if (shiftClicked) {
+ menu.addItem(
+ 'Export all scripts as pic...',
+ function () {myself.exportScriptsPicture(); },
+ 'show a picture of all scripts\nand block definitions',
+ new Color(100, 0, 0)
+ );
+ }
+
menu.addLine();
menu.addItem(
'Import tools',
@@ -2532,6 +2535,7 @@ IDE_Morph.prototype.aboutSnap = function () {
+ '\n\nNathan Dinsmore: Saving/Loading, Snap-Logo Design, '
+ 'countless bugfixes'
+ '\nKartik Chandra: Paint Editor'
+ + '\nYuan Yuan: Graphic Effects'
+ '\nIan Reynolds: UI Design, Event Bindings, '
+ 'Sound primitives'
+ '\nIvan Motyashov: Initial Squeak Porting'
@@ -2720,6 +2724,22 @@ IDE_Morph.prototype.newProject = function () {
this.fixLayout();
};
+IDE_Morph.prototype.save = function () {
+ if (this.source === 'examples') {
+ this.source = 'local'; // cannot save to examples
+ }
+ if (this.projectName) {
+ if (this.source === 'local') { // as well as 'examples'
+ this.saveProject(this.projectName);
+ } else { // 'cloud'
+ this.saveProjectToCloud(this.projectName);
+ }
+ } else {
+ this.saveProjectsBrowser();
+ }
+};
+
+
IDE_Morph.prototype.saveProject = function (name) {
var myself = this;
this.nextSteps([
@@ -2837,6 +2857,56 @@ IDE_Morph.prototype.exportSprite = function (sprite) {
+ '</sprites>');
};
+IDE_Morph.prototype.exportScriptsPicture = function () {
+ var pics = [],
+ pic,
+ padding = 20,
+ w = 0,
+ h = 0,
+ y = 0,
+ ctx;
+
+ // collect all script pics
+ this.sprites.asArray().forEach(function (sprite) {
+ pics.push(sprite.image);
+ pics.push(sprite.scripts.scriptsPicture());
+ sprite.customBlocks.forEach(function (def) {
+ pics.push(def.scriptsPicture());
+ });
+ });
+ pics.push(this.stage.image);
+ pics.push(this.stage.scripts.scriptsPicture());
+ this.stage.customBlocks.forEach(function (def) {
+ pics.push(def.scriptsPicture());
+ });
+
+ // collect global block pics
+ this.stage.globalBlocks.forEach(function (def) {
+ pics.push(def.scriptsPicture());
+ });
+
+ pics = pics.filter(function (each) {return !isNil(each); });
+
+ // determine dimensions of composite
+ pics.forEach(function (each) {
+ w = Math.max(w, each.width);
+ h += (each.height);
+ h += padding;
+ });
+ h -= padding;
+ pic = newCanvas(new Point(w, h));
+ ctx = pic.getContext('2d');
+
+ // draw all parts
+ pics.forEach(function (each) {
+ ctx.drawImage(each, 0, y);
+ y += padding;
+ y += each.height;
+ });
+
+ window.open(pic.toDataURL());
+};
+
IDE_Morph.prototype.openProjectString = function (str) {
var msg,
myself = this;
@@ -4524,6 +4594,17 @@ ProjectDialogMorph.prototype.installCloudProjectList = function (pl) {
myself.preview.texture = item.Thumbnail || null;
myself.preview.cachedTexture = null;
myself.preview.drawNew();
+ (new SpeechBubbleMorph(new TextMorph(
+ localize('last changed') + '\n' + item.Updated,
+ null,
+ null,
+ null,
+ null,
+ 'center'
+ ))).popUp(
+ myself.world(),
+ myself.preview.rightCenter().add(new Point(2, 0))
+ );
}
if (item.Public === 'true') {
myself.shareButton.hide();
diff --git a/history.txt b/history.txt
index 2096b08..02fc2a0 100755
--- a/history.txt
+++ b/history.txt
@@ -2103,3 +2103,66 @@ ______
* Widgets: new “promptVector” dialog box feature
* GUI: Use new vector prompter for stage dimensions
* German translation update
+
+140331
+------
+* Objects: experimental “wardrobe” and “jukebox” reporters in dev mode
+* Blocks, Objects: display costume thumbnails in speech/thought/value bubbles and watcher cells
+* Objects: let “switch to costume” block accept actual costume objects (in addition to names and numbers)
+
+140430
+------
+* new Finnish translation, yay! Thanks, Jouni!
+* new Brazilian Portuguese translation, yay! Thanks, Aldo!
+* Russian translation update
+* Portuguese translation update
+* additional localisations, thanks, Manuel!
+* text-encoding fix for exporting variable contents, thanks, Blob!
+* set turbo mode block fix, thanks, Michael and Nathan!
+* enable storage and retrieval of first-class costumes in both file formats
+
+140502
+------
+* error message when trying to import a non-text file into a variable, thanks, Nate!
+* fixed #407 (custom-block coloring w/ zebra off)
+
+140520
+------
+* Morphic: Prevent default action for ctrl-/cmd-key event
+* Snap.html: Focus the world canvas on startup, so Snap reacts to keyboard events right away
+* Threads: new Variable data structure, for refactoring upvar references, not yet used anywhere
+* Objects, GUI: Search Blocks, feature. Thanks, Kyle, for architecting and designing this!!!
+* Objects, GUI: Keyboard-shortcuts for opening (cmd-o), saving (cmd-s) projects and for finding blocks (cmd-f)
+
+140526
+------
+* Objects: Fixed #445 (minor search + zoom issues)
+* Localization additions and Portuguese translation update, thanks, Manuel!
+* GUI, cloud: Show last-changed-timestamp when opening cloud projects
+
+140604
+------
+* Blocks: refactor “script pics” feature
+* BYOB: new scriptsPicture() method for custom block definitions
+* GUI: new (hidden) feature: “Export all scripts as pic” (including custom block refs)
+* Graphic effects!!! Yay, thanks, Yuan!
+* Bug fixes from Nathan, yay, thanks, Nathan!!
+* German translation update
+* Paint Editor transforms, yay, thanks, Kartik!!
+
+140605
+------
+* Objects: stop replacing the empty string with the number zero in watchers
+* Threads: initialize new variables with zero (instead of null)
+* Objects: fixed #465
+* Objects: fixed #457
+
+140605
+------
+* Objects: gracefully hide & show the stage, fixed #281
+* Objects: add hide and show blocks to the stage’s “looks” category
+* Objects: added more relabelling options to SAY and THINK variants
+* Blocks, objects: enable relabelling blocks with C-Slots
+* Blocks: enable relabelling blocks across categories
+* Objects: more relabelling options for SAY, THINK, ASK
+* BYOB, Blocks: relabelling custom blocks (experimental)
diff --git a/lang-de.js b/lang-de.js
index 9ce0c50..0a62da0 100644
--- a/lang-de.js
+++ b/lang-de.js
@@ -185,7 +185,7 @@ SnapTranslator.dict.de = {
'translator_e-mail':
'jens@moenig.org', // optional
'last_changed':
- '2014-02-13', // this, too, will appear in the Translators tab
+ '2014-06-04', // this, too, will appear in the Translators tab
// GUI
// control bar:
@@ -1122,8 +1122,16 @@ SnapTranslator.dict.de = {
'Leer',
// graphical effects
+ 'brightness':
+ 'Helligeit',
'ghost':
'Durchsichtigkeit',
+ 'negative':
+ 'Farbumkehr',
+ 'comic':
+ 'Moire',
+ 'confetti':
+ 'Farbverschiebung',
// keys
'space':
diff --git a/lang-fi.js b/lang-fi.js
new file mode 100644
index 0000000..bb70a9f
--- /dev/null
+++ b/lang-fi.js
@@ -0,0 +1,1280 @@
+/*
+
+ lang-fi.js
+
+ Finnish translation for SNAP!
+
+ written by Jouni K. Seppänen
+
+ Copyright (C) 2014 by Jens Mönig
+
+ This file is part of Snap!.
+
+ Snap! is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+
+ Note to Translators:
+ --------------------
+ At this stage of development, Snap! can be translated to any LTR language
+ maintaining the current order of inputs (formal parameters in blocks).
+
+ Translating Snap! is easy:
+
+
+ 1. Download
+
+ Download the sources and extract them into a local folder on your
+ computer:
+
+ <http://snap.berkeley.edu/snapsource/snap.zip>
+
+ Use the German translation file (named 'lang-de.js') as template for your
+ own translations. Start with editing the original file, because that way
+ you will be able to immediately check the results in your browsers while
+ you're working on your translation (keep the local copy of snap.html open
+ in your web browser, and refresh it as you progress with your
+ translation).
+
+
+ 2. Edit
+
+ Edit the translation file with a regular text editor, or with your
+ favorite JavaScript editor.
+
+ In the first non-commented line (the one right below this
+ note) replace "de" with the two-letter ISO 639-1 code for your language,
+ e.g.
+
+ fr - French => SnapTranslator.dict.fr = {
+ it - Italian => SnapTranslator.dict.it = {
+ pl - Polish => SnapTranslator.dict.pl = {
+ pt - Portuguese => SnapTranslator.dict.pt = {
+ es - Spanish => SnapTranslator.dict.es = {
+ el - Greek => => SnapTranslator.dict.el = {
+
+ etc. (see <http://en.wikipedia.org/wiki/ISO_639-1>)
+
+
+ 3. Translate
+
+ Then work through the dictionary, replacing the German strings against
+ your translations. The dictionary is a straight-forward JavaScript ad-hoc
+ object, for review purposes it should be formatted as follows:
+
+ {
+ 'English string':
+ 'Translation string',
+ 'last key':
+ } 'last value'
+
+ and you only edit the indented value strings. Note that each key-value
+ pair needs to be delimited by a comma, but that there shouldn't be a comma
+ after the last pair (again, just overwrite the template file and you'll be
+ fine).
+
+ If something doesn't work, or if you're unsure about the formalities you
+ should check your file with
+
+ <http://JSLint.com>
+
+ This will inform you about any missed commas etc.
+
+
+ 4. Accented characters
+
+ Depending on which text editor and which file encoding you use you can
+ directly enter special characters (e.g. Umlaut, accented characters) on
+ your keyboard. However, I've noticed that some browsers may not display
+ special characters correctly, even if other browsers do. So it's best to
+ check your results in several browsers. If you want to be on the safe
+ side, it's even better to escape these characters using Unicode.
+
+ see: <http://0xcc.net/jsescape/>
+
+
+ 5. Block specs:
+
+ At this time your translation of block specs will only work
+ correctly, if the order of formal parameters and their types
+ are unchanged. Placeholders for inputs (formal parameters) are
+ indicated by a preceding % prefix and followed by a type
+ abbreviation.
+
+ For example:
+
+ 'say %s for %n secs'
+
+ can currently not be changed into
+
+ 'say %n secs long %s'
+
+ and still work as intended.
+
+ Similarly
+
+ 'point towards %dst'
+
+ cannot be changed into
+
+ 'point towards %cst'
+
+ without breaking its functionality.
+
+
+ 6. Submit
+
+ When you're done, rename the edited file by replacing the "de" part of the
+ filename with the two-letter ISO 639-1 code for your language, e.g.
+
+ fr - French => lang-fr.js
+ it - Italian => lang-it.js
+ pl - Polish => lang-pl.js
+ pt - Portuguese => lang-pt.js
+ es - Spanish => lang-es.js
+ el - Greek => => lang-el.js
+
+ and send it to me for inclusion in the official Snap! distribution.
+ Once your translation has been included, Your name will the shown in the
+ "Translators" tab in the "About Snap!" dialog box, and you will be able to
+ directly launch a translated version of Snap! in your browser by appending
+
+ lang:xx
+
+ to the URL, xx representing your translations two-letter code.
+
+
+ 7. Known issues
+
+ In some browsers accents or ornaments located in typographic ascenders
+ above the cap height are currently (partially) cut-off.
+
+ Enjoy!
+ -Jens
+*/
+
+/*global SnapTranslator*/
+
+SnapTranslator.dict.fi = {
+
+/*
+ Special characters: (see <http://0xcc.net/jsescape/>)
+
+ Ä, ä \u00c4, \u00e4
+ Ö, ö \u00d6, \u00f6
+ → \u2192
+ \u200B zero-width space, useful to escape % at the beginning of words
+*/
+
+ // translations meta information
+ 'language_name':
+ 'suomi', // the name as it should appear in the language menu
+ 'language_translator':
+ 'Jouni K. Sepp\u00e4nen', // your name for the Translators tab
+ 'translator_e-mail':
+ 'jks@iki.fi', // optional
+ 'last_changed':
+ '2014-04-18', // this, too, will appear in the Translators tab
+
+ // GUI
+ // control bar:
+ 'untitled':
+ 'nimet\u00f6n',
+ 'development mode':
+ 'kehitysmoodi',
+
+ // categories:
+ 'Motion':
+ 'Liike',
+ 'Looks':
+ 'Ulkon\u00e4k\u00f6',
+ 'Sound':
+ '\u00c4\u00e4ni',
+ 'Pen':
+ 'Kyn\u00e4',
+ 'Control':
+ 'Ohjaus',
+ 'Sensing':
+ 'Tuntoaisti',
+ 'Operators':
+ 'Laskenta',
+ 'Variables':
+ 'Muuttujat',
+ 'Lists':
+ 'Listat',
+ 'Other':
+ 'Muut',
+
+ // editor:
+ 'draggable':
+ 'hiirell\u00e4 liikuteltava',
+
+ // tabs:
+ 'Scripts':
+ 'Skriptit',
+ 'Costumes':
+ 'Asut',
+ 'Sounds':
+ '\u00c4\u00e4net',
+
+ // names:
+ 'Sprite':
+ 'Hahmo',
+ 'Stage':
+ 'Esiintymislava',
+
+ // rotation styles:
+ 'don\'t rotate':
+ 'ei py\u00f6ri',
+ 'can rotate':
+ 'py\u00f6rii vapaasti',
+ 'only face left/right':
+ 'k\u00e4\u00e4ntyy vain vasemmalle ja oikealle',
+
+ // new sprite button:
+ 'add a new sprite':
+ 'lis\u00e4\u00e4 uusi hahmo',
+
+ // tab help
+ 'costumes tab help':
+ 'Tuo kuva verkosta tai koneeltasi\n'
+ + 'siirt\u00e4m\u00e4ll\u00e4 se hiirell\u00e4 t\u00e4h\u00e4n',
+ 'import a sound from your computer\nby dragging it into here':
+ 'Tuo \u00e4\u00e4ni koneeltasi\n'
+ + 'siirt\u00e4m\u00e4ll\u00e4 se hiirell\u00e4 t\u00e4h\u00e4n',
+
+ // primitive blocks:
+
+ /*
+ Attention Translators:
+ ----------------------
+ At this time your translation of block specs will only work
+ correctly, if the order of formal parameters and their types
+ are unchanged. Placeholders for inputs (formal parameters) are
+ indicated by a preceding % prefix and followed by a type
+ abbreviation.
+
+ For example:
+
+ 'say %s for %n secs'
+
+ can currently not be changed into
+
+ 'say %n secs long %s'
+
+ and still work as intended.
+
+ Similarly
+
+ 'point towards %dst'
+
+ cannot be changed into
+
+ 'point towards %cst'
+
+ without breaking its functionality.
+ */
+
+ // motion:
+ 'Stage selected:\nno motion primitives':
+ 'Esiintymislava valittuna\nei liikekomentoja',
+
+ 'move %n steps':
+ 'liiku %n askelta',
+ 'turn %clockwise %n degrees':
+ 'k\u00e4\u00e4nny %clockwise %n astetta',
+ 'turn %counterclockwise %n degrees':
+ 'k\u00e4\u00e4nny %counterclockwise %n astetta',
+ 'point in direction %dir':
+ 'osoita suuntaan %dir',
+ 'point towards %dst':
+ 'osoita hahmoa %dst kohti',
+ 'go to x: %n y: %n':
+ 'mene paikkaan x: %n y: %n',
+ 'go to %dst':
+ 'mene hahmon %dst luo',
+ 'glide %n secs to x: %n y: %n':
+ 'liu\'u %n s \u2192 x: %n y: %n',
+ 'change x by %n':
+ 'muuta x:\u00e4\u00e4 %n askelta',
+ 'set x to %n':
+ 'aseta x:ksi %n',
+ 'change y by %n':
+ 'muuta y:t\u00e4 %n askelta',
+ 'set y to %n':
+ 'aseta y:ksi %n',
+ 'if on edge, bounce':
+ 'kimpoa reunasta',
+ 'x position':
+ 'x-paikka',
+ 'y position':
+ 'y-paikka',
+ 'direction':
+ 'suunta',
+
+ // looks:
+ 'switch to costume %cst':
+ 'vaihda asuun %cst',
+ 'next costume':
+ 'seuraava asu',
+ 'costume #':
+ 'asun nro',
+ 'say %s for %n secs':
+ 'sano %s %n sekunnin ajan',
+ 'say %s':
+ 'sano %s',
+ 'think %s for %n secs':
+ 'ajattele %s %n sekunnin ajan',
+ 'think %s':
+ 'ajattele %s',
+ 'Hello!':
+ 'Hei!',
+ 'Hmm...':
+ 'Hmm...',
+ 'change %eff effect by %n':
+ 'muuta efekti\u00e4 %eff %n yksikk\u00f6\u00e4',
+ 'set %eff effect to %n':
+ 'aseta efektin %eff m\u00e4\u00e4r\u00e4ksi %n',
+ 'clear graphic effects':
+ 'poista efektit',
+ 'change size by %n':
+ // using a zero-width space to hide % at word beginning
+ 'muuta kokoa %n \u200B%-yksikk\u00f6\u00e4',
+ 'set size to %n %':
+ 'aseta kooksi %n %',
+ 'size':
+ 'koko',
+ 'show':
+ 'n\u00e4yt\u00e4',
+ 'hide':
+ 'piilota',
+ 'go to front':
+ 'tule etualalle',
+ 'go back %n layers':
+ 'siirry %n kerrosta taakse',
+
+ 'development mode \ndebugging primitives:':
+ 'Kehitysmoodin \ndebuggauskomennot:',
+ 'console log %mult%s':
+ 'kirjoita konsoliin: %mult%s',
+ 'alert %mult%s':
+ 'ponnahdusikkuna: %mult%s',
+
+ // sound:
+ 'play sound %snd':
+ 'soita \u00e4\u00e4ni %snd',
+ 'play sound %snd until done':
+ 'soita \u00e4\u00e4ni %snd kokonaan',
+ 'stop all sounds':
+ 'pys\u00e4yt\u00e4 kaikki \u00e4\u00e4net',
+ 'rest for %n beats':
+ 'tauko %n iskua',
+ 'play note %n for %n beats':
+ 'nuotti %n %n iskua',
+ 'change tempo by %n':
+ 'vaihda tempoa %n iskulla/min',
+ 'set tempo to %n bpm':
+ 'aseta tempoksi %n iskua/min',
+ 'tempo':
+ 'tempo',
+
+ // pen:
+ 'clear':
+ 'tyhjenn\u00e4',
+ 'pen down':
+ 'kyn\u00e4 alas',
+ 'pen up':
+ 'kyn\u00e4 yl\u00f6s',
+ 'set pen color to %clr':
+ 'aseta kyn\u00e4n v\u00e4riksi %clr',
+ 'change pen color by %n':
+ 'vaihda kyn\u00e4n v\u00e4ri\u00e4 m\u00e4\u00e4r\u00e4ll\u00e4 %n',
+ 'set pen color to %n':
+ 'aseta kyn\u00e4n v\u00e4riksi %n',
+ 'change pen shade by %n':
+ // using a zero-width space to hide % at word beginning
+ 'muuta kirkkautta %n \u200b%-yks.',
+ 'set pen shade to %n':
+ 'aseta kirkkaudeksi %n %',
+ 'change pen size by %n':
+ 'muuta paksuutta m\u00e4\u00e4r\u00e4ll\u00e4 %n',
+ 'set pen size to %n':
+ 'aseta kyn\u00e4n paksuudeksi %n',
+ 'stamp':
+ 'leimaa',
+
+ // control:
+ 'when %greenflag clicked':
+ 'kun klikataan %greenflag',
+ 'when %keyHat key pressed':
+ 'kun painetaan %keyHat',
+ 'when I am clicked':
+ 'kun minua klikataan',
+ 'when I receive %msgHat':
+ 'kun vastaanotan sanoman %msgHat',
+ 'broadcast %msg':
+ 'l\u00e4het\u00e4 sanoma %msg',
+ 'broadcast %msg and wait':
+ 'l\u00e4het\u00e4 sanoma %msg ja odota',
+ 'Message name':
+ 'Sanoma',
+ 'message':
+ 'sanoma',
+ 'any message':
+ 'mik\u00e4 tahansa',
+ 'wait %n secs':
+ 'odota %n sekuntia',
+ 'wait until %b':
+ 'odota kunnes %b',
+ 'forever %c':
+ 'ikuisesti %c',
+ 'repeat %n %c':
+ 'toista %n kertaa %c',
+ 'repeat until %b %c':
+ 'toista kunnes %b %c',
+ 'if %b %c':
+ 'jos %b %c',
+ 'if %b %c else %c':
+ 'jos %b %c muuten %c',
+ 'report %s':
+ 'vastaa %s',
+ 'stop %stopChoices':
+ 'pys\u00e4yt\u00e4 %stopChoices',
+ 'all':
+ 'kaikki',
+ 'this script':
+ 't\u00e4m\u00e4 skripti',
+ 'this block':
+ 't\u00e4m\u00e4 palikka',
+ 'stop %stopOthersChoices':
+ 'pys\u00e4yt\u00e4 %stopOthersChoices',
+ 'all but this script':
+ 'kaikki paitsi t\u00e4m\u00e4 skripti',
+ 'other scripts in sprite':
+ 'hahmon muut skriptit',
+ 'pause all %pause':
+ 'keskeyt\u00e4 kaikki %pause',
+ 'run %cmdRing %inputs':
+ 'suorita %cmdRing %inputs',
+ 'launch %cmdRing %inputs':
+ 'k\u00e4ynnist\u00e4 %cmdRing %inputs',
+ 'call %repRing %inputs':
+ 'kutsu %repRing %inputs',
+ 'run %cmdRing w/continuation':
+ 'suorita %cmdRing kontinuaatiolla',
+ 'call %cmdRing w/continuation':
+ 'kutsu %cmdRing kontinuaatiolla',
+ 'warp %c':
+ 'supernopeasti %c',
+ 'when I start as a clone':
+ 'Kun aloitan kloonina',
+ 'create a clone of %cln':
+ 'kloonaa %cln',
+ 'myself':
+ 'minut',
+ 'delete this clone':
+ 'poista t\u00e4m\u00e4 klooni',
+
+ // sensing:
+ 'touching %col ?':
+ 'koskettaa hahmoa %col ?',
+ 'touching %clr ?':
+ 'koskettaa v\u00e4ri\u00e4 %clr ?',
+ 'color %clr is touching %clr ?':
+ 'v\u00e4ri %clr koskettaa v\u00e4ri\u00e4 %clr ?',
+ 'ask %s and wait':
+ 'kysy %s ja odota',
+ 'what\'s your name?':
+ 'Mik\u00e4 sinun nimesi on?',
+ 'answer':
+ 'vastaus',
+ 'mouse x':
+ 'hiiren x-paikka',
+ 'mouse y':
+ 'hiiren y-paikka',
+ 'mouse down?':
+ 'hiiren n\u00e4pp\u00e4in painettuna?',
+ 'key %key pressed?':
+ 'n\u00e4pp\u00e4in %key painettuna?',
+ 'distance to %dst':
+ 'et\u00e4isyys hahmoon %dst',
+ 'reset timer':
+ 'nollaa ajastin',
+ 'timer':
+ 'ajastin',
+ '%att of %spr':
+ '%att hahmolla %spr',
+ 'http:// %s':
+ 'http:// %s',
+ 'turbo mode?':
+ 'turbonopeus?',
+ 'set turbo mode to %b':
+ 'kytke turbonopeus p\u00e4\u00e4lle jos %b',
+
+ 'filtered for %clr':
+ 'suodatettuna v\u00e4ri %clr',
+ 'stack size':
+ 'pinon koko',
+ 'frames':
+ 'ruutuja',
+
+ // operators:
+ '%n mod %n':
+ 'jakoj\u00e4\u00e4nn\u00f6s laskusta %n / %n',
+ 'round %n':
+ 'py\u00f6rist\u00e4 %n',
+ '%fun of %n':
+ '%fun %n',
+ 'pick random %n to %n':
+ 'arvo satunnaisluku %n .. %n',
+ '%b and %b':
+ '%b ja %b',
+ '%b or %b':
+ '%b tai %b',
+ 'not %b':
+ 'ei %b',
+ 'true':
+ 'tosi',
+ 'false':
+ 'ep\u00e4tosi',
+ 'join %words':
+ 'yhdist\u00e4 %words',
+ 'split %s by %delim':
+ 'pilko %s %delim kohdalta',
+ 'hello':
+ 'Hei',
+ 'world':
+ 'maailma',
+ 'letter %n of %s':
+ 'kirjain nro %n tekstist\u00e4 %s',
+ 'length of %s':
+ 'tekstin %s pituus',
+ 'unicode of %s':
+ 'merkin %s Unicode-arvo',
+ 'unicode %n as letter':
+ 'Unicode-arvoa %n vastaava merkki',
+ 'is %s a %typ ?':
+ 'onko %s %typ ?',
+ 'is %s identical to %s ?':
+ 'onko %s sama kuin %s ?',
+
+ 'type of %s':
+ '%s:n tyyppi',
+
+ // variables:
+ 'Make a variable':
+ 'Uusi muuttuja',
+ 'Variable name':
+ 'Muuttujan nimi',
+ 'Script variable name':
+ 'Skriptimuuttujan nimi',
+ 'Delete a variable':
+ 'poista muuttuja',
+
+ 'set %var to %s':
+ 'aseta muuttujan %var arvoksi %s',
+ 'change %var by %n':
+ 'muuta muuttujaa %var m\u00e4\u00e4r\u00e4ll\u00e4 %n',
+ 'show variable %var':
+ 'n\u00e4yt\u00e4 muuttuja %var',
+ 'hide variable %var':
+ 'piilota muuttuja %var',
+ 'script variables %scriptVars':
+ 'skriptimuuttujat %scriptVars',
+
+ // lists:
+ 'list %exp':
+ 'lista %exp',
+ '%s in front of %l':
+ '%s listan %l aluksi',
+ 'item %idx of %l':
+ 'alkio kohdassa %idx listassa %l',
+ 'all but first of %l':
+ 'kaikki paitsi ensimm\u00e4inen alkio listasta %l',
+ 'length of %l':
+ 'listan %l pituus',
+ '%l contains %s':
+ 'lista %l sis\u00e4lt\u00e4\u00e4 %s',
+ 'thing':
+ 'alkio',
+ 'add %s to %l':
+ 'lis\u00e4\u00e4 %s listaan %l',
+ 'delete %ida of %l':
+ 'poista %ida listasta %l',
+ 'insert %s at %idx of %l':
+ 'lis\u00e4\u00e4 %s kohtaan %idx listassa %l',
+ 'replace item %idx of %l with %s':
+ 'vaihda kohtaan %idx listassa %l alkio %s',
+
+ // other
+ 'Make a block':
+ 'Uusi palikka',
+
+ // menus
+ // snap menu
+ 'About...':
+ 'Tietoa Snapista...',
+ 'Reference manual':
+ 'K\u00e4ytt\u00f6ohje',
+ 'Snap! website':
+ 'Snapin kotisivu',
+ 'Download source':
+ 'Lataa l\u00e4hdekoodi',
+ 'Switch back to user mode':
+ 'Palaa k\u00e4ytt\u00e4j\u00e4moodiin',
+ 'disable deep-Morphic\ncontext menus\nand show user-friendly ones':
+ 'poista Morphic-valikot k\u00e4yt\u00f6st\u00e4\n'
+ + 'ja n\u00e4yt\u00e4 helpot valikot',
+ 'Switch to dev mode':
+ 'vaihda kehitysmoodiin',
+ 'enable Morphic\ncontext menus\nand inspectors,\nnot user-friendly!':
+ 'n\u00e4yt\u00e4 Morphic-toiminnot,\n'
+ + 'ei kovin helppok\u00e4ytt\u00f6isi\u00e4',
+
+ // project menu
+ 'Project notes...':
+ 'Projektimerkint\u00f6j\u00e4...',
+ 'New':
+ 'Uusi',
+ 'Open...':
+ 'Avaa...',
+ 'Save':
+ 'Tallenna',
+ 'Save As...':
+ 'Tallenna nimell\u00e4...',
+ 'Import...':
+ 'Tuo...',
+ 'file menu import hint':
+ 'lataa viety projekti,\npalikkakirjasto, asu\ntai \u00e4\u00e4ni',
+ 'Export project as plain text...':
+ 'Vie projekti tekstin\u00e4...',
+ 'Export project...':
+ 'Vie projekti...',
+ 'show project data as XML\nin a new browser window':
+ 'n\u00e4yt\u00e4 projekti XML-muodossa\nuudessa selainikkunassa',
+ 'Export blocks...':
+ 'Vie palikoita...',
+ 'show global custom block definitions as XML\nin a new browser window':
+ 'n\u00e4yt\u00e4 yhteiset palikkam\u00e4\u00e4rittelyt\n'
+ + 'XML-muodossa uudessa selainikkunassa',
+ 'Import tools':
+ 'Tuo ty\u00f6kaluja',
+ 'load the official library of\npowerful blocks':
+ 'lataa virallinen tehopalikoiden kirjasto',
+ 'Libraries...':
+ 'Kirjastot...',
+ 'Import library':
+ 'Tuo kirjasto',
+
+ // cloud menu
+ 'Login...':
+ 'Kirjaudu...',
+ 'Signup...':
+ 'Luo k\u00e4ytt\u00e4j\u00e4tili...',
+
+ // settings menu
+ 'Language...':
+ 'Kieli...',
+ 'Zoom blocks...':
+ 'Suurenna palikoita...',
+ 'Stage size...':
+ 'Esiintymislavan koko...',
+ 'Stage size':
+ 'Esiintymislavan koko',
+ 'Stage width':
+ 'Esiintymislavan leveys',
+ 'Stage height':
+ 'Esiintymislavan korkeus',
+ 'Default':
+ 'Tavallinen',
+ 'Blurred shadows':
+ 'Sumeat varjot',
+ 'uncheck to use solid drop\nshadows and highlights':
+ 'poistamalla saat kiinte\u00e4t varjot\nja korostukset',
+ 'check to use blurred drop\nshadows and highlights':
+ 'asettamalla saat sumeat varjot\nja korostukset',
+ 'Zebra coloring':
+ 'Seeprav\u00e4ritys',
+ 'check to enable alternating\ncolors for nested blocks':
+ 'asettamalla saat vaihtuvat v\u00e4rit\nsis\u00e4kk\u00e4isille palikoille',
+ 'uncheck to disable alternating\ncolors for nested block':
+ 'poistamalla saat samat v\u00e4rit\nsis\u00e4kk\u00e4isille palikoille',
+ 'Dynamic input labels':
+ 'Vaihtuvat sy\u00f6tetunnukset',
+ 'uncheck to disable dynamic\nlabels for variadic inputs':
+ 'poistamalla est\u00e4t vaihtuvien\nsy\u00f6tteiden vaihtuvat tunnukset',
+ 'check to enable dynamic\nlabels for variadic inputs':
+ 'asettamalla saat vaihtuville\nsy\u00f6tteille vaihtuvat tunnukset',
+ 'Prefer empty slot drops':
+ 'Suosi asettamista tyhjiin aukkoihin',
+ 'settings menu prefer empty slots hint':
+ 'asettamalla saat asetettavat\npalikat osumaan tyhjiin aukkoihin',
+ 'uncheck to allow dropped\nreporters to kick out others':
+ 'poistamalla sallit asetettujen\npalikoiden pois potkimisen',
+ 'Long form input dialog':
+ 'Yksityiskohtainen sy\u00f6tevalinta',
+ 'Plain prototype labels':
+ 'Yksinkertaiset palikkatunnisteet',
+ 'uncheck to always show (+) symbols\nin block prototype labels':
+ 'poistamalla saat (+)-merkit\nn\u00e4kym\u00e4\u00e4n aina\n'
+ + 'palikan muokkauksessa',
+ 'check to hide (+) symbols\nin block prototype labels':
+ 'asettamalla piilotat (+)-merkit\npalikan muokkauksessa',
+ 'check to always show slot\ntypes in the input dialog':
+ 'asettamalla n\u00e4et aina\ntietotyyppivalinnat\n'
+ + 'palikan sy\u00f6tteit\u00e4 lis\u00e4tess\u00e4',
+ 'uncheck to use the input\ndialog in short form':
+ 'poistamalla teet palikan\nsy\u00f6tteiden lis\u00e4\u00e4misikkunasta\n'
+ + 'yksinkertaisen',
+ 'Virtual keyboard':
+ 'Virtuaalin\u00e4pp\u00e4imist\u00f6',
+ 'uncheck to disable\nvirtual keyboard support\nfor mobile devices':
+ 'poistamalla est\u00e4t mobiililaitteiden\n'
+ + 'virtuaalin\u00e4pp\u00e4imist\u00f6n k\u00e4yt\u00f6n',
+ 'check to enable\nvirtual keyboard support\nfor mobile devices':
+ 'asettamalla sallit mobiililaitteiden\n'
+ + 'virtuaalin\u00e4pp\u00e4imist\u00f6n k\u00e4yt\u00f6n',
+ 'Input sliders':
+ 'Liukus\u00e4\u00e4timet',
+ 'uncheck to disable\ninput sliders for\nentry fields':
+ 'poistamalla piilotat\nliukus\u00e4\u00e4timet sy\u00f6tekentist\u00e4\n',
+ 'check to enable\ninput sliders for\nentry fields':
+ 'asettamalla saat\nsy\u00f6tekenttiin liukus\u00e4\u00e4timet',
+ 'Clicking sound':
+ 'Klikkaus\u00e4\u00e4ni',
+ 'uncheck to turn\nblock clicking\nsound off':
+ 'poistamalla hiljenn\u00e4t\npalikoiden klikkaus\u00e4\u00e4nen',
+ 'check to turn\nblock clicking\nsound on':
+ 'asettamalla kytket p\u00e4\u00e4lle\npalikoiden klikkaus\u00e4\u00e4nen',
+ 'Animations':
+ 'Animaatiot',
+ 'uncheck to disable\nIDE animations':
+ 'poistamalla piilotat\nk\u00e4ytt\u00f6liittym\u00e4n animaatiot',
+ 'Turbo mode':
+ 'Turbonopeus',
+ 'check to prioritize\nscript execution':
+ 'asettamalla nostat\nskriptien prioriteettia',
+ 'uncheck to run scripts\nat normal speed':
+ 'poistamalla ajat\nskriptit normaalinopeudella',
+ 'check to enable\nIDE animations':
+ 'asettamalla kytket p\u00e4\u00e4lle\n'
+ + 'k\u00e4ytt\u00f6liittym\u00e4n animaatiot',
+ 'Thread safe scripts':
+ 'S\u00e4ieturvalliset skriptit',
+ 'uncheck to allow\nscript reentrance':
+ 'poistamalla sallit skriptin\nk\u00e4ynnistymisen vaikka se on ajossa',
+ 'check to disallow\nscript reentrance':
+ 'asettamalla est\u00e4t skriptin\nk\u00e4ynnistymisen jos se on jo ajossa',
+ 'Prefer smooth animations':
+ 'Pyri sulaviin animaatioihin',
+ 'uncheck for greater speed\nat variable frame rates':
+ 'poistamalla saat lis\u00e4\u00e4 nopeutta\n'
+ + 'mutta p\u00e4ivitystaajuus vaihtelee',
+ 'check for smooth, predictable\nanimations across computers':
+ 'asettamalla saat sulavat\nanimaatiot eri tietokoneilla',
+ 'Flat line ends':
+ 'Tasaiset viivanp\u00e4\u00e4t',
+ 'check for flat ends of lines':
+ 'asettamalla saat viivan p\u00e4ist\u00e4 suorat',
+ 'uncheck for round ends of lines':
+ 'poistamalla saat viivan p\u00e4ist\u00e4 py\u00f6ristetyt',
+
+ // inputs
+ 'with inputs':
+ 'sy\u00f6tteill\u00e4',
+ 'input names:':
+ 'sy\u00f6tteet:',
+ 'Input Names:':
+ 'Sy\u00f6tteet:',
+ 'input list:':
+ 'sy\u00f6telista:',
+
+ // context menus:
+ 'help':
+ 'apua',
+
+ // palette:
+ 'hide primitives':
+ 'piilota peruspalikat',
+ 'show primitives':
+ 'n\u00e4yt\u00e4 peruspalikat',
+
+ // blocks:
+ 'help...':
+ 'apua...',
+ 'relabel...':
+ 'nime\u00e4 uudestaan...',
+ 'duplicate':
+ 'kopioi',
+ 'make a copy\nand pick it up':
+ 'ota kopio mukaan',
+ 'only duplicate this block':
+ 'kopioi vain t\u00e4m\u00e4 palikka',
+ 'delete':
+ 'poista',
+ 'script pic...':
+ 'kuva skriptist\u00e4...',
+ 'open a new window\nwith a picture of this script':
+ 'avaa kuva t\u00e4st\u00e4 skriptist\u00e4\nuudessa selainikkunassa',
+ 'ringify':
+ 'ympyr\u00f6i',
+ 'unringify':
+ 'poista ympyr\u00f6inti',
+
+ // custom blocks:
+ 'delete block definition...':
+ 'poista palikkam\u00e4\u00e4rittely',
+ 'edit...':
+ 'muokkaa...',
+
+ // sprites:
+ 'edit':
+ 'muokkaa',
+ 'detach from':
+ 'irrota',
+ 'detach all parts':
+ 'irrota kaikki osat',
+ 'export...':
+ 'Vie...',
+
+ // stage:
+ 'show all':
+ 'N\u00e4yt\u00e4 kaikki',
+ 'pic...':
+ 'Vie kuva...',
+ 'open a new window\nwith a picture of the stage':
+ 'Avaa esiintymislavan kuva\nuuteen selainikkunaan',
+
+ // scripting area
+ 'clean up':
+ 'siivoa',
+ 'arrange scripts\nvertically':
+ 'j\u00e4rjest\u00e4 pystysuorasti',
+ 'add comment':
+ 'lis\u00e4\u00e4 kommentti',
+ 'undrop':
+ 'peruuta asetus',
+ 'undo the last\nblock drop\nin this pane':
+ 'peruuta viimeisin\npalikan asetus',
+ 'scripts pic...':
+ 'kuva skripteist\u00e4...',
+ 'open a new window\nwith a picture of all scripts':
+ 'avaa kuva\nkaikista skripteist\u00e4\nuudessa selainikkunassa',
+ 'make a block...':
+ 'tee uusi palikka...',
+
+ // costumes
+ 'rename':
+ 'nime\u00e4 uudestaan',
+ 'export':
+ 'vie',
+ 'rename costume':
+ 'nime\u00e4 asu uudestaan',
+
+ // sounds
+ 'Play sound':
+ 'Soita \u00e4\u00e4ni',
+ 'Stop sound':
+ 'Pys\u00e4yt\u00e4 \u00e4\u00e4ni',
+ 'Stop':
+ 'Pys\u00e4yt\u00e4',
+ 'Play':
+ 'Soita',
+ 'rename sound':
+ 'nime\u00e4 \u00e4\u00e4ni uudestaan',
+
+ // dialogs
+ // buttons
+ 'OK':
+ 'OK',
+ 'Ok':
+ 'OK',
+ 'Cancel':
+ 'Peruuta',
+ 'Yes':
+ 'Kyll\u00e4',
+ 'No':
+ 'Ei',
+
+ // help
+ 'Help':
+ 'Apua',
+
+ // zoom blocks
+ 'Zoom blocks':
+ 'Suurenna palikoita',
+ 'build':
+ 'rakenna',
+ 'your own':
+ 'omia',
+ 'blocks':
+ 'palikoita',
+ 'normal (1x)':
+ 'normaali (1x)',
+ 'demo (1.2x)':
+ 'demo (1.2x)',
+ 'presentation (1.4x)':
+ 'esitys (1.4x)',
+ 'big (2x)':
+ 'iso (2x)',
+ 'huge (4x)':
+ 'valtava (4x)',
+ 'giant (8x)':
+ 'j\u00e4ttim\u00e4inen (8x)',
+ 'monstrous (10x)':
+ 'hirvi\u00f6m\u00e4inen (10x)',
+
+ // Project Manager
+ 'Untitled':
+ 'Nimet\u00f6n',
+ 'Open Project':
+ 'Avaa projekti',
+ '(empty)':
+ '(tyhj\u00e4)',
+ 'Saved!':
+ 'Tallennettu!',
+ 'Delete Project':
+ 'Poista projekti',
+ 'Are you sure you want to delete':
+ 'Poistetaanko varmasti?',
+ 'rename...':
+ 'nime\u00e4 uusiksi...',
+
+ // costume editor
+ 'Costume Editor':
+ 'Asun muokkaus',
+ 'click or drag crosshairs to move the rotation center':
+ 'siirr\u00e4 kiertokeskusta klikkaamalla\n'
+ + 'tai pit\u00e4m\u00e4ll\u00e4 hiirt\u00e4 '
+ + 'painettuna ja liikuttamalla',
+
+ // project notes
+ 'Project Notes':
+ 'Projektin muistiinpanot',
+
+ // new project
+ 'New Project':
+ 'Uusi projekti',
+ 'Replace the current project with a new one?':
+ 'Korvataanko nykyinen projekti uudella?',
+
+ // save project
+ 'Save Project As...':
+ 'Tallenna projekti nimell\u00e4...',
+
+ // export blocks
+ 'Export blocks':
+ 'Vie palikoita',
+ 'Import blocks':
+ 'Tuo palikoita',
+ 'this project doesn\'t have any\ncustom global blocks yet':
+ 'projektilla ei ole viel\u00e4\nyht\u00e4\u00e4n yhteist\u00e4\n'
+ + 'muokattua palikkaa',
+ 'select':
+ 'valitse',
+ 'none':
+ 'ei mit\u00e4\u00e4n',
+
+ // variable dialog
+ 'for all sprites':
+ 'kaikille hahmoille',
+ 'for this sprite only':
+ 'vain t\u00e4lle hahmolle',
+
+ // block dialog
+ 'Change block':
+ 'Muuta palikkaa',
+ 'Command':
+ 'Komento',
+ 'Reporter':
+ 'Funktio',
+ 'Predicate':
+ 'Predikaatti',
+
+ // block editor
+ 'Block Editor':
+ 'Palikan muokkaus',
+ 'Apply':
+ 'Tee muutokset',
+
+ // block deletion dialog
+ 'Delete Custom Block':
+ 'Poista palikka',
+ 'block deletion dialog text':
+ 'Poistetaanko t\u00e4m\u00e4 palikka\n ja kaikki sen esiintym\u00e4t?',
+
+
+ // input dialog
+ 'Create input name':
+ 'Nime\u00e4 sy\u00f6te',
+ 'Edit input name':
+ 'Muokkaa sy\u00f6tteen nime\u00e4',
+ 'Edit label fragment':
+ 'Muokkaa otsikkoa',
+ 'Title text':
+ 'Otsikko',
+ 'Input name':
+ 'Sy\u00f6te',
+ 'Delete':
+ 'Poista',
+ 'Object':
+ 'Objekti',
+ 'Number':
+ 'Luku',
+ 'Text':
+ 'Teksti',
+ 'List':
+ 'Lista',
+ 'Any type':
+ 'Mik\u00e4 vain',
+ 'Boolean (T/F)':
+ 'Totuusarvo',
+ 'Command\n(inline)':
+ 'Komento',
+ 'Command\n(C-shape)':
+ 'Komento\n(C-muoto)',
+ 'Any\n(unevaluated)':
+ 'Mik\u00e4 vain\n(sitaatti)',
+ 'Boolean\n(unevaluated)':
+ 'Totuusarvo\n(sitaatti)',
+ 'Single input.':
+ 'Yksi sy\u00f6te.',
+ 'Default Value:':
+ 'Oletusarvo:',
+ 'Multiple inputs (value is list of inputs)':
+ 'Useita sy\u00f6tteit\u00e4 (listana)',
+ 'Upvar - make internal variable visible to caller':
+ 'Paljasta sis\u00e4inen muuttuja ulkopuolelle',
+
+ // About Snap
+ 'About Snap':
+ 'Tietoa Snapista',
+ 'Back...':
+ 'Takaisin...',
+ 'License...':
+ 'Tekij\u00e4noikeudet...',
+ 'Modules...':
+ 'Osat...',
+ 'Credits...':
+ 'Kiitokset...',
+ 'Translators...':
+ 'K\u00e4\u00e4nt\u00e4j\u00e4t...',
+ 'License':
+ 'Tekij\u00e4noikeudet',
+ 'current module versions:':
+ 'Osien versiot:',
+ 'Contributors':
+ 'Osallistujat',
+ 'Translations':
+ 'K\u00e4\u00e4nn\u00f6kset',
+
+ // variable watchers
+ 'normal':
+ 'tavallinen',
+ 'large':
+ 'suuri',
+ 'slider':
+ 'liukus\u00e4\u00e4din',
+ 'slider min...':
+ 'minimiarvo...',
+ 'slider max...':
+ 'maksimiarvo...',
+ 'import...':
+ 'tuo...',
+ 'Slider minimum value':
+ 'Liukus\u00e4\u00e4timen minimiarvo',
+ 'Slider maximum value':
+ 'Liukus\u00e4\u00e4timen maksimiarvo',
+
+ // list watchers
+ 'length: ':
+ 'pituus: ',
+
+ // coments
+ 'add comment here...':
+ 'Kirjoita kommentti t\u00e4h\u00e4n...',
+
+ // drow downs
+ // directions
+ '(90) right':
+ '(90) oikealle',
+ '(-90) left':
+ '(-90) vasemmalle',
+ '(0) up':
+ '(0) yl\u00f6s',
+ '(180) down':
+ '(180) alas',
+
+ // collision detection
+ 'mouse-pointer':
+ 'hiiren osoitin',
+ 'edge':
+ 'reuna',
+ 'pen trails':
+ 'kyn\u00e4n j\u00e4lki',
+
+ // costumes
+ 'Turtle':
+ 'Osoitin',
+ 'Empty':
+ 'Tyhj\u00e4',
+
+ // graphical effects
+ 'ghost':
+ 'l\u00e4pin\u00e4kyvyys',
+
+ // keys
+ 'space':
+ 'v\u00e4lily\u00f6nti',
+ 'up arrow':
+ 'nuoli yl\u00f6s',
+ 'down arrow':
+ 'nuoli alas',
+ 'right arrow':
+ 'nuoli oikealle',
+ 'left arrow':
+ 'nuoli vasemmalle',
+ 'a':
+ 'a',
+ 'b':
+ 'b',
+ 'c':
+ 'c',
+ 'd':
+ 'd',
+ 'e':
+ 'e',
+ 'f':
+ 'f',
+ 'g':
+ 'g',
+ 'h':
+ 'h',
+ 'i':
+ 'i',
+ 'j':
+ 'j',
+ 'k':
+ 'k',
+ 'l':
+ 'l',
+ 'm':
+ 'm',
+ 'n':
+ 'n',
+ 'o':
+ 'o',
+ 'p':
+ 'p',
+ 'q':
+ 'q',
+ 'r':
+ 'r',
+ 's':
+ 's',
+ 't':
+ 't',
+ 'u':
+ 'u',
+ 'v':
+ 'v',
+ 'w':
+ 'w',
+ 'x':
+ 'x',
+ 'y':
+ 'y',
+ 'z':
+ 'z',
+ '0':
+ '0',
+ '1':
+ '1',
+ '2':
+ '2',
+ '3':
+ '3',
+ '4':
+ '4',
+ '5':
+ '5',
+ '6':
+ '6',
+ '7':
+ '7',
+ '8':
+ '8',
+ '9':
+ '9',
+
+ // messages
+ 'new...':
+ 'uusi...',
+
+ // math functions
+ 'abs':
+ 'itseisarvo',
+ 'floor':
+ 'py\u00f6ristys alas',
+ 'sqrt':
+ 'neli\u00f6juuri',
+ 'sin':
+ 'sin',
+ 'cos':
+ 'cos',
+ 'tan':
+ 'tan',
+ 'asin':
+ 'asin',
+ 'acos':
+ 'acos',
+ 'atan':
+ 'atan',
+ 'ln':
+ 'ln',
+ 'e^':
+ 'e^',
+
+ // delimiters
+ 'whitespace':
+ 'tyhjien v\u00e4lien',
+ 'line':
+ 'rivinvaihtojen (lf)',
+ 'tab':
+ 'sarkaimien (tab)',
+ 'cr':
+ 'vaununpalautusten (cr)',
+
+ // data types
+ 'number':
+ 'luku',
+ 'text':
+ 'teksti',
+ 'Boolean':
+ 'totuusarvo',
+ 'list':
+ 'lista',
+ 'command':
+ 'komentopalikka',
+ 'reporter':
+ 'funktiopalikka',
+ 'predicate':
+ 'predikaatti',
+
+ // list indices
+ 'last':
+ 'viimeinen',
+ 'any':
+ 'mik\u00e4 tahansa'
+};
diff --git a/lang-pt.js b/lang-pt.js
index 36ae99d..d28c290 100755
--- a/lang-pt.js
+++ b/lang-pt.js
@@ -185,7 +185,7 @@ SnapTranslator.dict.pt = {
'translator_e-mail':
'mmsequeira@gmail.com',
'last_changed':
- '2014-01-12',
+ '2014-05-26',
// GUI
// control bar:
@@ -685,6 +685,16 @@ SnapTranslator.dict.pt = {
'Língua…',
'Zoom blocks...':
'Ampliação dos blocos…',
+ 'Stage size...':
+ 'Tamanho do palco…',
+ 'Stage size':
+ 'Tamanho do palco',
+ 'Stage width':
+ 'Largura do palco',
+ 'Stage height':
+ 'Altura do palco',
+ 'Default':
+ 'Normal',
'Blurred shadows':
'Sombras desfocadas',
'uncheck to use solid drop\nshadows and highlights':
@@ -767,6 +777,12 @@ SnapTranslator.dict.pt = {
'Desassinalar para aumentar a velocidade\npermitindo ritmos variáveis das tramas.',
'check for smooth, predictable\nanimations across computers':
'Assinalar para obter animações mais suaves\ne previsíveis de computador para computador.',
+ 'Flat line ends':
+ 'Extremos das linhas planos',
+ 'check for flat ends of lines':
+ 'Assinalar para que os extremos das linhas\ndesenhadas pela caneta sejam planos.',
+ 'uncheck for round ends of lines':
+ 'Desassinalar para que os extremos das linhas\ndesenhadas pela caneta sejam redondos.',
// entradas
'with inputs':
@@ -1093,21 +1109,29 @@ SnapTranslator.dict.pt = {
// detecção de colisões
'mouse-pointer':
- 'ponteiro do rato',
+ 'o ponteiro do rato',
'edge':
- 'borda',
+ 'a borda',
'pen trails':
'traços da caneta',
// trajes
'Turtle':
- 'seta',
+ 'tartaruga',
'Empty':
'vazio',
// efeitos gráficos
+ 'brightness':
+ 'brilho',
'ghost':
'fantasma',
+ 'negative':
+ 'negativo',
+ 'comic':
+ 'ondeado',
+ 'confetti':
+ 'cor',
// teclas
'space':
@@ -1225,7 +1249,7 @@ SnapTranslator.dict.pt = {
'whitespace':
'espaços em branco',
'line':
- 'avanços de linha',
+ 'linha',
'tab':
'tabuladores',
'cr':
@@ -1254,20 +1278,74 @@ SnapTranslator.dict.pt = {
'um item ao acaso',
// em falta no ficheiro lang-de.js
+ 'grow':
+ 'aumentar',
+ 'shrink':
+ 'reduzir',
+ 'flip ↔':
+ 'inverter ↔',
+ 'flip ↕':
+ 'inverter ↕',
+ 'Export all scripts as pic...':
+ 'Exportar todos os guiões como fotografia…',
+ 'show a picture of all scripts\nand block definitions':
+ 'Mostra uma imagem com todos\nos guiões e definições de blocos',
+ 'current %dates':
+ '%dates corrente',
+ 'year':
+ 'ano',
+ 'month':
+ 'mês',
+ 'date':
+ 'dia',
+ 'day of week':
+ 'dia da semana',
+ 'hour':
+ 'hora',
+ 'minute':
+ 'minuto',
+ 'second':
+ 'segundo',
+ 'time in milliseconds':
+ 'tempo (em milisegundos)',
+ 'find blocks...':
+ 'procurar blocos…',
'costume name':
'o nome do traje',
'Open':
'Abrir',
'Share':
'Partilhar',
+ 'Snap!Cloud':
+ 'Snap!Nuvem',
'Cloud':
'Nuvem',
+ 'could not connect to:':
+ 'Não foi possível ligar a:',
+ 'Service:':
+ 'Serviço:',
+ 'login':
+ 'autenticação',
+ 'ERROR: INVALID PASSWORD':
+ 'ERRO: PALAVRA-PASSE INVÁLIDA',
'Browser':
'Navegador',
'Sign up':
'Registar nova conta',
+ 'Signup':
+ 'Registo de nova conta',
'Sign in':
'Entrar',
+ 'Logout':
+ 'Sair',
+ 'Change Password...':
+ 'Alterar palavra-passe…',
+ 'Change Password':
+ 'Alterar palavra-passe',
+ 'Account created.':
+ 'Conta criada.',
+ 'An e-mail with your password\nhas been sent to the address provided':
+ 'Foi enviada uma mensagem para\no endereço disponibilizado\ncontendo a sua palavra-passe.',
'now connected.':
'entrou.',
'disconnected.':
@@ -1280,6 +1358,12 @@ SnapTranslator.dict.pt = {
'Nome de utilizador:',
'Password:':
'Palavra-passe:',
+ 'Old password:':
+ 'Palavra-passe actual:',
+ 'New password:':
+ 'Nova palavra-passe:',
+ 'Repeat new password:':
+ 'Repita a nova palavra-passe:',
'Birth date:':
'Data de nascimento:',
'January':
@@ -1385,5 +1469,117 @@ SnapTranslator.dict.pt = {
'comment pic...':
'fotografia do comentário…',
'open a new window\nwith a picture of this comment':
- 'Abrir uma nova janela com\numa fotografia deste comentário.'
+ 'Abrir uma nova janela com\numa fotografia deste comentário.',
+ 'undo':
+ 'desfazer',
+ 'Brush size':
+ 'Espessura do pincel',
+ 'Constrain proportions of shapes?\n(you can also hold shift)':
+ 'Preservar proporções das formas?\n(também pode pressionar shift)',
+ 'Eraser tool':
+ 'Borracha',
+ 'Paintbrush tool\n(free draw)':
+ 'Pincel\n(desenho livre)',
+ 'Line tool\n(shift: vertical/horizontal)':
+ 'Segmento de recta\n(shift: vertical/horizontal)',
+ 'Stroked Rectangle\n(shift: square)':
+ 'Rectângulo\n(shift: quadrado)',
+ 'Filled Rectangle\n(shift: square)':
+ 'Rectângulo preenchido\n(shift: quadrado)',
+ 'Stroked Ellipse\n(shift: circle)':
+ 'Elipse\n(shift: circunferência)',
+ 'Filled Ellipse\n(shift: circle)':
+ 'Elipse preenchida\n(shift: círculo)',
+ 'Fill a region':
+ 'Balde de tinta',
+ 'Set the rotation center':
+ 'Estabelecer centro de rotação',
+ 'Pipette tool\n(pick a color anywhere)':
+ 'Pipeta\n(recolher uma cor em qualquer lado)',
+ 'Paint Editor':
+ 'Editor de Pintura',
+ 'square':
+ 'quadrado',
+ 'pointRight':
+ 'triângulo para a direita',
+ 'gears':
+ 'roda dentada',
+ 'file':
+ 'arquivo',
+ 'fullScreen':
+ 'ecrã inteiro',
+ 'normalScreen':
+ 'ecrã normal',
+ 'smallStage':
+ 'palco pequeno',
+ 'normalStage':
+ 'palco normal',
+ 'turtle':
+ 'tartaruga',
+ 'stage':
+ 'palco',
+ 'turtleOutline':
+ 'contorno de tartaruga',
+ 'pause':
+ 'pausa',
+ 'flag':
+ 'bandeira',
+ 'octagon':
+ 'octógono',
+ 'cloud':
+ 'nuvem',
+ 'cloudOutline':
+ 'contorno de nuvem',
+ 'cloudGradient':
+ 'nuvem com gradiente',
+ 'turnRight':
+ 'girar à direita',
+ 'turnLeft':
+ 'girar à esquerda',
+ 'storage':
+ 'armazenagem',
+ 'poster':
+ 'póster',
+ 'flash':
+ 'relâmpago',
+ 'brush':
+ 'pincel',
+ 'rectangle':
+ 'rectângulo',
+ 'rectangleSolid':
+ 'rectângulo preenchido',
+ 'circle':
+ 'circunferência',
+ 'circleSolid':
+ 'círculo',
+ 'crosshairs':
+ 'mira',
+ 'paintbucket':
+ 'balde de tinta',
+ 'eraser':
+ 'borracha',
+ 'pipette':
+ 'pipeta',
+ 'speechBubble':
+ 'balão de fala',
+ 'speechBubbleOutline':
+ 'contorno de balão de fala',
+ 'arrowUp':
+ 'seta para cima',
+ 'arrowUpOutline':
+ 'contorno de seta para cima',
+ 'arrowLeft':
+ 'seta para a esquerda',
+ 'arrowLeftOutline':
+ 'contorno de seta para a esquerda',
+ 'arrowDown':
+ 'seta para baixo',
+ 'arrowDownOutline':
+ 'contorno de seta para baixo',
+ 'arrowRight':
+ 'seta para a direita',
+ 'arrowRightOutline':
+ 'contorno de seta para a direita',
+ 'robot':
+ 'robot'
};
diff --git a/lang-pt_BR.js b/lang-pt_BR.js
new file mode 100755
index 0000000..f277c45
--- /dev/null
+++ b/lang-pt_BR.js
@@ -0,0 +1,1389 @@
+/*
+
+ lang-pt_BR.js
+
+ Brazilian Portuguese translation for SNAP!
+
+ translated by Aldo von Wangenheim
+
+ Copyright (C) 2014 by Aldo von Wangenheim
+
+ This file is part of Snap!.
+
+ Snap! is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+
+ Note to Translators:
+ --------------------
+ At this stage of development, Snap! can be translated to any LTR language
+ maintaining the current order of inputs (formal parameters in blocks).
+
+ Translating Snap! is easy:
+
+
+ 1. Download
+
+ Download the sources and extract them into a local folder on your
+ computer:
+
+ <http://snap.berkeley.edu/snapsource/snap.zip>
+
+ Use the German translation file (named 'lang-de.js') as template for your
+ own translations. Start with editing the original file, because that way
+ you will be able to immediately check the results in your browsers while
+ you're working on your translation (keep the local copy of snap.html open
+ in your web browser, and refresh it as you progress with your
+ translation).
+
+
+ 2. Edit
+
+ Edit the translation file with a regular text editor, or with your
+ favorite JavaScript editor.
+
+ In the first non-commented line (the one right below this
+ note) replace "de" with the two-letter ISO 639-1 code for your language,
+ e.g.
+
+ fr - French => SnapTranslator.dict.fr = {
+ it - Italian => SnapTranslator.dict.it = {
+ pl - Polish => SnapTranslator.dict.pl = {
+ pt - Portuguese => SnapTranslator.dict.pt = {
+ es - Spanish => SnapTranslator.dict.es = {
+ el - Greek => => SnapTranslator.dict.el = {
+
+ etc. (see <http://en.wikipedia.org/wiki/ISO_639-1>)
+
+
+ 3. Translate
+
+ Then work through the dictionary, replacing the German strings against
+ your translations. The dictionary is a straight-forward JavaScript ad-hoc
+ object, for review purposes it should be formatted as follows:
+
+ {
+ 'English string':
+ 'Translation string',
+ 'last key':
+ } 'last value'
+
+ and you only edit the indented value strings. Note that each key-value
+ pair needs to be delimited by a comma, but that there shouldn't be a comma
+ after the last pair (again, just overwrite the template file and you'll be
+ fine).
+
+ If something doesn't work, or if you're unsure about the formalities you
+ should check your file with
+
+ <http://JSLint.com>
+
+ This will inform you about any missed commas etc.
+
+
+ 4. Accented characters
+
+ Depending on which text editor and which file encoding you use you can
+ directly enter special characters (e.g. Umlaut, accented characters) on
+ your keyboard. However, I've noticed that some browsers may not display
+ special characters correctly, even if other browsers do. So it's best to
+ check your results in several browsers. If you want to be on the safe
+ side, it's even better to escape these characters using Unicode.
+
+ see: <http://0xcc.net/jsescape/>
+
+
+ 5. Block specs:
+
+ At this time your translation of block specs will only work
+ correctly, if the order of formal parameters and their types
+ are unchanged. Placeholders for inputs (formal parameters) are
+ indicated by a preceding % prefix and followed by a type
+ abbreviation.
+
+ For example:
+
+ 'say %s for %n secs'
+
+ can currently not be changed into
+
+ 'say %n secs long %s'
+
+ and still work as intended.
+
+ Similarly
+
+ 'point towards %dst'
+
+ cannot be changed into
+
+ 'point towards %cst'
+
+ without breaking its functionality.
+
+
+ 6. Submit
+
+ When you're done, rename the edited file by replacing the "de" part of the
+ filename with the two-letter ISO 639-1 code for your language, e.g.
+
+ fr - French => lang-fr.js
+ it - Italian => lang-it.js
+ pl - Polish => lang-pl.js
+ pt - Portuguese => lang-pt.js
+ es - Spanish => lang-es.js
+ el - Greek => => lang-el.js
+
+ and send it to me for inclusion in the official Snap! distribution.
+ Once your translation has been included, Your name will the shown in the
+ "Translators" tab in the "About Snap!" dialog box, and you will be able to
+ directly launch a translated version of Snap! in your browser by appending
+
+ lang:xx
+
+ to the URL, xx representing your translations two-letter code.
+
+
+ 7. Known issues
+
+ In some browsers accents or ornaments located in typographic ascenders
+ above the cap height are currently (partially) cut-off.
+
+ Enjoy!
+ -Jens
+*/
+
+/*global SnapTranslator*/
+
+SnapTranslator.dict.pt_BR = {
+
+/*
+ Special characters: (see <http://0xcc.net/jsescape/>)
+
+ Ä, ä \u00c4, \u00e4
+ Ö, ö \u00d6, \u00f6
+ Ü, ü \u00dc, \u00fc
+ ß \u00df
+*/
+
+ // meta informação sobre a tradução
+ 'language_name':
+ 'Português do Brasil',
+ 'language_translator':
+ 'Aldo von Wangenheim',
+ 'translator_e-mail':
+ 'awangenh@inf.ufsc.br',
+ 'last_changed':
+ '2014-04-20',
+
+ // GUI
+ // control bar:
+ 'untitled':
+ 'Sem título',
+ 'development mode':
+ 'modo de desenvolvimento',
+
+ // categorias:
+ 'Motion':
+ 'Movimento',
+ 'Looks':
+ 'Aparência',
+ 'Sound':
+ 'Som',
+ 'Pen':
+ 'Caneta',
+ 'Control':
+ 'Controle',
+ 'Sensing':
+ 'Sensores',
+ 'Operators':
+ 'Operadores',
+ 'Variables':
+ 'Variáveis',
+ 'Lists':
+ 'Listas',
+ 'Other':
+ 'Outros',
+
+ // editor:
+ 'draggable':
+ 'arrastável',
+
+ // separadores:
+ 'Scripts':
+ 'Roteiros',
+ 'Costumes':
+ 'Fantasias',
+ 'Sounds':
+ 'Sons',
+
+ // nomes:
+ 'Sprite':
+ 'Ator',
+ 'Stage':
+ 'Palco',
+
+ // estilos de rotação:
+ 'don\'t rotate':
+ 'não rode',
+ 'can rotate':
+ 'rode',
+ 'only face left/right':
+ 'olhe apenas para a esquerda ou para a direita',
+
+ // botão de criação de novo actor:
+ 'add a new sprite':
+ 'adicionar um novo ator',
+
+ // ajuda nos tabuladores
+ 'costumes tab help':
+ 'Importa uma imagem de uma página Web ou de um\n'
+ + 'arquivo no teu computador arrastando-a para aqui',
+ 'import a sound from your computer\nby dragging it into here':
+ 'Importe um som de seu computador\narrastando-o para cá',
+
+ // blocos primitivos:
+
+ /*
+ Attention Translators:
+ ----------------------
+ At this time your translation of block specs will only work
+ correctly, if the order of formal parameters and their types
+ are unchanged. Placeholders for inputs (formal parameters) are
+ indicated by a preceding % prefix and followed by a type
+ abbreviation.
+
+ For example:
+
+ 'say %s for %n secs'
+
+ can currently not be changed into
+
+ 'say %n secs long %s'
+
+ and still work as intended.
+
+ Similarly
+
+ 'point towards %dst'
+
+ cannot be changed into
+
+ 'point towards %cst'
+
+ without breaking its functionality.
+ */
+
+ // Movimento:
+ 'Stage selected:\nno motion primitives':
+ 'Palco selecionado:\nsem primitivas de movimento',
+
+
+ 'move %n steps':
+ 'mova %n passos',
+ 'turn %clockwise %n degrees':
+ 'gire %clockwise %n graus',
+ 'turn %counterclockwise %n degrees':
+ 'gire %counterclockwise %n graus',
+ 'point in direction %dir':
+ 'aponte para a direção %dir graus',
+ 'point towards %dst':
+ 'aponte para %dst',
+ 'go to x: %n y: %n':
+ 'vá para x: %n , y: %n ',
+ 'go to %dst':
+ 'vá para %dst',
+ 'glide %n secs to x: %n y: %n':
+ 'deslize por %n segundos ate x: %n , y: %n ',
+ 'change x by %n':
+ 'adicione %n a x',
+ 'set x to %n':
+ 'mude x para %n',
+ 'change y by %n':
+ 'adicione %n a y',
+ 'set y to %n':
+ 'mude y para %n',
+ 'if on edge, bounce':
+ 'se tocar na borda, volte',
+ 'x position':
+ 'coordenada x da posição',
+ 'y position':
+ 'coordenada y da posição',
+ 'direction':
+ 'direção',
+
+ // Aparência:
+ 'switch to costume %cst':
+ 'mude para a fantasia %cst',
+ 'next costume':
+ 'próxima fantasia',
+ 'costume #':
+ 'n° da fantasia',
+ 'say %s for %n secs':
+ 'diga %s por %n segundos',
+ 'say %s':
+ 'diga %s',
+ 'think %s for %n secs':
+ 'pense %s por %n segundos',
+ 'think %s':
+ 'pense %s',
+ 'Hello!':
+ 'Olá!',
+ 'Hmm...':
+ 'Hmm…',
+ 'change %eff effect by %n':
+ 'adicione ao efeito %eff %n',
+ 'set %eff effect to %n':
+ 'mude o efeito %eff para %n',
+ 'clear graphic effects':
+ 'apague os efeitos gráficos',
+ 'change size by %n':
+ 'adicione %n ao seu tamanho',
+ 'set size to %n %':
+ 'mude o tamanho para %n %',
+ 'size':
+ 'tamanho',
+ 'show':
+ 'mostrar',
+ 'hide':
+ 'esconder',
+ 'go to front':
+ 'vá para a frente',
+ 'go back %n layers':
+ 'vá %n camadas para trás',
+
+ 'development mode \ndebugging primitives:':
+ 'primitivas de depuração \ndo modo de desenvolvimento:',
+ 'console log %mult%s':
+ 'registre %mult%s no console',
+ 'alert %mult%s':
+ 'mostre janela de alerta com %mult%s',
+
+ // Som:
+ 'play sound %snd':
+ 'toque o som %snd',
+ 'play sound %snd until done':
+ 'toque o som %snd até o fim',
+ 'stop all sounds':
+ 'pare todos os sons',
+ 'rest for %n beats':
+ 'silêncio por %n tempos',
+ 'play note %n for %n beats':
+ 'toque a nota %n durante %n tempos',
+ 'change tempo by %n':
+ 'adicione %n tempos ao andamento',
+ 'set tempo to %n bpm':
+ 'altere o andamento para %n tempos',
+ 'tempo':
+ 'andamento',
+
+ // Caneta:
+ 'clear':
+ 'apague tudo',
+ 'pen down':
+ 'use a caneta',
+ 'pen up':
+ 'levante a caneta',
+ 'set pen color to %clr':
+ 'mude a cor da caneta para %clr',
+ 'change pen color by %n':
+ 'adicione %n à cor da caneta',
+ 'set pen color to %n':
+ 'mude a cor da caneta para %n',
+ 'change pen shade by %n':
+ 'adicione %n à intensidade da caneta',
+ 'set pen shade to %n':
+ 'mude a intensidade da caneta para %n',
+ 'change pen size by %n':
+ 'adicione %n à espessura da caneta',
+ 'set pen size to %n':
+ 'mude a espessura da caneta para %n',
+ 'stamp':
+ 'carimbe',
+
+ // Eventos e Controle:
+ 'when %greenflag clicked':
+ 'quando clicar em %greenflag',
+ 'when %keyHat key pressed':
+ 'quando a tecla %keyHat for pressionada',
+ 'when I am clicked':
+ 'quando este ator for clicado',
+ 'when I receive %msgHat':
+ 'quando receber %msgHat',
+ 'broadcast %msg':
+ 'envie %msg a todos',
+ 'broadcast %msg and wait':
+ 'envie %msg a todos e espere',
+ 'Message name':
+ 'nome da mensagem',
+ 'message':
+ 'mensagem',
+ 'any message':
+ 'qualquer mensagem',
+ 'wait %n secs':
+ 'espere %n segundos',
+ 'wait until %b':
+ 'espere até que %b',
+ 'forever %c':
+ 'sempre %c',
+ 'repeat %n %c':
+ 'repita %n vezes %c',
+ 'repeat until %b %c':
+ 'repita até que %b %c',
+ 'if %b %c':
+ 'se %b então %c',
+ 'if %b %c else %c':
+ 'se %b então %c senão %c',
+ 'report %s':
+ 'reporte %s',
+ 'stop %stopChoices':
+ 'pare %stopChoices',
+ 'all':
+ 'tudo',
+ 'this script':
+ 'este roteiro',
+ 'this block':
+ 'este bloco',
+ 'stop %stopOthersChoices':
+ 'pare %stopOthersChoices',
+ 'all but this script':
+ 'todos os roteiros exceto este',
+ 'other scripts in sprite':
+ 'outros roteiros deste ator',
+ 'pause all %pause':
+ 'pause tudo %pause',
+ 'run %cmdRing %inputs':
+ 'execute %cmdRing %inputs',
+ 'launch %cmdRing %inputs':
+ 'inicie execução de %cmdRing %inputs',
+ 'call %repRing %inputs':
+ 'chame %repRing %inputs',
+ 'run %cmdRing w/continuation':
+ 'execute %cmdRing com continuação',
+ 'call %cmdRing w/continuation':
+ 'chame %cmdRing com continuação',
+ 'warp %c':
+ 'execute atomicamente %c',
+ 'when I start as a clone':
+ 'quando este ator começar como clone',
+ 'create a clone of %cln':
+ 'crie clone de %cln',
+ 'myself':
+ 'este ator',
+ 'delete this clone':
+ 'apague este clone',
+
+ // Sensores:
+ 'touching %col ?':
+ 'tocando em %col',
+ 'touching %clr ?':
+ 'tocando na cor %clr',
+ 'color %clr is touching %clr ?':
+ 'a cor %clr está tocando na cor %clr',
+ 'ask %s and wait':
+ 'pergunte %s e espere a resposta',
+ 'what\'s your name?':
+ 'qual o seu nome?',
+ 'answer':
+ 'resposta',
+ 'mouse x':
+ 'posição x do mouse',
+ 'mouse y':
+ 'posição y do mouse',
+ 'mouse down?':
+ 'mouse pressionado?',
+ 'key %key pressed?':
+ 'tecla %key pressionada?',
+ 'distance to %dst':
+ 'distância até %dst',
+ 'reset timer':
+ 'zere o cronómetro',
+ 'timer':
+ 'valor do cronómetro',
+ '%att of %spr':
+ '%att de %spr',
+ 'http:// %s':
+ 'página http:// %s',
+ 'turbo mode?':
+ 'modo turbo?',
+ 'set turbo mode to %b':
+ 'mude o modo turbo para %b',
+
+ 'filtered for %clr':
+ 'filtrado por %clr',
+ 'stack size':
+ 'altura da pilha',
+ 'frames':
+ 'quadros',
+
+ // Operadores:
+ '%n mod %n':
+ 'resto de %n por %n',
+ 'round %n':
+ 'arredondamento de %n',
+ '%fun of %n':
+ '%fun de %n',
+ 'pick random %n to %n':
+ 'escolha um valor ao acaso entre %n e %n',
+ '%b and %b':
+ '%b e %b',
+ '%b or %b':
+ '%b ou %b',
+ 'not %b':
+ 'não %b',
+ 'true':
+ 'verdadeiro',
+ 'false':
+ 'falso',
+ 'join %words':
+ 'junte %words',
+ 'split %s by %delim':
+ 'separe %s por %delim',
+ 'hello':
+ 'Olá',
+ 'world':
+ 'mundo',
+ 'letter %n of %s':
+ 'o caractere %n de %s',
+ 'length of %s':
+ 'o comprimento de %s',
+ 'unicode of %s':
+ 'o código Unicode do caractere %s',
+ 'unicode %n as letter':
+ 'o caractere cujo código Unicode é %n',
+ 'is %s a %typ ?':
+ '%s é um/uma %typ',
+ 'is %s identical to %s ?':
+ '%s é idêntico a %s',
+
+ 'type of %s':
+ 'o tipo de %s',
+
+ // Variáveis:
+ 'Make a variable':
+ 'Criar uma variável',
+ 'Variable name':
+ 'Nome da variável',
+ 'Script variable name':
+ 'Nome da variável de Roteiro',
+ 'Delete a variable':
+ 'Remova uma variável',
+
+ 'set %var to %s':
+ 'mude %var para %s',
+ 'change %var by %n':
+ 'adicione a %var o valor %n',
+ 'show variable %var':
+ 'mostre variável %var',
+ 'hide variable %var':
+ 'esconda variável %var',
+ 'script variables %scriptVars':
+ 'crie as variáveis de roteiro %scriptVars',
+
+ // listas:
+ 'list %exp':
+ 'uma lista com %exp',
+ '%s in front of %l':
+ '%s inicia %l',
+ 'item %idx of %l':
+ '%idx de %l',
+ 'all but first of %l':
+ 'todos elementos de %l menos o primeiro',
+ 'length of %l':
+ 'tamanho de %l',
+ '%l contains %s':
+ '%l contém %s',
+ 'thing':
+ 'valor',
+ 'add %s to %l':
+ 'adicione %s a %l',
+ 'delete %ida of %l':
+ 'apague %ida de %l',
+ 'insert %s at %idx of %l':
+ 'insira %s na posição %idx em %l',
+ 'replace item %idx of %l with %s':
+ 'substitua o item %idx de %l por %s',
+
+ // Outros
+ 'Make a block':
+ 'Criar um bloco',
+
+ // Menus
+ // Snap menu
+ 'About...':
+ 'Sobre Snap!…',
+ 'Reference manual':
+ 'Manual de Referência',
+ 'Snap! website':
+ 'Site do Snap!',
+ 'Download source':
+ 'Baixar código fonte',
+ 'Switch back to user mode':
+ 'Volte ao modo de usuário',
+ 'disable deep-Morphic\ncontext menus\nand show user-friendly ones':
+ 'Desative menus de contexto\nprofundos do Morphic e\nmostrar menus amigáveis.',
+ 'Switch to dev mode':
+ 'Mude para modo de desenvolvimento',
+ 'enable Morphic\ncontext menus\nand inspectors,\nnot user-friendly!':
+ 'Ativar menus de contexto\ne inspectores não\namigáveis do Morphic!',
+
+ // Menu de projeto
+ 'Project notes...':
+ 'Notas deste projeto…',
+ 'New':
+ 'Criar um novo projeto',
+ 'Open...':
+ 'Abrir um projeto…',
+ 'Save':
+ 'Salvar',
+ 'Save As...':
+ 'Salvar como…',
+ 'Import...':
+ 'Importar…',
+ 'file menu import hint':
+ 'Importar para este projecto\num projeto exportado,\n'
+ + 'uma biblioteca de blocos,\n'
+ + 'um traje ou um som.',
+ 'Export project as plain text...':
+ 'Exportar este projeto em modo texto…',
+ 'Export project...':
+ 'Exportar este projeto…',
+ 'show project data as XML\nin a new browser window':
+ 'Mostrar os dados no\nformato XML numa nova janela do navegador.',
+ 'Export blocks...':
+ 'Exportar blocos…',
+ 'show global custom block definitions as XML\nin a new browser window':
+ 'Mostrar as definições globais de blocos\npersonalizados no formato\nXML numa nova janela do navegador.',
+ 'Import tools':
+ 'Importar ferramentas oficiais',
+ 'load the official library of\npowerful blocks':
+ 'Importar a biblioteca\n oficial de blocos.',
+ 'Libraries...':
+ 'Bibliotecas...',
+ 'Import library':
+ 'Importar biblioteca',
+
+ // Menu da nuvem
+ 'Login...':
+ 'Entrar na sua conta…',
+ 'Signup...':
+ 'Registar uma nova conta…',
+
+ // menu de preferências
+ 'Language...':
+ 'Língua…',
+ 'Zoom blocks...':
+ 'Zoom dos blocos…',
+ 'Blurred shadows':
+ 'Sombras borradas',
+ 'uncheck to use solid drop\nshadows and highlights':
+ 'Desmarque para usar sombras\ne realces nítidos.',
+ 'check to use blurred drop\nshadows and highlights':
+ 'Marque para usar sombras\ne realces borrados.',
+ 'Zebra coloring':
+ 'Coloração em zebra',
+ 'check to enable alternating\ncolors for nested blocks':
+ 'Marque para alternar\nas cores de blocos aninhados.',
+ 'uncheck to disable alternating\ncolors for nested block':
+ 'Desmarque para deixar de alternar\nas cores de blocos aninhados.',
+ 'Dynamic input labels':
+ 'Nomes de entrada dinâmicos',
+ 'uncheck to disable dynamic\nlabels for variadic inputs':
+ 'Desmarque para desativar nomes\ndinâmicos nas variáveis de entrada.',
+ 'check to enable dynamic\nlabels for variadic inputs':
+ 'Marque para ativar nomes\ndinâmicos nas variáveis de entrada.',
+ 'Prefer empty slot drops':
+ 'Procure encaixar blocos de valor (repórteres) em campos vazios ao soltar',
+ 'settings menu prefer empty slots hint':
+ 'Marque para focar em campos vazios\nquando estiver arrastando e '
+ + 'soltando blocos de valor (repórteres).',
+ 'uncheck to allow dropped\nreporters to kick out others':
+ 'Desmarque para permitir que blocos\nrepórteres soltos em um campo '
+ + 'desalojem outros.',
+ 'Long form input dialog':
+ 'Forma longa da caixa de diálogo dos parâmetros',
+ 'Plain prototype labels':
+ 'Use texto simples para protótipos',
+ 'uncheck to always show (+) symbols\nin block prototype labels':
+ 'Desmarque para mostrar sempre os símbolos (+)\nno texto dos protótipos dos blocos',
+ 'check to hide (+) symbols\nin block prototype labels':
+ 'Marque para esconder os símbolos (+)\nno texto dos protótipos dos blocos',
+ 'check to always show slot\ntypes in the input dialog':
+ 'Marque para sempre mostrar\no tipo dos campos na caixa\nde diálogo dos parâmetros.',
+ 'uncheck to use the input\ndialog in short form':
+ 'Desmarque para usar texto abreviado\nda caixa de diálogo dos parâmetros.',
+ 'Virtual keyboard':
+ 'Teclado virtual',
+ 'uncheck to disable\nvirtual keyboard support\nfor mobile devices':
+ 'Desmarque para desativar o\nsuporte ao teclado virtual\npara dispositivos '
+ + 'móveis.',
+ 'check to enable\nvirtual keyboard support\nfor mobile devices':
+ 'Marque para ativar o\nsuporte ao teclado virtual\npara dispositivos '
+ + 'móveis.',
+ 'Input sliders':
+ 'Sliders nos campos de entrada',
+ 'uncheck to disable\ninput sliders for\nentry fields':
+ 'Desmarque para desativar\nsliders nos campos de entrada dos blocos.',
+ 'check to enable\ninput sliders for\nentry fields':
+ 'Marque para ativar\nsliders nos campos de entrada dos blocos.',
+ 'Clicking sound':
+ 'Som de cliques',
+ 'uncheck to turn\nblock clicking\nsound off':
+ 'Desmarque para desativar o som\nproduzido ao clicar nos blocos.',
+ 'check to turn\nblock clicking\nsound on':
+ 'Marque para ativar o som\nproduzido ao clicar nos blocos.',
+ 'Animations':
+ 'Animações',
+ 'uncheck to disable\nIDE animations':
+ 'Desmarque para desativar\nas animações da interface de usuário.',
+ 'Turbo mode.':
+ 'Modo turbo',
+ 'check to prioritize\nscript execution':
+ 'Marque para priorizar\na execução de roteiros.',
+ 'uncheck to run scripts\nat normal speed':
+ 'Desmarque para executar os roteiros\nna velocidade normal.',
+ 'check to enable\nIDE animations':
+ 'Marque para ativar\nas animações da interface de usuário.',
+ 'Thread safe scripts':
+ 'Roteiros seguros face a threads',
+ 'uncheck to allow\nscript reentrance':
+ 'Desmarque para permitir\nreentrância nos roteiros.',
+ 'check to disallow\nscript reentrance':
+ 'Marque para não permitir\nreentrância nos roteiros.',
+ 'Prefer smooth animations':
+ 'Prefira animações suaves',
+ 'uncheck for greater speed\nat variable frame rates':
+ 'Desmarque para aumentar a velocidade\npermitindo ritmos variáveis das tramas nas animações.',
+ 'check for smooth, predictable\nanimations across computers':
+ 'Marque para obter animações mais suaves\ne previsíveis de computador para computador.',
+
+ // Entradas
+ 'with inputs':
+ 'com argumentos',
+ 'input names:':
+ 'com parâmetros',
+ 'Input Names:':
+ 'Parâmetros:',
+ 'input list:':
+ 'lista de entradas',
+
+ // menus de contexto:
+ 'help':
+ 'ajuda',
+
+ // palette:
+ 'hide primitives':
+ 'esconda blocos primitivos',
+ 'show primitives':
+ 'mostre blocos primitivos',
+
+ // blocos:
+ 'help...':
+ 'ajuda…',
+ 'relabel...':
+ 'renomear…',
+ 'duplicate':
+ 'duplicar',
+ 'make a copy\nand pick it up':
+ 'Faça uma cópia do\nbloco e pegue-a.',
+ 'only duplicate this block':
+ 'Duplique apenas este bloco.',
+ 'delete':
+ 'apague',
+ 'script pic...':
+ 'fotografia do roteiro',
+ 'open a new window\nwith a picture of this script':
+ 'Abra uma nova janela com\numa fotografia deste roteiro.',
+ 'ringify':
+ 'adicione anel',
+ 'unringify':
+ 'apague anel',
+
+ // blocos personalizados:
+ 'delete block definition...':
+ 'remova definição do bloco…',
+ 'edit...':
+ 'editar…',
+
+ // Atores:
+ 'edit':
+ 'editar',
+ 'detach from':
+ 'desencaixe de',
+ 'detach all parts':
+ 'desencaixe todas as partes',
+ 'export...':
+ 'exportar…',
+
+ // palco:
+ 'show all':
+ 'mostre todos os atores',
+ 'pic...':
+ 'fotografia…',
+ 'open a new window\nwith a picture of the stage':
+ 'Abrir uma nova janela com\numa fotografia do palco.',
+
+ // área de Roteiros:
+ 'clean up':
+ 'limpar',
+ 'arrange scripts\nvertically':
+ 'Organize roteiros\nverticalmente.',
+ 'add comment':
+ 'adicione um comentário',
+ 'undrop':
+ 'desfaça posicionamento',
+ 'undo the last\nblock drop\nin this pane':
+ 'Desfazer o último posicionamento de um bloco\nneste painel.',
+ 'scripts pic...':
+ 'fotografe os roteiros…',
+ 'open a new window\nwith a picture of all scripts':
+ 'Abra uma nova janela com\numa fotografia de todos os roteiros.',
+ 'make a block...':
+ 'crie um bloco…',
+
+ // Fantasias:
+ 'rename':
+ 'renomear',
+ 'export':
+ 'exportar',
+ 'rename costume':
+ 'Qual o novo nome da fantasia?',
+
+ // Sons
+ 'Play sound':
+ 'Toque som.',
+ 'Stop sound':
+ 'Pare som.',
+ 'Stop':
+ 'Parar',
+ 'Play':
+ 'Tocar',
+ 'rename sound':
+ 'Qual o novo nome do som?',
+
+ // Caixas de diálogo
+ // botões
+ 'OK':
+ 'OK',
+ 'Ok':
+ 'OK',
+ 'Cancel':
+ 'Cancela',
+ 'Yes':
+ 'Sim',
+ 'No':
+ 'Não',
+
+ // ajuda
+ 'Help':
+ 'Ajuda',
+
+ // ampliação de blocos
+ 'Zoom blocks':
+ 'Zoom dos blocos',
+ 'build':
+ 'construa',
+ 'your own':
+ 'os seus próprios',
+ 'blocks':
+ 'blocos',
+ 'normal (1x)':
+ 'normal (1x)',
+ 'demo (1.2x)':
+ 'demonstração (1.2x)',
+ 'presentation (1.4x)':
+ 'apresentação (1.4x)',
+ 'big (2x)':
+ 'grande (2x)',
+ 'huge (4x)':
+ 'enorme (4x)',
+ 'giant (8x)':
+ 'gigante (8x)',
+ 'monstrous (10x)':
+ 'monstruoso (10x)',
+
+ // Gestor de Projetos
+ 'Untitled':
+ 'Sem título',
+ 'Open Project':
+ 'Abrir Projeto',
+ '(empty)':
+ '(vazio)',
+ 'Saved!':
+ 'Salvo!',
+ 'Delete Project':
+ 'Apague Projeto',
+ 'Are you sure you want to delete':
+ 'Tem certeza que deseja apagar?',
+ 'rename...':
+ 'alterar o nome…',
+
+ // Editor de fantasias
+ 'Costume Editor':
+ 'Editor de Fantasias',
+ 'click or drag crosshairs to move the rotation center':
+ 'Clique ou arraste a mira para mudar o centro de rotação.',
+
+ // Anotaes de projeto
+ 'Project Notes':
+ 'Notas do Projeto',
+
+ // Novo projeto
+ 'New Project':
+ 'Novo Projeto',
+ 'Replace the current project with a new one?':
+ 'Substituir este projeto por um novo projeto?',
+
+ // guardar projecto
+ 'Save Project As...':
+ 'Salvar Projeto Como…',
+
+ // exportar blocos
+ 'Export blocks':
+ 'Exportar blocos',
+ 'Import blocks':
+ 'Importar blocos',
+ 'this project doesn\'t have any\ncustom global blocks yet':
+ 'Este projeto ainda não possui\nnenhum bloco global personalizado.',
+ 'select':
+ 'selecionar',
+ 'none':
+ 'nenhum',
+
+ // Caixa de diálogo de variáveis
+ 'for all sprites':
+ 'para todos os atores',
+ 'for this sprite only':
+ 'apenas para este ator',
+
+ // caixa de diálogo de blocos
+ 'Change block':
+ 'Altere o tipo do bloco',
+ 'Command':
+ 'Comando',
+ 'Reporter':
+ 'Repórter',
+ 'Predicate':
+ 'Predicado',
+
+ // editor de blocos
+ 'Block Editor':
+ 'Editor de Blocos',
+ 'Apply':
+ 'Aplicar',
+
+ // caixa de diálogo de remoção de bloco
+ 'Delete Custom Block':
+ 'Remova Bloco Personalizado',
+ 'block deletion dialog text':
+ 'Quer mesmo remover este bloco e '
+ + 'todas as suas aplicações?',
+
+ // Caixa de diálogo de parâmetros
+ 'Create input name':
+ 'Criar parâmetro',
+ 'Edit input name':
+ 'Editar parâmetro',
+ 'Edit label fragment':
+ 'Editar rótulo',
+ 'Title text':
+ 'Nome',
+ 'Input name':
+ 'Parâmetro',
+ 'Delete':
+ 'Remover',
+ 'Object':
+ 'Objeto',
+ 'Number':
+ 'Número',
+ 'Text':
+ 'Texto',
+ 'List':
+ 'Lista',
+ 'Any type':
+ 'Qualquer tipo',
+ 'Boolean (T/F)':
+ 'Booleano (V/F)',
+ 'Command\n(inline)':
+ 'Comando\n(em linha)',
+ 'Command\n(C-shape)':
+ 'Comando\n(bloco de repetição)',
+ 'Any\n(unevaluated)':
+ 'Repórter\n(forma especial)',
+ 'Boolean\n(unevaluated)':
+ 'Predicado\n(forma especial)',
+ 'Single input.':
+ 'Parâmetro único.',
+ 'Default Value:':
+ 'Valor em caso de omissão:',
+ 'Multiple inputs (value is list of inputs)':
+ 'Múltiplos argumentos (o valor do parâmetro é a lista dos argumentos).',
+ 'Upvar - make internal variable visible to caller':
+ 'Tornar o parâmetro visível ao invocador.',
+
+ // Acerca do Snap
+ 'About Snap':
+ 'Sobre o Snap!',
+ 'Back...':
+ 'Para trás…',
+ 'License...':
+ 'Licença…',
+ 'Modules...':
+ 'Módulos…',
+ 'Credits...':
+ 'Créditos…',
+ 'Translators...':
+ 'Tradutores…',
+ 'License':
+ 'Licença',
+ 'current module versions:':
+ 'versões actuais dos módulos',
+ 'Contributors':
+ 'Contribuidores',
+ 'Translations':
+ 'Traduções',
+
+ // observadores de variáveis
+ 'normal':
+ 'normal',
+ 'large':
+ 'grande',
+ 'slider':
+ 'slider',
+ 'slider min...':
+ 'mínimo do slider…',
+ 'slider max...':
+ 'máximo do slider…',
+ 'import...':
+ 'importar…',
+ 'Slider minimum value':
+ 'Valor mínimo do potenciómetro deslizante',
+ 'Slider maximum value':
+ 'Valor máximo do potenciómetro deslizante',
+
+ // observadores de listas
+ 'length: ':
+ 'tamanho: ',
+
+ // comentários
+ 'add comment here...':
+ 'coloque aqui um comentário…',
+
+ // drop downs
+ // direcções
+ '(90) right':
+ '90° (direita)',
+ '(-90) left':
+ '-90° (esquerda)',
+ '(0) up':
+ '0° (acima)',
+ '(180) down':
+ '180° (abaixo)',
+
+ // detecção de colisões
+ 'mouse-pointer':
+ 'ponteiro do mouse',
+ 'edge':
+ 'borda',
+ 'pen trails':
+ 'traços da caneta',
+
+ // trajes
+ 'Turtle':
+ 'seta',
+ 'Empty':
+ 'vazio',
+
+ // efeitos gráficos
+ 'ghost':
+ 'fantasma',
+
+ // teclas
+ 'space':
+ 'espaço',
+ 'up arrow':
+ 'seta para cima',
+ 'down arrow':
+ 'seta para baixo',
+ 'right arrow':
+ 'seta para a direita',
+ 'left arrow':
+ 'seta para a esquerda',
+ 'a':
+ 'a',
+ 'b':
+ 'b',
+ 'c':
+ 'c',
+ 'd':
+ 'd',
+ 'e':
+ 'e',
+ 'f':
+ 'f',
+ 'g':
+ 'g',
+ 'h':
+ 'h',
+ 'i':
+ 'i',
+ 'j':
+ 'j',
+ 'k':
+ 'k',
+ 'l':
+ 'l',
+ 'm':
+ 'm',
+ 'n':
+ 'n',
+ 'o':
+ 'o',
+ 'p':
+ 'p',
+ 'q':
+ 'q',
+ 'r':
+ 'r',
+ 's':
+ 's',
+ 't':
+ 't',
+ 'u':
+ 'u',
+ 'v':
+ 'v',
+ 'w':
+ 'w',
+ 'x':
+ 'x',
+ 'y':
+ 'y',
+ 'z':
+ 'z',
+ '0':
+ '0',
+ '1':
+ '1',
+ '2':
+ '2',
+ '3':
+ '3',
+ '4':
+ '4',
+ '5':
+ '5',
+ '6':
+ '6',
+ '7':
+ '7',
+ '8':
+ '8',
+ '9':
+ '9',
+
+ // messagens
+ 'new...':
+ 'Nova…',
+
+ // funções matemáticas
+ 'abs':
+ 'valor absoluto',
+ 'floor':
+ 'arredondamento para baixo',
+ 'sqrt':
+ 'raiz quadrada',
+ 'sin':
+ 'seno',
+ 'cos':
+ 'cosseno',
+ 'tan':
+ 'tangente',
+ 'asin':
+ 'arco-seno',
+ 'acos':
+ 'arco-cosseno',
+ 'atan':
+ 'arco-tangente',
+ 'ln':
+ 'logaritmo natural',
+ 'e^':
+ 'exponencial',
+
+ // delimitadores
+ 'whitespace':
+ 'espaços em branco',
+ 'line':
+ 'avanços de linha',
+ 'tab':
+ 'tabuladores',
+ 'cr':
+ 'retornos',
+
+ // tipos de dados
+ 'number':
+ 'número',
+ 'text':
+ 'texto',
+ 'Boolean':
+ 'booleano',
+ 'list':
+ 'lista',
+ 'command':
+ 'comando',
+ 'reporter':
+ 'repórter',
+ 'predicate':
+ 'predicado',
+
+ // índices de listas
+ 'last':
+ 'último item',
+ 'any':
+ 'um item ao acaso',
+
+ // em falta no ficheiro lang-de.js
+ 'costume name':
+ 'nome da fantasia',
+ 'Open':
+ 'Abrir',
+ 'Share':
+ 'Compartilhar',
+ 'Cloud':
+ 'Nuvem',
+ 'Browser':
+ 'Navegador',
+ 'Sign up':
+ 'Registrar nova conta',
+ 'Sign in':
+ 'Entrar',
+ 'now connected.':
+ 'entrou.',
+ 'disconnected.':
+ 'saiu.',
+ 'Reset password':
+ 'Recuperar senha',
+ 'Reset Password...':
+ 'Recuperar a sua senha...',
+ 'User name:':
+ 'Nome de usuário:',
+ 'Password:':
+ 'Senha:',
+ 'Birth date:':
+ 'Data de nascimento:',
+ 'January':
+ 'Janeiro',
+ 'February':
+ 'Fevereiro',
+ 'March':
+ 'Março',
+ 'April':
+ 'Abril',
+ 'May':
+ 'Maio',
+ 'June':
+ 'Junho',
+ 'July':
+ 'Julho',
+ 'August':
+ 'Agosto',
+ 'September':
+ 'Setembro',
+ 'October':
+ 'Outubro',
+ 'November':
+ 'Novembro',
+ 'December':
+ 'Dezembro',
+ 'year:':
+ 'ano:',
+ ' or before':
+ ' ou antes',
+ 'E-mail address:':
+ 'Endereço de email:',
+ 'E-mail address of parent or guardian:':
+ 'Endereço de encarregado de educação:',
+ 'Terms of Service...':
+ 'Termos do Serviço…',
+ 'Privacy...':
+ 'Privacidade…',
+ 'I have read and agree\nto the Terms of Service':
+ 'Li e declaro concordar\ncom os Termos do Serviço',
+ 'stay signed in on this computer\nuntil logging out':
+ 'manter-me autenticado neste\ncomputador até que saia',
+ 'please fill out\nthis field':
+ 'Por favor preencha\neste campo.',
+ 'User name must be four\ncharacters or longer':
+ 'O nome de usuário tem de ter\npelo menos quatro caracteres.',
+ 'please provide a valid\nemail address':
+ 'Por favor indique um endereço\nde email válido.',
+ 'password must be six\ncharacters or longer':
+ 'A senha tem de ter\npelo menos seis caracteres.',
+ 'passwords do\nnot match':
+ 'As senhas\nnão correspondem.',
+ 'please agree to\nthe TOS':
+ 'Por favor concorde com\nos Termos do Serviço.',
+ 'Examples':
+ 'Exemplos',
+ 'You are not logged in':
+ 'Ainda não se autenticou',
+ 'Updating\nproject list...':
+ 'Atualizando a\nlista de projetos…',
+ 'Opening project...':
+ 'Abrindo o projeto…',
+ 'Fetching project from the cloud...':
+ 'Obtendo o projeto da nuvem…',
+ 'Saving project to the cloud...':
+ 'Salvando o projeto na nuvem…',
+ 'Sprite Nesting':
+ 'Atores aninhados',
+ 'uncheck to disable\nsprite composition':
+ 'Desmarque para desativar\na composição de atores.',
+ 'Codification support':
+ 'Suportar produção de código',
+ 'check for block\nto text mapping features':
+ 'Assinalar para funcionalidades\nde mapeamento entre blocos e texto.',
+ 'Save to disk':
+ 'Salvar no disco',
+ 'experimental - store this project\nin your downloads folder':
+ 'Experimental - Salvar este projeto\nna sua pasta de downloads.',
+ 'saved.':
+ 'salvo.',
+ 'options...':
+ 'opções…',
+ 'read-only':
+ 'apenas leitura',
+ 'Input Slot Options':
+ 'Opções de Campos de Entrada',
+ 'Enter one option per line.Optionally use "=" as key/value delimiter\ne.g.\n the answer=42':
+ 'Entre com uma opção por linha. Opcionalmente, use "=" como separador\nentre chave e valor, e.g.\n a resposta=42',
+ 'paint a new sprite':
+ 'Desenhar um novo ator.',
+ 'Paint a new costume':
+ 'Desenhar uma nova fantasia.',
+ 'add a new Turtle sprite':
+ 'Adicionar um novo ator.',
+ 'Flat design':
+ 'Visual plano',
+ 'check for alternative\nGUI design':
+ 'Marque para um design alternativo\nda interface gráfica de usuário.',
+ 'Rasterize SVGs':
+ 'Transformar desenhos vetorias (SVG) em mapas de bits',
+ 'check to rasterize\nSVGs on import':
+ 'Marque para transformar os arquivos vetoriais SVG\nem mapas de bits durante a importação.',
+ 'comment pic...':
+ 'fotografia do comentário…',
+ 'open a new window\nwith a picture of this comment':
+ 'Abrir uma nova janela com\numa fotografia deste comentário.'
+};
diff --git a/lang-ru.js b/lang-ru.js
index 45a0870..f113f2c 100644
--- a/lang-ru.js
+++ b/lang-ru.js
@@ -168,7 +168,8 @@ SnapTranslator.dict.ru = {
Special characters: (see <http://0xcc.net/jsescape/>)
€, Š \u00c4, \u00e4
-…, š \u00d6, \u00f6
+
+, š \u00d6, \u00f6
†, Ÿ \u00dc, \u00fc
§ \u00df
*/
@@ -186,15 +187,15 @@ SnapTranslator.dict.ru = {
// GUI
// control bar:
'untitled':
- 'неозаглавленный',
+ 'Безымянный',
'development mode':
- 'разрабатываемая версия',
+ 'Разрабатываемая версия',
// categories:
'Motion':
'Движение',
'Looks':
- 'Изображение',
+ 'Внешность',
'Sound':
'Звук',
'Pen':
@@ -202,7 +203,7 @@ SnapTranslator.dict.ru = {
'Control':
'Управление',
'Sensing':
- 'Состояние',
+ 'Сенсоры',
'Operators':
'Операторы',
'Variables':
@@ -220,13 +221,13 @@ SnapTranslator.dict.ru = {
'Scripts':
'Скрипты',
'Costumes':
- 'Маски',
+ 'Костюмы',
'Sounds':
- 'Звучания',
+ 'Звуки',
// names:
'Sprite':
- 'Образ',
+ 'Спрайт',
'Stage':
'Сцена',
@@ -236,17 +237,17 @@ SnapTranslator.dict.ru = {
'can rotate':
'вращаемый',
'only face left/right':
- 'вращаемый только слева направо',
+ 'вращаемый только на лево и направо',
// new sprite button:
'add a new sprite':
- 'Добавить новый Образ',
+ 'Добавить новый спрайт',
// tab help
'costumes tab help':
- 'импорт изображение с другого веб-сайта\nили со своего компьютера скопировав его сюда',
+ 'импортируйте изображение с другого веб-сайта\nили со своего компьютера скопировав его сюда',
'import a sound from your computer\nby dragging it into here':
- 'импорт звук со своего компьютера\nскопировав его сюда',
+ 'импортируйте звук со своего компьютера\nскопировав его сюда',
// primitive blocks:
@@ -282,7 +283,7 @@ SnapTranslator.dict.ru = {
// motion:
'Stage selected:\nno motion primitives':
- 'Сцена-клавиша нажата:\nДвижение-примитивы отключены',
+ 'Выбрана сцена:\nнет блоков движения',
'move %n steps':
'передвинуть на %n шагов',
@@ -291,7 +292,7 @@ SnapTranslator.dict.ru = {
'turn %counterclockwise %n degrees':
'повернуть %counterclockwise на %n градусов',
'point in direction %dir':
- 'указывать в направл. %dir',
+ 'указывать в направлении %dir',
'point towards %dst':
'указывать на %dst',
'go to x: %n y: %n':
@@ -319,17 +320,17 @@ SnapTranslator.dict.ru = {
// looks:
'switch to costume %cst':
- 'измен. маску на %cst',
+ 'изменить костюм на %cst',
'next costume':
- 'следующая маска',
+ 'следующий костюм',
'costume #':
- 'маска #',
+ 'костюм №',
'say %s for %n secs':
- 'произн. %s в теч. %n сек.',
+ 'говорить %s в течение %n сек',
'say %s':
- 'произнести %s',
+ 'говорить %s',
'think %s for %n secs':
- 'думать %s в теч. %n сек.',
+ 'думать %s в течение %n сек',
'think %s':
'думать %s',
'Hello!':
@@ -337,25 +338,25 @@ SnapTranslator.dict.ru = {
'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',
'set size to %n %':
- 'установить размер %n %',
+ 'установить размер в %n',
'size':
'размер',
'show':
- 'показывать',
+ 'показаться',
'hide':
- 'прятать',
+ 'спрятаться',
'go to front':
- 'переместить вперед',
+ 'переместиться на слой вперед',
'go back %n layers':
- 'перемест. на %n уровня назад',
+ 'переместиться на %n слоёв назад',
'development mode \ndebugging primitives:':
'Разрабатываемая версия \nотладка примитивов:',
@@ -913,7 +914,7 @@ SnapTranslator.dict.ru = {
// About Snap
'About Snap':
- 'Snap! Реквизиты',
+ 'О Snap!',
'Back...':
'Bозврат...',
'License...':
@@ -957,7 +958,7 @@ SnapTranslator.dict.ru = {
// coments
'add comment here...':
- 'добавить комментарий сюда...',
+ 'добавьте комментарий сюда...',
// drow downs
// directions
@@ -974,17 +975,17 @@ SnapTranslator.dict.ru = {
'mouse-pointer':
'курсор мышки',
'edge':
- 'грань',
+ 'край',
'pen trails':
'линии пера',
// costumes
'Turtle':
- 'Горлица',
+ 'Черепашка',
// graphical effects
'ghost':
- 'прозрачн.',
+ 'прозрачность',
// keys
'space':
@@ -1117,4 +1118,8 @@ SnapTranslator.dict.ru = {
'последний',
'any':
'любой'
+ 'now connected':
+ 'вы вошли в систему'
+ 'undo':
+ 'отменить'
};
diff --git a/lists.js b/lists.js
index 3166bf1..ea553b0 100644
--- a/lists.js
+++ b/lists.js
@@ -61,7 +61,7 @@ PushButtonMorph, SyntaxElementMorph, Color, Point, WatcherMorph,
StringMorph, SpriteMorph, ScrollFrameMorph, CellMorph, ArrowMorph,
MenuMorph, snapEquals, Morph, isNil, localize, MorphicPreferences*/
-modules.lists = '2014-January-09';
+modules.lists = '2014-Jun-04';
var List;
var ListWatcherMorph;
@@ -305,7 +305,7 @@ List.prototype.equalTo = function (other) {
if (this.length() !== other.length()) {
return false;
}
- for (i = 0; i < this.length(); i += 1) {
+ for (i = 1; i <= this.length(); i += 1) {
if (!snapEquals(this.at(i), other.at(i))) {
return false;
}
diff --git a/locale.js b/locale.js
index c4e8f6f..614b38c 100644
--- a/locale.js
+++ b/locale.js
@@ -42,7 +42,7 @@
/*global modules, contains*/
-modules.locale = '2014-February-13';
+modules.locale = '2014-Jun-04';
// Global stuff
@@ -149,7 +149,7 @@ SnapTranslator.dict.de = {
'translator_e-mail':
'jens@moenig.org',
'last_changed':
- '2014-02-13'
+ '2014-06-04'
};
SnapTranslator.dict.it = {
@@ -209,7 +209,7 @@ SnapTranslator.dict.pt = {
'translator_e-mail':
'mmsequeira@gmail.com',
'last_changed':
- '2014-01-12'
+ '2014-05-26'
};
SnapTranslator.dict.cs = {
@@ -368,4 +368,29 @@ SnapTranslator.dict.ca = {
'tibabenfortlapalanca@gmail.com',
'last_changed':
'2013-11-26'
-}; \ No newline at end of file
+};
+
+SnapTranslator.dict.fi = {
+ // meta information
+ 'language_name':
+ 'suomi',
+ 'language_translator':
+ 'Jouni K. Sepp\u00e4nen',
+ 'translator_e-mail':
+ 'jks@iki.fi',
+ 'last_changed':
+ '2014-04-18'
+};
+
+SnapTranslator.dict.pt_BR = {
+ // meta information
+ 'language_name':
+ 'Português do Brasil',
+ 'language_translator':
+ 'Aldo von Wangenheim',
+ 'translator_e-mail':
+ 'awangenh@inf.ufsc.br',
+ 'last_changed':
+ '2014-04-20'
+};
+
diff --git a/morphic.js b/morphic.js
index b55b180..7d1f53d 100644
--- a/morphic.js
+++ b/morphic.js
@@ -1035,7 +1035,7 @@
/*global window, HTMLCanvasElement, getMinimumFontHeight, FileReader, Audio,
FileList, getBlurredShadowSupport*/
-var morphicVersion = '2014-February-03';
+var morphicVersion = '2014-May-20';
var modules = {}; // keep track of additional loaded modules
var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug
@@ -10268,6 +10268,9 @@ WorldMorph.prototype.initEventListeners = function () {
}
event.preventDefault();
}
+ if (event.ctrlKey || event.metaKey) {
+ event.preventDefault();
+ }
},
false
);
diff --git a/objects.js b/objects.js
index 4b1b359..002b7e3 100644
--- a/objects.js
+++ b/objects.js
@@ -61,6 +61,7 @@
sound handling
Achal Dave contributed research and prototyping for creating music
using the Web Audio API
+ Yuan Yuan contributed graphic effects for costumes
*/
@@ -124,7 +125,7 @@ PrototypeHatBlockMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.objects = '2014-February-11';
+modules.objects = '2014-Jun-06';
var SpriteMorph;
var StageMorph;
@@ -203,90 +204,106 @@ SpriteMorph.prototype.initBlocks = function () {
// Motion
forward: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'move %n steps',
defaults: [10]
},
turn: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'turn %clockwise %n degrees',
defaults: [15]
},
turnLeft: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'turn %counterclockwise %n degrees',
defaults: [15]
},
setHeading: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'point in direction %dir'
},
doFaceTowards: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'point towards %dst'
},
gotoXY: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'go to x: %n y: %n',
defaults: [0, 0]
},
doGotoObject: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'go to %dst'
},
doGlide: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'glide %n secs to x: %n y: %n',
defaults: [1, 0, 0]
},
changeXPosition: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'change x by %n',
defaults: [10]
},
setXPosition: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'set x to %n',
defaults: [0]
},
changeYPosition: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'change y by %n',
defaults: [10]
},
setYPosition: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'set y to %n',
defaults: [0]
},
bounceOffEdge: {
+ only: SpriteMorph,
type: 'command',
category: 'motion',
spec: 'if on edge, bounce'
},
xPosition: {
+ only: SpriteMorph,
type: 'reporter',
category: 'motion',
spec: 'x position'
},
yPosition: {
+ only: SpriteMorph,
type: 'reporter',
category: 'motion',
spec: 'y position'
},
direction: {
+ only: SpriteMorph,
type: 'reporter',
category: 'motion',
spec: 'direction'
@@ -309,24 +326,28 @@ SpriteMorph.prototype.initBlocks = function () {
spec: 'costume #'
},
doSayFor: {
+ only: SpriteMorph,
type: 'command',
category: 'looks',
spec: 'say %s for %n secs',
defaults: [localize('Hello!'), 2]
},
bubble: {
+ only: SpriteMorph,
type: 'command',
category: 'looks',
spec: 'say %s',
defaults: [localize('Hello!')]
},
doThinkFor: {
+ only: SpriteMorph,
type: 'command',
category: 'looks',
spec: 'think %s for %n secs',
defaults: [localize('Hmm...'), 2]
},
doThink: {
+ only: SpriteMorph,
type: 'command',
category: 'looks',
spec: 'think %s',
@@ -350,38 +371,45 @@ SpriteMorph.prototype.initBlocks = function () {
spec: 'clear graphic effects'
},
changeScale: {
+ only: SpriteMorph,
type: 'command',
category: 'looks',
spec: 'change size by %n',
defaults: [10]
},
setScale: {
+ only: SpriteMorph,
type: 'command',
category: 'looks',
spec: 'set size to %n %',
defaults: [100]
},
getScale: {
+ only: SpriteMorph,
type: 'reporter',
category: 'looks',
spec: 'size'
},
show: {
+ only: SpriteMorph,
type: 'command',
category: 'looks',
spec: 'show'
},
hide: {
+ only: SpriteMorph,
type: 'command',
category: 'looks',
spec: 'hide'
},
comeToFront: {
+ only: SpriteMorph,
type: 'command',
category: 'looks',
spec: 'go to front'
},
goBack: {
+ only: SpriteMorph,
type: 'command',
category: 'looks',
spec: 'go back %n layers',
@@ -395,12 +423,21 @@ SpriteMorph.prototype.initBlocks = function () {
},
// Looks - Debugging primitives for development mode
+ reportCostumes: {
+ dev: true,
+ type: 'reporter',
+ category: 'looks',
+ spec: 'wardrobe'
+ },
+
alert: {
+ dev: true,
type: 'command',
category: 'looks',
spec: 'alert %mult%s'
},
log: {
+ dev: true,
type: 'command',
category: 'looks',
spec: 'console log %mult%s'
@@ -452,6 +489,14 @@ SpriteMorph.prototype.initBlocks = function () {
spec: 'tempo'
},
+ // Sound - Debugging primitives for development mode
+ reportSounds: {
+ dev: true,
+ type: 'reporter',
+ category: 'sound',
+ spec: 'jukebox'
+ },
+
// Pen
clear: {
type: 'command',
@@ -459,57 +504,67 @@ SpriteMorph.prototype.initBlocks = function () {
spec: 'clear'
},
down: {
+ only: SpriteMorph,
type: 'command',
category: 'pen',
spec: 'pen down'
},
up: {
+ only: SpriteMorph,
type: 'command',
category: 'pen',
spec: 'pen up'
},
setColor: {
+ only: SpriteMorph,
type: 'command',
category: 'pen',
spec: 'set pen color to %clr'
},
changeHue: {
+ only: SpriteMorph,
type: 'command',
category: 'pen',
spec: 'change pen color by %n',
defaults: [10]
},
setHue: {
+ only: SpriteMorph,
type: 'command',
category: 'pen',
spec: 'set pen color to %n',
defaults: [0]
},
changeBrightness: {
+ only: SpriteMorph,
type: 'command',
category: 'pen',
spec: 'change pen shade by %n',
defaults: [10]
},
setBrightness: {
+ only: SpriteMorph,
type: 'command',
category: 'pen',
spec: 'set pen shade to %n',
defaults: [100]
},
changeSize: {
+ only: SpriteMorph,
type: 'command',
category: 'pen',
spec: 'change pen size by %n',
defaults: [1]
},
setSize: {
+ only: SpriteMorph,
type: 'command',
category: 'pen',
spec: 'set pen size to %n',
defaults: [1]
},
doStamp: {
+ only: SpriteMorph,
type: 'command',
category: 'pen',
spec: 'stamp'
@@ -703,31 +758,37 @@ SpriteMorph.prototype.initBlocks = function () {
// Sensing
reportTouchingObject: {
+ only: SpriteMorph,
type: 'predicate',
category: 'sensing',
spec: 'touching %col ?'
},
reportTouchingColor: {
+ only: SpriteMorph,
type: 'predicate',
category: 'sensing',
spec: 'touching %clr ?'
},
reportColorIsTouchingColor: {
+ only: SpriteMorph,
type: 'predicate',
category: 'sensing',
spec: 'color %clr is touching %clr ?'
},
colorFiltered: {
+ dev: true,
type: 'reporter',
category: 'sensing',
spec: 'filtered for %clr'
},
reportStackSize: {
+ dev: true,
type: 'reporter',
category: 'sensing',
spec: 'stack size'
},
reportFrameCount: {
+ dev: true,
type: 'reporter',
category: 'sensing',
spec: 'frames'
@@ -739,6 +800,7 @@ SpriteMorph.prototype.initBlocks = function () {
defaults: [localize('what\'s your name?')]
},
reportLastAnswer: { // retained for legacy compatibility
+ dev: true,
type: 'reporter',
category: 'sensing',
spec: 'answer'
@@ -779,6 +841,7 @@ SpriteMorph.prototype.initBlocks = function () {
spec: 'reset timer'
},
reportTimer: { // retained for legacy compatibility
+ dev: true,
type: 'reporter',
category: 'sensing',
spec: 'timer'
@@ -962,12 +1025,14 @@ SpriteMorph.prototype.initBlocks = function () {
defaults: [localize('hello') + ' ' + localize('world'), " "]
},
reportTypeOf: { // only in dev mode for debugging
+ dev: true,
type: 'reporter',
category: 'operators',
spec: 'type of %s',
defaults: [5]
},
reportTextFunction: { // only in dev mode - experimental
+ dev: true,
type: 'reporter',
category: 'operators',
spec: '%txtfun of %s',
@@ -1076,6 +1141,7 @@ SpriteMorph.prototype.initBlocks = function () {
// MAP - experimental
reportMap: {
+ dev: true,
type: 'reporter',
category: 'lists',
spec: 'map %repRing over %l'
@@ -1139,10 +1205,10 @@ SpriteMorph.prototype.blockAlternatives = {
yPosition: ['xPosition'],
// looks:
- doSayFor: ['doThinkFor'],
- doThinkFor: ['doSayFor'],
- bubble: ['doThink'],
- doThink: ['bubble'],
+ doSayFor: ['doThinkFor', 'bubble', 'doThink', 'doAsk'],
+ doThinkFor: ['doSayFor', 'doThink', 'bubble', 'doAsk'],
+ bubble: ['doThink', 'doAsk', 'doSayFor', 'doThinkFor'],
+ doThink: ['bubble', 'doAsk', 'doSayFor', 'doThinkFor'],
show: ['hide'],
hide: ['show'],
changeEffect: ['setEffect'],
@@ -1173,8 +1239,13 @@ SpriteMorph.prototype.blockAlternatives = {
receiveClick: ['receiveGo'],
doBroadcast: ['doBroadcastAndWait'],
doBroadcastAndWait: ['doBroadcast'],
+ doIf: ['doIfElse', 'doUntil'],
+ doIfElse: ['doIf', 'doUntil'],
+ doRepeat: ['doUntil'],
+ doUntil: ['doRepeat', 'doIf'],
// sensing:
+ doAsk: ['bubble', 'doThink', 'doSayFor', 'doThinkFor'],
getLastAnswer: ['getTimer'],
getTimer: ['getLastAnswer'],
reportMouseX: ['reportMouseY'],
@@ -1233,6 +1304,18 @@ SpriteMorph.prototype.init = function (globals) {
this.idx = 0; // not to be serialized (!) - used for de-serialization
this.wasWarped = false; // not to be serialized, used for fast-tracking
+ this.graphicsValues = { 'negative': 0,
+ 'fisheye': 0,
+ 'whirl': 0,
+ 'pixelate': 0,
+ 'mosaic': 0,
+ 'brightness': 0,
+ 'color': 0,
+ 'comic': 0,
+ 'duplicate': 0,
+ 'confetti': 0
+ };
+
SpriteMorph.uber.init.call(this);
this.isDraggable = true;
@@ -1364,6 +1447,9 @@ SpriteMorph.prototype.drawNew = function () {
ctx.rotate(radians(facing - 90));
ctx.drawImage(pic.contents, 0, 0);
+ // apply graphics effects to image
+ this.image = this.applyGraphicsEffects(this.image);
+
// adjust my position to the rotation
this.setCenter(currentCenter, true); // just me
@@ -1386,6 +1472,7 @@ SpriteMorph.prototype.drawNew = function () {
this.setCenter(currentCenter, true); // just me
SpriteMorph.uber.drawNew.call(this, facing);
this.rotationOffset = this.extent().divideBy(2);
+ this.image = this.applyGraphicsEffects(this.image);
if (isLoadingCostume) { // retry until costume is done loading
cst = this.costume;
handle = setInterval(
@@ -1630,6 +1717,8 @@ SpriteMorph.prototype.blockTemplates = function (category) {
txt.setColor(this.paletteTextColor);
blocks.push(txt);
blocks.push('-');
+ blocks.push(block('reportCostumes'));
+ blocks.push('-');
blocks.push(block('log'));
blocks.push(block('alert'));
}
@@ -1651,6 +1740,20 @@ SpriteMorph.prototype.blockTemplates = function (category) {
blocks.push(watcherToggle('getTempo'));
blocks.push(block('getTempo'));
+ // for debugging: ///////////////
+
+ if (this.world().isDevMode) {
+ blocks.push('-');
+ txt = new TextMorph(localize(
+ 'development mode \ndebugging primitives:'
+ ));
+ txt.fontSize = 9;
+ txt.setColor(this.paletteTextColor);
+ blocks.push(txt);
+ blocks.push('-');
+ blocks.push(block('reportSounds'));
+ }
+
} else if (cat === 'pen') {
blocks.push(block('clear'));
@@ -2049,6 +2152,7 @@ SpriteMorph.prototype.freshPalette = function (category) {
});
}
+ menu.addItem('find blocks...', function () {myself.searchBlocks(); });
if (canHidePrimitives()) {
menu.addItem(
'hide primitives',
@@ -2180,6 +2284,137 @@ SpriteMorph.prototype.freshPalette = function (category) {
return palette;
};
+// SpriteMorph blocks searching
+
+SpriteMorph.prototype.blocksMatching = function (searchString, strictly) {
+ // answer an array of block templates whose spec contains
+ // the given search string, ordered by descending relevance
+ var blocks = [],
+ blocksDict,
+ myself = this,
+ search = searchString.toLowerCase(),
+ stage = this.parentThatIsA(StageMorph);
+
+ function labelOf(aBlockSpec) {
+ var words = (BlockMorph.prototype.parseSpec(aBlockSpec)),
+ filtered = words.filter(
+ function (each) {return (each.indexOf('%') !== 0); }
+ );
+ return filtered.join(' ');
+ }
+
+ function fillDigits(anInt, totalDigits, fillChar) {
+ var ans = String(anInt);
+ while (ans.length < totalDigits) {ans = fillChar + ans; }
+ return ans;
+ }
+
+ function relevance(aBlockLabel, aSearchString) {
+ var lbl = ' ' + aBlockLabel,
+ idx = lbl.indexOf(aSearchString),
+ atWord;
+ if (idx === -1) {return -1; }
+ atWord = (lbl.charAt(idx - 1) === ' ');
+ if (strictly && !atWord) {return -1; }
+ return (atWord ? '1' : '2') + fillDigits(idx, 4, '0');
+ }
+
+ function primitive(selector) {
+ var newBlock = SpriteMorph.prototype.blockForSelector(selector, true);
+ newBlock.isTemplate = true;
+ return newBlock;
+ }
+
+ // custom blocks
+ [this.customBlocks, stage.globalBlocks].forEach(function (blocksList) {
+ blocksList.forEach(function (definition) {
+ var spec = localize(definition.blockSpec()).toLowerCase(),
+ rel = relevance(labelOf(spec), search);
+ if (rel !== -1) {
+ blocks.push([definition.templateInstance(), rel + '1']);
+ }
+ });
+ });
+ // primitives
+ blocksDict = SpriteMorph.prototype.blocks;
+ Object.keys(blocksDict).forEach(function (selector) {
+ if (!StageMorph.prototype.hiddenPrimitives[selector]) {
+ var block = blocksDict[selector],
+ spec = localize(block.spec).toLowerCase(),
+ rel = relevance(labelOf(spec), search);
+ if (
+ (rel !== -1) &&
+ (!block.dev) &&
+ (!block.only || (block.only === myself.constructor))
+ ) {
+ blocks.push([primitive(selector), rel + '2']);
+ }
+ }
+ });
+ blocks.sort(function (x, y) {return x[1] < y[1] ? -1 : 1; });
+ return blocks.map(function (each) {return each[0]; });
+};
+
+SpriteMorph.prototype.searchBlocks = function () {
+ var myself = this,
+ unit = SyntaxElementMorph.prototype.fontSize,
+ ide = this.parentThatIsA(IDE_Morph),
+ oldSearch = '',
+ searchBar = new InputFieldMorph(''),
+ searchPane = ide.createPalette('forSearch');
+
+ function show(blocks) {
+ var oldFlag = Morph.prototype.trackChanges,
+ x = searchPane.contents.left() + 5,
+ y = (searchBar.bottom() + unit);
+ Morph.prototype.trackChanges = false;
+ searchPane.contents.children = [searchPane.contents.children[0]];
+ blocks.forEach(function (block) {
+ block.setPosition(new Point(x, y));
+ searchPane.addContents(block);
+ y += block.height();
+ y += unit * 0.3;
+ });
+ Morph.prototype.trackChanges = oldFlag;
+ searchPane.changed();
+ }
+
+ searchPane.owner = this;
+ searchPane.color = myself.paletteColor;
+ searchPane.contents.color = myself.paletteColor;
+ searchPane.addContents(searchBar);
+ searchBar.drawNew();
+ searchBar.setWidth(ide.logo.width() - 30);
+ searchBar.contrast = 90;
+ searchBar.setPosition(
+ searchPane.contents.topLeft().add(new Point(10, 10))
+ );
+ searchBar.drawNew();
+
+ searchPane.accept = function () {
+ var search = searchBar.getValue();
+ if (search.length > 0) {
+ show(myself.blocksMatching(search));
+ }
+ };
+
+ searchPane.reactToKeystroke = function () {
+ var search = searchBar.getValue();
+ if (search !== oldSearch) {
+ oldSearch = search;
+ show(myself.blocksMatching(search, search.length < 2));
+ }
+ };
+
+ searchBar.cancel = function () {
+ ide.refreshPalette();
+ ide.palette.adjustScrollBars();
+ };
+
+ ide.fixLayout('refreshPalette');
+ searchBar.edit();
+};
+
// SpriteMorph variable management
SpriteMorph.prototype.addVariable = function (name, isGlobal) {
@@ -2272,6 +2507,11 @@ SpriteMorph.prototype.doWearPreviousCostume = function () {
};
SpriteMorph.prototype.doSwitchToCostume = function (id) {
+ if (id instanceof Costume) { // allow first-class costumes
+ this.wearCostume(id);
+ return;
+ }
+
var num,
arr = this.costumes.asArray(),
costume;
@@ -2302,6 +2542,10 @@ SpriteMorph.prototype.doSwitchToCostume = function (id) {
this.wearCostume(costume);
};
+SpriteMorph.prototype.reportCostumes = function () {
+ return this.costumes;
+};
+
// SpriteMorph sound management
SpriteMorph.prototype.addSound = function (audio, name) {
@@ -2327,6 +2571,10 @@ SpriteMorph.prototype.playSound = function (name) {
}
};
+SpriteMorph.prototype.reportSounds = function () {
+ return this.sounds;
+};
+
// SpriteMorph user menu
SpriteMorph.prototype.userMenu = function () {
@@ -2615,14 +2863,132 @@ SpriteMorph.prototype.changeScale = function (delta) {
this.setScale(this.getScale() + (+delta || 0));
};
-// SpriteMorph graphic effects
+// Spritemorph graphic effects
+
+SpriteMorph.prototype.graphicsChanged = function () {
+ var myself = this;
+ return Object.keys(this.graphicsValues).some(
+ function (any) {
+ return myself.graphicsValues[any] < 0 ||
+ myself.graphicsValues[any] > 0;
+ }
+ );
+};
+
+SpriteMorph.prototype.applyGraphicsEffects = function (canvas) {
+// For every effect: apply transform of that effect(canvas, stored value)
+// The future: write more effects here
+ var ctx, imagedata, pixels, newimagedata;
+
+ function transform_negative(p, value) {
+ var i, rcom, gcom, bcom;
+ if (value !== 0) {
+ for (i = 0; i < p.length; i += 4) {
+ rcom = 255 - p[i];
+ gcom = 255 - p[i + 1];
+ bcom = 255 - p[i + 2];
+
+ if (p[i] < rcom) { //compare to the complement
+ p[i] += value;
+ } else if (p[i] > rcom) {
+ p[i] -= value;
+ }
+ if (p[i + 1] < gcom) {
+ p[i + 1] += value;
+ } else if (p[i + 1] > gcom) {
+ p[i + 1] -= value;
+ }
+ if (p[i + 2] < bcom) {
+ p[i + 2] += value;
+ } else if (p[i + 2] > bcom) {
+ p[i + 2] -= value;
+ }
+ }
+ }
+ return p;
+ }
+
+ function transform_brightness(p, value) {
+ var i;
+ if (value !== 0) {
+ for (i = 0; i < p.length; i += 4) {
+ p[i] += value; //255 = 100% of this color
+ p[i + 1] += value;
+ p[i + 2] += value;
+ }
+ }
+ return p;
+ }
+
+ function transform_comic(p, value) {
+ var i;
+ if (value !== 0) {
+ for (i = 0; i < p.length; i += 4) {
+ p[i] += Math.sin(i * value) * 127 + 128;
+ p[i + 1] += Math.sin(i * value) * 127 + 128;
+ p[i + 2] += Math.sin(i * value) * 127 + 128;
+ }
+ }
+ return p;
+ }
+
+ function transform_duplicate(p, value) {
+ var i;
+ if (value !== 0) {
+ for (i = 0; i < p.length; i += 4) {
+ p[i] = p[i * value];
+ p[i + 1] = p[i * value + 1];
+ p[i + 2] = p[i * value + 2];
+ p[i + 3] = p[i * value + 3];
+ }
+ }
+ return p;
+ }
+
+ function transform_confetti(p, value) {
+ var i;
+ if (value !== 0) {
+ for (i = 0; i < p.length; i += 1) {
+ p[i] = Math.sin(value * p[i]) * 127 + p[i];
+ }
+ }
+ return p;
+ }
+
+ if (this.graphicsChanged()) {
+ ctx = canvas.getContext("2d");
+ imagedata = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ pixels = imagedata.data;
+
+ //A sprite should wear all 7 effects at once
+ /*pixels = transform_whirl(pixels, this.graphicsValues.whirl);*/
+ pixels = transform_negative(pixels, this.graphicsValues.negative);
+ pixels = transform_brightness(pixels, this.graphicsValues.brightness);
+ pixels = transform_comic(pixels, this.graphicsValues.comic);
+ /*pixels = transform_pixelate(pixels, this.graphicsValues.pixelate);*/
+ pixels = transform_duplicate(pixels, this.graphicsValues.duplicate);
+ /*pixels = transform_color(pixels, this.graphicsValues.color);*/
+ /*pixels = transform_fisheye(pixels, this.graphicsValues.fisheye);*/
+ pixels = transform_confetti(pixels, this.graphicsValues.confetti);
+
+ //the last object will have all the transformations done on it
+ newimagedata = ctx.createImageData(imagedata); //make imgdata object
+ newimagedata.data.set(pixels); //add transformed pixels
+ ctx.putImageData(newimagedata, 0, 0);
+ }
+
+ return canvas;
+};
SpriteMorph.prototype.setEffect = function (effect, value) {
var eff = effect instanceof Array ? effect[0] : null;
if (eff === 'ghost') {
this.alpha = 1 - Math.min(Math.max(+value || 0, 0), 100) / 100;
- this.changed();
+ } else {
+ this.graphicsValues[eff] = value;
}
+ this.drawNew();
+ this.changed();
};
SpriteMorph.prototype.getGhostEffect = function () {
@@ -2633,10 +2999,18 @@ SpriteMorph.prototype.changeEffect = function (effect, value) {
var eff = effect instanceof Array ? effect[0] : null;
if (eff === 'ghost') {
this.setEffect(effect, this.getGhostEffect() + (+value || 0));
+ } else {
+ this.setEffect(effect, this.graphicsValues[eff] + value);
}
};
SpriteMorph.prototype.clearEffects = function () {
+ var effect;
+ for (effect in this.graphicsValues) {
+ if (this.graphicsValues.hasOwnProperty(effect)) {
+ this.setEffect([effect], 0);
+ }
+ }
this.setEffect(['ghost'], 0);
};
@@ -2845,11 +3219,12 @@ SpriteMorph.prototype.forward = function (steps) {
SpriteMorph.prototype.setHeading = function (degrees) {
var x = this.xPosition(),
y = this.yPosition(),
- turn = degrees - this.heading;
+ dir = (+degrees || 0),
+ turn = dir - this.heading;
// apply to myself
this.changed();
- SpriteMorph.uber.setHeading.call(this, degrees);
+ SpriteMorph.uber.setHeading.call(this, dir);
this.silentGotoXY(x, y, true); // just me
this.positionTalkBubble();
@@ -3832,12 +4207,24 @@ StageMorph.prototype.init = function (globals) {
this.keysPressed = {}; // for handling keyboard events, do not persist
this.blocksCache = {}; // not to be serialized (!)
this.paletteCache = {}; // not to be serialized (!)
- this.lastAnswer = null; // last user input, do not persist
+ this.lastAnswer = ''; // last user input, do not persist
this.activeSounds = []; // do not persist
this.trailsCanvas = null;
this.isThreadSafe = false;
+ this.graphicsValues = { 'negative': 0,
+ 'fisheye': 0,
+ 'whirl': 0,
+ 'pixelate': 0,
+ 'mosaic': 0,
+ 'brightness': 0,
+ 'color': 0,
+ 'comic': 0,
+ 'duplicate': 0,
+ 'confetti': 0
+ };
+
StageMorph.uber.init.call(this);
this.acceptsDrops = false;
@@ -3904,6 +4291,7 @@ StageMorph.prototype.drawNew = function () {
(this.width() / this.scale - this.costume.width()) / 2,
(this.height() / this.scale - this.costume.height()) / 2
);
+ this.image = this.applyGraphicsEffects(this.image);
}
};
@@ -4228,6 +4616,9 @@ StageMorph.prototype.processKeyEvent = function (event, action) {
break;
default:
keyName = String.fromCharCode(event.keyCode || event.charCode);
+ if (event.ctrlKey || event.metaKey) {
+ keyName = 'ctrl ' + (event.shiftKey ? 'shift ' : '') + keyName;
+ }
}
action.call(this, keyName);
};
@@ -4242,6 +4633,18 @@ StageMorph.prototype.fireKeyEvent = function (key) {
if (evt === 'ctrl enter') {
return this.fireGreenFlagEvent();
}
+ if (evt === 'ctrl f') {
+ return this.parentThatIsA(IDE_Morph).currentSprite.searchBlocks();
+ }
+ if (evt === 'ctrl o') {
+ return this.parentThatIsA(IDE_Morph).openProjectsBrowser();
+ }
+ if (evt === 'ctrl s') {
+ return this.parentThatIsA(IDE_Morph).save();
+ }
+ if (evt === 'ctrl shift s') {
+ return this.parentThatIsA(IDE_Morph).saveProjectsBrowser();
+ }
if (evt === 'esc') {
return this.fireStopAllEvent();
}
@@ -4402,7 +4805,12 @@ StageMorph.prototype.blockTemplates = function (category) {
blocks.push(block('setEffect'));
blocks.push(block('clearEffects'));
blocks.push('-');
+<<<<<<< HEAD
blocks.push(block('doScreenshot'));
+=======
+ blocks.push(block('show'));
+ blocks.push(block('hide'));
+>>>>>>> master
// for debugging: ///////////////
@@ -4415,6 +4823,8 @@ StageMorph.prototype.blockTemplates = function (category) {
txt.setColor(this.paletteTextColor);
blocks.push(txt);
blocks.push('-');
+ blocks.push(block('reportCostumes'));
+ blocks.push('-');
blocks.push(block('log'));
blocks.push(block('alert'));
}
@@ -4436,6 +4846,20 @@ StageMorph.prototype.blockTemplates = function (category) {
blocks.push(watcherToggle('getTempo'));
blocks.push(block('getTempo'));
+ // for debugging: ///////////////
+
+ if (this.world().isDevMode) {
+ blocks.push('-');
+ txt = new TextMorph(localize(
+ 'development mode \ndebugging primitives:'
+ ));
+ txt.fontSize = 9;
+ txt.setColor(this.paletteTextColor);
+ blocks.push(txt);
+ blocks.push('-');
+ blocks.push(block('reportSounds'));
+ }
+
} else if (cat === 'pen') {
blocks.push(block('clear'));
@@ -4839,6 +5263,23 @@ StageMorph.prototype.thumbnail = function (extentPoint, excludedSprite) {
return trg;
};
+// StageMorph hiding and showing:
+
+/*
+ override the inherited behavior to recursively hide/show all
+ children.
+*/
+
+StageMorph.prototype.hide = function () {
+ this.isVisible = false;
+ this.changed();
+};
+
+StageMorph.prototype.show = function () {
+ this.isVisible = true;
+ this.changed();
+};
+
// StageMorph cloning overrice
StageMorph.prototype.createClone = nop;
@@ -4851,6 +5292,8 @@ StageMorph.prototype.paletteColor = SpriteMorph.prototype.paletteColor;
StageMorph.prototype.setName = SpriteMorph.prototype.setName;
StageMorph.prototype.palette = SpriteMorph.prototype.palette;
StageMorph.prototype.freshPalette = SpriteMorph.prototype.freshPalette;
+StageMorph.prototype.blocksMatching = SpriteMorph.prototype.blocksMatching;
+StageMorph.prototype.searchBlocks = SpriteMorph.prototype.searchBlocks;
StageMorph.prototype.showingWatcher = SpriteMorph.prototype.showingWatcher;
StageMorph.prototype.addVariable = SpriteMorph.prototype.addVariable;
StageMorph.prototype.deleteVariable = SpriteMorph.prototype.deleteVariable;
@@ -4900,8 +5343,17 @@ StageMorph.prototype.doWearPreviousCostume
StageMorph.prototype.doSwitchToCostume
= SpriteMorph.prototype.doSwitchToCostume;
+StageMorph.prototype.reportCostumes
+ = SpriteMorph.prototype.reportCostumes;
+
// StageMorph graphic effects
+StageMorph.prototype.graphicsChanged
+ = SpriteMorph.prototype.graphicsChanged;
+
+StageMorph.prototype.applyGraphicsEffects
+ = SpriteMorph.prototype.applyGraphicsEffects;
+
StageMorph.prototype.setEffect
= SpriteMorph.prototype.setEffect;
@@ -4941,6 +5393,9 @@ StageMorph.prototype.resumeAllActiveSounds = function () {
});
};
+StageMorph.prototype.reportSounds
+ = SpriteMorph.prototype.reportSounds;
+
// StageMorph non-variable watchers
StageMorph.prototype.toggleWatcher
@@ -5067,6 +5522,12 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data) {
contents.silentSetWidth(img.width);
contents.silentSetHeight(img.height);
contents.image = img;
+ } else if (data instanceof Costume) {
+ img = data.thumbnail(new Point(40, 40));
+ contents = new Morph();
+ contents.silentSetWidth(img.width);
+ contents.silentSetHeight(img.height);
+ contents.image = img;
} else if (data instanceof HTMLCanvasElement) {
contents = new Morph();
contents.silentSetWidth(data.width);
@@ -5909,6 +6370,12 @@ CellMorph.prototype.drawNew = function () {
this.contentsMorph.silentSetWidth(img.width);
this.contentsMorph.silentSetHeight(img.height);
this.contentsMorph.image = img;
+ } else if (this.contents instanceof Costume) {
+ img = this.contents.thumbnail(new Point(40, 40));
+ this.contentsMorph = new Morph();
+ this.contentsMorph.silentSetWidth(img.width);
+ this.contentsMorph.silentSetHeight(img.height);
+ this.contentsMorph.image = img;
} else if (this.contents instanceof List) {
if (this.isCircular()) {
this.contentsMorph = new TextMorph(
@@ -6220,9 +6687,11 @@ WatcherMorph.prototype.update = function () {
} else {
newValue = this.target[this.getter]();
}
- num = +newValue;
- if (typeof newValue !== 'boolean' && !isNaN(num)) {
- newValue = Math.round(newValue * 1000000000) / 1000000000;
+ if (newValue !== '' && !isNil(newValue)) {
+ num = +newValue;
+ if (typeof newValue !== 'boolean' && !isNaN(num)) {
+ newValue = Math.round(newValue * 1000000000) / 1000000000;
+ }
}
if (newValue !== this.currentValue) {
this.changed();
@@ -6442,7 +6911,17 @@ WatcherMorph.prototype.userMenu = function () {
inp.addEventListener(
"change",
function () {
- var file, i;
+ var file;
+
+ function txtOnlyMsg(ftype) {
+ ide.inform(
+ 'Unable to import',
+ 'Snap! can only import "text" files.\n' +
+ 'You selected a file of type "' +
+ ftype +
+ '".'
+ );
+ }
function readText(aFile) {
var frd = new FileReader();
@@ -6452,18 +6931,19 @@ WatcherMorph.prototype.userMenu = function () {
e.target.result
);
};
- frd.readAsText(aFile);
+
+ if (aFile.type.indexOf("text") === 0) {
+ frd.readAsText(aFile);
+ } else {
+ txtOnlyMsg(aFile.type);
+ }
}
document.body.removeChild(inp);
ide.filePicker = null;
if (inp.files.length > 0) {
- for (i = 0; i < inp.files.length; i += 1) {
- file = inp.files[i];
- if (file.type.indexOf("text") === 0) {
- readText(file);
- }
- }
+ file = inp.files[inp.files.length - 1];
+ readText(file);
}
},
false
@@ -6479,7 +6959,7 @@ WatcherMorph.prototype.userMenu = function () {
'export...',
function () {
window.open(
- 'data:text/plain,' +
+ 'data:text/plain;charset=utf-8,' +
encodeURIComponent(this.currentValue.toString())
);
}
diff --git a/paint.js b/paint.js
index e3a01af..7105b72 100644
--- a/paint.js
+++ b/paint.js
@@ -3,12 +3,12 @@
a paint editor for Snap!
inspired by the Scratch paint editor.
-
+
written by Kartik Chandra
Copyright (C) 2014 by Kartik Chandra
-
+
This file is part of Snap!.
-
+
Snap! is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of
@@ -52,6 +52,9 @@
September 16 - flood fill freeze fix (Kartik)
Jan 08 - mouse leave dragging fix (Kartik)
Feb 11 - dynamically adjust to stage dimensions (Jens)
+ Apr 30 - localizations (Manuel)
+ June 3 - transformations (Kartik)
+ June 4 - tweaks (Jens)
*/
@@ -65,7 +68,7 @@
// Global stuff ////////////////////////////////////////////////////////
-modules.paint = '2014-February-11';
+modules.paint = '2014-June-4';
// Declarations
@@ -110,10 +113,10 @@ PaintEditorMorph.prototype.buildContents = function () {
this.paper.setExtent(StageMorph.prototype.dimensions);
this.addBody(new AlignmentMorph('row', this.padding));
- this.controls = new AlignmentMorph('column', this.padding);
+ this.controls = new AlignmentMorph('column', this.padding / 2);
this.controls.alignment = 'left';
- this.edits = new AlignmentMorph('row', this.padding);
+ this.edits = new AlignmentMorph('row', this.padding / 2);
this.buildEdits();
this.controls.add(this.edits);
@@ -132,6 +135,10 @@ PaintEditorMorph.prototype.buildContents = function () {
this.buildToolbox();
this.controls.add(this.toolbox);
+ this.scaleBox = new AlignmentMorph('row', this.padding / 2);
+ this.buildScaleBox();
+ this.controls.add(this.scaleBox);
+
this.propertiesControls = {
colorpicker: null,
penSizeSlider: null,
@@ -217,6 +224,27 @@ PaintEditorMorph.prototype.buildEdits = function () {
this.edits.fixLayout();
};
+PaintEditorMorph.prototype.buildScaleBox = function () {
+ var paper = this.paper;
+ this.scaleBox.add(this.pushButton(
+ "grow",
+ function () {paper.scale(0.05, 0.05); }
+ ));
+ this.scaleBox.add(this.pushButton(
+ "shrink",
+ function () {paper.scale(-0.05, -0.05); }
+ ));
+ this.scaleBox.add(this.pushButton(
+ "flip ↔",
+ function () {paper.scale(-2, 0); }
+ ));
+ this.scaleBox.add(this.pushButton(
+ "flip ↕",
+ function () {paper.scale(0, -2); }
+ ));
+ this.scaleBox.fixLayout();
+};
+
PaintEditorMorph.prototype.openIn = function (world, oldim, oldrc, callback) {
// Open the editor in a world with an optional image to edit
this.oldim = oldim;
@@ -372,7 +400,7 @@ PaintEditorMorph.prototype.populatePropertiesMenu = function () {
c.add(pc.colorpicker);
//c.add(pc.primaryColorButton);
c.add(pc.primaryColorViewer);
- c.add(new TextMorph("Brush size"));
+ c.add(new TextMorph(localize("Brush size")));
c.add(alpen);
c.add(pc.constrain);
};
@@ -557,6 +585,26 @@ PaintCanvasMorph.prototype.init = function (shift) {
this.buildContents();
};
+PaintCanvasMorph.prototype.scale = function (x, y) {
+ this.mask = newCanvas(this.extent());
+ var c = newCanvas(this.extent());
+ c.getContext("2d").save();
+ c.getContext("2d").translate(
+ this.rotationCenter.x,
+ this.rotationCenter.y
+ );
+ c.getContext("2d").scale(1 + x, 1 + y);
+ c.getContext("2d").drawImage(
+ this.paper,
+ -this.rotationCenter.x,
+ -this.rotationCenter.y
+ );
+ c.getContext("2d").restore();
+ this.paper = c;
+ this.drawNew();
+ this.changed();
+};
+
PaintCanvasMorph.prototype.cacheUndo = function () {
var cachecan = newCanvas(this.extent());
this.merge(this.paper, cachecan);
diff --git a/snap.html b/snap.html
index 66604c5..904aba8 100755
--- a/snap.html
+++ b/snap.html
@@ -22,6 +22,7 @@
var world;
window.onload = function () {
world = new WorldMorph(document.getElementById('world'));
+ world.worldCanvas.focus();
new IDE_Morph().openIn(world);
setInterval(loop, 1);
};
diff --git a/store.js b/store.js
index b3f5d95..11e2757 100644
--- a/store.js
+++ b/store.js
@@ -61,7 +61,7 @@ SyntaxElementMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.store = '2014-February-13';
+modules.store = '2014-Jun-04';
// XML_Serializer ///////////////////////////////////////////////////////
@@ -457,8 +457,6 @@ SnapSerializer.prototype.loadProjectModel = function (xmlNode) {
}
});
- this.objects = {};
-
/* Global Variables */
if (model.globalVariables) {
@@ -468,6 +466,8 @@ SnapSerializer.prototype.loadProjectModel = function (xmlNode) {
);
}
+ this.objects = {};
+
/* Watchers */
model.sprites.childrenNamed('watcher').forEach(function (model) {
@@ -521,7 +521,7 @@ SnapSerializer.prototype.loadProjectModel = function (xmlNode) {
))
);
project.stage.add(watcher);
- watcher.update();
+ watcher.onNextStep = function () {this.currentValue = null; };
// set watcher's contentsMorph's extent if it is showing a list and
// its monitor dimensions are given
@@ -1032,7 +1032,7 @@ SnapSerializer.prototype.loadInput = function (model, input, block) {
input.setColor(this.loadColor(model.contents));
} else {
val = this.loadValue(model);
- if (val) {
+ if (!isNil(val) && input.setContents) {
input.setContents(this.loadValue(model));
}
}
@@ -1302,6 +1302,12 @@ SnapSerializer.prototype.openProject = function (project, ide) {
ide.createCorral();
ide.selectSprite(sprite);
ide.fixLayout();
+
+ // force watchers to update
+ //project.stage.watchers().forEach(function (watcher) {
+ // watcher.onNextStep = function () {this.currentValue = null;};
+ //})
+
ide.world().keyboardReceiver = project.stage;
};
diff --git a/threads.js b/threads.js
index 77632d0..d489441 100644
--- a/threads.js
+++ b/threads.js
@@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/
// Global stuff ////////////////////////////////////////////////////////
-modules.threads = '2014-Feb-10';
+modules.threads = '2014-Jun-05';
var ThreadManager;
var Process;
@@ -1482,10 +1482,10 @@ Process.prototype.doSetFastTracking = function (bool) {
if (this.homeContext.receiver) {
ide = this.homeContext.receiver.parentThatIsA(IDE_Morph);
if (ide) {
- if (ide.stage.isFastTracked) {
- ide.stopFastTracking();
- } else {
+ if (bool) {
ide.startFastTracking();
+ } else {
+ ide.stopFastTracking();
}
}
}
@@ -3054,7 +3054,7 @@ VariableFrame.prototype.getVar = function (name, upvars) {
VariableFrame.prototype.addVar = function (name, value) {
this.vars[name] = (value === 0 ? 0
: value === false ? false
- : value === '' ? '' : value || null);
+ : value === '' ? '' : value || 0);
};
VariableFrame.prototype.deleteVar = function (name) {
@@ -3110,6 +3110,20 @@ VariableFrame.prototype.allNames = function () {
return answer;
};
+// Variable /////////////////////////////////////////////////////////////////
+
+function Variable(value) {
+ this.value = value;
+}
+
+Variable.prototype.toString = function () {
+ return 'a Variable [' + this.value + ']';
+};
+
+Variable.prototype.copy = function () {
+ return new Variable(this.value);
+};
+
// UpvarReference ///////////////////////////////////////////////////////////
// ... quasi-inherits some features from VariableFrame