├── Blockly ├── bz2.pyd ├── _ssl.pyd ├── select.pyd ├── CRYPT32.dll ├── _hashlib.pyd ├── _socket.pyd ├── library.zip ├── python27.dll ├── w9xpopen.exe ├── unicodedata.pyd ├── brobot │ ├── icons.png │ ├── Brobot2.jpg │ ├── media │ │ ├── 1x1.gif │ │ ├── click.mp3 │ │ ├── click.ogg │ │ ├── click.wav │ │ ├── delete.mp3 │ │ ├── delete.ogg │ │ ├── delete.wav │ │ ├── handopen.cur │ │ ├── quote0.png │ │ ├── quote1.png │ │ ├── sprites.png │ │ ├── disconnect.mp3 │ │ ├── disconnect.ogg │ │ ├── disconnect.wav │ │ ├── handclosed.cur │ │ ├── handdelete.cur │ │ └── sprites.svg │ ├── spinleft.png │ ├── spinright.png │ ├── turnleft.png │ ├── turnright.png │ ├── Brobot2_old.jpg │ ├── moveforward.png │ ├── turnleft180.png │ ├── blocks │ │ └── brobot.js │ ├── logojjrobots.png │ ├── movebackward.png │ ├── turnright180.png │ ├── jquery │ │ ├── images │ │ │ ├── ui-icons_444444_256x240.png │ │ │ ├── ui-icons_555555_256x240.png │ │ │ ├── ui-icons_777620_256x240.png │ │ │ ├── ui-icons_777777_256x240.png │ │ │ ├── ui-icons_cc0000_256x240.png │ │ │ └── ui-icons_ffffff_256x240.png │ │ ├── jquery-ui.theme.min.css │ │ └── jquery-ui.structure.min.css │ ├── brobot_config.js │ ├── README.md │ ├── demos │ │ ├── prettify.css │ │ └── prettify.js │ ├── msg │ │ ├── en.js │ │ └── json │ │ │ └── en-gb.json │ ├── generators │ │ ├── python │ │ │ ├── variables.js │ │ │ ├── brobot.js │ │ │ ├── colour.js │ │ │ ├── logic.js │ │ │ ├── procedures.js │ │ │ ├── loops.js │ │ │ ├── text.js │ │ │ └── lists.js │ │ ├── javascript │ │ │ └── brobot.js │ │ └── python.js │ ├── style.css │ ├── index.html │ ├── LICENSE │ └── code.js ├── BROBOT_Blockly.exe └── python │ ├── BROBOT_Class.pyc │ ├── server │ ├── BROBOT_Class.pyc │ ├── BROBOT_Class.py │ └── webserver.py │ ├── Example1.py │ ├── Example2.py │ ├── Example4.py │ ├── BROBOT_Class.py │ └── Example3.py ├── .gitattributes ├── README.md ├── .gitignore └── Arduino └── BROBOT_EVO2 ├── Servos.ino ├── Network.ino ├── Control.ino └── OSC.ino /Blockly/bz2.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/bz2.pyd -------------------------------------------------------------------------------- /Blockly/_ssl.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/_ssl.pyd -------------------------------------------------------------------------------- /Blockly/select.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/select.pyd -------------------------------------------------------------------------------- /Blockly/CRYPT32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/CRYPT32.dll -------------------------------------------------------------------------------- /Blockly/_hashlib.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/_hashlib.pyd -------------------------------------------------------------------------------- /Blockly/_socket.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/_socket.pyd -------------------------------------------------------------------------------- /Blockly/library.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/library.zip -------------------------------------------------------------------------------- /Blockly/python27.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/python27.dll -------------------------------------------------------------------------------- /Blockly/w9xpopen.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/w9xpopen.exe -------------------------------------------------------------------------------- /Blockly/unicodedata.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/unicodedata.pyd -------------------------------------------------------------------------------- /Blockly/brobot/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/icons.png -------------------------------------------------------------------------------- /Blockly/BROBOT_Blockly.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/BROBOT_Blockly.exe -------------------------------------------------------------------------------- /Blockly/brobot/Brobot2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/Brobot2.jpg -------------------------------------------------------------------------------- /Blockly/brobot/media/1x1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/1x1.gif -------------------------------------------------------------------------------- /Blockly/brobot/spinleft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/spinleft.png -------------------------------------------------------------------------------- /Blockly/brobot/spinright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/spinright.png -------------------------------------------------------------------------------- /Blockly/brobot/turnleft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/turnleft.png -------------------------------------------------------------------------------- /Blockly/brobot/turnright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/turnright.png -------------------------------------------------------------------------------- /Blockly/brobot/Brobot2_old.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/Brobot2_old.jpg -------------------------------------------------------------------------------- /Blockly/brobot/media/click.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/click.mp3 -------------------------------------------------------------------------------- /Blockly/brobot/media/click.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/click.ogg -------------------------------------------------------------------------------- /Blockly/brobot/media/click.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/click.wav -------------------------------------------------------------------------------- /Blockly/brobot/moveforward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/moveforward.png -------------------------------------------------------------------------------- /Blockly/brobot/turnleft180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/turnleft180.png -------------------------------------------------------------------------------- /Blockly/brobot/blocks/brobot.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/blocks/brobot.js -------------------------------------------------------------------------------- /Blockly/brobot/logojjrobots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/logojjrobots.png -------------------------------------------------------------------------------- /Blockly/brobot/media/delete.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/delete.mp3 -------------------------------------------------------------------------------- /Blockly/brobot/media/delete.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/delete.ogg -------------------------------------------------------------------------------- /Blockly/brobot/media/delete.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/delete.wav -------------------------------------------------------------------------------- /Blockly/brobot/media/handopen.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/handopen.cur -------------------------------------------------------------------------------- /Blockly/brobot/media/quote0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/quote0.png -------------------------------------------------------------------------------- /Blockly/brobot/media/quote1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/quote1.png -------------------------------------------------------------------------------- /Blockly/brobot/media/sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/sprites.png -------------------------------------------------------------------------------- /Blockly/brobot/movebackward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/movebackward.png -------------------------------------------------------------------------------- /Blockly/brobot/turnright180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/turnright180.png -------------------------------------------------------------------------------- /Blockly/python/BROBOT_Class.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/python/BROBOT_Class.pyc -------------------------------------------------------------------------------- /Blockly/brobot/media/disconnect.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/disconnect.mp3 -------------------------------------------------------------------------------- /Blockly/brobot/media/disconnect.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/disconnect.ogg -------------------------------------------------------------------------------- /Blockly/brobot/media/disconnect.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/disconnect.wav -------------------------------------------------------------------------------- /Blockly/brobot/media/handclosed.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/handclosed.cur -------------------------------------------------------------------------------- /Blockly/brobot/media/handdelete.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/media/handdelete.cur -------------------------------------------------------------------------------- /Blockly/python/server/BROBOT_Class.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/python/server/BROBOT_Class.pyc -------------------------------------------------------------------------------- /Blockly/brobot/jquery/images/ui-icons_444444_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/jquery/images/ui-icons_444444_256x240.png -------------------------------------------------------------------------------- /Blockly/brobot/jquery/images/ui-icons_555555_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/jquery/images/ui-icons_555555_256x240.png -------------------------------------------------------------------------------- /Blockly/brobot/jquery/images/ui-icons_777620_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/jquery/images/ui-icons_777620_256x240.png -------------------------------------------------------------------------------- /Blockly/brobot/jquery/images/ui-icons_777777_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/jquery/images/ui-icons_777777_256x240.png -------------------------------------------------------------------------------- /Blockly/brobot/jquery/images/ui-icons_cc0000_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/jquery/images/ui-icons_cc0000_256x240.png -------------------------------------------------------------------------------- /Blockly/brobot/jquery/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrobots/B-ROBOT_EVO2/HEAD/Blockly/brobot/jquery/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /Blockly/brobot/brobot_config.js: -------------------------------------------------------------------------------- 1 | 2 | // BROBOT STEP CONSTANTS 3 | var STEPSMETER = 11428; // STEPS/METERS default: 11428 4 | var STEPSTURN = 4720;//4675; // STEPS/TURN (360 deg) default:4675 -------------------------------------------------------------------------------- /Blockly/brobot/README.md: -------------------------------------------------------------------------------- 1 | # Blockly 2 | 3 | Google's Blockly is a web-based, visual programming editor. Users can drag 4 | blocks together to build programs. All code is free and open source. 5 | 6 | **The project page is https://developers.google.com/blockly/** 7 | 8 | ![](https://developers.google.com/blockly/images/sample.png) 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | JJROBOTS B-ROBOT EVO 2 2 | ====================== 3 | This is the new and improved version of our popular self Balancing Arduino robot. 4 | Control your robot via Smartphone/Tablet with our app. 3D printed parts. 5 | This new version is more stable, with lot of new features and more fun! 6 | 7 | All the documentation, features, how it works, build manuals and SHOP here: 8 | URL: http://www.jjrobots.com/b-robot-evo-2-much-more-than-a-self-balancing-robot/ 9 | 10 | JJROBOTS 2017. Science & fun! 11 | 12 | 13 | -------------------------------------------------------------------------------- /Blockly/brobot/demos/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /Blockly/brobot/msg/en.js: -------------------------------------------------------------------------------- 1 | var MSG = { 2 | title: "Code", 3 | blocks: "Blocks", 4 | linkTooltip: "Save and link to blocks.", 5 | runTooltip: "Run the program defined by the blocks in the workspace.", 6 | badCode: "Program error:\n%1", 7 | timeout: "Maximum execution iterations exceeded.", 8 | trashTooltip: "Discard all blocks.", 9 | catLogic: "Logic", 10 | catLoops: "Loops", 11 | catMath: "Math", 12 | catText: "Text", 13 | catLists: "Lists", 14 | catColour: "Colour", 15 | catVariables: "Variables", 16 | catFunctions: "Functions", 17 | listVariable: "list", 18 | textVariable: "text", 19 | httpRequestError: "There was a problem with the request.", 20 | linkAlert: "Share your blocks with this link:\n\n%1", 21 | hashError: "Sorry, '%1' doesn't correspond with any saved program.", 22 | xmlError: "Could not load your saved file. Perhaps it was created with a different version of Blockly?", 23 | badXml: "Error parsing XML:\n%1\n\nSelect 'OK' to abandon your changes or 'Cancel' to further edit the XML." 24 | }; 25 | -------------------------------------------------------------------------------- /Blockly/python/Example1.py: -------------------------------------------------------------------------------- 1 | # BROBOT PC CONTROL python script 2 | # Exampe 1: Simple commands 3 | # Before running the script you need to connect the PC to the BROBOT wifi 4 | # Remember, default password for Wifi network JJROBOTS_XX is 87654321 5 | 6 | # author: JJROBOTS 2016 7 | # version: 1.01 (28/10/2016) 8 | # Licence: Open Source (GNU LGPLv3) 9 | 10 | import time 11 | from BROBOT_Class import BROBOT # Import CLASS to control BROBOT 12 | 13 | # BROBOT initialization 14 | myRobot = BROBOT() 15 | myRobot.mode(0) # Normal mode. optional: PRO MODE=1 16 | 17 | # Example of sequence of commands to BROBOT: 18 | myRobot.servo(1) #Move servo 19 | time.sleep(0.25) 20 | myRobot.servo(0) 21 | time.sleep(0.25) 22 | myRobot.servo(1) #Move servo 23 | time.sleep(0.25) 24 | myRobot.servo(0) 25 | 26 | myRobot.throttle(0.6) #Move forward 27 | time.sleep(1.2) 28 | myRobot.throttle(0) #Stop 29 | time.sleep(2) 30 | myRobot.steering(0.8) #Turn right 31 | time.sleep(2) 32 | myRobot.steering(0) 33 | time.sleep(0.25) 34 | myRobot.steering(-0.8) #Turn left 35 | time.sleep(2) 36 | myRobot.steering(0) #Stop 37 | myRobot.throttle(0) 38 | 39 | 40 | -------------------------------------------------------------------------------- /Blockly/python/Example2.py: -------------------------------------------------------------------------------- 1 | # BROBOT PC CONTROL python script 2 | # Exampe 2: Brobot Dance 3 | # Before running the script you need to connect the PC to the BROBOT wifi 4 | # Remember, default password for Wifi network JJROBOTS_XX is 87654321 5 | 6 | # author: JJROBOTS 2016 7 | # version: 1.01 (28/10/2016) 8 | # Licence: Open Source (GNU LGPLv3) 9 | 10 | import time 11 | from BROBOT_Class import BROBOT # Import CLASS to control BROBOT 12 | 13 | # BROBOT initialization 14 | myRobot = BROBOT() 15 | myRobot.mode(1) # PRO MODE 16 | 17 | for i in range(0,2): 18 | myRobot.servo(1) 19 | time.sleep(0.15) 20 | myRobot.servo(0) 21 | time.sleep(0.15) 22 | 23 | for i in range(0,3): 24 | myRobot.steering(0.5+i*0.1) 25 | time.sleep(0.25) 26 | myRobot.steering(0) 27 | myRobot.steering(-0.5-i*0.1) 28 | time.sleep(0.25) 29 | myRobot.steering(0) 30 | myRobot.steering(-0.5-i*0.1) 31 | time.sleep(0.25) 32 | myRobot.steering(0) 33 | myRobot.steering(0.5+i*0.1) 34 | time.sleep(0.25) 35 | myRobot.steering(0) 36 | myRobot.servo(1) 37 | myRobot.servo(0) 38 | 39 | 40 | for i in range(0,5): 41 | myRobot.throttle(0.3) 42 | time.sleep(0.08) 43 | myRobot.throttle(0) 44 | time.sleep(0.08) 45 | myRobot.throttle(-0.3) 46 | time.sleep(0.08) 47 | myRobot.throttle(0) 48 | myRobot.servo(1) 49 | myRobot.servo(0) 50 | 51 | myRobot.steering(1) 52 | time.sleep(1) 53 | myRobot.steering(0) 54 | time.sleep(0.1) 55 | myRobot.steering(-1) 56 | time.sleep(1) 57 | myRobot.steering(0) 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /Blockly/brobot/generators/python/variables.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Visual Blocks Language 4 | * 5 | * Copyright 2012 Google Inc. 6 | * https://developers.google.com/blockly/ 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | /** 22 | * @fileoverview Generating Python for variable blocks. 23 | * @author q.neutron@gmail.com (Quynh Neutron) 24 | */ 25 | 'use strict'; 26 | 27 | goog.provide('Blockly.Python.variables'); 28 | 29 | goog.require('Blockly.Python'); 30 | 31 | 32 | Blockly.Python['variables_get'] = function(block) { 33 | // Variable getter. 34 | var code = Blockly.Python.variableDB_.getName(block.getFieldValue('VAR'), 35 | Blockly.Variables.NAME_TYPE); 36 | return [code, Blockly.Python.ORDER_ATOMIC]; 37 | }; 38 | 39 | Blockly.Python['variables_set'] = function(block) { 40 | // Variable setter. 41 | var argument0 = Blockly.Python.valueToCode(block, 'VALUE', 42 | Blockly.Python.ORDER_NONE) || '0'; 43 | var varName = Blockly.Python.variableDB_.getName(block.getFieldValue('VAR'), 44 | Blockly.Variables.NAME_TYPE); 45 | return varName + ' = ' + argument0 + '\n'; 46 | }; 47 | -------------------------------------------------------------------------------- /Blockly/python/Example4.py: -------------------------------------------------------------------------------- 1 | # BROBOT PC CONTROL python script 2 | # Exampe 4: Controlling 2 BROBOTS in a coreography... 3 | # You should modify your BROBOT arduino code to connecto to your wifi network 4 | # BROBOT1 is on IP 192.168.1.101 and BROBOT 2 IP is 192.168.1.102 5 | 6 | # author: JJROBOTS 2016 7 | # version: 1.01 (28/10/2016) 8 | # Licence: Open Source (GNU LGPLv3) 9 | 10 | import time 11 | from BROBOT_Class import BROBOT # Import CLASS to control BROBOT 12 | 13 | # BROBOT1 initialization 14 | myRobot1 = BROBOT() 15 | myRobot1.UDP_IP = "192.168.1.101" 16 | myRobot1.mode(0) # Normal mode. optional: PRO MODE=1 17 | 18 | # BROBOT1 initialization 19 | myRobot2 = BROBOT() 20 | myRobot2.UDP_IP = "192.168.1.102" 21 | myRobot2.mode(0) # Normal mode. optional: PRO MODE=1 22 | 23 | 24 | # Example of sequence of commands to BROBOT: 25 | myRobot1.servo(1) #Move servo 26 | myRobot2.servo(1) 27 | time.sleep(0.25) 28 | myRobot1.servo(0) 29 | myRobot2.servo(0) 30 | time.sleep(0.25) 31 | myRobot1.servo(1) #Move servo 32 | myRobot2.servo(1) 33 | time.sleep(0.25) 34 | myRobot1.servo(0) 35 | myRobot2.servo(0) 36 | 37 | myRobot1.throttle(0.4) 38 | myRobot2.throttle(0.4) 39 | time.sleep(0.75) 40 | myRobot1.throttle(0) 41 | myRobot2.throttle(0) 42 | time.sleep(1) 43 | myRobot1.steering(0.8) # Robot1 Turn right 44 | myRobot2.steering(-0.8) # Robot2 Turn left 45 | time.sleep(2) 46 | myRobot1.steering(0) 47 | myRobot2.steering(0) 48 | time.sleep(0.25) 49 | myRobot1.steering(-0.8) # Robot1 Turn left 50 | myRobot2.steering(0.8) # Robot2 Turn right 51 | time.sleep(2) 52 | myRobot1.steering(0) #Stop 53 | myRobot2.steering(0) 54 | myRobot1.throttle(0) 55 | myRobot2.throttle(0) 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Blockly/brobot/media/sprites.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /Blockly/python/BROBOT_Class.py: -------------------------------------------------------------------------------- 1 | # BROBOT PYTHON CLASS 2 | # Exampe 1: Simple commands 3 | # Before running the script you need to connect the PC to the BROBOT wifi 4 | # Remember, default password for Wifi network JJROBOTS_XX is 87654321 5 | 6 | # author: JJROBOTS 2016 7 | # version: 1.01 (27/10/2016) 8 | # Licence: Open Source (GNU LGPLv3) 9 | 10 | import socket 11 | import time 12 | import struct 13 | 14 | # CLASS to control BROBOT 15 | class BROBOT(object): 16 | UDP_IP = "192.168.4.1" # Default BROBOT IP (with BROBOT JJROBOTS_XX wifi) 17 | UDP_PORT = 2222 # Default BROBOT port 18 | sock = 0 19 | def __init__(self): 20 | # Create default socket with UDP protocol 21 | self.sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 22 | 23 | def sendCommand(self,OSCmessage,param): 24 | base = bytearray(OSCmessage) # OSC message 25 | param = bytearray(struct.pack(">f",param)) 26 | message = base+param 27 | self.sock.sendto(message,(self.UDP_IP,self.UDP_PORT)) 28 | time.sleep(0.05) 29 | 30 | # Mode: 0 NORMAL MODE, 1 PRO MODE 31 | def mode(self,value=0.0): 32 | print "BROBOT Mode:",value 33 | if (value!=1): value = 0.0 34 | # Encapsulate the commands on OSC protocol UDP message and send... 35 | self.sendCommand(b'/1/toggle1/\x00\x00,f\x00\x00',value) 36 | 37 | # Throttle command. Values from [-1.0 to 1.0] positive: forward 38 | def throttle(self,value=0.0): 39 | print "BROBOT Throttle:",value 40 | value = (value+1.0)/2.0 # Adapt values to 0.0-1.0 range 41 | self.sendCommand(b'/1/fader1\x00\x00\x00,f\x00\x00',value) #send OSC message 42 | 43 | # Steering command. Values from [-1.0 to 1.0] positive: turn right 44 | def steering(self,value=0.0): 45 | print "BROBOT Steering:",value 46 | value = (value+1.0)/2.0 # Adapt values to 0.0-1.0 range 47 | self.sendCommand(b'/1/fader2\x00\x00\x00,f\x00\x00',value) #send OSC message 48 | 49 | # Servo command. Values 0 or 1 (activated) 50 | def servo(self,value=0.0): 51 | print "BROBOT Servo:",value 52 | if (value!=1):value=0.0 53 | self.sendCommand(b'/1/push1\x00\x00,f\x00\x00',value) #send OSC message 54 | 55 | -------------------------------------------------------------------------------- /Blockly/python/Example3.py: -------------------------------------------------------------------------------- 1 | # BROBOT PC CONTROL python script 2 | # Exampe 3: Graphic User Interface to control BROBOT (using Tkinter python UI) 3 | # Before running the script you need to connect the PC to the BROBOT wifi 4 | # Remember, default password for Wifi network JJROBOTS_XX is 87654321 5 | 6 | # author: JJROBOTS 2016 7 | # version: 1.01 (28/10/2016) 8 | # Licence: Open Source (GNU LGPLv3) 9 | 10 | import socket 11 | import time 12 | import struct 13 | import Tkinter as tk 14 | from Tkinter import IntVar 15 | from BROBOT_Class import BROBOT # Import CLASS to control BROBOT 16 | 17 | 18 | # GRAPHIC USER INTERFACE 19 | class MainApplication(tk.Frame): 20 | throttle = 0 21 | steering = 0 22 | mode = 0 23 | myRobot = BROBOT() 24 | def draw(self): 25 | print "DRAW" 26 | def __init__(self,parent,*args,**kwargs): 27 | tk.Frame.__init__(self,parent,*args,**kwargs) 28 | self.parent = parent 29 | # GUI INIT: 2 sliders and 1 button 30 | self.t = tk.Scale(troughcolor="light yellow",from_=100,to=-100,width=40,length=200) 31 | self.t.pack(side=tk.LEFT,fill=tk.BOTH,expand=1) 32 | self.s = tk.Scale(troughcolor="light cyan",from_=-100,to=100,width=40,length=250,orient=tk.HORIZONTAL) 33 | self.s.pack(side=tk.LEFT,fill=tk.X) 34 | self.after(50,self.timer) 35 | self.b = tk.Button(bg="light green",repeatdelay=1,repeatinterval=50,width=10,height=2,text="SERVO",command=self.buttonCallback) 36 | self.b.pack(side=tk.LEFT) 37 | self.mode_control = IntVar() 38 | self.m = tk.Checkbutton(text="PRO MODE",variable=self.mode_control) 39 | self.m.pack() 40 | def buttonCallback(self): 41 | self.myRobot.servo(1) 42 | time.sleep(0.2) 43 | self.myRobot.servo(0) 44 | def timer(self): # Timer at 50ms interval to read slider values 45 | if (self.t.get()!=self.throttle): 46 | self.throttle = self.t.get() 47 | self.myRobot.throttle(self.throttle/100.0) 48 | #print "THROTTLE:",self.throttle 49 | if (self.s.get()!=self.steering): 50 | self.steering = self.s.get() 51 | self.myRobot.steering(self.steering/100.0) 52 | #print "STEERING:",self.steering 53 | if (self.mode_control.get()!=self.mode): 54 | self.mode = self.mode_control.get() 55 | self.myRobot.mode(self.mode) 56 | #print "MODE:",self.mode 57 | self.after(50,self.timer) 58 | 59 | 60 | # START APPLICATION 61 | if __name__=="__main__": 62 | root = tk.Tk() 63 | root.wm_title("BROBOT CONTROL") 64 | MainApplication(root).pack(side="top",fill="both",expand=True) 65 | root.mainloop() 66 | 67 | 68 | -------------------------------------------------------------------------------- /Blockly/python/server/BROBOT_Class.py: -------------------------------------------------------------------------------- 1 | # BROBOT PYTHON CLASS 2 | # Exampe 1: Simple commands 3 | # Before running the script you need to connect the PC to the BROBOT wifi 4 | # Remember, default password for Wifi network JJROBOTS_XX is 87654321 5 | 6 | # author: JJROBOTS 2016 7 | # version: 1.01 (27/10/2016) 8 | # Licence: Open Source (GNU LGPLv3) 9 | 10 | import socket 11 | import time 12 | import struct 13 | 14 | # CLASS to control BROBOT 15 | class BROBOT(object): 16 | UDP_IP = "192.168.4.1" # Default BROBOT IP (with BROBOT JJROBOTS_XX wifi) 17 | UDP_PORT = 2222 # Default BROBOT port 18 | sock = 0 19 | def __init__(self): 20 | # Create default socket with UDP protocol 21 | self.sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 22 | 23 | def sendCommand(self,OSCmessage,param): 24 | base = bytearray(OSCmessage) # OSC message 25 | param = bytearray(struct.pack(">f",param)) 26 | message = base+param 27 | self.sock.sendto(message,(self.UDP_IP,self.UDP_PORT)) 28 | time.sleep(0.05) 29 | 30 | # Mode: 0 NORMAL MODE, 1 PRO MODE 31 | def mode(self,value=0.0): 32 | print "BROBOT Mode:",value 33 | if (value!=1): value = 0.0 34 | # Encapsulate the commands on OSC protocol UDP message and send... 35 | self.sendCommand(b'/1/toggle1/\x00\x00,f\x00\x00',value) 36 | 37 | # Throttle command. Values from [-1.0 to 1.0] positive: forward 38 | def throttle(self,value=0.0): 39 | print "BROBOT Throttle:",value 40 | value = (value+1.0)/2.0 # Adapt values to 0.0-1.0 range 41 | self.sendCommand(b'/1/fader1\x00\x00\x00,f\x00\x00',value) #send OSC message 42 | 43 | # Steering command. Values from [-1.0 to 1.0] positive: turn right 44 | def steering(self,value=0.0): 45 | print "BROBOT Steering:",value 46 | value = (value+1.0)/2.0 # Adapt values to 0.0-1.0 range 47 | self.sendCommand(b'/1/fader2\x00\x00\x00,f\x00\x00',value) #send OSC message 48 | 49 | # Move speed, steps1, steps2 50 | def move(self,speed,steps1,steps2): 51 | print "BROBOT MOVE",speed,steps1,steps2 52 | base = bytearray(b'/1/move\x00\x00\x00') 53 | param1 = bytearray(struct.pack("h",speed)) 54 | param2 = bytearray(struct.pack("h",steps1)) 55 | param3 = bytearray(struct.pack("h",steps2)) 56 | message = base+param1+param2+param3 57 | self.sock.sendto(message,(self.UDP_IP,self.UDP_PORT)) 58 | #print len(message) 59 | #self.sendCommand(b'/1/move\x00\x00\x00\x00\x00\x00 60 | 61 | # Servo command. Values 0 or 1 (activated) 62 | def servo(self,value=0.0): 63 | print "BROBOT Servo:",value 64 | if (value!=1):value=0.0 65 | self.sendCommand(b'/1/push1\x00\x00,f\x00\x00',value) #send OSC message 66 | 67 | -------------------------------------------------------------------------------- /Arduino/BROBOT_EVO2/Servos.ino: -------------------------------------------------------------------------------- 1 | // BROBOT EVO 2 by JJROBOTS 2 | // SELF BALANCE ARDUINO ROBOT WITH STEPPER MOTORS 3 | // License: GPL v2 4 | // Servo and aux functions 5 | 6 | //#include "Arduino.h" 7 | 8 | // Default servo definitions 9 | #define SERVO1_AUX_NEUTRO 1500 // Servo neutral position 10 | #define SERVO1_MIN_PULSEWIDTH 700 11 | #define SERVO1_MAX_PULSEWIDTH 2300 12 | #define SERVO2_AUX_NEUTRO 1500 // Servo neutral position 13 | #define SERVO2_MIN_PULSEWIDTH 700 14 | #define SERVO2_MAX_PULSEWIDTH 2300 15 | 16 | 17 | #define BATT_VOLT_FACTOR 8 18 | 19 | int battery; 20 | 21 | // Init servo on T4 timer. Output OC4B (Leonardo Pin10) 22 | // We configure the Timer4 for 11 bits PWM (enhacend precision) and 16.3ms period (OK for most servos) 23 | // Resolution: 8us per step (this is OK for servos, around 175 steps for typical servo) 24 | void BROBOT_initServo() 25 | { 26 | int temp; 27 | 28 | // Initialize Timer4 as Fast PWM 29 | TCCR4A = (1< 11 bits 34 | 35 | temp = 1500>>3; 36 | TC4H = temp >> 8; 37 | OCR4B = temp & 0xff; 38 | 39 | // Reset timer 40 | TC4H = 0; 41 | TCNT4 = 0; 42 | 43 | // Set TOP to 1023 (10 bit timer) 44 | TC4H = 3; 45 | OCR4C = 0xFF; 46 | 47 | // OC4A = PC7 (Pin13) OC4B = PB6 (Pin10) OC4D = PD7 (Pin6) 48 | // Set pins as outputs 49 | DDRB |= (1 << 6); // OC4B = PB6 (Pin10 on Leonardo board) 50 | DDRC |= (1 << 7); // OC4A = PC7 (Pin13 on Leonardo board) 51 | DDRD |= (1 << 7); // OC4D = PD7 (Pin6 on Leonardo board) 52 | 53 | //Enable OC4A and OC4B and OCR4D output 54 | TCCR4A |= (1<>3; // Check max values and Resolution: 8us 63 | // 11 bits => 3 MSB bits on TC4H, LSB bits on OCR4B 64 | TC4H = pwm>>8; 65 | OCR4B = pwm & 0xFF; 66 | } 67 | 68 | void BROBOT_moveServo2(int pwm) 69 | { 70 | pwm = constrain(pwm,SERVO2_MIN_PULSEWIDTH,SERVO2_MAX_PULSEWIDTH)>>3; // Check max values and Resolution: 8us 71 | // 11 bits => 3 MSB bits on TC4H, LSB bits on OCR4B 72 | TC4H = pwm>>8; 73 | OCR4A = pwm & 0xFF; // 2.0 or 2.3 boards servo2 output 74 | OCR4D = pwm & 0xFF; // 2.1 or 2.4 boards servo2 output 75 | } 76 | 77 | // output : Battery voltage*10 (aprox) and noise filtered 78 | int BROBOT_readBattery(bool first_time) 79 | { 80 | if (first_time) 81 | battery = analogRead(5)/BATT_VOLT_FACTOR; 82 | else 83 | battery = (battery*9 + (analogRead(5)/BATT_VOLT_FACTOR))/10; 84 | return battery; 85 | } 86 | 87 | 88 | -------------------------------------------------------------------------------- /Blockly/brobot/generators/python/brobot.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Visual Blocks Language 4 | * 5 | * Copyright 2012 Google Inc. 6 | * https://developers.google.com/blockly/ 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | /** 22 | * @fileoverview Generating JavaScript for colour blocks. 23 | * @author fraser@google.com (Neil Fraser) 24 | */ 25 | 'use strict'; 26 | 27 | goog.provide('Blockly.Python.brobot'); 28 | 29 | goog.require('Blockly.Python'); 30 | 31 | Blockly.Python['robotconfig'] = function(block) { 32 | var IPvalue = Blockly.JavaScript.valueToCode(block, 'IPvalue', Blockly.JavaScript.ORDER_ATOMIC).replace(/'/g, ""); 33 | var PORTvalue = Blockly.JavaScript.valueToCode(block, 'PORTvalue', Blockly.JavaScript.ORDER_ATOMIC).replace(/'/g, ""); 34 | var code = 'myRobot.UDP_IP=\"'+IPvalue+'\"\n'; 35 | code += 'myRobot.UDP_PORT=\"'+PORTvalue+'\"\n'; 36 | //var code = ''; 37 | return code; 38 | }; 39 | 40 | Blockly.Python['throttle'] = function(block) { 41 | var value = Blockly.JavaScript.valueToCode(block, 'TValue', Blockly.JavaScript.ORDER_ATOMIC);// 42 | //var value = block.getFieldValue('TValue'); 43 | // TODO: Assemble JavaScript into code variable. 44 | //var code = 'window.alert("T'+value+'");\n'; 45 | // Create the Socket 46 | var code = 'myRobot.throttle('+value+')\n'; 47 | return code; 48 | }; 49 | 50 | Blockly.Python['steering'] = function(block) { 51 | var value = Blockly.JavaScript.valueToCode(block, 'SValue', Blockly.JavaScript.ORDER_ATOMIC);// 52 | //var value = block.getFieldValue('SValue'); 53 | // TODO: Assemble JavaScript into code variable. 54 | var code = 'myRobot.steering('+value+')\n'; 55 | return code; 56 | }; 57 | 58 | Blockly.Python['servo'] = function(block) { 59 | //var value = Blockly.JavaScript.valueToCode(block, 'SValue', Blockly.JavaScript.ORDER_ATOMIC);// 60 | var value = block.getFieldValue('Servo'); 61 | // TODO: Assemble JavaScript into code variable. 62 | var code = 'myRobot.servo('+value+')\n'; 63 | return code; 64 | }; 65 | 66 | Blockly.Python['mode'] = function(block) { 67 | //var value = Blockly.JavaScript.valueToCode(block, 'SValue', Blockly.JavaScript.ORDER_ATOMIC);// 68 | var value = block.getFieldValue('Mode'); 69 | // TODO: Assemble JavaScript into code variable. 70 | var code = 'myRobot.mode('+value+')\n'; 71 | return code; 72 | }; 73 | 74 | Blockly.Python['delay'] = function(block) { 75 | //var value = Blockly.JavaScript.valueToCode(block, 'SValue', Blockly.JavaScript.ORDER_ATOMIC);// 76 | var value = block.getFieldValue('DValue'); 77 | // TODO: Assemble JavaScript into code variable. 78 | //var code = 'window.alert(delay'+value+');\n'; 79 | var code = 'time.sleep('+value+')\n'; 80 | return code; 81 | }; 82 | 83 | 84 | -------------------------------------------------------------------------------- /Blockly/brobot/style.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | } 4 | 5 | body { 6 | background-color: #fff; 7 | font-family: sans-serif; 8 | margin: 0; 9 | overflow: hidden; 10 | } 11 | 12 | .farSide { 13 | text-align: right; 14 | } 15 | 16 | html[dir="RTL"] .farSide { 17 | text-align: left; 18 | } 19 | 20 | /* Buttons */ 21 | button { 22 | margin: 5px; 23 | padding: 10px; 24 | border-radius: 4px; 25 | border: 1px solid #ddd; 26 | font-size: large; 27 | background-color: #eee; 28 | color: #000; 29 | } 30 | button.primary { 31 | border: 1px solid #dd4b39; 32 | background-color: #dd4b39; 33 | color: #fff; 34 | } 35 | button.primary>img { 36 | opacity: 1; 37 | } 38 | button>img { 39 | opacity: 0.6; 40 | vertical-align: text-bottom; 41 | } 42 | button:hover>img { 43 | opacity: 1; 44 | } 45 | button:active { 46 | border: 1px solid #888 !important; 47 | } 48 | button:hover { 49 | box-shadow: 2px 2px 5px #888; 50 | } 51 | button.disabled:hover>img { 52 | opacity: 0.6; 53 | } 54 | button.disabled { 55 | display: none; 56 | } 57 | button.notext { 58 | font-size: 10%; 59 | } 60 | 61 | h1 { 62 | font-weight: normal; 63 | font-size: 140%; 64 | margin-left: 5px; 65 | margin-right: 5px; 66 | } 67 | 68 | /* Tabs */ 69 | #tabRow>td { 70 | border: 1px solid #ccc; 71 | border-bottom: none; 72 | } 73 | td.tabon { 74 | border-bottom-color: #ddd !important; 75 | background-color: #ddd; 76 | padding: 5px 19px; 77 | } 78 | td.taboff { 79 | cursor: pointer; 80 | padding: 5px 19px; 81 | } 82 | td.taboff:hover { 83 | background-color: #eee; 84 | } 85 | td.tabmin { 86 | border-top-style: none !important; 87 | border-left-style: none !important; 88 | border-right-style: none !important; 89 | } 90 | td.tabmax { 91 | border-top-style: none !important; 92 | border-left-style: none !important; 93 | border-right-style: none !important; 94 | width: 99%; 95 | padding-left: 10px; 96 | padding-right: 10px; 97 | text-align: right; 98 | } 99 | html[dir=rtl] td.tabmax { 100 | text-align: left; 101 | } 102 | 103 | table { 104 | border-collapse: collapse; 105 | margin: 0; 106 | padding: 0; 107 | border: none; 108 | } 109 | td { 110 | padding: 0; 111 | vertical-align: top; 112 | } 113 | .content { 114 | visibility: hidden; 115 | margin: 0; 116 | padding: 1ex; 117 | position: absolute; 118 | direction: ltr; 119 | } 120 | pre.content { 121 | border: 1px solid #ccc; 122 | overflow: scroll; 123 | } 124 | #content_blocks { 125 | padding: 0; 126 | } 127 | .blocklySvg { 128 | border-top: none !important; 129 | } 130 | #content_xml { 131 | resize: none; 132 | outline: none; 133 | border: 1px solid #ccc; 134 | font-family: monospace; 135 | overflow: scroll; 136 | } 137 | #languageMenu { 138 | vertical-align: top; 139 | margin-top: 15px; 140 | margin-right: 15px; 141 | } 142 | 143 | /* Buttons */ 144 | button { 145 | padding: 1px 10px; 146 | margin: 1px 5px; 147 | } 148 | 149 | /* Sprited icons. */ 150 | .icon21 { 151 | height: 21px; 152 | width: 21px; 153 | background-image: url(icons.png); 154 | } 155 | .trash { 156 | background-position: 0px 0px; 157 | } 158 | .link { 159 | background-position: -21px 0px; 160 | } 161 | .run { 162 | background-position: -42px 0px; 163 | } 164 | -------------------------------------------------------------------------------- /Blockly/brobot/generators/python/colour.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Visual Blocks Language 4 | * 5 | * Copyright 2012 Google Inc. 6 | * https://developers.google.com/blockly/ 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | /** 22 | * @fileoverview Generating Python for colour blocks. 23 | * @author fraser@google.com (Neil Fraser) 24 | */ 25 | 'use strict'; 26 | 27 | goog.provide('Blockly.Python.colour'); 28 | 29 | goog.require('Blockly.Python'); 30 | 31 | 32 | Blockly.Python['colour_picker'] = function(block) { 33 | // Colour picker. 34 | var code = '\'' + block.getFieldValue('COLOUR') + '\''; 35 | return [code, Blockly.Python.ORDER_ATOMIC]; 36 | }; 37 | 38 | Blockly.Python['colour_random'] = function(block) { 39 | // Generate a random colour. 40 | Blockly.Python.definitions_['import_random'] = 'import random'; 41 | var code = '\'#%06x\' % random.randint(0, 2**24 - 1)'; 42 | return [code, Blockly.Python.ORDER_FUNCTION_CALL]; 43 | }; 44 | 45 | Blockly.Python['colour_rgb'] = function(block) { 46 | // Compose a colour from RGB components expressed as percentages. 47 | var functionName = Blockly.Python.provideFunction_( 48 | 'colour_rgb', 49 | ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(r, g, b):', 50 | ' r = round(min(100, max(0, r)) * 2.55)', 51 | ' g = round(min(100, max(0, g)) * 2.55)', 52 | ' b = round(min(100, max(0, b)) * 2.55)', 53 | ' return \'#%02x%02x%02x\' % (r, g, b)']); 54 | var r = Blockly.Python.valueToCode(block, 'RED', 55 | Blockly.Python.ORDER_NONE) || 0; 56 | var g = Blockly.Python.valueToCode(block, 'GREEN', 57 | Blockly.Python.ORDER_NONE) || 0; 58 | var b = Blockly.Python.valueToCode(block, 'BLUE', 59 | Blockly.Python.ORDER_NONE) || 0; 60 | var code = functionName + '(' + r + ', ' + g + ', ' + b + ')'; 61 | return [code, Blockly.Python.ORDER_FUNCTION_CALL]; 62 | }; 63 | 64 | Blockly.Python['colour_blend'] = function(block) { 65 | // Blend two colours together. 66 | var functionName = Blockly.Python.provideFunction_( 67 | 'colour_blend', 68 | ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + 69 | '(colour1, colour2, ratio):', 70 | ' r1, r2 = int(colour1[1:3], 16), int(colour2[1:3], 16)', 71 | ' g1, g2 = int(colour1[3:5], 16), int(colour2[3:5], 16)', 72 | ' b1, b2 = int(colour1[5:7], 16), int(colour2[5:7], 16)', 73 | ' ratio = min(1, max(0, ratio))', 74 | ' r = round(r1 * (1 - ratio) + r2 * ratio)', 75 | ' g = round(g1 * (1 - ratio) + g2 * ratio)', 76 | ' b = round(b1 * (1 - ratio) + b2 * ratio)', 77 | ' return \'#%02x%02x%02x\' % (r, g, b)']); 78 | var colour1 = Blockly.Python.valueToCode(block, 'COLOUR1', 79 | Blockly.Python.ORDER_NONE) || '\'#000000\''; 80 | var colour2 = Blockly.Python.valueToCode(block, 'COLOUR2', 81 | Blockly.Python.ORDER_NONE) || '\'#000000\''; 82 | var ratio = Blockly.Python.valueToCode(block, 'RATIO', 83 | Blockly.Python.ORDER_NONE) || 0; 84 | var code = functionName + '(' + colour1 + ', ' + colour2 + ', ' + ratio + ')'; 85 | return [code, Blockly.Python.ORDER_FUNCTION_CALL]; 86 | }; 87 | -------------------------------------------------------------------------------- /Arduino/BROBOT_EVO2/Network.ino: -------------------------------------------------------------------------------- 1 | // BROBOT EVO 2 by JJROBOTS 2 | // SELF BALANCE ARDUINO ROBOT WITH STEPPER MOTORS 3 | // License: GPL v2 4 | // Network functions (ESP module) 5 | 6 | // Read control PID parameters from user. This is only for advanced users that want to "play" with the controllers... 7 | void readControlParameters() 8 | { 9 | // Parameters Mode (page2 controls) 10 | // Parameter initialization (first time we enter page2) 11 | if (!modifing_control_parameters) 12 | { 13 | for (uint8_t i = 0; i < 4; i++) 14 | OSCfader[i] = 0.5; 15 | OSCtoggle[0] = 0; 16 | 17 | modifing_control_parameters = true; 18 | Serial1.println("$P2"); 19 | } 20 | // User could adjust KP, KD, KP_THROTTLE and KI_THROTTLE (fadder1,2,3,4) 21 | // Now we need to adjust all the parameters all the times because we dont know what parameter has been moved 22 | Kp_user = KP * 2 * OSCfader[0]; 23 | Kd_user = KD * 2 * OSCfader[1]; 24 | Kp_thr_user = KP_THROTTLE * 2 * OSCfader[2]; 25 | Ki_thr_user = KI_THROTTLE * 2 * OSCfader[3]; 26 | // Send a special telemetry message with the new parameters 27 | char auxS[50]; 28 | sprintf(auxS, "$tP,%d,%d,%d,%d", int(Kp_user * 1000), int(Kd_user * 1000), int(Kp_thr_user * 1000), int(Ki_thr_user * 1000)); 29 | Serial1.println(auxS); 30 | 31 | #if DEBUG>0 32 | Serial.print("Par: "); 33 | Serial.print(Kp_user); 34 | Serial.print(" "); 35 | Serial.print(Kd_user); 36 | Serial.print(" "); 37 | Serial.print(Kp_thr_user); 38 | Serial.print(" "); 39 | Serial.println(Ki_thr_user); 40 | #endif 41 | 42 | // Calibration mode?? 43 | if (OSCpush[2]==1) 44 | { 45 | Serial.print("Calibration MODE "); 46 | angle_offset = angle_adjusted_filtered; 47 | Serial.println(angle_offset); 48 | } 49 | 50 | // Kill robot => Sleep 51 | while (OSCtoggle[0] == 1) 52 | { 53 | //Reset external parameters 54 | PID_errorSum = 0; 55 | timer_old = millis(); 56 | setMotorSpeedM1(0); 57 | setMotorSpeedM2(0); 58 | digitalWrite(4, HIGH); // Disable motors 59 | OSC_MsgRead(); 60 | } 61 | } 62 | 63 | 64 | int ESPwait(String stopstr, int timeout_secs) 65 | { 66 | String response; 67 | bool found = false; 68 | char c; 69 | long timer_init; 70 | long timer; 71 | 72 | timer_init = millis(); 73 | while (!found) { 74 | timer = millis(); 75 | if (((timer - timer_init) / 1000) > timeout_secs) { // Timeout? 76 | Serial.println("!Timeout!"); 77 | return 0; // timeout 78 | } 79 | if (Serial1.available()) { 80 | c = Serial1.read(); 81 | Serial.print(c); 82 | response += c; 83 | if (response.endsWith(stopstr)) { 84 | found = true; 85 | delay(10); 86 | Serial1.flush(); 87 | Serial.println(); 88 | } 89 | } // end Serial1_available() 90 | } // end while (!found) 91 | return 1; 92 | } 93 | 94 | // getMacAddress from ESP wifi module 95 | int ESPgetMac() 96 | { 97 | char c1, c2; 98 | bool timeout = false; 99 | long timer_init; 100 | long timer; 101 | uint8_t state = 0; 102 | uint8_t index = 0; 103 | 104 | MAC = ""; 105 | timer_init = millis(); 106 | while (!timeout) { 107 | timer = millis(); 108 | if (((timer - timer_init) / 1000) > 5) // Timeout? 109 | timeout = true; 110 | if (Serial1.available()) { 111 | c2 = c1; 112 | c1 = Serial1.read(); 113 | Serial.print(c1); 114 | switch (state) { 115 | case 0: 116 | if (c1 == ':') 117 | state = 1; 118 | break; 119 | case 1: 120 | if (c1 == '\r') { 121 | MAC.toUpperCase(); 122 | state = 2; 123 | } 124 | else { 125 | if ((c1 != '"') && (c1 != ':')) 126 | MAC += c1; // Uppercase 127 | } 128 | break; 129 | case 2: 130 | if ((c2 == 'O') && (c1 == 'K')) { 131 | Serial.println(); 132 | Serial1.flush(); 133 | return 1; // Ok 134 | } 135 | break; 136 | } // end switch 137 | } // Serial_available 138 | } // while (!timeout) 139 | Serial.println("!Timeout!"); 140 | Serial1.flush(); 141 | return -1; // timeout 142 | } 143 | 144 | int ESPsendCommand(char *command, String stopstr, int timeout_secs) 145 | { 146 | Serial1.println(command); 147 | ESPwait(stopstr, timeout_secs); 148 | delay(250); 149 | } 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /Blockly/brobot/generators/python/logic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Visual Blocks Language 4 | * 5 | * Copyright 2012 Google Inc. 6 | * https://developers.google.com/blockly/ 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | /** 22 | * @fileoverview Generating Python for logic blocks. 23 | * @author q.neutron@gmail.com (Quynh Neutron) 24 | */ 25 | 'use strict'; 26 | 27 | goog.provide('Blockly.Python.logic'); 28 | 29 | goog.require('Blockly.Python'); 30 | 31 | 32 | Blockly.Python['controls_if'] = function(block) { 33 | // If/elseif/else condition. 34 | var n = 0; 35 | var argument = Blockly.Python.valueToCode(block, 'IF' + n, 36 | Blockly.Python.ORDER_NONE) || 'False'; 37 | var branch = Blockly.Python.statementToCode(block, 'DO' + n) || 38 | Blockly.Python.PASS; 39 | var code = 'if ' + argument + ':\n' + branch; 40 | for (n = 1; n <= block.elseifCount_; n++) { 41 | argument = Blockly.Python.valueToCode(block, 'IF' + n, 42 | Blockly.Python.ORDER_NONE) || 'False'; 43 | branch = Blockly.Python.statementToCode(block, 'DO' + n) || 44 | Blockly.Python.PASS; 45 | code += 'elif ' + argument + ':\n' + branch; 46 | } 47 | if (block.elseCount_) { 48 | branch = Blockly.Python.statementToCode(block, 'ELSE') || 49 | Blockly.Python.PASS; 50 | code += 'else:\n' + branch; 51 | } 52 | return code; 53 | }; 54 | 55 | Blockly.Python['logic_compare'] = function(block) { 56 | // Comparison operator. 57 | var OPERATORS = { 58 | 'EQ': '==', 59 | 'NEQ': '!=', 60 | 'LT': '<', 61 | 'LTE': '<=', 62 | 'GT': '>', 63 | 'GTE': '>=' 64 | }; 65 | var operator = OPERATORS[block.getFieldValue('OP')]; 66 | var order = Blockly.Python.ORDER_RELATIONAL; 67 | var argument0 = Blockly.Python.valueToCode(block, 'A', order) || '0'; 68 | var argument1 = Blockly.Python.valueToCode(block, 'B', order) || '0'; 69 | var code = argument0 + ' ' + operator + ' ' + argument1; 70 | return [code, order]; 71 | }; 72 | 73 | Blockly.Python['logic_operation'] = function(block) { 74 | // Operations 'and', 'or'. 75 | var operator = (block.getFieldValue('OP') == 'AND') ? 'and' : 'or'; 76 | var order = (operator == 'and') ? Blockly.Python.ORDER_LOGICAL_AND : 77 | Blockly.Python.ORDER_LOGICAL_OR; 78 | var argument0 = Blockly.Python.valueToCode(block, 'A', order); 79 | var argument1 = Blockly.Python.valueToCode(block, 'B', order); 80 | if (!argument0 && !argument1) { 81 | // If there are no arguments, then the return value is false. 82 | argument0 = 'False'; 83 | argument1 = 'False'; 84 | } else { 85 | // Single missing arguments have no effect on the return value. 86 | var defaultArgument = (operator == 'and') ? 'True' : 'False'; 87 | if (!argument0) { 88 | argument0 = defaultArgument; 89 | } 90 | if (!argument1) { 91 | argument1 = defaultArgument; 92 | } 93 | } 94 | var code = argument0 + ' ' + operator + ' ' + argument1; 95 | return [code, order]; 96 | }; 97 | 98 | Blockly.Python['logic_negate'] = function(block) { 99 | // Negation. 100 | var argument0 = Blockly.Python.valueToCode(block, 'BOOL', 101 | Blockly.Python.ORDER_LOGICAL_NOT) || 'True'; 102 | var code = 'not ' + argument0; 103 | return [code, Blockly.Python.ORDER_LOGICAL_NOT]; 104 | }; 105 | 106 | Blockly.Python['logic_boolean'] = function(block) { 107 | // Boolean values true and false. 108 | var code = (block.getFieldValue('BOOL') == 'TRUE') ? 'True' : 'False'; 109 | return [code, Blockly.Python.ORDER_ATOMIC]; 110 | }; 111 | 112 | Blockly.Python['logic_null'] = function(block) { 113 | // Null data type. 114 | return ['None', Blockly.Python.ORDER_ATOMIC]; 115 | }; 116 | 117 | Blockly.Python['logic_ternary'] = function(block) { 118 | // Ternary operator. 119 | var value_if = Blockly.Python.valueToCode(block, 'IF', 120 | Blockly.Python.ORDER_CONDITIONAL) || 'False'; 121 | var value_then = Blockly.Python.valueToCode(block, 'THEN', 122 | Blockly.Python.ORDER_CONDITIONAL) || 'None'; 123 | var value_else = Blockly.Python.valueToCode(block, 'ELSE', 124 | Blockly.Python.ORDER_CONDITIONAL) || 'None'; 125 | var code = value_then + ' if ' + value_if + ' else ' + value_else; 126 | return [code, Blockly.Python.ORDER_CONDITIONAL]; 127 | }; 128 | -------------------------------------------------------------------------------- /Blockly/brobot/generators/python/procedures.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Visual Blocks Language 4 | * 5 | * Copyright 2012 Google Inc. 6 | * https://developers.google.com/blockly/ 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | /** 22 | * @fileoverview Generating Python for procedure blocks. 23 | * @author fraser@google.com (Neil Fraser) 24 | */ 25 | 'use strict'; 26 | 27 | goog.provide('Blockly.Python.procedures'); 28 | 29 | goog.require('Blockly.Python'); 30 | 31 | 32 | Blockly.Python['procedures_defreturn'] = function(block) { 33 | // Define a procedure with a return value. 34 | // First, add a 'global' statement for every variable that is not shadowed by 35 | // a local parameter. 36 | var globals = []; 37 | for (var i = 0, varName; varName = block.workspace.variableList[i]; i++) { 38 | if (block.arguments_.indexOf(varName) == -1) { 39 | globals.push(Blockly.Python.variableDB_.getName(varName, 40 | Blockly.Variables.NAME_TYPE)); 41 | } 42 | } 43 | globals = globals.length ? ' global ' + globals.join(', ') + '\n' : ''; 44 | var funcName = Blockly.Python.variableDB_.getName(block.getFieldValue('NAME'), 45 | Blockly.Procedures.NAME_TYPE); 46 | var branch = Blockly.Python.statementToCode(block, 'STACK'); 47 | if (Blockly.Python.STATEMENT_PREFIX) { 48 | branch = Blockly.Python.prefixLines( 49 | Blockly.Python.STATEMENT_PREFIX.replace(/%1/g, 50 | '\'' + block.id + '\''), Blockly.Python.INDENT) + branch; 51 | } 52 | if (Blockly.Python.INFINITE_LOOP_TRAP) { 53 | branch = Blockly.Python.INFINITE_LOOP_TRAP.replace(/%1/g, 54 | '"' + block.id + '"') + branch; 55 | } 56 | var returnValue = Blockly.Python.valueToCode(block, 'RETURN', 57 | Blockly.Python.ORDER_NONE) || ''; 58 | if (returnValue) { 59 | returnValue = ' return ' + returnValue + '\n'; 60 | } else if (!branch) { 61 | branch = Blockly.Python.PASS; 62 | } 63 | var args = []; 64 | for (var i = 0; i < block.arguments_.length; i++) { 65 | args[i] = Blockly.Python.variableDB_.getName(block.arguments_[i], 66 | Blockly.Variables.NAME_TYPE); 67 | } 68 | var code = 'def ' + funcName + '(' + args.join(', ') + '):\n' + 69 | globals + branch + returnValue; 70 | code = Blockly.Python.scrub_(block, code); 71 | // Add % so as not to collide with helper functions in definitions list. 72 | Blockly.Python.definitions_['%' + funcName] = code; 73 | return null; 74 | }; 75 | 76 | // Defining a procedure without a return value uses the same generator as 77 | // a procedure with a return value. 78 | Blockly.Python['procedures_defnoreturn'] = 79 | Blockly.Python['procedures_defreturn']; 80 | 81 | Blockly.Python['procedures_callreturn'] = function(block) { 82 | // Call a procedure with a return value. 83 | var funcName = Blockly.Python.variableDB_.getName(block.getFieldValue('NAME'), 84 | Blockly.Procedures.NAME_TYPE); 85 | var args = []; 86 | for (var i = 0; i < block.arguments_.length; i++) { 87 | args[i] = Blockly.Python.valueToCode(block, 'ARG' + i, 88 | Blockly.Python.ORDER_NONE) || 'None'; 89 | } 90 | var code = funcName + '(' + args.join(', ') + ')'; 91 | return [code, Blockly.Python.ORDER_FUNCTION_CALL]; 92 | }; 93 | 94 | Blockly.Python['procedures_callnoreturn'] = function(block) { 95 | // Call a procedure with no return value. 96 | var funcName = Blockly.Python.variableDB_.getName(block.getFieldValue('NAME'), 97 | Blockly.Procedures.NAME_TYPE); 98 | var args = []; 99 | for (var i = 0; i < block.arguments_.length; i++) { 100 | args[i] = Blockly.Python.valueToCode(block, 'ARG' + i, 101 | Blockly.Python.ORDER_NONE) || 'None'; 102 | } 103 | var code = funcName + '(' + args.join(', ') + ')\n'; 104 | return code; 105 | }; 106 | 107 | Blockly.Python['procedures_ifreturn'] = function(block) { 108 | // Conditionally return value from a procedure. 109 | var condition = Blockly.Python.valueToCode(block, 'CONDITION', 110 | Blockly.Python.ORDER_NONE) || 'False'; 111 | var code = 'if ' + condition + ':\n'; 112 | if (block.hasReturnValue_) { 113 | var value = Blockly.Python.valueToCode(block, 'VALUE', 114 | Blockly.Python.ORDER_NONE) || 'None'; 115 | code += ' return ' + value + '\n'; 116 | } else { 117 | code += ' return\n'; 118 | } 119 | return code; 120 | }; 121 | -------------------------------------------------------------------------------- /Arduino/BROBOT_EVO2/Control.ino: -------------------------------------------------------------------------------- 1 | // BROBOT EVO 2 by JJROBOTS 2 | // SELF BALANCE ARDUINO ROBOT WITH STEPPER MOTORS 3 | // License: GPL v2 4 | // Control functions (PID controls, Steppers control...) 5 | 6 | // PD controller implementation(Proportional, derivative). DT in seconds 7 | float stabilityPDControl(float DT, float input, float setPoint, float Kp, float Kd) 8 | { 9 | float error; 10 | float output; 11 | 12 | error = setPoint - input; 13 | 14 | // Kd is implemented in two parts 15 | // The biggest one using only the input (sensor) part not the SetPoint input-input(t-1). 16 | // And the second using the setpoint to make it a bit more agressive setPoint-setPoint(t-1) 17 | float Kd_setPoint = constrain((setPoint - setPointOld), -8, 8); // We limit the input part... 18 | output = Kp * error + (Kd * Kd_setPoint - Kd * (input - PID_errorOld)) / DT; 19 | //Serial.print(Kd*(error-PID_errorOld));Serial.print("\t"); 20 | //PID_errorOld2 = PID_errorOld; 21 | PID_errorOld = input; // error for Kd is only the input component 22 | setPointOld = setPoint; 23 | return (output); 24 | } 25 | 26 | 27 | // PI controller implementation (Proportional, integral). DT in seconds 28 | float speedPIControl(float DT, int16_t input, int16_t setPoint, float Kp, float Ki) 29 | { 30 | int16_t error; 31 | float output; 32 | 33 | error = setPoint - input; 34 | PID_errorSum += constrain(error, -ITERM_MAX_ERROR, ITERM_MAX_ERROR); 35 | PID_errorSum = constrain(PID_errorSum, -ITERM_MAX, ITERM_MAX); 36 | 37 | //Serial.println(PID_errorSum); 38 | 39 | output = Kp * error + Ki * PID_errorSum * DT; // DT is in miliseconds... 40 | return (output); 41 | } 42 | 43 | 44 | float positionPDControl(long actualPos, long setPointPos, float Kpp, float Kdp, int16_t speedM) 45 | { 46 | float output; 47 | float P; 48 | 49 | P = constrain(Kpp * float(setPointPos - actualPos), -115, 115); // Limit command 50 | output = P + Kdp * float(speedM); 51 | return (output); 52 | } 53 | 54 | // TIMER 1 : STEPPER MOTOR1 SPEED CONTROL 55 | ISR(TIMER1_COMPA_vect) 56 | { 57 | if (dir_M1 == 0) // If we are not moving we dont generate a pulse 58 | return; 59 | // We generate 1us STEP pulse 60 | SET(PORTE, 6); // STEP MOTOR 1 61 | //delay_1us(); 62 | if (dir_M1 > 0) 63 | steps1--; 64 | else 65 | steps1++; 66 | CLR(PORTE, 6); 67 | } 68 | // TIMER 3 : STEPPER MOTOR2 SPEED CONTROL 69 | ISR(TIMER3_COMPA_vect) 70 | { 71 | if (dir_M2 == 0) // If we are not moving we dont generate a pulse 72 | return; 73 | // We generate 1us STEP pulse 74 | SET(PORTD, 6); // STEP MOTOR 2 75 | //delay_1us(); 76 | if (dir_M2 > 0) 77 | steps2--; 78 | else 79 | steps2++; 80 | CLR(PORTD, 6); 81 | } 82 | 83 | 84 | // Set speed of Stepper Motor1 85 | // tspeed could be positive or negative (reverse) 86 | void setMotorSpeedM1(int16_t tspeed) 87 | { 88 | long timer_period; 89 | int16_t speed; 90 | 91 | // Limit max speed? 92 | 93 | // WE LIMIT MAX ACCELERATION of the motors 94 | if ((speed_M1 - tspeed) > MAX_ACCEL) 95 | speed_M1 -= MAX_ACCEL; 96 | else if ((speed_M1 - tspeed) < -MAX_ACCEL) 97 | speed_M1 += MAX_ACCEL; 98 | else 99 | speed_M1 = tspeed; 100 | 101 | #if MICROSTEPPING==16 102 | speed = speed_M1 * 50; // Adjust factor from control output speed to real motor speed in steps/second 103 | #else 104 | speed = speed_M1 * 25; // 1/8 Microstepping 105 | #endif 106 | 107 | if (speed == 0) 108 | { 109 | timer_period = ZERO_SPEED; 110 | dir_M1 = 0; 111 | } 112 | else if (speed > 0) 113 | { 114 | timer_period = 2000000 / speed; // 2Mhz timer 115 | dir_M1 = 1; 116 | SET(PORTB, 4); // DIR Motor 1 (Forward) 117 | } 118 | else 119 | { 120 | timer_period = 2000000 / -speed; 121 | dir_M1 = -1; 122 | CLR(PORTB, 4); // Dir Motor 1 123 | } 124 | if (timer_period > 65535) // Check for minimun speed (maximun period without overflow) 125 | timer_period = ZERO_SPEED; 126 | 127 | OCR1A = timer_period; 128 | // Check if we need to reset the timer... 129 | if (TCNT1 > OCR1A) 130 | TCNT1 = 0; 131 | } 132 | 133 | // Set speed of Stepper Motor2 134 | // tspeed could be positive or negative (reverse) 135 | void setMotorSpeedM2(int16_t tspeed) 136 | { 137 | long timer_period; 138 | int16_t speed; 139 | 140 | // Limit max speed? 141 | 142 | // WE LIMIT MAX ACCELERATION of the motors 143 | if ((speed_M2 - tspeed) > MAX_ACCEL) 144 | speed_M2 -= MAX_ACCEL; 145 | else if ((speed_M2 - tspeed) < -MAX_ACCEL) 146 | speed_M2 += MAX_ACCEL; 147 | else 148 | speed_M2 = tspeed; 149 | 150 | #if MICROSTEPPING==16 151 | speed = speed_M2 * 50; // Adjust factor from control output speed to real motor speed in steps/second 152 | #else 153 | speed = speed_M2 * 25; // 1/8 Microstepping 154 | #endif 155 | 156 | if (speed == 0) 157 | { 158 | timer_period = ZERO_SPEED; 159 | dir_M2 = 0; 160 | } 161 | else if (speed > 0) 162 | { 163 | timer_period = 2000000 / speed; // 2Mhz timer 164 | dir_M2 = 1; 165 | CLR(PORTC, 6); // Dir Motor2 (Forward) 166 | } 167 | else 168 | { 169 | timer_period = 2000000 / -speed; 170 | dir_M2 = -1; 171 | SET(PORTC, 6); // DIR Motor 2 172 | } 173 | if (timer_period > 65535) // Check for minimun speed (maximun period without overflow) 174 | timer_period = ZERO_SPEED; 175 | 176 | OCR3A = timer_period; 177 | // Check if we need to reset the timer... 178 | if (TCNT3 > OCR3A) 179 | TCNT3 = 0; 180 | } 181 | 182 | -------------------------------------------------------------------------------- /Blockly/python/server/webserver.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Blockly interface for BROBOT block programming 3 | 4 | # Remember to connect your wifi to your robot network JJROBOTS_XX password:8764321 5 | 6 | # author: JJROBOTS 2017 7 | # version: 1.01 (10/03/2017) 8 | # Licence: Open Source (GNU LGPLv3) 9 | 10 | from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer 11 | from os import curdir, sep 12 | import urlparse 13 | from BROBOT_Class import BROBOT 14 | import time 15 | import webbrowser 16 | import threading 17 | import socket 18 | 19 | # BROBOT initialization 20 | myRobot = BROBOT() 21 | IP = myRobot.UDP_IP 22 | PORT = myRobot.UDP_PORT 23 | 24 | HTTP2UDP_PORT = 8008 25 | PORT_NUMBER = 8080 26 | 27 | # Telemetry port 28 | UDP_PORT = 2223 29 | 30 | # Global variables 31 | global status 32 | global angle 33 | status = 0 34 | angle = 0.0 35 | 36 | # Class to launch servers on different threads 37 | class ServerThread(threading.Thread): 38 | def __init__(self,port,handler): 39 | threading.Thread.__init__(self) 40 | self.port=port 41 | self.handler = handler 42 | 43 | def run(self): 44 | server = HTTPServer(('localhost', self.port), self.handler) 45 | server.serve_forever() 46 | 47 | 48 | #Browser to handle HTTP to UDP conversion 49 | class HTTP2UDP(BaseHTTPRequestHandler): 50 | # Override address_string to avoid using name lookup 51 | def address_string(self): 52 | host, port = self.client_address[:2] 53 | #return socket.getfqdn(host) 54 | return host 55 | def do_GET(self): 56 | #print("GET request") 57 | self.send_response(200) 58 | self.send_header("Access-Control-Allow-Origin","*") 59 | self.send_header("Content-type", "text/html") 60 | self.end_headers() 61 | params = self.path 62 | params = params.split('?') 63 | if (len(params)>1): 64 | params = urlparse.parse_qs(params[1]) 65 | if 'IP' in params.keys(): 66 | print "IP: "+params['IP'][0] 67 | myRobot.UDP_IP = params['IP'][0] 68 | if 'PORT' in params.keys(): 69 | print "PORT: "+params['PORT'][0] 70 | myRobot.UDP_PORT = int(params['PORT'][0]) 71 | if 'ST' in params.keys(): 72 | #print params['ST'][0] 73 | myRobot.steering(int(params['ST'][0])/100.0) 74 | if 'TH' in params.keys(): 75 | #print params['TH'][0] 76 | myRobot.throttle(int(params['TH'][0])/100.0) 77 | if 'MV' in params.keys(): 78 | mvparams = params['MV'][0].split(",") 79 | #print mvparams[0]+" "+mvparams[1]+" "+mvparams[2] 80 | myRobot.move(int(mvparams[0]),int(mvparams[1]),int(mvparams[2])) 81 | if 'MO' in params.keys(): 82 | #print params['MO'][0] 83 | myRobot.mode(int(params['MO'][0])) 84 | if 'SE' in params.keys(): 85 | #print params['SE'][0] 86 | myRobot.servo(int(params['SE'][0])) 87 | if 'RS' in params.keys(): 88 | self.wfile.write(status) 89 | return 90 | if 'RA' in params.keys(): 91 | self.wfile.write(angle) 92 | return 93 | self.wfile.write('OK') 94 | return 95 | 96 | def log_request(self, code=None, size=None): 97 | pass # Do nothing... 98 | #print('Request') 99 | 100 | 101 | 102 | #This class will handles any incoming request from 103 | #the browser 104 | class myHandler(BaseHTTPRequestHandler): 105 | 106 | #Handler for the GET requests 107 | def do_GET(self): 108 | if self.path=="/": 109 | self.path="brobot/index.html" 110 | 111 | try: 112 | #Check the file extension required and 113 | #set the right mime type 114 | 115 | sendReply = False 116 | binary = False 117 | if self.path.endswith(".html"): 118 | mimetype='text/html' 119 | sendReply = True 120 | if self.path.endswith(".jpg"): 121 | binary = True 122 | mimetype='image/jpg' 123 | sendReply = True 124 | if self.path.endswith(".png"): 125 | binary = True 126 | mimetype='image/png' 127 | sendReply = True 128 | if self.path.endswith(".cur"): 129 | binary = True 130 | mimetype='image/x-win-bitmap' 131 | sendReply = True 132 | if self.path.endswith(".wav"): 133 | binary = True 134 | mimetype='audio/wav' 135 | sendReply = True 136 | if self.path.endswith(".mp3"): 137 | binary = True 138 | mimetype='audio/mpeg' 139 | sendReply = True 140 | if self.path.endswith(".gif"): 141 | binary = True 142 | mimetype='image/gif' 143 | sendReply = True 144 | if self.path.endswith(".js"): 145 | mimetype='application/javascript' 146 | sendReply = True 147 | if self.path.endswith(".css"): 148 | mimetype='text/css' 149 | sendReply = True 150 | 151 | if sendReply == True: 152 | #Open the static file requested and send it 153 | if binary: 154 | f = open(curdir + sep + self.path,'rb') 155 | else: 156 | f = open(curdir + sep + self.path) 157 | self.send_response(200) 158 | self.send_header('Content-type',mimetype) 159 | self.end_headers() 160 | self.wfile.write(f.read()) 161 | f.close() 162 | return 163 | 164 | except IOError: 165 | self.send_error(404,'File Not Found: %s' % self.path) 166 | 167 | try: 168 | #Create the HTTP to UDP server to send messages to robot 169 | ServerThread(HTTP2UDP_PORT,HTTP2UDP).start() 170 | #Create a web server and define the handler to manage the incoming requests 171 | ServerThread(PORT_NUMBER,myHandler).start() 172 | print "Started HTTP2UDP server on port ", HTTP2UDP_PORT 173 | print "Started httpserver on port " , PORT_NUMBER 174 | print "Opening browser... wait a moment..." 175 | time.sleep(2) 176 | url = "http://localhost:8080/brobot/index.html" 177 | webbrowser.open(url,new=2) 178 | while 1: 179 | pass 180 | 181 | except KeyboardInterrupt: 182 | print '^C received, shutting down the web server' 183 | exit() 184 | -------------------------------------------------------------------------------- /Blockly/brobot/generators/javascript/brobot.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Visual Blocks Language 4 | * 5 | * Copyright 2012 Google Inc. 6 | * https://developers.google.com/blockly/ 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | /** 22 | * @fileoverview Generating JavaScript for colour blocks. 23 | * @author fraser@google.com (Neil Fraser) 24 | */ 25 | 'use strict'; 26 | 27 | goog.provide('Blockly.JavaScript.brobot'); 28 | 29 | goog.require('Blockly.JavaScript'); 30 | 31 | 32 | Blockly.JavaScript['moveforward'] = function(block) { 33 | var code = "var datavalue='MV=50,'+(Math.round(STEPSMETER*0.4))+','+(Math.round(STEPSMETER*0.4));\n"; 34 | code += "$.ajax({url:'http://127.0.0.1:8008', data: datavalue});\n"; 35 | code += 'var dt = new Date();while ((new Date()) - dt <= 3700) {};\n'; // delay 36 | return code; 37 | }; 38 | 39 | Blockly.JavaScript['movebackward'] = function(block) { 40 | var code = "var datavalue='MV=50,'+(-Math.round(STEPSMETER*0.4))+','+(-Math.round(STEPSMETER*0.4));\n"; 41 | code += "$.ajax({url:'http://127.0.0.1:8008', data: datavalue});\n"; 42 | code += 'var dt = new Date();while ((new Date()) - dt <= 3700) {};\n'; // delay 43 | return code; 44 | }; 45 | 46 | Blockly.JavaScript['turnleft'] = function(block) { 47 | var code = "var datavalue='MV=50,'+(-Math.round(STEPSTURN/4))+','+(Math.round(STEPSTURN/4));\n"; 48 | code += "$.ajax({url:'http://127.0.0.1:8008', data: datavalue});\n"; 49 | code += 'var dt = new Date();while ((new Date()) - dt <= 2200) {};\n'; // delay 50 | return code; 51 | }; 52 | 53 | Blockly.JavaScript['turnright'] = function(block) { 54 | var code = "var datavalue='MV=50,'+(Math.round(STEPSTURN/4))+','+(-Math.round(STEPSTURN/4));\n"; 55 | code += "$.ajax({url:'http://127.0.0.1:8008', data: datavalue});\n"; 56 | code += 'var dt = new Date();while ((new Date()) - dt <= 2200) {};\n'; // delay 57 | return code; 58 | }; 59 | 60 | Blockly.JavaScript['turn180'] = function(block) { 61 | var value = block.getFieldValue('turn'); 62 | var code; 63 | if (value==1) 64 | code = "var datavalue='MV=50,'+(-Math.round(STEPSTURN/2))+','+(Math.round(STEPSTURN/2));\n"; 65 | else 66 | code = "var datavalue='MV=50,'+(Math.round(STEPSTURN/2))+','+(-Math.round(STEPSTURN/2));\n"; 67 | code += "$.ajax({url:'http://127.0.0.1:8008', data: datavalue});\n"; 68 | code += 'var dt = new Date();while ((new Date()) - dt <= 3600) {};\n'; // delay 69 | return code; 70 | }; 71 | 72 | Blockly.JavaScript['spin360'] = function(block) { 73 | var value = block.getFieldValue('spin'); 74 | var code; 75 | if (value==1) 76 | code = "var datavalue='MV=50,'+(-Math.round(STEPSTURN))+','+(Math.round(STEPSTURN));\n"; 77 | else 78 | code = "var datavalue='MV=50,'+(Math.round(STEPSTURN))+','+(-Math.round(STEPSTURN));\n"; 79 | code += "$.ajax({url:'http://127.0.0.1:8008', data: datavalue});\n"; 80 | code += 'var dt = new Date();while ((new Date()) - dt <= 5400) {};\n'; // delay 81 | return code; 82 | }; 83 | 84 | Blockly.JavaScript['movesimple'] = function(block) { 85 | var value = Blockly.JavaScript.valueToCode(block, 'cm', Blockly.JavaScript.ORDER_ATOMIC); 86 | var value2 = block.getFieldValue('move'); 87 | var code; 88 | if (value2 == 0) 89 | code = "var datavalue='MV=50,"+(Math.round(value*STEPSMETER/100))+","+(Math.round(value*STEPSMETER/100))+"';\n"; 90 | else 91 | code = "var datavalue='MV=50,"+(-Math.round(value*STEPSMETER/100))+","+(-Math.round(value*STEPSMETER/100))+"';\n"; 92 | code += "$.ajax({url:'http://127.0.0.1:8008', data: datavalue});\n"; 93 | var delay = 51*Math.abs(value) + 1200; 94 | code += 'var dt = new Date();while ((new Date()) - dt <= '+delay+') {};\n'; // delay 95 | return code; 96 | }; 97 | 98 | Blockly.JavaScript['turndegrees'] = function(block) { 99 | var value = Blockly.JavaScript.valueToCode(block, 'degrees', Blockly.JavaScript.ORDER_ATOMIC); 100 | var value2 = block.getFieldValue('turn'); 101 | var code; 102 | if (value2 == 1) 103 | code = "var datavalue='MV=50,"+(-Math.round(value*STEPSTURN/360))+","+(Math.round(value*STEPSTURN/360))+"';\n"; 104 | else 105 | code = "var datavalue='MV=50,"+(Math.round(value*STEPSTURN/360))+","+(-Math.round(value*STEPSTURN/360))+"';\n"; 106 | code += "$.ajax({url:'http://127.0.0.1:8008', data: datavalue});\n"; 107 | var delay = 16*Math.abs(value)+700; 108 | code += 'var dt = new Date();while ((new Date()) - dt <= '+delay+') {};\n'; // delay 109 | return code; 110 | }; 111 | 112 | Blockly.JavaScript['robotconfig'] = function(block) { 113 | var IPvalue = Blockly.JavaScript.valueToCode(block, 'IPvalue', Blockly.JavaScript.ORDER_ATOMIC).replace(/'/g, ""); 114 | //var PORTvalue = Blockly.JavaScript.valueToCode(block, 'PORTvalue', Blockly.JavaScript.ORDER_ATOMIC).replace(/'/g, ""); 115 | var PORTvalue = "2222" 116 | var code = '//Robot Initialization\n\n'; 117 | code += "$.ajax({url:'http://127.0.0.1:8008', data:\"IP="+ IPvalue+"&PORT="+PORTvalue+"\"});\n"; 118 | return code; 119 | } 120 | 121 | Blockly.JavaScript['throttle'] = function(block) { 122 | var value = Blockly.JavaScript.valueToCode(block, 'TValue', Blockly.JavaScript.ORDER_ATOMIC); 123 | var code = "var datavalue='TH='+"+value+";\n"; 124 | code += "$.ajax({url:'http://127.0.0.1:8008', data: datavalue});\n"; 125 | return code; 126 | }; 127 | 128 | Blockly.JavaScript['steering'] = function(block) { 129 | var value = Blockly.JavaScript.valueToCode(block, 'SValue', Blockly.JavaScript.ORDER_ATOMIC); 130 | var code = "var datavalue='ST='+"+value+";\n"; 131 | code += "$.ajax({url:'http://127.0.0.1:8008', data: datavalue});\n"; 132 | return code; 133 | }; 134 | 135 | Blockly.JavaScript['servo'] = function(block) { 136 | //var value = Blockly.JavaScript.valueToCode(block, 'SValue', Blockly.JavaScript.ORDER_ATOMIC);// 137 | var value = block.getFieldValue('Servo'); 138 | // TODO: Assemble JavaScript into code variable. 139 | var code = "$.ajax({url:'http://127.0.0.1:8008', data:'SE="+ value+"'});\n"; 140 | return code; 141 | }; 142 | 143 | Blockly.JavaScript['mode'] = function(block) { 144 | //var value = Blockly.JavaScript.valueToCode(block, 'SValue', Blockly.JavaScript.ORDER_ATOMIC);// 145 | var value = block.getFieldValue('Mode'); 146 | // TODO: Assemble JavaScript into code variable. 147 | var code = "$.ajax({url:'http://127.0.0.1:8008', data:'MO="+ value+"'});\n"; 148 | return code; 149 | }; 150 | 151 | Blockly.JavaScript['delay'] = function(block) { 152 | //var value = Blockly.JavaScript.valueToCode(block, 'SValue', Blockly.JavaScript.ORDER_ATOMIC);// 153 | var value = block.getFieldValue('DValue')*1000; 154 | // TODO: Assemble JavaScript into code variable. 155 | //var code = 'window.alert(delay'+value+');\n'; 156 | var end = 0; 157 | var code = 'var dt = new Date();while ((new Date()) - dt <= '+value+') {};\n'; 158 | return code; 159 | }; 160 | 161 | 162 | -------------------------------------------------------------------------------- /Blockly/brobot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | BROBOT Block programming 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 36 | 41 | 42 | 43 | 44 | 68 | 69 | 70 | 72 | 73 |
33 | 34 | 35 | 37 |

BROBOT Block Programming v0.8

38 | 39 | 40 |
45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 65 | 66 |
... JavaScript Python XML 55 | 58 | 61 | 64 |
67 |
71 |
74 |
75 |

 76 |   

 77 |   
 78 | 
 79 |   
210 | 
211 |   
212 |

Remember to connect your PC/laptop to to your B-Robot Wifi network! (JJROBOTS_xx, password:87654321)

213 |
214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /Blockly/brobot/generators/python/loops.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Visual Blocks Language 4 | * 5 | * Copyright 2012 Google Inc. 6 | * https://developers.google.com/blockly/ 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | /** 22 | * @fileoverview Generating Python for loop blocks. 23 | * @author q.neutron@gmail.com (Quynh Neutron) 24 | */ 25 | 'use strict'; 26 | 27 | goog.provide('Blockly.Python.loops'); 28 | 29 | goog.require('Blockly.Python'); 30 | 31 | 32 | Blockly.Python['controls_repeat_ext'] = function(block) { 33 | // Repeat n times. 34 | if (block.getField('TIMES')) { 35 | // Internal number. 36 | var repeats = String(parseInt(block.getFieldValue('TIMES'), 10)); 37 | } else { 38 | // External number. 39 | var repeats = Blockly.Python.valueToCode(block, 'TIMES', 40 | Blockly.Python.ORDER_NONE) || '0'; 41 | } 42 | if (Blockly.isNumber(repeats)) { 43 | repeats = parseInt(repeats, 10); 44 | } else { 45 | repeats = 'int(' + repeats + ')'; 46 | } 47 | var branch = Blockly.Python.statementToCode(block, 'DO'); 48 | branch = Blockly.Python.addLoopTrap(branch, block.id) || 49 | Blockly.Python.PASS; 50 | var loopVar = Blockly.Python.variableDB_.getDistinctName( 51 | 'count', Blockly.Variables.NAME_TYPE); 52 | var code = 'for ' + loopVar + ' in range(' + repeats + '):\n' + branch; 53 | return code; 54 | }; 55 | 56 | Blockly.Python['controls_repeat'] = Blockly.Python['controls_repeat_ext']; 57 | 58 | Blockly.Python['controls_whileUntil'] = function(block) { 59 | // Do while/until loop. 60 | var until = block.getFieldValue('MODE') == 'UNTIL'; 61 | var argument0 = Blockly.Python.valueToCode(block, 'BOOL', 62 | until ? Blockly.Python.ORDER_LOGICAL_NOT : 63 | Blockly.Python.ORDER_NONE) || 'False'; 64 | var branch = Blockly.Python.statementToCode(block, 'DO'); 65 | branch = Blockly.Python.addLoopTrap(branch, block.id) || 66 | Blockly.Python.PASS; 67 | if (until) { 68 | argument0 = 'not ' + argument0; 69 | } 70 | return 'while ' + argument0 + ':\n' + branch; 71 | }; 72 | 73 | Blockly.Python['controls_for'] = function(block) { 74 | // For loop. 75 | var variable0 = Blockly.Python.variableDB_.getName( 76 | block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE); 77 | var argument0 = Blockly.Python.valueToCode(block, 'FROM', 78 | Blockly.Python.ORDER_NONE) || '0'; 79 | var argument1 = Blockly.Python.valueToCode(block, 'TO', 80 | Blockly.Python.ORDER_NONE) || '0'; 81 | var increment = Blockly.Python.valueToCode(block, 'BY', 82 | Blockly.Python.ORDER_NONE) || '1'; 83 | var branch = Blockly.Python.statementToCode(block, 'DO'); 84 | branch = Blockly.Python.addLoopTrap(branch, block.id) || 85 | Blockly.Python.PASS; 86 | 87 | var code = ''; 88 | var range; 89 | 90 | // Helper functions. 91 | var defineUpRange = function() { 92 | return Blockly.Python.provideFunction_( 93 | 'upRange', 94 | ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + 95 | '(start, stop, step):', 96 | ' while start <= stop:', 97 | ' yield start', 98 | ' start += abs(step)']); 99 | }; 100 | var defineDownRange = function() { 101 | return Blockly.Python.provideFunction_( 102 | 'downRange', 103 | ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + 104 | '(start, stop, step):', 105 | ' while start >= stop:', 106 | ' yield start', 107 | ' start -= abs(step)']); 108 | }; 109 | // Arguments are legal Python code (numbers or strings returned by scrub()). 110 | var generateUpDownRange = function(start, end, inc) { 111 | return '(' + start + ' <= ' + end + ') and ' + 112 | defineUpRange() + '(' + start + ', ' + end + ', ' + inc + ') or ' + 113 | defineDownRange() + '(' + start + ', ' + end + ', ' + inc + ')'; 114 | }; 115 | 116 | if (Blockly.isNumber(argument0) && Blockly.isNumber(argument1) && 117 | Blockly.isNumber(increment)) { 118 | // All parameters are simple numbers. 119 | argument0 = parseFloat(argument0); 120 | argument1 = parseFloat(argument1); 121 | increment = Math.abs(parseFloat(increment)); 122 | if (argument0 % 1 === 0 && argument1 % 1 === 0 && increment % 1 === 0) { 123 | // All parameters are integers. 124 | if (argument0 <= argument1) { 125 | // Count up. 126 | argument1++; 127 | if (argument0 == 0 && increment == 1) { 128 | // If starting index is 0, omit it. 129 | range = argument1; 130 | } else { 131 | range = argument0 + ', ' + argument1; 132 | } 133 | // If increment isn't 1, it must be explicit. 134 | if (increment != 1) { 135 | range += ', ' + increment; 136 | } 137 | } else { 138 | // Count down. 139 | argument1--; 140 | range = argument0 + ', ' + argument1 + ', -' + increment; 141 | } 142 | range = 'range(' + range + ')'; 143 | } else { 144 | // At least one of the parameters is not an integer. 145 | if (argument0 < argument1) { 146 | range = defineUpRange(); 147 | } else { 148 | range = defineDownRange(); 149 | } 150 | range += '(' + argument0 + ', ' + argument1 + ', ' + increment + ')'; 151 | } 152 | } else { 153 | // Cache non-trivial values to variables to prevent repeated look-ups. 154 | var scrub = function(arg, suffix) { 155 | if (Blockly.isNumber(arg)) { 156 | // Simple number. 157 | arg = parseFloat(arg); 158 | } else if (arg.match(/^\w+$/)) { 159 | // Variable. 160 | arg = 'float(' + arg + ')'; 161 | } else { 162 | // It's complicated. 163 | var varName = Blockly.Python.variableDB_.getDistinctName( 164 | variable0 + suffix, Blockly.Variables.NAME_TYPE); 165 | code += varName + ' = float(' + arg + ')\n'; 166 | arg = varName; 167 | } 168 | return arg; 169 | }; 170 | var startVar = scrub(argument0, '_start'); 171 | var endVar = scrub(argument1, '_end'); 172 | var incVar = scrub(increment, '_inc'); 173 | 174 | if (typeof startVar == 'number' && typeof endVar == 'number') { 175 | if (startVar < endVar) { 176 | range = defineUpRange(startVar, endVar, increment); 177 | } else { 178 | range = defineDownRange(startVar, endVar, increment); 179 | } 180 | } else { 181 | // We cannot determine direction statically. 182 | range = generateUpDownRange(startVar, endVar, increment); 183 | } 184 | } 185 | code += 'for ' + variable0 + ' in ' + range + ':\n' + branch; 186 | return code; 187 | }; 188 | 189 | Blockly.Python['controls_forEach'] = function(block) { 190 | // For each loop. 191 | var variable0 = Blockly.Python.variableDB_.getName( 192 | block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE); 193 | var argument0 = Blockly.Python.valueToCode(block, 'LIST', 194 | Blockly.Python.ORDER_RELATIONAL) || '[]'; 195 | var branch = Blockly.Python.statementToCode(block, 'DO'); 196 | branch = Blockly.Python.addLoopTrap(branch, block.id) || 197 | Blockly.Python.PASS; 198 | var code = 'for ' + variable0 + ' in ' + argument0 + ':\n' + branch; 199 | return code; 200 | }; 201 | 202 | Blockly.Python['controls_flow_statements'] = function(block) { 203 | // Flow statements: continue, break. 204 | switch (block.getFieldValue('FLOW')) { 205 | case 'BREAK': 206 | return 'break\n'; 207 | case 'CONTINUE': 208 | return 'continue\n'; 209 | } 210 | throw 'Unknown flow statement.'; 211 | }; 212 | -------------------------------------------------------------------------------- /Blockly/brobot/msg/json/en-gb.json: -------------------------------------------------------------------------------- 1 | { 2 | "@metadata": { 3 | "authors": [ 4 | "Andibing", 5 | "Codynguyen1116", 6 | "Shirayuki" 7 | ] 8 | }, 9 | "VARIABLES_DEFAULT_NAME": "item", 10 | "TODAY": "Today", 11 | "DUPLICATE_BLOCK": "Duplicate", 12 | "ADD_COMMENT": "Add Comment", 13 | "REMOVE_COMMENT": "Remove Comment", 14 | "EXTERNAL_INPUTS": "External Inputs", 15 | "INLINE_INPUTS": "Inline Inputs", 16 | "DELETE_BLOCK": "Delete Block", 17 | "DELETE_X_BLOCKS": "Delete %1 Blocks", 18 | "DELETE_ALL_BLOCKS": "Delete all %1 blocks?", 19 | "CLEAN_UP": "Clean up Blocks", 20 | "COLLAPSE_BLOCK": "Collapse Block", 21 | "COLLAPSE_ALL": "Collapse Blocks", 22 | "EXPAND_BLOCK": "Expand Block", 23 | "EXPAND_ALL": "Expand Blocks", 24 | "DISABLE_BLOCK": "Disable Block", 25 | "ENABLE_BLOCK": "Enable Block", 26 | "HELP": "Help", 27 | "UNDO": "Undo", 28 | "REDO": "Redo", 29 | "CHANGE_VALUE_TITLE": "Change value:", 30 | "RENAME_VARIABLE": "Rename variable...", 31 | "RENAME_VARIABLE_TITLE": "Rename all '%1' variables to:", 32 | "NEW_VARIABLE": "New variable...", 33 | "NEW_VARIABLE_TITLE": "New variable name:", 34 | "COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Colour", 35 | "COLOUR_PICKER_TOOLTIP": "Choose a colour from the palette.", 36 | "COLOUR_RANDOM_TITLE": "random colour", 37 | "COLOUR_RANDOM_TOOLTIP": "Choose a colour at random.", 38 | "COLOUR_RGB_TITLE": "colour with", 39 | "COLOUR_RGB_RED": "red", 40 | "COLOUR_RGB_GREEN": "green", 41 | "COLOUR_RGB_BLUE": "blue", 42 | "COLOUR_RGB_TOOLTIP": "Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.", 43 | "COLOUR_BLEND_TITLE": "blend", 44 | "COLOUR_BLEND_COLOUR1": "colour 1", 45 | "COLOUR_BLEND_COLOUR2": "colour 2", 46 | "COLOUR_BLEND_RATIO": "ratio", 47 | "COLOUR_BLEND_TOOLTIP": "Blends two colours together with a given ratio (0.0 - 1.0).", 48 | "CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop", 49 | "CONTROLS_REPEAT_TITLE": "repeat %1 times", 50 | "CONTROLS_REPEAT_INPUT_DO": "do", 51 | "CONTROLS_REPEAT_TOOLTIP": "Do some statements several times.", 52 | "CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "repeat while", 53 | "CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "repeat until", 54 | "CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "While a value is true, then do some statements.", 55 | "CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "While a value is false, then do some statements.", 56 | "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.", 57 | "CONTROLS_FOR_TITLE": "count with %1 from %2 to %3 by %4", 58 | "CONTROLS_FOREACH_TITLE": "for each item %1 in list %2", 59 | "CONTROLS_FOREACH_TOOLTIP": "For each item in a list, set the variable '%1' to the item, and then do some statements.", 60 | "CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "break out of loop", 61 | "CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "continue with next iteration of loop", 62 | "CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Break out of the containing loop.", 63 | "CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Skip the rest of this loop, and continue with the next iteration.", 64 | "CONTROLS_FLOW_STATEMENTS_WARNING": "Warning: This block may only be used within a loop.", 65 | "CONTROLS_IF_TOOLTIP_1": "If a value is true, then do some statements.", 66 | "CONTROLS_IF_TOOLTIP_2": "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.", 67 | "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.", 68 | "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.", 69 | "CONTROLS_IF_MSG_IF": "if", 70 | "CONTROLS_IF_MSG_ELSEIF": "else if", 71 | "CONTROLS_IF_MSG_ELSE": "else", 72 | "CONTROLS_IF_IF_TOOLTIP": "Add, remove, or reorder sections to reconfigure this if block.", 73 | "CONTROLS_IF_ELSEIF_TOOLTIP": "Add a condition to the if block.", 74 | "CONTROLS_IF_ELSE_TOOLTIP": "Add a final, catch-all condition to the if block.", 75 | "LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)", 76 | "LOGIC_COMPARE_TOOLTIP_EQ": "Return true if both inputs equal each other.", 77 | "LOGIC_COMPARE_TOOLTIP_NEQ": "Return true if both inputs are not equal to each other.", 78 | "LOGIC_COMPARE_TOOLTIP_LT": "Return true if the first input is smaller than the second input.", 79 | "LOGIC_COMPARE_TOOLTIP_LTE": "Return true if the first input is smaller than or equal to the second input.", 80 | "LOGIC_COMPARE_TOOLTIP_GT": "Return true if the first input is greater than the second input.", 81 | "LOGIC_COMPARE_TOOLTIP_GTE": "Return true if the first input is greater than or equal to the second input.", 82 | "LOGIC_OPERATION_TOOLTIP_AND": "Return true if both inputs are true.", 83 | "LOGIC_OPERATION_AND": "and", 84 | "LOGIC_OPERATION_TOOLTIP_OR": "Return true if at least one of the inputs is true.", 85 | "LOGIC_OPERATION_OR": "or", 86 | "LOGIC_NEGATE_TITLE": "not %1", 87 | "LOGIC_NEGATE_TOOLTIP": "Returns true if the input is false. Returns false if the input is true.", 88 | "LOGIC_BOOLEAN_TRUE": "true", 89 | "LOGIC_BOOLEAN_FALSE": "false", 90 | "LOGIC_BOOLEAN_TOOLTIP": "Returns either true or false.", 91 | "LOGIC_NULL": "null", 92 | "LOGIC_NULL_TOOLTIP": "Returns null.", 93 | "LOGIC_TERNARY_CONDITION": "test", 94 | "LOGIC_TERNARY_IF_TRUE": "if true", 95 | "LOGIC_TERNARY_IF_FALSE": "if false", 96 | "LOGIC_TERNARY_TOOLTIP": "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.", 97 | "MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number", 98 | "MATH_NUMBER_TOOLTIP": "A number.", 99 | "MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic", 100 | "MATH_ARITHMETIC_TOOLTIP_ADD": "Return the sum of the two numbers.", 101 | "MATH_ARITHMETIC_TOOLTIP_MINUS": "Return the difference of the two numbers.", 102 | "MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Return the product of the two numbers.", 103 | "MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Return the quotient of the two numbers.", 104 | "MATH_ARITHMETIC_TOOLTIP_POWER": "Return the first number raised to the power of the second number.", 105 | "MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root", 106 | "MATH_SINGLE_OP_ROOT": "square root", 107 | "MATH_SINGLE_TOOLTIP_ROOT": "Return the square root of a number.", 108 | "MATH_SINGLE_OP_ABSOLUTE": "absolute", 109 | "MATH_SINGLE_TOOLTIP_ABS": "Return the absolute value of a number.", 110 | "MATH_SINGLE_TOOLTIP_NEG": "Return the negation of a number.", 111 | "MATH_SINGLE_TOOLTIP_LN": "Return the natural logarithm of a number.", 112 | "MATH_SINGLE_TOOLTIP_LOG10": "Return the base 10 logarithm of a number.", 113 | "MATH_SINGLE_TOOLTIP_EXP": "Return e to the power of a number.", 114 | "MATH_SINGLE_TOOLTIP_POW10": "Return 10 to the power of a number.", 115 | "MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions", 116 | "MATH_TRIG_TOOLTIP_SIN": "Return the sine of a degree (not radian).", 117 | "MATH_TRIG_TOOLTIP_COS": "Return the cosine of a degree (not radian).", 118 | "MATH_TRIG_TOOLTIP_TAN": "Return the tangent of a degree (not radian).", 119 | "MATH_TRIG_TOOLTIP_ASIN": "Return the arcsine of a number.", 120 | "MATH_TRIG_TOOLTIP_ACOS": "Return the arccosine of a number.", 121 | "MATH_TRIG_TOOLTIP_ATAN": "Return the arctangent of a number.", 122 | "MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant", 123 | "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).", 124 | "MATH_IS_EVEN": "is even", 125 | "MATH_IS_ODD": "is odd", 126 | "MATH_IS_PRIME": "is prime", 127 | "MATH_IS_WHOLE": "is whole", 128 | "MATH_IS_POSITIVE": "is positive", 129 | "MATH_IS_NEGATIVE": "is negative", 130 | "MATH_IS_DIVISIBLE_BY": "is divisible by", 131 | "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.", 132 | "MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter", 133 | "MATH_CHANGE_TITLE": "change %1 by %2", 134 | "MATH_CHANGE_TOOLTIP": "Add a number to variable '%1'.", 135 | "MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding", 136 | "MATH_ROUND_TOOLTIP": "Round a number up or down.", 137 | "MATH_ROUND_OPERATOR_ROUND": "round", 138 | "LISTS_SORT_ORDER_DESCENDING": "descendente" 139 | } 140 | -------------------------------------------------------------------------------- /Blockly/brobot/generators/python/text.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Visual Blocks Language 4 | * 5 | * Copyright 2012 Google Inc. 6 | * https://developers.google.com/blockly/ 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | /** 22 | * @fileoverview Generating Python for text blocks. 23 | * @author q.neutron@gmail.com (Quynh Neutron) 24 | */ 25 | 'use strict'; 26 | 27 | goog.provide('Blockly.Python.texts'); 28 | 29 | goog.require('Blockly.Python'); 30 | 31 | 32 | Blockly.Python['text'] = function(block) { 33 | // Text value. 34 | var code = Blockly.Python.quote_(block.getFieldValue('TEXT')); 35 | return [code, Blockly.Python.ORDER_ATOMIC]; 36 | }; 37 | 38 | Blockly.Python['text_join'] = function(block) { 39 | // Create a string made up of any number of elements of any type. 40 | //Should we allow joining by '-' or ',' or any other characters? 41 | switch (block.itemCount_) { 42 | case 0: 43 | return ['\'\'', Blockly.Python.ORDER_ATOMIC]; 44 | break; 45 | case 1: 46 | var element = Blockly.Python.valueToCode(block, 'ADD0', 47 | Blockly.Python.ORDER_NONE) || '\'\''; 48 | var code = 'str(' + element + ')'; 49 | return [code, Blockly.Python.ORDER_FUNCTION_CALL]; 50 | break; 51 | case 2: 52 | var element0 = Blockly.Python.valueToCode(block, 'ADD0', 53 | Blockly.Python.ORDER_NONE) || '\'\''; 54 | var element1 = Blockly.Python.valueToCode(block, 'ADD1', 55 | Blockly.Python.ORDER_NONE) || '\'\''; 56 | var code = 'str(' + element0 + ') + str(' + element1 + ')'; 57 | return [code, Blockly.Python.ORDER_ADDITIVE]; 58 | break; 59 | default: 60 | var elements = []; 61 | for (var i = 0; i < block.itemCount_; i++) { 62 | elements[i] = Blockly.Python.valueToCode(block, 'ADD' + i, 63 | Blockly.Python.ORDER_NONE) || '\'\''; 64 | } 65 | var tempVar = Blockly.Python.variableDB_.getDistinctName('x', 66 | Blockly.Variables.NAME_TYPE); 67 | var code = '\'\'.join([str(' + tempVar + ') for ' + tempVar + ' in [' + 68 | elements.join(', ') + ']])'; 69 | return [code, Blockly.Python.ORDER_FUNCTION_CALL]; 70 | } 71 | }; 72 | 73 | Blockly.Python['text_append'] = function(block) { 74 | // Append to a variable in place. 75 | var varName = Blockly.Python.variableDB_.getName(block.getFieldValue('VAR'), 76 | Blockly.Variables.NAME_TYPE); 77 | var value = Blockly.Python.valueToCode(block, 'TEXT', 78 | Blockly.Python.ORDER_NONE) || '\'\''; 79 | return varName + ' = str(' + varName + ') + str(' + value + ')\n'; 80 | }; 81 | 82 | Blockly.Python['text_length'] = function(block) { 83 | // Is the string null or array empty? 84 | var text = Blockly.Python.valueToCode(block, 'VALUE', 85 | Blockly.Python.ORDER_NONE) || '\'\''; 86 | return ['len(' + text + ')', Blockly.Python.ORDER_FUNCTION_CALL]; 87 | }; 88 | 89 | Blockly.Python['text_isEmpty'] = function(block) { 90 | // Is the string null or array empty? 91 | var text = Blockly.Python.valueToCode(block, 'VALUE', 92 | Blockly.Python.ORDER_NONE) || '\'\''; 93 | var code = 'not len(' + text + ')'; 94 | return [code, Blockly.Python.ORDER_LOGICAL_NOT]; 95 | }; 96 | 97 | Blockly.Python['text_indexOf'] = function(block) { 98 | // Search the text for a substring. 99 | // Should we allow for non-case sensitive??? 100 | var operator = block.getFieldValue('END') == 'FIRST' ? 'find' : 'rfind'; 101 | var substring = Blockly.Python.valueToCode(block, 'FIND', 102 | Blockly.Python.ORDER_NONE) || '\'\''; 103 | var text = Blockly.Python.valueToCode(block, 'VALUE', 104 | Blockly.Python.ORDER_MEMBER) || '\'\''; 105 | var code = text + '.' + operator + '(' + substring + ')'; 106 | if (block.workspace.options.oneBasedIndex) { 107 | return [code + ' + 1', Blockly.Python.ORDER_ADDITIVE]; 108 | } 109 | return [code, Blockly.Python.ORDER_FUNCTION_CALL]; 110 | }; 111 | 112 | Blockly.Python['text_charAt'] = function(block) { 113 | // Get letter at index. 114 | // Note: Until January 2013 this block did not have the WHERE input. 115 | var where = block.getFieldValue('WHERE') || 'FROM_START'; 116 | var text = Blockly.Python.valueToCode(block, 'VALUE', 117 | Blockly.Python.ORDER_MEMBER) || '\'\''; 118 | switch (where) { 119 | case 'FIRST': 120 | var code = text + '[0]'; 121 | return [code, Blockly.Python.ORDER_MEMBER]; 122 | case 'LAST': 123 | var code = text + '[-1]'; 124 | return [code, Blockly.Python.ORDER_MEMBER]; 125 | case 'FROM_START': 126 | var at = Blockly.Python.getAdjustedInt(block, 'AT'); 127 | var code = text + '[' + at + ']'; 128 | return [code, Blockly.Python.ORDER_MEMBER]; 129 | case 'FROM_END': 130 | var at = Blockly.Python.getAdjustedInt(block, 'AT', 1, true); 131 | var code = text + '[' + at + ']'; 132 | return [code, Blockly.Python.ORDER_MEMBER]; 133 | case 'RANDOM': 134 | Blockly.Python.definitions_['import_random'] = 'import random'; 135 | var functionName = Blockly.Python.provideFunction_( 136 | 'text_random_letter', 137 | ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(text):', 138 | ' x = int(random.random() * len(text))', 139 | ' return text[x];']); 140 | code = functionName + '(' + text + ')'; 141 | return [code, Blockly.Python.ORDER_FUNCTION_CALL]; 142 | } 143 | throw 'Unhandled option (text_charAt).'; 144 | }; 145 | 146 | Blockly.Python['text_getSubstring'] = function(block) { 147 | // Get substring. 148 | var where1 = block.getFieldValue('WHERE1'); 149 | var where2 = block.getFieldValue('WHERE2'); 150 | var text = Blockly.Python.valueToCode(block, 'STRING', 151 | Blockly.Python.ORDER_MEMBER) || '\'\''; 152 | switch (where1) { 153 | case 'FROM_START': 154 | var at1 = Blockly.Python.getAdjustedInt(block, 'AT1'); 155 | if (at1 == '0') { 156 | at1 = ''; 157 | } 158 | break; 159 | case 'FROM_END': 160 | var at1 = Blockly.Python.getAdjustedInt(block, 'AT1', 1, true); 161 | break; 162 | case 'FIRST': 163 | var at1 = ''; 164 | break; 165 | default: 166 | throw 'Unhandled option (text_getSubstring)'; 167 | } 168 | switch (where2) { 169 | case 'FROM_START': 170 | var at2 = Blockly.Python.getAdjustedInt(block, 'AT2', 1); 171 | break; 172 | case 'FROM_END': 173 | var at2 = Blockly.Python.getAdjustedInt(block, 'AT2', 0, true); 174 | // Ensure that if the result calculated is 0 that sub-sequence will 175 | // include all elements as expected. 176 | if (!Blockly.isNumber(String(at2))) { 177 | Blockly.Python.definitions_['import_sys'] = 'import sys'; 178 | at2 += ' or sys.maxsize'; 179 | } else if (at2 == '0') { 180 | at2 = ''; 181 | } 182 | break; 183 | case 'LAST': 184 | var at2 = ''; 185 | break; 186 | default: 187 | throw 'Unhandled option (text_getSubstring)'; 188 | } 189 | var code = text + '[' + at1 + ' : ' + at2 + ']'; 190 | return [code, Blockly.Python.ORDER_MEMBER]; 191 | }; 192 | 193 | Blockly.Python['text_changeCase'] = function(block) { 194 | // Change capitalization. 195 | var OPERATORS = { 196 | 'UPPERCASE': '.upper()', 197 | 'LOWERCASE': '.lower()', 198 | 'TITLECASE': '.title()' 199 | }; 200 | var operator = OPERATORS[block.getFieldValue('CASE')]; 201 | var text = Blockly.Python.valueToCode(block, 'TEXT', 202 | Blockly.Python.ORDER_MEMBER) || '\'\''; 203 | var code = text + operator; 204 | return [code, Blockly.Python.ORDER_FUNCTION_CALL]; 205 | }; 206 | 207 | Blockly.Python['text_trim'] = function(block) { 208 | // Trim spaces. 209 | var OPERATORS = { 210 | 'LEFT': '.lstrip()', 211 | 'RIGHT': '.rstrip()', 212 | 'BOTH': '.strip()' 213 | }; 214 | var operator = OPERATORS[block.getFieldValue('MODE')]; 215 | var text = Blockly.Python.valueToCode(block, 'TEXT', 216 | Blockly.Python.ORDER_MEMBER) || '\'\''; 217 | var code = text + operator; 218 | return [code, Blockly.Python.ORDER_FUNCTION_CALL]; 219 | }; 220 | 221 | Blockly.Python['text_print'] = function(block) { 222 | // Print statement. 223 | var msg = Blockly.Python.valueToCode(block, 'TEXT', 224 | Blockly.Python.ORDER_NONE) || '\'\''; 225 | return 'print(' + msg + ')\n'; 226 | }; 227 | 228 | Blockly.Python['text_prompt_ext'] = function(block) { 229 | // Prompt function. 230 | var functionName = Blockly.Python.provideFunction_( 231 | 'text_prompt', 232 | ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(msg):', 233 | ' try:', 234 | ' return raw_input(msg)', 235 | ' except NameError:', 236 | ' return input(msg)']); 237 | if (block.getField('TEXT')) { 238 | // Internal message. 239 | var msg = Blockly.Python.quote_(block.getFieldValue('TEXT')); 240 | } else { 241 | // External message. 242 | var msg = Blockly.Python.valueToCode(block, 'TEXT', 243 | Blockly.Python.ORDER_NONE) || '\'\''; 244 | } 245 | var code = functionName + '(' + msg + ')'; 246 | var toNumber = block.getFieldValue('TYPE') == 'NUMBER'; 247 | if (toNumber) { 248 | code = 'float(' + code + ')'; 249 | } 250 | return [code, Blockly.Python.ORDER_FUNCTION_CALL]; 251 | }; 252 | 253 | Blockly.Python['text_prompt'] = Blockly.Python['text_prompt_ext']; 254 | -------------------------------------------------------------------------------- /Arduino/BROBOT_EVO2/OSC.ino: -------------------------------------------------------------------------------- 1 | // BROBOT EVO 2 by JJROBOTS 2 | // SELF BALANCE ARDUINO ROBOT WITH STEPPER MOTORS 3 | // License: GPL v2 4 | // OSC functions (OSC = Open Sound Control protocol) 5 | 6 | // OSC Messages read: OSC: /page/command parameters 7 | // FADER (1,2,3,4) Ex: /1/fader1 f, XXXX => lenght:20, Param: float (0.0-1.0) 8 | // XY (1,2) Ex: /1/xy1 f,f, XXXXXXXX => length: 24 Params: float,float (0.0-1.0) 9 | // PUSH (1,2,3,4) Ex: /1/push1 f, XXXX => length:20 Param: float 10 | // TOGGLE (1,2,3,4) Ex: /1/toggle1 f, XXXX => length:20 Param: float 11 | // MOVE Ex: /1/m XXXX XXXX XXXX => length:16 Params: speed, steps1, steps2 (all float) 12 | // 13 | // OSC Message send: 14 | // string to send + param (float)[last 4 bytes] 15 | 16 | 17 | // for DEBUG uncomment this lines... 18 | //#define OSCDEBUG 0 19 | 20 | 21 | char UDPBuffer[8]; // input message buffer 22 | 23 | // OSC message internal variables 24 | unsigned char OSCreadStatus; 25 | unsigned char OSCreadCounter; 26 | unsigned char OSCreadNumParams; 27 | unsigned char OSCcommandType; 28 | unsigned char OSCtouchMessage; 29 | 30 | 31 | // ------- OSC functions ----------------------------------------- 32 | 33 | // Aux functions 34 | float OSC_extractParamFloat(uint8_t pos) { 35 | union { 36 | unsigned char Buff[4]; 37 | float d; 38 | } u; 39 | 40 | u.Buff[0] = (unsigned char)UDPBuffer[pos]; 41 | u.Buff[1] = (unsigned char)UDPBuffer[pos + 1]; 42 | u.Buff[2] = (unsigned char)UDPBuffer[pos + 2]; 43 | u.Buff[3] = (unsigned char)UDPBuffer[pos + 3]; 44 | return (u.d); 45 | } 46 | 47 | int16_t OSC_extractParamInt(uint8_t pos) { 48 | union { 49 | unsigned char Buff[2]; 50 | int16_t d; 51 | } u; 52 | 53 | u.Buff[1] = (unsigned char)UDPBuffer[pos]; 54 | u.Buff[0] = (unsigned char)UDPBuffer[pos + 1]; 55 | return (u.d); 56 | } 57 | 58 | 59 | void OSC_init() 60 | { 61 | OSCreadStatus = 0; 62 | OSCreadCounter = 0; 63 | OSCreadNumParams = 0; 64 | OSCcommandType = 0; 65 | OSCfader[0] = 0.5; 66 | OSCfader[1] = 0.5; 67 | OSCfader[2] = 0.5; 68 | OSCfader[3] = 0.5; 69 | } 70 | 71 | void OSC_MsgSend(char *c, unsigned char msgSize, float p) 72 | { 73 | uint8_t i; 74 | union { 75 | unsigned char Buff[4]; 76 | float d; 77 | } u; 78 | 79 | // We copy the param in the last 4 bytes 80 | u.d = p; 81 | c[msgSize - 4] = u.Buff[3]; 82 | c[msgSize - 3] = u.Buff[2]; 83 | c[msgSize - 2] = u.Buff[1]; 84 | c[msgSize - 1] = u.Buff[0]; 85 | for (i = 0; i < msgSize; i++) 86 | { 87 | Serial1.write((uint8_t)c[i]); 88 | //Serial.write((uint8_t)c[i]); 89 | } 90 | } 91 | 92 | void OSC_MsgRead() 93 | { 94 | uint8_t i; 95 | uint8_t tmp; 96 | float value; 97 | float value2; 98 | 99 | // New bytes available to process? 100 | if (Serial1.available() > 0) { 101 | // We rotate the Buffer (we could implement a ring buffer in future) 102 | for (i = 7; i > 0; i--) { 103 | UDPBuffer[i] = UDPBuffer[i - 1]; 104 | } 105 | UDPBuffer[0] = Serial1.read(); 106 | #ifdef OSCDEBUG3 107 | Serial.print(UDPBuffer[0]); 108 | #endif 109 | // We look for an OSC message start like /x/ 110 | if ((UDPBuffer[0] == '/') && (UDPBuffer[2] == '/') && ((UDPBuffer[1] == '1') || (UDPBuffer[1] == '2'))) { 111 | if (OSCreadStatus == 0) { 112 | OSCpage = UDPBuffer[1] - '0'; // Convert page to int 113 | OSCreadStatus = 1; 114 | OSCtouchMessage = 0; 115 | //Serial.print("$"); 116 | #ifdef OSCDEBUG3 117 | Serial.println(); 118 | #endif 119 | } 120 | else { 121 | Serial.println("!ERR:osc"); 122 | OSCreadStatus = 1; 123 | } 124 | return; 125 | } else if (OSCreadStatus == 1) { // looking for the message type 126 | // Fadder /1/fader1 ,f xxxx 127 | if ((UDPBuffer[3] == 'd') && (UDPBuffer[2] == 'e') && (UDPBuffer[1] == 'r')) { 128 | OSCreadStatus = 2; // Message type detected 129 | OSCreadCounter = 11; // Bytes to read the parameter 130 | OSCreadNumParams = 1; // 1 parameters 131 | OSCcommandType = UDPBuffer[0] - '0'; 132 | #ifdef OSCDEBUG2 133 | Serial.print("$FAD1"); 134 | Serial.print(OSCcommandType); 135 | Serial.print("$"); 136 | #endif 137 | return; 138 | } // end fadder 139 | // MOVE message 140 | if ((UDPBuffer[3] == 'o') && (UDPBuffer[2] == 'v') && (UDPBuffer[1] == 'e')) { 141 | OSCreadStatus = 2; // Message type detected 142 | OSCreadCounter = 8; // Bytes to read the parameters 143 | OSCreadNumParams = 3; // 3 parameters 144 | OSCcommandType = 40; 145 | #ifdef OSCDEBUG2 146 | Serial.print("$MOVE:"); 147 | #endif 148 | return; 149 | } // End MOVE message 150 | // XY message 151 | if ((UDPBuffer[2] == 'x') && (UDPBuffer[1] == 'y')) { 152 | OSCreadStatus = 2; // Message type detected 153 | OSCreadCounter = 14; // Bytes to read the parameters 154 | OSCreadNumParams = 2; // 2 parameters 155 | OSCcommandType = 10 + (UDPBuffer[0] - '0'); 156 | return; 157 | } // End XY message 158 | // Push message 159 | if ((UDPBuffer[3] == 'u') && (UDPBuffer[2] == 's') && (UDPBuffer[1] == 'h')) { 160 | OSCreadStatus = 2; // Message type detected 161 | OSCreadCounter = 10; // Bytes to read the parameter 162 | OSCreadNumParams = 1; // 1 parameters 163 | OSCcommandType = 20 + (UDPBuffer[0] - '1'); 164 | //Serial.println(commandType); 165 | #ifdef OSCDEBUG2 166 | Serial.print("$P"): 167 | Serial.print(UDPBuffer[0] - '1'); 168 | Serial.print(":"); 169 | #endif 170 | return; 171 | } // end push 172 | // Toggle message 173 | if ((UDPBuffer[3] == 'g') && (UDPBuffer[2] == 'l') && (UDPBuffer[1] == 'e')) { 174 | OSCreadStatus = 2; // Message type detected 175 | OSCreadCounter = 10; // Bytes to read the parameter 176 | OSCreadNumParams = 1; // 1 parameters 177 | OSCcommandType = 30 + (UDPBuffer[0] - '1'); 178 | //Serial.println(commandType); 179 | #ifdef OSCDEBUG2 180 | Serial.print("$T"): 181 | Serial.print(UDPBuffer[0] - '1'); 182 | Serial.print(":"); 183 | #endif 184 | return; 185 | } // end toggle 186 | } else if (OSCreadStatus == 2) { 187 | if ((UDPBuffer[1] == '/') && (UDPBuffer[0] == 'z')) { // Touch up message? (/z) [only on page1] 188 | if ((OSCpage == 1) && (OSCcommandType <= 2)) { // Touchup message only on Fadder1 and Fadder2 189 | OSCtouchMessage = 1; 190 | } 191 | else { 192 | OSCtouchMessage = 0; 193 | OSCreadStatus = 0; //Finish 194 | } 195 | } // Touch message(/z) 196 | OSCreadCounter--; // Reading counter until we reach the Parameter position 197 | if (OSCreadCounter <= 0) { 198 | OSCreadStatus = 0; 199 | OSCnewMessage = 1; 200 | //Serial.println(value); 201 | switch (OSCcommandType) { 202 | case 1: 203 | value = OSC_extractParamFloat(0); 204 | OSCfader[0] = value; 205 | if ((OSCtouchMessage) && (value == 0)) { 206 | OSCfader[0] = 0.5; 207 | //Serial.println("TOUCH_X"); 208 | OSC_MsgSend("/1/fader1\0\0\0,f\0\0\0\0\0\0", 20, 0.5); 209 | } 210 | #ifdef OSCDEBUG 211 | Serial.print("$F1:"); 212 | Serial.println(OSCfader[0]); 213 | #endif 214 | break; 215 | case 2: 216 | value = OSC_extractParamFloat(0); 217 | OSCfader[1] = value; 218 | if ((OSCtouchMessage) && (value == 0)) { 219 | OSCfader[1] = 0.5; 220 | //Serial.println("TOUCH_Y"); 221 | OSC_MsgSend("/1/fader2\0\0\0,f\0\0\0\0\0\0", 20, 0.5); 222 | } 223 | #ifdef OSCDEBUG 224 | Serial.print("$F2:"); 225 | Serial.println(OSCfader[1]); 226 | #endif 227 | break; 228 | case 3: 229 | OSCfader[2] = OSC_extractParamFloat(0); 230 | #ifdef OSCDEBUG 231 | Serial.print("$F3:"); 232 | Serial.println(OSCfader[2]); 233 | #endif 234 | break; 235 | case 4: 236 | OSCfader[3] = OSC_extractParamFloat(0); 237 | #ifdef OSCDEBUG 238 | Serial.print("$F4:"); 239 | Serial.println(OSCfader[3]); 240 | #endif 241 | break; 242 | case 11: 243 | OSCxy1_x = OSC_extractParamFloat(0); 244 | OSCxy1_y = OSC_extractParamFloat(4); 245 | #ifdef OSCDEBUG 246 | Serial.print("$XY1:"); 247 | Serial.print(OSCxy1_x); 248 | Serial.print(","); 249 | Serial.println(OSCxy1_y); 250 | #endif 251 | break; 252 | case 12: 253 | OSCxy2_x = OSC_extractParamFloat(0); 254 | OSCxy2_y = OSC_extractParamFloat(4); 255 | #ifdef OSCDEBUG 256 | Serial.print("$XY2:"); 257 | Serial.print(OSCxy2_x); 258 | Serial.print(","); 259 | Serial.println(OSCxy2_y); 260 | #endif 261 | break; 262 | case 40: 263 | // MOVE 264 | OSCmove_mode = 1; 265 | OSCmove_speed = OSC_extractParamInt(4); 266 | OSCmove_steps1 = OSC_extractParamInt(2); 267 | OSCmove_steps2 = OSC_extractParamInt(0); 268 | #ifdef OSCDEBUG 269 | Serial.print("$MOVE:"); 270 | Serial.print(OSCmove_speed); 271 | Serial.print(","); 272 | Serial.print(OSCmove_steps1); 273 | Serial.print(","); 274 | Serial.println(OSCmove_steps2); 275 | #endif 276 | break; 277 | 278 | default: 279 | // Push y toggle 280 | value = OSC_extractParamFloat(0); 281 | if ((OSCcommandType >= 20) && (OSCcommandType < 25)) 282 | { 283 | if (value == 0) 284 | OSCpush[OSCcommandType - 20] = 0; 285 | else 286 | OSCpush[OSCcommandType - 20] = 1; 287 | } 288 | if ((OSCcommandType >= 30) && (OSCcommandType < 35)) 289 | { 290 | if (value == 0) 291 | OSCtoggle[OSCcommandType - 30] = 0; 292 | else 293 | OSCtoggle[OSCcommandType - 30] = 1; 294 | } 295 | break; 296 | } // switch 297 | } // if (OSCRead_counter<=0) 298 | } // if (OSCread_status==2) 299 | } // end Serial.available() 300 | } 301 | 302 | -------------------------------------------------------------------------------- /Blockly/brobot/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2011 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | -------------------------------------------------------------------------------- /Blockly/brobot/generators/python.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Visual Blocks Language 4 | * 5 | * Copyright 2012 Google Inc. 6 | * https://developers.google.com/blockly/ 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | /** 22 | * @fileoverview Helper functions for generating Python for blocks. 23 | * @author fraser@google.com (Neil Fraser) 24 | */ 25 | 'use strict'; 26 | 27 | goog.provide('Blockly.Python'); 28 | 29 | goog.require('Blockly.Generator'); 30 | 31 | 32 | /** 33 | * Python code generator. 34 | * @type {!Blockly.Generator} 35 | */ 36 | Blockly.Python = new Blockly.Generator('Python'); 37 | 38 | /** 39 | * List of illegal variable names. 40 | * This is not intended to be a security feature. Blockly is 100% client-side, 41 | * so bypassing this list is trivial. This is intended to prevent users from 42 | * accidentally clobbering a built-in object or function. 43 | * @private 44 | */ 45 | Blockly.Python.addReservedWords( 46 | // import keyword 47 | // print ','.join(keyword.kwlist) 48 | // http://docs.python.org/reference/lexical_analysis.html#keywords 49 | 'and,as,assert,break,class,continue,def,del,elif,else,except,exec,' + 50 | 'finally,for,from,global,if,import,in,is,lambda,not,or,pass,print,raise,' + 51 | 'return,try,while,with,yield,' + 52 | //http://docs.python.org/library/constants.html 53 | 'True,False,None,NotImplemented,Ellipsis,__debug__,quit,exit,copyright,' + 54 | 'license,credits,' + 55 | // http://docs.python.org/library/functions.html 56 | 'abs,divmod,input,open,staticmethod,all,enumerate,int,ord,str,any,eval,' + 57 | 'isinstance,pow,sum,basestring,execfile,issubclass,print,super,bin,file,' + 58 | 'iter,property,tuple,bool,filter,len,range,type,bytearray,float,list,' + 59 | 'raw_input,unichr,callable,format,locals,reduce,unicode,chr,frozenset,' + 60 | 'long,reload,vars,classmethod,getattr,map,repr,xrange,cmp,globals,max,' + 61 | 'reversed,zip,compile,hasattr,memoryview,round,__import__,complex,hash,' + 62 | 'min,set,apply,delattr,help,next,setattr,buffer,dict,hex,object,slice,' + 63 | 'coerce,dir,id,oct,sorted,intern' 64 | ); 65 | 66 | /** 67 | * Order of operation ENUMs. 68 | * http://docs.python.org/reference/expressions.html#summary 69 | */ 70 | Blockly.Python.ORDER_ATOMIC = 0; // 0 "" ... 71 | Blockly.Python.ORDER_COLLECTION = 1; // tuples, lists, dictionaries 72 | Blockly.Python.ORDER_STRING_CONVERSION = 1; // `expression...` 73 | Blockly.Python.ORDER_MEMBER = 2.1; // . [] 74 | Blockly.Python.ORDER_FUNCTION_CALL = 2.2; // () 75 | Blockly.Python.ORDER_EXPONENTIATION = 3; // ** 76 | Blockly.Python.ORDER_UNARY_SIGN = 4; // + - 77 | Blockly.Python.ORDER_BITWISE_NOT = 4; // ~ 78 | Blockly.Python.ORDER_MULTIPLICATIVE = 5; // * / // % 79 | Blockly.Python.ORDER_ADDITIVE = 6; // + - 80 | Blockly.Python.ORDER_BITWISE_SHIFT = 7; // << >> 81 | Blockly.Python.ORDER_BITWISE_AND = 8; // & 82 | Blockly.Python.ORDER_BITWISE_XOR = 9; // ^ 83 | Blockly.Python.ORDER_BITWISE_OR = 10; // | 84 | Blockly.Python.ORDER_RELATIONAL = 11; // in, not in, is, is not, 85 | // <, <=, >, >=, <>, !=, == 86 | Blockly.Python.ORDER_LOGICAL_NOT = 12; // not 87 | Blockly.Python.ORDER_LOGICAL_AND = 13; // and 88 | Blockly.Python.ORDER_LOGICAL_OR = 14; // or 89 | Blockly.Python.ORDER_CONDITIONAL = 15; // if else 90 | Blockly.Python.ORDER_LAMBDA = 16; // lambda 91 | Blockly.Python.ORDER_NONE = 99; // (...) 92 | 93 | /** 94 | * List of outer-inner pairings that do NOT require parentheses. 95 | * @type {!Array.>} 96 | */ 97 | Blockly.Python.ORDER_OVERRIDES = [ 98 | // (foo()).bar -> foo().bar 99 | // (foo())[0] -> foo()[0] 100 | [Blockly.Python.ORDER_FUNCTION_CALL, Blockly.Python.ORDER_MEMBER], 101 | // (foo())() -> foo()() 102 | [Blockly.Python.ORDER_FUNCTION_CALL, Blockly.Python.ORDER_FUNCTION_CALL], 103 | // (foo.bar).baz -> foo.bar.baz 104 | // (foo.bar)[0] -> foo.bar[0] 105 | // (foo[0]).bar -> foo[0].bar 106 | // (foo[0])[1] -> foo[0][1] 107 | [Blockly.Python.ORDER_MEMBER, Blockly.Python.ORDER_MEMBER], 108 | // (foo.bar)() -> foo.bar() 109 | // (foo[0])() -> foo[0]() 110 | [Blockly.Python.ORDER_MEMBER, Blockly.Python.ORDER_FUNCTION_CALL], 111 | 112 | // not (not foo) -> not not foo 113 | [Blockly.Python.ORDER_LOGICAL_NOT, Blockly.Python.ORDER_LOGICAL_NOT], 114 | // a and (b and c) -> a and b and c 115 | [Blockly.Python.ORDER_LOGICAL_AND, Blockly.Python.ORDER_LOGICAL_AND], 116 | // a or (b or c) -> a or b or c 117 | [Blockly.Python.ORDER_LOGICAL_OR, Blockly.Python.ORDER_LOGICAL_OR] 118 | ]; 119 | 120 | /** 121 | * Initialise the database of variable names. 122 | * @param {!Blockly.Workspace} workspace Workspace to generate code from. 123 | */ 124 | Blockly.Python.init = function(workspace) { 125 | /** 126 | * Empty loops or conditionals are not allowed in Python. 127 | */ 128 | Blockly.Python.PASS = this.INDENT + 'pass\n'; 129 | // Create a dictionary of definitions to be printed before the code. 130 | Blockly.Python.definitions_ = Object.create(null); 131 | // Create a dictionary mapping desired function names in definitions_ 132 | // to actual function names (to avoid collisions with user functions). 133 | Blockly.Python.functionNames_ = Object.create(null); 134 | 135 | if (!Blockly.Python.variableDB_) { 136 | Blockly.Python.variableDB_ = 137 | new Blockly.Names(Blockly.Python.RESERVED_WORDS_); 138 | } else { 139 | Blockly.Python.variableDB_.reset(); 140 | } 141 | 142 | var defvars = []; 143 | var variables = workspace.variableList; 144 | for (var i = 0; i < variables.length; i++) { 145 | defvars[i] = Blockly.Python.variableDB_.getName(variables[i], 146 | Blockly.Variables.NAME_TYPE) + ' = None'; 147 | } 148 | Blockly.Python.definitions_['variables'] = defvars.join('\n'); 149 | }; 150 | 151 | /** 152 | * Prepend the generated code with the variable definitions. 153 | * @param {string} code Generated code. 154 | * @return {string} Completed code. 155 | */ 156 | Blockly.Python.finish = function(code) { 157 | // Convert the definitions dictionary into a list. 158 | var imports = []; 159 | var definitions = []; 160 | for (var name in Blockly.Python.definitions_) { 161 | var def = Blockly.Python.definitions_[name]; 162 | if (def.match(/^(from\s+\S+\s+)?import\s+\S+/)) { 163 | imports.push(def); 164 | } else { 165 | definitions.push(def); 166 | } 167 | } 168 | // Clean up temporary data. 169 | delete Blockly.Python.definitions_; 170 | delete Blockly.Python.functionNames_; 171 | Blockly.Python.variableDB_.reset(); 172 | var allDefs = imports.join('\n') + '\n\n' + definitions.join('\n\n'); 173 | return allDefs.replace(/\n\n+/g, '\n\n').replace(/\n*$/, '\n\n\n') + code; 174 | }; 175 | 176 | /** 177 | * Naked values are top-level blocks with outputs that aren't plugged into 178 | * anything. 179 | * @param {string} line Line of generated code. 180 | * @return {string} Legal line of code. 181 | */ 182 | Blockly.Python.scrubNakedValue = function(line) { 183 | return line + '\n'; 184 | }; 185 | 186 | /** 187 | * Encode a string as a properly escaped Python string, complete with quotes. 188 | * @param {string} string Text to encode. 189 | * @return {string} Python string. 190 | * @private 191 | */ 192 | Blockly.Python.quote_ = function(string) { 193 | // Can't use goog.string.quote since % must also be escaped. 194 | string = string.replace(/\\/g, '\\\\') 195 | .replace(/\n/g, '\\\n') 196 | .replace(/\%/g, '\\%') 197 | .replace(/'/g, '\\\''); 198 | return '\'' + string + '\''; 199 | }; 200 | 201 | /** 202 | * Common tasks for generating Python from blocks. 203 | * Handles comments for the specified block and any connected value blocks. 204 | * Calls any statements following this block. 205 | * @param {!Blockly.Block} block The current block. 206 | * @param {string} code The Python code created for this block. 207 | * @return {string} Python code with comments and subsequent blocks added. 208 | * @private 209 | */ 210 | Blockly.Python.scrub_ = function(block, code) { 211 | var commentCode = ''; 212 | // Only collect comments for blocks that aren't inline. 213 | if (!block.outputConnection || !block.outputConnection.targetConnection) { 214 | // Collect comment for this block. 215 | var comment = block.getCommentText(); 216 | comment = Blockly.utils.wrap(comment, Blockly.Python.COMMENT_WRAP - 3); 217 | if (comment) { 218 | if (block.getProcedureDef) { 219 | // Use a comment block for function comments. 220 | commentCode += '"""' + comment + '\n"""\n'; 221 | } else { 222 | commentCode += Blockly.Python.prefixLines(comment + '\n', '# '); 223 | } 224 | } 225 | // Collect comments for all value arguments. 226 | // Don't collect comments for nested statements. 227 | for (var i = 0; i < block.inputList.length; i++) { 228 | if (block.inputList[i].type == Blockly.INPUT_VALUE) { 229 | var childBlock = block.inputList[i].connection.targetBlock(); 230 | if (childBlock) { 231 | var comment = Blockly.Python.allNestedComments(childBlock); 232 | if (comment) { 233 | commentCode += Blockly.Python.prefixLines(comment, '# '); 234 | } 235 | } 236 | } 237 | } 238 | } 239 | var nextBlock = block.nextConnection && block.nextConnection.targetBlock(); 240 | var nextCode = Blockly.Python.blockToCode(nextBlock); 241 | return commentCode + code + nextCode; 242 | }; 243 | 244 | /** 245 | * Gets a property and adjusts the value, taking into account indexing, and 246 | * casts to an integer. 247 | * @param {!Blockly.Block} block The block. 248 | * @param {string} atId The property ID of the element to get. 249 | * @param {number=} opt_delta Value to add. 250 | * @param {boolean=} opt_negate Whether to negate the value. 251 | * @return {string|number} 252 | */ 253 | Blockly.Python.getAdjustedInt = function(block, atId, opt_delta, opt_negate) { 254 | var delta = opt_delta || 0; 255 | if (block.workspace.options.oneBasedIndex) { 256 | delta--; 257 | } 258 | var defaultAtIndex = block.workspace.options.oneBasedIndex ? '1' : '0'; 259 | var atOrder = delta ? Blockly.Python.ORDER_ADDITIVE : 260 | Blockly.Python.ORDER_NONE; 261 | var at = Blockly.Python.valueToCode(block, atId, atOrder) || defaultAtIndex; 262 | 263 | if (Blockly.isNumber(at)) { 264 | // If the index is a naked number, adjust it right now. 265 | at = parseInt(at, 10) + delta; 266 | if (opt_negate) { 267 | at = -at; 268 | } 269 | } else { 270 | // If the index is dynamic, adjust it in code. 271 | if (delta > 0) { 272 | at = 'int(' + at + ' + ' + delta + ')'; 273 | } else if (delta < 0) { 274 | at = 'int(' + at + ' - ' + -delta + ')'; 275 | } else { 276 | at = 'int(' + at + ')'; 277 | } 278 | if (opt_negate) { 279 | at = '-' + at; 280 | } 281 | } 282 | return at; 283 | }; 284 | -------------------------------------------------------------------------------- /Blockly/brobot/jquery/jquery-ui.theme.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.12.1 - 2016-09-14 2 | * http://jqueryui.com 3 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 4 | 5 | .ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #c5c5c5}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#2b2b2b;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-icon-background,.ui-state-active .ui-icon-background{border:#003eff;background-color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-checked{border:1px solid #dad55e;background:#fffa90}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.003;filter:Alpha(Opacity=.3)}.ui-widget-shadow{-webkit-box-shadow:0 0 5px #666;box-shadow:0 0 5px #666} -------------------------------------------------------------------------------- /Blockly/brobot/code.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Blockly Demos: Code 3 | * 4 | * Copyright 2012 Google Inc. 5 | * https://developers.google.com/blockly/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | 21 | /** 22 | * @fileoverview JavaScript for Blockly's Code demo. 23 | * @author fraser@google.com (Neil Fraser) 24 | */ 25 | 'use strict'; 26 | 27 | /** 28 | * Create a namespace for the application. 29 | */ 30 | var Code = {}; 31 | 32 | Code.Lang = 'en'; 33 | 34 | /** 35 | * Lookup for names of supported languages. Keys should be in ISO 639 format. 36 | */ 37 | Code.LANGUAGE_NAME = { 38 | 'en': 'English', 39 | }; 40 | 41 | /** 42 | * Blockly's main workspace. 43 | * @type {Blockly.WorkspaceSvg} 44 | */ 45 | Code.workspace = null; 46 | 47 | /** 48 | * Extracts a parameter from the URL. 49 | * If the parameter is absent default_value is returned. 50 | * @param {string} name The name of the parameter. 51 | * @param {string} defaultValue Value to return if paramater not found. 52 | * @return {string} The parameter value or the default value if not found. 53 | */ 54 | Code.getStringParamFromUrl = function(name, defaultValue) { 55 | var val = location.search.match(new RegExp('[?&]' + name + '=([^&]+)')); 56 | return val ? decodeURIComponent(val[1].replace(/\+/g, '%20')) : defaultValue; 57 | }; 58 | 59 | /** 60 | * Get the language of this user from the URL. 61 | * @return {string} User's language. 62 | */ 63 | Code.getLang = function() { 64 | return 'en'; 65 | }; 66 | 67 | 68 | /** 69 | * Load blocks saved on App Engine Storage or in session/local storage. 70 | * @param {string} defaultXml Text representation of default blocks. 71 | */ 72 | Code.loadBlocks = function(defaultXml) { 73 | try { 74 | var loadOnce = window.sessionStorage.loadOnceBlocks; 75 | } catch(e) { 76 | // Firefox sometimes throws a SecurityError when accessing sessionStorage. 77 | // Restarting Firefox fixes this, so it looks like a bug. 78 | var loadOnce = null; 79 | } 80 | if ('BlocklyStorage' in window && window.location.hash.length > 1) { 81 | // An href with #key trigers an AJAX call to retrieve saved blocks. 82 | BlocklyStorage.retrieveXml(window.location.hash.substring(1)); 83 | } else if (loadOnce) { 84 | // Language switching stores the blocks during the reload. 85 | delete window.sessionStorage.loadOnceBlocks; 86 | var xml = Blockly.Xml.textToDom(loadOnce); 87 | Blockly.Xml.domToWorkspace(xml, Code.workspace); 88 | } else if (defaultXml) { 89 | // Load the editor with default starting blocks. 90 | var xml = Blockly.Xml.textToDom(defaultXml); 91 | Blockly.Xml.domToWorkspace(xml, Code.workspace); 92 | } else if ('BlocklyStorage' in window) { 93 | // Restore saved blocks in a separate thread so that subsequent 94 | // initialization is not affected from a failed load. 95 | window.setTimeout(BlocklyStorage.restoreBlocks, 0); 96 | } 97 | }; 98 | 99 | /** 100 | * Bind a function to a button's click event. 101 | * On touch enabled browsers, ontouchend is treated as equivalent to onclick. 102 | * @param {!Element|string} el Button element or ID thereof. 103 | * @param {!Function} func Event handler to bind. 104 | */ 105 | Code.bindClick = function(el, func) { 106 | if (typeof el == 'string') { 107 | el = document.getElementById(el); 108 | } 109 | el.addEventListener('click', func, true); 110 | el.addEventListener('touchend', func, true); 111 | }; 112 | 113 | /** 114 | * Load the Prettify CSS and JavaScript. 115 | */ 116 | Code.importPrettify = function() { 117 | // 118 | // 119 | var link = document.createElement('link'); 120 | link.setAttribute('rel', 'stylesheet'); 121 | link.setAttribute('href', 'demos/prettify.css'); 122 | document.head.appendChild(link); 123 | var script = document.createElement('script'); 124 | script.setAttribute('src', 'demos/prettify.js'); 125 | document.head.appendChild(script); 126 | }; 127 | 128 | /** 129 | * Compute the absolute coordinates and dimensions of an HTML element. 130 | * @param {!Element} element Element to match. 131 | * @return {!Object} Contains height, width, x, and y properties. 132 | * @private 133 | */ 134 | Code.getBBox_ = function(element) { 135 | var height = element.offsetHeight; 136 | var width = element.offsetWidth; 137 | var x = 0; 138 | var y = 0; 139 | do { 140 | x += element.offsetLeft; 141 | y += element.offsetTop; 142 | element = element.offsetParent; 143 | } while (element); 144 | return { 145 | height: height, 146 | width: width, 147 | x: x, 148 | y: y 149 | }; 150 | }; 151 | 152 | /** 153 | * User's language (e.g. "en"). 154 | * @type {string} 155 | */ 156 | Code.LANG = Code.getLang(); 157 | 158 | /** 159 | * List of tab names. 160 | * @private 161 | */ 162 | Code.TABS_ = ['blocks', 'javascript', 'python', 'xml']; 163 | Code.selected = 'blocks'; 164 | 165 | /** 166 | * Switch the visible pane when a tab is clicked. 167 | * @param {string} clickedName Name of tab clicked. 168 | */ 169 | Code.tabClick = function(clickedName) { 170 | // If the XML tab was open, save and render the content. 171 | if (document.getElementById('tab_xml').className == 'tabon') { 172 | var xmlTextarea = document.getElementById('content_xml'); 173 | var xmlText = xmlTextarea.value; 174 | var xmlDom = null; 175 | try { 176 | xmlDom = Blockly.Xml.textToDom(xmlText); 177 | } catch (e) { 178 | var q = 179 | window.confirm(MSG['badXml'].replace('%1', e)); 180 | if (!q) { 181 | // Leave the user on the XML tab. 182 | return; 183 | } 184 | } 185 | if (xmlDom) { 186 | Code.workspace.clear(); 187 | Blockly.Xml.domToWorkspace(xmlDom, Code.workspace); 188 | } 189 | } 190 | 191 | if (document.getElementById('tab_blocks').className == 'tabon') { 192 | Code.workspace.setVisible(false); 193 | } 194 | // Deselect all tabs and hide all panes. 195 | for (var i = 0; i < Code.TABS_.length; i++) { 196 | var name = Code.TABS_[i]; 197 | document.getElementById('tab_' + name).className = 'taboff'; 198 | document.getElementById('content_' + name).style.visibility = 'hidden'; 199 | } 200 | 201 | // Select the active tab. 202 | Code.selected = clickedName; 203 | document.getElementById('tab_' + clickedName).className = 'tabon'; 204 | // Show the selected pane. 205 | document.getElementById('content_' + clickedName).style.visibility = 206 | 'visible'; 207 | Code.renderContent(); 208 | if (clickedName == 'blocks') { 209 | Code.workspace.setVisible(true); 210 | } 211 | Blockly.svgResize(Code.workspace); 212 | }; 213 | 214 | /** 215 | * Populate the currently selected pane with content generated from the blocks. 216 | */ 217 | Code.renderContent = function() { 218 | var content = document.getElementById('content_' + Code.selected); 219 | // Initialize the pane. 220 | if (content.id == 'content_xml') { 221 | var xmlTextarea = document.getElementById('content_xml'); 222 | var xmlDom = Blockly.Xml.workspaceToDom(Code.workspace); 223 | var xmlText = Blockly.Xml.domToPrettyText(xmlDom); 224 | xmlTextarea.value = xmlText; 225 | xmlTextarea.focus(); 226 | } else if (content.id == 'content_javascript') { 227 | var code = "// BROBOT code\n"; 228 | code += "var STEPSMETER="+STEPSMETER+";\nvar STEPSTURN="+STEPSTURN+";\n\n"; 229 | code += Blockly.JavaScript.workspaceToCode(Code.workspace); 230 | content.textContent = code; 231 | if (typeof prettyPrintOne == 'function') { 232 | code = content.innerHTML; 233 | code = prettyPrintOne(code, 'js'); 234 | content.innerHTML = code; 235 | } 236 | } else if (content.id == 'content_python') { 237 | // Add python Initialization code 238 | code = '# PYTHON BROBOT CODE\n'; 239 | code +='import time\nfrom BROBOT_Class import BROBOT\n'; 240 | code += 'myRobot = BROBOT()\n\n'; 241 | code += Blockly.Python.workspaceToCode(Code.workspace); 242 | content.textContent = code; 243 | if (typeof prettyPrintOne == 'function') { 244 | code = content.innerHTML; 245 | code = prettyPrintOne(code, 'py'); 246 | content.innerHTML = code; 247 | } 248 | 249 | } 250 | }; 251 | 252 | /** 253 | * Initialize Blockly. Called on page load. 254 | */ 255 | Code.init = function() { 256 | $( function() { 257 | $( "#dialog" ).dialog(); 258 | } ); 259 | Code.initLanguage(); 260 | 261 | var container = document.getElementById('content_area'); 262 | var onresize = function(e) { 263 | var bBox = Code.getBBox_(container); 264 | for (var i = 0; i < Code.TABS_.length; i++) { 265 | var el = document.getElementById('content_' + Code.TABS_[i]); 266 | el.style.top = bBox.y + 'px'; 267 | el.style.left = bBox.x + 'px'; 268 | // Height and width need to be set, read back, then set again to 269 | // compensate for scrollbars. 270 | el.style.height = bBox.height + 'px'; 271 | el.style.height = (2 * bBox.height - el.offsetHeight) + 'px'; 272 | el.style.width = bBox.width + 'px'; 273 | el.style.width = (2 * bBox.width - el.offsetWidth) + 'px'; 274 | } 275 | // Make the 'Blocks' tab line up with the toolbox. 276 | if (Code.workspace && Code.workspace.toolbox_.width) { 277 | document.getElementById('tab_blocks').style.minWidth = 278 | (Code.workspace.toolbox_.width - 38) + 'px'; 279 | // Account for the 19 pixel margin and on each side. 280 | } 281 | }; 282 | window.addEventListener('resize', onresize, false); 283 | 284 | // Interpolate translated messages into toolbox. 285 | var toolboxText = document.getElementById('toolbox').outerHTML; 286 | toolboxText = toolboxText.replace(/{(\w+)}/g, 287 | function(m, p1) {return MSG[p1]}); 288 | var toolboxXml = Blockly.Xml.textToDom(toolboxText); 289 | 290 | Code.workspace = Blockly.inject('content_blocks', 291 | {grid: 292 | {spacing: 25, 293 | length: 3, 294 | colour: '#ccc', 295 | snap: true}, 296 | media: 'media/', 297 | toolbox: toolboxXml, 298 | zoom: 299 | {controls: true, 300 | wheel: true} 301 | }); 302 | 303 | // Add to reserved word list: Local variables in execution environment (runJS) 304 | // and the infinite loop detection function. 305 | // Blockly.JavaScript.addReservedWords('code,timeouts,checkTimeout'); 306 | 307 | Code.loadBlocks(''); 308 | 309 | if ('BlocklyStorage' in window) { 310 | // Hook a save function onto unload. 311 | BlocklyStorage.backupOnUnload(Code.workspace); 312 | } 313 | 314 | Code.tabClick(Code.selected); 315 | 316 | Code.bindClick('trashButton', 317 | function() {Code.discard(); Code.renderContent();}); 318 | Code.bindClick('runButton', Code.runJS); 319 | // Disable the link button if page isn't backed by App Engine storage. 320 | var linkButton = document.getElementById('linkButton'); 321 | if ('BlocklyStorage' in window) { 322 | BlocklyStorage['HTTPREQUEST_ERROR'] = MSG['httpRequestError']; 323 | BlocklyStorage['LINK_ALERT'] = MSG['linkAlert']; 324 | BlocklyStorage['HASH_ERROR'] = MSG['hashError']; 325 | BlocklyStorage['XML_ERROR'] = MSG['xmlError']; 326 | Code.bindClick(linkButton, 327 | function() {BlocklyStorage.link(Code.workspace);}); 328 | } else if (linkButton) { 329 | linkButton.className = 'disabled'; 330 | } 331 | 332 | for (var i = 0; i < Code.TABS_.length; i++) { 333 | var name = Code.TABS_[i]; 334 | Code.bindClick('tab_' + name, 335 | function(name_) {return function() {Code.tabClick(name_);};}(name)); 336 | } 337 | onresize(); 338 | Blockly.svgResize(Code.workspace); 339 | 340 | // Lazy-load the syntax-highlighting. 341 | window.setTimeout(Code.importPrettify, 1); 342 | }; 343 | 344 | /** 345 | * Initialize the page language. 346 | */ 347 | Code.initLanguage = function() { 348 | document.head.parentElement.setAttribute('lang', 'en'); 349 | 350 | // Inject language strings. 351 | document.title += ' ' + 'title'; 352 | document.getElementById('tab_blocks').textContent = 'blocks'; 353 | document.getElementById('linkButton').title = 'link'; 354 | document.getElementById('runButton').title = 'run'; 355 | document.getElementById('trashButton').title = 'trash'; 356 | }; 357 | 358 | /** 359 | * Execute the user's code. 360 | * Just a quick and dirty eval. Catch infinite loops. 361 | */ 362 | Code.runJS = function() { 363 | console.log('run code...'); 364 | Blockly.JavaScript.INFINITE_LOOP_TRAP = ' checkTimeout();\n'; 365 | var timeouts = 0; 366 | var checkTimeout = function() { 367 | if (timeouts++ > 1000000) { 368 | throw MSG['timeout']; 369 | } 370 | }; 371 | var code = Blockly.JavaScript.workspaceToCode(Code.workspace); 372 | Blockly.JavaScript.INFINITE_LOOP_TRAP = null; 373 | console.log(code); 374 | eval(code); 375 | 376 | //try { 377 | // eval(code); 378 | //} catch (e) { 379 | // console.log('Code error...'); 380 | //alert(MSG['badCode'].replace('%1', e)); 381 | //} 382 | }; 383 | 384 | /** 385 | * Discard all blocks from the workspace. 386 | */ 387 | Code.discard = function() { 388 | var count = Code.workspace.getAllBlocks().length; 389 | if (count < 2 || 390 | window.confirm(Blockly.Msg.DELETE_ALL_BLOCKS.replace('%1', count))) { 391 | Code.workspace.clear(); 392 | if (window.location.hash) { 393 | window.location.hash = ''; 394 | } 395 | } 396 | }; 397 | 398 | window.addEventListener('load', Code.init); 399 | -------------------------------------------------------------------------------- /Blockly/brobot/demos/prettify.js: -------------------------------------------------------------------------------- 1 | !function(){var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; 2 | (function(){function S(a){function d(e){var b=e.charCodeAt(0);if(b!==92)return b;var a=e.charAt(1);return(b=r[a])?b:"0"<=a&&a<="7"?parseInt(e.substring(1),8):a==="u"||a==="x"?parseInt(e.substring(2),16):e.charCodeAt(1)}function g(e){if(e<32)return(e<16?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e);return e==="\\"||e==="-"||e==="]"||e==="^"?"\\"+e:e}function b(e){var b=e.substring(1,e.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),e=[],a= 3 | b[0]==="^",c=["["];a&&c.push("^");for(var a=a?1:0,f=b.length;a122||(l<65||h>90||e.push([Math.max(65,h)|32,Math.min(l,90)|32]),l<97||h>122||e.push([Math.max(97,h)&-33,Math.min(l,122)&-33]))}}e.sort(function(e,a){return e[0]-a[0]||a[1]-e[1]});b=[];f=[];for(a=0;ah[0]&&(h[1]+1>h[0]&&c.push("-"),c.push(g(h[1])));c.push("]");return c.join("")}function s(e){for(var a=e.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),c=a.length,d=[],f=0,h=0;f=2&&e==="["?a[f]=b(l):e!=="\\"&&(a[f]=l.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return a.join("")}for(var x=0,m=!1,j=!1,k=0,c=a.length;k=5&&"lang-"===w.substring(0,5))&&!(t&&typeof t[1]==="string"))f=!1,w="src";f||(r[z]=w)}h=c;c+=z.length;if(f){f=t[1];var l=z.indexOf(f),B=l+f.length;t[2]&&(B=z.length-t[2].length,l=B-f.length);w=w.substring(5);H(j+h,z.substring(0,l),g,k);H(j+h+l,f,I(w,f),k);H(j+h+B,z.substring(B),g,k)}else k.push(j+h,w)}a.g=k}var b={},s;(function(){for(var g=a.concat(d),j=[],k={},c=0,i=g.length;c=0;)b[n.charAt(e)]=r;r=r[1];n=""+r;k.hasOwnProperty(n)||(j.push(r),k[n]=q)}j.push(/[\S\s]/);s=S(j)})();var x=d.length;return g}function v(a){var d=[],g=[];a.tripleQuotedStrings?d.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?d.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, 10 | q,"'\"`"]):d.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&g.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var b=a.hashComments;b&&(a.cStyleComments?(b>1?d.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):d.push(["com",/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),g.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,q])):d.push(["com", 11 | /^#[^\n\r]*/,q,"#"]));a.cStyleComments&&(g.push(["com",/^\/\/[^\n\r]*/,q]),g.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));if(b=a.regexLiterals){var s=(b=b>1?"":"\n\r")?".":"[\\S\\s]";g.push(["lang-regex",RegExp("^(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+("/(?=[^/*"+b+"])(?:[^/\\x5B\\x5C"+b+"]|\\x5C"+s+"|\\x5B(?:[^\\x5C\\x5D"+b+"]|\\x5C"+ 12 | s+")*(?:\\x5D|$))+/")+")")])}(b=a.types)&&g.push(["typ",b]);b=(""+a.keywords).replace(/^ | $/g,"");b.length&&g.push(["kwd",RegExp("^(?:"+b.replace(/[\s,]+/g,"|")+")\\b"),q]);d.push(["pln",/^\s+/,q," \r\n\t\u00a0"]);b="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(b+="(?!s*/)");g.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/, 13 | q],["pun",RegExp(b),q]);return C(d,g)}function J(a,d,g){function b(a){var c=a.nodeType;if(c==1&&!x.test(a.className))if("br"===a.nodeName)s(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)b(a);else if((c==3||c==4)&&g){var d=a.nodeValue,i=d.match(m);if(i)c=d.substring(0,i.index),a.nodeValue=c,(d=d.substring(i.index+i[0].length))&&a.parentNode.insertBefore(j.createTextNode(d),a.nextSibling),s(a),c||a.parentNode.removeChild(a)}}function s(a){function b(a,c){var d= 14 | c?a.cloneNode(!1):a,e=a.parentNode;if(e){var e=b(e,1),g=a.nextSibling;e.appendChild(d);for(var i=g;i;i=g)g=i.nextSibling,e.appendChild(i)}return d}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),d;(d=a.parentNode)&&d.nodeType===1;)a=d;c.push(a)}for(var x=/(?:^|\s)nocode(?:\s|$)/,m=/\r\n?|\n/,j=a.ownerDocument,k=j.createElement("li");a.firstChild;)k.appendChild(a.firstChild);for(var c=[k],i=0;i=0;){var b=d[g];F.hasOwnProperty(b)?D.console&&console.warn("cannot override language handler %s",b):F[b]=a}}function I(a,d){if(!a||!F.hasOwnProperty(a))a=/^\s*=l&&(b+=2);g>=B&&(r+=2)}}finally{if(f)f.style.display=h}}catch(u){D.console&&console.log(u&&u.stack||u)}}var D=window,y=["break,continue,do,else,for,if,return,while"],E=[[y,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], 18 | "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],M=[E,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],N=[E,"abstract,assert,boolean,byte,extends,final,finally,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"], 19 | O=[N,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,internal,into,is,let,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var,virtual,where"],E=[E,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],P=[y,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], 20 | Q=[y,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],W=[y,"as,assert,const,copy,drop,enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv,pub,pure,ref,self,static,struct,true,trait,type,unsafe,use"],y=[y,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],R=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/, 21 | V=/\S/,X=v({keywords:[M,O,E,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",P,Q,y],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),F={};p(X,["default-code"]);p(C([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-", 22 | /^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);p(C([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/], 23 | ["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);p(C([],[["atv",/^[\S\s]+/]]),["uq.val"]);p(v({keywords:M,hashComments:!0,cStyleComments:!0,types:R}),["c","cc","cpp","cxx","cyc","m"]);p(v({keywords:"null,true,false"}),["json"]);p(v({keywords:O,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:R}), 24 | ["cs"]);p(v({keywords:N,cStyleComments:!0}),["java"]);p(v({keywords:y,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);p(v({keywords:P,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);p(v({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:2}),["perl","pl","pm"]);p(v({keywords:Q, 25 | hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);p(v({keywords:E,cStyleComments:!0,regexLiterals:!0}),["javascript","js"]);p(v({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);p(v({keywords:W,cStyleComments:!0,multilineStrings:!0}),["rc","rs","rust"]); 26 | p(C([],[["str",/^[\S\s]+/]]),["regex"]);var Y=D.PR={createSimpleLexer:C,registerLangHandler:p,sourceDecorator:v,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",prettyPrintOne:D.prettyPrintOne=function(a,d,g){var b=document.createElement("div");b.innerHTML="
"+a+"
";b=b.firstChild;g&&J(b,g,!0);K({h:d,j:g,c:b,i:1}); 27 | return b.innerHTML},prettyPrint:D.prettyPrint=function(a,d){function g(){for(var b=D.PR_SHOULD_USE_CONTINUATION?c.now()+250:Infinity;i .ui-controlgroup-item{float:left;margin-left:0;margin-right:0}.ui-controlgroup > .ui-controlgroup-item:focus,.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus{z-index:9999}.ui-controlgroup-vertical > .ui-controlgroup-item{display:block;float:none;width:100%;margin-top:0;margin-bottom:0;text-align:left}.ui-controlgroup-vertical .ui-controlgroup-item{box-sizing:border-box}.ui-controlgroup .ui-controlgroup-label{padding:.4em 1em}.ui-controlgroup .ui-controlgroup-label span{font-size:80%}.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item{border-left:none}.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item{border-top:none}.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content{border-right:none}.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content{border-bottom:none}.ui-controlgroup-vertical .ui-spinner-input{width:75%;width:calc( 100% - 2.4em )}.ui-controlgroup-vertical .ui-spinner .ui-spinner-up{border-top-style:solid}.ui-checkboxradio-label .ui-icon-background{box-shadow:inset 1px 1px 1px #ccc;border-radius:.12em;border:none}.ui-checkboxradio-radio-label .ui-icon-background{width:16px;height:16px;border-radius:1em;overflow:visible;border:none}.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon{background-image:none;width:8px;height:8px;border-width:4px;border-style:solid}.ui-checkboxradio-disabled{pointer-events:none}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker .ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;left:.5em;top:.3em}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-n{height:2px;top:0}.ui-dialog .ui-resizable-e{width:2px;right:0}.ui-dialog .ui-resizable-s{height:2px;bottom:0}.ui-dialog .ui-resizable-w{width:2px;left:0}.ui-dialog .ui-resizable-se,.ui-dialog .ui-resizable-sw,.ui-dialog .ui-resizable-ne,.ui-dialog .ui-resizable-nw{width:7px;height:7px}.ui-dialog .ui-resizable-se{right:0;bottom:0}.ui-dialog .ui-resizable-sw{left:0;bottom:0}.ui-dialog .ui-resizable-ne{right:0;top:0}.ui-dialog .ui-resizable-nw{left:0;top:0}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-text{display:block;margin-right:20px;overflow:hidden;text-overflow:ellipsis}.ui-selectmenu-button.ui-button{text-align:left;white-space:nowrap;width:14em}.ui-selectmenu-icon.ui-icon{float:right;margin-top:0}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:.222em 0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:2em}.ui-spinner-button{width:1.6em;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top-style:none;border-bottom-style:none;border-right-style:none}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px}body .ui-tooltip{border-width:2px} --------------------------------------------------------------------------------