summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Barksdale <amatus@amatus.name>2017-01-02 19:42:35 -0600
committerDavid Barksdale <amatus@amatus.name>2017-01-02 19:55:57 -0600
commitb31224a0a2c3145cf97de47b4f5616b27fe2b843 (patch)
treeffd5a33459b1f71a76a294060bcb9899878a9d01 /src
parent5578ec8cdbc0abbfa000c2cedef05d37313fe01b (diff)
Optimization works!
Diffstat (limited to 'src')
-rw-r--r--src/blockly/blocks/colour.js133
-rw-r--r--src/blockly/blocks/lists.js836
-rw-r--r--src/blockly/blocks/logic.js488
-rw-r--r--src/blockly/blocks/loops.js283
-rw-r--r--src/blockly/blocks/math.js553
-rw-r--r--src/blockly/blocks/procedures.js875
-rw-r--r--src/blockly/blocks/text.js685
-rw-r--r--src/blockly/blocks/variables.js100
-rw-r--r--src/blockly/core/events.js2
-rw-r--r--src/blockly/msg/messages.js1113
-rw-r--r--src/deps.cljs52
-rw-r--r--src/index.cljs.hl17
-rw-r--r--src/svg.ext.js10381
13 files changed, 15463 insertions, 55 deletions
diff --git a/src/blockly/blocks/colour.js b/src/blockly/blocks/colour.js
new file mode 100644
index 0000000..ceb9efc
--- /dev/null
+++ b/src/blockly/blocks/colour.js
@@ -0,0 +1,133 @@
+/**
+ * @license
+ * Visual Blocks Editor
+ *
+ * Copyright 2012 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Colour blocks for Blockly.
+ * @author fraser@google.com (Neil Fraser)
+ */
+'use strict';
+
+goog.provide('Blockly.Blocks.colour');
+
+goog.require('Blockly.Blocks');
+
+
+/**
+ * Common HSV hue for all blocks in this category.
+ */
+Blockly.Blocks.colour.HUE = 20;
+
+Blockly.Blocks['colour_picker'] = {
+ /**
+ * Block for colour picker.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": "%1",
+ "args0": [
+ {
+ "type": "field_colour",
+ "name": "COLOUR",
+ "colour": "#ff0000"
+ }
+ ],
+ "output": "Colour",
+ "colour": Blockly.Blocks.colour.HUE,
+ "helpUrl": Blockly.Msg.COLOUR_PICKER_HELPURL
+ });
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ // Colour block is trivial. Use tooltip of parent block if it exists.
+ this.setTooltip(function() {
+ var parent = thisBlock.getParent();
+ return (parent && parent.getInputsInline() && parent.tooltip) ||
+ Blockly.Msg.COLOUR_PICKER_TOOLTIP;
+ });
+ }
+};
+
+Blockly.Blocks['colour_random'] = {
+ /**
+ * Block for random colour.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.COLOUR_RANDOM_TITLE,
+ "output": "Colour",
+ "colour": Blockly.Blocks.colour.HUE,
+ "tooltip": Blockly.Msg.COLOUR_RANDOM_TOOLTIP,
+ "helpUrl": Blockly.Msg.COLOUR_RANDOM_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['colour_rgb'] = {
+ /**
+ * Block for composing a colour from RGB components.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setHelpUrl(Blockly.Msg.COLOUR_RGB_HELPURL);
+ this.setColour(Blockly.Blocks.colour.HUE);
+ this.appendValueInput('RED')
+ .setCheck('Number')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .appendField(Blockly.Msg.COLOUR_RGB_TITLE)
+ .appendField(Blockly.Msg.COLOUR_RGB_RED);
+ this.appendValueInput('GREEN')
+ .setCheck('Number')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .appendField(Blockly.Msg.COLOUR_RGB_GREEN);
+ this.appendValueInput('BLUE')
+ .setCheck('Number')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .appendField(Blockly.Msg.COLOUR_RGB_BLUE);
+ this.setOutput(true, 'Colour');
+ this.setTooltip(Blockly.Msg.COLOUR_RGB_TOOLTIP);
+ }
+};
+
+Blockly.Blocks['colour_blend'] = {
+ /**
+ * Block for blending two colours together.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setHelpUrl(Blockly.Msg.COLOUR_BLEND_HELPURL);
+ this.setColour(Blockly.Blocks.colour.HUE);
+ this.appendValueInput('COLOUR1')
+ .setCheck('Colour')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .appendField(Blockly.Msg.COLOUR_BLEND_TITLE)
+ .appendField(Blockly.Msg.COLOUR_BLEND_COLOUR1);
+ this.appendValueInput('COLOUR2')
+ .setCheck('Colour')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .appendField(Blockly.Msg.COLOUR_BLEND_COLOUR2);
+ this.appendValueInput('RATIO')
+ .setCheck('Number')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .appendField(Blockly.Msg.COLOUR_BLEND_RATIO);
+ this.setOutput(true, 'Colour');
+ this.setTooltip(Blockly.Msg.COLOUR_BLEND_TOOLTIP);
+ }
+};
diff --git a/src/blockly/blocks/lists.js b/src/blockly/blocks/lists.js
new file mode 100644
index 0000000..55dfac0
--- /dev/null
+++ b/src/blockly/blocks/lists.js
@@ -0,0 +1,836 @@
+/**
+ * @license
+ * Visual Blocks Editor
+ *
+ * Copyright 2012 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview List blocks for Blockly.
+ * @author fraser@google.com (Neil Fraser)
+ */
+'use strict';
+
+goog.provide('Blockly.Blocks.lists');
+
+goog.require('Blockly.Blocks');
+
+
+/**
+ * Common HSV hue for all blocks in this category.
+ */
+Blockly.Blocks.lists.HUE = 260;
+
+Blockly.Blocks['lists_create_empty'] = {
+ /**
+ * Block for creating an empty list.
+ * The 'list_create_with' block is preferred as it is more flexible.
+ * <block type="lists_create_with">
+ * <mutation items="0"></mutation>
+ * </block>
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.LISTS_CREATE_EMPTY_TITLE,
+ "output": "Array",
+ "colour": Blockly.Blocks.lists.HUE,
+ "tooltip": Blockly.Msg.LISTS_CREATE_EMPTY_TOOLTIP,
+ "helpUrl": Blockly.Msg.LISTS_CREATE_EMPTY_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['lists_create_with'] = {
+ /**
+ * Block for creating a list with any number of elements of any type.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setHelpUrl(Blockly.Msg.LISTS_CREATE_WITH_HELPURL);
+ this.setColour(Blockly.Blocks.lists.HUE);
+ this.itemCount_ = 3;
+ this.updateShape_();
+ this.setOutput(true, 'Array');
+ this.setMutator(new Blockly.Mutator(['lists_create_with_item']));
+ this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP);
+ },
+ /**
+ * Create XML to represent list inputs.
+ * @return {!Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ container.setAttribute('items', this.itemCount_);
+ return container;
+ },
+ /**
+ * Parse XML to restore the list inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
+ this.updateShape_();
+ },
+ /**
+ * Populate the mutator's dialog with this block's components.
+ * @param {!Blockly.Workspace} workspace Mutator's workspace.
+ * @return {!Blockly.Block} Root block in mutator.
+ * @this Blockly.Block
+ */
+ decompose: function(workspace) {
+ var containerBlock = workspace.newBlock('lists_create_with_container');
+ containerBlock.initSvg();
+ var connection = containerBlock.getInput('STACK').connection;
+ for (var i = 0; i < this.itemCount_; i++) {
+ var itemBlock = workspace.newBlock('lists_create_with_item');
+ itemBlock.initSvg();
+ connection.connect(itemBlock.previousConnection);
+ connection = itemBlock.nextConnection;
+ }
+ return containerBlock;
+ },
+ /**
+ * Reconfigure this block based on the mutator dialog's components.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ compose: function(containerBlock) {
+ var itemBlock = containerBlock.getInputTargetBlock('STACK');
+ // Count number of inputs.
+ var connections = [];
+ while (itemBlock) {
+ connections.push(itemBlock.valueConnection_);
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ }
+ // Disconnect any children that don't belong.
+ for (var i = 0; i < this.itemCount_; i++) {
+ var connection = this.getInput('ADD' + i).connection.targetConnection;
+ if (connection && connections.indexOf(connection) == -1) {
+ connection.disconnect();
+ }
+ }
+ this.itemCount_ = connections.length;
+ this.updateShape_();
+ // Reconnect any child blocks.
+ for (var i = 0; i < this.itemCount_; i++) {
+ Blockly.Mutator.reconnect(connections[i], this, 'ADD' + i);
+ }
+ },
+ /**
+ * Store pointers to any connected child blocks.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ saveConnections: function(containerBlock) {
+ var itemBlock = containerBlock.getInputTargetBlock('STACK');
+ var i = 0;
+ while (itemBlock) {
+ var input = this.getInput('ADD' + i);
+ itemBlock.valueConnection_ = input && input.connection.targetConnection;
+ i++;
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ }
+ },
+ /**
+ * Modify this block to have the correct number of inputs.
+ * @private
+ * @this Blockly.Block
+ */
+ updateShape_: function() {
+ if (this.itemCount_ && this.getInput('EMPTY')) {
+ this.removeInput('EMPTY');
+ } else if (!this.itemCount_ && !this.getInput('EMPTY')) {
+ this.appendDummyInput('EMPTY')
+ .appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE);
+ }
+ // Add new inputs.
+ for (var i = 0; i < this.itemCount_; i++) {
+ if (!this.getInput('ADD' + i)) {
+ var input = this.appendValueInput('ADD' + i);
+ if (i == 0) {
+ input.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH);
+ }
+ }
+ }
+ // Remove deleted inputs.
+ while (this.getInput('ADD' + i)) {
+ this.removeInput('ADD' + i);
+ i++;
+ }
+ }
+};
+
+Blockly.Blocks['lists_create_with_container'] = {
+ /**
+ * Mutator block for list container.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setColour(Blockly.Blocks.lists.HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD);
+ this.appendStatementInput('STACK');
+ this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+Blockly.Blocks['lists_create_with_item'] = {
+ /**
+ * Mutator bolck for adding items.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setColour(Blockly.Blocks.lists.HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+Blockly.Blocks['lists_repeat'] = {
+ /**
+ * Block for creating a list with one element repeated.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.LISTS_REPEAT_TITLE,
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "ITEM"
+ },
+ {
+ "type": "input_value",
+ "name": "NUM",
+ "check": "Number"
+ }
+ ],
+ "output": "Array",
+ "colour": Blockly.Blocks.lists.HUE,
+ "tooltip": Blockly.Msg.LISTS_REPEAT_TOOLTIP,
+ "helpUrl": Blockly.Msg.LISTS_REPEAT_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['lists_length'] = {
+ /**
+ * Block for list length.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.LISTS_LENGTH_TITLE,
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "VALUE",
+ "check": ['String', 'Array']
+ }
+ ],
+ "output": 'Number',
+ "colour": Blockly.Blocks.lists.HUE,
+ "tooltip": Blockly.Msg.LISTS_LENGTH_TOOLTIP,
+ "helpUrl": Blockly.Msg.LISTS_LENGTH_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['lists_isEmpty'] = {
+ /**
+ * Block for is the list empty?
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.LISTS_ISEMPTY_TITLE,
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "VALUE",
+ "check": ['String', 'Array']
+ }
+ ],
+ "output": 'Boolean',
+ "colour": Blockly.Blocks.lists.HUE,
+ "tooltip": Blockly.Msg.LISTS_ISEMPTY_TOOLTIP,
+ "helpUrl": Blockly.Msg.LISTS_ISEMPTY_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['lists_indexOf'] = {
+ /**
+ * Block for finding an item in the list.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var OPERATORS =
+ [[Blockly.Msg.LISTS_INDEX_OF_FIRST, 'FIRST'],
+ [Blockly.Msg.LISTS_INDEX_OF_LAST, 'LAST']];
+ this.setHelpUrl(Blockly.Msg.LISTS_INDEX_OF_HELPURL);
+ this.setColour(Blockly.Blocks.lists.HUE);
+ this.setOutput(true, 'Number');
+ this.appendValueInput('VALUE')
+ .setCheck('Array')
+ .appendField(Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST);
+ this.appendValueInput('FIND')
+ .appendField(new Blockly.FieldDropdown(OPERATORS), 'END');
+ this.setInputsInline(true);
+ var tooltip = Blockly.Msg.LISTS_INDEX_OF_TOOLTIP
+ .replace('%1', Blockly.Blocks.ONE_BASED_INDEXING ? '0' : '-1');
+ this.setTooltip(tooltip);
+ }
+};
+
+Blockly.Blocks['lists_getIndex'] = {
+ /**
+ * Block for getting element at index.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var MODE =
+ [[Blockly.Msg.LISTS_GET_INDEX_GET, 'GET'],
+ [Blockly.Msg.LISTS_GET_INDEX_GET_REMOVE, 'GET_REMOVE'],
+ [Blockly.Msg.LISTS_GET_INDEX_REMOVE, 'REMOVE']];
+ this.WHERE_OPTIONS =
+ [[Blockly.Msg.LISTS_GET_INDEX_FROM_START, 'FROM_START'],
+ [Blockly.Msg.LISTS_GET_INDEX_FROM_END, 'FROM_END'],
+ [Blockly.Msg.LISTS_GET_INDEX_FIRST, 'FIRST'],
+ [Blockly.Msg.LISTS_GET_INDEX_LAST, 'LAST'],
+ [Blockly.Msg.LISTS_GET_INDEX_RANDOM, 'RANDOM']];
+ this.setHelpUrl(Blockly.Msg.LISTS_GET_INDEX_HELPURL);
+ this.setColour(Blockly.Blocks.lists.HUE);
+ var modeMenu = new Blockly.FieldDropdown(MODE, function(value) {
+ var isStatement = (value == 'REMOVE');
+ this.sourceBlock_.updateStatement_(isStatement);
+ });
+ this.appendValueInput('VALUE')
+ .setCheck('Array')
+ .appendField(Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST);
+ this.appendDummyInput()
+ .appendField(modeMenu, 'MODE')
+ .appendField('', 'SPACE');
+ this.appendDummyInput('AT');
+ if (Blockly.Msg.LISTS_GET_INDEX_TAIL) {
+ this.appendDummyInput('TAIL')
+ .appendField(Blockly.Msg.LISTS_GET_INDEX_TAIL);
+ }
+ this.setInputsInline(true);
+ this.setOutput(true);
+ this.updateAt_(true);
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ var mode = thisBlock.getFieldValue('MODE');
+ var where = thisBlock.getFieldValue('WHERE');
+ var tooltip = '';
+ switch (mode + ' ' + where) {
+ case 'GET FROM_START':
+ case 'GET FROM_END':
+ tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM;
+ break;
+ case 'GET FIRST':
+ tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FIRST;
+ break;
+ case 'GET LAST':
+ tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_LAST;
+ break;
+ case 'GET RANDOM':
+ tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM;
+ break;
+ case 'GET_REMOVE FROM_START':
+ case 'GET_REMOVE FROM_END':
+ tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM;
+ break;
+ case 'GET_REMOVE FIRST':
+ tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST;
+ break;
+ case 'GET_REMOVE LAST':
+ tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST;
+ break;
+ case 'GET_REMOVE RANDOM':
+ tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM;
+ break;
+ case 'REMOVE FROM_START':
+ case 'REMOVE FROM_END':
+ tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM;
+ break;
+ case 'REMOVE FIRST':
+ tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST;
+ break;
+ case 'REMOVE LAST':
+ tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST;
+ break;
+ case 'REMOVE RANDOM':
+ tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM;
+ break;
+ }
+ if (where == 'FROM_START' || where == 'FROM_END') {
+ tooltip += ' ' + Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP
+ .replace('%1', Blockly.Blocks.ONE_BASED_INDEXING ? '#1' : '#0');
+ }
+ return tooltip;
+ });
+ },
+ /**
+ * Create XML to represent whether the block is a statement or a value.
+ * Also represent whether there is an 'AT' input.
+ * @return {Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ var isStatement = !this.outputConnection;
+ container.setAttribute('statement', isStatement);
+ var isAt = this.getInput('AT').type == Blockly.INPUT_VALUE;
+ container.setAttribute('at', isAt);
+ return container;
+ },
+ /**
+ * Parse XML to restore the 'AT' input.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ // Note: Until January 2013 this block did not have mutations,
+ // so 'statement' defaults to false and 'at' defaults to true.
+ var isStatement = (xmlElement.getAttribute('statement') == 'true');
+ this.updateStatement_(isStatement);
+ var isAt = (xmlElement.getAttribute('at') != 'false');
+ this.updateAt_(isAt);
+ },
+ /**
+ * Switch between a value block and a statement block.
+ * @param {boolean} newStatement True if the block should be a statement.
+ * False if the block should be a value.
+ * @private
+ * @this Blockly.Block
+ */
+ updateStatement_: function(newStatement) {
+ var oldStatement = !this.outputConnection;
+ if (newStatement != oldStatement) {
+ this.unplug(true, true);
+ if (newStatement) {
+ this.setOutput(false);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ } else {
+ this.setPreviousStatement(false);
+ this.setNextStatement(false);
+ this.setOutput(true);
+ }
+ }
+ },
+ /**
+ * Create or delete an input for the numeric index.
+ * @param {boolean} isAt True if the input should exist.
+ * @private
+ * @this Blockly.Block
+ */
+ updateAt_: function(isAt) {
+ // Destroy old 'AT' and 'ORDINAL' inputs.
+ this.removeInput('AT');
+ this.removeInput('ORDINAL', true);
+ // Create either a value 'AT' input or a dummy input.
+ if (isAt) {
+ this.appendValueInput('AT').setCheck('Number');
+ if (Blockly.Msg.ORDINAL_NUMBER_SUFFIX) {
+ this.appendDummyInput('ORDINAL')
+ .appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX);
+ }
+ } else {
+ this.appendDummyInput('AT');
+ }
+ var menu = new Blockly.FieldDropdown(this.WHERE_OPTIONS, function(value) {
+ var newAt = (value == 'FROM_START') || (value == 'FROM_END');
+ // The 'isAt' variable is available due to this function being a closure.
+ if (newAt != isAt) {
+ var block = this.sourceBlock_;
+ block.updateAt_(newAt);
+ // This menu has been destroyed and replaced. Update the replacement.
+ block.setFieldValue(value, 'WHERE');
+ return null;
+ }
+ return undefined;
+ });
+ this.getInput('AT').appendField(menu, 'WHERE');
+ if (Blockly.Msg.LISTS_GET_INDEX_TAIL) {
+ this.moveInputBefore('TAIL', null);
+ }
+ }
+};
+
+Blockly.Blocks['lists_setIndex'] = {
+ /**
+ * Block for setting the element at index.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var MODE =
+ [[Blockly.Msg.LISTS_SET_INDEX_SET, 'SET'],
+ [Blockly.Msg.LISTS_SET_INDEX_INSERT, 'INSERT']];
+ this.WHERE_OPTIONS =
+ [[Blockly.Msg.LISTS_GET_INDEX_FROM_START, 'FROM_START'],
+ [Blockly.Msg.LISTS_GET_INDEX_FROM_END, 'FROM_END'],
+ [Blockly.Msg.LISTS_GET_INDEX_FIRST, 'FIRST'],
+ [Blockly.Msg.LISTS_GET_INDEX_LAST, 'LAST'],
+ [Blockly.Msg.LISTS_GET_INDEX_RANDOM, 'RANDOM']];
+ this.setHelpUrl(Blockly.Msg.LISTS_SET_INDEX_HELPURL);
+ this.setColour(Blockly.Blocks.lists.HUE);
+ this.appendValueInput('LIST')
+ .setCheck('Array')
+ .appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(MODE), 'MODE')
+ .appendField('', 'SPACE');
+ this.appendDummyInput('AT');
+ this.appendValueInput('TO')
+ .appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_TO);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.LISTS_SET_INDEX_TOOLTIP);
+ this.updateAt_(true);
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ var mode = thisBlock.getFieldValue('MODE');
+ var where = thisBlock.getFieldValue('WHERE');
+ var tooltip = '';
+ switch (mode + ' ' + where) {
+ case 'SET FROM_START':
+ case 'SET FROM_END':
+ tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM;
+ break;
+ case 'SET FIRST':
+ tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FIRST;
+ break;
+ case 'SET LAST':
+ tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST;
+ break;
+ case 'SET RANDOM':
+ tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM;
+ break;
+ case 'INSERT FROM_START':
+ case 'INSERT FROM_END':
+ tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM;
+ break;
+ case 'INSERT FIRST':
+ tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST;
+ break;
+ case 'INSERT LAST':
+ tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_LAST;
+ break;
+ case 'INSERT RANDOM':
+ tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM;
+ break;
+ }
+ if (where == 'FROM_START' || where == 'FROM_END') {
+ tooltip += ' ' + Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP
+ .replace('%1', Blockly.Blocks.ONE_BASED_INDEXING ? '#1' : '#0');
+ }
+ return tooltip;
+ });
+ },
+ /**
+ * Create XML to represent whether there is an 'AT' input.
+ * @return {Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ var isAt = this.getInput('AT').type == Blockly.INPUT_VALUE;
+ container.setAttribute('at', isAt);
+ return container;
+ },
+ /**
+ * Parse XML to restore the 'AT' input.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ // Note: Until January 2013 this block did not have mutations,
+ // so 'at' defaults to true.
+ var isAt = (xmlElement.getAttribute('at') != 'false');
+ this.updateAt_(isAt);
+ },
+ /**
+ * Create or delete an input for the numeric index.
+ * @param {boolean} isAt True if the input should exist.
+ * @private
+ * @this Blockly.Block
+ */
+ updateAt_: function(isAt) {
+ // Destroy old 'AT' and 'ORDINAL' input.
+ this.removeInput('AT');
+ this.removeInput('ORDINAL', true);
+ // Create either a value 'AT' input or a dummy input.
+ if (isAt) {
+ this.appendValueInput('AT').setCheck('Number');
+ if (Blockly.Msg.ORDINAL_NUMBER_SUFFIX) {
+ this.appendDummyInput('ORDINAL')
+ .appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX);
+ }
+ } else {
+ this.appendDummyInput('AT');
+ }
+ var menu = new Blockly.FieldDropdown(this.WHERE_OPTIONS, function(value) {
+ var newAt = (value == 'FROM_START') || (value == 'FROM_END');
+ // The 'isAt' variable is available due to this function being a closure.
+ if (newAt != isAt) {
+ var block = this.sourceBlock_;
+ block.updateAt_(newAt);
+ // This menu has been destroyed and replaced. Update the replacement.
+ block.setFieldValue(value, 'WHERE');
+ return null;
+ }
+ return undefined;
+ });
+ this.moveInputBefore('AT', 'TO');
+ if (this.getInput('ORDINAL')) {
+ this.moveInputBefore('ORDINAL', 'TO');
+ }
+
+ this.getInput('AT').appendField(menu, 'WHERE');
+ }
+};
+
+Blockly.Blocks['lists_getSublist'] = {
+ /**
+ * Block for getting sublist.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this['WHERE_OPTIONS_1'] =
+ [[Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_START, 'FROM_START'],
+ [Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_END, 'FROM_END'],
+ [Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST, 'FIRST']];
+ this['WHERE_OPTIONS_2'] =
+ [[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START, 'FROM_START'],
+ [Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END, 'FROM_END'],
+ [Blockly.Msg.LISTS_GET_SUBLIST_END_LAST, 'LAST']];
+ this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);
+ this.setColour(Blockly.Blocks.lists.HUE);
+ this.appendValueInput('LIST')
+ .setCheck('Array')
+ .appendField(Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST);
+ this.appendDummyInput('AT1');
+ this.appendDummyInput('AT2');
+ if (Blockly.Msg.LISTS_GET_SUBLIST_TAIL) {
+ this.appendDummyInput('TAIL')
+ .appendField(Blockly.Msg.LISTS_GET_SUBLIST_TAIL);
+ }
+ this.setInputsInline(true);
+ this.setOutput(true, 'Array');
+ this.updateAt_(1, true);
+ this.updateAt_(2, true);
+ this.setTooltip(Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP);
+ },
+ /**
+ * Create XML to represent whether there are 'AT' inputs.
+ * @return {Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ var isAt1 = this.getInput('AT1').type == Blockly.INPUT_VALUE;
+ container.setAttribute('at1', isAt1);
+ var isAt2 = this.getInput('AT2').type == Blockly.INPUT_VALUE;
+ container.setAttribute('at2', isAt2);
+ return container;
+ },
+ /**
+ * Parse XML to restore the 'AT' inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ var isAt1 = (xmlElement.getAttribute('at1') == 'true');
+ var isAt2 = (xmlElement.getAttribute('at2') == 'true');
+ this.updateAt_(1, isAt1);
+ this.updateAt_(2, isAt2);
+ },
+ /**
+ * Create or delete an input for a numeric index.
+ * This block has two such inputs, independant of each other.
+ * @param {number} n Specify first or second input (1 or 2).
+ * @param {boolean} isAt True if the input should exist.
+ * @private
+ * @this Blockly.Block
+ */
+ updateAt_: function(n, isAt) {
+ // Create or delete an input for the numeric index.
+ // Destroy old 'AT' and 'ORDINAL' inputs.
+ this.removeInput('AT' + n);
+ this.removeInput('ORDINAL' + n, true);
+ // Create either a value 'AT' input or a dummy input.
+ if (isAt) {
+ this.appendValueInput('AT' + n).setCheck('Number');
+ if (Blockly.Msg.ORDINAL_NUMBER_SUFFIX) {
+ this.appendDummyInput('ORDINAL' + n)
+ .appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX);
+ }
+ } else {
+ this.appendDummyInput('AT' + n);
+ }
+ var menu = new Blockly.FieldDropdown(this['WHERE_OPTIONS_' + n],
+ function(value) {
+ var newAt = (value == 'FROM_START') || (value == 'FROM_END');
+ // The 'isAt' variable is available due to this function being a
+ // closure.
+ if (newAt != isAt) {
+ var block = this.sourceBlock_;
+ block.updateAt_(n, newAt);
+ // This menu has been destroyed and replaced.
+ // Update the replacement.
+ block.setFieldValue(value, 'WHERE' + n);
+ return null;
+ }
+ return undefined;
+ });
+ this.getInput('AT' + n)
+ .appendField(menu, 'WHERE' + n);
+ if (n == 1) {
+ this.moveInputBefore('AT1', 'AT2');
+ if (this.getInput('ORDINAL1')) {
+ this.moveInputBefore('ORDINAL1', 'AT2');
+ }
+ }
+ if (Blockly.Msg.LISTS_GET_SUBLIST_TAIL) {
+ this.moveInputBefore('TAIL', null);
+ }
+ }
+};
+
+Blockly.Blocks['lists_sort'] = {
+ /**
+ * Block for sorting a list.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.LISTS_SORT_TITLE,
+ "args0": [
+ {
+ "type": "field_dropdown",
+ "name": "TYPE",
+ "options": [
+ [Blockly.Msg.LISTS_SORT_TYPE_NUMERIC, "NUMERIC"],
+ [Blockly.Msg.LISTS_SORT_TYPE_TEXT, "TEXT"],
+ [Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE, "IGNORE_CASE"]
+ ]
+ },
+ {
+ "type": "field_dropdown",
+ "name": "DIRECTION",
+ "options": [
+ [Blockly.Msg.LISTS_SORT_ORDER_ASCENDING, "1"],
+ [Blockly.Msg.LISTS_SORT_ORDER_DESCENDING, "-1"]
+ ]
+ },
+ {
+ "type": "input_value",
+ "name": "LIST",
+ "check": "Array"
+ }
+ ],
+ "output": "Array",
+ "colour": Blockly.Blocks.lists.HUE,
+ "tooltip": Blockly.Msg.LISTS_SORT_TOOLTIP,
+ "helpUrl": Blockly.Msg.LISTS_SORT_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['lists_split'] = {
+ /**
+ * Block for splitting text into a list, or joining a list into text.
+ * @this Blockly.Block
+ */
+ init: function() {
+ // Assign 'this' to a variable for use in the closures below.
+ var thisBlock = this;
+ var dropdown = new Blockly.FieldDropdown(
+ [[Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT, 'SPLIT'],
+ [Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST, 'JOIN']],
+ function(newMode) {
+ thisBlock.updateType_(newMode);
+ });
+ this.setHelpUrl(Blockly.Msg.LISTS_SPLIT_HELPURL);
+ this.setColour(Blockly.Blocks.lists.HUE);
+ this.appendValueInput('INPUT')
+ .setCheck('String')
+ .appendField(dropdown, 'MODE');
+ this.appendValueInput('DELIM')
+ .setCheck('String')
+ .appendField(Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER);
+ this.setInputsInline(true);
+ this.setOutput(true, 'Array');
+ this.setTooltip(function() {
+ var mode = thisBlock.getFieldValue('MODE');
+ if (mode == 'SPLIT') {
+ return Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT;
+ } else if (mode == 'JOIN') {
+ return Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN;
+ }
+ throw 'Unknown mode: ' + mode;
+ });
+ },
+ /**
+ * Modify this block to have the correct input and output types.
+ * @param {string} newMode Either 'SPLIT' or 'JOIN'.
+ * @private
+ * @this Blockly.Block
+ */
+ updateType_: function(newMode) {
+ if (newMode == 'SPLIT') {
+ this.outputConnection.setCheck('Array');
+ this.getInput('INPUT').setCheck('String');
+ } else {
+ this.outputConnection.setCheck('String');
+ this.getInput('INPUT').setCheck('Array');
+ }
+ },
+ /**
+ * Create XML to represent the input and output types.
+ * @return {!Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ container.setAttribute('mode', this.getFieldValue('MODE'));
+ return container;
+ },
+ /**
+ * Parse XML to restore the input and output types.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ this.updateType_(xmlElement.getAttribute('mode'));
+ }
+};
diff --git a/src/blockly/blocks/logic.js b/src/blockly/blocks/logic.js
new file mode 100644
index 0000000..57af601
--- /dev/null
+++ b/src/blockly/blocks/logic.js
@@ -0,0 +1,488 @@
+/**
+ * @license
+ * Visual Blocks Editor
+ *
+ * Copyright 2012 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Logic blocks for Blockly.
+ * @author q.neutron@gmail.com (Quynh Neutron)
+ */
+'use strict';
+
+goog.provide('Blockly.Blocks.logic');
+
+goog.require('Blockly.Blocks');
+
+
+/**
+ * Common HSV hue for all blocks in this category.
+ */
+Blockly.Blocks.logic.HUE = 210;
+
+Blockly.Blocks['controls_if'] = {
+ /**
+ * Block for if/elseif/else condition.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setHelpUrl(Blockly.Msg.CONTROLS_IF_HELPURL);
+ this.setColour(Blockly.Blocks.logic.HUE);
+ this.appendValueInput('IF0')
+ .setCheck('Boolean')
+ .appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);
+ this.appendStatementInput('DO0')
+ .appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setMutator(new Blockly.Mutator(['controls_if_elseif',
+ 'controls_if_else']));
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ if (!thisBlock.elseifCount_ && !thisBlock.elseCount_) {
+ return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;
+ } else if (!thisBlock.elseifCount_ && thisBlock.elseCount_) {
+ return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;
+ } else if (thisBlock.elseifCount_ && !thisBlock.elseCount_) {
+ return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;
+ } else if (thisBlock.elseifCount_ && thisBlock.elseCount_) {
+ return Blockly.Msg.CONTROLS_IF_TOOLTIP_4;
+ }
+ return '';
+ });
+ this.elseifCount_ = 0;
+ this.elseCount_ = 0;
+ },
+ /**
+ * Create XML to represent the number of else-if and else inputs.
+ * @return {Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ if (!this.elseifCount_ && !this.elseCount_) {
+ return null;
+ }
+ var container = document.createElement('mutation');
+ if (this.elseifCount_) {
+ container.setAttribute('elseif', this.elseifCount_);
+ }
+ if (this.elseCount_) {
+ container.setAttribute('else', 1);
+ }
+ return container;
+ },
+ /**
+ * Parse XML to restore the else-if and else inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ this.elseifCount_ = parseInt(xmlElement.getAttribute('elseif'), 10) || 0;
+ this.elseCount_ = parseInt(xmlElement.getAttribute('else'), 10) || 0;
+ this.updateShape_();
+ },
+ /**
+ * Populate the mutator's dialog with this block's components.
+ * @param {!Blockly.Workspace} workspace Mutator's workspace.
+ * @return {!Blockly.Block} Root block in mutator.
+ * @this Blockly.Block
+ */
+ decompose: function(workspace) {
+ var containerBlock = workspace.newBlock('controls_if_if');
+ containerBlock.initSvg();
+ var connection = containerBlock.nextConnection;
+ for (var i = 1; i <= this.elseifCount_; i++) {
+ var elseifBlock = workspace.newBlock('controls_if_elseif');
+ elseifBlock.initSvg();
+ connection.connect(elseifBlock.previousConnection);
+ connection = elseifBlock.nextConnection;
+ }
+ if (this.elseCount_) {
+ var elseBlock = workspace.newBlock('controls_if_else');
+ elseBlock.initSvg();
+ connection.connect(elseBlock.previousConnection);
+ }
+ return containerBlock;
+ },
+ /**
+ * Reconfigure this block based on the mutator dialog's components.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ compose: function(containerBlock) {
+ var clauseBlock = containerBlock.nextConnection.targetBlock();
+ // Count number of inputs.
+ this.elseifCount_ = 0;
+ this.elseCount_ = 0;
+ var valueConnections = [null];
+ var statementConnections = [null];
+ var elseStatementConnection = null;
+ while (clauseBlock) {
+ switch (clauseBlock.type) {
+ case 'controls_if_elseif':
+ this.elseifCount_++;
+ valueConnections.push(clauseBlock.valueConnection_);
+ statementConnections.push(clauseBlock.statementConnection_);
+ break;
+ case 'controls_if_else':
+ this.elseCount_++;
+ elseStatementConnection = clauseBlock.statementConnection_;
+ break;
+ default:
+ throw 'Unknown block type.';
+ }
+ clauseBlock = clauseBlock.nextConnection &&
+ clauseBlock.nextConnection.targetBlock();
+ }
+ this.updateShape_();
+ // Reconnect any child blocks.
+ for (var i = 1; i <= this.elseifCount_; i++) {
+ Blockly.Mutator.reconnect(valueConnections[i], this, 'IF' + i);
+ Blockly.Mutator.reconnect(statementConnections[i], this, 'DO' + i);
+ }
+ Blockly.Mutator.reconnect(elseStatementConnection, this, 'ELSE');
+ },
+ /**
+ * Store pointers to any connected child blocks.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ saveConnections: function(containerBlock) {
+ var clauseBlock = containerBlock.nextConnection.targetBlock();
+ var i = 1;
+ while (clauseBlock) {
+ switch (clauseBlock.type) {
+ case 'controls_if_elseif':
+ var inputIf = this.getInput('IF' + i);
+ var inputDo = this.getInput('DO' + i);
+ clauseBlock.valueConnection_ =
+ inputIf && inputIf.connection.targetConnection;
+ clauseBlock.statementConnection_ =
+ inputDo && inputDo.connection.targetConnection;
+ i++;
+ break;
+ case 'controls_if_else':
+ var inputDo = this.getInput('ELSE');
+ clauseBlock.statementConnection_ =
+ inputDo && inputDo.connection.targetConnection;
+ break;
+ default:
+ throw 'Unknown block type.';
+ }
+ clauseBlock = clauseBlock.nextConnection &&
+ clauseBlock.nextConnection.targetBlock();
+ }
+ },
+ /**
+ * Modify this block to have the correct number of inputs.
+ * @private
+ * @this Blockly.Block
+ */
+ updateShape_: function() {
+ // Delete everything.
+ if (this.getInput('ELSE')) {
+ this.removeInput('ELSE');
+ }
+ var i = 1;
+ while (this.getInput('IF' + i)) {
+ this.removeInput('IF' + i);
+ this.removeInput('DO' + i);
+ i++;
+ }
+ // Rebuild block.
+ for (var i = 1; i <= this.elseifCount_; i++) {
+ this.appendValueInput('IF' + i)
+ .setCheck('Boolean')
+ .appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF);
+ this.appendStatementInput('DO' + i)
+ .appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
+ }
+ if (this.elseCount_) {
+ this.appendStatementInput('ELSE')
+ .appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE);
+ }
+ }
+};
+
+Blockly.Blocks['controls_if_if'] = {
+ /**
+ * Mutator block for if container.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setColour(Blockly.Blocks.logic.HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.CONTROLS_IF_IF_TITLE_IF);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.CONTROLS_IF_IF_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+Blockly.Blocks['controls_if_elseif'] = {
+ /**
+ * Mutator bolck for else-if condition.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setColour(Blockly.Blocks.logic.HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.CONTROLS_IF_ELSEIF_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+Blockly.Blocks['controls_if_else'] = {
+ /**
+ * Mutator block for else condition.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setColour(Blockly.Blocks.logic.HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE);
+ this.setPreviousStatement(true);
+ this.setTooltip(Blockly.Msg.CONTROLS_IF_ELSE_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+Blockly.Blocks['logic_compare'] = {
+ /**
+ * Block for comparison operator.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var rtlOperators = [
+ ['=', 'EQ'],
+ ['\u2260', 'NEQ'],
+ ['\u200F<\u200F', 'LT'],
+ ['\u200F\u2264\u200F', 'LTE'],
+ ['\u200F>\u200F', 'GT'],
+ ['\u200F\u2265\u200F', 'GTE']
+ ];
+ var ltrOperators = [
+ ['=', 'EQ'],
+ ['\u2260', 'NEQ'],
+ ['<', 'LT'],
+ ['\u2264', 'LTE'],
+ ['>', 'GT'],
+ ['\u2265', 'GTE']
+ ];
+ var OPERATORS = this.RTL ? rtlOperators : ltrOperators;
+ this.setHelpUrl(Blockly.Msg.LOGIC_COMPARE_HELPURL);
+ this.setColour(Blockly.Blocks.logic.HUE);
+ this.setOutput(true, 'Boolean');
+ this.appendValueInput('A');
+ this.appendValueInput('B')
+ .appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
+ this.setInputsInline(true);
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ var op = thisBlock.getFieldValue('OP');
+ var TOOLTIPS = {
+ 'EQ': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_EQ,
+ 'NEQ': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_NEQ,
+ 'LT': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LT,
+ 'LTE': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LTE,
+ 'GT': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GT,
+ 'GTE': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE
+ };
+ return TOOLTIPS[op];
+ });
+ this.prevBlocks_ = [null, null];
+ },
+ /**
+ * Called whenever anything on the workspace changes.
+ * Prevent mismatched types from being compared.
+ * @param {!Blockly.Events.Abstract} e Change event.
+ * @this Blockly.Block
+ */
+ onchange: function(e) {
+ var blockA = this.getInputTargetBlock('A');
+ var blockB = this.getInputTargetBlock('B');
+ // Disconnect blocks that existed prior to this change if they don't match.
+ if (blockA && blockB &&
+ !blockA.outputConnection.checkType_(blockB.outputConnection)) {
+ // Mismatch between two inputs. Disconnect previous and bump it away.
+ // Ensure that any disconnections are grouped with the causing event.
+ Blockly.Events.setGroup(e.group);
+ for (var i = 0; i < this.prevBlocks_.length; i++) {
+ var block = this.prevBlocks_[i];
+ if (block === blockA || block === blockB) {
+ block.unplug();
+ block.bumpNeighbours_();
+ }
+ }
+ Blockly.Events.setGroup(false);
+ }
+ this.prevBlocks_[0] = blockA;
+ this.prevBlocks_[1] = blockB;
+ }
+};
+
+Blockly.Blocks['logic_operation'] = {
+ /**
+ * Block for logical operations: 'and', 'or'.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var OPERATORS =
+ [[Blockly.Msg.LOGIC_OPERATION_AND, 'AND'],
+ [Blockly.Msg.LOGIC_OPERATION_OR, 'OR']];
+ this.setHelpUrl(Blockly.Msg.LOGIC_OPERATION_HELPURL);
+ this.setColour(Blockly.Blocks.logic.HUE);
+ this.setOutput(true, 'Boolean');
+ this.appendValueInput('A')
+ .setCheck('Boolean');
+ this.appendValueInput('B')
+ .setCheck('Boolean')
+ .appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
+ this.setInputsInline(true);
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ var op = thisBlock.getFieldValue('OP');
+ var TOOLTIPS = {
+ 'AND': Blockly.Msg.LOGIC_OPERATION_TOOLTIP_AND,
+ 'OR': Blockly.Msg.LOGIC_OPERATION_TOOLTIP_OR
+ };
+ return TOOLTIPS[op];
+ });
+ }
+};
+
+Blockly.Blocks['logic_negate'] = {
+ /**
+ * Block for negation.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.LOGIC_NEGATE_TITLE,
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "BOOL",
+ "check": "Boolean"
+ }
+ ],
+ "output": "Boolean",
+ "colour": Blockly.Blocks.logic.HUE,
+ "tooltip": Blockly.Msg.LOGIC_NEGATE_TOOLTIP,
+ "helpUrl": Blockly.Msg.LOGIC_NEGATE_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['logic_boolean'] = {
+ /**
+ * Block for boolean data type: true and false.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": "%1",
+ "args0": [
+ {
+ "type": "field_dropdown",
+ "name": "BOOL",
+ "options": [
+ [Blockly.Msg.LOGIC_BOOLEAN_TRUE, "TRUE"],
+ [Blockly.Msg.LOGIC_BOOLEAN_FALSE, "FALSE"]
+ ]
+ }
+ ],
+ "output": "Boolean",
+ "colour": Blockly.Blocks.logic.HUE,
+ "tooltip": Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP,
+ "helpUrl": Blockly.Msg.LOGIC_BOOLEAN_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['logic_null'] = {
+ /**
+ * Block for null data type.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.LOGIC_NULL,
+ "output": null,
+ "colour": Blockly.Blocks.logic.HUE,
+ "tooltip": Blockly.Msg.LOGIC_NULL_TOOLTIP,
+ "helpUrl": Blockly.Msg.LOGIC_NULL_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['logic_ternary'] = {
+ /**
+ * Block for ternary operator.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setHelpUrl(Blockly.Msg.LOGIC_TERNARY_HELPURL);
+ this.setColour(Blockly.Blocks.logic.HUE);
+ this.appendValueInput('IF')
+ .setCheck('Boolean')
+ .appendField(Blockly.Msg.LOGIC_TERNARY_CONDITION);
+ this.appendValueInput('THEN')
+ .appendField(Blockly.Msg.LOGIC_TERNARY_IF_TRUE);
+ this.appendValueInput('ELSE')
+ .appendField(Blockly.Msg.LOGIC_TERNARY_IF_FALSE);
+ this.setOutput(true);
+ this.setTooltip(Blockly.Msg.LOGIC_TERNARY_TOOLTIP);
+ this.prevParentConnection_ = null;
+ },
+ /**
+ * Called whenever anything on the workspace changes.
+ * Prevent mismatched types.
+ * @param {!Blockly.Events.Abstract} e Change event.
+ * @this Blockly.Block
+ */
+ onchange: function(e) {
+ var blockA = this.getInputTargetBlock('THEN');
+ var blockB = this.getInputTargetBlock('ELSE');
+ var parentConnection = this.outputConnection.targetConnection;
+ // Disconnect blocks that existed prior to this change if they don't match.
+ if ((blockA || blockB) && parentConnection) {
+ for (var i = 0; i < 2; i++) {
+ var block = (i == 1) ? blockA : blockB;
+ if (block && !block.outputConnection.checkType_(parentConnection)) {
+ // Ensure that any disconnections are grouped with the causing event.
+ Blockly.Events.setGroup(e.group);
+ if (parentConnection === this.prevParentConnection_) {
+ this.unplug();
+ parentConnection.getSourceBlock().bumpNeighbours_();
+ } else {
+ block.unplug();
+ block.bumpNeighbours_();
+ }
+ Blockly.Events.setGroup(false);
+ }
+ }
+ }
+ this.prevParentConnection_ = parentConnection;
+ }
+};
diff --git a/src/blockly/blocks/loops.js b/src/blockly/blocks/loops.js
new file mode 100644
index 0000000..b9bae1e
--- /dev/null
+++ b/src/blockly/blocks/loops.js
@@ -0,0 +1,283 @@
+/**
+ * @license
+ * Visual Blocks Editor
+ *
+ * Copyright 2012 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Loop blocks for Blockly.
+ * @author fraser@google.com (Neil Fraser)
+ */
+'use strict';
+
+goog.provide('Blockly.Blocks.loops');
+
+goog.require('Blockly.Blocks');
+
+
+/**
+ * Common HSV hue for all blocks in this category.
+ */
+Blockly.Blocks.loops.HUE = 120;
+
+Blockly.Blocks['controls_repeat_ext'] = {
+ /**
+ * Block for repeat n times (external number).
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.CONTROLS_REPEAT_TITLE,
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "TIMES",
+ "check": "Number"
+ }
+ ],
+ "previousStatement": null,
+ "nextStatement": null,
+ "colour": Blockly.Blocks.loops.HUE,
+ "tooltip": Blockly.Msg.CONTROLS_REPEAT_TOOLTIP,
+ "helpUrl": Blockly.Msg.CONTROLS_REPEAT_HELPURL
+ });
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.CONTROLS_REPEAT_INPUT_DO);
+ }
+};
+
+Blockly.Blocks['controls_repeat'] = {
+ /**
+ * Block for repeat n times (internal number).
+ * The 'controls_repeat_ext' block is preferred as it is more flexible.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.CONTROLS_REPEAT_TITLE,
+ "args0": [
+ {
+ "type": "field_number",
+ "name": "TIMES",
+ "value": 10,
+ "min": 0,
+ "precision": 1
+ }
+ ],
+ "previousStatement": null,
+ "nextStatement": null,
+ "colour": Blockly.Blocks.loops.HUE,
+ "tooltip": Blockly.Msg.CONTROLS_REPEAT_TOOLTIP,
+ "helpUrl": Blockly.Msg.CONTROLS_REPEAT_HELPURL
+ });
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.CONTROLS_REPEAT_INPUT_DO);
+ }
+};
+
+Blockly.Blocks['controls_whileUntil'] = {
+ /**
+ * Block for 'do while/until' loop.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var OPERATORS =
+ [[Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_WHILE, 'WHILE'],
+ [Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_UNTIL, 'UNTIL']];
+ this.setHelpUrl(Blockly.Msg.CONTROLS_WHILEUNTIL_HELPURL);
+ this.setColour(Blockly.Blocks.loops.HUE);
+ this.appendValueInput('BOOL')
+ .setCheck('Boolean')
+ .appendField(new Blockly.FieldDropdown(OPERATORS), 'MODE');
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ var op = thisBlock.getFieldValue('MODE');
+ var TOOLTIPS = {
+ 'WHILE': Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_WHILE,
+ 'UNTIL': Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL
+ };
+ return TOOLTIPS[op];
+ });
+ }
+};
+
+Blockly.Blocks['controls_for'] = {
+ /**
+ * Block for 'for' loop.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.CONTROLS_FOR_TITLE,
+ "args0": [
+ {
+ "type": "field_variable",
+ "name": "VAR",
+ "variable": null
+ },
+ {
+ "type": "input_value",
+ "name": "FROM",
+ "check": "Number",
+ "align": "RIGHT"
+ },
+ {
+ "type": "input_value",
+ "name": "TO",
+ "check": "Number",
+ "align": "RIGHT"
+ },
+ {
+ "type": "input_value",
+ "name": "BY",
+ "check": "Number",
+ "align": "RIGHT"
+ }
+ ],
+ "inputsInline": true,
+ "previousStatement": null,
+ "nextStatement": null,
+ "colour": Blockly.Blocks.loops.HUE,
+ "helpUrl": Blockly.Msg.CONTROLS_FOR_HELPURL
+ });
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.CONTROLS_FOR_INPUT_DO);
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ return Blockly.Msg.CONTROLS_FOR_TOOLTIP.replace('%1',
+ thisBlock.getFieldValue('VAR'));
+ });
+ },
+ /**
+ * Add menu option to create getter block for loop variable.
+ * @param {!Array} options List of menu options to add to.
+ * @this Blockly.Block
+ */
+ customContextMenu: function(options) {
+ if (!this.isCollapsed()) {
+ var option = {enabled: true};
+ var name = this.getFieldValue('VAR');
+ option.text = Blockly.Msg.VARIABLES_SET_CREATE_GET.replace('%1', name);
+ var xmlField = goog.dom.createDom('field', null, name);
+ xmlField.setAttribute('name', 'VAR');
+ var xmlBlock = goog.dom.createDom('block', null, xmlField);
+ xmlBlock.setAttribute('type', 'variables_get');
+ option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
+ options.push(option);
+ }
+ }
+};
+
+Blockly.Blocks['controls_forEach'] = {
+ /**
+ * Block for 'for each' loop.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.CONTROLS_FOREACH_TITLE,
+ "args0": [
+ {
+ "type": "field_variable",
+ "name": "VAR",
+ "variable": null
+ },
+ {
+ "type": "input_value",
+ "name": "LIST",
+ "check": "Array"
+ }
+ ],
+ "previousStatement": null,
+ "nextStatement": null,
+ "colour": Blockly.Blocks.loops.HUE,
+ "helpUrl": Blockly.Msg.CONTROLS_FOREACH_HELPURL
+ });
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.CONTROLS_FOREACH_INPUT_DO);
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ return Blockly.Msg.CONTROLS_FOREACH_TOOLTIP.replace('%1',
+ thisBlock.getFieldValue('VAR'));
+ });
+ },
+ customContextMenu: Blockly.Blocks['controls_for'].customContextMenu
+};
+
+Blockly.Blocks['controls_flow_statements'] = {
+ /**
+ * Block for flow statements: continue, break.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var OPERATORS =
+ [[Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK, 'BREAK'],
+ [Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE, 'CONTINUE']];
+ this.setHelpUrl(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_HELPURL);
+ this.setColour(Blockly.Blocks.loops.HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(OPERATORS), 'FLOW');
+ this.setPreviousStatement(true);
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ var op = thisBlock.getFieldValue('FLOW');
+ var TOOLTIPS = {
+ 'BREAK': Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK,
+ 'CONTINUE': Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE
+ };
+ return TOOLTIPS[op];
+ });
+ },
+ /**
+ * Called whenever anything on the workspace changes.
+ * Add warning if this flow block is not nested inside a loop.
+ * @param {!Blockly.Events.Abstract} e Change event.
+ * @this Blockly.Block
+ */
+ onchange: function(e) {
+ var legal = false;
+ // Is the block nested in a loop?
+ var block = this;
+ do {
+ if (this.LOOP_TYPES.indexOf(block.type) != -1) {
+ legal = true;
+ break;
+ }
+ block = block.getSurroundParent();
+ } while (block);
+ if (legal) {
+ this.setWarningText(null);
+ } else {
+ this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING);
+ }
+ },
+ /**
+ * List of block types that are loops and thus do not need warnings.
+ * To add a new loop type add this to your code:
+ * Blockly.Blocks['controls_flow_statements'].LOOP_TYPES.push('custom_loop');
+ */
+ LOOP_TYPES: ['controls_repeat', 'controls_repeat_ext', 'controls_forEach',
+ 'controls_for', 'controls_whileUntil']
+};
diff --git a/src/blockly/blocks/math.js b/src/blockly/blocks/math.js
new file mode 100644
index 0000000..053b545
--- /dev/null
+++ b/src/blockly/blocks/math.js
@@ -0,0 +1,553 @@
+/**
+ * @license
+ * Visual Blocks Editor
+ *
+ * Copyright 2012 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Math blocks for Blockly.
+ * @author q.neutron@gmail.com (Quynh Neutron)
+ */
+'use strict';
+
+goog.provide('Blockly.Blocks.math');
+
+goog.require('Blockly.Blocks');
+
+
+/**
+ * Common HSV hue for all blocks in this category.
+ */
+Blockly.Blocks.math.HUE = 230;
+
+Blockly.Blocks['math_number'] = {
+ /**
+ * Block for numeric value.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setHelpUrl(Blockly.Msg.MATH_NUMBER_HELPURL);
+ this.setColour(Blockly.Blocks.math.HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldNumber('0'), 'NUM');
+ this.setOutput(true, 'Number');
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ // Number block is trivial. Use tooltip of parent block if it exists.
+ this.setTooltip(function() {
+ var parent = thisBlock.getParent();
+ return (parent && parent.getInputsInline() && parent.tooltip) ||
+ Blockly.Msg.MATH_NUMBER_TOOLTIP;
+ });
+ }
+};
+
+Blockly.Blocks['math_arithmetic'] = {
+ /**
+ * Block for basic arithmetic operator.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": "%1 %2 %3",
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "A",
+ "check": "Number"
+ },
+ {
+ "type": "field_dropdown",
+ "name": "OP",
+ "options":
+ [[Blockly.Msg.MATH_ADDITION_SYMBOL, 'ADD'],
+ [Blockly.Msg.MATH_SUBTRACTION_SYMBOL, 'MINUS'],
+ [Blockly.Msg.MATH_MULTIPLICATION_SYMBOL, 'MULTIPLY'],
+ [Blockly.Msg.MATH_DIVISION_SYMBOL, 'DIVIDE'],
+ [Blockly.Msg.MATH_POWER_SYMBOL, 'POWER']]
+ },
+ {
+ "type": "input_value",
+ "name": "B",
+ "check": "Number"
+ }
+ ],
+ "inputsInline": true,
+ "output": "Number",
+ "colour": Blockly.Blocks.math.HUE,
+ "helpUrl": Blockly.Msg.MATH_ARITHMETIC_HELPURL
+ });
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ var mode = thisBlock.getFieldValue('OP');
+ var TOOLTIPS = {
+ 'ADD': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,
+ 'MINUS': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,
+ 'MULTIPLY': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,
+ 'DIVIDE': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
+ 'POWER': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER
+ };
+ return TOOLTIPS[mode];
+ });
+ }
+};
+
+Blockly.Blocks['math_single'] = {
+ /**
+ * Block for advanced math operators with single operand.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": "%1 %2",
+ "args0": [
+ {
+ "type": "field_dropdown",
+ "name": "OP",
+ "options": [
+ [Blockly.Msg.MATH_SINGLE_OP_ROOT, 'ROOT'],
+ [Blockly.Msg.MATH_SINGLE_OP_ABSOLUTE, 'ABS'],
+ ['-', 'NEG'],
+ ['ln', 'LN'],
+ ['log10', 'LOG10'],
+ ['e^', 'EXP'],
+ ['10^', 'POW10']
+ ]
+ },
+ {
+ "type": "input_value",
+ "name": "NUM",
+ "check": "Number"
+ }
+ ],
+ "output": "Number",
+ "colour": Blockly.Blocks.math.HUE,
+ "helpUrl": Blockly.Msg.MATH_SINGLE_HELPURL
+ });
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ var mode = thisBlock.getFieldValue('OP');
+ var TOOLTIPS = {
+ 'ROOT': Blockly.Msg.MATH_SINGLE_TOOLTIP_ROOT,
+ 'ABS': Blockly.Msg.MATH_SINGLE_TOOLTIP_ABS,
+ 'NEG': Blockly.Msg.MATH_SINGLE_TOOLTIP_NEG,
+ 'LN': Blockly.Msg.MATH_SINGLE_TOOLTIP_LN,
+ 'LOG10': Blockly.Msg.MATH_SINGLE_TOOLTIP_LOG10,
+ 'EXP': Blockly.Msg.MATH_SINGLE_TOOLTIP_EXP,
+ 'POW10': Blockly.Msg.MATH_SINGLE_TOOLTIP_POW10
+ };
+ return TOOLTIPS[mode];
+ });
+ }
+};
+
+Blockly.Blocks['math_trig'] = {
+ /**
+ * Block for trigonometry operators.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": "%1 %2",
+ "args0": [
+ {
+ "type": "field_dropdown",
+ "name": "OP",
+ "options": [
+ [Blockly.Msg.MATH_TRIG_SIN, 'SIN'],
+ [Blockly.Msg.MATH_TRIG_COS, 'COS'],
+ [Blockly.Msg.MATH_TRIG_TAN, 'TAN'],
+ [Blockly.Msg.MATH_TRIG_ASIN, 'ASIN'],
+ [Blockly.Msg.MATH_TRIG_ACOS, 'ACOS'],
+ [Blockly.Msg.MATH_TRIG_ATAN, 'ATAN']
+ ]
+ },
+ {
+ "type": "input_value",
+ "name": "NUM",
+ "check": "Number"
+ }
+ ],
+ "output": "Number",
+ "colour": Blockly.Blocks.math.HUE,
+ "helpUrl": Blockly.Msg.MATH_TRIG_HELPURL
+ });
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ var mode = thisBlock.getFieldValue('OP');
+ var TOOLTIPS = {
+ 'SIN': Blockly.Msg.MATH_TRIG_TOOLTIP_SIN,
+ 'COS': Blockly.Msg.MATH_TRIG_TOOLTIP_COS,
+ 'TAN': Blockly.Msg.MATH_TRIG_TOOLTIP_TAN,
+ 'ASIN': Blockly.Msg.MATH_TRIG_TOOLTIP_ASIN,
+ 'ACOS': Blockly.Msg.MATH_TRIG_TOOLTIP_ACOS,
+ 'ATAN': Blockly.Msg.MATH_TRIG_TOOLTIP_ATAN
+ };
+ return TOOLTIPS[mode];
+ });
+ }
+};
+
+Blockly.Blocks['math_constant'] = {
+ /**
+ * Block for constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": "%1",
+ "args0": [
+ {
+ "type": "field_dropdown",
+ "name": "CONSTANT",
+ "options": [
+ ['\u03c0', 'PI'],
+ ['e', 'E'],
+ ['\u03c6', 'GOLDEN_RATIO'],
+ ['sqrt(2)', 'SQRT2'],
+ ['sqrt(\u00bd)', 'SQRT1_2'],
+ ['\u221e', 'INFINITY']
+ ]
+ }
+ ],
+ "output": "Number",
+ "colour": Blockly.Blocks.math.HUE,
+ "tooltip": Blockly.Msg.MATH_CONSTANT_TOOLTIP,
+ "helpUrl": Blockly.Msg.MATH_CONSTANT_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['math_number_property'] = {
+ /**
+ * Block for checking if a number is even, odd, prime, whole, positive,
+ * negative or if it is divisible by certain number.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var PROPERTIES =
+ [[Blockly.Msg.MATH_IS_EVEN, 'EVEN'],
+ [Blockly.Msg.MATH_IS_ODD, 'ODD'],
+ [Blockly.Msg.MATH_IS_PRIME, 'PRIME'],
+ [Blockly.Msg.MATH_IS_WHOLE, 'WHOLE'],
+ [Blockly.Msg.MATH_IS_POSITIVE, 'POSITIVE'],
+ [Blockly.Msg.MATH_IS_NEGATIVE, 'NEGATIVE'],
+ [Blockly.Msg.MATH_IS_DIVISIBLE_BY, 'DIVISIBLE_BY']];
+ this.setColour(Blockly.Blocks.math.HUE);
+ this.appendValueInput('NUMBER_TO_CHECK')
+ .setCheck('Number');
+ var dropdown = new Blockly.FieldDropdown(PROPERTIES, function(option) {
+ var divisorInput = (option == 'DIVISIBLE_BY');
+ this.sourceBlock_.updateShape_(divisorInput);
+ });
+ this.appendDummyInput()
+ .appendField(dropdown, 'PROPERTY');
+ this.setInputsInline(true);
+ this.setOutput(true, 'Boolean');
+ this.setTooltip(Blockly.Msg.MATH_IS_TOOLTIP);
+ },
+ /**
+ * Create XML to represent whether the 'divisorInput' should be present.
+ * @return {Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ var divisorInput = (this.getFieldValue('PROPERTY') == 'DIVISIBLE_BY');
+ container.setAttribute('divisor_input', divisorInput);
+ return container;
+ },
+ /**
+ * Parse XML to restore the 'divisorInput'.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ var divisorInput = (xmlElement.getAttribute('divisor_input') == 'true');
+ this.updateShape_(divisorInput);
+ },
+ /**
+ * Modify this block to have (or not have) an input for 'is divisible by'.
+ * @param {boolean} divisorInput True if this block has a divisor input.
+ * @private
+ * @this Blockly.Block
+ */
+ updateShape_: function(divisorInput) {
+ // Add or remove a Value Input.
+ var inputExists = this.getInput('DIVISOR');
+ if (divisorInput) {
+ if (!inputExists) {
+ this.appendValueInput('DIVISOR')
+ .setCheck('Number');
+ }
+ } else if (inputExists) {
+ this.removeInput('DIVISOR');
+ }
+ }
+};
+
+Blockly.Blocks['math_change'] = {
+ /**
+ * Block for adding to a variable in place.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.MATH_CHANGE_TITLE,
+ "args0": [
+ {
+ "type": "field_variable",
+ "name": "VAR",
+ "variable": Blockly.Msg.MATH_CHANGE_TITLE_ITEM
+ },
+ {
+ "type": "input_value",
+ "name": "DELTA",
+ "check": "Number"
+ }
+ ],
+ "previousStatement": null,
+ "nextStatement": null,
+ "colour": Blockly.Blocks.variables.HUE,
+ "helpUrl": Blockly.Msg.MATH_CHANGE_HELPURL
+ });
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ return Blockly.Msg.MATH_CHANGE_TOOLTIP.replace('%1',
+ thisBlock.getFieldValue('VAR'));
+ });
+ }
+};
+
+Blockly.Blocks['math_round'] = {
+ /**
+ * Block for rounding functions.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": "%1 %2",
+ "args0": [
+ {
+ "type": "field_dropdown",
+ "name": "OP",
+ "options": [
+ [Blockly.Msg.MATH_ROUND_OPERATOR_ROUND, 'ROUND'],
+ [Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDUP, 'ROUNDUP'],
+ [Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDDOWN, 'ROUNDDOWN']
+ ]
+ },
+ {
+ "type": "input_value",
+ "name": "NUM",
+ "check": "Number"
+ }
+ ],
+ "output": "Number",
+ "colour": Blockly.Blocks.math.HUE,
+ "tooltip": Blockly.Msg.MATH_ROUND_TOOLTIP,
+ "helpUrl": Blockly.Msg.MATH_ROUND_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['math_on_list'] = {
+ /**
+ * Block for evaluating a list of numbers to return sum, average, min, max,
+ * etc. Some functions also work on text (min, max, mode, median).
+ * @this Blockly.Block
+ */
+ init: function() {
+ var OPERATORS =
+ [[Blockly.Msg.MATH_ONLIST_OPERATOR_SUM, 'SUM'],
+ [Blockly.Msg.MATH_ONLIST_OPERATOR_MIN, 'MIN'],
+ [Blockly.Msg.MATH_ONLIST_OPERATOR_MAX, 'MAX'],
+ [Blockly.Msg.MATH_ONLIST_OPERATOR_AVERAGE, 'AVERAGE'],
+ [Blockly.Msg.MATH_ONLIST_OPERATOR_MEDIAN, 'MEDIAN'],
+ [Blockly.Msg.MATH_ONLIST_OPERATOR_MODE, 'MODE'],
+ [Blockly.Msg.MATH_ONLIST_OPERATOR_STD_DEV, 'STD_DEV'],
+ [Blockly.Msg.MATH_ONLIST_OPERATOR_RANDOM, 'RANDOM']];
+ // Assign 'this' to a variable for use in the closures below.
+ var thisBlock = this;
+ this.setHelpUrl(Blockly.Msg.MATH_ONLIST_HELPURL);
+ this.setColour(Blockly.Blocks.math.HUE);
+ this.setOutput(true, 'Number');
+ var dropdown = new Blockly.FieldDropdown(OPERATORS, function(newOp) {
+ thisBlock.updateType_(newOp);
+ });
+ this.appendValueInput('LIST')
+ .setCheck('Array')
+ .appendField(dropdown, 'OP');
+ this.setTooltip(function() {
+ var mode = thisBlock.getFieldValue('OP');
+ var TOOLTIPS = {
+ 'SUM': Blockly.Msg.MATH_ONLIST_TOOLTIP_SUM,
+ 'MIN': Blockly.Msg.MATH_ONLIST_TOOLTIP_MIN,
+ 'MAX': Blockly.Msg.MATH_ONLIST_TOOLTIP_MAX,
+ 'AVERAGE': Blockly.Msg.MATH_ONLIST_TOOLTIP_AVERAGE,
+ 'MEDIAN': Blockly.Msg.MATH_ONLIST_TOOLTIP_MEDIAN,
+ 'MODE': Blockly.Msg.MATH_ONLIST_TOOLTIP_MODE,
+ 'STD_DEV': Blockly.Msg.MATH_ONLIST_TOOLTIP_STD_DEV,
+ 'RANDOM': Blockly.Msg.MATH_ONLIST_TOOLTIP_RANDOM
+ };
+ return TOOLTIPS[mode];
+ });
+ },
+ /**
+ * Modify this block to have the correct output type.
+ * @param {string} newOp Either 'MODE' or some op than returns a number.
+ * @private
+ * @this Blockly.Block
+ */
+ updateType_: function(newOp) {
+ if (newOp == 'MODE') {
+ this.outputConnection.setCheck('Array');
+ } else {
+ this.outputConnection.setCheck('Number');
+ }
+ },
+ /**
+ * Create XML to represent the output type.
+ * @return {Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ container.setAttribute('op', this.getFieldValue('OP'));
+ return container;
+ },
+ /**
+ * Parse XML to restore the output type.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ this.updateType_(xmlElement.getAttribute('op'));
+ }
+};
+
+Blockly.Blocks['math_modulo'] = {
+ /**
+ * Block for remainder of a division.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.MATH_MODULO_TITLE,
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "DIVIDEND",
+ "check": "Number"
+ },
+ {
+ "type": "input_value",
+ "name": "DIVISOR",
+ "check": "Number"
+ }
+ ],
+ "inputsInline": true,
+ "output": "Number",
+ "colour": Blockly.Blocks.math.HUE,
+ "tooltip": Blockly.Msg.MATH_MODULO_TOOLTIP,
+ "helpUrl": Blockly.Msg.MATH_MODULO_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['math_constrain'] = {
+ /**
+ * Block for constraining a number between two limits.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.MATH_CONSTRAIN_TITLE,
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "VALUE",
+ "check": "Number"
+ },
+ {
+ "type": "input_value",
+ "name": "LOW",
+ "check": "Number"
+ },
+ {
+ "type": "input_value",
+ "name": "HIGH",
+ "check": "Number"
+ }
+ ],
+ "inputsInline": true,
+ "output": "Number",
+ "colour": Blockly.Blocks.math.HUE,
+ "tooltip": Blockly.Msg.MATH_CONSTRAIN_TOOLTIP,
+ "helpUrl": Blockly.Msg.MATH_CONSTRAIN_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['math_random_int'] = {
+ /**
+ * Block for random integer between [X] and [Y].
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.MATH_RANDOM_INT_TITLE,
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "FROM",
+ "check": "Number"
+ },
+ {
+ "type": "input_value",
+ "name": "TO",
+ "check": "Number"
+ }
+ ],
+ "inputsInline": true,
+ "output": "Number",
+ "colour": Blockly.Blocks.math.HUE,
+ "tooltip": Blockly.Msg.MATH_RANDOM_INT_TOOLTIP,
+ "helpUrl": Blockly.Msg.MATH_RANDOM_INT_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['math_random_float'] = {
+ /**
+ * Block for random fraction between 0 and 1.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM,
+ "output": "Number",
+ "colour": Blockly.Blocks.math.HUE,
+ "tooltip": Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP,
+ "helpUrl": Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL
+ });
+ }
+};
diff --git a/src/blockly/blocks/procedures.js b/src/blockly/blocks/procedures.js
new file mode 100644
index 0000000..19a5f6e
--- /dev/null
+++ b/src/blockly/blocks/procedures.js
@@ -0,0 +1,875 @@
+/**
+ * @license
+ * Visual Blocks Editor
+ *
+ * Copyright 2012 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Procedure blocks for Blockly.
+ * @author fraser@google.com (Neil Fraser)
+ */
+'use strict';
+
+goog.provide('Blockly.Blocks.procedures');
+
+goog.require('Blockly.Blocks');
+
+
+/**
+ * Common HSV hue for all blocks in this category.
+ */
+Blockly.Blocks.procedures.HUE = 290;
+
+Blockly.Blocks['procedures_defnoreturn'] = {
+ /**
+ * Block for defining a procedure with no return value.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var nameField = new Blockly.FieldTextInput(
+ Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE,
+ Blockly.Procedures.rename);
+ nameField.setSpellcheck(false);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE)
+ .appendField(nameField, 'NAME')
+ .appendField('', 'PARAMS');
+ this.setMutator(new Blockly.Mutator(['procedures_mutatorarg']));
+ if (Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT) {
+ this.setCommentText(Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT);
+ }
+ this.setColour(Blockly.Blocks.procedures.HUE);
+ this.setTooltip(Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP);
+ this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL);
+ this.arguments_ = [];
+ this.setStatements_(true);
+ this.statementConnection_ = null;
+ },
+ /**
+ * Add or remove the statement block from this function definition.
+ * @param {boolean} hasStatements True if a statement block is needed.
+ * @this Blockly.Block
+ */
+ setStatements_: function(hasStatements) {
+ if (this.hasStatements_ === hasStatements) {
+ return;
+ }
+ if (hasStatements) {
+ this.appendStatementInput('STACK')
+ .appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_DO);
+ if (this.getInput('RETURN')) {
+ this.moveInputBefore('STACK', 'RETURN');
+ }
+ } else {
+ this.removeInput('STACK', true);
+ }
+ this.hasStatements_ = hasStatements;
+ },
+ /**
+ * Update the display of parameters for this procedure definition block.
+ * Display a warning if there are duplicately named parameters.
+ * @private
+ * @this Blockly.Block
+ */
+ updateParams_: function() {
+ // Check for duplicated arguments.
+ var badArg = false;
+ var hash = {};
+ for (var i = 0; i < this.arguments_.length; i++) {
+ if (hash['arg_' + this.arguments_[i].toLowerCase()]) {
+ badArg = true;
+ break;
+ }
+ hash['arg_' + this.arguments_[i].toLowerCase()] = true;
+ }
+ if (badArg) {
+ this.setWarningText(Blockly.Msg.PROCEDURES_DEF_DUPLICATE_WARNING);
+ } else {
+ this.setWarningText(null);
+ }
+ // Merge the arguments into a human-readable list.
+ var paramString = '';
+ if (this.arguments_.length) {
+ paramString = Blockly.Msg.PROCEDURES_BEFORE_PARAMS +
+ ' ' + this.arguments_.join(', ');
+ }
+ // The params field is deterministic based on the mutation,
+ // no need to fire a change event.
+ Blockly.Events.disable();
+ try {
+ this.setFieldValue(paramString, 'PARAMS');
+ } finally {
+ Blockly.Events.enable();
+ }
+ },
+ /**
+ * Create XML to represent the argument inputs.
+ * @param {=boolean} opt_paramIds If true include the IDs of the parameter
+ * quarks. Used by Blockly.Procedures.mutateCallers for reconnection.
+ * @return {!Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function(opt_paramIds) {
+ var container = document.createElement('mutation');
+ if (opt_paramIds) {
+ container.setAttribute('name', this.getFieldValue('NAME'));
+ }
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var parameter = document.createElement('arg');
+ parameter.setAttribute('name', this.arguments_[i]);
+ if (opt_paramIds && this.paramIds_) {
+ parameter.setAttribute('paramId', this.paramIds_[i]);
+ }
+ container.appendChild(parameter);
+ }
+
+ // Save whether the statement input is visible.
+ if (!this.hasStatements_) {
+ container.setAttribute('statements', 'false');
+ }
+ return container;
+ },
+ /**
+ * Parse XML to restore the argument inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ this.arguments_ = [];
+ for (var i = 0, childNode; childNode = xmlElement.childNodes[i]; i++) {
+ if (childNode.nodeName.toLowerCase() == 'arg') {
+ this.arguments_.push(childNode.getAttribute('name'));
+ }
+ }
+ this.updateParams_();
+ Blockly.Procedures.mutateCallers(this);
+
+ // Show or hide the statement input.
+ this.setStatements_(xmlElement.getAttribute('statements') !== 'false');
+ },
+ /**
+ * Populate the mutator's dialog with this block's components.
+ * @param {!Blockly.Workspace} workspace Mutator's workspace.
+ * @return {!Blockly.Block} Root block in mutator.
+ * @this Blockly.Block
+ */
+ decompose: function(workspace) {
+ var containerBlock = workspace.newBlock('procedures_mutatorcontainer');
+ containerBlock.initSvg();
+
+ // Check/uncheck the allow statement box.
+ if (this.getInput('RETURN')) {
+ containerBlock.setFieldValue(this.hasStatements_ ? 'TRUE' : 'FALSE',
+ 'STATEMENTS');
+ } else {
+ containerBlock.getInput('STATEMENT_INPUT').setVisible(false);
+ }
+
+ // Parameter list.
+ var connection = containerBlock.getInput('STACK').connection;
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var paramBlock = workspace.newBlock('procedures_mutatorarg');
+ paramBlock.initSvg();
+ paramBlock.setFieldValue(this.arguments_[i], 'NAME');
+ // Store the old location.
+ paramBlock.oldLocation = i;
+ connection.connect(paramBlock.previousConnection);
+ connection = paramBlock.nextConnection;
+ }
+ // Initialize procedure's callers with blank IDs.
+ Blockly.Procedures.mutateCallers(this);
+ return containerBlock;
+ },
+ /**
+ * Reconfigure this block based on the mutator dialog's components.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ compose: function(containerBlock) {
+ // Parameter list.
+ this.arguments_ = [];
+ this.paramIds_ = [];
+ var paramBlock = containerBlock.getInputTargetBlock('STACK');
+ while (paramBlock) {
+ this.arguments_.push(paramBlock.getFieldValue('NAME'));
+ this.paramIds_.push(paramBlock.id);
+ paramBlock = paramBlock.nextConnection &&
+ paramBlock.nextConnection.targetBlock();
+ }
+ this.updateParams_();
+ Blockly.Procedures.mutateCallers(this);
+
+ // Show/hide the statement input.
+ var hasStatements = containerBlock.getFieldValue('STATEMENTS');
+ if (hasStatements !== null) {
+ hasStatements = hasStatements == 'TRUE';
+ if (this.hasStatements_ != hasStatements) {
+ if (hasStatements) {
+ this.setStatements_(true);
+ // Restore the stack, if one was saved.
+ Blockly.Mutator.reconnect(this.statementConnection_, this, 'STACK');
+ this.statementConnection_ = null;
+ } else {
+ // Save the stack, then disconnect it.
+ var stackConnection = this.getInput('STACK').connection;
+ this.statementConnection_ = stackConnection.targetConnection;
+ if (this.statementConnection_) {
+ var stackBlock = stackConnection.targetBlock();
+ stackBlock.unplug();
+ stackBlock.bumpNeighbours_();
+ }
+ this.setStatements_(false);
+ }
+ }
+ }
+ },
+ /**
+ * Return the signature of this procedure definition.
+ * @return {!Array} Tuple containing three elements:
+ * - the name of the defined procedure,
+ * - a list of all its arguments,
+ * - that it DOES NOT have a return value.
+ * @this Blockly.Block
+ */
+ getProcedureDef: function() {
+ return [this.getFieldValue('NAME'), this.arguments_, false];
+ },
+ /**
+ * Return all variables referenced by this block.
+ * @return {!Array.<string>} List of variable names.
+ * @this Blockly.Block
+ */
+ getVars: function() {
+ return this.arguments_;
+ },
+ /**
+ * Notification that a variable is renaming.
+ * If the name matches one of this block's variables, rename it.
+ * @param {string} oldName Previous name of variable.
+ * @param {string} newName Renamed variable.
+ * @this Blockly.Block
+ */
+ renameVar: function(oldName, newName) {
+ var change = false;
+ for (var i = 0; i < this.arguments_.length; i++) {
+ if (Blockly.Names.equals(oldName, this.arguments_[i])) {
+ this.arguments_[i] = newName;
+ change = true;
+ }
+ }
+ if (change) {
+ this.updateParams_();
+ // Update the mutator's variables if the mutator is open.
+ if (this.mutator.isVisible()) {
+ var blocks = this.mutator.workspace_.getAllBlocks();
+ for (var i = 0, block; block = blocks[i]; i++) {
+ if (block.type == 'procedures_mutatorarg' &&
+ Blockly.Names.equals(oldName, block.getFieldValue('NAME'))) {
+ block.setFieldValue(newName, 'NAME');
+ }
+ }
+ }
+ }
+ },
+ /**
+ * Add custom menu options to this block's context menu.
+ * @param {!Array} options List of menu options to add to.
+ * @this Blockly.Block
+ */
+ customContextMenu: function(options) {
+ // Add option to create caller.
+ var option = {enabled: true};
+ var name = this.getFieldValue('NAME');
+ option.text = Blockly.Msg.PROCEDURES_CREATE_DO.replace('%1', name);
+ var xmlMutation = goog.dom.createDom('mutation');
+ xmlMutation.setAttribute('name', name);
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var xmlArg = goog.dom.createDom('arg');
+ xmlArg.setAttribute('name', this.arguments_[i]);
+ xmlMutation.appendChild(xmlArg);
+ }
+ var xmlBlock = goog.dom.createDom('block', null, xmlMutation);
+ xmlBlock.setAttribute('type', this.callType_);
+ option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
+ options.push(option);
+
+ // Add options to create getters for each parameter.
+ if (!this.isCollapsed()) {
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var option = {enabled: true};
+ var name = this.arguments_[i];
+ option.text = Blockly.Msg.VARIABLES_SET_CREATE_GET.replace('%1', name);
+ var xmlField = goog.dom.createDom('field', null, name);
+ xmlField.setAttribute('name', 'VAR');
+ var xmlBlock = goog.dom.createDom('block', null, xmlField);
+ xmlBlock.setAttribute('type', 'variables_get');
+ option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
+ options.push(option);
+ }
+ }
+ },
+ callType_: 'procedures_callnoreturn'
+};
+
+Blockly.Blocks['procedures_defreturn'] = {
+ /**
+ * Block for defining a procedure with a return value.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var nameField = new Blockly.FieldTextInput(
+ Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE,
+ Blockly.Procedures.rename);
+ nameField.setSpellcheck(false);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_TITLE)
+ .appendField(nameField, 'NAME')
+ .appendField('', 'PARAMS');
+ this.appendValueInput('RETURN')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ this.setMutator(new Blockly.Mutator(['procedures_mutatorarg']));
+ if (Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT) {
+ this.setCommentText(Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT);
+ }
+ this.setColour(Blockly.Blocks.procedures.HUE);
+ this.setTooltip(Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP);
+ this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL);
+ this.arguments_ = [];
+ this.setStatements_(true);
+ this.statementConnection_ = null;
+ },
+ setStatements_: Blockly.Blocks['procedures_defnoreturn'].setStatements_,
+ updateParams_: Blockly.Blocks['procedures_defnoreturn'].updateParams_,
+ mutationToDom: Blockly.Blocks['procedures_defnoreturn'].mutationToDom,
+ domToMutation: Blockly.Blocks['procedures_defnoreturn'].domToMutation,
+ decompose: Blockly.Blocks['procedures_defnoreturn'].decompose,
+ compose: Blockly.Blocks['procedures_defnoreturn'].compose,
+ /**
+ * Return the signature of this procedure definition.
+ * @return {!Array} Tuple containing three elements:
+ * - the name of the defined procedure,
+ * - a list of all its arguments,
+ * - that it DOES have a return value.
+ * @this Blockly.Block
+ */
+ getProcedureDef: function() {
+ return [this.getFieldValue('NAME'), this.arguments_, true];
+ },
+ getVars: Blockly.Blocks['procedures_defnoreturn'].getVars,
+ renameVar: Blockly.Blocks['procedures_defnoreturn'].renameVar,
+ customContextMenu: Blockly.Blocks['procedures_defnoreturn'].customContextMenu,
+ callType_: 'procedures_callreturn'
+};
+
+Blockly.Blocks['procedures_mutatorcontainer'] = {
+ /**
+ * Mutator block for procedure container.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE);
+ this.appendStatementInput('STACK');
+ this.appendDummyInput('STATEMENT_INPUT')
+ .appendField(Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS)
+ .appendField(new Blockly.FieldCheckbox('TRUE'), 'STATEMENTS');
+ this.setColour(Blockly.Blocks.procedures.HUE);
+ this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+Blockly.Blocks['procedures_mutatorarg'] = {
+ /**
+ * Mutator block for procedure argument.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var field = new Blockly.FieldTextInput('x', this.validator_);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.PROCEDURES_MUTATORARG_TITLE)
+ .appendField(field, 'NAME');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setColour(Blockly.Blocks.procedures.HUE);
+ this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP);
+ this.contextMenu = false;
+
+ // Create the default variable when we drag the block in from the flyout.
+ // Have to do this after installing the field on the block.
+ field.onFinishEditing_ = this.createNewVar_;
+ field.onFinishEditing_('x');
+ },
+ /**
+ * Obtain a valid name for the procedure.
+ * Merge runs of whitespace. Strip leading and trailing whitespace.
+ * Beyond this, all names are legal.
+ * @param {string} newVar User-supplied name.
+ * @return {?string} Valid name, or null if a name was not specified.
+ * @private
+ * @this Blockly.Block
+ */
+ validator_: function(newVar) {
+ newVar = newVar.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
+ return newVar || null;
+ },
+ /**
+ * Called when focusing away from the text field.
+ * Creates a new variable with this name.
+ * @param {string} newText The new variable name.
+ * @private
+ * @this Blockly.FieldTextInput
+ */
+ createNewVar_: function(newText) {
+ var source = this.sourceBlock_;
+ if (source && source.workspace && source.workspace.options
+ && source.workspace.options.parentWorkspace) {
+ source.workspace.options.parentWorkspace.createVariable(newText);
+ }
+ }
+};
+
+Blockly.Blocks['procedures_callnoreturn'] = {
+ /**
+ * Block for calling a procedure with no return value.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.appendDummyInput('TOPROW')
+ .appendField(this.id, 'NAME');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setColour(Blockly.Blocks.procedures.HUE);
+ // Tooltip is set in renameProcedure.
+ this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL);
+ this.arguments_ = [];
+ this.quarkConnections_ = {};
+ this.quarkIds_ = null;
+ },
+ /**
+ * Returns the name of the procedure this block calls.
+ * @return {string} Procedure name.
+ * @this Blockly.Block
+ */
+ getProcedureCall: function() {
+ // The NAME field is guaranteed to exist, null will never be returned.
+ return /** @type {string} */ (this.getFieldValue('NAME'));
+ },
+ /**
+ * Notification that a procedure is renaming.
+ * If the name matches this block's procedure, rename it.
+ * @param {string} oldName Previous name of procedure.
+ * @param {string} newName Renamed procedure.
+ * @this Blockly.Block
+ */
+ renameProcedure: function(oldName, newName) {
+ if (Blockly.Names.equals(oldName, this.getProcedureCall())) {
+ this.setFieldValue(newName, 'NAME');
+ this.setTooltip(
+ (this.outputConnection ? Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP :
+ Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP)
+ .replace('%1', newName));
+ }
+ },
+ /**
+ * Notification that the procedure's parameters have changed.
+ * @param {!Array.<string>} paramNames New param names, e.g. ['x', 'y', 'z'].
+ * @param {!Array.<string>} paramIds IDs of params (consistent for each
+ * parameter through the life of a mutator, regardless of param renaming),
+ * e.g. ['piua', 'f8b_', 'oi.o'].
+ * @private
+ * @this Blockly.Block
+ */
+ setProcedureParameters_: function(paramNames, paramIds) {
+ // Data structures:
+ // this.arguments = ['x', 'y']
+ // Existing param names.
+ // this.quarkConnections_ {piua: null, f8b_: Blockly.Connection}
+ // Look-up of paramIds to connections plugged into the call block.
+ // this.quarkIds_ = ['piua', 'f8b_']
+ // Existing param IDs.
+ // Note that quarkConnections_ may include IDs that no longer exist, but
+ // which might reappear if a param is reattached in the mutator.
+ var defBlock = Blockly.Procedures.getDefinition(this.getProcedureCall(),
+ this.workspace);
+ var mutatorOpen = defBlock && defBlock.mutator &&
+ defBlock.mutator.isVisible();
+ if (!mutatorOpen) {
+ this.quarkConnections_ = {};
+ this.quarkIds_ = null;
+ }
+ if (!paramIds) {
+ // Reset the quarks (a mutator is about to open).
+ return;
+ }
+ if (goog.array.equals(this.arguments_, paramNames)) {
+ // No change.
+ this.quarkIds_ = paramIds;
+ return;
+ }
+ if (paramIds.length != paramNames.length) {
+ throw 'Error: paramNames and paramIds must be the same length.';
+ }
+ this.setCollapsed(false);
+ if (!this.quarkIds_) {
+ // Initialize tracking for this block.
+ this.quarkConnections_ = {};
+ if (paramNames.join('\n') == this.arguments_.join('\n')) {
+ // No change to the parameters, allow quarkConnections_ to be
+ // populated with the existing connections.
+ this.quarkIds_ = paramIds;
+ } else {
+ this.quarkIds_ = [];
+ }
+ }
+ // Switch off rendering while the block is rebuilt.
+ var savedRendered = this.rendered;
+ this.rendered = false;
+ // Update the quarkConnections_ with existing connections.
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var input = this.getInput('ARG' + i);
+ if (input) {
+ var connection = input.connection.targetConnection;
+ this.quarkConnections_[this.quarkIds_[i]] = connection;
+ if (mutatorOpen && connection &&
+ paramIds.indexOf(this.quarkIds_[i]) == -1) {
+ // This connection should no longer be attached to this block.
+ connection.disconnect();
+ connection.getSourceBlock().bumpNeighbours_();
+ }
+ }
+ }
+ // Rebuild the block's arguments.
+ this.arguments_ = [].concat(paramNames);
+ this.updateShape_();
+ this.quarkIds_ = paramIds;
+ // Reconnect any child blocks.
+ if (this.quarkIds_) {
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var quarkId = this.quarkIds_[i];
+ if (quarkId in this.quarkConnections_) {
+ var connection = this.quarkConnections_[quarkId];
+ if (!Blockly.Mutator.reconnect(connection, this, 'ARG' + i)) {
+ // Block no longer exists or has been attached elsewhere.
+ delete this.quarkConnections_[quarkId];
+ }
+ }
+ }
+ }
+ // Restore rendering and show the changes.
+ this.rendered = savedRendered;
+ if (this.rendered) {
+ this.render();
+ }
+ },
+ /**
+ * Modify this block to have the correct number of arguments.
+ * @private
+ * @this Blockly.Block
+ */
+ updateShape_: function() {
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var field = this.getField('ARGNAME' + i);
+ if (field) {
+ // Ensure argument name is up to date.
+ // The argument name field is deterministic based on the mutation,
+ // no need to fire a change event.
+ Blockly.Events.disable();
+ try {
+ field.setValue(this.arguments_[i]);
+ } finally {
+ Blockly.Events.enable();
+ }
+ } else {
+ // Add new input.
+ field = new Blockly.FieldLabel(this.arguments_[i]);
+ var input = this.appendValueInput('ARG' + i)
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .appendField(field, 'ARGNAME' + i);
+ input.init();
+ }
+ }
+ // Remove deleted inputs.
+ while (this.getInput('ARG' + i)) {
+ this.removeInput('ARG' + i);
+ i++;
+ }
+ // Add 'with:' if there are parameters, remove otherwise.
+ var topRow = this.getInput('TOPROW');
+ if (topRow) {
+ if (this.arguments_.length) {
+ if (!this.getField('WITH')) {
+ topRow.appendField(Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS, 'WITH');
+ topRow.init();
+ }
+ } else {
+ if (this.getField('WITH')) {
+ topRow.removeField('WITH');
+ }
+ }
+ }
+ },
+ /**
+ * Create XML to represent the (non-editable) name and arguments.
+ * @return {!Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ container.setAttribute('name', this.getProcedureCall());
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var parameter = document.createElement('arg');
+ parameter.setAttribute('name', this.arguments_[i]);
+ container.appendChild(parameter);
+ }
+ return container;
+ },
+ /**
+ * Parse XML to restore the (non-editable) name and parameters.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ var name = xmlElement.getAttribute('name');
+ this.renameProcedure(this.getProcedureCall(), name);
+ var args = [];
+ var paramIds = [];
+ for (var i = 0, childNode; childNode = xmlElement.childNodes[i]; i++) {
+ if (childNode.nodeName.toLowerCase() == 'arg') {
+ args.push(childNode.getAttribute('name'));
+ paramIds.push(childNode.getAttribute('paramId'));
+ }
+ }
+ this.setProcedureParameters_(args, paramIds);
+ },
+ /**
+ * Notification that a variable is renaming.
+ * If the name matches one of this block's variables, rename it.
+ * @param {string} oldName Previous name of variable.
+ * @param {string} newName Renamed variable.
+ * @this Blockly.Block
+ */
+ renameVar: function(oldName, newName) {
+ for (var i = 0; i < this.arguments_.length; i++) {
+ if (Blockly.Names.equals(oldName, this.arguments_[i])) {
+ this.arguments_[i] = newName;
+ this.getField('ARGNAME' + i).setValue(newName);
+ }
+ }
+ },
+ /**
+ * Procedure calls cannot exist without the corresponding procedure
+ * definition. Enforce this link whenever an event is fired.
+ * @this Blockly.Block
+ */
+ onchange: function(event) {
+ if (!this.workspace || this.workspace.isFlyout) {
+ // Block is deleted or is in a flyout.
+ return;
+ }
+ if (event.type == Blockly.Events.CREATE &&
+ event.ids.indexOf(this.id) != -1) {
+ // Look for the case where a procedure call was created (usually through
+ // paste) and there is no matching definition. In this case, create
+ // an empty definition block with the correct signature.
+ var name = this.getProcedureCall();
+ var def = Blockly.Procedures.getDefinition(name, this.workspace);
+ if (def && (def.type != this.defType_ ||
+ JSON.stringify(def.arguments_) != JSON.stringify(this.arguments_))) {
+ // The signatures don't match.
+ def = null;
+ }
+ if (!def) {
+ Blockly.Events.setGroup(event.group);
+ /**
+ * Create matching definition block.
+ * <xml>
+ * <block type="procedures_defreturn" x="10" y="20">
+ * <mutation name="test">
+ * <arg name="x"></arg>
+ * </mutation>
+ * <field name="NAME">test</field>
+ * </block>
+ * </xml>
+ */
+ var xml = goog.dom.createDom('xml');
+ var block = goog.dom.createDom('block');
+ block.setAttribute('type', this.defType_);
+ var xy = this.getRelativeToSurfaceXY();
+ var x = xy.x + Blockly.SNAP_RADIUS * (this.RTL ? -1 : 1);
+ var y = xy.y + Blockly.SNAP_RADIUS * 2;
+ block.setAttribute('x', x);
+ block.setAttribute('y', y);
+ var mutation = this.mutationToDom();
+ block.appendChild(mutation);
+ var field = goog.dom.createDom('field');
+ field.setAttribute('name', 'NAME');
+ field.appendChild(document.createTextNode(this.getProcedureCall()));
+ block.appendChild(field);
+ xml.appendChild(block);
+ Blockly.Xml.domToWorkspace(xml, this.workspace);
+ Blockly.Events.setGroup(false);
+ }
+ } else if (event.type == Blockly.Events.DELETE) {
+ // Look for the case where a procedure definition has been deleted,
+ // leaving this block (a procedure call) orphaned. In this case, delete
+ // the orphan.
+ var name = this.getProcedureCall();
+ var def = Blockly.Procedures.getDefinition(name, this.workspace);
+ if (!def) {
+ Blockly.Events.setGroup(event.group);
+ this.dispose(true, false);
+ Blockly.Events.setGroup(false);
+ }
+ }
+ },
+ /**
+ * Add menu option to find the definition block for this call.
+ * @param {!Array} options List of menu options to add to.
+ * @this Blockly.Block
+ */
+ customContextMenu: function(options) {
+ var option = {enabled: true};
+ option.text = Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF;
+ var name = this.getProcedureCall();
+ var workspace = this.workspace;
+ option.callback = function() {
+ var def = Blockly.Procedures.getDefinition(name, workspace);
+ def && def.select();
+ };
+ options.push(option);
+ },
+ defType_: 'procedures_defnoreturn'
+};
+
+Blockly.Blocks['procedures_callreturn'] = {
+ /**
+ * Block for calling a procedure with a return value.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.appendDummyInput('TOPROW')
+ .appendField('', 'NAME');
+ this.setOutput(true);
+ this.setColour(Blockly.Blocks.procedures.HUE);
+ // Tooltip is set in domToMutation.
+ this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL);
+ this.arguments_ = [];
+ this.quarkConnections_ = {};
+ this.quarkIds_ = null;
+ },
+ getProcedureCall: Blockly.Blocks['procedures_callnoreturn'].getProcedureCall,
+ renameProcedure: Blockly.Blocks['procedures_callnoreturn'].renameProcedure,
+ setProcedureParameters_:
+ Blockly.Blocks['procedures_callnoreturn'].setProcedureParameters_,
+ updateShape_: Blockly.Blocks['procedures_callnoreturn'].updateShape_,
+ mutationToDom: Blockly.Blocks['procedures_callnoreturn'].mutationToDom,
+ domToMutation: Blockly.Blocks['procedures_callnoreturn'].domToMutation,
+ renameVar: Blockly.Blocks['procedures_callnoreturn'].renameVar,
+ onchange: Blockly.Blocks['procedures_callnoreturn'].onchange,
+ customContextMenu:
+ Blockly.Blocks['procedures_callnoreturn'].customContextMenu,
+ defType_: 'procedures_defreturn'
+};
+
+Blockly.Blocks['procedures_ifreturn'] = {
+ /**
+ * Block for conditionally returning a value from a procedure.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.appendValueInput('CONDITION')
+ .setCheck('Boolean')
+ .appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);
+ this.appendValueInput('VALUE')
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setColour(Blockly.Blocks.procedures.HUE);
+ this.setTooltip(Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP);
+ this.setHelpUrl(Blockly.Msg.PROCEDURES_IFRETURN_HELPURL);
+ this.hasReturnValue_ = true;
+ },
+ /**
+ * Create XML to represent whether this block has a return value.
+ * @return {!Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ container.setAttribute('value', Number(this.hasReturnValue_));
+ return container;
+ },
+ /**
+ * Parse XML to restore whether this block has a return value.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ var value = xmlElement.getAttribute('value');
+ this.hasReturnValue_ = (value == 1);
+ if (!this.hasReturnValue_) {
+ this.removeInput('VALUE');
+ this.appendDummyInput('VALUE')
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ }
+ },
+ /**
+ * Called whenever anything on the workspace changes.
+ * Add warning if this flow block is not nested inside a loop.
+ * @param {!Blockly.Events.Abstract} e Change event.
+ * @this Blockly.Block
+ */
+ onchange: function(e) {
+ var legal = false;
+ // Is the block nested in a procedure?
+ var block = this;
+ do {
+ if (this.FUNCTION_TYPES.indexOf(block.type) != -1) {
+ legal = true;
+ break;
+ }
+ block = block.getSurroundParent();
+ } while (block);
+ if (legal) {
+ // If needed, toggle whether this block has a return value.
+ if (block.type == 'procedures_defnoreturn' && this.hasReturnValue_) {
+ this.removeInput('VALUE');
+ this.appendDummyInput('VALUE')
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ this.hasReturnValue_ = false;
+ } else if (block.type == 'procedures_defreturn' &&
+ !this.hasReturnValue_) {
+ this.removeInput('VALUE');
+ this.appendValueInput('VALUE')
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ this.hasReturnValue_ = true;
+ }
+ this.setWarningText(null);
+ } else {
+ this.setWarningText(Blockly.Msg.PROCEDURES_IFRETURN_WARNING);
+ }
+ },
+ /**
+ * List of block types that are functions and thus do not need warnings.
+ * To add a new function type add this to your code:
+ * Blockly.Blocks['procedures_ifreturn'].FUNCTION_TYPES.push('custom_func');
+ */
+ FUNCTION_TYPES: ['procedures_defnoreturn', 'procedures_defreturn']
+};
diff --git a/src/blockly/blocks/text.js b/src/blockly/blocks/text.js
new file mode 100644
index 0000000..c26bb57
--- /dev/null
+++ b/src/blockly/blocks/text.js
@@ -0,0 +1,685 @@
+/**
+ * @license
+ * Visual Blocks Editor
+ *
+ * Copyright 2012 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Text blocks for Blockly.
+ * @author fraser@google.com (Neil Fraser)
+ */
+'use strict';
+
+goog.provide('Blockly.Blocks.texts');
+
+goog.require('Blockly.Blocks');
+
+
+/**
+ * Common HSV hue for all blocks in this category.
+ */
+Blockly.Blocks.texts.HUE = 160;
+
+Blockly.Blocks['text'] = {
+ /**
+ * Block for text value.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setHelpUrl(Blockly.Msg.TEXT_TEXT_HELPURL);
+ this.setColour(Blockly.Blocks.texts.HUE);
+ this.appendDummyInput()
+ .appendField(this.newQuote_(true))
+ .appendField(new Blockly.FieldTextInput(''), 'TEXT')
+ .appendField(this.newQuote_(false));
+ this.setOutput(true, 'String');
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ // Text block is trivial. Use tooltip of parent block if it exists.
+ this.setTooltip(function() {
+ var parent = thisBlock.getParent();
+ return (parent && parent.getInputsInline() && parent.tooltip) ||
+ Blockly.Msg.TEXT_TEXT_TOOLTIP;
+ });
+ },
+ /**
+ * Create an image of an open or closed quote.
+ * @param {boolean} open True if open quote, false if closed.
+ * @return {!Blockly.FieldImage} The field image of the quote.
+ * @this Blockly.Block
+ * @private
+ */
+ newQuote_: function(open) {
+ if (open == this.RTL) {
+ var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==';
+ } else {
+ var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC';
+ }
+ return new Blockly.FieldImage(file, 12, 12, '"');
+ }
+};
+
+Blockly.Blocks['text_join'] = {
+ /**
+ * Block for creating a string made up of any number of elements of any type.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setHelpUrl(Blockly.Msg.TEXT_JOIN_HELPURL);
+ this.setColour(Blockly.Blocks.texts.HUE);
+ this.itemCount_ = 2;
+ this.updateShape_();
+ this.setOutput(true, 'String');
+ this.setMutator(new Blockly.Mutator(['text_create_join_item']));
+ this.setTooltip(Blockly.Msg.TEXT_JOIN_TOOLTIP);
+ },
+ /**
+ * Create XML to represent number of text inputs.
+ * @return {!Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ container.setAttribute('items', this.itemCount_);
+ return container;
+ },
+ /**
+ * Parse XML to restore the text inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
+ this.updateShape_();
+ },
+ /**
+ * Populate the mutator's dialog with this block's components.
+ * @param {!Blockly.Workspace} workspace Mutator's workspace.
+ * @return {!Blockly.Block} Root block in mutator.
+ * @this Blockly.Block
+ */
+ decompose: function(workspace) {
+ var containerBlock = workspace.newBlock('text_create_join_container');
+ containerBlock.initSvg();
+ var connection = containerBlock.getInput('STACK').connection;
+ for (var i = 0; i < this.itemCount_; i++) {
+ var itemBlock = workspace.newBlock('text_create_join_item');
+ itemBlock.initSvg();
+ connection.connect(itemBlock.previousConnection);
+ connection = itemBlock.nextConnection;
+ }
+ return containerBlock;
+ },
+ /**
+ * Reconfigure this block based on the mutator dialog's components.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ compose: function(containerBlock) {
+ var itemBlock = containerBlock.getInputTargetBlock('STACK');
+ // Count number of inputs.
+ var connections = [];
+ while (itemBlock) {
+ connections.push(itemBlock.valueConnection_);
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ }
+ // Disconnect any children that don't belong.
+ for (var i = 0; i < this.itemCount_; i++) {
+ var connection = this.getInput('ADD' + i).connection.targetConnection;
+ if (connection && connections.indexOf(connection) == -1) {
+ connection.disconnect();
+ }
+ }
+ this.itemCount_ = connections.length;
+ this.updateShape_();
+ // Reconnect any child blocks.
+ for (var i = 0; i < this.itemCount_; i++) {
+ Blockly.Mutator.reconnect(connections[i], this, 'ADD' + i);
+ }
+ },
+ /**
+ * Store pointers to any connected child blocks.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ saveConnections: function(containerBlock) {
+ var itemBlock = containerBlock.getInputTargetBlock('STACK');
+ var i = 0;
+ while (itemBlock) {
+ var input = this.getInput('ADD' + i);
+ itemBlock.valueConnection_ = input && input.connection.targetConnection;
+ i++;
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ }
+ },
+ /**
+ * Modify this block to have the correct number of inputs.
+ * @private
+ * @this Blockly.Block
+ */
+ updateShape_: function() {
+ if (this.itemCount_ && this.getInput('EMPTY')) {
+ this.removeInput('EMPTY');
+ } else if (!this.itemCount_ && !this.getInput('EMPTY')) {
+ this.appendDummyInput('EMPTY')
+ .appendField(this.newQuote_(true))
+ .appendField(this.newQuote_(false));
+ }
+ // Add new inputs.
+ for (var i = 0; i < this.itemCount_; i++) {
+ if (!this.getInput('ADD' + i)) {
+ var input = this.appendValueInput('ADD' + i);
+ if (i == 0) {
+ input.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH);
+ }
+ }
+ }
+ // Remove deleted inputs.
+ while (this.getInput('ADD' + i)) {
+ this.removeInput('ADD' + i);
+ i++;
+ }
+ },
+ newQuote_: Blockly.Blocks['text'].newQuote_
+};
+
+Blockly.Blocks['text_create_join_container'] = {
+ /**
+ * Mutator block for container.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setColour(Blockly.Blocks.texts.HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.TEXT_CREATE_JOIN_TITLE_JOIN);
+ this.appendStatementInput('STACK');
+ this.setTooltip(Blockly.Msg.TEXT_CREATE_JOIN_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+Blockly.Blocks['text_create_join_item'] = {
+ /**
+ * Mutator block for add items.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setColour(Blockly.Blocks.texts.HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+Blockly.Blocks['text_append'] = {
+ /**
+ * Block for appending to a variable in place.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setHelpUrl(Blockly.Msg.TEXT_APPEND_HELPURL);
+ this.setColour(Blockly.Blocks.texts.HUE);
+ this.appendValueInput('TEXT')
+ .appendField(Blockly.Msg.TEXT_APPEND_TO)
+ .appendField(new Blockly.FieldVariable(
+ Blockly.Msg.TEXT_APPEND_VARIABLE), 'VAR')
+ .appendField(Blockly.Msg.TEXT_APPEND_APPENDTEXT);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ return Blockly.Msg.TEXT_APPEND_TOOLTIP.replace('%1',
+ thisBlock.getFieldValue('VAR'));
+ });
+ }
+};
+
+Blockly.Blocks['text_length'] = {
+ /**
+ * Block for string length.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.TEXT_LENGTH_TITLE,
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "VALUE",
+ "check": ['String', 'Array']
+ }
+ ],
+ "output": 'Number',
+ "colour": Blockly.Blocks.texts.HUE,
+ "tooltip": Blockly.Msg.TEXT_LENGTH_TOOLTIP,
+ "helpUrl": Blockly.Msg.TEXT_LENGTH_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['text_isEmpty'] = {
+ /**
+ * Block for is the string null?
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.TEXT_ISEMPTY_TITLE,
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "VALUE",
+ "check": ['String', 'Array']
+ }
+ ],
+ "output": 'Boolean',
+ "colour": Blockly.Blocks.texts.HUE,
+ "tooltip": Blockly.Msg.TEXT_ISEMPTY_TOOLTIP,
+ "helpUrl": Blockly.Msg.TEXT_ISEMPTY_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['text_indexOf'] = {
+ /**
+ * Block for finding a substring in the text.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var OPERATORS =
+ [[Blockly.Msg.TEXT_INDEXOF_OPERATOR_FIRST, 'FIRST'],
+ [Blockly.Msg.TEXT_INDEXOF_OPERATOR_LAST, 'LAST']];
+ this.setHelpUrl(Blockly.Msg.TEXT_INDEXOF_HELPURL);
+ this.setColour(Blockly.Blocks.texts.HUE);
+ this.setOutput(true, 'Number');
+ this.appendValueInput('VALUE')
+ .setCheck('String')
+ .appendField(Blockly.Msg.TEXT_INDEXOF_INPUT_INTEXT);
+ this.appendValueInput('FIND')
+ .setCheck('String')
+ .appendField(new Blockly.FieldDropdown(OPERATORS), 'END');
+ if (Blockly.Msg.TEXT_INDEXOF_TAIL) {
+ this.appendDummyInput().appendField(Blockly.Msg.TEXT_INDEXOF_TAIL);
+ }
+ this.setInputsInline(true);
+ var tooltip = Blockly.Msg.TEXT_INDEXOF_TOOLTIP
+ .replace('%1', Blockly.Blocks.ONE_BASED_INDEXING ? '0' : '-1');
+ this.setTooltip(tooltip);
+ }
+};
+
+Blockly.Blocks['text_charAt'] = {
+ /**
+ * Block for getting a character from the string.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.WHERE_OPTIONS =
+ [[Blockly.Msg.TEXT_CHARAT_FROM_START, 'FROM_START'],
+ [Blockly.Msg.TEXT_CHARAT_FROM_END, 'FROM_END'],
+ [Blockly.Msg.TEXT_CHARAT_FIRST, 'FIRST'],
+ [Blockly.Msg.TEXT_CHARAT_LAST, 'LAST'],
+ [Blockly.Msg.TEXT_CHARAT_RANDOM, 'RANDOM']];
+ this.setHelpUrl(Blockly.Msg.TEXT_CHARAT_HELPURL);
+ this.setColour(Blockly.Blocks.texts.HUE);
+ this.setOutput(true, 'String');
+ this.appendValueInput('VALUE')
+ .setCheck('String')
+ .appendField(Blockly.Msg.TEXT_CHARAT_INPUT_INTEXT);
+ this.appendDummyInput('AT');
+ this.setInputsInline(true);
+ this.updateAt_(true);
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function() {
+ var where = thisBlock.getFieldValue('WHERE');
+ var tooltip = Blockly.Msg.TEXT_CHARAT_TOOLTIP;
+ if (where == 'FROM_START' || where == 'FROM_END') {
+ tooltip += ' ' + Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP
+ .replace('%1', Blockly.Blocks.ONE_BASED_INDEXING ? '#1' : '#0');
+ }
+ return tooltip;
+ });
+ },
+ /**
+ * Create XML to represent whether there is an 'AT' input.
+ * @return {!Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ var isAt = this.getInput('AT').type == Blockly.INPUT_VALUE;
+ container.setAttribute('at', isAt);
+ return container;
+ },
+ /**
+ * Parse XML to restore the 'AT' input.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ // Note: Until January 2013 this block did not have mutations,
+ // so 'at' defaults to true.
+ var isAt = (xmlElement.getAttribute('at') != 'false');
+ this.updateAt_(isAt);
+ },
+ /**
+ * Create or delete an input for the numeric index.
+ * @param {boolean} isAt True if the input should exist.
+ * @private
+ * @this Blockly.Block
+ */
+ updateAt_: function(isAt) {
+ // Destroy old 'AT' and 'ORDINAL' inputs.
+ this.removeInput('AT');
+ this.removeInput('ORDINAL', true);
+ // Create either a value 'AT' input or a dummy input.
+ if (isAt) {
+ this.appendValueInput('AT').setCheck('Number');
+ if (Blockly.Msg.ORDINAL_NUMBER_SUFFIX) {
+ this.appendDummyInput('ORDINAL')
+ .appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX);
+ }
+ } else {
+ this.appendDummyInput('AT');
+ }
+ if (Blockly.Msg.TEXT_CHARAT_TAIL) {
+ this.removeInput('TAIL', true);
+ this.appendDummyInput('TAIL')
+ .appendField(Blockly.Msg.TEXT_CHARAT_TAIL);
+ }
+ var menu = new Blockly.FieldDropdown(this.WHERE_OPTIONS, function(value) {
+ var newAt = (value == 'FROM_START') || (value == 'FROM_END');
+ // The 'isAt' variable is available due to this function being a closure.
+ if (newAt != isAt) {
+ var block = this.sourceBlock_;
+ block.updateAt_(newAt);
+ // This menu has been destroyed and replaced. Update the replacement.
+ block.setFieldValue(value, 'WHERE');
+ return null;
+ }
+ return undefined;
+ });
+ this.getInput('AT').appendField(menu, 'WHERE');
+ }
+};
+
+Blockly.Blocks['text_getSubstring'] = {
+ /**
+ * Block for getting substring.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this['WHERE_OPTIONS_1'] =
+ [[Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_START, 'FROM_START'],
+ [Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_END, 'FROM_END'],
+ [Blockly.Msg.TEXT_GET_SUBSTRING_START_FIRST, 'FIRST']];
+ this['WHERE_OPTIONS_2'] =
+ [[Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_START, 'FROM_START'],
+ [Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_END, 'FROM_END'],
+ [Blockly.Msg.TEXT_GET_SUBSTRING_END_LAST, 'LAST']];
+ this.setHelpUrl(Blockly.Msg.TEXT_GET_SUBSTRING_HELPURL);
+ this.setColour(Blockly.Blocks.texts.HUE);
+ this.appendValueInput('STRING')
+ .setCheck('String')
+ .appendField(Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT);
+ this.appendDummyInput('AT1');
+ this.appendDummyInput('AT2');
+ if (Blockly.Msg.TEXT_GET_SUBSTRING_TAIL) {
+ this.appendDummyInput('TAIL')
+ .appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL);
+ }
+ this.setInputsInline(true);
+ this.setOutput(true, 'String');
+ this.updateAt_(1, true);
+ this.updateAt_(2, true);
+ this.setTooltip(Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP);
+ },
+ /**
+ * Create XML to represent whether there are 'AT' inputs.
+ * @return {!Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ var isAt1 = this.getInput('AT1').type == Blockly.INPUT_VALUE;
+ container.setAttribute('at1', isAt1);
+ var isAt2 = this.getInput('AT2').type == Blockly.INPUT_VALUE;
+ container.setAttribute('at2', isAt2);
+ return container;
+ },
+ /**
+ * Parse XML to restore the 'AT' inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ var isAt1 = (xmlElement.getAttribute('at1') == 'true');
+ var isAt2 = (xmlElement.getAttribute('at2') == 'true');
+ this.updateAt_(1, isAt1);
+ this.updateAt_(2, isAt2);
+ },
+ /**
+ * Create or delete an input for a numeric index.
+ * This block has two such inputs, independant of each other.
+ * @param {number} n Specify first or second input (1 or 2).
+ * @param {boolean} isAt True if the input should exist.
+ * @private
+ * @this Blockly.Block
+ */
+ updateAt_: function(n, isAt) {
+ // Create or delete an input for the numeric index.
+ // Destroy old 'AT' and 'ORDINAL' inputs.
+ this.removeInput('AT' + n);
+ this.removeInput('ORDINAL' + n, true);
+ // Create either a value 'AT' input or a dummy input.
+ if (isAt) {
+ this.appendValueInput('AT' + n).setCheck('Number');
+ if (Blockly.Msg.ORDINAL_NUMBER_SUFFIX) {
+ this.appendDummyInput('ORDINAL' + n)
+ .appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX);
+ }
+ } else {
+ this.appendDummyInput('AT' + n);
+ }
+ // Move tail, if present, to end of block.
+ if (n == 2 && Blockly.Msg.TEXT_GET_SUBSTRING_TAIL) {
+ this.removeInput('TAIL', true);
+ this.appendDummyInput('TAIL')
+ .appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL);
+ }
+ var menu = new Blockly.FieldDropdown(this['WHERE_OPTIONS_' + n],
+ function(value) {
+ var newAt = (value == 'FROM_START') || (value == 'FROM_END');
+ // The 'isAt' variable is available due to this function being a
+ // closure.
+ if (newAt != isAt) {
+ var block = this.sourceBlock_;
+ block.updateAt_(n, newAt);
+ // This menu has been destroyed and replaced.
+ // Update the replacement.
+ block.setFieldValue(value, 'WHERE' + n);
+ return null;
+ }
+ return undefined;
+ });
+
+ this.getInput('AT' + n)
+ .appendField(menu, 'WHERE' + n);
+ if (n == 1) {
+ this.moveInputBefore('AT1', 'AT2');
+ }
+ }
+};
+
+Blockly.Blocks['text_changeCase'] = {
+ /**
+ * Block for changing capitalization.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var OPERATORS =
+ [[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE, 'UPPERCASE'],
+ [Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE, 'LOWERCASE'],
+ [Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE, 'TITLECASE']];
+ this.setHelpUrl(Blockly.Msg.TEXT_CHANGECASE_HELPURL);
+ this.setColour(Blockly.Blocks.texts.HUE);
+ this.appendValueInput('TEXT')
+ .setCheck('String')
+ .appendField(new Blockly.FieldDropdown(OPERATORS), 'CASE');
+ this.setOutput(true, 'String');
+ this.setTooltip(Blockly.Msg.TEXT_CHANGECASE_TOOLTIP);
+ }
+};
+
+Blockly.Blocks['text_trim'] = {
+ /**
+ * Block for trimming spaces.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var OPERATORS =
+ [[Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH, 'BOTH'],
+ [Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT, 'LEFT'],
+ [Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT, 'RIGHT']];
+ this.setHelpUrl(Blockly.Msg.TEXT_TRIM_HELPURL);
+ this.setColour(Blockly.Blocks.texts.HUE);
+ this.appendValueInput('TEXT')
+ .setCheck('String')
+ .appendField(new Blockly.FieldDropdown(OPERATORS), 'MODE');
+ this.setOutput(true, 'String');
+ this.setTooltip(Blockly.Msg.TEXT_TRIM_TOOLTIP);
+ }
+};
+
+Blockly.Blocks['text_print'] = {
+ /**
+ * Block for print statement.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.TEXT_PRINT_TITLE,
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "TEXT"
+ }
+ ],
+ "previousStatement": null,
+ "nextStatement": null,
+ "colour": Blockly.Blocks.texts.HUE,
+ "tooltip": Blockly.Msg.TEXT_PRINT_TOOLTIP,
+ "helpUrl": Blockly.Msg.TEXT_PRINT_HELPURL
+ });
+ }
+};
+
+Blockly.Blocks['text_prompt_ext'] = {
+ /**
+ * Block for prompt function (external message).
+ * @this Blockly.Block
+ */
+ init: function() {
+ var TYPES =
+ [[Blockly.Msg.TEXT_PROMPT_TYPE_TEXT, 'TEXT'],
+ [Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER, 'NUMBER']];
+ this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);
+ this.setColour(Blockly.Blocks.texts.HUE);
+ // Assign 'this' to a variable for use in the closures below.
+ var thisBlock = this;
+ var dropdown = new Blockly.FieldDropdown(TYPES, function(newOp) {
+ thisBlock.updateType_(newOp);
+ });
+ this.appendValueInput('TEXT')
+ .appendField(dropdown, 'TYPE');
+ this.setOutput(true, 'String');
+ this.setTooltip(function() {
+ return (thisBlock.getFieldValue('TYPE') == 'TEXT') ?
+ Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT :
+ Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER;
+ });
+ },
+ /**
+ * Modify this block to have the correct output type.
+ * @param {string} newOp Either 'TEXT' or 'NUMBER'.
+ * @private
+ * @this Blockly.Block
+ */
+ updateType_: function(newOp) {
+ this.outputConnection.setCheck(newOp == 'NUMBER' ? 'Number' : 'String');
+ },
+ /**
+ * Create XML to represent the output type.
+ * @return {!Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function() {
+ var container = document.createElement('mutation');
+ container.setAttribute('type', this.getFieldValue('TYPE'));
+ return container;
+ },
+ /**
+ * Parse XML to restore the output type.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function(xmlElement) {
+ this.updateType_(xmlElement.getAttribute('type'));
+ }
+};
+
+Blockly.Blocks['text_prompt'] = {
+ /**
+ * Block for prompt function (internal message).
+ * The 'text_prompt_ext' block is preferred as it is more flexible.
+ * @this Blockly.Block
+ */
+ init: function() {
+ var TYPES =
+ [[Blockly.Msg.TEXT_PROMPT_TYPE_TEXT, 'TEXT'],
+ [Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER, 'NUMBER']];
+ // Assign 'this' to a variable for use in the closures below.
+ var thisBlock = this;
+ this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);
+ this.setColour(Blockly.Blocks.texts.HUE);
+ var dropdown = new Blockly.FieldDropdown(TYPES, function(newOp) {
+ thisBlock.updateType_(newOp);
+ });
+ this.appendDummyInput()
+ .appendField(dropdown, 'TYPE')
+ .appendField(this.newQuote_(true))
+ .appendField(new Blockly.FieldTextInput(''), 'TEXT')
+ .appendField(this.newQuote_(false));
+ this.setOutput(true, 'String');
+ this.setTooltip(function() {
+ return (thisBlock.getFieldValue('TYPE') == 'TEXT') ?
+ Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT :
+ Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER;
+ });
+ },
+ newQuote_: Blockly.Blocks['text'].newQuote_,
+ updateType_: Blockly.Blocks['text_prompt_ext'].updateType_,
+ mutationToDom: Blockly.Blocks['text_prompt_ext'].mutationToDom,
+ domToMutation: Blockly.Blocks['text_prompt_ext'].domToMutation
+};
diff --git a/src/blockly/blocks/variables.js b/src/blockly/blocks/variables.js
new file mode 100644
index 0000000..3b7d99f
--- /dev/null
+++ b/src/blockly/blocks/variables.js
@@ -0,0 +1,100 @@
+/**
+ * @license
+ * Visual Blocks Editor
+ *
+ * Copyright 2012 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Variable blocks for Blockly.
+ * @author fraser@google.com (Neil Fraser)
+ */
+'use strict';
+
+goog.provide('Blockly.Blocks.variables');
+
+goog.require('Blockly.Blocks');
+
+
+/**
+ * Common HSV hue for all blocks in this category.
+ */
+Blockly.Blocks.variables.HUE = 330;
+
+Blockly.Blocks['variables_get'] = {
+ /**
+ * Block for variable getter.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.setHelpUrl(Blockly.Msg.VARIABLES_GET_HELPURL);
+ this.setColour(Blockly.Blocks.variables.HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldVariable(
+ Blockly.Msg.VARIABLES_DEFAULT_NAME), 'VAR');
+ this.setOutput(true);
+ this.setTooltip(Blockly.Msg.VARIABLES_GET_TOOLTIP);
+ this.contextMenuMsg_ = Blockly.Msg.VARIABLES_GET_CREATE_SET;
+ },
+ contextMenuType_: 'variables_set',
+ /**
+ * Add menu option to create getter/setter block for this setter/getter.
+ * @param {!Array} options List of menu options to add to.
+ * @this Blockly.Block
+ */
+ customContextMenu: function(options) {
+ var option = {enabled: true};
+ var name = this.getFieldValue('VAR');
+ option.text = this.contextMenuMsg_.replace('%1', name);
+ var xmlField = goog.dom.createDom('field', null, name);
+ xmlField.setAttribute('name', 'VAR');
+ var xmlBlock = goog.dom.createDom('block', null, xmlField);
+ xmlBlock.setAttribute('type', this.contextMenuType_);
+ option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
+ options.push(option);
+ }
+};
+
+Blockly.Blocks['variables_set'] = {
+ /**
+ * Block for variable setter.
+ * @this Blockly.Block
+ */
+ init: function() {
+ this.jsonInit({
+ "message0": Blockly.Msg.VARIABLES_SET,
+ "args0": [
+ {
+ "type": "field_variable",
+ "name": "VAR",
+ "variable": Blockly.Msg.VARIABLES_DEFAULT_NAME
+ },
+ {
+ "type": "input_value",
+ "name": "VALUE"
+ }
+ ],
+ "previousStatement": null,
+ "nextStatement": null,
+ "colour": Blockly.Blocks.variables.HUE,
+ "tooltip": Blockly.Msg.VARIABLES_SET_TOOLTIP,
+ "helpUrl": Blockly.Msg.VARIABLES_SET_HELPURL
+ });
+ this.contextMenuMsg_ = Blockly.Msg.VARIABLES_SET_CREATE_GET;
+ },
+ contextMenuType_: 'variables_get',
+ customContextMenu: Blockly.Blocks['variables_get'].customContextMenu
+};
diff --git a/src/blockly/core/events.js b/src/blockly/core/events.js
index 1d1e2b7..dcec635 100644
--- a/src/blockly/core/events.js
+++ b/src/blockly/core/events.js
@@ -302,7 +302,7 @@ Blockly.Events.Abstract = function(block) {
*/
Blockly.Events.Abstract.prototype.toJson = function() {
var json = {
- 'type': this.type,
+ 'type': this.type
};
if (this.blockId) {
json['blockId'] = this.blockId;
diff --git a/src/blockly/msg/messages.js b/src/blockly/msg/messages.js
new file mode 100644
index 0000000..f4b0559
--- /dev/null
+++ b/src/blockly/msg/messages.js
@@ -0,0 +1,1113 @@
+/**
+ * @license
+ * Visual Blocks Language
+ *
+ * Copyright 2012 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview English strings.
+ * @author fraser@google.com (Neil Fraser)
+ *
+ * After modifying this file, either run "build.py" from the parent directory,
+ * or run (from this directory):
+ * ../i18n/js_to_json.py
+ * to regenerate json/{en,qqq,synonyms}.json.
+ *
+ * To convert all of the json files to .js files, run:
+ * ../i18n/create_messages.py json/*.json
+ */
+'use strict';
+
+goog.provide('Blockly.Msg.en');
+
+goog.require('Blockly.Msg');
+
+
+/**
+ * Due to the frequency of long strings, the 80-column wrap rule need not apply
+ * to message files.
+ */
+
+/**
+ * Each message is preceded with a tripple-slash comment that becomes the
+ * message descriptor. The build process extracts these descriptors, adds
+ * them to msg/json/qqq.json, and they show up in the translation console.
+ */
+
+/// default name - A simple, general default name for a variable, preferably short.
+/// For more context, see
+/// [[Translating:Blockly#infrequent_message_types]].\n{{Identical|Item}}
+Blockly.Msg.VARIABLES_DEFAULT_NAME = 'item';
+/// button text - Button that sets a calendar to today's date.\n{{Identical|Today}}
+Blockly.Msg.TODAY = 'Today';
+
+// Context menus.
+/// context menu - Make a copy of the selected block (and any blocks it contains).\n{{Identical|Duplicate}}
+Blockly.Msg.DUPLICATE_BLOCK = 'Duplicate';
+/// context menu - Add a descriptive comment to the selected block.
+Blockly.Msg.ADD_COMMENT = 'Add Comment';
+/// context menu - Remove the descriptive comment from the selected block.
+Blockly.Msg.REMOVE_COMMENT = 'Remove Comment';
+/// context menu - Change from 'external' to 'inline' mode for displaying blocks used as inputs to the selected block. See [[Translating:Blockly#context_menus]].
+Blockly.Msg.EXTERNAL_INPUTS = 'External Inputs';
+/// context menu - Change from 'internal' to 'external' mode for displaying blocks used as inputs to the selected block. See [[Translating:Blockly#context_menus]].
+Blockly.Msg.INLINE_INPUTS = 'Inline Inputs';
+/// context menu - Permanently delete the selected block.
+Blockly.Msg.DELETE_BLOCK = 'Delete Block';
+/// context menu - Permanently delete the %1 selected blocks.\n\nParameters:\n* %1 - an integer greater than 1.
+Blockly.Msg.DELETE_X_BLOCKS = 'Delete %1 Blocks';
+/// confirmation prompt - Question the user if they really wanted to permanently delete all %1 blocks.\n\nParameters:\n* %1 - an integer greater than 1.
+Blockly.Msg.DELETE_ALL_BLOCKS = 'Delete all %1 blocks?';
+/// context menu - Reposition all the blocks so that they form a neat line.
+Blockly.Msg.CLEAN_UP = 'Clean up Blocks';
+/// context menu - Make the appearance of the selected block smaller by hiding some information about it.
+Blockly.Msg.COLLAPSE_BLOCK = 'Collapse Block';
+/// context menu - Make the appearance of all blocks smaller by hiding some information about it. Use the same terminology as in the previous message.
+Blockly.Msg.COLLAPSE_ALL = 'Collapse Blocks';
+/// context menu - Restore the appearance of the selected block by showing information about it that was hidden (collapsed) earlier.
+Blockly.Msg.EXPAND_BLOCK = 'Expand Block';
+/// context menu - Restore the appearance of all blocks by showing information about it that was hidden (collapsed) earlier. Use the same terminology as in the previous message.
+Blockly.Msg.EXPAND_ALL = 'Expand Blocks';
+/// context menu - Make the selected block have no effect (unless reenabled).
+Blockly.Msg.DISABLE_BLOCK = 'Disable Block';
+/// context menu - Make the selected block have effect (after having been disabled earlier).
+Blockly.Msg.ENABLE_BLOCK = 'Enable Block';
+/// context menu - Provide helpful information about the selected block.\n{{Identical|Help}}
+Blockly.Msg.HELP = 'Help';
+/// context menu - Undo the previous action.\n{{Identical|Undo}}
+Blockly.Msg.UNDO = 'Undo';
+/// context menu - Undo the previous undo action.\n{{Identical|Redo}}
+Blockly.Msg.REDO = 'Redo';
+
+// Variable renaming.
+/// prompt - This message is only seen in the Opera browser. With most browsers, users can edit numeric values in blocks by just clicking and typing. Opera does not allows this, so we have to open a new window and prompt users with this message to chanage a value.
+Blockly.Msg.CHANGE_VALUE_TITLE = 'Change value:';
+/// dropdown choice - When the user clicks on a variable block, this is one of the dropdown menu choices. It is used to rename the current variable. See [https://github.com/google/blockly/wiki/Variables#dropdown-menu https://github.com/google/blockly/wiki/Variables#dropdown-menu].
+Blockly.Msg.RENAME_VARIABLE = 'Rename variable...';
+/// prompt - Prompts the user to enter the new name for the selected variable. See [https://github.com/google/blockly/wiki/Variables#dropdown-menu https://github.com/google/blockly/wiki/Variables#dropdown-menu].\n\nParameters:\n* %1 - the name of the variable to be renamed.
+Blockly.Msg.RENAME_VARIABLE_TITLE = 'Rename all "%1" variables to:';
+
+// Variable creation
+/// button text - Text on the button used to launch the variable creation dialogue.
+Blockly.Msg.NEW_VARIABLE = 'Create variable...';
+/// prompt - Prompts the user to enter the name for a new variable. See [https://github.com/google/blockly/wiki/Variables#dropdown-menu https://github.com/google/blockly/wiki/Variables#dropdown-menu].
+Blockly.Msg.NEW_VARIABLE_TITLE = 'New variable name:';
+/// alert - Tells the user that the name they entered is already in use.
+Blockly.Msg.VARIABLE_ALREADY_EXISTS = 'A variable named "%1" already exists.'
+
+// Variable deletion.
+/// confirm - Ask the user to confirm their deletion of multiple uses of a variable.
+Blockly.Msg.DELETE_VARIABLE_CONFIRMATION = 'Delete %1 uses of the "%2" variable?';
+/// alert - Tell the user that they can't delete a variable because it's part of the definition of a procedure.
+Blockly.Msg.CANNOT_DELETE_VARIABLE_PROCEDURE = 'Can\'t delete the variable "%1" because it is part of the definition of the procedure "%2"';
+/// dropdown choice - Delete the currently selected variable.
+Blockly.Msg.DELETE_VARIABLE = 'Delete the "%1" variable';
+
+// Colour Blocks.
+/// url - Information about colour.
+Blockly.Msg.COLOUR_PICKER_HELPURL = 'https://en.wikipedia.org/wiki/Color';
+/// tooltip - See [https://github.com/google/blockly/wiki/Colour#picking-a-colour-from-a-palette https://github.com/google/blockly/wiki/Colour#picking-a-colour-from-a-palette].
+Blockly.Msg.COLOUR_PICKER_TOOLTIP = 'Choose a colour from the palette.';
+/// url - A link that displays a random colour each time you visit it.
+Blockly.Msg.COLOUR_RANDOM_HELPURL = 'http://randomcolour.com';
+/// block text - Title of block that generates a colour at random.
+Blockly.Msg.COLOUR_RANDOM_TITLE = 'random colour';
+/// tooltip - See [https://github.com/google/blockly/wiki/Colour#generating-a-random-colour https://github.com/google/blockly/wiki/Colour#generating-a-random-colour].
+Blockly.Msg.COLOUR_RANDOM_TOOLTIP = 'Choose a colour at random.';
+/// url - A link for color codes with percentages (0-100%) for each component, instead of the more common 0-255, which may be more difficult for beginners.
+Blockly.Msg.COLOUR_RGB_HELPURL = 'http://www.december.com/html/spec/colorper.html';
+/// block text - Title of block for [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].
+Blockly.Msg.COLOUR_RGB_TITLE = 'colour with';
+/// block input text - The amount of red (from 0 to 100) to use when [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].\n{{Identical|Red}}
+Blockly.Msg.COLOUR_RGB_RED = 'red';
+/// block input text - The amount of green (from 0 to 100) to use when [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].
+Blockly.Msg.COLOUR_RGB_GREEN = 'green';
+/// block input text - The amount of blue (from 0 to 100) to use when [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].\n{{Identical|Blue}}
+Blockly.Msg.COLOUR_RGB_BLUE = 'blue';
+/// tooltip - See [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].
+Blockly.Msg.COLOUR_RGB_TOOLTIP = 'Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.';
+/// url - A useful link that displays blending of two colors.
+Blockly.Msg.COLOUR_BLEND_HELPURL = 'http://meyerweb.com/eric/tools/color-blend/';
+/// block text - A verb for blending two shades of paint.
+Blockly.Msg.COLOUR_BLEND_TITLE = 'blend';
+/// block input text - The first of two colours to [https://github.com/google/blockly/wiki/Colour#blending-colours blend].
+Blockly.Msg.COLOUR_BLEND_COLOUR1 = 'colour 1';
+/// block input text - The second of two colours to [https://github.com/google/blockly/wiki/Colour#blending-colours blend].
+Blockly.Msg.COLOUR_BLEND_COLOUR2 = 'colour 2';
+/// block input text - The proportion of the [https://github.com/google/blockly/wiki/Colour#blending-colours blend] containing the first color; the remaining proportion is of the second colour. For example, if the first colour is red and the second color blue, a ratio of 1 would yield pure red, a ratio of .5 would yield purple (equal amounts of red and blue), and a ratio of 0 would yield pure blue.\n{{Identical|Ratio}}
+Blockly.Msg.COLOUR_BLEND_RATIO = 'ratio';
+/// tooltip - See [https://github.com/google/blockly/wiki/Colour#blending-colours https://github.com/google/blockly/wiki/Colour#blending-colours].
+Blockly.Msg.COLOUR_BLEND_TOOLTIP = 'Blends two colours together with a given ratio (0.0 - 1.0).';
+
+// Loop Blocks.
+/// url - Describes 'repeat loops' in computer programs; consider using the translation of the page [https://en.wikipedia.org/wiki/Control_flow http://en.wikipedia.org/wiki/Control_flow].
+Blockly.Msg.CONTROLS_REPEAT_HELPURL = 'https://en.wikipedia.org/wiki/For_loop';
+/// block input text - Title of [https://github.com/google/blockly/wiki/Loops#repeat repeat block].\n\nParameters:\n* %1 - the number of times the body of the loop should be repeated.
+Blockly.Msg.CONTROLS_REPEAT_TITLE = 'repeat %1 times';
+/// block text - Preceding the blocks in the body of the loop. See [https://github.com/google/blockly/wiki/Loops https://github.com/google/blockly/wiki/Loops].\n{{Identical|Do}}
+Blockly.Msg.CONTROLS_REPEAT_INPUT_DO = 'do';
+/// tooltip - See [https://github.com/google/blockly/wiki/Loops#repeat https://github.com/google/blockly/wiki/Loops#repeat].
+Blockly.Msg.CONTROLS_REPEAT_TOOLTIP = 'Do some statements several times.';
+/// url - Describes 'while loops' in computer programs; consider using the translation of [https://en.wikipedia.org/wiki/While_loop https://en.wikipedia.org/wiki/While_loop], if present, or [https://en.wikipedia.org/wiki/Control_flow https://en.wikipedia.org/wiki/Control_flow].
+Blockly.Msg.CONTROLS_WHILEUNTIL_HELPURL = 'https://github.com/google/blockly/wiki/Loops#repeat';
+Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
+/// dropdown - Specifies that a loop should [https://github.com/google/blockly/wiki/Loops#repeat-while repeat while] the following condition is true.
+Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_WHILE = 'repeat while';
+/// dropdown - Specifies that a loop should [https://github.com/google/blockly/wiki/Loops#repeat-until repeat until] the following condition becomes true.
+Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_UNTIL = 'repeat until';
+/// tooltip - See [https://github.com/google/blockly/wiki/Loops#repeat-while Loops#repeat-while https://github.com/google/blockly/wiki/Loops#repeat-while Loops#repeat-while].
+Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_WHILE = 'While a value is true, then do some statements.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Loops#repeat-until https://github.com/google/blockly/wiki/Loops#repeat-until].
+Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL = 'While a value is false, then do some statements.';
+
+/// url - Describes 'for loops' in computer programs. Consider using your language's translation of [https://en.wikipedia.org/wiki/For_loop https://en.wikipedia.org/wiki/For_loop], if present.
+Blockly.Msg.CONTROLS_FOR_HELPURL = 'https://github.com/google/blockly/wiki/Loops#count-with';
+/// tooltip - See [https://github.com/google/blockly/wiki/Loops#count-with https://github.com/google/blockly/wiki/Loops#count-with].\n\nParameters:\n* %1 - the name of the loop variable.
+Blockly.Msg.CONTROLS_FOR_TOOLTIP = 'Have the variable "%1" take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.';
+/// block text - Repeatedly counts a variable (%1)
+/// starting with a (usually lower) number in a range (%2),
+/// ending with a (usually higher) number in a range (%3), and counting the
+/// iterations by a number of steps (%4). As in
+/// [https://github.com/google/blockly/wiki/Loops#count-with
+/// https://github.com/google/blockly/wiki/Loops#count-with].
+/// [[File:Blockly-count-with.png]]
+Blockly.Msg.CONTROLS_FOR_TITLE = 'count with %1 from %2 to %3 by %4';
+Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
+
+/// url - Describes 'for-each loops' in computer programs. Consider using your language's translation of [https://en.wikipedia.org/wiki/Foreach https://en.wikipedia.org/wiki/Foreach] if present.
+Blockly.Msg.CONTROLS_FOREACH_HELPURL = 'https://github.com/google/blockly/wiki/Loops#for-each';
+/// block text - Title of [https://github.com/google/blockly/wiki/Loops#for-each for each block].
+/// Sequentially assigns every item in array %2 to the valiable %1.
+Blockly.Msg.CONTROLS_FOREACH_TITLE = 'for each item %1 in list %2';
+Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
+/// block text - Description of [https://github.com/google/blockly/wiki/Loops#for-each for each blocks].\n\nParameters:\n* %1 - the name of the loop variable.
+Blockly.Msg.CONTROLS_FOREACH_TOOLTIP = 'For each item in a list, set the variable "%1" to the item, and then do some statements.';
+
+/// url - Describes control flow in computer programs. Consider using your language's translation of [https://en.wikipedia.org/wiki/Control_flow https://en.wikipedia.org/wiki/Control_flow], if it exists.
+Blockly.Msg.CONTROLS_FLOW_STATEMENTS_HELPURL = 'https://github.com/google/blockly/wiki/Loops#loop-termination-blocks';
+/// dropdown - The current loop should be exited. See [https://github.com/google/blockly/wiki/Loops#break https://github.com/google/blockly/wiki/Loops#break].
+Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK = 'break out of loop';
+/// dropdown - The current iteration of the loop should be ended and the next should begin. See [https://github.com/google/blockly/wiki/Loops#continue-with-next-iteration https://github.com/google/blockly/wiki/Loops#continue-with-next-iteration].
+Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE = 'continue with next iteration of loop';
+/// tooltip - See [https://github.com/google/blockly/wiki/Loops#break-out-of-loop https://github.com/google/blockly/wiki/Loops#break-out-of-loop].
+Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK = 'Break out of the containing loop.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Loops#continue-with-next-iteration https://github.com/google/blockly/wiki/Loops#continue-with-next-iteration].
+Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE = 'Skip the rest of this loop, and continue with the next iteration.';
+/// warning - The user has tried placing a block outside of a loop (for each, while, repeat, etc.), but this type of block may only be used within a loop. See [https://github.com/google/blockly/wiki/Loops#loop-termination-blocks https://github.com/google/blockly/wiki/Loops#loop-termination-blocks].
+Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING = 'Warning: This block may only be used within a loop.';
+
+// Logic Blocks.
+/// url - Describes conditional statements (if-then-else) in computer programs. Consider using your language's translation of [https://en.wikipedia.org/wiki/If_else https://en.wikipedia.org/wiki/If_else], if present.
+Blockly.Msg.CONTROLS_IF_HELPURL = 'https://github.com/google/blockly/wiki/IfElse';
+/// tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#if-blocks 'if' blocks]. Consider using your language's translation of [https://en.wikipedia.org/wiki/If_statement https://en.wikipedia.org/wiki/If_statement], if present.
+Blockly.Msg.CONTROLS_IF_TOOLTIP_1 = 'If a value is true, then do some statements.';
+/// tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#if-else-blocks if-else blocks]. Consider using your language's translation of [https://en.wikipedia.org/wiki/If_statement https://en.wikipedia.org/wiki/If_statement], if present.
+Blockly.Msg.CONTROLS_IF_TOOLTIP_2 = 'If a value is true, then do the first block of statements. Otherwise, do the second block of statements.';
+/// tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#if-else-if-blocks if-else-if blocks]. Consider using your language's translation of [https://en.wikipedia.org/wiki/If_statement https://en.wikipedia.org/wiki/If_statement], if present.
+Blockly.Msg.CONTROLS_IF_TOOLTIP_3 = 'If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.';
+/// tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#if-else-if-else-blocks if-else-if-else blocks]. Consider using your language's translation of [https://en.wikipedia.org/wiki/If_statement https://en.wikipedia.org/wiki/If_statement], if present.
+Blockly.Msg.CONTROLS_IF_TOOLTIP_4 = 'If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.';
+/// block text - See [https://github.com/google/blockly/wiki/IfElse https://github.com/google/blockly/wiki/IfElse].
+/// It is recommended, but not essential, that this have text in common with the translation of 'else if'
+Blockly.Msg.CONTROLS_IF_MSG_IF = 'if';
+/// block text - See [https://github.com/google/blockly/wiki/IfElse https://github.com/google/blockly/wiki/IfElse]. The English words "otherwise if" would probably be clearer than "else if", but the latter is used because it is traditional and shorter.
+Blockly.Msg.CONTROLS_IF_MSG_ELSEIF = 'else if';
+/// block text - See [https://github.com/google/blockly/wiki/IfElse https://github.com/google/blockly/wiki/IfElse]. The English word "otherwise" would probably be superior to "else", but the latter is used because it is traditional and shorter.
+Blockly.Msg.CONTROLS_IF_MSG_ELSE = 'else';
+Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
+Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
+/// tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#block-modification if block modification].
+Blockly.Msg.CONTROLS_IF_IF_TOOLTIP = 'Add, remove, or reorder sections to reconfigure this if block.';
+Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
+/// tooltip - Describes the 'else if' subblock during [https://github.com/google/blockly/wiki/IfElse#block-modification if block modification].
+Blockly.Msg.CONTROLS_IF_ELSEIF_TOOLTIP = 'Add a condition to the if block.';
+Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
+/// tooltip - Describes the 'else' subblock during [https://github.com/google/blockly/wiki/IfElse#block-modification if block modification].
+Blockly.Msg.CONTROLS_IF_ELSE_TOOLTIP = 'Add a final, catch-all condition to the if block.';
+
+/// url - Information about comparisons.
+Blockly.Msg.LOGIC_COMPARE_HELPURL = 'https://en.wikipedia.org/wiki/Inequality_(mathematics)';
+/// tooltip - Describes the equals (=) block.
+Blockly.Msg.LOGIC_COMPARE_TOOLTIP_EQ = 'Return true if both inputs equal each other.';
+/// tooltip - Describes the not equals (≠) block.
+Blockly.Msg.LOGIC_COMPARE_TOOLTIP_NEQ = 'Return true if both inputs are not equal to each other.';
+/// tooltip - Describes the less than (<) block.
+Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LT = 'Return true if the first input is smaller than the second input.';
+/// tooltip - Describes the less than or equals (≤) block.
+Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LTE = 'Return true if the first input is smaller than or equal to the second input.';
+/// tooltip - Describes the greater than (>) block.
+Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GT = 'Return true if the first input is greater than the second input.';
+/// tooltip - Describes the greater than or equals (≥) block.
+Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE = 'Return true if the first input is greater than or equal to the second input.';
+
+/// url - Information about the Boolean conjunction ("and") and disjunction ("or") operators. Consider using the translation of [https://en.wikipedia.org/wiki/Boolean_logic https://en.wikipedia.org/wiki/Boolean_logic], if it exists in your language.
+Blockly.Msg.LOGIC_OPERATION_HELPURL = 'https://github.com/google/blockly/wiki/Logic#logical-operations';
+/// tooltip - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction].
+Blockly.Msg.LOGIC_OPERATION_TOOLTIP_AND = 'Return true if both inputs are true.';
+/// block text - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction].\n{{Identical|And}}
+Blockly.Msg.LOGIC_OPERATION_AND = 'and';
+/// block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction].
+Blockly.Msg.LOGIC_OPERATION_TOOLTIP_OR = 'Return true if at least one of the inputs is true.';
+/// block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction].\n{{Identical|Or}}
+Blockly.Msg.LOGIC_OPERATION_OR = 'or';
+
+/// url - Information about logical negation. The translation of [https://en.wikipedia.org/wiki/Logical_negation https://en.wikipedia.org/wiki/Logical_negation] is recommended if it exists in the target language.
+Blockly.Msg.LOGIC_NEGATE_HELPURL = 'https://github.com/google/blockly/wiki/Logic#not';
+/// block text - This is a unary operator that returns ''false'' when the input is ''true'', and ''true'' when the input is ''false''.
+/// \n\nParameters:\n* %1 - the input (which should be either the value "true" or "false")
+Blockly.Msg.LOGIC_NEGATE_TITLE = 'not %1';
+/// tooltip - See [https://en.wikipedia.org/wiki/Logical_negation https://en.wikipedia.org/wiki/Logical_negation].
+Blockly.Msg.LOGIC_NEGATE_TOOLTIP = 'Returns true if the input is false. Returns false if the input is true.';
+
+/// url - Information about the logic values ''true'' and ''false''. Consider using the translation of [https://en.wikipedia.org/wiki/Truth_value https://en.wikipedia.org/wiki/Truth_value] if it exists in your language.
+Blockly.Msg.LOGIC_BOOLEAN_HELPURL = 'https://github.com/google/blockly/wiki/Logic#values';
+/// block text - The word for the [https://en.wikipedia.org/wiki/Truth_value logical value] ''true''.\n{{Identical|True}}
+Blockly.Msg.LOGIC_BOOLEAN_TRUE = 'true';
+/// block text - The word for the [https://en.wikipedia.org/wiki/Truth_value logical value] ''false''.\n{{Identical|False}}
+Blockly.Msg.LOGIC_BOOLEAN_FALSE = 'false';
+/// tooltip - Indicates that the block returns either of the two possible [https://en.wikipedia.org/wiki/Truth_value logical values].
+Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP = 'Returns either true or false.';
+
+/// url - Provide a link to the translation of [https://en.wikipedia.org/wiki/Nullable_type https://en.wikipedia.org/wiki/Nullable_type], if it exists in your language; otherwise, do not worry about translating this advanced concept.
+Blockly.Msg.LOGIC_NULL_HELPURL = 'https://en.wikipedia.org/wiki/Nullable_type';
+/// block text - In computer languages, ''null'' is a special value that indicates that no value has been set. You may use your language's word for "nothing" or "invalid".\n{{Identical|Null}}
+Blockly.Msg.LOGIC_NULL = 'null';
+/// tooltip - This should use the word from the previous message.
+Blockly.Msg.LOGIC_NULL_TOOLTIP = 'Returns null.';
+
+/// url - Describes the programming language operator known as the ''ternary'' or ''conditional'' operator. It is recommended that you use the translation of [https://en.wikipedia.org/wiki/%3F: https://en.wikipedia.org/wiki/%3F:] if it exists.
+Blockly.Msg.LOGIC_TERNARY_HELPURL = 'https://en.wikipedia.org/wiki/%3F:';
+/// block input text - Label for the input whose value determines which of the other two inputs is returned. In some programming languages, this is called a ''''predicate''''.
+Blockly.Msg.LOGIC_TERNARY_CONDITION = 'test';
+/// block input text - Indicates that the following input should be returned (used as output) if the test input is true. Remember to try to keep block text terse (short).
+Blockly.Msg.LOGIC_TERNARY_IF_TRUE = 'if true';
+/// block input text - Indicates that the following input should be returned (used as output) if the test input is false.
+Blockly.Msg.LOGIC_TERNARY_IF_FALSE = 'if false';
+/// tooltip - See [https://en.wikipedia.org/wiki/%3F: https://en.wikipedia.org/wiki/%3F:].
+Blockly.Msg.LOGIC_TERNARY_TOOLTIP = 'Check the condition in "test". If the condition is true, returns the "if true" value; otherwise returns the "if false" value.';
+
+// Math Blocks.
+/// url - Information about (real) numbers.
+Blockly.Msg.MATH_NUMBER_HELPURL = 'https://en.wikipedia.org/wiki/Number';
+/// tooltip - Any positive or negative number, not necessarily an integer.
+Blockly.Msg.MATH_NUMBER_TOOLTIP = 'A number.';
+
+/// {{optional}}\nmath - The symbol for the binary operation addition.
+Blockly.Msg.MATH_ADDITION_SYMBOL = '+';
+/// {{optional}}\nmath - The symbol for the binary operation indicating that the right operand should be
+/// subtracted from the left operand.
+Blockly.Msg.MATH_SUBTRACTION_SYMBOL = '-';
+/// {{optional}}\nmath - The binary operation indicating that the left operand should be divided by
+/// the right operand.
+Blockly.Msg.MATH_DIVISION_SYMBOL = '÷';
+/// {{optional}}\nmath - The symbol for the binary operation multiplication.
+Blockly.Msg.MATH_MULTIPLICATION_SYMBOL = '×';
+/// {{optional}}\nmath - The symbol for the binary operation exponentiation. Specifically, if the
+/// value of the left operand is L and the value of the right operand (the exponent) is
+/// R, multiply L by itself R times. (Fractional and negative exponents are also legal.)
+Blockly.Msg.MATH_POWER_SYMBOL = '^';
+
+/// math - The short name of the trigonometric function
+/// [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent sine].
+Blockly.Msg.MATH_TRIG_SIN = 'sin';
+/// math - The short name of the trigonometric function
+/// [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent cosine].
+Blockly.Msg.MATH_TRIG_COS = 'cos';
+/// math - The short name of the trigonometric function
+/// [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent tangent].
+Blockly.Msg.MATH_TRIG_TAN = 'tan';
+/// math - The short name of the ''inverse of'' the trigonometric function
+/// [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent sine].
+Blockly.Msg.MATH_TRIG_ASIN = 'asin';
+/// math - The short name of the ''inverse of'' the trigonometric function
+/// [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent cosine].
+Blockly.Msg.MATH_TRIG_ACOS = 'acos';
+/// math - The short name of the ''inverse of'' the trigonometric function
+/// [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent tangent].
+Blockly.Msg.MATH_TRIG_ATAN = 'atan';
+
+/// url - Information about addition, subtraction, multiplication, division, and exponentiation.
+Blockly.Msg.MATH_ARITHMETIC_HELPURL = 'https://en.wikipedia.org/wiki/Arithmetic';
+/// tooltip - See [https://en.wikipedia.org/wiki/Addition https://en.wikipedia.org/wiki/Addition].
+Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD = 'Return the sum of the two numbers.';
+/// tooltip - See [https://en.wikipedia.org/wiki/Subtraction https://en.wikipedia.org/wiki/Subtraction].
+Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS = 'Return the difference of the two numbers.';
+/// tooltip - See [https://en.wikipedia.org/wiki/Multiplication https://en.wikipedia.org/wiki/Multiplication].
+Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY = 'Return the product of the two numbers.';
+/// tooltip - See [https://en.wikipedia.org/wiki/Division_(mathematics) https://en.wikipedia.org/wiki/Division_(mathematics)].
+Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE = 'Return the quotient of the two numbers.';
+/// tooltip - See [https://en.wikipedia.org/wiki/Exponentiation https://en.wikipedia.org/wiki/Exponentiation].
+Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER = 'Return the first number raised to the power of the second number.';
+
+/// url - Information about the square root operation.
+Blockly.Msg.MATH_SINGLE_HELPURL = 'https://en.wikipedia.org/wiki/Square_root';
+/// dropdown - This computes the positive [https://en.wikipedia.org/wiki/Square_root square root] of its input. For example, the square root of 16 is 4.
+Blockly.Msg.MATH_SINGLE_OP_ROOT = 'square root';
+/// tooltip - Please use the same term as in the previous message.
+Blockly.Msg.MATH_SINGLE_TOOLTIP_ROOT = 'Return the square root of a number.';
+/// dropdown - This leaves positive numeric inputs changed and inverts negative inputs. For example, the absolute value of 5 is 5; the absolute value of -5 is also 5. For more information, see [https://en.wikipedia.org/wiki/Absolute_value https://en.wikipedia.org/wiki/Absolute_value].
+Blockly.Msg.MATH_SINGLE_OP_ABSOLUTE = 'absolute';
+/// tooltip - Please use the same term as in the previous message.
+Blockly.Msg.MATH_SINGLE_TOOLTIP_ABS = 'Return the absolute value of a number.';
+
+/// tooltip - Calculates '''0-n''', where '''n''' is the single numeric input.
+Blockly.Msg.MATH_SINGLE_TOOLTIP_NEG = 'Return the negation of a number.';
+/// tooltip - Calculates the [https://en.wikipedia.org/wiki/Natural_logarithm|natural logarithm] of its single numeric input.
+Blockly.Msg.MATH_SINGLE_TOOLTIP_LN = 'Return the natural logarithm of a number.';
+/// tooltip - Calculates the [https://en.wikipedia.org/wiki/Common_logarithm common logarithm] of its single numeric input.
+Blockly.Msg.MATH_SINGLE_TOOLTIP_LOG10 = 'Return the base 10 logarithm of a number.';
+/// tooltip - Multiplies [https://en.wikipedia.org/wiki/E_%28mathematical_constant%29 e] by itself n times, where n is the single numeric input.
+Blockly.Msg.MATH_SINGLE_TOOLTIP_EXP = 'Return e to the power of a number.';
+/// tooltip - Multiplies 10 by itself n times, where n is the single numeric input.
+Blockly.Msg.MATH_SINGLE_TOOLTIP_POW10 = 'Return 10 to the power of a number.';
+
+/// url - Information about the trigonometric functions sine, cosine, tangent, and their inverses (ideally using degrees, not radians).
+Blockly.Msg.MATH_TRIG_HELPURL = 'https://en.wikipedia.org/wiki/Trigonometric_functions';
+/// tooltip - Return the [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent sine] of an [https://en.wikipedia.org/wiki/Degree_(angle) angle in degrees], not radians.
+Blockly.Msg.MATH_TRIG_TOOLTIP_SIN = 'Return the sine of a degree (not radian).';
+/// tooltip - Return the [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent cosine] of an [https://en.wikipedia.org/wiki/Degree_(angle) angle in degrees], not radians.
+Blockly.Msg.MATH_TRIG_TOOLTIP_COS = 'Return the cosine of a degree (not radian).';
+/// tooltip - Return the [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent tangent] of an [https://en.wikipedia.org/wiki/Degree_(angle) angle in degrees], not radians.
+Blockly.Msg.MATH_TRIG_TOOLTIP_TAN = 'Return the tangent of a degree (not radian).';
+/// tooltip - The [https://en.wikipedia.org/wiki/Inverse_trigonometric_functions inverse] of the [https://en.wikipedia.org/wiki/Cosine#Sine.2C_cosine_and_tangent sine function], using [https://en.wikipedia.org/wiki/Degree_(angle) degrees], not radians.
+Blockly.Msg.MATH_TRIG_TOOLTIP_ASIN = 'Return the arcsine of a number.';
+/// tooltip - The [https://en.wikipedia.org/wiki/Inverse_trigonometric_functions inverse] of the [https://en.wikipedia.org/wiki/Cosine#Sine.2C_cosine_and_tangent cosine] function, using [https://en.wikipedia.org/wiki/Degree_(angle) degrees], not radians.
+Blockly.Msg.MATH_TRIG_TOOLTIP_ACOS = 'Return the arccosine of a number.';
+/// tooltip - The [https://en.wikipedia.org/wiki/Inverse_trigonometric_functions inverse] of the [https://en.wikipedia.org/wiki/Cosine#Sine.2C_cosine_and_tangent tangent] function, using [https://en.wikipedia.org/wiki/Degree_(angle) degrees], not radians.
+Blockly.Msg.MATH_TRIG_TOOLTIP_ATAN = 'Return the arctangent of a number.';
+
+/// url - Information about the mathematical constants Pi (π), e, the golden ratio (φ), √ 2, √ 1/2, and infinity (∞).
+Blockly.Msg.MATH_CONSTANT_HELPURL = 'https://en.wikipedia.org/wiki/Mathematical_constant';
+/// tooltip - Provides the specified [https://en.wikipedia.org/wiki/Mathematical_constant mathematical constant].
+Blockly.Msg.MATH_CONSTANT_TOOLTIP = 'Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).';
+/// dropdown - A number is '''even''' if it is a multiple of 2. For example, 4 is even (yielding true), but 3 is not (false).
+Blockly.Msg.MATH_IS_EVEN = 'is even';
+/// dropdown - A number is '''odd''' if it is not a multiple of 2. For example, 3 is odd (yielding true), but 4 is not (false). The opposite of "odd" is "even".
+Blockly.Msg.MATH_IS_ODD = 'is odd';
+/// dropdown - A number is [https://en.wikipedia.org/wiki/Prime prime] if it cannot be evenly divided by any positive integers except for 1 and itself. For example, 5 is prime, but 6 is not because 2 × 3 = 6.
+Blockly.Msg.MATH_IS_PRIME = 'is prime';
+/// dropdown - A number is '''whole''' if it is an [https://en.wikipedia.org/wiki/Integer integer]. For example, 5 is whole, but 5.1 is not.
+Blockly.Msg.MATH_IS_WHOLE = 'is whole';
+/// dropdown - A number is '''positive''' if it is greater than 0. (0 is neither negative nor positive.)
+Blockly.Msg.MATH_IS_POSITIVE = 'is positive';
+/// dropdown - A number is '''negative''' if it is less than 0. (0 is neither negative nor positive.)
+Blockly.Msg.MATH_IS_NEGATIVE = 'is negative';
+/// dropdown - A number x is divisible by y if y goes into x evenly. For example, 10 is divisible by 5, but 10 is not divisible by 3.
+Blockly.Msg.MATH_IS_DIVISIBLE_BY = 'is divisible by';
+/// tooltip - This block lets the user specify via a dropdown menu whether to check if the numeric input is even, odd, prime, whole, positive, negative, or divisible by a given value.
+Blockly.Msg.MATH_IS_TOOLTIP = 'Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.';
+
+/// url - Information about incrementing (increasing the value of) a variable.
+/// For other languages, just use the translation of the Wikipedia page about
+/// addition ([https://en.wikipedia.org/wiki/Addition https://en.wikipedia.org/wiki/Addition]).
+Blockly.Msg.MATH_CHANGE_HELPURL = 'https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter';
+/// - As in: ''change'' [the value of variable] ''item'' ''by'' 1 (e.g., if the variable named 'item' had the value 5, change it to 6).
+/// %1 is a variable name.
+/// %2 is the amount of change.
+Blockly.Msg.MATH_CHANGE_TITLE = 'change %1 by %2';
+Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
+/// tooltip - This updates the value of the variable by adding to it the following numeric input.\n\nParameters:\n* %1 - the name of the variable whose value should be increased.
+Blockly.Msg.MATH_CHANGE_TOOLTIP = 'Add a number to variable "%1".';
+
+/// url - Information about how numbers are rounded to the nearest integer
+Blockly.Msg.MATH_ROUND_HELPURL = 'https://en.wikipedia.org/wiki/Rounding';
+/// tooltip - See [https://en.wikipedia.org/wiki/Rounding https://en.wikipedia.org/wiki/Rounding].
+Blockly.Msg.MATH_ROUND_TOOLTIP = 'Round a number up or down.';
+/// dropdown - This rounds its input to the nearest whole number. For example, 3.4 is rounded to 3.
+Blockly.Msg.MATH_ROUND_OPERATOR_ROUND = 'round';
+/// dropdown - This rounds its input up to the nearest whole number. For example, if the input was 2.2, the result would be 3.
+Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDUP = 'round up';
+/// dropdown - This rounds its input down to the nearest whole number. For example, if the input was 3.8, the result would be 3.
+Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDDOWN = 'round down';
+
+/// url - Information about applying a function to a list of numbers. (We were unable to find such information in English. Feel free to skip this and any other URLs that are difficult.)
+Blockly.Msg.MATH_ONLIST_HELPURL = '';
+/// dropdown - This computes the sum of the numeric elements in the list. For example, the sum of the list {1, 4} is 5.
+Blockly.Msg.MATH_ONLIST_OPERATOR_SUM = 'sum of list';
+/// tooltip - Please use the same term for "sum" as in the previous message.
+Blockly.Msg.MATH_ONLIST_TOOLTIP_SUM = 'Return the sum of all the numbers in the list.';
+/// dropdown - This finds the smallest (minimum) number in a list. For example, the smallest number in the list [-5, 0, 3] is -5.
+Blockly.Msg.MATH_ONLIST_OPERATOR_MIN = 'min of list';
+/// tooltip - Please use the same term for "min" or "minimum" as in the previous message.
+Blockly.Msg.MATH_ONLIST_TOOLTIP_MIN = 'Return the smallest number in the list.';
+/// dropdown - This finds the largest (maximum) number in a list. For example, the largest number in the list [-5, 0, 3] is 3.
+Blockly.Msg.MATH_ONLIST_OPERATOR_MAX = 'max of list';
+/// tooltip
+Blockly.Msg.MATH_ONLIST_TOOLTIP_MAX = 'Return the largest number in the list.';
+/// dropdown - This adds up all of the numbers in a list and divides the sum by the number of elements in the list. For example, the [https://en.wikipedia.org/wiki/Arithmetic_mean average] of the list [1, 2, 3, 4] is 2.5 (10/4).
+Blockly.Msg.MATH_ONLIST_OPERATOR_AVERAGE = 'average of list';
+/// tooltip - See [https://en.wikipedia.org/wiki/Arithmetic_mean https://en.wikipedia.org/wiki/Arithmetic_mean] for more informatin.
+Blockly.Msg.MATH_ONLIST_TOOLTIP_AVERAGE = 'Return the average (arithmetic mean) of the numeric values in the list.';
+/// dropdown - This finds the [https://en.wikipedia.org/wiki/Median median] of the numeric values in a list. For example, the median of the list {1, 2, 7, 12, 13} is 7.
+Blockly.Msg.MATH_ONLIST_OPERATOR_MEDIAN = 'median of list';
+/// tooltip - See [https://en.wikipedia.org/wiki/Median median https://en.wikipedia.org/wiki/Median median] for more information.
+Blockly.Msg.MATH_ONLIST_TOOLTIP_MEDIAN = 'Return the median number in the list.';
+/// dropdown - This finds the most common numbers ([https://en.wikipedia.org/wiki/Mode_(statistics) modes]) in a list. For example, the modes of the list {1, 3, 9, 3, 9} are {3, 9}.
+Blockly.Msg.MATH_ONLIST_OPERATOR_MODE = 'modes of list';
+/// tooltip - See [https://en.wikipedia.org/wiki/Mode_(statistics) https://en.wikipedia.org/wiki/Mode_(statistics)] for more information.
+Blockly.Msg.MATH_ONLIST_TOOLTIP_MODE = 'Return a list of the most common item(s) in the list.';
+/// dropdown - This finds the [https://en.wikipedia.org/wiki/Standard_deviation standard deviation] of the numeric values in a list.
+Blockly.Msg.MATH_ONLIST_OPERATOR_STD_DEV = 'standard deviation of list';
+/// tooltip - See [https://en.wikipedia.org/wiki/Standard_deviation https://en.wikipedia.org/wiki/Standard_deviation] for more information.
+Blockly.Msg.MATH_ONLIST_TOOLTIP_STD_DEV = 'Return the standard deviation of the list.';
+/// dropdown - This choose an element at random from a list. Each element is chosen with equal probability.
+Blockly.Msg.MATH_ONLIST_OPERATOR_RANDOM = 'random item of list';
+/// tooltip - Please use same term for 'random' as in previous entry.
+Blockly.Msg.MATH_ONLIST_TOOLTIP_RANDOM = 'Return a random element from the list.';
+
+/// url - information about the modulo (remainder) operation.
+Blockly.Msg.MATH_MODULO_HELPURL = 'https://en.wikipedia.org/wiki/Modulo_operation';
+/// block text - Title of block providing the remainder when dividing the first numerical input by the second. For example, the remainder of 10 divided by 3 is 1.\n\nParameters:\n* %1 - the dividend (10, in our example)\n* %2 - the divisor (3 in our example).
+Blockly.Msg.MATH_MODULO_TITLE = 'remainder of %1 ÷ %2';
+/// tooltip - For example, the remainder of 10 divided by 3 is 1.
+Blockly.Msg.MATH_MODULO_TOOLTIP = 'Return the remainder from dividing the two numbers.';
+
+/// url - Information about constraining a numeric value to be in a specific range. (The English URL is not ideal. Recall that translating URLs is the lowest priority.)
+Blockly.Msg.MATH_CONSTRAIN_HELPURL = 'https://en.wikipedia.org/wiki/Clamping_%28graphics%29';
+/// block text - The title of the block that '''constrain'''s (forces) a number to be in a given range.
+///For example, if the number 150 is constrained to be between 5 and 100, the result will be 100.
+///\n\nParameters:\n* %1 - the value to constrain (e.g., 150)\n* %2 - the minimum value (e.g., 5)\n* %3 - the maximum value (e.g., 100).
+Blockly.Msg.MATH_CONSTRAIN_TITLE = 'constrain %1 low %2 high %3';
+/// tooltip - This compares a number ''x'' to a low value ''L'' and a high value ''H''. If ''x'' is less then ''L'', the result is ''L''. If ''x'' is greater than ''H'', the result is ''H''. Otherwise, the result is ''x''.
+Blockly.Msg.MATH_CONSTRAIN_TOOLTIP = 'Constrain a number to be between the specified limits (inclusive).';
+
+/// url - Information about how computers generate random numbers.
+Blockly.Msg.MATH_RANDOM_INT_HELPURL = 'https://en.wikipedia.org/wiki/Random_number_generation';
+/// block text - The title of the block that generates a random integer (whole number) in the specified range. For example, if the range is from 5 to 7, this returns 5, 6, or 7 with equal likelihood. %1 is a placeholder for the lower number, %2 is the placeholder for the larger number.
+Blockly.Msg.MATH_RANDOM_INT_TITLE = 'random integer from %1 to %2';
+/// tooltip - Return a random integer between two values specified as inputs. For example, if one input was 7 and another 9, any of the numbers 7, 8, or 9 could be produced.
+Blockly.Msg.MATH_RANDOM_INT_TOOLTIP = 'Return a random integer between the two specified limits, inclusive.';
+
+/// url - Information about how computers generate random numbers (specifically, numbers in the range from 0 to just below 1).
+Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL = 'https://en.wikipedia.org/wiki/Random_number_generation';
+/// block text - The title of the block that generates a random number greater than or equal to 0 and less than 1.
+Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM = 'random fraction';
+/// tooltip - Return a random fraction between 0 and 1. The value may be equal to 0 but must be less than 1.
+Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP = 'Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).';
+
+// Text Blocks.
+/// url - Information about how computers represent text (sometimes referred to as ''string''s).
+Blockly.Msg.TEXT_TEXT_HELPURL = 'https://en.wikipedia.org/wiki/String_(computer_science)';
+/// tooltip - See [https://github.com/google/blockly/wiki/Text https://github.com/google/blockly/wiki/Text].
+Blockly.Msg.TEXT_TEXT_TOOLTIP = 'A letter, word, or line of text.';
+
+/// url - Information on concatenating/appending pieces of text.
+Blockly.Msg.TEXT_JOIN_HELPURL = 'https://github.com/google/blockly/wiki/Text#text-creation';
+/// block text - See [https://github.com/google/blockly/wiki/Text#text-creation https://github.com/google/blockly/wiki/Text#text-creation].
+Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH = 'create text with';
+/// tooltip - See [https://github.com/google/blockly/wiki/Text#text-creation create text with] for more information.
+Blockly.Msg.TEXT_JOIN_TOOLTIP = 'Create a piece of text by joining together any number of items.';
+
+/// block text - This is shown when the programmer wants to change the number of pieces of text being joined together. See [https://github.com/google/blockly/wiki/Text#text-creation https://github.com/google/blockly/wiki/Text#text-creation], specifically the last picture in the 'Text creation' section.\n{{Identical|Join}}
+Blockly.Msg.TEXT_CREATE_JOIN_TITLE_JOIN = 'join';
+/// tooltip - See [https://github.com/google/blockly/wiki/Text#text-creation https://github.com/google/blockly/wiki/Text#text-creation], specifically the last picture in the 'Text creation' section.
+Blockly.Msg.TEXT_CREATE_JOIN_TOOLTIP = 'Add, remove, or reorder sections to reconfigure this text block.';
+Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
+/// block text - See [https://github.com/google/blockly/wiki/Text#text-creation https://github.com/google/blockly/wiki/Text#text-creation], specifically the last picture in the 'Text creation' section.
+Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TOOLTIP = 'Add an item to the text.';
+
+/// url - This and the other text-related URLs are going to be hard to translate. As always, it is okay to leave untranslated or paste in the English-language URL. For these URLs, you might also consider a general URL about how computers represent text (such as the translation of [https://en.wikipedia.org/wiki/String_(computer_science) this Wikipedia page]).
+Blockly.Msg.TEXT_APPEND_HELPURL = 'https://github.com/google/blockly/wiki/Text#text-modification';
+/// block input text - Message preceding the name of a variable to which text should be appended.
+/// [[File:blockly-append-text.png]]
+Blockly.Msg.TEXT_APPEND_TO = 'to';
+/// block input text - Message following the variable and preceding the piece of text that should
+/// be appended, as shown below.
+/// [[File:blockly-append-text.png]]
+Blockly.Msg.TEXT_APPEND_APPENDTEXT = 'append text';
+Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
+/// tooltip - See [https://github.com/google/blockly/wiki/Text#text-modification https://github.com/google/blockly/wiki/Text#text-modification] for more information.\n\nParameters:\n* %1 - the name of the variable to which text should be appended
+Blockly.Msg.TEXT_APPEND_TOOLTIP = 'Append some text to variable "%1".';
+
+/// url - Information about text on computers (usually referred to as 'strings').
+Blockly.Msg.TEXT_LENGTH_HELPURL = 'https://github.com/google/blockly/wiki/Text#text-modification';
+/// block text - See [https://github.com/google/blockly/wiki/Text#text-length https://github.com/google/blockly/wiki/Text#text-length].
+/// \n\nParameters:\n* %1 - the piece of text to take the length of
+Blockly.Msg.TEXT_LENGTH_TITLE = 'length of %1';
+/// tooltip - See [https://github.com/google/blockly/wiki/Text#text-length https://github.com/google/blockly/wiki/Text#text-length].
+Blockly.Msg.TEXT_LENGTH_TOOLTIP = 'Returns the number of letters (including spaces) in the provided text.';
+
+/// url - Information about empty pieces of text on computers (usually referred to as 'empty strings').
+Blockly.Msg.TEXT_ISEMPTY_HELPURL = 'https://github.com/google/blockly/wiki/Text#checking-for-empty-text';
+/// block text - See [https://github.com/google/blockly/wiki/Text#checking-for-empty-text https://github.com/google/blockly/wiki/Text#checking-for-empty-text].
+/// \n\nParameters:\n* %1 - the piece of text to test for emptiness
+Blockly.Msg.TEXT_ISEMPTY_TITLE = '%1 is empty';
+/// tooltip - See [https://github.com/google/blockly/wiki/Text#checking-for-empty-text https://github.com/google/blockly/wiki/Text#checking-for-empty-text].
+Blockly.Msg.TEXT_ISEMPTY_TOOLTIP = 'Returns true if the provided text is empty.';
+
+/// url - Information about finding a character in a piece of text.
+Blockly.Msg.TEXT_INDEXOF_HELPURL = 'https://github.com/google/blockly/wiki/Text#finding-text';
+/// tooltip - %1 will be replaced by either the number 0 or -1 depending on the indexing mode. See [https://github.com/google/blockly/wiki/Text#finding-text https://github.com/google/blockly/wiki/Text#finding-text].
+Blockly.Msg.TEXT_INDEXOF_TOOLTIP = 'Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.';
+/// block text - Title of blocks allowing users to find text. See
+/// [https://github.com/google/blockly/wiki/Text#finding-text
+/// https://github.com/google/blockly/wiki/Text#finding-text].
+/// [[File:Blockly-find-text.png]].
+Blockly.Msg.TEXT_INDEXOF_INPUT_INTEXT = 'in text';
+/// dropdown - See [https://github.com/google/blockly/wiki/Text#finding-text
+/// https://github.com/google/blockly/wiki/Text#finding-text].
+/// [[File:Blockly-find-text.png]].
+Blockly.Msg.TEXT_INDEXOF_OPERATOR_FIRST = 'find first occurrence of text';
+/// dropdown - See [https://github.com/google/blockly/wiki/Text#finding-text
+/// https://github.com/google/blockly/wiki/Text#finding-text]. This would
+/// replace "find first occurrence of text" below. (For more information on
+/// how common text is factored out of dropdown menus, see
+/// [https://translatewiki.net/wiki/Translating:Blockly#Drop-Down_Menus
+/// https://translatewiki.net/wiki/Translating:Blockly#Drop-Down_Menus)].)
+/// [[File:Blockly-find-text.png]].
+Blockly.Msg.TEXT_INDEXOF_OPERATOR_LAST = 'find last occurrence of text';
+/// block text - Optional text to follow the rightmost block in a
+/// [https://github.com/google/blockly/wiki/Text#finding-text
+/// https://github.com/google/blockly/wiki/Text#finding-text in text ... find block]
+/// (after the "a" in the below picture). This will be the empty string in most languages.
+/// [[File:Blockly-find-text.png]].
+Blockly.Msg.TEXT_INDEXOF_TAIL = '';
+
+/// url - Information about extracting characters (letters, number, symbols, etc.) from text.
+Blockly.Msg.TEXT_CHARAT_HELPURL = 'https://github.com/google/blockly/wiki/Text#extracting-text';
+/// block text - Appears before the piece of text from which a letter (or number,
+/// punctuation character, etc.) should be extracted, as shown below. See
+/// [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
+/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
+/// [[File:Blockly-text-get.png]]
+Blockly.Msg.TEXT_CHARAT_INPUT_INTEXT = 'in text';
+/// dropdown - Indicates that the letter (or number, punctuation character, etc.) with the
+/// specified index should be obtained from the preceding piece of text. See
+/// [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
+/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
+/// [[File:Blockly-text-get.png]]
+Blockly.Msg.TEXT_CHARAT_FROM_START = 'get letter #';
+/// block text - Indicates that the letter (or number, punctuation character, etc.) with the
+/// specified index from the end of a given piece of text should be obtained. See
+/// [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
+/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
+/// [[File:Blockly-text-get.png]]
+Blockly.Msg.TEXT_CHARAT_FROM_END = 'get letter # from end';
+/// block text - Indicates that the first letter of the following piece of text should be
+/// retrieved. See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
+/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
+/// [[File:Blockly-text-get.png]]
+Blockly.Msg.TEXT_CHARAT_FIRST = 'get first letter';
+/// block text - Indicates that the last letter (or number, punctuation mark, etc.) of the
+/// following piece of text should be retrieved. See
+/// [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
+/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
+/// [[File:Blockly-text-get.png]]
+Blockly.Msg.TEXT_CHARAT_LAST = 'get last letter';
+/// block text - Indicates that any letter (or number, punctuation mark, etc.) in the
+/// following piece of text should be randomly selected. See
+/// [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
+/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
+/// [[File:Blockly-text-get.png]]
+Blockly.Msg.TEXT_CHARAT_RANDOM = 'get random letter';
+/// block text - Text that goes after the rightmost block/dropdown when getting a single letter from
+/// a piece of text, as in [https://blockly-demo.appspot.com/static/apps/code/index.html#3m23km these
+/// blocks] or shown below. For most languages, this will be blank.
+/// [[File:Blockly-text-get.png]]
+Blockly.Msg.TEXT_CHARAT_TAIL = '';
+/// tooltip - See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
+/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
+/// [[File:Blockly-text-get.png]]
+Blockly.Msg.TEXT_CHARAT_TOOLTIP = 'Returns the letter at the specified position.';
+
+/// See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
+/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
+Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP = 'Returns a specified portion of the text.';
+/// url - Information about extracting characters from text. Reminder: urls are the
+/// lowest priority translations. Feel free to skip.
+Blockly.Msg.TEXT_GET_SUBSTRING_HELPURL = 'https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text';
+/// block text - Precedes a piece of text from which a portion should be extracted.
+/// [[File:Blockly-get-substring.png]]
+Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT = 'in text';
+/// dropdown - Indicates that the following number specifies the position (relative to the start
+/// position) of the beginning of the region of text that should be obtained from the preceding
+/// piece of text. See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
+/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
+/// [[File:Blockly-get-substring.png]]
+Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_START = 'get substring from letter #';
+/// dropdown - Indicates that the following number specifies the position (relative to the end
+/// position) of the beginning of the region of text that should be obtained from the preceding
+/// piece of text. See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
+/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
+/// Note: If {{msg-Blockly|ORDINAL_NUMBER_SUFFIX}} is defined, it will
+/// automatically appear ''after'' this and any other
+/// [https://translatewiki.net/wiki/Translating:Blockly#Ordinal_numbers ordinal numbers]
+/// on this block.
+/// [[File:Blockly-get-substring.png]]
+Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_END = 'get substring from letter # from end';
+/// block text - Indicates that a region starting with the first letter of the preceding piece
+/// of text should be extracted. See
+/// [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
+/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
+/// [[File:Blockly-get-substring.png]]
+Blockly.Msg.TEXT_GET_SUBSTRING_START_FIRST = 'get substring from first letter';
+/// dropdown - Indicates that the following number specifies the position (relative to
+/// the start position) of the end of the region of text that should be obtained from the
+/// preceding piece of text. See
+/// [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
+/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
+/// [[File:Blockly-get-substring.png]]
+Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_START = 'to letter #';
+/// dropdown - Indicates that the following number specifies the position (relative to the
+/// end position) of the end of the region of text that should be obtained from the preceding
+/// piece of text. See
+/// [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
+/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
+/// [[File:Blockly-get-substring.png]]
+Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_END = 'to letter # from end';
+/// block text - Indicates that a region ending with the last letter of the preceding piece
+/// of text should be extracted. See
+/// [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
+/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
+/// [[File:Blockly-get-substring.png]]
+Blockly.Msg.TEXT_GET_SUBSTRING_END_LAST = 'to last letter';
+/// block text - Text that should go after the rightmost block/dropdown when
+/// [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
+/// extracting a region of text]. In most languages, this will be the empty string.
+/// [[File:Blockly-get-substring.png]]
+Blockly.Msg.TEXT_GET_SUBSTRING_TAIL = '';
+
+/// url - Information about the case of letters (upper-case and lower-case).
+Blockly.Msg.TEXT_CHANGECASE_HELPURL = 'https://github.com/google/blockly/wiki/Text#adjusting-text-case';
+/// tooltip - Describes a block to adjust the case of letters. For more information on this block,
+/// see [https://github.com/google/blockly/wiki/Text#adjusting-text-case
+/// https://github.com/google/blockly/wiki/Text#adjusting-text-case].
+Blockly.Msg.TEXT_CHANGECASE_TOOLTIP = 'Return a copy of the text in a different case.';
+/// block text - Indicates that all of the letters in the following piece of text should be
+/// capitalized. If your language does not use case, you may indicate that this is not
+/// applicable to your language. For more information on this block, see
+/// [https://github.com/google/blockly/wiki/Text#adjusting-text-case
+/// https://github.com/google/blockly/wiki/Text#adjusting-text-case].
+Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE = 'to UPPER CASE';
+/// block text - Indicates that all of the letters in the following piece of text should be converted to lower-case. If your language does not use case, you may indicate that this is not applicable to your language. For more information on this block, see [https://github.com/google/blockly/wiki/Text#adjusting-text-case https://github.com/google/blockly/wiki/Text#adjusting-text-case].
+Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE = 'to lower case';
+/// block text - Indicates that the first letter of each of the following words should be capitalized and the rest converted to lower-case. If your language does not use case, you may indicate that this is not applicable to your language. For more information on this block, see [https://github.com/google/blockly/wiki/Text#adjusting-text-case https://github.com/google/blockly/wiki/Text#adjusting-text-case].
+Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE = 'to Title Case';
+
+/// url - Information about trimming (removing) text off the beginning and ends of pieces of text.
+Blockly.Msg.TEXT_TRIM_HELPURL = 'https://github.com/google/blockly/wiki/Text#trimming-removing-spaces';
+/// tooltip - See [https://github.com/google/blockly/wiki/Text#trimming-removing-spaces
+/// https://github.com/google/blockly/wiki/Text#trimming-removing-spaces].
+Blockly.Msg.TEXT_TRIM_TOOLTIP = 'Return a copy of the text with spaces removed from one or both ends.';
+/// dropdown - Removes spaces from the beginning and end of a piece of text. See
+/// [https://github.com/google/blockly/wiki/Text#trimming-removing-spaces
+/// https://github.com/google/blockly/wiki/Text#trimming-removing-spaces]. Note that neither
+/// this nor the other options modify the original piece of text (that follows);
+/// the block just returns a version of the text without the specified spaces.
+Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH = 'trim spaces from both sides of';
+/// dropdown - Removes spaces from the beginning of a piece of text. See
+/// [https://github.com/google/blockly/wiki/Text#trimming-removing-spaces
+/// https://github.com/google/blockly/wiki/Text#trimming-removing-spaces].
+/// Note that in right-to-left scripts, this will remove spaces from the right side.
+Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT = 'trim spaces from left side of';
+/// dropdown - Removes spaces from the end of a piece of text. See
+/// [https://github.com/google/blockly/wiki/Text#trimming-removing-spaces
+/// https://github.com/google/blockly/wiki/Text#trimming-removing-spaces].
+/// Note that in right-to-left scripts, this will remove spaces from the left side.
+Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT = 'trim spaces from right side of';
+
+/// url - Information about displaying text on computers.
+Blockly.Msg.TEXT_PRINT_HELPURL = 'https://github.com/google/blockly/wiki/Text#printing-text';
+/// block text - Display the input on the screen. See
+/// [https://github.com/google/blockly/wiki/Text#printing-text
+/// https://github.com/google/blockly/wiki/Text#printing-text].
+/// \n\nParameters:\n* %1 - the value to print
+Blockly.Msg.TEXT_PRINT_TITLE = 'print %1';
+/// tooltip - See [https://github.com/google/blockly/wiki/Text#printing-text
+/// https://github.com/google/blockly/wiki/Text#printing-text].
+Blockly.Msg.TEXT_PRINT_TOOLTIP = 'Print the specified text, number or other value.';
+/// url - Information about getting text from users.
+Blockly.Msg.TEXT_PROMPT_HELPURL = 'https://github.com/google/blockly/wiki/Text#getting-input-from-the-user';
+/// dropdown - Specifies that a piece of text should be requested from the user with
+/// the following message. See [https://github.com/google/blockly/wiki/Text#printing-text
+/// https://github.com/google/blockly/wiki/Text#printing-text].
+Blockly.Msg.TEXT_PROMPT_TYPE_TEXT = 'prompt for text with message';
+/// dropdown - Specifies that a number should be requested from the user with the
+/// following message. See [https://github.com/google/blockly/wiki/Text#printing-text
+/// https://github.com/google/blockly/wiki/Text#printing-text].
+Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER = 'prompt for number with message';
+/// dropdown - Precedes the message with which the user should be prompted for
+/// a number. See [https://github.com/google/blockly/wiki/Text#printing-text
+/// https://github.com/google/blockly/wiki/Text#printing-text].
+Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER = 'Prompt for user for a number.';
+/// dropdown - Precedes the message with which the user should be prompted for some text.
+/// See [https://github.com/google/blockly/wiki/Text#printing-text
+/// https://github.com/google/blockly/wiki/Text#printing-text].
+Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT = 'Prompt for user for some text.';
+
+// Lists Blocks.
+/// url - Information on empty lists.
+Blockly.Msg.LISTS_CREATE_EMPTY_HELPURL = 'https://github.com/google/blockly/wiki/Lists#create-empty-list';
+/// block text - See [https://github.com/google/blockly/wiki/Lists#create-empty-list https://github.com/google/blockly/wiki/Lists#create-empty-list].
+Blockly.Msg.LISTS_CREATE_EMPTY_TITLE = 'create empty list';
+/// block text - See [https://github.com/google/blockly/wiki/Lists#create-empty-list https://github.com/google/blockly/wiki/Lists#create-empty-list].
+Blockly.Msg.LISTS_CREATE_EMPTY_TOOLTIP = 'Returns a list, of length 0, containing no data records';
+
+/// url - Information on building lists.
+Blockly.Msg.LISTS_CREATE_WITH_HELPURL = 'https://github.com/google/blockly/wiki/Lists#create-list-with';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#create-list-with https://github.com/google/blockly/wiki/Lists#create-list-with].
+Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP = 'Create a list with any number of items.';
+/// block text - See [https://github.com/google/blockly/wiki/Lists#create-list-with https://github.com/google/blockly/wiki/Lists#create-list-with].
+Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH = 'create list with';
+/// block text - This appears in a sub-block when [https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs changing the number of inputs in a ''''create list with'''' block].\n{{Identical|List}}
+Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD = 'list';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs].
+Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP = 'Add, remove, or reorder sections to reconfigure this list block.';
+Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs].
+Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP = 'Add an item to the list.';
+
+/// url - Information about [https://github.com/google/blockly/wiki/Lists#create-list-with creating a list with multiple copies of a single item].
+Blockly.Msg.LISTS_REPEAT_HELPURL = 'https://github.com/google/blockly/wiki/Lists#create-list-with';
+/// url - See [https://github.com/google/blockly/wiki/Lists#create-list-with creating a list with multiple copies of a single item].
+Blockly.Msg.LISTS_REPEAT_TOOLTIP = 'Creates a list consisting of the given value repeated the specified number of times.';
+/// block text - See [https://github.com/google/blockly/wiki/Lists#create-list-with
+/// https://github.com/google/blockly/wiki/Lists#create-list-with].
+///\n\nParameters:\n* %1 - the item (text) to be repeated\n* %2 - the number of times to repeat it
+Blockly.Msg.LISTS_REPEAT_TITLE = 'create list with item %1 repeated %2 times';
+
+/// url - Information about how the length of a list is computed (i.e., by the total number of elements, not the number of different elements).
+Blockly.Msg.LISTS_LENGTH_HELPURL = 'https://github.com/google/blockly/wiki/Lists#length-of';
+/// block text - See [https://github.com/google/blockly/wiki/Lists#length-of https://github.com/google/blockly/wiki/Lists#length-of].
+/// \n\nParameters:\n* %1 - the list whose length is desired
+Blockly.Msg.LISTS_LENGTH_TITLE = 'length of %1';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#length-of https://github.com/google/blockly/wiki/Lists#length-of Blockly:Lists:length of].
+Blockly.Msg.LISTS_LENGTH_TOOLTIP = 'Returns the length of a list.';
+
+/// url - See [https://github.com/google/blockly/wiki/Lists#is-empty https://github.com/google/blockly/wiki/Lists#is-empty].
+Blockly.Msg.LISTS_ISEMPTY_HELPURL = 'https://github.com/google/blockly/wiki/Lists#is-empty';
+/// block text - See [https://github.com/google/blockly/wiki/Lists#is-empty
+/// https://github.com/google/blockly/wiki/Lists#is-empty].
+/// \n\nParameters:\n* %1 - the list to test
+Blockly.Msg.LISTS_ISEMPTY_TITLE = '%1 is empty';
+/// block tooltip - See [https://github.com/google/blockly/wiki/Lists#is-empty
+/// https://github.com/google/blockly/wiki/Lists#is-empty].
+Blockly.Msg.LISTS_ISEMPTY_TOOLTIP = 'Returns true if the list is empty.';
+
+/// block text - Title of blocks operating on [https://github.com/google/blockly/wiki/Lists lists].
+Blockly.Msg.LISTS_INLIST = 'in list';
+
+/// url - See [https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list
+/// https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list].
+Blockly.Msg.LISTS_INDEX_OF_HELPURL = 'https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list';
+Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
+/// dropdown - See [https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list
+/// Lists#finding-items-in-a-list].
+/// [[File:Blockly-list-find.png]]
+Blockly.Msg.LISTS_INDEX_OF_FIRST = 'find first occurrence of item';
+/// dropdown - See [https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list
+/// https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list].
+/// [[File:Blockly-list-find.png]]
+Blockly.Msg.LISTS_INDEX_OF_LAST = 'find last occurrence of item';
+/// tooltip - %1 will be replaced by either the number 0 or -1 depending on the indexing mode. See [https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list
+/// https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list].
+/// [[File:Blockly-list-find.png]]
+Blockly.Msg.LISTS_INDEX_OF_TOOLTIP = 'Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.';
+
+Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
+/// dropdown - Indicates that the user wishes to
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item
+/// get an item from a list] without removing it from the list.
+Blockly.Msg.LISTS_GET_INDEX_GET = 'get';
+/// dropdown - Indicates that the user wishes to
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item
+/// get and remove an item from a list], as opposed to merely getting
+/// it without modifying the list.
+Blockly.Msg.LISTS_GET_INDEX_GET_REMOVE = 'get and remove';
+/// dropdown - Indicates that the user wishes to
+/// [https://github.com/google/blockly/wiki/Lists#removing-an-item
+/// remove an item from a list].\n{{Identical|Remove}}
+Blockly.Msg.LISTS_GET_INDEX_REMOVE = 'remove';
+/// dropdown - Indicates that an index relative to the front of the list should be used to
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item get and/or remove
+/// an item from a list]. Note: If {{msg-Blockly|ORDINAL_NUMBER_SUFFIX}} is defined, it will
+/// automatically appear ''after'' this number (and any other ordinal numbers on this block).
+/// See [[Translating:Blockly#Ordinal_numbers]] for more information on ordinal numbers in Blockly.
+/// [[File:Blockly-list-get-item.png]]
+Blockly.Msg.LISTS_GET_INDEX_FROM_START = '#';
+/// dropdown - Indicates that an index relative to the end of the list should be used
+/// to [https://github.com/google/blockly/wiki/Lists#getting-a-single-item access an item in a list].
+/// [[File:Blockly-list-get-item.png]]
+Blockly.Msg.LISTS_GET_INDEX_FROM_END = '# from end';
+/// dropdown - Indicates that the '''first''' item should be
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item accessed in a list].
+/// [[File:Blockly-list-get-item.png]]
+Blockly.Msg.LISTS_GET_INDEX_FIRST = 'first';
+/// dropdown - Indicates that the '''last''' item should be
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item accessed in a list].
+/// [[File:Blockly-list-get-item.png]]
+Blockly.Msg.LISTS_GET_INDEX_LAST = 'last';
+/// dropdown - Indicates that a '''random''' item should be
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item accessed in a list].
+/// [[File:Blockly-list-get-item.png]]
+Blockly.Msg.LISTS_GET_INDEX_RANDOM = 'random';
+/// block text - Text that should go after the rightmost block/dropdown when
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item
+/// accessing an item from a list]. In most languages, this will be the empty string.
+/// [[File:Blockly-list-get-item.png]]
+Blockly.Msg.LISTS_GET_INDEX_TAIL = '';
+Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
+/// tooltip - Indicates the ordinal number that the first item in a list is referenced by. %1 will be replaced by either "#0" or "#1" depending on the indexing mode.
+Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP = '%1 is the first item.';
+/// tooltip - Indicates the ordinal number that the last item in a list is referenced by. %1 will be replaced by either "#0" or "#1" depending on the indexing mode.
+Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP = '%1 is the last item.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for more information.
+Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM = 'Returns the item at the specified position in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for more information.
+Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FIRST = 'Returns the first item in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for more information.
+Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_LAST = 'Returns the last item in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for more information.
+Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM = 'Returns a random item in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for '#' or '# from end'.
+Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM = 'Removes and returns the item at the specified position in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'first'.
+Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST = 'Removes and returns the first item in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'last'.
+Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST = 'Removes and returns the last item in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'random'.
+Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM = 'Removes and returns a random item in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for '#' or '# from end'.
+Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM = 'Removes the item at the specified position in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'first'.
+Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST = 'Removes the first item in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'last'.
+Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST = 'Removes the last item in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'random'.
+Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM = 'Removes a random item in a list.';
+/// url - Information about putting items in lists.
+Blockly.Msg.LISTS_SET_INDEX_HELPURL = 'https://github.com/google/blockly/wiki/Lists#in-list--set';
+Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
+/// block text - [https://github.com/google/blockly/wiki/Lists#in-list--set
+/// Replaces an item in a list].
+/// [[File:Blockly-in-list-set-insert.png]]
+Blockly.Msg.LISTS_SET_INDEX_SET = 'set';
+/// block text - [https://github.com/google/blockly/wiki/Lists#in-list--insert-at
+/// Inserts an item into a list].
+/// [[File:Blockly-in-list-set-insert.png]]
+Blockly.Msg.LISTS_SET_INDEX_INSERT = 'insert at';
+/// block text - The word(s) after the position in the list and before the item to be set/inserted.
+/// [[File:Blockly-in-list-set-insert.png]]
+Blockly.Msg.LISTS_SET_INDEX_INPUT_TO = 'as';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "set" block).
+Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM = 'Sets the item at the specified position in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "set" block).
+Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FIRST = 'Sets the first item in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "set" block).
+Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST = 'Sets the last item in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "set" block).
+Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM = 'Sets a random item in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "insert" block).
+Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM = 'Inserts the item at the specified position in a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "insert" block).
+Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST = 'Inserts the item at the start of a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "insert" block).
+Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_LAST = 'Append the item to the end of a list.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "insert" block).
+Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM = 'Inserts the item randomly in a list.';
+
+/// url - Information describing extracting a sublist from an existing list.
+Blockly.Msg.LISTS_GET_SUBLIST_HELPURL = 'https://github.com/google/blockly/wiki/Lists#getting-a-sublist';
+Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
+/// dropdown - Indicates that an index relative to the front of the list should be used
+/// to specify the beginning of the range from which to
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist get a sublist].
+/// [[File:Blockly-get-sublist.png]]
+/// Note: If {{msg-Blockly|ORDINAL_NUMBER_SUFFIX}} is defined, it will
+/// automatically appear ''after'' this number (and any other ordinal numbers on this block).
+/// See [[Translating:Blockly#Ordinal_numbers]] for more information on ordinal numbers in Blockly.
+Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_START = 'get sub-list from #';
+/// dropdown - Indicates that an index relative to the end of the list should be used
+/// to specify the beginning of the range from which to
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist get a sublist].
+Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_END = 'get sub-list from # from end';
+/// dropdown - Indicates that the
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist sublist to extract]
+/// should begin with the list's first item.
+Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST = 'get sub-list from first';
+/// dropdown - Indicates that an index relative to the front of the list should be
+/// used to specify the end of the range from which to
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist get a sublist].
+/// [[File:Blockly-get-sublist.png]]
+Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START = 'to #';
+/// dropdown - Indicates that an index relative to the end of the list should be
+/// used to specify the end of the range from which to
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist get a sublist].
+/// [[File:Blockly-get-sublist.png]]
+Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END = 'to # from end';
+/// dropdown - Indicates that the '''last''' item in the given list should be
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist the end
+/// of the selected sublist].
+/// [[File:Blockly-get-sublist.png]]
+Blockly.Msg.LISTS_GET_SUBLIST_END_LAST = 'to last';
+/// block text - This appears in the rightmost position ("tail") of the
+/// sublist block, as described at
+/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist
+/// https://github.com/google/blockly/wiki/Lists#getting-a-sublist].
+/// In English and most other languages, this is the empty string.
+/// [[File:Blockly-get-sublist.png]]
+Blockly.Msg.LISTS_GET_SUBLIST_TAIL = '';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-sublist
+/// https://github.com/google/blockly/wiki/Lists#getting-a-sublist] for more information.
+/// [[File:Blockly-get-sublist.png]]
+Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP = 'Creates a copy of the specified portion of a list.';
+
+/// url - Information describing sorting a list.
+Blockly.Msg.LISTS_SORT_HELPURL = 'https://github.com/google/blockly/wiki/Lists#sorting-a-list';
+/// Sort as type %1 (numeric or alphabetic) in order %2 (ascending or descending) a list of items %3.\n{{Identical|Sort}}
+Blockly.Msg.LISTS_SORT_TITLE = 'sort %1 %2 %3';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#sorting-a-list].
+Blockly.Msg.LISTS_SORT_TOOLTIP = 'Sort a copy of a list.';
+/// sorting order or direction from low to high value for numeric, or A-Z for alphabetic.\n{{Identical|Ascending}}
+Blockly.Msg.LISTS_SORT_ORDER_ASCENDING = 'ascending';
+/// sorting order or direction from high to low value for numeric, or Z-A for alphabetic.\n{{Identical|Descending}}
+Blockly.Msg.LISTS_SORT_ORDER_DESCENDING = 'descending';
+/// sort by treating each item as a number.
+Blockly.Msg.LISTS_SORT_TYPE_NUMERIC = 'numeric';
+/// sort by treating each item alphabetically, case-sensitive.
+Blockly.Msg.LISTS_SORT_TYPE_TEXT = 'alphabetic';
+/// sort by treating each item alphabetically, ignoring differences in case.
+Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE = 'alphabetic, ignore case';
+
+/// url - Information describing splitting text into a list, or joining a list into text.
+Blockly.Msg.LISTS_SPLIT_HELPURL = 'https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists';
+/// dropdown - Indicates that text will be split up into a list (e.g. "a-b-c" -> ["a", "b", "c"]).
+Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT = 'make list from text';
+/// dropdown - Indicates that a list will be joined together to form text (e.g. ["a", "b", "c"] -> "a-b-c").
+Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST = 'make text from list';
+/// block text - Prompts for a letter to be used as a separator when splitting or joining text.
+Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER = 'with delimiter';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#make-list-from-text
+/// https://github.com/google/blockly/wiki/Lists#make-list-from-text] for more information.
+Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT = 'Split text into a list of texts, breaking at each delimiter.';
+/// tooltip - See [https://github.com/google/blockly/wiki/Lists#make-text-from-list
+/// https://github.com/google/blockly/wiki/Lists#make-text-from-list] for more information.
+Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN = 'Join a list of texts into one text, separated by a delimiter.';
+
+/// grammar - Text that follows an ordinal number (a number that indicates
+/// position relative to other numbers). In most languages, such text appears
+/// before the number, so this should be blank. An exception is Hungarian.
+/// See [[Translating:Blockly#Ordinal_numbers]] for more information.
+Blockly.Msg.ORDINAL_NUMBER_SUFFIX = '';
+
+// Variables Blocks.
+/// url - Information about ''variables'' in computer programming. Consider using your language's translation of [https://en.wikipedia.org/wiki/Variable_(computer_science) https://en.wikipedia.org/wiki/Variable_(computer_science)], if it exists.
+Blockly.Msg.VARIABLES_GET_HELPURL = 'https://github.com/google/blockly/wiki/Variables#get';
+/// tooltip - This gets the value of the named variable without modifying it.
+Blockly.Msg.VARIABLES_GET_TOOLTIP = 'Returns the value of this variable.';
+/// context menu - Selecting this creates a block to set (change) the value of this variable.
+/// \n\nParameters:\n* %1 - the name of the variable.
+Blockly.Msg.VARIABLES_GET_CREATE_SET = 'Create "set %1"';
+
+/// url - Information about ''variables'' in computer programming. Consider using your language's translation of [https://en.wikipedia.org/wiki/Variable_(computer_science) https://en.wikipedia.org/wiki/Variable_(computer_science)], if it exists.
+Blockly.Msg.VARIABLES_SET_HELPURL = 'https://github.com/google/blockly/wiki/Variables#set';
+/// block text - Change the value of a mathematical variable: '''set [the value of] x to 7'''.\n\nParameters:\n* %1 - the name of the variable.\n* %2 - the value to be assigned.
+Blockly.Msg.VARIABLES_SET = 'set %1 to %2';
+/// tooltip - This initializes or changes the value of the named variable.
+Blockly.Msg.VARIABLES_SET_TOOLTIP = 'Sets this variable to be equal to the input.';
+/// context menu - Selecting this creates a block to get (change) the value of
+/// this variable.\n\nParameters:\n* %1 - the name of the variable.
+Blockly.Msg.VARIABLES_SET_CREATE_GET = 'Create "get %1"';
+
+// Procedures Blocks.
+/// url - Information about defining [https://en.wikipedia.org/wiki/Procedure_(computer_science) functions] that do not have return values.
+Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL = 'https://en.wikipedia.org/wiki/Procedure_%28computer_science%29';
+/// block text - This precedes the name of the function when defining it. See
+/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#c84aoc this sample
+/// function definition].
+Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE = 'to';
+/// default name - This acts as a placeholder for the name of a function on a
+/// function definition block, as shown on
+/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#w7cfju this block].
+/// The user will replace it with the function's name.
+Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE = 'do something';
+/// block text - This precedes the list of parameters on a function's defiition block. See
+/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample
+/// function with parameters].
+Blockly.Msg.PROCEDURES_BEFORE_PARAMS = 'with:';
+/// block text - This precedes the list of parameters on a function's caller block. See
+/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample
+/// function with parameters].
+Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS = 'with:';
+/// block text - This appears next to the function's "body", the blocks that should be
+/// run when the function is called, as shown in
+/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample
+/// function definition].
+Blockly.Msg.PROCEDURES_DEFNORETURN_DO = '';
+/// tooltip
+Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP = 'Creates a function with no output.';
+/// Placeholder text that the user is encouraged to replace with a description of what their function does.
+Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT = 'Describe this function...';
+/// url - Information about defining [https://en.wikipedia.org/wiki/Procedure_(computer_science) functions] that have return values.
+Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL = 'https://en.wikipedia.org/wiki/Procedure_%28computer_science%29';
+Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
+Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
+Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
+Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
+/// block text - This imperative or infinite verb precedes the value that is used as the return value
+/// (output) of this function. See
+/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#6ot5y5 this sample
+/// function that returns a value].
+Blockly.Msg.PROCEDURES_DEFRETURN_RETURN = 'return';
+/// tooltip
+Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP = 'Creates a function with an output.';
+/// Label for a checkbox that controls if statements are allowed in a function.
+Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS = 'allow statements';
+
+/// alert - The user has created a function with two parameters that have the same name. Every parameter must have a different name.
+Blockly.Msg.PROCEDURES_DEF_DUPLICATE_WARNING = 'Warning: This function has duplicate parameters.';
+
+/// url - Information about calling [https://en.wikipedia.org/wiki/Procedure_(computer_science) functions] that do not return values.
+Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL = 'https://en.wikipedia.org/wiki/Procedure_%28computer_science%29';
+/// tooltip - This block causes the body (blocks inside) of the named function definition to be run.
+Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP = 'Run the user-defined function "%1".';
+
+/// url - Information about calling [https://en.wikipedia.org/wiki/Procedure_(computer_science) functions] that return values.
+Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL = 'https://en.wikipedia.org/wiki/Procedure_%28computer_science%29';
+/// tooltip - This block causes the body (blocks inside) of the named function definition to be run.\n\nParameters:\n* %1 - the name of the function.
+Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP = 'Run the user-defined function "%1" and use its output.';
+
+/// block text - This text appears on a block in a window that appears when the user clicks
+/// on the plus sign or star on a function definition block. It refers to the set of parameters
+/// (referred to by the simpler term "inputs") to the function. See
+/// [[Translating:Blockly#function_definitions]].
+Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE = 'inputs';
+/// tooltip
+Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP = 'Add, remove, or reorder inputs to this function.';
+/// block text - This text appears on a block in a window that appears when the user clicks
+/// on the plus sign or star on a function definition block]. It appears on the block for
+/// adding an individual parameter (referred to by the simpler term "inputs") to the function.
+/// See [[Translating:Blockly#function_definitions]].
+Blockly.Msg.PROCEDURES_MUTATORARG_TITLE = 'input name:';
+/// tooltip
+Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP = 'Add an input to the function.';
+
+/// context menu - This appears on the context menu for function calls. Selecting
+/// it causes the corresponding function definition to be highlighted (as shown at
+/// [[Translating:Blockly#context_menus]].
+Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF = 'Highlight function definition';
+/// context menu - This appears on the context menu for function definitions.
+/// Selecting it creates a block to call the function.\n\nParameters:\n* %1 - the name of the function.\n{{Identical|Create}}
+Blockly.Msg.PROCEDURES_CREATE_DO = 'Create "%1"';
+
+/// tooltip - If the first value is true, this causes the second value to be returned
+/// immediately from the enclosing function.
+Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP = 'If a value is true, then return a second value.';
+/// url - Information about guard clauses.
+Blockly.Msg.PROCEDURES_IFRETURN_HELPURL = 'http://c2.com/cgi/wiki?GuardClause';
+/// warning - This appears if the user tries to use this block outside of a function definition.
+Blockly.Msg.PROCEDURES_IFRETURN_WARNING = 'Warning: This block may be used only within a function definition.';
diff --git a/src/deps.cljs b/src/deps.cljs
index baa64cb..c4f27f3 100644
--- a/src/deps.cljs
+++ b/src/deps.cljs
@@ -1,50 +1,2 @@
-{:libs [
-"blockly/core/block.js"
-"blockly/core/blockly.js"
-"blockly/core/block_render_svg.js"
-"blockly/core/blocks.js"
-"blockly/core/block_svg.js"
-"blockly/core/bubble.js"
-"blockly/core/comment.js"
-"blockly/core/connection_db.js"
-"blockly/core/connection.js"
-"blockly/core/constants.js"
-"blockly/core/contextmenu.js"
-"blockly/core/css.js"
-"blockly/core/events.js"
-"blockly/core/field_angle.js"
-"blockly/core/field_checkbox.js"
-"blockly/core/field_colour.js"
-"blockly/core/field_date.js"
-"blockly/core/field_dropdown.js"
-"blockly/core/field_image.js"
-"blockly/core/field.js"
-"blockly/core/field_label.js"
-"blockly/core/field_number.js"
-"blockly/core/field_textinput.js"
-"blockly/core/field_variable.js"
-"blockly/core/flyout_button.js"
-"blockly/core/flyout.js"
-"blockly/core/generator.js"
-"blockly/core/icon.js"
-"blockly/core/inject.js"
-"blockly/core/input.js"
-"blockly/core/msg.js"
-"blockly/core/mutator.js"
-"blockly/core/names.js"
-"blockly/core/options.js"
-"blockly/core/procedures.js"
-"blockly/core/rendered_connection.js"
-"blockly/core/scrollbar.js"
-"blockly/core/toolbox.js"
-"blockly/core/tooltip.js"
-"blockly/core/trashcan.js"
-"blockly/core/utils.js"
-"blockly/core/variables.js"
-"blockly/core/warning.js"
-"blockly/core/widgetdiv.js"
-"blockly/core/workspace.js"
-"blockly/core/workspace_svg.js"
-"blockly/core/xml.js"
-"blockly/core/zoom_controls.js"
-]}
+{:libs ["src/blockly"]
+ :externs ["svg.ext.js"]}
diff --git a/src/index.cljs.hl b/src/index.cljs.hl
index 70fe417..cc70325 100644
--- a/src/index.cljs.hl
+++ b/src/index.cljs.hl
@@ -2,7 +2,16 @@
(:require [app.rpc :as rpc]
[cljs.pprint :refer [pprint]]
[cljsjs.semantic-ui :as ui]
- [Blockly]))
+ [Blockly]
+ [Blockly.Blocks.loops]
+ [Blockly.Blocks.lists]
+ [Blockly.Blocks.texts]
+ [Blockly.Blocks.procedures]
+ [Blockly.Blocks.math]
+ [Blockly.Blocks.variables]
+ [Blockly.Blocks.colour]
+ [Blockly.Blocks.logic]
+ [Blockly.Msg.en]))
(rpc/init)
(defc= state rpc/state)
@@ -32,11 +41,11 @@
(head
(link :rel "stylesheet" :type "text/css"
:href "cljsjs/semantic-ui/common/semantic.min.css")
- (script :src "blocks_compressed.js")
- (script :src "en.js")
(title "Tankputer"))
(body
(h1 "Tankputer")
- (textarea :text (cell= (with-out-str (pprint state))))))
+ (textarea :text (cell= (with-out-str (pprint state))))
+ (blockly-workspace :css {:height "480px" :width "600px"}
+ :options {:media "media/" :toolbox toolbox})))
;; vim: set expandtab ts=2 sw=2 filetype=clojure :
diff --git a/src/svg.ext.js b/src/svg.ext.js
new file mode 100644
index 0000000..e11ace7
--- /dev/null
+++ b/src/svg.ext.js
@@ -0,0 +1,10381 @@
+/*
+ * Copyright 2012 The Closure Compiler Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Generated by closureidl 0.2dev closureidl-parser-webkit 0.2dev dart-idl 7592.
+ * Parser: type=webkit dir=${WEBKIT}/Source/WebCore/_/_.idl dir=${WEBKIT}/Source/WebCore/_/_/_.idl dir=${WEBKIT}/Source/WebCore/Modules/_/_.idl
+ * Context0: id=webkit
+ * Filter0: annotate-platform platform=webkit
+ * Filter1: merge-supplemental
+ * Filter2: fix-nulls
+ * Filter3: fix-constructors
+ * Filter4: rename-interfaces
+ * Filter5: check-consistency
+ * Context1: id=closure
+ * Filter0: import context=webkit
+ * Filter1: closure:merge-overloaded-methods
+ * Filter2: closure:fix-callbacks remove=false
+ * Filter3: closure:fix-arrays remove=simple
+ * Filter4: closure:fix-optionals
+ * Filter5: closure:rename-reserved-params
+ * Filter6: closure:guess-interfaces
+ * Filter7: closure:expand-interfaces
+ * Output: format=js
+ *
+ * @externs
+ */
+
+/**
+ * @constructor
+ */
+function SVGAnimatedNumberList(){}
+
+
+/**
+ * @type {!SVGNumberList}
+ */
+SVGAnimatedNumberList.prototype.baseVal;
+
+
+/**
+ * @type {!SVGNumberList}
+ */
+SVGAnimatedNumberList.prototype.animVal;
+
+
+
+/**
+ * @constructor
+ */
+function SVGLengthList(){}
+
+
+/**
+ * @type {number}
+ */
+SVGLengthList.prototype.numberOfItems;
+
+
+/** */
+SVGLengthList.prototype.clear = function(){};
+
+
+/**
+ * @param {!SVGLength} item
+ * @return {!SVGLength}
+ */
+SVGLengthList.prototype.initialize = function(item){};
+
+
+/**
+ * @param {number} index
+ * @return {!SVGLength}
+ */
+SVGLengthList.prototype.getItem = function(index){};
+
+
+/**
+ * @param {!SVGLength} item
+ * @param {number} index
+ * @return {!SVGLength}
+ */
+SVGLengthList.prototype.insertItemBefore = function(item, index){};
+
+
+/**
+ * @param {!SVGLength} item
+ * @param {number} index
+ * @return {!SVGLength}
+ */
+SVGLengthList.prototype.replaceItem = function(item, index){};
+
+
+/**
+ * @param {number} index
+ * @return {!SVGLength}
+ */
+SVGLengthList.prototype.removeItem = function(index){};
+
+
+/**
+ * @param {!SVGLength} item
+ * @return {!SVGLength}
+ */
+SVGLengthList.prototype.appendItem = function(item){};
+
+
+
+/**
+ * @constructor
+ * @implements {EventTarget}
+ */
+function SVGElementInstance(){}
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGElementInstance.prototype.correspondingElement;
+
+
+/**
+ * @type {!SVGUseElement}
+ */
+SVGElementInstance.prototype.correspondingUseElement;
+
+
+/**
+ * @type {!SVGElementInstance}
+ */
+SVGElementInstance.prototype.parentNode;
+
+
+/**
+ * @type {!Array.<!SVGElementInstance>|!SVGElementInstanceList}
+ */
+SVGElementInstance.prototype.childNodes;
+
+
+/**
+ * @type {!SVGElementInstance}
+ */
+SVGElementInstance.prototype.firstChild;
+
+
+/**
+ * @type {!SVGElementInstance}
+ */
+SVGElementInstance.prototype.lastChild;
+
+
+/**
+ * @type {!SVGElementInstance}
+ */
+SVGElementInstance.prototype.previousSibling;
+
+
+/**
+ * @type {!SVGElementInstance}
+ */
+SVGElementInstance.prototype.nextSibling;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onabort;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onblur;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onchange;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onclick;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.oncontextmenu;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.ondblclick;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onerror;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onfocus;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.oninput;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onkeydown;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onkeypress;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onkeyup;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onload;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onmousedown;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onmousemove;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onmouseout;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onmouseover;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onmouseup;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onmousewheel;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onbeforecut;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.oncut;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onbeforecopy;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.oncopy;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onbeforepaste;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onpaste;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.ondragenter;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.ondragover;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.ondragleave;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.ondrop;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.ondragstart;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.ondrag;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.ondragend;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onreset;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onresize;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onscroll;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onsearch;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onselect;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onselectstart;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onsubmit;
+
+
+/**
+ * @type {!EventListener|function(!Event)}
+ */
+SVGElementInstance.prototype.onunload;
+
+
+/**
+ * @param {string} type
+ * @param {!EventListener|(function(Event): (boolean|undefined))| null} listener
+ * @param {boolean=} opt_useCapture
+ */
+SVGElementInstance.prototype.addEventListener = function(type, listener, opt_useCapture){};
+
+
+/**
+ * @param {string} type
+ * @param {!EventListener|(function(Event): (boolean|undefined))| null} listener
+ * @param {boolean=} opt_useCapture
+ */
+SVGElementInstance.prototype.removeEventListener = function(type, listener, opt_useCapture){};
+
+
+/**
+ * @param {Event} event
+ * @return {boolean}
+ */
+SVGElementInstance.prototype.dispatchEvent = function(event){};
+
+
+
+/**
+ * @constructor
+ */
+function SVGAnimatedRect(){}
+
+
+/**
+ * @type {!SVGRect}
+ */
+SVGAnimatedRect.prototype.baseVal;
+
+
+/**
+ * @type {!SVGRect}
+ */
+SVGAnimatedRect.prototype.animVal;
+
+
+
+/**
+ * @constructor
+ */
+function SVGAnimatedString(){}
+
+
+/**
+ * @type {string}
+ */
+SVGAnimatedString.prototype.baseVal;
+
+
+/**
+ * @type {string}
+ */
+SVGAnimatedString.prototype.animVal;
+
+
+
+/**
+ * @interface
+ */
+function SVGStylable(){}
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGStylable.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGStylable.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGStylable.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @interface
+ */
+function SVGExternalResourcesRequired(){}
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGExternalResourcesRequired.prototype.externalResourcesRequired;
+
+
+
+/**
+ * @constructor
+ */
+function SVGPoint(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPoint.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPoint.prototype.y;
+
+
+/**
+ * @param {!SVGMatrix} matrix
+ * @return {!SVGPoint}
+ */
+SVGPoint.prototype.matrixTransform = function(matrix){};
+
+
+
+/**
+ * @constructor
+ */
+function SVGMatrix(){}
+
+
+/**
+ * @type {number}
+ */
+SVGMatrix.prototype.a;
+
+
+/**
+ * @type {number}
+ */
+SVGMatrix.prototype.b;
+
+
+/**
+ * @type {number}
+ */
+SVGMatrix.prototype.c;
+
+
+/**
+ * @type {number}
+ */
+SVGMatrix.prototype.d;
+
+
+/**
+ * @type {number}
+ */
+SVGMatrix.prototype.e;
+
+
+/**
+ * @type {number}
+ */
+SVGMatrix.prototype.f;
+
+
+/**
+ * @param {!SVGMatrix} secondMatrix
+ * @return {!SVGMatrix}
+ */
+SVGMatrix.prototype.multiply = function(secondMatrix){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGMatrix.prototype.inverse = function(){};
+
+
+/**
+ * @param {number} x
+ * @param {number} y
+ * @return {!SVGMatrix}
+ */
+SVGMatrix.prototype.translate = function(x, y){};
+
+
+/**
+ * @param {number} scaleFactor
+ * @return {!SVGMatrix}
+ */
+SVGMatrix.prototype.scale = function(scaleFactor){};
+
+
+/**
+ * @param {number} scaleFactorX
+ * @param {number} scaleFactorY
+ * @return {!SVGMatrix}
+ */
+SVGMatrix.prototype.scaleNonUniform = function(scaleFactorX, scaleFactorY){};
+
+
+/**
+ * @param {number} angle
+ * @return {!SVGMatrix}
+ */
+SVGMatrix.prototype.rotate = function(angle){};
+
+
+/**
+ * @param {number} x
+ * @param {number} y
+ * @return {!SVGMatrix}
+ */
+SVGMatrix.prototype.rotateFromVector = function(x, y){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGMatrix.prototype.flipX = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGMatrix.prototype.flipY = function(){};
+
+
+/**
+ * @param {number} angle
+ * @return {!SVGMatrix}
+ */
+SVGMatrix.prototype.skewX = function(angle){};
+
+
+/**
+ * @param {number} angle
+ * @return {!SVGMatrix}
+ */
+SVGMatrix.prototype.skewY = function(angle){};
+
+
+
+/**
+ * @constructor
+ */
+function SVGNumberList(){}
+
+
+/**
+ * @type {number}
+ */
+SVGNumberList.prototype.numberOfItems;
+
+
+/** */
+SVGNumberList.prototype.clear = function(){};
+
+
+/**
+ * @param {!SVGNumber} item
+ * @return {!SVGNumber}
+ */
+SVGNumberList.prototype.initialize = function(item){};
+
+
+/**
+ * @param {number} index
+ * @return {!SVGNumber}
+ */
+SVGNumberList.prototype.getItem = function(index){};
+
+
+/**
+ * @param {!SVGNumber} item
+ * @param {number} index
+ * @return {!SVGNumber}
+ */
+SVGNumberList.prototype.insertItemBefore = function(item, index){};
+
+
+/**
+ * @param {!SVGNumber} item
+ * @param {number} index
+ * @return {!SVGNumber}
+ */
+SVGNumberList.prototype.replaceItem = function(item, index){};
+
+
+/**
+ * @param {number} index
+ * @return {!SVGNumber}
+ */
+SVGNumberList.prototype.removeItem = function(index){};
+
+
+/**
+ * @param {!SVGNumber} item
+ * @return {!SVGNumber}
+ */
+SVGNumberList.prototype.appendItem = function(item){};
+
+
+
+/**
+ * @interface
+ */
+function SVGLangSpace(){}
+
+
+/**
+ * @type {string}
+ */
+SVGLangSpace.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGLangSpace.prototype.xmlspace;
+
+
+
+/**
+ * @constructor
+ */
+function SVGAnimatedLengthList(){}
+
+
+/**
+ * @type {!SVGLengthList}
+ */
+SVGAnimatedLengthList.prototype.baseVal;
+
+
+/**
+ * @type {!SVGLengthList}
+ */
+SVGAnimatedLengthList.prototype.animVal;
+
+
+
+/**
+ * @constructor
+ */
+function SVGAnimatedTransformList(){}
+
+
+/**
+ * @type {!SVGTransformList}
+ */
+SVGAnimatedTransformList.prototype.baseVal;
+
+
+/**
+ * @type {!SVGTransformList}
+ */
+SVGAnimatedTransformList.prototype.animVal;
+
+
+
+/**
+ * @constructor
+ */
+function SVGUnitTypes(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGUnitTypes.SVG_UNIT_TYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGUnitTypes.prototype.SVG_UNIT_TYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGUnitTypes.prototype.SVG_UNIT_TYPE_USERSPACEONUSE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGUnitTypes.prototype.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
+
+
+
+/**
+ * @constructor
+ */
+function SVGLength(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.SVG_LENGTHTYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.prototype.SVG_LENGTHTYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.SVG_LENGTHTYPE_NUMBER;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.prototype.SVG_LENGTHTYPE_NUMBER;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.SVG_LENGTHTYPE_PERCENTAGE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.prototype.SVG_LENGTHTYPE_PERCENTAGE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.SVG_LENGTHTYPE_EMS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.prototype.SVG_LENGTHTYPE_EMS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.SVG_LENGTHTYPE_EXS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.prototype.SVG_LENGTHTYPE_EXS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.SVG_LENGTHTYPE_PX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.prototype.SVG_LENGTHTYPE_PX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.SVG_LENGTHTYPE_CM;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.prototype.SVG_LENGTHTYPE_CM;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.SVG_LENGTHTYPE_MM;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.prototype.SVG_LENGTHTYPE_MM;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.SVG_LENGTHTYPE_IN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.prototype.SVG_LENGTHTYPE_IN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.SVG_LENGTHTYPE_PT;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.prototype.SVG_LENGTHTYPE_PT;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.SVG_LENGTHTYPE_PC;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGLength.prototype.SVG_LENGTHTYPE_PC;
+
+
+/**
+ * @type {number}
+ */
+SVGLength.prototype.unitType;
+
+
+/**
+ * @type {number}
+ */
+SVGLength.prototype.value;
+
+
+/**
+ * @type {number}
+ */
+SVGLength.prototype.valueInSpecifiedUnits;
+
+
+/**
+ * @type {string}
+ */
+SVGLength.prototype.valueAsString;
+
+
+/**
+ * @param {number} unitType
+ * @param {number} valueInSpecifiedUnits
+ */
+SVGLength.prototype.newValueSpecifiedUnits = function(unitType, valueInSpecifiedUnits){};
+
+
+/**
+ * @param {number} unitType
+ */
+SVGLength.prototype.convertToSpecifiedUnits = function(unitType){};
+
+
+
+/**
+ * @constructor
+ */
+function SVGAnimatedNumber(){}
+
+
+/**
+ * @type {number}
+ */
+SVGAnimatedNumber.prototype.baseVal;
+
+
+/**
+ * @type {number}
+ */
+SVGAnimatedNumber.prototype.animVal;
+
+
+
+/**
+ * @constructor
+ */
+function SVGAnimatedAngle(){}
+
+
+/**
+ * @type {!SVGAngle}
+ */
+SVGAnimatedAngle.prototype.baseVal;
+
+
+/**
+ * @type {!SVGAngle}
+ */
+SVGAnimatedAngle.prototype.animVal;
+
+
+
+/**
+ * @interface
+ * @extends {SVGStylable}
+ */
+function SVGFilterPrimitiveStandardAttributes(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFilterPrimitiveStandardAttributes.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFilterPrimitiveStandardAttributes.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFilterPrimitiveStandardAttributes.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFilterPrimitiveStandardAttributes.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFilterPrimitiveStandardAttributes.prototype.result;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGGradientElement}
+ */
+function SVGLinearGradientElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGLinearGradientElement.prototype.x1;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGLinearGradientElement.prototype.y1;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGLinearGradientElement.prototype.x2;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGLinearGradientElement.prototype.y2;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGGradientElement}
+ */
+function SVGRadialGradientElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGRadialGradientElement.prototype.cx;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGRadialGradientElement.prototype.cy;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGRadialGradientElement.prototype.r;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGRadialGradientElement.prototype.fx;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGRadialGradientElement.prototype.fy;
+
+
+
+/**
+ * @constructor
+ */
+function SVGTransform(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.SVG_TRANSFORM_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.prototype.SVG_TRANSFORM_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.SVG_TRANSFORM_MATRIX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.prototype.SVG_TRANSFORM_MATRIX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.SVG_TRANSFORM_TRANSLATE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.prototype.SVG_TRANSFORM_TRANSLATE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.SVG_TRANSFORM_SCALE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.prototype.SVG_TRANSFORM_SCALE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.SVG_TRANSFORM_ROTATE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.prototype.SVG_TRANSFORM_ROTATE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.SVG_TRANSFORM_SKEWX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.prototype.SVG_TRANSFORM_SKEWX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.SVG_TRANSFORM_SKEWY;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTransform.prototype.SVG_TRANSFORM_SKEWY;
+
+
+/**
+ * @type {number}
+ */
+SVGTransform.prototype.type;
+
+
+/**
+ * @type {!SVGMatrix}
+ */
+SVGTransform.prototype.matrix;
+
+
+/**
+ * @type {number}
+ */
+SVGTransform.prototype.angle;
+
+
+/**
+ * @param {!SVGMatrix} matrix
+ */
+SVGTransform.prototype.setMatrix = function(matrix){};
+
+
+/**
+ * @param {number} tx
+ * @param {number} ty
+ */
+SVGTransform.prototype.setTranslate = function(tx, ty){};
+
+
+/**
+ * @param {number} sx
+ * @param {number} sy
+ */
+SVGTransform.prototype.setScale = function(sx, sy){};
+
+
+/**
+ * @param {number} angle
+ * @param {number} cx
+ * @param {number} cy
+ */
+SVGTransform.prototype.setRotate = function(angle, cx, cy){};
+
+
+/**
+ * @param {number} angle
+ */
+SVGTransform.prototype.setSkewX = function(angle){};
+
+
+/**
+ * @param {number} angle
+ */
+SVGTransform.prototype.setSkewY = function(angle){};
+
+
+
+/**
+ * @interface
+ */
+function SVGZoomAndPan(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGZoomAndPan.SVG_ZOOMANDPAN_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGZoomAndPan.prototype.SVG_ZOOMANDPAN_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGZoomAndPan.SVG_ZOOMANDPAN_DISABLE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGZoomAndPan.prototype.SVG_ZOOMANDPAN_DISABLE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGZoomAndPan.SVG_ZOOMANDPAN_MAGNIFY;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGZoomAndPan.prototype.SVG_ZOOMANDPAN_MAGNIFY;
+
+
+/**
+ * @type {number}
+ */
+SVGZoomAndPan.prototype.zoomAndPan;
+
+
+
+/**
+ * @constructor
+ */
+function SVGPreserveAspectRatio(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_PRESERVEASPECTRATIO_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_PRESERVEASPECTRATIO_NONE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMIN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_PRESERVEASPECTRATIO_XMINYMIN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMIN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_PRESERVEASPECTRATIO_XMIDYMIN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMIN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_PRESERVEASPECTRATIO_XMAXYMIN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMID;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_PRESERVEASPECTRATIO_XMINYMID;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMID;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_PRESERVEASPECTRATIO_XMIDYMID;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMID;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_PRESERVEASPECTRATIO_XMAXYMID;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMAX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_PRESERVEASPECTRATIO_XMINYMAX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMAX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_PRESERVEASPECTRATIO_XMIDYMAX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMAX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_PRESERVEASPECTRATIO_XMAXYMAX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_MEETORSLICE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_MEETORSLICE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_MEETORSLICE_MEET;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.SVG_MEETORSLICE_SLICE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.SVG_MEETORSLICE_SLICE;
+
+
+/**
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.align;
+
+
+/**
+ * @type {number}
+ */
+SVGPreserveAspectRatio.prototype.meetOrSlice;
+
+
+
+/**
+ * @constructor
+ */
+function SVGRect(){}
+
+
+/**
+ * @type {number}
+ */
+SVGRect.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGRect.prototype.y;
+
+
+/**
+ * @type {number}
+ */
+SVGRect.prototype.width;
+
+
+/**
+ * @type {number}
+ */
+SVGRect.prototype.height;
+
+
+
+/**
+ * @constructor
+ */
+function SVGException(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGException.SVG_WRONG_TYPE_ERR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGException.prototype.SVG_WRONG_TYPE_ERR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGException.SVG_INVALID_VALUE_ERR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGException.prototype.SVG_INVALID_VALUE_ERR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGException.SVG_MATRIX_NOT_INVERTABLE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGException.prototype.SVG_MATRIX_NOT_INVERTABLE;
+
+
+/**
+ * @type {number}
+ */
+SVGException.prototype.code;
+
+
+/**
+ * @type {string}
+ */
+SVGException.prototype.name;
+
+
+/**
+ * @type {string}
+ */
+SVGException.prototype.message;
+
+
+/**
+ * @return {string}
+ */
+SVGException.prototype.toString = function(){};
+
+
+
+/**
+ * @constructor
+ * @extends {CSSValue}
+ */
+function SVGColor(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGColor.SVG_COLORTYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGColor.prototype.SVG_COLORTYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGColor.SVG_COLORTYPE_RGBCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGColor.prototype.SVG_COLORTYPE_RGBCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGColor.SVG_COLORTYPE_RGBCOLOR_ICCCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGColor.prototype.SVG_COLORTYPE_RGBCOLOR_ICCCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGColor.SVG_COLORTYPE_CURRENTCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGColor.prototype.SVG_COLORTYPE_CURRENTCOLOR;
+
+
+/**
+ * @type {number}
+ */
+SVGColor.prototype.colorType;
+
+
+/**
+ * @type {!RGBColor}
+ */
+SVGColor.prototype.rgbColor;
+
+
+/**
+ * @param {string} rgbColor
+ */
+SVGColor.prototype.setRGBColor = function(rgbColor){};
+
+
+/**
+ * @param {string} rgbColor
+ * @param {string} iccColor
+ */
+SVGColor.prototype.setRGBColorICCColor = function(rgbColor, iccColor){};
+
+
+/**
+ * @param {number} colorType
+ * @param {string} rgbColor
+ * @param {string} iccColor
+ */
+SVGColor.prototype.setColor = function(colorType, rgbColor, iccColor){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGColor}
+ */
+function SVGPaint(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.SVG_PAINTTYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.prototype.SVG_PAINTTYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.SVG_PAINTTYPE_RGBCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.prototype.SVG_PAINTTYPE_RGBCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.prototype.SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.SVG_PAINTTYPE_NONE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.prototype.SVG_PAINTTYPE_NONE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.SVG_PAINTTYPE_CURRENTCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.prototype.SVG_PAINTTYPE_CURRENTCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.SVG_PAINTTYPE_URI_NONE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.prototype.SVG_PAINTTYPE_URI_NONE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.SVG_PAINTTYPE_URI_CURRENTCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.prototype.SVG_PAINTTYPE_URI_CURRENTCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.SVG_PAINTTYPE_URI_RGBCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.prototype.SVG_PAINTTYPE_URI_RGBCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.prototype.SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.SVG_PAINTTYPE_URI;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPaint.prototype.SVG_PAINTTYPE_URI;
+
+
+/**
+ * @type {number}
+ */
+SVGPaint.prototype.paintType;
+
+
+/**
+ * @type {string}
+ */
+SVGPaint.prototype.uri;
+
+
+/**
+ * @param {string} uri
+ */
+SVGPaint.prototype.setUri = function(uri){};
+
+
+/**
+ * @param {number} paintType
+ * @param {string} uri
+ * @param {string} rgbColor
+ * @param {string} iccColor
+ */
+SVGPaint.prototype.setPaint = function(paintType, uri, rgbColor, iccColor){};
+
+
+
+/**
+ * @constructor
+ */
+function SVGPointList(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPointList.prototype.numberOfItems;
+
+
+/** */
+SVGPointList.prototype.clear = function(){};
+
+
+/**
+ * @param {!SVGPoint} item
+ * @return {!SVGPoint}
+ */
+SVGPointList.prototype.initialize = function(item){};
+
+
+/**
+ * @param {number} index
+ * @return {!SVGPoint}
+ */
+SVGPointList.prototype.getItem = function(index){};
+
+
+/**
+ * @param {!SVGPoint} item
+ * @param {number} index
+ * @return {!SVGPoint}
+ */
+SVGPointList.prototype.insertItemBefore = function(item, index){};
+
+
+/**
+ * @param {!SVGPoint} item
+ * @param {number} index
+ * @return {!SVGPoint}
+ */
+SVGPointList.prototype.replaceItem = function(item, index){};
+
+
+/**
+ * @param {number} index
+ * @return {!SVGPoint}
+ */
+SVGPointList.prototype.removeItem = function(index){};
+
+
+/**
+ * @param {!SVGPoint} item
+ * @return {!SVGPoint}
+ */
+SVGPointList.prototype.appendItem = function(item){};
+
+
+
+/**
+ * @constructor
+ */
+function SVGTransformList(){}
+
+
+/**
+ * @type {number}
+ */
+SVGTransformList.prototype.numberOfItems;
+
+
+/** */
+SVGTransformList.prototype.clear = function(){};
+
+
+/**
+ * @param {!SVGTransform} item
+ * @return {!SVGTransform}
+ */
+SVGTransformList.prototype.initialize = function(item){};
+
+
+/**
+ * @param {number} index
+ * @return {!SVGTransform}
+ */
+SVGTransformList.prototype.getItem = function(index){};
+
+
+/**
+ * @param {!SVGTransform} item
+ * @param {number} index
+ * @return {!SVGTransform}
+ */
+SVGTransformList.prototype.insertItemBefore = function(item, index){};
+
+
+/**
+ * @param {!SVGTransform} item
+ * @param {number} index
+ * @return {!SVGTransform}
+ */
+SVGTransformList.prototype.replaceItem = function(item, index){};
+
+
+/**
+ * @param {number} index
+ * @return {!SVGTransform}
+ */
+SVGTransformList.prototype.removeItem = function(index){};
+
+
+/**
+ * @param {!SVGTransform} item
+ * @return {!SVGTransform}
+ */
+SVGTransformList.prototype.appendItem = function(item){};
+
+
+/**
+ * @param {!SVGMatrix} matrix
+ * @return {!SVGTransform}
+ */
+SVGTransformList.prototype.createSVGTransformFromMatrix = function(matrix){};
+
+
+/**
+ * @return {!SVGTransform}
+ */
+SVGTransformList.prototype.consolidate = function(){};
+
+
+
+/**
+ * @constructor
+ * @extends {UIEvent}
+ */
+function SVGZoomEvent(){}
+
+
+/**
+ * @type {!SVGRect}
+ */
+SVGZoomEvent.prototype.zoomRectScreen;
+
+
+/**
+ * @type {number}
+ */
+SVGZoomEvent.prototype.previousScale;
+
+
+/**
+ * @type {!SVGPoint}
+ */
+SVGZoomEvent.prototype.previousTranslate;
+
+
+/**
+ * @type {number}
+ */
+SVGZoomEvent.prototype.newScale;
+
+
+/**
+ * @type {!SVGPoint}
+ */
+SVGZoomEvent.prototype.newTranslate;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGTextContentElement}
+ */
+function SVGTextPositioningElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLengthList}
+ */
+SVGTextPositioningElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLengthList}
+ */
+SVGTextPositioningElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLengthList}
+ */
+SVGTextPositioningElement.prototype.dx;
+
+
+/**
+ * @type {!SVGAnimatedLengthList}
+ */
+SVGTextPositioningElement.prototype.dy;
+
+
+/**
+ * @type {!SVGAnimatedNumberList}
+ */
+SVGTextPositioningElement.prototype.rotate;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGTextPositioningElement}
+ */
+function SVGTSpanElement(){}
+
+
+
+/**
+ * @constructor
+ */
+function SVGStringList(){}
+
+
+/**
+ * @type {number}
+ */
+SVGStringList.prototype.numberOfItems;
+
+
+/** */
+SVGStringList.prototype.clear = function(){};
+
+
+/**
+ * @param {string} item
+ * @return {string}
+ */
+SVGStringList.prototype.initialize = function(item){};
+
+
+/**
+ * @param {number} index
+ * @return {string}
+ */
+SVGStringList.prototype.getItem = function(index){};
+
+
+/**
+ * @param {string} item
+ * @param {number} index
+ * @return {string}
+ */
+SVGStringList.prototype.insertItemBefore = function(item, index){};
+
+
+/**
+ * @param {string} item
+ * @param {number} index
+ * @return {string}
+ */
+SVGStringList.prototype.replaceItem = function(item, index){};
+
+
+/**
+ * @param {number} index
+ * @return {string}
+ */
+SVGStringList.prototype.removeItem = function(index){};
+
+
+/**
+ * @param {string} item
+ * @return {string}
+ */
+SVGStringList.prototype.appendItem = function(item){};
+
+
+
+/**
+ * @interface
+ */
+function SVGURIReference(){}
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGURIReference.prototype.href;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGTextPositioningElement}
+ * @implements {SVGURIReference}
+ */
+function SVGTRefElement(){}
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGTRefElement.prototype.href;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGTextContentElement}
+ * @implements {SVGURIReference}
+ */
+function SVGTextPathElement(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextPathElement.TEXTPATH_METHODTYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextPathElement.prototype.TEXTPATH_METHODTYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextPathElement.TEXTPATH_METHODTYPE_ALIGN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextPathElement.prototype.TEXTPATH_METHODTYPE_ALIGN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextPathElement.TEXTPATH_METHODTYPE_STRETCH;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextPathElement.prototype.TEXTPATH_METHODTYPE_STRETCH;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextPathElement.TEXTPATH_SPACINGTYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextPathElement.prototype.TEXTPATH_SPACINGTYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextPathElement.TEXTPATH_SPACINGTYPE_AUTO;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextPathElement.prototype.TEXTPATH_SPACINGTYPE_AUTO;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextPathElement.TEXTPATH_SPACINGTYPE_EXACT;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextPathElement.prototype.TEXTPATH_SPACINGTYPE_EXACT;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGTextPathElement.prototype.startOffset;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGTextPathElement.prototype.method;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGTextPathElement.prototype.spacing;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGTextPathElement.prototype.href;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGTextPositioningElement}
+ * @implements {SVGURIReference}
+ */
+function SVGAltGlyphElement(){}
+
+
+/**
+ * @type {string}
+ */
+SVGAltGlyphElement.prototype.glyphRef;
+
+
+/**
+ * @type {string}
+ */
+SVGAltGlyphElement.prototype.format;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGAltGlyphElement.prototype.href;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGComponentTransferFunctionElement}
+ */
+function SVGFEFuncGElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGComponentTransferFunctionElement}
+ */
+function SVGFEFuncAElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGComponentTransferFunctionElement}
+ */
+function SVGFEFuncRElement(){}
+
+
+
+/**
+ * @constructor
+ */
+function SVGNumber(){}
+
+
+/**
+ * @type {number}
+ */
+SVGNumber.prototype.value;
+
+
+
+/**
+ * @interface
+ */
+function SVGTests(){}
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGTests.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGTests.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGTests.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGTests.prototype.hasExtension = function(opt_extension){};
+
+
+
+/**
+ * @constructor
+ */
+function SVGPathSeg(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_CLOSEPATH;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_CLOSEPATH;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_MOVETO_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_MOVETO_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_MOVETO_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_MOVETO_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_LINETO_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_LINETO_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_LINETO_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_LINETO_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_CURVETO_CUBIC_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_CURVETO_CUBIC_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_CURVETO_QUADRATIC_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_CURVETO_QUADRATIC_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_ARC_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_ARC_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_ARC_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_ARC_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_LINETO_HORIZONTAL_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_LINETO_HORIZONTAL_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_LINETO_VERTICAL_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_LINETO_VERTICAL_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGPathSeg.prototype.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSeg.prototype.pathSegType;
+
+
+/**
+ * @type {string}
+ */
+SVGPathSeg.prototype.pathSegTypeAsLetter;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegCurvetoQuadraticSmoothAbs(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoQuadraticSmoothAbs.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoQuadraticSmoothAbs.prototype.y;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegArcRel(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegArcRel.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegArcRel.prototype.y;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegArcRel.prototype.r1;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegArcRel.prototype.r2;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegArcRel.prototype.angle;
+
+
+/**
+ * @type {boolean}
+ */
+SVGPathSegArcRel.prototype.largeArcFlag;
+
+
+/**
+ * @type {boolean}
+ */
+SVGPathSegArcRel.prototype.sweepFlag;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegCurvetoQuadraticAbs(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoQuadraticAbs.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoQuadraticAbs.prototype.y;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoQuadraticAbs.prototype.x1;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoQuadraticAbs.prototype.y1;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegLinetoHorizontalRel(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegLinetoHorizontalRel.prototype.x;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegLinetoRel(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegLinetoRel.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegLinetoRel.prototype.y;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegCurvetoCubicRel(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicRel.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicRel.prototype.y;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicRel.prototype.x1;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicRel.prototype.y1;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicRel.prototype.x2;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicRel.prototype.y2;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegMovetoAbs(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegMovetoAbs.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegMovetoAbs.prototype.y;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegCurvetoQuadraticSmoothRel(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoQuadraticSmoothRel.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoQuadraticSmoothRel.prototype.y;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegLinetoVerticalRel(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegLinetoVerticalRel.prototype.y;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegLinetoAbs(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegLinetoAbs.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegLinetoAbs.prototype.y;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegCurvetoCubicSmoothRel(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicSmoothRel.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicSmoothRel.prototype.y;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicSmoothRel.prototype.x2;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicSmoothRel.prototype.y2;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegLinetoHorizontalAbs(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegLinetoHorizontalAbs.prototype.x;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegCurvetoQuadraticRel(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoQuadraticRel.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoQuadraticRel.prototype.y;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoQuadraticRel.prototype.x1;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoQuadraticRel.prototype.y1;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegCurvetoCubicSmoothAbs(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicSmoothAbs.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicSmoothAbs.prototype.y;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicSmoothAbs.prototype.x2;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicSmoothAbs.prototype.y2;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegCurvetoCubicAbs(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicAbs.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicAbs.prototype.y;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicAbs.prototype.x1;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicAbs.prototype.y1;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicAbs.prototype.x2;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegCurvetoCubicAbs.prototype.y2;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegClosePath(){}
+
+
+
+/**
+ * @interface
+ */
+function SVGFitToViewBox(){}
+
+
+/**
+ * @type {!SVGAnimatedRect}
+ */
+SVGFitToViewBox.prototype.viewBox;
+
+
+/**
+ * @type {!SVGAnimatedPreserveAspectRatio}
+ */
+SVGFitToViewBox.prototype.preserveAspectRatio;
+
+
+
+/**
+ * @constructor
+ * @implements {SVGZoomAndPan}
+ * @implements {SVGFitToViewBox}
+ */
+function SVGViewSpec(){}
+
+
+/**
+ * @type {!SVGTransformList}
+ */
+SVGViewSpec.prototype.transform;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGViewSpec.prototype.viewTarget;
+
+
+/**
+ * @type {string}
+ */
+SVGViewSpec.prototype.viewBoxString;
+
+
+/**
+ * @type {string}
+ */
+SVGViewSpec.prototype.preserveAspectRatioString;
+
+
+/**
+ * @type {string}
+ */
+SVGViewSpec.prototype.transformString;
+
+
+/**
+ * @type {string}
+ */
+SVGViewSpec.prototype.viewTargetString;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGViewSpec.SVG_ZOOMANDPAN_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGViewSpec.prototype.SVG_ZOOMANDPAN_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGViewSpec.SVG_ZOOMANDPAN_DISABLE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGViewSpec.prototype.SVG_ZOOMANDPAN_DISABLE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGViewSpec.SVG_ZOOMANDPAN_MAGNIFY;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGViewSpec.prototype.SVG_ZOOMANDPAN_MAGNIFY;
+
+
+/**
+ * @type {number}
+ */
+SVGViewSpec.prototype.zoomAndPan;
+
+
+/**
+ * @type {!SVGAnimatedRect}
+ */
+SVGViewSpec.prototype.viewBox;
+
+
+/**
+ * @type {!SVGAnimatedPreserveAspectRatio}
+ */
+SVGViewSpec.prototype.preserveAspectRatio;
+
+
+
+/**
+ * @constructor
+ */
+function SVGRenderingIntent(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGRenderingIntent.RENDERING_INTENT_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGRenderingIntent.prototype.RENDERING_INTENT_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGRenderingIntent.RENDERING_INTENT_AUTO;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGRenderingIntent.prototype.RENDERING_INTENT_AUTO;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGRenderingIntent.RENDERING_INTENT_PERCEPTUAL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGRenderingIntent.prototype.RENDERING_INTENT_PERCEPTUAL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGRenderingIntent.RENDERING_INTENT_RELATIVE_COLORIMETRIC;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGRenderingIntent.prototype.RENDERING_INTENT_RELATIVE_COLORIMETRIC;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGRenderingIntent.RENDERING_INTENT_SATURATION;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGRenderingIntent.prototype.RENDERING_INTENT_SATURATION;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGRenderingIntent.RENDERING_INTENT_ABSOLUTE_COLORIMETRIC;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGRenderingIntent.prototype.RENDERING_INTENT_ABSOLUTE_COLORIMETRIC;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegLinetoVerticalAbs(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegLinetoVerticalAbs.prototype.y;
+
+
+
+/**
+ * @constructor
+ */
+function SVGPathSegList(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegList.prototype.numberOfItems;
+
+
+/** */
+SVGPathSegList.prototype.clear = function(){};
+
+
+/**
+ * @param {!SVGPathSeg} newItem
+ * @return {!SVGPathSeg}
+ */
+SVGPathSegList.prototype.initialize = function(newItem){};
+
+
+/**
+ * @param {number} index
+ * @return {!SVGPathSeg}
+ */
+SVGPathSegList.prototype.getItem = function(index){};
+
+
+/**
+ * @param {!SVGPathSeg} newItem
+ * @param {number} index
+ * @return {!SVGPathSeg}
+ */
+SVGPathSegList.prototype.insertItemBefore = function(newItem, index){};
+
+
+/**
+ * @param {!SVGPathSeg} newItem
+ * @param {number} index
+ * @return {!SVGPathSeg}
+ */
+SVGPathSegList.prototype.replaceItem = function(newItem, index){};
+
+
+/**
+ * @param {number} index
+ * @return {!SVGPathSeg}
+ */
+SVGPathSegList.prototype.removeItem = function(index){};
+
+
+/**
+ * @param {!SVGPathSeg} newItem
+ * @return {!SVGPathSeg}
+ */
+SVGPathSegList.prototype.appendItem = function(newItem){};
+
+
+
+/**
+ * @constructor
+ * @extends {Document}
+ */
+function SVGDocument(){}
+
+
+/**
+ * @type {!SVGSVGElement}
+ */
+SVGDocument.prototype.rootElement;
+
+
+/**
+ * @param {string=} opt_eventType
+ * @return {!Event}
+ */
+SVGDocument.prototype.createEvent = function(opt_eventType){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGAltGlyphItemElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGFontFaceFormatElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFECompositeElement(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.SVG_FECOMPOSITE_OPERATOR_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.prototype.SVG_FECOMPOSITE_OPERATOR_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.SVG_FECOMPOSITE_OPERATOR_OVER;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.prototype.SVG_FECOMPOSITE_OPERATOR_OVER;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.SVG_FECOMPOSITE_OPERATOR_IN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.prototype.SVG_FECOMPOSITE_OPERATOR_IN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.SVG_FECOMPOSITE_OPERATOR_OUT;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.prototype.SVG_FECOMPOSITE_OPERATOR_OUT;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.SVG_FECOMPOSITE_OPERATOR_ATOP;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.prototype.SVG_FECOMPOSITE_OPERATOR_ATOP;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.SVG_FECOMPOSITE_OPERATOR_XOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.prototype.SVG_FECOMPOSITE_OPERATOR_XOR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.SVG_FECOMPOSITE_OPERATOR_ARITHMETIC;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFECompositeElement.prototype.SVG_FECOMPOSITE_OPERATOR_ARITHMETIC;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFECompositeElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFECompositeElement.prototype.in2;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGFECompositeElement.prototype.operator;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFECompositeElement.prototype.k1;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFECompositeElement.prototype.k2;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFECompositeElement.prototype.k3;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFECompositeElement.prototype.k4;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFECompositeElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFECompositeElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFECompositeElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFECompositeElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFECompositeElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFECompositeElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFECompositeElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFECompositeElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGLangSpace}
+ * @implements {SVGStylable}
+ */
+function SVGDescElement(){}
+
+
+/**
+ * @type {string}
+ */
+SVGDescElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGDescElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGDescElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGDescElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGDescElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGEllipseElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGEllipseElement.prototype.cx;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGEllipseElement.prototype.cy;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGEllipseElement.prototype.rx;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGEllipseElement.prototype.ry;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGEllipseElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGEllipseElement.prototype.transform;
+
+
+/**
+ * @type {string}
+ */
+SVGEllipseElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGEllipseElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGEllipseElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGEllipseElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGEllipseElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGEllipseElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGEllipseElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGEllipseElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGEllipseElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGEllipseElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGEllipseElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGEllipseElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGEllipseElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGEllipseElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGEllipseElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFESpecularLightingElement(){}
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFESpecularLightingElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFESpecularLightingElement.prototype.surfaceScale;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFESpecularLightingElement.prototype.specularConstant;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFESpecularLightingElement.prototype.specularExponent;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFESpecularLightingElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFESpecularLightingElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFESpecularLightingElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFESpecularLightingElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFESpecularLightingElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFESpecularLightingElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFESpecularLightingElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFESpecularLightingElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEColorMatrixElement(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEColorMatrixElement.prototype.SVG_FECOLORMATRIX_TYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_MATRIX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEColorMatrixElement.prototype.SVG_FECOLORMATRIX_TYPE_MATRIX;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_SATURATE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEColorMatrixElement.prototype.SVG_FECOLORMATRIX_TYPE_SATURATE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_HUEROTATE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEColorMatrixElement.prototype.SVG_FECOLORMATRIX_TYPE_HUEROTATE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEColorMatrixElement.prototype.SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEColorMatrixElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGFEColorMatrixElement.prototype.type;
+
+
+/**
+ * @type {!SVGAnimatedNumberList}
+ */
+SVGFEColorMatrixElement.prototype.values;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEColorMatrixElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEColorMatrixElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEColorMatrixElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEColorMatrixElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEColorMatrixElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEColorMatrixElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEColorMatrixElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEColorMatrixElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGFitToViewBox}
+ */
+function SVGSymbolElement(){}
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGSymbolElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedRect}
+ */
+SVGSymbolElement.prototype.viewBox;
+
+
+/**
+ * @type {!SVGAnimatedPreserveAspectRatio}
+ */
+SVGSymbolElement.prototype.preserveAspectRatio;
+
+
+/**
+ * @type {string}
+ */
+SVGSymbolElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGSymbolElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGSymbolElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGSymbolElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGSymbolElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEConvolveMatrixElement(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEConvolveMatrixElement.SVG_EDGEMODE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEConvolveMatrixElement.prototype.SVG_EDGEMODE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEConvolveMatrixElement.SVG_EDGEMODE_DUPLICATE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEConvolveMatrixElement.prototype.SVG_EDGEMODE_DUPLICATE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEConvolveMatrixElement.prototype.SVG_EDGEMODE_WRAP;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEConvolveMatrixElement.SVG_EDGEMODE_NONE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEConvolveMatrixElement.prototype.SVG_EDGEMODE_NONE;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEConvolveMatrixElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedInteger}
+ */
+SVGFEConvolveMatrixElement.prototype.orderX;
+
+
+/**
+ * @type {!SVGAnimatedInteger}
+ */
+SVGFEConvolveMatrixElement.prototype.orderY;
+
+
+/**
+ * @type {!SVGAnimatedNumberList}
+ */
+SVGFEConvolveMatrixElement.prototype.kernelMatrix;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEConvolveMatrixElement.prototype.divisor;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEConvolveMatrixElement.prototype.bias;
+
+
+/**
+ * @type {!SVGAnimatedInteger}
+ */
+SVGFEConvolveMatrixElement.prototype.targetX;
+
+
+/**
+ * @type {!SVGAnimatedInteger}
+ */
+SVGFEConvolveMatrixElement.prototype.targetY;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGFEConvolveMatrixElement.prototype.edgeMode;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEConvolveMatrixElement.prototype.kernelUnitLengthX;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEConvolveMatrixElement.prototype.kernelUnitLengthY;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGFEConvolveMatrixElement.prototype.preserveAlpha;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEConvolveMatrixElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEConvolveMatrixElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEConvolveMatrixElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEConvolveMatrixElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEConvolveMatrixElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEConvolveMatrixElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEConvolveMatrixElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEConvolveMatrixElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEFloodElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEFloodElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEFloodElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEFloodElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEFloodElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEFloodElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEFloodElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEFloodElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEFloodElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGStylable}
+ */
+function SVGStopElement(){}
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGStopElement.prototype.offset;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGStopElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGStopElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGStopElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGGlyphElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGHKernElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGVKernElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGFontElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEOffsetElement(){}
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEOffsetElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEOffsetElement.prototype.dx;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEOffsetElement.prototype.dy;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEOffsetElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEOffsetElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEOffsetElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEOffsetElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEOffsetElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEOffsetElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEOffsetElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEOffsetElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGURIReference}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ */
+function SVGFilterElement(){}
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGFilterElement.prototype.filterUnits;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGFilterElement.prototype.primitiveUnits;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFilterElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFilterElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFilterElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFilterElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedInteger}
+ */
+SVGFilterElement.prototype.filterResX;
+
+
+/**
+ * @type {!SVGAnimatedInteger}
+ */
+SVGFilterElement.prototype.filterResY;
+
+
+/**
+ * @param {number=} opt_filterResX
+ * @param {number=} opt_filterResY
+ */
+SVGFilterElement.prototype.setFilterRes = function(opt_filterResX, opt_filterResY){};
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGFilterElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFilterElement.prototype.href;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFilterElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFilterElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFilterElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+/**
+ * @type {string}
+ */
+SVGFilterElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGFilterElement.prototype.xmlspace;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEGaussianBlurElement(){}
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEGaussianBlurElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEGaussianBlurElement.prototype.stdDeviationX;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEGaussianBlurElement.prototype.stdDeviationY;
+
+
+/**
+ * @param {number=} opt_stdDeviationX
+ * @param {number=} opt_stdDeviationY
+ */
+SVGFEGaussianBlurElement.prototype.setStdDeviation = function(opt_stdDeviationX, opt_stdDeviationY){};
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEGaussianBlurElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEGaussianBlurElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEGaussianBlurElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEGaussianBlurElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEGaussianBlurElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEGaussianBlurElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEGaussianBlurElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEGaussianBlurElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGAltGlyphDefElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGComponentTransferFunctionElement(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGComponentTransferFunctionElement.SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGComponentTransferFunctionElement.prototype.SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGComponentTransferFunctionElement.SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGComponentTransferFunctionElement.prototype.SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGComponentTransferFunctionElement.SVG_FECOMPONENTTRANSFER_TYPE_TABLE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGComponentTransferFunctionElement.prototype.SVG_FECOMPONENTTRANSFER_TYPE_TABLE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGComponentTransferFunctionElement.SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGComponentTransferFunctionElement.prototype.SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGComponentTransferFunctionElement.SVG_FECOMPONENTTRANSFER_TYPE_LINEAR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGComponentTransferFunctionElement.prototype.SVG_FECOMPONENTTRANSFER_TYPE_LINEAR;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGComponentTransferFunctionElement.SVG_FECOMPONENTTRANSFER_TYPE_GAMMA;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGComponentTransferFunctionElement.prototype.SVG_FECOMPONENTTRANSFER_TYPE_GAMMA;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGComponentTransferFunctionElement.prototype.type;
+
+
+/**
+ * @type {!SVGAnimatedNumberList}
+ */
+SVGComponentTransferFunctionElement.prototype.tableValues;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGComponentTransferFunctionElement.prototype.slope;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGComponentTransferFunctionElement.prototype.intercept;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGComponentTransferFunctionElement.prototype.amplitude;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGComponentTransferFunctionElement.prototype.exponent;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGComponentTransferFunctionElement.prototype.offset;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGMetadataElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGLangSpace}
+ * @implements {SVGStylable}
+ */
+function SVGTitleElement(){}
+
+
+/**
+ * @type {string}
+ */
+SVGTitleElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGTitleElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGTitleElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGTitleElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGTitleElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGURIReference}
+ * @implements {SVGTests}
+ * @implements {SVGExternalResourcesRequired}
+ */
+function SVGCursorElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGCursorElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGCursorElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGCursorElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGCursorElement.prototype.href;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGCursorElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGCursorElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGCursorElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGCursorElement.prototype.hasExtension = function(opt_extension){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGURIReference}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ */
+function SVGGradientElement(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGGradientElement.SVG_SPREADMETHOD_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGGradientElement.prototype.SVG_SPREADMETHOD_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGGradientElement.SVG_SPREADMETHOD_PAD;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGGradientElement.prototype.SVG_SPREADMETHOD_PAD;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGGradientElement.SVG_SPREADMETHOD_REFLECT;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGGradientElement.prototype.SVG_SPREADMETHOD_REFLECT;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGGradientElement.SVG_SPREADMETHOD_REPEAT;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGGradientElement.prototype.SVG_SPREADMETHOD_REPEAT;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGGradientElement.prototype.gradientUnits;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGGradientElement.prototype.gradientTransform;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGGradientElement.prototype.spreadMethod;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGGradientElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGGradientElement.prototype.href;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGGradientElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGGradientElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGGradientElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGFitToViewBox}
+ */
+function SVGMarkerElement(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGMarkerElement.SVG_MARKERUNITS_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGMarkerElement.prototype.SVG_MARKERUNITS_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGMarkerElement.prototype.SVG_MARKERUNITS_USERSPACEONUSE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGMarkerElement.SVG_MARKERUNITS_STROKEWIDTH;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGMarkerElement.prototype.SVG_MARKERUNITS_STROKEWIDTH;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGMarkerElement.prototype.SVG_MARKER_ORIENT_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGMarkerElement.SVG_MARKER_ORIENT_AUTO;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGMarkerElement.prototype.SVG_MARKER_ORIENT_AUTO;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGMarkerElement.prototype.SVG_MARKER_ORIENT_ANGLE;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGMarkerElement.prototype.refX;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGMarkerElement.prototype.refY;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGMarkerElement.prototype.markerUnits;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGMarkerElement.prototype.markerWidth;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGMarkerElement.prototype.markerHeight;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGMarkerElement.prototype.orientType;
+
+
+/**
+ * @type {!SVGAnimatedAngle}
+ */
+SVGMarkerElement.prototype.orientAngle;
+
+
+/** */
+SVGMarkerElement.prototype.setOrientToAuto = function(){};
+
+
+/**
+ * @param {!SVGAngle=} opt_angle
+ */
+SVGMarkerElement.prototype.setOrientToAngle = function(opt_angle){};
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGMarkerElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedRect}
+ */
+SVGMarkerElement.prototype.viewBox;
+
+
+/**
+ * @type {!SVGAnimatedPreserveAspectRatio}
+ */
+SVGMarkerElement.prototype.preserveAspectRatio;
+
+
+/**
+ * @type {string}
+ */
+SVGMarkerElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGMarkerElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGMarkerElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGMarkerElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGMarkerElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ */
+function SVGMaskElement(){}
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGMaskElement.prototype.maskUnits;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGMaskElement.prototype.maskContentUnits;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGMaskElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGMaskElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGMaskElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGMaskElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGMaskElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGMaskElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGMaskElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGMaskElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGMaskElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGMaskElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGMaskElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGMaskElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+/**
+ * @type {string}
+ */
+SVGMaskElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGMaskElement.prototype.xmlspace;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGFitToViewBox}
+ * @implements {SVGZoomAndPan}
+ */
+function SVGViewElement(){}
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGViewElement.prototype.viewTarget;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGViewElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGViewElement.SVG_ZOOMANDPAN_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGViewElement.prototype.SVG_ZOOMANDPAN_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGViewElement.SVG_ZOOMANDPAN_DISABLE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGViewElement.prototype.SVG_ZOOMANDPAN_DISABLE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGViewElement.SVG_ZOOMANDPAN_MAGNIFY;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGViewElement.prototype.SVG_ZOOMANDPAN_MAGNIFY;
+
+
+/**
+ * @type {number}
+ */
+SVGViewElement.prototype.zoomAndPan;
+
+
+/**
+ * @type {!SVGAnimatedRect}
+ */
+SVGViewElement.prototype.viewBox;
+
+
+/**
+ * @type {!SVGAnimatedPreserveAspectRatio}
+ */
+SVGViewElement.prototype.preserveAspectRatio;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGURIReference}
+ * @implements {SVGExternalResourcesRequired}
+ */
+function SVGMPathElement(){}
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGMPathElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGMPathElement.prototype.href;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGFontFaceSrcElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGURIReference}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEImageElement(){}
+
+
+/**
+ * @type {!SVGAnimatedPreserveAspectRatio}
+ */
+SVGFEImageElement.prototype.preserveAspectRatio;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEImageElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEImageElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEImageElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEImageElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEImageElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGFEImageElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEImageElement.prototype.href;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEImageElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEImageElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEImageElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+/**
+ * @type {string}
+ */
+SVGFEImageElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGFEImageElement.prototype.xmlspace;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGFEDistantLightElement(){}
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEDistantLightElement.prototype.azimuth;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEDistantLightElement.prototype.elevation;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGFontFaceUriElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEDiffuseLightingElement(){}
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEDiffuseLightingElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEDiffuseLightingElement.prototype.surfaceScale;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEDiffuseLightingElement.prototype.diffuseConstant;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEDiffuseLightingElement.prototype.kernelUnitLengthX;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEDiffuseLightingElement.prototype.kernelUnitLengthY;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEDiffuseLightingElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEDiffuseLightingElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEDiffuseLightingElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEDiffuseLightingElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEDiffuseLightingElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEDiffuseLightingElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEDiffuseLightingElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEDiffuseLightingElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEMorphologyElement(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEMorphologyElement.SVG_MORPHOLOGY_OPERATOR_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEMorphologyElement.prototype.SVG_MORPHOLOGY_OPERATOR_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEMorphologyElement.SVG_MORPHOLOGY_OPERATOR_ERODE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEMorphologyElement.prototype.SVG_MORPHOLOGY_OPERATOR_ERODE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEMorphologyElement.SVG_MORPHOLOGY_OPERATOR_DILATE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEMorphologyElement.prototype.SVG_MORPHOLOGY_OPERATOR_DILATE;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEMorphologyElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGFEMorphologyElement.prototype.operator;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEMorphologyElement.prototype.radiusX;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEMorphologyElement.prototype.radiusY;
+
+
+/**
+ * @param {number=} opt_radiusX
+ * @param {number=} opt_radiusY
+ */
+SVGFEMorphologyElement.prototype.setRadius = function(opt_radiusX, opt_radiusY){};
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEMorphologyElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEMorphologyElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEMorphologyElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEMorphologyElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEMorphologyElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEMorphologyElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEMorphologyElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEMorphologyElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGURIReference}
+ * @implements {SVGStylable}
+ */
+function SVGGlyphRefElement(){}
+
+
+/**
+ * @type {string}
+ */
+SVGGlyphRefElement.prototype.glyphRef;
+
+
+/**
+ * @type {string}
+ */
+SVGGlyphRefElement.prototype.format;
+
+
+/**
+ * @type {number}
+ */
+SVGGlyphRefElement.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGGlyphRefElement.prototype.y;
+
+
+/**
+ * @type {number}
+ */
+SVGGlyphRefElement.prototype.dx;
+
+
+/**
+ * @type {number}
+ */
+SVGGlyphRefElement.prototype.dy;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGGlyphRefElement.prototype.href;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGGlyphRefElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGGlyphRefElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGGlyphRefElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ */
+function SVGTextContentElement(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextContentElement.LENGTHADJUST_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextContentElement.prototype.LENGTHADJUST_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextContentElement.LENGTHADJUST_SPACING;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextContentElement.prototype.LENGTHADJUST_SPACING;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextContentElement.LENGTHADJUST_SPACINGANDGLYPHS;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGTextContentElement.prototype.LENGTHADJUST_SPACINGANDGLYPHS;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGTextContentElement.prototype.textLength;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGTextContentElement.prototype.lengthAdjust;
+
+
+/**
+ * @return {number}
+ */
+SVGTextContentElement.prototype.getNumberOfChars = function(){};
+
+
+/**
+ * @return {number}
+ */
+SVGTextContentElement.prototype.getComputedTextLength = function(){};
+
+
+/**
+ * @param {number=} opt_offset
+ * @param {number=} opt_length
+ * @return {number}
+ */
+SVGTextContentElement.prototype.getSubStringLength = function(opt_offset, opt_length){};
+
+
+/**
+ * @param {number=} opt_offset
+ * @return {!SVGPoint}
+ */
+SVGTextContentElement.prototype.getStartPositionOfChar = function(opt_offset){};
+
+
+/**
+ * @param {number=} opt_offset
+ * @return {!SVGPoint}
+ */
+SVGTextContentElement.prototype.getEndPositionOfChar = function(opt_offset){};
+
+
+/**
+ * @param {number=} opt_offset
+ * @return {!SVGRect}
+ */
+SVGTextContentElement.prototype.getExtentOfChar = function(opt_offset){};
+
+
+/**
+ * @param {number=} opt_offset
+ * @return {number}
+ */
+SVGTextContentElement.prototype.getRotationOfChar = function(opt_offset){};
+
+
+/**
+ * @param {!SVGPoint=} opt_point
+ * @return {number}
+ */
+SVGTextContentElement.prototype.getCharNumAtPosition = function(opt_point){};
+
+
+/**
+ * @param {number=} opt_offset
+ * @param {number=} opt_length
+ */
+SVGTextContentElement.prototype.selectSubString = function(opt_offset, opt_length){};
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGTextContentElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGTextContentElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGTextContentElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGTextContentElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGTextContentElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGTextContentElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGTextContentElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGTextContentElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+/**
+ * @type {string}
+ */
+SVGTextContentElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGTextContentElement.prototype.xmlspace;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGFESpotLightElement(){}
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFESpotLightElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFESpotLightElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFESpotLightElement.prototype.z;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFESpotLightElement.prototype.pointsAtX;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFESpotLightElement.prototype.pointsAtY;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFESpotLightElement.prototype.pointsAtZ;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFESpotLightElement.prototype.specularExponent;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFESpotLightElement.prototype.limitingConeAngle;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGFontFaceNameElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGFEPointLightElement(){}
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEPointLightElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEPointLightElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEPointLightElement.prototype.z;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEDropShadowElement(){}
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEDropShadowElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEDropShadowElement.prototype.dx;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEDropShadowElement.prototype.dy;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEDropShadowElement.prototype.stdDeviationX;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEDropShadowElement.prototype.stdDeviationY;
+
+
+/**
+ * @param {number=} opt_stdDeviationX
+ * @param {number=} opt_stdDeviationY
+ */
+SVGFEDropShadowElement.prototype.setStdDeviation = function(opt_stdDeviationX, opt_stdDeviationY){};
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEDropShadowElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEDropShadowElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEDropShadowElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEDropShadowElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEDropShadowElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEDropShadowElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEDropShadowElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEDropShadowElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFETileElement(){}
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFETileElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFETileElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFETileElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFETileElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFETileElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFETileElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFETileElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFETileElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFETileElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGMissingGlyphElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEBlendElement(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEBlendElement.SVG_FEBLEND_MODE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEBlendElement.prototype.SVG_FEBLEND_MODE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEBlendElement.SVG_FEBLEND_MODE_NORMAL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEBlendElement.prototype.SVG_FEBLEND_MODE_NORMAL;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEBlendElement.SVG_FEBLEND_MODE_MULTIPLY;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEBlendElement.prototype.SVG_FEBLEND_MODE_MULTIPLY;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEBlendElement.SVG_FEBLEND_MODE_SCREEN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEBlendElement.prototype.SVG_FEBLEND_MODE_SCREEN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEBlendElement.SVG_FEBLEND_MODE_DARKEN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEBlendElement.prototype.SVG_FEBLEND_MODE_DARKEN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEBlendElement.prototype.SVG_FEBLEND_MODE_LIGHTEN;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEBlendElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEBlendElement.prototype.in2;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGFEBlendElement.prototype.mode;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEBlendElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEBlendElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEBlendElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEBlendElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEBlendElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEBlendElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEBlendElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEBlendElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGURIReference}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGFitToViewBox}
+ */
+function SVGPatternElement(){}
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGPatternElement.prototype.patternUnits;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGPatternElement.prototype.patternContentUnits;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGPatternElement.prototype.patternTransform;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGPatternElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGPatternElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGPatternElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGPatternElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGPatternElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedRect}
+ */
+SVGPatternElement.prototype.viewBox;
+
+
+/**
+ * @type {!SVGAnimatedPreserveAspectRatio}
+ */
+SVGPatternElement.prototype.preserveAspectRatio;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGPatternElement.prototype.href;
+
+
+/**
+ * @type {string}
+ */
+SVGPatternElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGPatternElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGPatternElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGPatternElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGPatternElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGPatternElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGPatternElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGPatternElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGPatternElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGFEMergeNodeElement(){}
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEMergeNodeElement.prototype.in1;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGComponentTransferFunctionElement}
+ */
+function SVGFEFuncBElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegMovetoRel(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegMovetoRel.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegMovetoRel.prototype.y;
+
+
+
+/**
+ * @interface
+ */
+function SVGLocatable(){}
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGLocatable.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGLocatable.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGLocatable.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGLocatable.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGLocatable.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGLocatable.prototype.getTransformToElement = function(opt_element){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGLocatable}
+ * @implements {SVGFitToViewBox}
+ * @implements {SVGZoomAndPan}
+ */
+function SVGSVGElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGSVGElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGSVGElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGSVGElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGSVGElement.prototype.height;
+
+
+/**
+ * @type {string}
+ */
+SVGSVGElement.prototype.contentScriptType;
+
+
+/**
+ * @type {string}
+ */
+SVGSVGElement.prototype.contentStyleType;
+
+
+/**
+ * @type {!SVGRect}
+ */
+SVGSVGElement.prototype.viewport;
+
+
+/**
+ * @type {number}
+ */
+SVGSVGElement.prototype.pixelUnitToMillimeterX;
+
+
+/**
+ * @type {number}
+ */
+SVGSVGElement.prototype.pixelUnitToMillimeterY;
+
+
+/**
+ * @type {number}
+ */
+SVGSVGElement.prototype.screenPixelToMillimeterX;
+
+
+/**
+ * @type {number}
+ */
+SVGSVGElement.prototype.screenPixelToMillimeterY;
+
+
+/**
+ * @type {boolean}
+ */
+SVGSVGElement.prototype.useCurrentView;
+
+
+/**
+ * @type {number}
+ */
+SVGSVGElement.prototype.currentScale;
+
+
+/**
+ * @type {!SVGPoint}
+ */
+SVGSVGElement.prototype.currentTranslate;
+
+
+/**
+ * @param {number=} opt_maxWaitMilliseconds
+ * @return {number}
+ */
+SVGSVGElement.prototype.suspendRedraw = function(opt_maxWaitMilliseconds){};
+
+
+/**
+ * @param {number=} opt_suspendHandleId
+ */
+SVGSVGElement.prototype.unsuspendRedraw = function(opt_suspendHandleId){};
+
+
+/** */
+SVGSVGElement.prototype.unsuspendRedrawAll = function(){};
+
+
+/** */
+SVGSVGElement.prototype.forceRedraw = function(){};
+
+
+/** */
+SVGSVGElement.prototype.pauseAnimations = function(){};
+
+
+/** */
+SVGSVGElement.prototype.unpauseAnimations = function(){};
+
+
+/**
+ * @return {boolean}
+ */
+SVGSVGElement.prototype.animationsPaused = function(){};
+
+
+/**
+ * @return {number}
+ */
+SVGSVGElement.prototype.getCurrentTime = function(){};
+
+
+/**
+ * @param {number=} opt_seconds
+ */
+SVGSVGElement.prototype.setCurrentTime = function(opt_seconds){};
+
+
+/**
+ * @param {!SVGRect=} opt_rect
+ * @param {!SVGElement=} opt_referenceElement
+ * @return {!Array.<!Node>|!NodeList}
+ */
+SVGSVGElement.prototype.getIntersectionList = function(opt_rect, opt_referenceElement){};
+
+
+/**
+ * @param {!SVGRect=} opt_rect
+ * @param {!SVGElement=} opt_referenceElement
+ * @return {!Array.<!Node>|!NodeList}
+ */
+SVGSVGElement.prototype.getEnclosureList = function(opt_rect, opt_referenceElement){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @param {!SVGRect=} opt_rect
+ * @return {boolean}
+ */
+SVGSVGElement.prototype.checkIntersection = function(opt_element, opt_rect){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @param {!SVGRect=} opt_rect
+ * @return {boolean}
+ */
+SVGSVGElement.prototype.checkEnclosure = function(opt_element, opt_rect){};
+
+
+/** */
+SVGSVGElement.prototype.deselectAll = function(){};
+
+
+/**
+ * @return {!SVGNumber}
+ */
+SVGSVGElement.prototype.createSVGNumber = function(){};
+
+
+/**
+ * @return {!SVGLength}
+ */
+SVGSVGElement.prototype.createSVGLength = function(){};
+
+
+/**
+ * @return {!SVGAngle}
+ */
+SVGSVGElement.prototype.createSVGAngle = function(){};
+
+
+/**
+ * @return {!SVGPoint}
+ */
+SVGSVGElement.prototype.createSVGPoint = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGSVGElement.prototype.createSVGMatrix = function(){};
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGSVGElement.prototype.createSVGRect = function(){};
+
+
+/**
+ * @return {!SVGTransform}
+ */
+SVGSVGElement.prototype.createSVGTransform = function(){};
+
+
+/**
+ * @param {!SVGMatrix=} opt_matrix
+ * @return {!SVGTransform}
+ */
+SVGSVGElement.prototype.createSVGTransformFromMatrix = function(opt_matrix){};
+
+
+/**
+ * @param {string=} opt_elementId
+ * @return {!Element}
+ */
+SVGSVGElement.prototype.getElementById = function(opt_elementId){};
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGSVGElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedRect}
+ */
+SVGSVGElement.prototype.viewBox;
+
+
+/**
+ * @type {!SVGAnimatedPreserveAspectRatio}
+ */
+SVGSVGElement.prototype.preserveAspectRatio;
+
+
+/**
+ * @type {string}
+ */
+SVGSVGElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGSVGElement.prototype.xmlspace;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGSVGElement.SVG_ZOOMANDPAN_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGSVGElement.prototype.SVG_ZOOMANDPAN_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGSVGElement.SVG_ZOOMANDPAN_DISABLE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGSVGElement.prototype.SVG_ZOOMANDPAN_DISABLE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGSVGElement.SVG_ZOOMANDPAN_MAGNIFY;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGSVGElement.prototype.SVG_ZOOMANDPAN_MAGNIFY;
+
+
+/**
+ * @type {number}
+ */
+SVGSVGElement.prototype.zoomAndPan;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGSVGElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGSVGElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGSVGElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGSVGElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGSVGElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGSVGElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGSVGElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGSVGElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGSVGElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGSVGElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGSVGElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGSVGElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGSVGElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @interface
+ * @extends {SVGLocatable}
+ */
+function SVGTransformable(){}
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGTransformable.prototype.transform;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGDefsElement(){}
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGDefsElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGDefsElement.prototype.transform;
+
+
+/**
+ * @type {string}
+ */
+SVGDefsElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGDefsElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGDefsElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGDefsElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGDefsElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGDefsElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGDefsElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGDefsElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGDefsElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGDefsElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGDefsElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGDefsElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGDefsElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGDefsElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGDefsElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGPolygonElement(){}
+
+
+/**
+ * @type {!SVGPointList}
+ */
+SVGPolygonElement.prototype.points;
+
+
+/**
+ * @type {!SVGPointList}
+ */
+SVGPolygonElement.prototype.animatedPoints;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGPolygonElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGPolygonElement.prototype.transform;
+
+
+/**
+ * @type {string}
+ */
+SVGPolygonElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGPolygonElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGPolygonElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGPolygonElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGPolygonElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGPolygonElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGPolygonElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGPolygonElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGPolygonElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGPolygonElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGPolygonElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGPolygonElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGPolygonElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGPolygonElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGPolygonElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGPathElement(){}
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGPathElement.prototype.pathLength;
+
+
+/**
+ * @type {!SVGPathSegList}
+ */
+SVGPathElement.prototype.pathSegList;
+
+
+/**
+ * @type {!SVGPathSegList}
+ */
+SVGPathElement.prototype.normalizedPathSegList;
+
+
+/**
+ * @type {!SVGPathSegList}
+ */
+SVGPathElement.prototype.animatedPathSegList;
+
+
+/**
+ * @type {!SVGPathSegList}
+ */
+SVGPathElement.prototype.animatedNormalizedPathSegList;
+
+
+/**
+ * @return {number}
+ */
+SVGPathElement.prototype.getTotalLength = function(){};
+
+
+/**
+ * @param {number=} opt_distance
+ * @return {!SVGPoint}
+ */
+SVGPathElement.prototype.getPointAtLength = function(opt_distance){};
+
+
+/**
+ * @param {number=} opt_distance
+ * @return {number}
+ */
+SVGPathElement.prototype.getPathSegAtLength = function(opt_distance){};
+
+
+/**
+ * @return {!SVGPathSegClosePath}
+ */
+SVGPathElement.prototype.createSVGPathSegClosePath = function(){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @return {!SVGPathSegMovetoAbs}
+ */
+SVGPathElement.prototype.createSVGPathSegMovetoAbs = function(opt_x, opt_y){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @return {!SVGPathSegMovetoRel}
+ */
+SVGPathElement.prototype.createSVGPathSegMovetoRel = function(opt_x, opt_y){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @return {!SVGPathSegLinetoAbs}
+ */
+SVGPathElement.prototype.createSVGPathSegLinetoAbs = function(opt_x, opt_y){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @return {!SVGPathSegLinetoRel}
+ */
+SVGPathElement.prototype.createSVGPathSegLinetoRel = function(opt_x, opt_y){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @param {number=} opt_x1
+ * @param {number=} opt_y1
+ * @param {number=} opt_x2
+ * @param {number=} opt_y2
+ * @return {!SVGPathSegCurvetoCubicAbs}
+ */
+SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function(opt_x, opt_y, opt_x1, opt_y1, opt_x2, opt_y2){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @param {number=} opt_x1
+ * @param {number=} opt_y1
+ * @param {number=} opt_x2
+ * @param {number=} opt_y2
+ * @return {!SVGPathSegCurvetoCubicRel}
+ */
+SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function(opt_x, opt_y, opt_x1, opt_y1, opt_x2, opt_y2){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @param {number=} opt_x1
+ * @param {number=} opt_y1
+ * @return {!SVGPathSegCurvetoQuadraticAbs}
+ */
+SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function(opt_x, opt_y, opt_x1, opt_y1){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @param {number=} opt_x1
+ * @param {number=} opt_y1
+ * @return {!SVGPathSegCurvetoQuadraticRel}
+ */
+SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function(opt_x, opt_y, opt_x1, opt_y1){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @param {number=} opt_r1
+ * @param {number=} opt_r2
+ * @param {number=} opt_angle
+ * @param {boolean=} opt_largeArcFlag
+ * @param {boolean=} opt_sweepFlag
+ * @return {!SVGPathSegArcAbs}
+ */
+SVGPathElement.prototype.createSVGPathSegArcAbs = function(opt_x, opt_y, opt_r1, opt_r2, opt_angle, opt_largeArcFlag, opt_sweepFlag){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @param {number=} opt_r1
+ * @param {number=} opt_r2
+ * @param {number=} opt_angle
+ * @param {boolean=} opt_largeArcFlag
+ * @param {boolean=} opt_sweepFlag
+ * @return {!SVGPathSegArcRel}
+ */
+SVGPathElement.prototype.createSVGPathSegArcRel = function(opt_x, opt_y, opt_r1, opt_r2, opt_angle, opt_largeArcFlag, opt_sweepFlag){};
+
+
+/**
+ * @param {number=} opt_x
+ * @return {!SVGPathSegLinetoHorizontalAbs}
+ */
+SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function(opt_x){};
+
+
+/**
+ * @param {number=} opt_x
+ * @return {!SVGPathSegLinetoHorizontalRel}
+ */
+SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function(opt_x){};
+
+
+/**
+ * @param {number=} opt_y
+ * @return {!SVGPathSegLinetoVerticalAbs}
+ */
+SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function(opt_y){};
+
+
+/**
+ * @param {number=} opt_y
+ * @return {!SVGPathSegLinetoVerticalRel}
+ */
+SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function(opt_y){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @param {number=} opt_x2
+ * @param {number=} opt_y2
+ * @return {!SVGPathSegCurvetoCubicSmoothAbs}
+ */
+SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function(opt_x, opt_y, opt_x2, opt_y2){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @param {number=} opt_x2
+ * @param {number=} opt_y2
+ * @return {!SVGPathSegCurvetoCubicSmoothRel}
+ */
+SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function(opt_x, opt_y, opt_x2, opt_y2){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @return {!SVGPathSegCurvetoQuadraticSmoothAbs}
+ */
+SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function(opt_x, opt_y){};
+
+
+/**
+ * @param {number=} opt_x
+ * @param {number=} opt_y
+ * @return {!SVGPathSegCurvetoQuadraticSmoothRel}
+ */
+SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function(opt_x, opt_y){};
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGPathElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGPathElement.prototype.transform;
+
+
+/**
+ * @type {string}
+ */
+SVGPathElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGPathElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGPathElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGPathElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGPathElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGPathElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGPathElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGPathElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGPathElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGPathElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGPathElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGPathElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGPathElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGPathElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGPathElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGCircleElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGCircleElement.prototype.cx;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGCircleElement.prototype.cy;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGCircleElement.prototype.r;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGCircleElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGCircleElement.prototype.transform;
+
+
+/**
+ * @type {string}
+ */
+SVGCircleElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGCircleElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGCircleElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGCircleElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGCircleElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGCircleElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGCircleElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGCircleElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGCircleElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGCircleElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGCircleElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGCircleElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGCircleElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGCircleElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGCircleElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGURIReference}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGUseElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGUseElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGUseElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGUseElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGUseElement.prototype.height;
+
+
+/**
+ * @type {!SVGElementInstance}
+ */
+SVGUseElement.prototype.instanceRoot;
+
+
+/**
+ * @type {!SVGElementInstance}
+ */
+SVGUseElement.prototype.animatedInstanceRoot;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGUseElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGUseElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGUseElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGUseElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGUseElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGUseElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGUseElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGUseElement.prototype.transform;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGUseElement.prototype.href;
+
+
+/**
+ * @type {string}
+ */
+SVGUseElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGUseElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGUseElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGUseElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGUseElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGUseElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGUseElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGUseElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGUseElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGPolylineElement(){}
+
+
+/**
+ * @type {!SVGPointList}
+ */
+SVGPolylineElement.prototype.points;
+
+
+/**
+ * @type {!SVGPointList}
+ */
+SVGPolylineElement.prototype.animatedPoints;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGPolylineElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGPolylineElement.prototype.transform;
+
+
+/**
+ * @type {string}
+ */
+SVGPolylineElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGPolylineElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGPolylineElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGPolylineElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGPolylineElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGPolylineElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGPolylineElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGPolylineElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGPolylineElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGPolylineElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGPolylineElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGPolylineElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGPolylineElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGPolylineElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGPolylineElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGGElement(){}
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGGElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGGElement.prototype.transform;
+
+
+/**
+ * @type {string}
+ */
+SVGGElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGGElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGGElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGGElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGGElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGGElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGGElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGGElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGGElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGGElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGGElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGGElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGGElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGGElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGGElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGSwitchElement(){}
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGSwitchElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGSwitchElement.prototype.transform;
+
+
+/**
+ * @type {string}
+ */
+SVGSwitchElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGSwitchElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGSwitchElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGSwitchElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGSwitchElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGSwitchElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGSwitchElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGSwitchElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGSwitchElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGSwitchElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGSwitchElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGSwitchElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGSwitchElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGSwitchElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGSwitchElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGURIReference}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGImageElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGImageElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGImageElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGImageElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGImageElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedPreserveAspectRatio}
+ */
+SVGImageElement.prototype.preserveAspectRatio;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGImageElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGImageElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGImageElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGImageElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGImageElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGImageElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGImageElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGImageElement.prototype.transform;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGImageElement.prototype.href;
+
+
+/**
+ * @type {string}
+ */
+SVGImageElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGImageElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGImageElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGImageElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGImageElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGImageElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGImageElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGImageElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGImageElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGRectElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGRectElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGRectElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGRectElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGRectElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGRectElement.prototype.rx;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGRectElement.prototype.ry;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGRectElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGRectElement.prototype.transform;
+
+
+/**
+ * @type {string}
+ */
+SVGRectElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGRectElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGRectElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGRectElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGRectElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGRectElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGRectElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGRectElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGRectElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGRectElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGRectElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGRectElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGRectElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGRectElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGRectElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGURIReference}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGAElement(){}
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGAElement.prototype.target;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGAElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGAElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGAElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGAElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGAElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGAElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGAElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGAElement.prototype.transform;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGAElement.prototype.href;
+
+
+/**
+ * @type {string}
+ */
+SVGAElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGAElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGAElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGAElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGAElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGAElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGAElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGAElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGAElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ */
+function SVGAnimatedPreserveAspectRatio(){}
+
+
+/**
+ * @type {!SVGPreserveAspectRatio}
+ */
+SVGAnimatedPreserveAspectRatio.prototype.baseVal;
+
+
+/**
+ * @type {!SVGPreserveAspectRatio}
+ */
+SVGAnimatedPreserveAspectRatio.prototype.animVal;
+
+
+
+/**
+ * @constructor
+ */
+function SVGElementInstanceList(){}
+
+
+/**
+ * @type {number}
+ */
+SVGElementInstanceList.prototype.length;
+
+
+/**
+ * @param {number=} opt_index
+ * @return {!SVGElementInstance}
+ */
+SVGElementInstanceList.prototype.item = function(opt_index){};
+
+
+
+/**
+ * @constructor
+ * @extends {Element}
+ */
+function SVGElement(){}
+
+
+/**
+ * @type {string}
+ */
+SVGElement.prototype.id;
+
+
+/**
+ * @type {string}
+ */
+SVGElement.prototype.xmlbase;
+
+
+/**
+ * @type {!SVGSVGElement}
+ */
+SVGElement.prototype.ownerSVGElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGElement.prototype.viewportElement;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFETurbulenceElement(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFETurbulenceElement.SVG_TURBULENCE_TYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFETurbulenceElement.prototype.SVG_TURBULENCE_TYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFETurbulenceElement.SVG_TURBULENCE_TYPE_FRACTALNOISE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFETurbulenceElement.prototype.SVG_TURBULENCE_TYPE_FRACTALNOISE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFETurbulenceElement.SVG_TURBULENCE_TYPE_TURBULENCE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFETurbulenceElement.prototype.SVG_TURBULENCE_TYPE_TURBULENCE;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFETurbulenceElement.SVG_STITCHTYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFETurbulenceElement.prototype.SVG_STITCHTYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFETurbulenceElement.SVG_STITCHTYPE_STITCH;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFETurbulenceElement.prototype.SVG_STITCHTYPE_STITCH;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFETurbulenceElement.SVG_STITCHTYPE_NOSTITCH;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFETurbulenceElement.prototype.SVG_STITCHTYPE_NOSTITCH;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFETurbulenceElement.prototype.baseFrequencyX;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFETurbulenceElement.prototype.baseFrequencyY;
+
+
+/**
+ * @type {!SVGAnimatedInteger}
+ */
+SVGFETurbulenceElement.prototype.numOctaves;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFETurbulenceElement.prototype.seed;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGFETurbulenceElement.prototype.stitchTiles;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGFETurbulenceElement.prototype.type;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFETurbulenceElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFETurbulenceElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFETurbulenceElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFETurbulenceElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFETurbulenceElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFETurbulenceElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFETurbulenceElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFETurbulenceElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGPathSeg}
+ */
+function SVGPathSegArcAbs(){}
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegArcAbs.prototype.x;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegArcAbs.prototype.y;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegArcAbs.prototype.r1;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegArcAbs.prototype.r2;
+
+
+/**
+ * @type {number}
+ */
+SVGPathSegArcAbs.prototype.angle;
+
+
+/**
+ * @type {boolean}
+ */
+SVGPathSegArcAbs.prototype.largeArcFlag;
+
+
+/**
+ * @type {boolean}
+ */
+SVGPathSegArcAbs.prototype.sweepFlag;
+
+
+
+/**
+ * @constructor
+ */
+function SVGAnimatedBoolean(){}
+
+
+/**
+ * @type {boolean}
+ */
+SVGAnimatedBoolean.prototype.baseVal;
+
+
+/**
+ * @type {boolean}
+ */
+SVGAnimatedBoolean.prototype.animVal;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGLangSpace}
+ */
+function SVGStyleElement(){}
+
+
+/**
+ * @type {boolean}
+ */
+SVGStyleElement.prototype.disabled;
+
+
+/**
+ * @type {string}
+ */
+SVGStyleElement.prototype.type;
+
+
+/**
+ * @type {string}
+ */
+SVGStyleElement.prototype.media;
+
+
+/**
+ * @type {string}
+ */
+SVGStyleElement.prototype.title;
+
+
+/**
+ * @type {string}
+ */
+SVGStyleElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGStyleElement.prototype.xmlspace;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGClipPathElement(){}
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGClipPathElement.prototype.clipPathUnits;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGClipPathElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGClipPathElement.prototype.transform;
+
+
+/**
+ * @type {string}
+ */
+SVGClipPathElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGClipPathElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGClipPathElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGClipPathElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGClipPathElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGClipPathElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGClipPathElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGClipPathElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGClipPathElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGClipPathElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGClipPathElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGClipPathElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGClipPathElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGClipPathElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGClipPathElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @interface
+ */
+function ElementTimeControl(){}
+
+
+/** */
+ElementTimeControl.prototype.beginElement = function(){};
+
+
+/**
+ * @param {number=} opt_offset
+ */
+ElementTimeControl.prototype.beginElementAt = function(opt_offset){};
+
+
+/** */
+ElementTimeControl.prototype.endElement = function(){};
+
+
+/**
+ * @param {number=} opt_offset
+ */
+ElementTimeControl.prototype.endElementAt = function(opt_offset){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {ElementTimeControl}
+ */
+function SVGAnimationElement(){}
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGAnimationElement.prototype.targetElement;
+
+
+/**
+ * @return {number}
+ */
+SVGAnimationElement.prototype.getStartTime = function(){};
+
+
+/**
+ * @return {number}
+ */
+SVGAnimationElement.prototype.getCurrentTime = function(){};
+
+
+/**
+ * @return {number}
+ */
+SVGAnimationElement.prototype.getSimpleDuration = function(){};
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGAnimationElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGAnimationElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGAnimationElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGAnimationElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGAnimationElement.prototype.hasExtension = function(opt_extension){};
+
+
+/** */
+SVGAnimationElement.prototype.beginElement = function(){};
+
+
+/**
+ * @param {number=} opt_offset
+ */
+SVGAnimationElement.prototype.beginElementAt = function(opt_offset){};
+
+
+/** */
+SVGAnimationElement.prototype.endElement = function(){};
+
+
+/**
+ * @param {number=} opt_offset
+ */
+SVGAnimationElement.prototype.endElementAt = function(opt_offset){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGAnimationElement}
+ */
+function SVGAnimateMotionElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGAnimationElement}
+ */
+function SVGAnimateElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGAnimationElement}
+ */
+function SVGAnimateColorElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGAnimationElement}
+ */
+function SVGAnimateTransformElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGAnimationElement}
+ */
+function SVGSetElement(){}
+
+
+
+/**
+ * @constructor
+ */
+function SVGAngle(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGAngle.SVG_ANGLETYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGAngle.prototype.SVG_ANGLETYPE_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGAngle.SVG_ANGLETYPE_UNSPECIFIED;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGAngle.prototype.SVG_ANGLETYPE_UNSPECIFIED;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGAngle.SVG_ANGLETYPE_DEG;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGAngle.prototype.SVG_ANGLETYPE_DEG;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGAngle.SVG_ANGLETYPE_RAD;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGAngle.prototype.SVG_ANGLETYPE_RAD;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGAngle.SVG_ANGLETYPE_GRAD;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGAngle.prototype.SVG_ANGLETYPE_GRAD;
+
+
+/**
+ * @type {number}
+ */
+SVGAngle.prototype.unitType;
+
+
+/**
+ * @type {number}
+ */
+SVGAngle.prototype.value;
+
+
+/**
+ * @type {number}
+ */
+SVGAngle.prototype.valueInSpecifiedUnits;
+
+
+/**
+ * @type {string}
+ */
+SVGAngle.prototype.valueAsString;
+
+
+/**
+ * @param {number} unitType
+ * @param {number} valueInSpecifiedUnits
+ */
+SVGAngle.prototype.newValueSpecifiedUnits = function(unitType, valueInSpecifiedUnits){};
+
+
+/**
+ * @param {number} unitType
+ */
+SVGAngle.prototype.convertToSpecifiedUnits = function(unitType){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGTextPositioningElement}
+ * @implements {SVGTransformable}
+ */
+function SVGTextElement(){}
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGTextElement.prototype.transform;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGTextElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGTextElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGTextElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGTextElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGTextElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGTextElement.prototype.getTransformToElement = function(opt_element){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ */
+function SVGFontFaceElement(){}
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGLineElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGLineElement.prototype.x1;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGLineElement.prototype.y1;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGLineElement.prototype.x2;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGLineElement.prototype.y2;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGLineElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGLineElement.prototype.transform;
+
+
+/**
+ * @type {string}
+ */
+SVGLineElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGLineElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGLineElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGLineElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGLineElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGLineElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGLineElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGLineElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGLineElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGLineElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGLineElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGLineElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGLineElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGLineElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGLineElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEComponentTransferElement(){}
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEComponentTransferElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEComponentTransferElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEComponentTransferElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEComponentTransferElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEComponentTransferElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEComponentTransferElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEComponentTransferElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEComponentTransferElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEComponentTransferElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEDisplacementMapElement(){}
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEDisplacementMapElement.SVG_CHANNEL_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEDisplacementMapElement.prototype.SVG_CHANNEL_UNKNOWN;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEDisplacementMapElement.SVG_CHANNEL_R;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEDisplacementMapElement.prototype.SVG_CHANNEL_R;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEDisplacementMapElement.SVG_CHANNEL_G;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEDisplacementMapElement.prototype.SVG_CHANNEL_G;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEDisplacementMapElement.SVG_CHANNEL_B;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEDisplacementMapElement.prototype.SVG_CHANNEL_B;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEDisplacementMapElement.SVG_CHANNEL_A;
+
+
+/**
+ * @const
+ * @type {number}
+ */
+SVGFEDisplacementMapElement.prototype.SVG_CHANNEL_A;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEDisplacementMapElement.prototype.in1;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEDisplacementMapElement.prototype.in2;
+
+
+/**
+ * @type {!SVGAnimatedNumber}
+ */
+SVGFEDisplacementMapElement.prototype.scale;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGFEDisplacementMapElement.prototype.xChannelSelector;
+
+
+/**
+ * @type {!SVGAnimatedEnumeration}
+ */
+SVGFEDisplacementMapElement.prototype.yChannelSelector;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEDisplacementMapElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEDisplacementMapElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEDisplacementMapElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEDisplacementMapElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEDisplacementMapElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEDisplacementMapElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEDisplacementMapElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEDisplacementMapElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ */
+function SVGAnimatedEnumeration(){}
+
+
+/**
+ * @type {number}
+ */
+SVGAnimatedEnumeration.prototype.baseVal;
+
+
+/**
+ * @type {number}
+ */
+SVGAnimatedEnumeration.prototype.animVal;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGFilterPrimitiveStandardAttributes}
+ */
+function SVGFEMergeElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEMergeElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEMergeElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEMergeElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGFEMergeElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEMergeElement.prototype.result;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGFEMergeElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGFEMergeElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGFEMergeElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGTests}
+ * @implements {SVGLangSpace}
+ * @implements {SVGExternalResourcesRequired}
+ * @implements {SVGStylable}
+ * @implements {SVGTransformable}
+ */
+function SVGForeignObjectElement(){}
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGForeignObjectElement.prototype.x;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGForeignObjectElement.prototype.y;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGForeignObjectElement.prototype.width;
+
+
+/**
+ * @type {!SVGAnimatedLength}
+ */
+SVGForeignObjectElement.prototype.height;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGForeignObjectElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedTransformList}
+ */
+SVGForeignObjectElement.prototype.transform;
+
+
+/**
+ * @type {string}
+ */
+SVGForeignObjectElement.prototype.xmllang;
+
+
+/**
+ * @type {string}
+ */
+SVGForeignObjectElement.prototype.xmlspace;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGForeignObjectElement.prototype.nearestViewportElement;
+
+
+/**
+ * @type {!SVGElement}
+ */
+SVGForeignObjectElement.prototype.farthestViewportElement;
+
+
+/**
+ * @return {!SVGRect}
+ */
+SVGForeignObjectElement.prototype.getBBox = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGForeignObjectElement.prototype.getCTM = function(){};
+
+
+/**
+ * @return {!SVGMatrix}
+ */
+SVGForeignObjectElement.prototype.getScreenCTM = function(){};
+
+
+/**
+ * @param {!SVGElement=} opt_element
+ * @return {!SVGMatrix}
+ */
+SVGForeignObjectElement.prototype.getTransformToElement = function(opt_element){};
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGForeignObjectElement.prototype.requiredFeatures;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGForeignObjectElement.prototype.requiredExtensions;
+
+
+/**
+ * @type {!SVGStringList}
+ */
+SVGForeignObjectElement.prototype.systemLanguage;
+
+
+/**
+ * @param {string=} opt_extension
+ * @return {boolean}
+ */
+SVGForeignObjectElement.prototype.hasExtension = function(opt_extension){};
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGForeignObjectElement.prototype.className;
+
+
+/**
+ * @type {!Array.<string>|!CSSStyleDeclaration}
+ */
+SVGForeignObjectElement.prototype.style;
+
+
+/**
+ * @param {string=} opt_name
+ * @return {!CSSValue}
+ */
+SVGForeignObjectElement.prototype.getPresentationAttribute = function(opt_name){};
+
+
+
+/**
+ * @constructor
+ */
+function SVGAnimatedLength(){}
+
+
+/**
+ * @type {!SVGLength}
+ */
+SVGAnimatedLength.prototype.baseVal;
+
+
+/**
+ * @type {!SVGLength}
+ */
+SVGAnimatedLength.prototype.animVal;
+
+
+
+/**
+ * @constructor
+ * @extends {SVGElement}
+ * @implements {SVGURIReference}
+ * @implements {SVGExternalResourcesRequired}
+ */
+function SVGScriptElement(){}
+
+
+/**
+ * @type {string}
+ */
+SVGScriptElement.prototype.type;
+
+
+/**
+ * @type {!SVGAnimatedBoolean}
+ */
+SVGScriptElement.prototype.externalResourcesRequired;
+
+
+/**
+ * @type {!SVGAnimatedString}
+ */
+SVGScriptElement.prototype.href;
+
+
+
+/**
+ * @constructor
+ */
+function SVGAnimatedInteger(){}
+
+
+/**
+ * @type {number}
+ */
+SVGAnimatedInteger.prototype.baseVal;
+
+
+/**
+ * @type {number}
+ */
+SVGAnimatedInteger.prototype.animVal;