Compare commits

..

4 Commits

Author SHA1 Message Date
83793fc668 strings 2018-01-09 12:39:56 -08:00
47ee87fe72 adding logging 2018-01-09 09:03:22 -08:00
374fa36548 cholesky 2018-01-08 23:15:43 -08:00
358ef7e19f started on matrix library 2018-01-08 23:05:09 -08:00
76 changed files with 756 additions and 1568 deletions

View File

@ -14,7 +14,7 @@ function accelerate() {
} }
function update() { function update() {
brick.clearScreen() brick.clearScreen()
brick.showString("speed: " + speed, 1) brick.printLine("speed: " + speed, 1)
motors.largeBC.setSpeed(speed) motors.largeBC.setSpeed(speed)
} }
sensors.touch2.onEvent(TouchSensorEvent.Pressed, function () { sensors.touch2.onEvent(TouchSensorEvent.Pressed, function () {

View File

@ -7,5 +7,5 @@ loops.forever(function () {
}) })
motors.largeBC.setSpeed(-20); motors.largeBC.setSpeed(-20);
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear); sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear);
motors.largeBC.stop(); motors.stopAllMotors();
``` ```

View File

@ -9,5 +9,5 @@ loops.forever(function () {
}) })
motors.largeBC.setSpeed(-20); motors.largeBC.setSpeed(-20);
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear); sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear);
motors.largeBC.stop(); motors.stopAllMotors();
``` ```

View File

@ -4,9 +4,10 @@
let beep = false let beep = false
beep = true beep = true
control.runInBackground(function () { control.runInBackground(function () {
motors.largeBC.setSpeed(-20) motors.largeB.setSpeed(-20)
motors.largeC.setSpeed(-20)
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear) sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear)
motors.largeBC.stop() motors.stopAllMotors()
beep = false beep = false
}) })
control.runInBackground(function () { control.runInBackground(function () {

109
docs/static/avatar.svg vendored
View File

@ -1,109 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg2" inkscape:version="0.91 r13725" sodipodi:docname="avatar.svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 32 32"
style="enable-background:new 0 0 32 32;" xml:space="preserve">
<style type="text/css">
.st0{fill:#303030;}
</style>
<sodipodi:namedview bordercolor="#666666" borderopacity="1" gridtolerance="10" guidetolerance="10" id="namedview15" inkscape:current-layer="svg2" inkscape:cx="16" inkscape:cy="16" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-height="661" inkscape:window-maximized="0" inkscape:window-width="997" inkscape:window-x="0" inkscape:window-y="0" inkscape:zoom="5.2149125" objecttolerance="10" pagecolor="#ffffff" showgrid="false">
</sodipodi:namedview>
<g id="avatar_mf" transform="translate(-5304.979 8145.745)">
<path id="Path_180" class="st0" d="M5317.1-8125.6c0.2,0,0.3-0.1,0.5-0.1l2.9-0.6c1.3-0.3,2.5-0.5,3.8-0.8c0.5-0.1,1-0.2,1.5-0.3
c0.1,0,0.1,0,0.1-0.1c0-0.5,0-1-0.1-1.5c-0.1-0.6-0.2-1.1-0.3-1.7c-0.1-0.4-0.1-0.8-0.2-1.2c-0.1-0.7-0.2-1.4-0.3-2
c-0.1-0.6-0.2-1.1-0.3-1.7c0-0.2-0.2-0.4-0.4-0.4c0,0,0,0-0.1,0c-0.2,0-0.5,0.1-0.7,0.1c-0.5,0.1-1,0.1-1.5,0.2
c-0.5,0.1-1,0.1-1.6,0.2c-0.5,0.1-1,0.1-1.4,0.2c-0.2,0-0.3,0-0.5,0.1c-0.2,0-0.4,0.2-0.5,0.4c0,0.2-0.1,0.4-0.1,0.5
c0,0.4-0.1,0.8-0.1,1.2c-0.1,0.5-0.1,1-0.2,1.5c0,0.4-0.1,0.9-0.1,1.3l-0.1,1.3l-0.1,1.3c-0.1,0.5-0.1,1-0.2,1.5
C5317.1-8126,5317.1-8125.8,5317.1-8125.6z"/>
<path id="Path_181" class="st0" d="M5316.1-8140c0,0.6,0.1,1.2,0.1,1.8c0,0.4,0.2,0.8,0.6,1c0.3,0.2,0.7,0.3,1.1,0.3
c0.7,0.1,1.4,0.1,2.1,0c0.6,0,1.2-0.1,1.8-0.2c0.4,0,0.9-0.2,1.2-0.5c0.3-0.3,0.5-0.7,0.5-1.1c0-1.2,0-2.3-0.1-3.5
c0-0.3-0.1-0.6-0.3-0.8c-0.3-0.4-0.8-0.6-1.4-0.6c0,0,0,0-0.1,0c-0.2,0.1-0.4,0.1-0.6,0.1c-0.9,0-1.8,0.1-2.7,0.1
c-0.1,0-0.3,0-0.4,0c-0.4-0.1-0.8,0-1.2,0.2c-0.4,0.2-0.6,0.6-0.7,1c0,0.1,0,0.2,0,0.3C5316-8141.2,5316.1-8140.6,5316.1-8140
L5316.1-8140z"/>
<path id="Path_182" class="st0" d="M5312-8129.2c0,0.6,0,1.2,0,1.8c0,0.1,0,0.1,0.1,0.1c0.3,0,0.6,0.1,0.9,0.1c0.3,0,0.7,0,1,0
c0.1,0,0.2,0,0.3,0c0.1,0,0.1,0,0.1-0.1c0.1-0.4,0.2-0.8,0.2-1.2c0.1-0.5,0.2-1,0.3-1.4c0-0.1,0.1-0.1,0.1-0.1
c0.4-0.2,0.8-0.5,1.2-0.8c0.4-0.4,0.7-0.9,0.8-1.5c0.1-0.6,0-1.2-0.4-1.7c-0.2-0.3-0.6-0.4-0.9-0.3c-0.3,0.1-0.6,0.3-0.9,0.5
c-0.7,0.6-1.5,1.2-2.2,1.8c-0.3,0.2-0.5,0.5-0.6,0.8c0,0.2-0.1,0.4-0.1,0.6C5311.9-8130.2,5311.9-8129.7,5312-8129.2
C5311.9-8129.2,5312-8129.2,5312-8129.2z"/>
<path id="Path_183" class="st0" d="M5315.5-8124.7c0,0.2-0.1,0.5-0.1,0.7c-0.1,0.5-0.4,0.9-0.8,1.1c0,0,0,0,0,0
c-0.1,0-0.2,0.2-0.2,0.3c-0.4,1.4-0.9,2.7-1.3,4.1c0,0,0,0.1,0,0.1c0.8,1.1,1.6,2.2,2.4,3.3c0,0,0,0,0.1,0.1
c0.1-0.2,0.1-0.3,0.2-0.5c0.1-0.3,0.2-0.5,0.3-0.8c0,0,0-0.1,0-0.1c-0.2-0.3-0.5-0.7-0.7-1c0,0,0-0.1,0-0.2
c0.3-0.9,0.6-1.7,0.9-2.6c0,0,0-0.1,0.1-0.1c0.5-0.2,0.9-0.6,1.1-1.1c0.1-0.3,0.1-0.7,0.1-1.1c0-0.4-0.1-0.8-0.3-1.2
c-0.2-0.4-0.5-0.8-1-1C5315.9-8124.7,5315.7-8124.7,5315.5-8124.7z"/>
<path id="Path_184" class="st0" d="M5314.7-8134.2c0.1-0.1,0.2-0.1,0.3-0.2c0.3-0.2,0.7-0.3,1-0.3c0.4,0,0.7,0.2,0.8,0.6
c0.6,1.1,0.5,2.4-0.4,3.3c-0.4,0.4-0.8,0.7-1.3,1c0,0-0.1,0.1-0.1,0.1c-0.2,0.8-0.3,1.6-0.5,2.5c0,0,0,0.1,0,0.1
c0,0.2,0,0.2-0.2,0.2c-0.1,0-0.1,0-0.2,0c0,0.1,0,0.2,0,0.3c0,0,0,0,0.1,0.1l1.9,0.7c0.2,0.1,0.4,0.2,0.7,0.2c0-0.1,0-0.2,0-0.2
c0-0.3,0-0.6,0-0.8l0.2-1.5l0.2-1.5c0.1-0.5,0.1-1,0.2-1.5c0.1-0.5,0.1-1.1,0.2-1.6c0.1-0.5,0.1-1,0.2-1.5c0-0.2,0-0.4,0-0.6
c0-0.2-0.1-0.4-0.3-0.4c0,0,0,0,0,0c-0.1,0-0.1,0-0.2,0c-0.6-0.1-1.2-0.2-1.9-0.3c-0.1,0-0.2,0-0.3,0c-0.1,0-0.2,0.1-0.3,0.3
C5314.8-8135,5314.7-8134.6,5314.7-8134.2z"/>
<path id="Path_185" class="st0" d="M5324.5-8117.2c-0.2-0.7-0.5-1.3-0.7-2l-0.7,0.3c0,0-0.1,0-0.1,0c-0.1,0.1-0.2,0-0.2-0.1
c-0.1-0.3-0.2-0.5-0.3-0.8c-0.2-0.7-0.5-1.4-0.7-2.1c0,0,0-0.1,0-0.1c0,0,0,0.1-0.1,0.1c-0.1,0.2-0.3,0.3-0.5,0.5c0,0-0.1,0-0.1,0
c-0.3,0.1-0.6,0.1-0.8,0.2c0,0-0.1,0-0.1,0c0,0.2-0.1,0.3-0.1,0.5c0.6,1.5,1.1,3.1,1.7,4.6c0,0,0,0,0,0.1
C5322.7-8116.3,5323.6-8116.7,5324.5-8117.2z"/>
<path id="Path_186" class="st0" d="M5325.4-8123.1c-0.7,0.2-1.3,0.3-2,0.5c-0.5,0.1-0.9,0.2-1.4,0.3c-0.1,0-0.2,0.1-0.1,0.2
c0,0,0,0,0,0.1c0.2,0.5,0.3,0.9,0.5,1.4c0.2,0.5,0.4,1.1,0.6,1.6c0,0,0,0,0,0c0.1-0.1,0.2-0.1,0.3-0.2c0.2-0.1,0.3-0.2,0.5-0.2
c0.2-0.1,0.4-0.1,0.6-0.2c0.7-0.2,1.5-0.4,2.2-0.6c0,0,0,0,0.1,0C5326.3-8121.1,5325.9-8122.1,5325.4-8123.1z"/>
<path id="Path_187" class="st0" d="M5320.7-8124.4c-0.4,0.1-0.8,0.2-1.2,0.3c-0.6,0.1-1.3,0.3-1.9,0.4c0,0-0.1,0-0.1,0
c-0.1,0-0.2-0.1-0.3-0.1c0,0,0,0.1,0,0.1c0.3,0.7,0.4,1.5,0.3,2.2c-0.1,0.4-0.3,0.8-0.5,1.1c0,0,0,0-0.1,0.1
c0.2-0.1,0.4-0.1,0.6-0.1l2.5-0.6c0.5-0.1,0.9-0.6,1-1.1c0.1-0.5,0-1-0.1-1.5C5320.8-8124,5320.8-8124.2,5320.7-8124.4z"/>
<path id="Path_188" class="st0" d="M5325.5-8127c-2.7,0.5-5.3,1.1-7.9,1.6c0,0.5,0,0.9,0.1,1.4c0.1,0,0.2,0,0.3-0.1
c1.2-0.3,2.3-0.5,3.5-0.8c1.2-0.3,2.4-0.5,3.6-0.8c0.1,0,0.3-0.1,0.4-0.1c0,0,0.1,0,0.1-0.1
C5325.6-8126.2,5325.5-8126.6,5325.5-8127z"/>
<path id="Path_189" class="st0" d="M5328.6-8118.4c-0.2-0.4-0.3-0.7-0.5-1.1c-0.1-0.2-0.2-0.5-0.3-0.7c0-0.1,0-0.1-0.1,0
c-1.2,0.3-2.4,0.6-3.6,1c0,0,0,0-0.1,0c0.2,0.7,0.5,1.3,0.7,2C5326-8117.6,5327.3-8118,5328.6-8118.4z"/>
<path id="Path_190" class="st0" d="M5319.9-8120.9l-0.6,0.1c-1,0.2-2,0.5-3,0.7c-0.1,0-0.1,0.1-0.1,0.1c-0.3,0.7-0.5,1.5-0.8,2.2
c0,0,0,0,0,0.1c0.2,0,0.4-0.1,0.5-0.1c1-0.3,2-0.5,3.1-0.8c0.1,0,0.2-0.1,0.3-0.2C5319.5-8119.5,5319.7-8120.2,5319.9-8120.9z"/>
<path id="Path_191" class="st0" d="M5325.1-8125.4c-1.1,0.2-2.2,0.5-3.3,0.7c0.3,0.7,0.4,1.4,0.3,2.2c0.2,0,0.4-0.1,0.5-0.1
c0.9-0.2,1.8-0.4,2.7-0.6c0.1,0,0.1,0,0.1-0.1c0.1-0.4,0-0.9-0.1-1.3C5325.3-8124.9,5325.2-8125.1,5325.1-8125.4
C5325.1-8125.3,5325.1-8125.4,5325.1-8125.4z"/>
<path id="Path_192" class="st0" d="M5325.6-8132c0.2,0,0.4,0,0.5,0c0.2,0,0.4,0,0.6,0c0.3,0,0.6-0.2,0.8-0.4c0.3-0.4,0.7-0.8,1-1.2
c-0.1-0.1-0.1-0.1-0.1-0.2c0,0,0,0-0.1,0c-0.7-0.1-1.3-0.5-1.4-1.2c-0.1-0.2-0.1-0.4-0.1-0.6c-0.2,0.1-0.3,0.3-0.5,0.4
c-0.1,0.1-0.2,0.1-0.3,0.2c0,0-0.1,0.1-0.2,0c-0.2,0-0.5-0.1-0.7-0.1c0,0,0,0-0.1,0C5325.3-8134.1,5325.4-8133.1,5325.6-8132z"/>
<path id="Path_193" class="st0" d="M5328.4-8134.2c0.2-0.3,0.5-0.5,0.8-0.7c0.4-0.4,0.6-0.8,0.7-1.4c0-0.1,0-0.2-0.1-0.3
c-0.3-0.5-0.7-1.1-1-1.6c0-0.1-0.1-0.1-0.1,0c-0.4,0.2-0.8,0.5-1.1,0.8c-0.2,0.2-0.4,0.4-0.6,0.6c-0.1,0.1-0.1,0.3,0,0.4
c0.5,0.7,1,1.5,1.4,2.2C5328.4-8134.2,5328.4-8134.2,5328.4-8134.2z"/>
<path id="Path_194" class="st0" d="M5314.3-8126.1c-0.1-0.1-0.1-0.1-0.2-0.2c-0.1,0-0.1-0.1-0.1-0.2c0-0.1,0-0.3,0-0.4h-0.1
c-0.6,0-1.2-0.1-1.7-0.2c0,0-0.1,0-0.1,0c-0.4,0.2-0.7,0.4-1,0.8c-0.4,0.6-0.4,1.4,0.1,1.9c0.2,0.2,0.4,0.4,0.6,0.6
c0.1,0.1,0.2,0.2,0.3,0.2c-0.2-0.6,0-1.3,0.5-1.8C5313-8125.9,5313.6-8126.2,5314.3-8126.1z"/>
<path id="Path_195" class="st0" d="M5315.7-8114.9c0.5-0.1,0.9-0.3,1.4-0.4c0.8-0.2,1.6-0.4,2.4-0.7c0.1,0,0.1,0,0.1-0.1
c0.1-0.4,0.2-0.7,0.4-1.1c0,0,0,0,0-0.1c-0.1,0-0.2,0-0.3,0.1c-1.2,0.3-2.3,0.6-3.5,1c-0.1,0-0.1,0.1-0.1,0.1
c-0.1,0.4-0.3,0.7-0.4,1.1C5315.7-8115,5315.7-8115,5315.7-8114.9z"/>
<path id="Path_196" class="st0" d="M5315.4-8117.4c0.2,0.3,0.4,0.6,0.6,0.9c0,0,0.1,0,0.1,0c1-0.3,1.9-0.5,2.9-0.8
c0.3-0.1,0.6-0.2,0.9-0.2c-0.1-0.1-0.1-0.2-0.2-0.2c-0.2-0.2-0.3-0.4-0.5-0.6c0,0-0.1-0.1-0.1,0c-0.9,0.3-1.9,0.5-2.8,0.8
C5316-8117.5,5315.7-8117.5,5315.4-8117.4z"/>
<path id="Path_197" class="st0" d="M5321.3-8143.6c0-0.3,0-0.7,0-1c0,0-0.1,0-0.1,0c-0.7,0-1.5,0-2.2,0.1c-0.4,0-0.7,0-1.1,0.1
c-0.1,0-0.1,0-0.1,0.1c0,0.3,0,0.6,0,0.8c0,0,0,0.1,0.1,0.1c0.4,0,0.8,0,1.1,0c0.5,0,1.1,0,1.6-0.1
C5320.9-8143.5,5321.1-8143.6,5321.3-8143.6z"/>
<path id="Path_198" class="st0" d="M5329.2-8134.3c0.1,0,0.2,0,0.2-0.1c0.4-0.2,0.8-0.4,1.1-0.7c0.3-0.2,0.4-0.5,0.6-0.8
c0.1-0.3,0.1-0.6-0.1-0.9c-0.4-0.5-0.7-1-1.1-1.6c0,0,0,0-0.1-0.1c-0.2,0.2-0.4,0.4-0.6,0.6c0,0,0,0,0,0c0,0,0,0.1,0,0.1
c0.2,0.4,0.5,0.7,0.7,1c0.1,0.2,0.2,0.4,0.1,0.6c0,0.5-0.1,0.9-0.4,1.3c-0.1,0.1-0.2,0.2-0.3,0.3
C5329.4-8134.5,5329.3-8134.4,5329.2-8134.3C5329.2-8134.3,5329.2-8134.3,5329.2-8134.3z"/>
<path id="Path_199" class="st0" d="M5317.5-8136.7c0,0.2,0,0.3,0,0.5c0,0,0,0.1,0.1,0.1c0.2,0,0.3,0.1,0.5,0.1c0.7,0.1,1.4,0.1,2,0
c0.4,0,0.8-0.1,1.2-0.1c0.2,0,0.5-0.1,0.7-0.1c0.1,0,0.1,0,0.1-0.1c0-0.2,0-0.3,0-0.5C5320.5-8136.6,5319-8136.5,5317.5-8136.7z"/>
<path id="Path_200" class="st0" d="M5312.5-8123.2c0.1-0.4,0.1-0.8,0.2-1.2c0.1-0.6,0.6-1,1.2-1c0.3,0,0.5,0.1,0.7,0.3
c0.2,0.2,0.2,0.4,0.2,0.7c-0.1,0.3-0.2,0.6-0.2,0.9c0,0.1-0.1,0.2-0.1,0.4c0,0,0,0,0,0c0.1-0.1,0.2-0.2,0.3-0.3
c0.3-0.4,0.4-0.9,0.4-1.4c0-0.6-0.4-1-0.9-1.1c-0.1,0-0.1,0-0.2,0c-0.5,0-1,0.3-1.4,0.7c-0.3,0.3-0.4,0.6-0.5,1
c-0.1,0.3,0,0.7,0.2,1C5312.5-8123.2,5312.5-8123.2,5312.5-8123.2z"/>
<path id="Path_201" class="st0" d="M5314.3-8123.2c0.1-0.5,0.3-0.9,0.4-1.4c0.1-0.2,0-0.4-0.2-0.5c-0.4-0.2-0.9-0.1-1.2,0.2
c0,0,0,0,0,0.1c0,0.2,0,0.4,0.1,0.6c0,0.1,0.1,0.2,0.2,0.3C5313.7-8123.6,5314-8123.4,5314.3-8123.2
C5314.2-8123.2,5314.3-8123.2,5314.3-8123.2z"/>
<path id="Path_202" class="st0" d="M5317.4-8124.1c0-0.4,0-0.9-0.1-1.3c-0.1,0-0.1,0-0.2,0c-0.1,0-0.2,0-0.3,0
c-0.7-0.3-1.4-0.5-2.1-0.8c0,0,0,0,0,0c0.1,0.1,0.1,0.1,0.2,0.2c0.3,0.2,0.5,0.6,0.6,0.9c0,0,0,0,0,0c0.1,0,0.3,0,0.4,0.1
c0.3,0.1,0.6,0.3,0.9,0.5c0,0,0.1,0.1,0.1,0.1C5317.1-8124.2,5317.2-8124.1,5317.4-8124.1z"/>
<path id="Path_203" class="st0" d="M5321.6-8124.6c-0.2,0-0.4,0.1-0.6,0.1c0.1,0.2,0.1,0.4,0.2,0.6c0.1,0.4,0.2,0.8,0.1,1.2
c0,0.5-0.1,0.9-0.4,1.3c0,0,0,0,0,0c0.3,0,0.6-0.2,0.7-0.5c0.2-0.3,0.3-0.6,0.3-0.9C5321.9-8123.4,5321.8-8124,5321.6-8124.6z"/>
<path id="Path_204" class="st0" d="M5315.7-8135.8c0.2,0,0.3,0.1,0.5,0.1c0.5,0.1,1,0.2,1.5,0.2c0.2,0,0.5,0,0.7,0
c0.7-0.1,1.4-0.2,2.1-0.2c0.6-0.1,1.2-0.2,1.8-0.2c0.5-0.1,1.1-0.1,1.6-0.2l-1.5-0.2c0,0,0,0,0,0c0,0.2-0.1,0.3-0.2,0.3
c0,0,0,0,0,0c-0.3,0.1-0.5,0.1-0.8,0.2c-0.8,0.1-1.6,0.1-2.3,0.1c-0.4,0-0.9,0-1.3-0.1c-0.1,0-0.2-0.1-0.3-0.2c0,0-0.1,0-0.1,0
c-0.3,0-0.6,0.1-0.9,0.1L5315.7-8135.8L5315.7-8135.8z"/>
<path id="Path_205" class="st0" d="M5327.3-8117.7c-0.3,0.1-0.5,0.2-0.8,0.2c-0.6,0.2-1.1,0.3-1.7,0.5c0,0-0.1,0-0.1,0.1
c-0.5,0.2-1,0.5-1.5,0.7c0,0,0,0,0,0c0.3-0.1,0.5-0.1,0.8-0.2c0.5-0.2,1.1-0.3,1.6-0.5c0.1,0,0.2-0.1,0.2-0.1
C5326.2-8117.2,5326.8-8117.5,5327.3-8117.7C5327.3-8117.7,5327.3-8117.7,5327.3-8117.7C5327.3-8117.7,5327.3-8117.7,5327.3-8117.7
z"/>
<path id="Path_206" class="st0" d="M5327-8135.8c0,0.1,0,0.2,0,0.4c0.1,0.5,0.3,0.9,0.7,1.1c0.1,0.1,0.3,0.1,0.4,0.2l0,0
C5327.8-8134.7,5327.4-8135.2,5327-8135.8L5327-8135.8z"/>
<path id="Path_207" class="st0" d="M5329-8134.4c-0.1,0.1-0.2,0.2-0.3,0.4c0,0,0,0,0,0.1c0,0.1,0,0.1,0.1,0.1c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.1c-0.1,0-0.1-0.1-0.2-0.1C5329-8134.2,5329-8134.3,5329-8134.4z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@ -6,7 +6,6 @@ import { FieldPorts } from "./field_ports";
import { FieldImages } from "./field_images"; import { FieldImages } from "./field_images";
import {FieldSpeed} from "./field_speed"; import {FieldSpeed} from "./field_speed";
import { FieldBrickButtons } from "./field_brickbuttons"; import { FieldBrickButtons } from "./field_brickbuttons";
import { FieldTurnRatio } from "./field_turnratio";
pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): Promise<pxt.editor.ExtensionResult> { pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): Promise<pxt.editor.ExtensionResult> {
pxt.debug('loading pxt-ev3 target extensions...') pxt.debug('loading pxt-ev3 target extensions...')
@ -24,9 +23,6 @@ pxt.editor.initExtensionsAsync = function(opts: pxt.editor.ExtensionOptions): Pr
}, { }, {
selector: "brickbuttons", selector: "brickbuttons",
editor: FieldBrickButtons editor: FieldBrickButtons
}, {
selector: "turnratio",
editor: FieldTurnRatio
}], }],
deployCoreAsync deployCoreAsync
}; };

View File

@ -24,9 +24,6 @@ export class FieldPorts extends Blockly.FieldDropdown implements Blockly.FieldCu
this.width_ = parseInt(options.width) || 300; this.width_ = parseInt(options.width) || 300;
} }
trimOptions_() {
}
/** /**
* Create a dropdown menu under the text. * Create a dropdown menu under the text.
* @private * @private
@ -45,8 +42,7 @@ export class FieldPorts extends Blockly.FieldDropdown implements Blockly.FieldCu
// Accessibility properties // Accessibility properties
contentDiv.setAttribute('role', 'menu'); contentDiv.setAttribute('role', 'menu');
contentDiv.setAttribute('aria-haspopup', 'true'); contentDiv.setAttribute('aria-haspopup', 'true');
let options = this.getOptions(); const options = this.getOptions();
options = options.sort();
for (let i = 0, option: any; option = options[i]; i++) { for (let i = 0, option: any; option = options[i]; i++) {
let content = (options[i] as any)[0]; // Human-readable text or image. let content = (options[i] as any)[0]; // Human-readable text or image.
const value = (options[i] as any)[1]; // Language-neutral value. const value = (options[i] as any)[1]; // Language-neutral value.

View File

@ -1,108 +0,0 @@
/// <reference path="../node_modules/pxt-core/localtypings/blockly.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
export interface FieldTurnRatioOptions extends Blockly.FieldCustomOptions {
}
export class FieldTurnRatio extends Blockly.FieldSlider implements Blockly.FieldCustom {
public isFieldCustom_ = true;
private params: any;
private path_: SVGPathElement;
private reporter_: SVGTextElement;
/**
* Class for a color wheel field.
* @param {number|string} value The initial content of the field.
* @param {Function=} opt_validator An optional function that is called
* to validate any constraints on what the user entered. Takes the new
* text as an argument and returns either the accepted text, a replacement
* text, or null to abort the change.
* @extends {Blockly.FieldNumber}
* @constructor
*/
constructor(value_: any, params: FieldTurnRatioOptions, opt_validator?: Function) {
super(String(value_), '-100', '100', null, '10', 'TurnRatio', opt_validator);
this.params = params;
(this as any).sliderColor_ = '#a8aaa8';
}
static HALF = 80;
static HANDLE_RADIUS = 30;
static RADIUS = FieldTurnRatio.HALF - FieldTurnRatio.HANDLE_RADIUS - 1;
createLabelDom_(labelText: string) {
let labelContainer = document.createElement('div');
let svg = Blockly.utils.createSvgElement('svg', {
'xmlns': 'http://www.w3.org/2000/svg',
'xmlns:html': 'http://www.w3.org/1999/xhtml',
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
'version': '1.1',
'height': (FieldTurnRatio.HALF + FieldTurnRatio.HANDLE_RADIUS + 10) + 'px',
'width': (FieldTurnRatio.HALF * 2) + 'px'
}, labelContainer);
let defs = Blockly.utils.createSvgElement('defs', {}, svg);
let marker = Blockly.utils.createSvgElement('marker', {
'id': 'head',
'orient': "auto",
'markerWidth': '2',
'markerHeight': '4',
'refX': '0.1', 'refY': '1.5'
}, defs);
let markerPath = Blockly.utils.createSvgElement('path', {
'd': 'M0,0 V3 L1.5,1.5 Z',
'fill': '#f12a21'
}, marker);
this.reporter_ = pxsim.svg.child(svg, "text", {
'x': FieldTurnRatio.HALF, 'y': 96,
'text-anchor': 'middle', 'alignment-baseline': 'middle',
'style': 'font-size: 50px',
'class': 'sim-text inverted number'
}) as SVGTextElement;
this.path_ = Blockly.utils.createSvgElement('path', {
'x1': FieldTurnRatio.HALF,
'y1': FieldTurnRatio.HALF,
'marker-end': 'url(#head)',
'style': 'fill: none; stroke: #f12a21; stroke-width: 10'
}, svg);
this.updateGraph_();
let readout = document.createElement('span');
readout.setAttribute('class', 'blocklyFieldSliderReadout');
return [labelContainer, readout];
};
updateGraph_() {
if (!this.path_) {
return;
}
let v = goog.math.clamp(parseFloat(this.getText()), -100, 100);
if (isNaN(v)) {
v = 0;
}
const x = goog.math.clamp(parseFloat(this.getText()), -100, 100) / 100;
const theta = x * Math.PI / 2;
const cx = FieldTurnRatio.HALF;
const cy = FieldTurnRatio.HALF - 14;
const gamma = Math.PI - 2 * theta;
const r = FieldTurnRatio.RADIUS;
const alpha = 0.2 + Math.abs(x) * 0.5;
const x1 = 0;
const y1 = r * alpha;
const y2 = r * Math.sin(Math.PI / 2 - theta);
const x2 = r * Math.cos(Math.PI / 2 - theta);
const y3 = y2 - r * alpha * Math.cos(2 * theta);
const x3 = x2 - r * alpha * Math.sin(2 * theta);
const d = `M ${cx} ${cy} C ${cx} ${cy - y1} ${cx + x3} ${cy - y3} ${cx + x2} ${cy - y2}`;
this.path_.setAttribute('d', d);
this.reporter_.textContent = `${v}`;
}
setReadout_(readout: Element, value: string) {
this.updateGraph_();
}
}

View File

@ -1,9 +1,12 @@
{ {
"chassis.Chassis": "A differential drive robot", "chassis.Chassis": "A differential drive robot",
"chassis.Chassis.drive": "Makes a differential drive robot move with a given speed (cm/s) and rotation rate (deg/s)\nusing a unicycle model.", "chassis.Chassis.drive": "Makes a differential drive robot move with a given speed (cm/s) and rotation rate (deg/s)\nusing a unicycle model.",
"chassis.Chassis.driveFor": "Makes a differential drive robot move with a given speed (cm/s) and rotation rate (deg/s)\nusing a unicycle model.",
"chassis.Chassis.driveFor|param|rotationSpeed": "rotation of the robot around the center point, eg: 30",
"chassis.Chassis.driveFor|param|speed": "speed of the center point between motors, eg: 10",
"chassis.Chassis.driveFor|param|value": "the amount of movement, eg: 2",
"chassis.Chassis.drive|param|rotationSpeed": "rotation of the robot around the center point, eg: 30", "chassis.Chassis.drive|param|rotationSpeed": "rotation of the robot around the center point, eg: 30",
"chassis.Chassis.drive|param|speed": "speed of the center point between motors, eg: 10", "chassis.Chassis.drive|param|speed": "speed of the center point between motors, eg: 10",
"chassis.Chassis.drive|param|value": "the amount of movement, eg: 2",
"chassis.Chassis.setMotors": "Sets the motors used by the chassis, default is B+C", "chassis.Chassis.setMotors": "Sets the motors used by the chassis, default is B+C",
"chassis.Chassis.setProperty": "Sets a property of the robot", "chassis.Chassis.setProperty": "Sets a property of the robot",
"chassis.Chassis.setProperty|param|property": "the property to set", "chassis.Chassis.setProperty|param|property": "the property to set",

View File

@ -1,6 +1,7 @@
{ {
"ChassisProperty.BaseLength|block": "base length (cm)", "ChassisProperty.BaseLength|block": "base length (cm)",
"ChassisProperty.WheelRadius|block": "wheel radius (cm)", "ChassisProperty.WheelRadius|block": "wheel radius (cm)",
"chassis.Chassis.driveFor|block": "drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s|for %value|%unit",
"chassis.Chassis.drive|block": "drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s", "chassis.Chassis.drive|block": "drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s",
"chassis.Chassis.setMotors|block": "set %chassis|motors to %motors", "chassis.Chassis.setMotors|block": "set %chassis|motors to %motors",
"chassis.Chassis.setProperty|block": "set %chassis|%property|to %value", "chassis.Chassis.setProperty|block": "set %chassis|%property|to %value",

View File

@ -29,13 +29,26 @@ namespace chassis {
* using a unicycle model. * using a unicycle model.
* @param speed speed of the center point between motors, eg: 10 * @param speed speed of the center point between motors, eg: 10
* @param rotationSpeed rotation of the robot around the center point, eg: 30 * @param rotationSpeed rotation of the robot around the center point, eg: 30
* @param value the amount of movement, eg: 2
* @param unit
*/ */
//% blockId=motorDrive block="drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s" //% blockId=motorDrive block="drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s"
//% inlineInputMode=inline //% inlineInputMode=inline
//% weight=99 blockGap=8
drive(speed: number, rotationSpeed: number) {
this.driveFor(speed, rotationSpeed, 0, MoveUnit.Degrees);
}
/**
* Makes a differential drive robot move with a given speed (cm/s) and rotation rate (deg/s)
* using a unicycle model.
* @param speed speed of the center point between motors, eg: 10
* @param rotationSpeed rotation of the robot around the center point, eg: 30
* @param value the amount of movement, eg: 2
* @param unit
*/
//% blockId=motorDriveFor block="drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s|for %value|%unit"
//% inlineInputMode=inline
//% weight=95 blockGap=8 //% weight=95 blockGap=8
drive(speed: number, rotationSpeed: number, value: number = 0, unit: MoveUnit = MoveUnit.MilliSeconds) { driveFor(speed: number, rotationSpeed: number, value: number, unit: MoveUnit) {
// speed is expressed in % // speed is expressed in %
const R = this.wheelRadius; // cm const R = this.wheelRadius; // cm
const L = this.baseLength; // cm const L = this.baseLength; // cm
@ -52,7 +65,7 @@ namespace chassis {
const sr = vr / maxw * 100; // % const sr = vr / maxw * 100; // %
const sl = vl / maxw * 100; // % const sl = vl / maxw * 100; // %
this.motors.tank(sr, sl, value, unit) this.motors.tankFor(sr, sl, value, unit)
} }
/** /**

View File

@ -11,8 +11,5 @@
"sensors.ColorSensor.onLightChanged|param|handler": "the code to run when detected", "sensors.ColorSensor.onLightChanged|param|handler": "the code to run when detected",
"sensors.ColorSensor.pauseForColor": "Waits for the given color to be detected", "sensors.ColorSensor.pauseForColor": "Waits for the given color to be detected",
"sensors.ColorSensor.pauseForColor|param|color": "the color to detect", "sensors.ColorSensor.pauseForColor|param|color": "the color to detect",
"sensors.ColorSensor.pauseForLight": "Waits for the given color to be detected", "sensors.ColorSensor.pauseForLight": "Waits for the given color to be detected"
"sensors.ColorSensor.setThreshold": "Sets a threshold value",
"sensors.ColorSensor.setThreshold|param|condition": "the dark or bright light condition",
"sensors.ColorSensor.setThreshold|param|value": "the value threshold"
} }

View File

@ -19,13 +19,11 @@
"sensors.ColorSensor.onLightChanged|block": "on %sensor|%mode|%condition", "sensors.ColorSensor.onLightChanged|block": "on %sensor|%mode|%condition",
"sensors.ColorSensor.pauseForColor|block": "pause %sensor|for color %color", "sensors.ColorSensor.pauseForColor|block": "pause %sensor|for color %color",
"sensors.ColorSensor.pauseForLight|block": "pause %sensor|for %mode|%condition", "sensors.ColorSensor.pauseForLight|block": "pause %sensor|for %mode|%condition",
"sensors.ColorSensor.setThreshold|block": "set %sensor|%condition|to %value",
"sensors.color1|block": "color 1", "sensors.color1|block": "color 1",
"sensors.color2|block": "color 2", "sensors.color2|block": "color 2",
"sensors.color3|block": "color 3", "sensors.color3|block": "color 3",
"sensors.color4|block": "color 4", "sensors.color4|block": "color 4",
"sensors|block": "sensors", "sensors|block": "sensors",
"{id:category}Sensors": "Sensors", "{id:category}Sensors": "Sensors",
"{id:group}Color Sensor": "Color Sensor", "{id:group}Color Sensor": "Color Sensor"
"{id:group}Threshold": "Threshold"
} }

View File

@ -152,7 +152,7 @@ namespace sensors {
//% parts="colorsensor" //% parts="colorsensor"
//% blockNamespace=sensors //% blockNamespace=sensors
//% sensor.fieldEditor="ports" //% sensor.fieldEditor="ports"
//% weight=98 //% weight=99
//% group="Color Sensor" //% group="Color Sensor"
color(): ColorSensorColor { color(): ColorSensorColor {
this.setMode(ColorSensorMode.Color) this.setMode(ColorSensorMode.Color)
@ -221,21 +221,6 @@ namespace sensors {
reflectedLight() { reflectedLight() {
return this.light(LightIntensityMode.Reflected); return this.light(LightIntensityMode.Reflected);
} }
/**
* Sets a threshold value
* @param condition the dark or bright light condition
* @param value the value threshold
*/
//% blockId=colorSetThreshold block="set %sensor|%condition|to %value"
//% group="Threshold" blockGap=8 weight=90
//% value.min=0 value.max=100
setThreshold(condition: LightCondition, value: number) {
if (condition == LightCondition.Dark)
this.thresholdDetector.setLowThreshold(value)
else
this.thresholdDetector.setHighThreshold(value);
}
} }
//% whenUsed block="color 3" weight=90 fixedInstance jres=icons.port3 //% whenUsed block="color 3" weight=90 fixedInstance jres=icons.port3

View File

@ -1,5 +1,4 @@
{ {
"BrickLight": "Patterns for lights under the buttons.",
"ButtonEvent": "User interaction on buttons", "ButtonEvent": "User interaction on buttons",
"Draw": "Drawing modes", "Draw": "Drawing modes",
"Image.buffer": "Returns the underlaying Buffer object.", "Image.buffer": "Returns the underlaying Buffer object.",
@ -7,15 +6,14 @@
"Image.draw": "Draw an image on the screen.", "Image.draw": "Draw an image on the screen.",
"Image.height": "Returns the height of an image.", "Image.height": "Returns the height of an image.",
"Image.width": "Returns the width of an image.", "Image.width": "Returns the width of an image.",
"LightsPattern": "Patterns for lights under the buttons.",
"MMap.getNumber": "Read a number in specified format from the buffer.", "MMap.getNumber": "Read a number in specified format from the buffer.",
"MMap.ioctl": "Perform ioctl(2) on the underlaying file", "MMap.ioctl": "Perform ioctl(2) on the underlaying file",
"MMap.length": "Returns the length of a Buffer object.", "MMap.length": "Returns the length of a Buffer object.",
"MMap.lseek": "Set pointer on the underlaying file.",
"MMap.read": "Perform read(2) on the underlaying file", "MMap.read": "Perform read(2) on the underlaying file",
"MMap.setNumber": "Write a number in specified format in the buffer.", "MMap.setNumber": "Write a number in specified format in the buffer.",
"MMap.slice": "Read a range of bytes into a buffer.", "MMap.slice": "Read a range of bytes into a buffer.",
"MMap.write": "Perform write(2) on the underlaying file", "MMap.write": "Perform write(2) on the underlaying file",
"SeekWhence": "Mode for lseek()",
"brick.Button": "Generic button class, for device buttons and sensors.", "brick.Button": "Generic button class, for device buttons and sensors.",
"brick.Button.isPressed": "Check if button is currently pressed or not.", "brick.Button.isPressed": "Check if button is currently pressed or not.",
"brick.Button.onEvent": "Do something when a button or sensor is clicked, up or down.", "brick.Button.onEvent": "Do something when a button or sensor is clicked, up or down.",
@ -30,9 +28,11 @@
"brick.buttonRight": "Right button on the EV3 Brick.", "brick.buttonRight": "Right button on the EV3 Brick.",
"brick.buttonUp": "Up button on the EV3 Brick.", "brick.buttonUp": "Up button on the EV3 Brick.",
"brick.clearScreen": "Clears the screen", "brick.clearScreen": "Clears the screen",
"brick.lightPattern": "Pattern block.",
"brick.lightPattern|param|pattern": "the lights pattern to use. eg: LightsPattern.Green",
"brick.printPorts": "Prints the port states on the screen", "brick.printPorts": "Prints the port states on the screen",
"brick.setLight": "Set lights.", "brick.setLight": "Set lights.",
"brick.setLight|param|pattern": "the lights pattern to use. eg: BrickLight.Orange", "brick.setLight|param|pattern": "the lights pattern to use.",
"brick.showImage": "Shows an image on screen", "brick.showImage": "Shows an image on screen",
"brick.showImage|param|image": "image to draw", "brick.showImage|param|image": "image to draw",
"brick.showNumber": "Shows a number on the screen", "brick.showNumber": "Shows a number on the screen",
@ -52,9 +52,6 @@
"console.logValue|param|value": "to write", "console.logValue|param|value": "to write",
"console.sendToScreen": "Sends the log messages to the brick screen and uses the brick up and down buttons to scroll.", "console.sendToScreen": "Sends the log messages to the brick screen and uses the brick up and down buttons to scroll.",
"control": "Program controls and events.", "control": "Program controls and events.",
"control.Timer.millis": "Gets the elapsed time in millis",
"control.Timer.reset": "Resets the timer",
"control.Timer.seconds": "Gets the elapsed time in seconds",
"control.allocateNotifyEvent": "Allocates the next user notification event", "control.allocateNotifyEvent": "Allocates the next user notification event",
"control.deviceFirmwareVersion": "Determine the version of system software currently running.", "control.deviceFirmwareVersion": "Determine the version of system software currently running.",
"control.dmesg": "Write data to DMESG debugging buffer.", "control.dmesg": "Write data to DMESG debugging buffer.",
@ -64,8 +61,6 @@
"control.raiseEvent|param|value": "Component specific code indicating the cause of the event.", "control.raiseEvent|param|value": "Component specific code indicating the cause of the event.",
"motors.Motor.angle": "Gets motor angle.", "motors.Motor.angle": "Gets motor angle.",
"motors.Motor.clearCounts": "Clears the motor count", "motors.Motor.clearCounts": "Clears the motor count",
"motors.Motor.setRegulated": "Indicates if the motor speed should be regulated. Default is true.",
"motors.Motor.setRegulated|param|value": "true for regulated motor",
"motors.Motor.speed": "Gets motor actual speed.", "motors.Motor.speed": "Gets motor actual speed.",
"motors.Motor.tacho": "Gets motor tachometer count.", "motors.Motor.tacho": "Gets motor tachometer count.",
"motors.Motor.toString": "Returns the status of the motor", "motors.Motor.toString": "Returns the status of the motor",
@ -76,7 +71,7 @@
"motors.MotorBase.setBrake": "Sets the automatic brake on or off when the motor is off", "motors.MotorBase.setBrake": "Sets the automatic brake on or off when the motor is off",
"motors.MotorBase.setBrake|param|brake": "a value indicating if the motor should break when off", "motors.MotorBase.setBrake|param|brake": "a value indicating if the motor should break when off",
"motors.MotorBase.setReversed": "Reverses the motor polarity", "motors.MotorBase.setReversed": "Reverses the motor polarity",
"motors.MotorBase.setSpeed": "Sets the motor speed for limited time or distance.", "motors.MotorBase.setSpeed": "Sets the motor speed for limited time or distance",
"motors.MotorBase.setSpeed|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50", "motors.MotorBase.setSpeed|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50",
"motors.MotorBase.setSpeed|param|unit": "(optional) unit of the value", "motors.MotorBase.setSpeed|param|unit": "(optional) unit of the value",
"motors.MotorBase.setSpeed|param|value": "(optional) measured distance or rotation", "motors.MotorBase.setSpeed|param|value": "(optional) measured distance or rotation",

View File

@ -1,17 +1,17 @@
{ {
"BrickLight.GreenFlash|block": "green flash",
"BrickLight.GreenPulse|block": "green pulse",
"BrickLight.Green|block": "green",
"BrickLight.Off|block": "off",
"BrickLight.OrangeFlash|block": "orange flash",
"BrickLight.OrangePulse|block": "orange pulse",
"BrickLight.Orange|block": "orange",
"BrickLight.RedFlash|block": "red flash",
"BrickLight.RedPulse|block": "red pulse",
"BrickLight.Red|block": "red",
"ButtonEvent.Click|block": "click", "ButtonEvent.Click|block": "click",
"ButtonEvent.Down|block": "down", "ButtonEvent.Down|block": "down",
"ButtonEvent.Up|block": "up", "ButtonEvent.Up|block": "up",
"LightsPattern.GreenFlash|block": "Flashing Green",
"LightsPattern.GreenPulse|block": "Pulsing Green",
"LightsPattern.Green|block": "Green",
"LightsPattern.Off|block": "Off",
"LightsPattern.OrangeFlash|block": "Flashing Orange",
"LightsPattern.OrangePulse|block": "Pulsing Orange",
"LightsPattern.Orange|block": "Orange",
"LightsPattern.RedFlash|block": "Flashing Red",
"LightsPattern.RedPulse|block": "Pulsing Red",
"LightsPattern.Red|block": "Red",
"MoveUnit.Degrees|block": "degrees", "MoveUnit.Degrees|block": "degrees",
"MoveUnit.MilliSeconds|block": "milliseconds", "MoveUnit.MilliSeconds|block": "milliseconds",
"MoveUnit.Rotations|block": "rotations", "MoveUnit.Rotations|block": "rotations",
@ -30,14 +30,15 @@
"brick.Button.pauseUntil|block": "pause until %button|%event", "brick.Button.pauseUntil|block": "pause until %button|%event",
"brick.Button.wasPressed|block": "%button|was pressed", "brick.Button.wasPressed|block": "%button|was pressed",
"brick.batteryLevel|block": "battery level", "brick.batteryLevel|block": "battery level",
"brick.buttonDown|block": "button down", "brick.buttonDown|block": "down",
"brick.buttonEnter|block": "button enter", "brick.buttonEnter|block": "enter",
"brick.buttonLeft|block": "button left", "brick.buttonLeft|block": "left",
"brick.buttonRight|block": "button right", "brick.buttonRight|block": "right",
"brick.buttonUp|block": "button up", "brick.buttonUp|block": "up",
"brick.clearScreen|block": "clear screen", "brick.clearScreen|block": "clear screen",
"brick.lightPattern|block": "%pattern",
"brick.printPorts|block": "print ports", "brick.printPorts|block": "print ports",
"brick.setLight|block": "set light to %pattern", "brick.setLight|block": "set light to %pattern=led_pattern",
"brick.showImage|block": "show image %image=screen_image_picker", "brick.showImage|block": "show image %image=screen_image_picker",
"brick.showNumber|block": "show number %name|at line %line", "brick.showNumber|block": "show number %name|at line %line",
"brick.showString|block": "show string %text|at line %line", "brick.showString|block": "show string %text|at line %line",
@ -47,31 +48,17 @@
"console.log|block": "console|log %text", "console.log|block": "console|log %text",
"console.sendToScreen|block": "send console to screen", "console.sendToScreen|block": "send console to screen",
"console|block": "console", "console|block": "console",
"control.Timer.millis|block": "%timer|millis",
"control.Timer.reset|block": "%timer|reset",
"control.Timer.seconds|block": "%timer|seconds",
"control.raiseEvent|block": "raise event|from %src|with value %value", "control.raiseEvent|block": "raise event|from %src|with value %value",
"control.timer1|block": "timer 1",
"control.timer2|block": "timer 2",
"control.timer3|block": "timer 3",
"control.timer4|block": "timer 4",
"control.timer5|block": "timer 5",
"control.timer6|block": "timer 6",
"control.timer7|block": "timer 7",
"control.timer8|block": "timer 8",
"control|block": "control", "control|block": "control",
"motors.Motor.angle|block": "%motor|angle", "motors.Motor.angle|block": "%motor|angle",
"motors.Motor.clearCounts|block": "%motor|clear counts", "motors.Motor.clearCounts|block": "%motor|clear counts",
"motors.Motor.setRegulated|block": "set %motor|regulated %value",
"motors.Motor.speed|block": "%motor|speed", "motors.Motor.speed|block": "%motor|speed",
"motors.Motor.tacho|block": "%motor|tacho", "motors.Motor.tacho|block": "%motor|tacho",
"motors.MotorBase.pauseUntilReady|block": "%motor|pause until ready", "motors.MotorBase.pauseUntilReady|block": "%motor|pause until ready",
"motors.MotorBase.reset|block": "%motors|reset",
"motors.MotorBase.setBrake|block": "set %motor|brake %brake", "motors.MotorBase.setBrake|block": "set %motor|brake %brake",
"motors.MotorBase.setReversed|block": "set %motor|reversed %reversed", "motors.MotorBase.setReversed|block": "set %motor|reversed %reversed",
"motors.MotorBase.setSpeed|block": "set %motor|speed to %speed=motorSpeedPicker|%", "motors.MotorBase.setSpeed|block": "set %motor|speed to %speed=motorSpeedPicker|%",
"motors.MotorBase.stop|block": "%motors|stop", "motors.SynchedMotorPair.steer|block": "steer %chassis|turn ratio %turnRatio|speed %speed=motorSpeedPicker|%",
"motors.SynchedMotorPair.steer|block": "steer %chassis|turn ratio %turnRatio=motorTurnRatioPicker|speed %speed=motorSpeedPicker|%",
"motors.SynchedMotorPair.tank|block": "tank %motors|%speedLeft=motorSpeedPicker|%|%speedRight=motorSpeedPicker|%", "motors.SynchedMotorPair.tank|block": "tank %motors|%speedLeft=motorSpeedPicker|%|%speedRight=motorSpeedPicker|%",
"motors.largeAB|block": "large A+B", "motors.largeAB|block": "large A+B",
"motors.largeAD|block": "large A+D", "motors.largeAD|block": "large A+D",
@ -103,6 +90,7 @@
"{id:category}Serial": "Serial", "{id:category}Serial": "Serial",
"{id:group}Buttons": "Buttons", "{id:group}Buttons": "Buttons",
"{id:group}Counters": "Counters", "{id:group}Counters": "Counters",
"{id:group}Light": "Light",
"{id:group}More": "More", "{id:group}More": "More",
"{id:group}Move": "Move", "{id:group}Move": "Move",
"{id:group}Screen": "Screen", "{id:group}Screen": "Screen",

View File

@ -2,35 +2,35 @@
/** /**
* Patterns for lights under the buttons. * Patterns for lights under the buttons.
*/ */
const enum BrickLight { const enum LightsPattern {
//% block=off enumval=0 //% block=Off enumval=0
//% blockIdentity=brick.lightPattern //% blockIdentity=brick.lightPattern
Off = 0, Off = 0,
//% block=green enumval=1 //% block=Green enumval=1
//% blockIdentity=brick.lightPattern //% blockIdentity=brick.lightPattern
Green = 1, Green = 1,
//% block=red enumval=2 //% block=Red enumval=2
//% blockIdentity=brick.lightPattern //% blockIdentity=brick.lightPattern
Red = 2, Red = 2,
//% block=orange enumval=3 //% block=Orange enumval=3
//% blockIdentity=brick.lightPattern //% blockIdentity=brick.lightPattern
Orange = 3, Orange = 3,
//% block="green flash" enumval=4 //% block="Flashing Green" enumval=4
//% blockIdentity=brick.lightPattern //% blockIdentity=brick.lightPattern
GreenFlash = 4, GreenFlash = 4,
//% block="red flash" enumval=5 //% block="Flashing Red" enumval=5
//% blockIdentity=brick.lightPattern //% blockIdentity=brick.lightPattern
RedFlash = 5, RedFlash = 5,
//% block="orange flash" enumval=6 //% block="Flashing Orange" enumval=6
//% blockIdentity=brick.lightPattern //% blockIdentity=brick.lightPattern
OrangeFlash = 6, OrangeFlash = 6,
//% block="green pulse" enumval=7 //% block="Pulsing Green" enumval=7
//% blockIdentity=brick.lightPattern //% blockIdentity=brick.lightPattern
GreenPulse = 7, GreenPulse = 7,
//% block="red pulse" enumval=8 //% block="Pulsing Red" enumval=8
//% blockIdentity=brick.lightPattern //% blockIdentity=brick.lightPattern
RedPulse = 8, RedPulse = 8,
//% block="orange pulse" enumval=9 //% block="Pulsing Orange" enumval=9
//% blockIdentity=brick.lightPattern //% blockIdentity=brick.lightPattern
OrangePulse = 9, OrangePulse = 9,
} }
@ -170,7 +170,6 @@ namespace brick {
// this needs to be done in query(), which is run without the main JS execution mutex // this needs to be done in query(), which is run without the main JS execution mutex
// otherwise, while(true){} will lock the device // otherwise, while(true){} will lock the device
if (ret & DAL.BUTTON_ID_ESCAPE) { if (ret & DAL.BUTTON_ID_ESCAPE) {
motors.stopAllMotors(); // ensuring that all motors are off
control.reset() control.reset()
} }
return ret return ret
@ -204,31 +203,31 @@ namespace brick {
/** /**
* Enter button on the EV3 Brick. * Enter button on the EV3 Brick.
*/ */
//% whenUsed block="button enter" weight=95 fixedInstance //% whenUsed block="enter" weight=95 fixedInstance
export const buttonEnter: Button = new DevButton(DAL.BUTTON_ID_ENTER) export const buttonEnter: Button = new DevButton(DAL.BUTTON_ID_ENTER)
/** /**
* Left button on the EV3 Brick. * Left button on the EV3 Brick.
*/ */
//% whenUsed block="button left" weight=95 fixedInstance //% whenUsed block="left" weight=95 fixedInstance
export const buttonLeft: Button = new DevButton(DAL.BUTTON_ID_LEFT) export const buttonLeft: Button = new DevButton(DAL.BUTTON_ID_LEFT)
/** /**
* Right button on the EV3 Brick. * Right button on the EV3 Brick.
*/ */
//% whenUsed block="button right" weight=94 fixedInstance //% whenUsed block="right" weight=94 fixedInstance
export const buttonRight: Button = new DevButton(DAL.BUTTON_ID_RIGHT) export const buttonRight: Button = new DevButton(DAL.BUTTON_ID_RIGHT)
/** /**
* Up button on the EV3 Brick. * Up button on the EV3 Brick.
*/ */
//% whenUsed block="button up" weight=95 fixedInstance //% whenUsed block="up" weight=95 fixedInstance
export const buttonUp: Button = new DevButton(DAL.BUTTON_ID_UP) export const buttonUp: Button = new DevButton(DAL.BUTTON_ID_UP)
/** /**
* Down button on the EV3 Brick. * Down button on the EV3 Brick.
*/ */
//% whenUsed block="button down" weight=95 fixedInstance //% whenUsed block="down" weight=95 fixedInstance
export const buttonDown: Button = new DevButton(DAL.BUTTON_ID_DOWN) export const buttonDown: Button = new DevButton(DAL.BUTTON_ID_DOWN)
} }
@ -252,21 +251,32 @@ namespace control {
} }
namespace brick { namespace brick {
// the brick starts with the red color let currPattern: LightsPattern
let currPattern: BrickLight = BrickLight.Red;
/** /**
* Set lights. * Set lights.
* @param pattern the lights pattern to use. eg: BrickLight.Orange * @param pattern the lights pattern to use.
*/ */
//% blockId=setLights block="set light to %pattern" //% blockId=setLights block="set light to %pattern=led_pattern"
//% weight=100 group="Buttons" //% weight=100 group="Buttons"
export function setLight(pattern: BrickLight): void { export function setLight(pattern: number): void {
if (currPattern === pattern) if (currPattern === pattern)
return return
currPattern = pattern; currPattern = pattern
const cmd = output.createBuffer(2) let cmd = output.createBuffer(2)
cmd[0] = pattern + 48 cmd[0] = pattern + 48
brick.internal.getBtnsMM().write(cmd) brick.internal.getBtnsMM().write(cmd)
} }
/**
* Pattern block.
* @param pattern the lights pattern to use. eg: LightsPattern.Green
*/
//% blockId=led_pattern block="%pattern"
//% shim=TD_ID colorSecondary="#6e9a36" group="Light"
//% blockHidden=true useEnumVal=1 pattern.fieldOptions.decompileLiterals=1
export function lightPattern(pattern: LightsPattern): number {
return pattern;
}
} }

View File

@ -58,7 +58,7 @@ namespace console {
namespace console.screen { namespace console.screen {
const maxLines = 100; const maxLines = 100;
const screenLines = 10; const screenLines = 8;
let lines: string[]; let lines: string[];
let scrollPosition = 0; let scrollPosition = 0;
@ -66,8 +66,8 @@ namespace console.screen {
if (!lines) { if (!lines) {
lines = []; lines = [];
console.addListener(log); console.addListener(log);
brick.buttonUp.onEvent(ButtonEvent.Click, () => scroll(-3)) brick.buttonUp.onEvent(ButtonEvent.Click, () => scroll(-1))
brick.buttonDown.onEvent(ButtonEvent.Click, () => scroll(3)) brick.buttonDown.onEvent(ButtonEvent.Click, () => scroll(1))
} }
} }

11
libs/core/enums.d.ts vendored
View File

@ -1,17 +1,6 @@
// Auto-generated. Do not edit. // Auto-generated. Do not edit.
/**
* Mode for lseek()
*/
declare const enum SeekWhence {
Set = 0,
Current = 1,
End = 2,
}
/** /**
* Drawing modes * Drawing modes
*/ */

View File

@ -114,7 +114,23 @@
"progressWaterLevel3": "iVBORw0KGgoAAAANSUhEUgAAALIAAACAAQAAAACHQw5jAAABP0lEQVR42u2VMWrEMBBFRxGsGrNqXYT4CltuFV9lj5EqVlhImyPkKoKFbJcrrHKCKJ2XKFb+BGxsGBdbBRJ/mGHm+VtjJGNT/srQO6cG8cnFKXvKLVdHRFcjfXD3xDyybY9IFVJgbpgHtilEa5E8XJ1m/gJbVwJFXuwRrqSYa9hSCZt/A1/B1VLjqdMG1mu0bgeD4W5Te2r1A6YVJne0qfNP57fWU9AY5dYKd29tDgodldoTqagjGaoc3VAiiibQmlg1ApeIQIjuufDUq+C0Q1z1xaJFi/60iluZ28aJ3Jy9yPU5iFxlmesZvsry+kUz8/z/5qTuZKyizM2F3IYZfnDyuR7kc61fL+P4qYmq0mCZ+tuhfHZjPvhV8iKnMVejuZNXrjnK3O77aeo03hEzNGqyUcbNnJdfPjqLFv2+vgH+JtBJ4nz/SAAAAABJRU5ErkJggg==", "progressWaterLevel3": "iVBORw0KGgoAAAANSUhEUgAAALIAAACAAQAAAACHQw5jAAABP0lEQVR42u2VMWrEMBBFRxGsGrNqXYT4CltuFV9lj5EqVlhImyPkKoKFbJcrrHKCKJ2XKFb+BGxsGBdbBRJ/mGHm+VtjJGNT/srQO6cG8cnFKXvKLVdHRFcjfXD3xDyybY9IFVJgbpgHtilEa5E8XJ1m/gJbVwJFXuwRrqSYa9hSCZt/A1/B1VLjqdMG1mu0bgeD4W5Te2r1A6YVJne0qfNP57fWU9AY5dYKd29tDgodldoTqagjGaoc3VAiiibQmlg1ApeIQIjuufDUq+C0Q1z1xaJFi/60iluZ28aJ3Jy9yPU5iFxlmesZvsry+kUz8/z/5qTuZKyizM2F3IYZfnDyuR7kc61fL+P4qYmq0mCZ+tuhfHZjPvhV8iKnMVejuZNXrjnK3O77aeo03hEzNGqyUcbNnJdfPjqLFv2+vgH+JtBJ4nz/SAAAAABJRU5ErkJggg==",
"systemAccept1": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAQElEQVR42mM4wMDMsP//X4b6//+AWI6h/p8dQ/2fOob6H/8YKj/+Y6h4/I+hxvkfQx07UJ4fiOf/A6sF6QHqBQDsYh9jNdETHwAAAABJRU5ErkJggg==", "systemAccept1": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAQElEQVR42mM4wMDMsP//X4b6//+AWI6h/p8dQ/2fOob6H/8YKj/+Y6h4/I+hxvkfQx07UJ4fiOf/A6sF6QHqBQDsYh9jNdETHwAAAABJRU5ErkJggg==",
"systemAccept2": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAQUlEQVR42mM4wMDMsP//X4YEBjYGB4ZHDA6MhxgcmJsYHNiZGNz4mBjcZZgYnPcwMTj+YGJw+ADECUxgtSA9QL0A+IIPxwiZFtwAAAAASUVORK5CYII=", "systemAccept2": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAQUlEQVR42mM4wMDMsP//X4YEBjYGB4ZHDA6MhxgcmJsYHNiZGNz4mBjcZZgYnPcwMTj+YGJw+ADECUxgtSA9QL0A+IIPxwiZFtwAAAAASUVORK5CYII=",
"systemAlert": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAVAQAAAAB0khOLAAAARUlEQVR42iXD0QmAIAAE0IvWCtqmMbLG8MtVhAZwjBvALyE85XzwoE/QO8f5WPsd0K+An6c3Jq8sThIUUVg9qfmDDRn7AD/WMAQEJ+pCAAAAAElFTkSuQmCC",
"systemBox": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAGklEQVR42mM4wMDMsP//X4b6//9IwiA9QL0AlQYkzY8nCoAAAAAASUVORK5CYII=", "systemBox": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAGklEQVR42mM4wMDMsP//X4b6//9IwiA9QL0AlQYkzY8nCoAAAAAASUVORK5CYII=",
"systemBusy0": "iVBORw0KGgoAAAANSUhEUgAAABMAAAAPAQAAAAAuP8mBAAAAMElEQVR42mPY/38Bg/x/BgbnHw4Msd8dGKLeA+k4IL0XSGdB6TioOFAepA6kHqgPAJCPFdTsOCPGAAAAAElFTkSuQmCC",
"systemBusy1": "iVBORw0KGgoAAAANSUhEUgAAAA8AAAATAQAAAABnuWoHAAAAOUlEQVR42mNoYGKw/8EAJO9/A6GrYQyv1jF8jWP4tY/hbx3D730M3+4xvH/HcO8bw90yhlvbGGDqAdjhGYsKgwC5AAAAAElFTkSuQmCC",
"systemDecline1": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAANUlEQVR42mM4wMDMsP//X4b6//8Y6urtGOrt6hjq5/xjqD8JxI+hGMQGiQHlwGqAakF6gHoBybUeX0RcSJEAAAAASUVORK5CYII=", "systemDecline1": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAANUlEQVR42mM4wMDMsP//X4b6//8Y6urtGOrt6hjq5/xjqD8JxI+hGMQGiQHlwGqAakF6gHoBybUeX0RcSJEAAAAASUVORK5CYII=",
"systemDecline2": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAANUlEQVR42mM4wMDMsP//X4YEBjYGx4ZDDA4HmxgckpkYHMyAWAaKQWyQGFAOpAakFqQHqBcAGz4QyzSHE/gAAAAASUVORK5CYII=" "systemDecline2": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAANUlEQVR42mM4wMDMsP//X4YEBjYGx4ZDDA4HmxgckpkYHMyAWAaKQWyQGFAOpAakFqQHqBcAGz4QyzSHE/gAAAAASUVORK5CYII=",
"systemDotEmpty": "iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQAAAAA31SuUAAAAYklEQVR42oWOMQ5AQBRE5yZ7FEfSKTmC25CQuILehkahkc12IvgjRqHUTPX/ew+MzsByNlhxGq7ochz90mFL9gmBFjCSGTxZoSUb1OTwTkquP/Md61cU8USWQzZ5VaCWp+oGeLZn9EklJaAAAAAASUVORK5CYII=",
"systemDotFull": "iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQAAAAA31SuUAAAAX0lEQVR42mP4/0H+H8P//sf/GP7V//nH8PeDfB3D7wPs+xi+MzDeY3jHAER3GBjKGG4wMJgx7GBgsGLYwMAgBSESGBh4CBAIxWC9YFPA5oFNBtsBtg1sL9gFYLeAXAUAPIwyHWLMTS8AAAAASUVORK5CYII=",
"systemEv3small": "iVBORw0KGgoAAAANSUhEUgAAACsAAAANAQAAAAAY06pGAAAAPUlEQVR42mNg4LFvYwACFEr+n32fPYiS5/8P5PLLyz8AUXwQqs8eSMn/b7H/D6IO1NmDBA/UgbTzP/gHpwBcwBWO2QYBDwAAAABJRU5ErkJggg==",
"systemPlay": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQAAAAA3iMLMAAAAMElEQVR42mP4Y8/wsZ/h+XOG858Z5v5k2POXwcaGoUYOhIAMIBcoCJQCKgAq+2MPAAFKFVmziLfGAAAAAElFTkSuQmCC",
"systemSlider0": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAEklEQVR42mM4YMBwfwPV0AEDAHmKKNims3dJAAAAAElFTkSuQmCC",
"systemSlider1": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAGklEQVR42mM4YMBwfwNFCAKuGjCc2sBwwAAAT7olG9TpXdAAAAAASUVORK5CYII=",
"systemSlider2": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAG0lEQVR42mM4YMBwfwM5CAJObWC4aoAgDxgAACpUJGftPg+WAAAAAElFTkSuQmCC",
"systemSlider3": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAG0lEQVR42mM4YMBwfwMJCAKuGjCc2oCFPGAAAPSIIz417p4OAAAAAElFTkSuQmCC",
"systemSlider4": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAG0lEQVR42mM4YMBwfwNhBAGnNjBcNcBHHjAAAMJ6IooqNLP/AAAAAElFTkSuQmCC",
"systemSlider5": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAG0lEQVR42mM4YMBwfwNOBAFXDRhObSCKPGAAAHfbIWHuFKlNAAAAAElFTkSuQmCC",
"systemSlider6": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAG0lEQVR42mM4YMBwfwM6goBTGxiuGpBGHjAAADklIK1PooVQAAAAAElFTkSuQmCC",
"systemSlider7": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAG0lEQVR42mM4YMBwfwMUQcBVA4ZTG8gkDxgAANmVH4SOiUHMAAAAAElFTkSuQmCC",
"systemSlider8": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAFElEQVR42mM4YMBwagPDVSqRBwwASoohT92wVBIAAAAASUVORK5CYII="
} }

View File

@ -220,10 +220,41 @@ namespace images {
//% fixedInstance jres blockIdentity=brick.__imagePicker //% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemAccept2 = screen.unpackPNG(hex``); export const systemAccept2 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker //% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemAlert = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemBox = screen.unpackPNG(hex``); export const systemBox = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker //% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemBusy0 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemBusy1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemDecline1 = screen.unpackPNG(hex``); export const systemDecline1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker //% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemDecline2 = screen.unpackPNG(hex``); export const systemDecline2 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker //% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemDotEmpty = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemDotFull = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemEv3small = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemPlay = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider0 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider2 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider3 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider4 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider5 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider6 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider7 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider8 = screen.unpackPNG(hex``);
} }

View File

@ -93,7 +93,7 @@ namespace sensors.internal {
init(); init();
return { return {
temp: analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.BatteryTemp), temp: analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.BatteryTemp),
current: Math.round(analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.BatteryCurrent) / 10) current: analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.BatteryCurrent)
} }
} }
@ -310,7 +310,7 @@ namespace sensors.internal {
return getUartNumber(fmt, off, this._port) return getUartNumber(fmt, off, this._port)
} }
reset() { protected reset() {
if (this.isActive()) uartReset(this._port); if (this.isActive()) uartReset(this._port);
} }
} }

View File

@ -7,16 +7,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
/**
* Mode for lseek()
*/
enum class SeekWhence {
Set = 0,
Current = 1,
End = 2,
};
namespace pxt { namespace pxt {
PXT_VTABLE_CTOR(MMap) { PXT_VTABLE_CTOR(MMap) {
length = 0; length = 0;
@ -121,10 +111,4 @@ int read(MMap *mmap, Buffer data) {
return ::read(mmap->fd, data->data, data->length); return ::read(mmap->fd, data->data, data->length);
} }
/** Set pointer on the underlaying file. */
//%
int lseek(MMap *mmap, int offset, SeekWhence whence) {
return ::lseek(mmap->fd, offset, (int)whence);
}
} }

View File

@ -11,15 +11,4 @@ namespace motors {
export function __speedPicker(speed: number): number { export function __speedPicker(speed: number): number {
return speed; return speed;
} }
/**
* A turn ratio picker
* @param turnratio the turn ratio, eg: 0
*/
//% blockId=motorTurnRatioPicker block="%turnratio" shim=TD_ID
//% turnratio.fieldEditor="turnratio" colorSecondary="#FFFFFF"
//% weight=0 blockHidden=1 turnRatio.fieldOptions.decompileLiterals=1
export function __turnRatioPicker(turnratio: number): number {
return turnratio;
}
} }

View File

@ -111,7 +111,7 @@ namespace motors {
* Stops all motors * Stops all motors
*/ */
//% blockId=motorStopAll block="stop all motors" //% blockId=motorStopAll block="stop all motors"
//% weight=1 //% weight=5
//% group="Move" //% group="Move"
export function stopAllMotors() { export function stopAllMotors() {
const b = mkCmd(Output.ALL, DAL.opOutputStop, 0) const b = mkCmd(Output.ALL, DAL.opOutputStop, 0)
@ -175,7 +175,7 @@ namespace motors {
*/ */
//% blockId=motorSetReversed block="set %motor|reversed %reversed" //% blockId=motorSetReversed block="set %motor|reversed %reversed"
//% reversed.fieldEditor=toggleonoff //% reversed.fieldEditor=toggleonoff
//% weight=59 blockGap=8 //% weight=59
//% group="Move" //% group="Move"
setReversed(reversed: boolean) { setReversed(reversed: boolean) {
this.init(); this.init();
@ -187,9 +187,7 @@ namespace motors {
/** /**
* Stops the motor(s). * Stops the motor(s).
*/ */
//% weight=6 blockGap=8 //%
//% group="Move"
//% blockId=motorStop block="%motors|stop"
stop() { stop() {
this.init(); this.init();
stop(this._port, this._brake); stop(this._port, this._brake);
@ -198,16 +196,14 @@ namespace motors {
/** /**
* Resets the motor(s). * Resets the motor(s).
*/ */
//% weight=5 //%
//% group="Move"
//% blockId=motorReset block="%motors|reset"
reset() { reset() {
this.init(); this.init();
reset(this._port); reset(this._port);
} }
/** /**
* Sets the motor speed for limited time or distance. * Sets the motor speed for limited time or distance
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50 * @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
* @param value (optional) measured distance or rotation * @param value (optional) measured distance or rotation
* @param unit (optional) unit of the value * @param unit (optional) unit of the value
@ -218,17 +214,10 @@ namespace motors {
setSpeed(speed: number, value: number = 0, unit: MoveUnit = MoveUnit.MilliSeconds) { setSpeed(speed: number, value: number = 0, unit: MoveUnit = MoveUnit.MilliSeconds) {
this.init(); this.init();
speed = Math.clamp(-100, 100, speed >> 0); speed = Math.clamp(-100, 100, speed >> 0);
// stop if speed is 0
if (!speed) { if (!speed) {
this.stop(); this.stop();
return; return;
} }
// special: 0 is infinity
if (value == 0) {
this._setSpeed(speed);
return;
}
// timed motor moves
let useSteps: boolean; let useSteps: boolean;
let stepsOrTime: number; let stepsOrTime: number;
switch (unit) { switch (unit) {
@ -251,8 +240,6 @@ namespace motors {
} }
this._move(useSteps, stepsOrTime, speed); this._move(useSteps, stepsOrTime, speed);
// wait till motor is done with this work
this.pauseUntilReady();
} }
/** /**
@ -282,12 +269,10 @@ namespace motors {
//% fixedInstances //% fixedInstances
export class Motor extends MotorBase { export class Motor extends MotorBase {
private _large: boolean; private _large: boolean;
private _regulated: boolean;
constructor(port: Output, large: boolean) { constructor(port: Output, large: boolean) {
super(port, () => this.__init(), (speed) => this.__setSpeed(speed), (steps, stepsOrTime, speed) => this.__move(steps, stepsOrTime, speed)); super(port, () => this.__init(), (speed) => this.__setSpeed(speed), (steps, stepsOrTime, speed) => this.__move(steps, stepsOrTime, speed));
this._large = large; this._large = large;
this._regulated = true;
this.markUsed(); this.markUsed();
} }
@ -303,7 +288,7 @@ namespace motors {
} }
private __setSpeed(speed: number) { private __setSpeed(speed: number) {
const b = mkCmd(this._port, this._regulated ? DAL.opOutputSpeed : DAL.opOutputPower, 1) const b = mkCmd(this._port, DAL.opOutputSpeed, 1)
b.setNumber(NumberFormat.Int8LE, 2, speed) b.setNumber(NumberFormat.Int8LE, 2, speed)
writePWM(b) writePWM(b)
if (speed) { if (speed) {
@ -317,24 +302,11 @@ namespace motors {
step1: 0, step1: 0,
step2: stepsOrTime, step2: stepsOrTime,
step3: 0, step3: 0,
speed: this._regulated ? speed : undefined, speed: speed,
power: this._regulated ? undefined : speed,
useBrake: this._brake useBrake: this._brake
}) })
} }
/**
* Indicates if the motor speed should be regulated. Default is true.
* @param value true for regulated motor
*/
//% blockId=outputMotorSetRegulated block="set %motor|regulated %value"
//% value.fieldEditor=toggleonoff
//% weight=58
//% group="Move"
setRegulated(value: boolean) {
this._regulated = value;
}
/** /**
* Gets motor actual speed. * Gets motor actual speed.
* @param motor the port which connects to the motor * @param motor the port which connects to the motor
@ -502,7 +474,7 @@ namespace motors {
* @param value (optional) move duration or rotation * @param value (optional) move duration or rotation
* @param unit (optional) unit of the value * @param unit (optional) unit of the value
*/ */
//% blockId=motorPairSteer block="steer %chassis|turn ratio %turnRatio=motorTurnRatioPicker|speed %speed=motorSpeedPicker|%" //% blockId=motorPairSteer block="steer %chassis|turn ratio %turnRatio|speed %speed=motorSpeedPicker|%"
//% weight=95 //% weight=95
//% turnRatio.min=-200 turnRatio=200 //% turnRatio.min=-200 turnRatio=200
//% inlineInputMode=inline //% inlineInputMode=inline

View File

@ -11,7 +11,6 @@
"mmap.cpp", "mmap.cpp",
"control.cpp", "control.cpp",
"console.ts", "console.ts",
"timer.ts",
"serialnumber.cpp", "serialnumber.cpp",
"buttons.ts", "buttons.ts",
"png.cpp", "png.cpp",

View File

@ -41,10 +41,6 @@ declare interface MMap {
/** Perform read(2) on the underlaying file */ /** Perform read(2) on the underlaying file */
//% shim=MMapMethods::read //% shim=MMapMethods::read
read(data: Buffer): int32; read(data: Buffer): int32;
/** Set pointer on the underlaying file. */
//% shim=MMapMethods::lseek
lseek(offset: int32, whence: SeekWhence): int32;
} }
declare namespace control { declare namespace control {

View File

@ -2,7 +2,7 @@ screen.clear()
brick.print("PXT!", 10, 30, Draw.Quad) brick.print("PXT!", 10, 30, Draw.Quad)
brick.drawRect(40, 40, 20, 10, Draw.Fill) brick.drawRect(40, 40, 20, 10, Draw.Fill)
brick.setLight(BrickLight.Orange) brick.setLight(LightsPattern.Orange)
brick.heart.doubled().draw(100, 50, Draw.Double | Draw.Transparent) brick.heart.doubled().draw(100, 50, Draw.Double | Draw.Transparent)
@ -12,7 +12,7 @@ brick.buttonEnter.onEvent(ButtonEvent.Click, () => {
brick.buttonLeft.onEvent(ButtonEvent.Click, () => { brick.buttonLeft.onEvent(ButtonEvent.Click, () => {
brick.drawRect(10, 70, 20, 10, Draw.Fill) brick.drawRect(10, 70, 20, 10, Draw.Fill)
brick.setLight(BrickLight.Red) brick.setLight(LightsPattern.Red)
brick.setFont(brick.microbitFont()) brick.setFont(brick.microbitFont())
}) })

View File

@ -1,51 +0,0 @@
namespace control {
//% fixedInstances
export class Timer {
start: number;
constructor() {
this.start = control.millis();
}
/**
* Gets the elapsed time in millis
*/
//% blockId=timerMillis block="%timer|millis"
millis(): number {
return control.millis() - this.start;
}
/**
* Gets the elapsed time in seconds
*/
//% blockId=timerSeconds block="%timer|seconds"
seconds(): number {
return this.millis() / 1000;
}
/**
* Resets the timer
*/
//% blockId=timerRest block="%timer|reset"
reset() {
this.start = control.millis();
}
}
//% whenUsed fixedInstance block="timer 1"
export const timer1 = new Timer();
//% whenUsed fixedInstance block="timer 2"
export const timer2 = new Timer();
//% whenUsed fixedInstance block="timer 3"
export const timer3 = new Timer();
//% whenUsed fixedInstance block="timer 4"
export const timer4 = new Timer();
//% whenUsed fixedInstance block="timer 5"
export const timer5 = new Timer();
//% whenUsed fixedInstance block="timer 6"
export const timer6 = new Timer();
//% whenUsed fixedInstance block="timer 7"
export const timer7 = new Timer();
//% whenUsed fixedInstance block="timer 8"
export const timer8 = new Timer();
}

View File

@ -1,3 +0,0 @@
# Datalog
A tiny libraty to create CSV datalog files.

View File

@ -1,8 +0,0 @@
{
"datalog.addRow": "Starts a row of data",
"datalog.addValue": "Adds a cell to the row of data",
"datalog.addValue|param|name": "name of the cell, eg: \"x\"",
"datalog.addValue|param|value": "value of the cell, eg: 0",
"datalog.setFile": "Starts a new data logger for the given file",
"datalog.setStorage": "* @param storage custom storage solution"
}

View File

@ -1,6 +0,0 @@
{
"datalog.addRow|block": "datalog add row",
"datalog.addValue|block": "datalog add %name|=%value",
"datalog|block": "datalog",
"{id:category}Datalog": "Datalog"
}

View File

@ -1,90 +0,0 @@
//% weight=100 color=#0fbc11 icon=""
namespace datalog {
let _headers: string[] = undefined;
let _headersLength: number;
let _values: number[];
let _start: number;
let _filename = "data.csv";
let _storage: storage.Storage = storage.temporary;
function clear() {
_headers = undefined;
_values = undefined;
}
function init() {
if (!_headers) {
_headers = [];
_headersLength = 0;
_start = control.millis();
_storage.remove(_filename);
}
_values = [];
}
function commit() {
// write row if any data
if (_values && _values.length > 0) {
// write headers for the first row
if (!_headersLength) {
_storage.appendCSVHeaders(_filename, _headers);
_headersLength = _storage.size(_filename);
}
// commit row data
_storage.appendCSV(_filename, _values);
}
// clear values
_values = undefined;
}
/**
* Starts a row of data
*/
//% weight=100
//% blockId=datalogAddRow block="datalog add row"
export function addRow(): void {
commit();
init();
const s = (control.millis() - _start) / 1000;
addValue("time (s)", s);
}
/**
* Adds a cell to the row of data
* @param name name of the cell, eg: "x"
* @param value value of the cell, eg: 0
*/
//% weight=99
//% blockId=datalogAddValue block="datalog add %name|=%value"
export function addValue(name: string, value: number) {
if (!_values) return;
let i = _headers.indexOf(name);
if (i < 0) {
_headers.push(name);
i = _headers.length - 1;
}
_values[i] = value;
if (i > 0) // 0 is time
console.logValue(name, value)
}
/**
* Starts a new data logger for the given file
*/
//%
export function setFile(fn: string) {
_filename = fn;
clear();
}
/**
*
* @param storage custom storage solution
*/
//%
export function setStorage(storage: storage.Storage) {
_storage = storage;
clear();
}
}

View File

@ -1,16 +0,0 @@
{
"name": "datalog",
"description": "Tiny data logging framework",
"files": [
"README.md",
"datalog.ts"
],
"testFiles": [
"test.ts"
],
"public": true,
"dependencies": {
"core": "file:../core",
"storage": "file:../storage"
}
}

View File

@ -1,6 +0,0 @@
loops.forever(function () {
datalog.addRow()
datalog.addValue("x", Math.random())
datalog.addValue("y", Math.random())
})

View File

@ -8,7 +8,7 @@ namespace brick {
//% color="#C8509B" weight=95 icon="\uf10f" //% color="#C8509B" weight=95 icon="\uf10f"
//% labelLineWidth=0 //% labelLineWidth=0
//% groups='["Touch Sensor", "Color Sensor", "Ultrasonic Sensor", "Gyro Sensor", "Infrared Sensor", "Remote Infrared Beacon", "Threshold"]' //% groups='["Ultrasonic Sensor", "Touch Sensor", "Color Sensor", "Infrared Sensor", "Remote Infrared Beacon", "Gyro Sensor"]'
//% groupIcons='["\uf101","\uf103","\uf102","","","\uf104"]' //% groupIcons='["\uf101","\uf103","\uf102","","","\uf104"]'
namespace sensors { namespace sensors {
} }
@ -57,8 +57,3 @@ namespace loops {
namespace light { namespace light {
} }
//% color="#b0b0b0" advanced=true weight=5
namespace storage {
}

View File

@ -1,5 +1,5 @@
{ {
"sensors.GyroSensor.angle": "Get the current angle from the gyroscope.", "sensors.GyroSensor.angle": "Get the current angle from the gyroscope.",
"sensors.GyroSensor.rate": "Get the current rotation rate from the gyroscope.", "sensors.GyroSensor.calibrate": "Forces a calibration of the gyro. Must be called when the sensor is completely still.",
"sensors.GyroSensor.reset": "Forces a calibration of the gyro. Must be called when the sensor is completely still." "sensors.GyroSensor.rotationRate": "Get the current rotation rate from the gyroscope."
} }

View File

@ -1,7 +1,7 @@
{ {
"sensors.GyroSensor.angle|block": "%sensor|angle", "sensors.GyroSensor.angle|block": "%sensor|angle",
"sensors.GyroSensor.rate|block": "%sensor|rate", "sensors.GyroSensor.calibrate|block": "%sensor|calibrate",
"sensors.GyroSensor.reset|block": "%sensor|reset", "sensors.GyroSensor.rotationRate|block": "%sensor|rotation rate",
"sensors.gyro1|block": "gyro 1", "sensors.gyro1|block": "gyro 1",
"sensors.gyro2|block": "gyro 2", "sensors.gyro2|block": "gyro 2",
"sensors.gyro3|block": "gyro 3", "sensors.gyro3|block": "gyro 3",

View File

@ -31,7 +31,7 @@ namespace sensors {
//% parts="gyroscope" //% parts="gyroscope"
//% blockNamespace=sensors //% blockNamespace=sensors
//% sensor.fieldEditor="ports" //% sensor.fieldEditor="ports"
//% weight=64 blockGap=8 //% weight=65 blockGap=8
//% group="Gyro Sensor" //% group="Gyro Sensor"
angle(): number { angle(): number {
if (this.calibrating) if (this.calibrating)
@ -45,15 +45,15 @@ namespace sensors {
* Get the current rotation rate from the gyroscope. * Get the current rotation rate from the gyroscope.
* @param sensor the gyroscope to query the request * @param sensor the gyroscope to query the request
*/ */
//% help=input/gyro/rate //% help=input/gyro/rotation-rate
//% block="%sensor|rate" //% block="%sensor|rotation rate"
//% blockId=gyroGetRate //% blockId=gyroGetRate
//% parts="gyroscope" //% parts="gyroscope"
//% blockNamespace=sensors //% blockNamespace=sensors
//% sensor.fieldEditor="ports" //% sensor.fieldEditor="ports"
//% weight=65 blockGap=8 //% weight=65 blockGap=8
//% group="Gyro Sensor" //% group="Gyro Sensor"
rate(): number { rotationRate(): number {
if (this.calibrating) if (this.calibrating)
pauseUntil(() => !this.calibrating, 2000); pauseUntil(() => !this.calibrating, 2000);
@ -65,21 +65,21 @@ namespace sensors {
* Forces a calibration of the gyro. Must be called when the sensor is completely still. * Forces a calibration of the gyro. Must be called when the sensor is completely still.
*/ */
//% help=input/gyro/calibrate //% help=input/gyro/calibrate
//% block="%sensor|reset" //% block="%sensor|calibrate"
//% blockId=gyroReset //% blockId=gyroCalibrate
//% parts="gyroscope" //% parts="gyroscope"
//% blockNamespace=sensors //% blockNamespace=sensors
//% sensor.fieldEditor="ports" //% sensor.fieldEditor="ports"
//% weight=50 blockGap=8 //% weight=65 blockGap=8
//% group="Gyro Sensor" //% group="Gyro Sensor"
reset(): void { calibrate(): void {
if (this.calibrating) return; // already in calibration mode if (this.calibrating) return; // already in calibration mode
this.calibrating = true; this.calibrating = true;
// may be triggered by a button click, give time to settle // may be triggered by a button click, give time to settle
loops.pause(500); loops.pause(500);
// send a reset command // send a reset command
super.reset(); this.reset();
// we need to switch mode twice to perform a calibration // we need to switch mode twice to perform a calibration
if (this.mode == GyroSensorMode.Rate) if (this.mode == GyroSensorMode.Rate)
this.setMode(GyroSensorMode.Angle); this.setMode(GyroSensorMode.Angle);
@ -90,8 +90,6 @@ namespace sensors {
this.setMode(GyroSensorMode.Angle); this.setMode(GyroSensorMode.Angle);
else else
this.setMode(GyroSensorMode.Rate); this.setMode(GyroSensorMode.Rate);
// give it more time to settle
loops.pause(500);
this.calibrating = false; this.calibrating = false;
} }
} }

View File

@ -4,9 +4,6 @@
"sensors.InfraredSensor.pauseUntil": "Waits for the event to occur", "sensors.InfraredSensor.pauseUntil": "Waits for the event to occur",
"sensors.InfraredSensor.proximity": "Get the promixity measured by the infrared sensor, from ``0`` (close) to ``100`` (far)", "sensors.InfraredSensor.proximity": "Get the promixity measured by the infrared sensor, from ``0`` (close) to ``100`` (far)",
"sensors.InfraredSensor.remoteCommand": "Get the remote commandreceived the infrared sensor.", "sensors.InfraredSensor.remoteCommand": "Get the remote commandreceived the infrared sensor.",
"sensors.InfraredSensor.setThreshold": "Sets a threshold value",
"sensors.InfraredSensor.setThreshold|param|condition": "the dark or bright light condition",
"sensors.InfraredSensor.setThreshold|param|value": "the value threshold",
"sensors.RemoteInfraredBeaconButton.isPressed": "Check if a remote button is currently pressed or not.", "sensors.RemoteInfraredBeaconButton.isPressed": "Check if a remote button is currently pressed or not.",
"sensors.RemoteInfraredBeaconButton.onEvent": "Do something when a button or sensor is clicked, up or down", "sensors.RemoteInfraredBeaconButton.onEvent": "Do something when a button or sensor is clicked, up or down",
"sensors.RemoteInfraredBeaconButton.onEvent|param|body": "code to run when the event is raised", "sensors.RemoteInfraredBeaconButton.onEvent|param|body": "code to run when the event is raised",

View File

@ -5,7 +5,6 @@
"sensors.InfraredSensor.pauseUntil|block": "pause until %sensor| %event", "sensors.InfraredSensor.pauseUntil|block": "pause until %sensor| %event",
"sensors.InfraredSensor.proximity|block": "%sensor|proximity", "sensors.InfraredSensor.proximity|block": "%sensor|proximity",
"sensors.InfraredSensor.remoteCommand|block": "%sensor|remote command", "sensors.InfraredSensor.remoteCommand|block": "%sensor|remote command",
"sensors.InfraredSensor.setThreshold|block": "set %sensor|%condition|to %value",
"sensors.RemoteInfraredBeaconButton.isPressed|block": "%button|is pressed", "sensors.RemoteInfraredBeaconButton.isPressed|block": "%button|is pressed",
"sensors.RemoteInfraredBeaconButton.onEvent|block": "on %button|%event", "sensors.RemoteInfraredBeaconButton.onEvent|block": "on %button|%event",
"sensors.RemoteInfraredBeaconButton.wasPressed|block": "%button|was pressed", "sensors.RemoteInfraredBeaconButton.wasPressed|block": "%button|was pressed",
@ -21,6 +20,5 @@
"sensors|block": "sensors", "sensors|block": "sensors",
"{id:category}Sensors": "Sensors", "{id:category}Sensors": "Sensors",
"{id:group}Infrared Sensor": "Infrared Sensor", "{id:group}Infrared Sensor": "Infrared Sensor",
"{id:group}Remote Infrared Beacon": "Remote Infrared Beacon", "{id:group}Remote Infrared Beacon": "Remote Infrared Beacon"
"{id:group}Threshold": "Threshold"
} }

View File

@ -250,22 +250,6 @@ namespace sensors {
this._setMode(IrSensorMode.Seek) this._setMode(IrSensorMode.Seek)
return this.getNumber(NumberFormat.UInt16LE, this.channel * 2) return this.getNumber(NumberFormat.UInt16LE, this.channel * 2)
} }
/**
* Sets a threshold value
* @param condition the dark or bright light condition
* @param value the value threshold
*/
//% blockId=irSetThreshold block="set %sensor|%condition|to %value"
//% group="Threshold" blockGap=8
//% value.min=0 value.max=100
setThreshold(condition: InfraredSensorEvent, value: number) {
if (condition == InfraredSensorEvent.ObjectNear)
this.proximityThreshold.setLowThreshold(value)
else
this.proximityThreshold.setHighThreshold(value);
}
} }
//% fixedInstance whenUsed block="infrared 1" jres=icons.port1 //% fixedInstance whenUsed block="infrared 1" jres=icons.port1

1
libs/matrix/README.md Normal file
View File

@ -0,0 +1 @@
# Matrix

View File

@ -0,0 +1,15 @@
{
"matrix.Matrix": "A 2D matrix",
"matrix.Matrix.add": "Returns a new matrix as the sum of both matrices",
"matrix.Matrix.cholesky": "Performs a Cholesky factorized for a symmetric and positive definite",
"matrix.Matrix.clone": "Clones the matrix",
"matrix.Matrix.get": "Gets a value from the matrix",
"matrix.Matrix.get|param|row": "@param col ",
"matrix.Matrix.identity": "Creates an identity matrix",
"matrix.Matrix.logToConsole": "Renders the matrix to the console",
"matrix.Matrix.multiply": "Multiplies the current matrix with the other matrix and returns a new matrix",
"matrix.Matrix.scale": "Returns a new matrix with scaled values",
"matrix.Matrix.set": "Sets a value in the array",
"matrix.Matrix.set|param|row": "@param col ",
"matrix.Matrix.transpose": "Returns a transposed matrix"
}

View File

@ -0,0 +1,4 @@
{
"matrix|block": "matrix",
"{id:category}Matrix": "Matrix"
}

186
libs/matrix/matrix.ts Normal file
View File

@ -0,0 +1,186 @@
namespace matrix {
function pre(check: boolean) {
if (!check)
control.reset();
}
/**
* A 2D matrix
*/
export class Matrix {
private _rows: number;
private _cols: number;
private _values: number[];
constructor(rows: number, cols: number, values: number[] = undefined) {
pre(rows > 0);
pre(cols > 0);
this._rows = rows;
this._cols = cols;
const n = this._rows * this._cols;
this._values = values || [];
// fill gaps
while (this._values.length < n)
this._values.push(0);
}
/**
* Creates an identity matrix
* @param size
*/
static identity(size: number): Matrix {
const m = new Matrix(size, size);
for (let i = 0; i < size; ++i)
m._values[i * size] = 1;
return m;
}
/**
* Sets a value in the array
* @param row
* @param col
* @param val
*/
set(row: number, col: number, val: number) {
pre(row == row >> 0 && row >= 0 && row < this._rows && col == col >> 0 && col >= 0 && col < this._cols);
this._values[row * this._cols + col] = val;
}
/**
* Gets a value from the matrix
* @param row
* @param col
*/
get(row: number, col: number): number {
pre(row == row >> 0 && row >= 0 && row < this._rows && col == col >> 0 && col >= 0 && col < this._cols);
return this._values[row * this._cols + col];
}
/**
* Gets the number of rows
*/
get rows(): number {
return this._rows;
}
/**
* Gets the number of colums
*/
get cols(): number {
return this._cols;
}
/**
* Gets the raw storage buffer
*/
get values(): number[] {
return this._values;
}
/**
* Returns a new matrix as the sum of both matrices
* @param other
*/
add(other: Matrix): Matrix {
pre(this._rows != other._rows || this._cols != other._cols)
const n = this._rows * this._cols;
const r: number[] = [];
for (let i = 0; i < n; ++i) {
r[i] = this._values[i] + other._values[i];
}
return new Matrix(this._rows, this._cols, r);
}
/**
* Returns a new matrix with scaled values
* @param factor
*/
scale(factor: number): Matrix {
const n = this._rows * this._cols;
const r: number[] = [];
for (let i = 0; i < n; ++i) {
r[i] = this._values[i] * factor;
}
return new Matrix(this._rows, this._cols, r);
}
/**
* Multiplies the current matrix with the other matrix and returns a new matrix
* @param other
*/
multiply(other: Matrix): Matrix {
pre(this._cols == other._rows);
const r: number[] = [];
for (let i = 0; i < this._rows; ++i) {
for (let j = 0; j < other._cols; ++j) {
let s = 0;
for (let k = 0; k < this._cols; ++k) {
s += this._values[i * this._cols + k] * other._values[k * other._cols + j];
}
r[i * other._cols + j];
}
}
return new Matrix(this._rows, other._cols, r);
}
/**
* Returns a transposed matrix
*/
transpose(): Matrix {
const R = new Matrix(this._cols, this._rows);
const r: number[] = R._values;
for (let i = 0; i < this._rows; ++i) {
for (let j = 0; j < this._cols; ++j) {
r[i + j * this._rows] = this._values[i * this._cols + j];
}
}
return R;
}
/**
* Clones the matrix
*/
clone(): Matrix {
const r = new Matrix(this._rows, this._cols, this._values.slice(0));
return r;
}
/**
* Performs a Cholesky factorized for a symmetric and positive definite
*
*/
cholesky(): Matrix {
pre(this._rows == this._cols);
const l = this.clone();
const n = this._rows;
const L = l._values;
for (let j = 0; j < n; j++) {
const jj = L[j * n + j] = Math.sqrt(L[j * n + j]);
for (let i = j + 1; i < n; ++i)
L[i * n + j] /= jj;
for (let k = j + 1; k < n; k++)
for (let i = k; i < n; i++)
L[i * n + j] -= L[i * n + j] * L[k * n + j];
}
return l;
}
/**
* Renders the matrix to the console
*/
logToConsole(): void {
let k = 0;
for(let i = 0; i < this._rows; ++i) {
let s = ""
for(let j = 0; j < this._cols; ++j) {
if (j > 0)
s += " "
s += Math.round((this._values[k++] * 100) / 100);
}
console.log(s)
}
}
}
}

15
libs/matrix/pxt.json Normal file
View File

@ -0,0 +1,15 @@
{
"name": "matrix",
"description": "Matrix algebra",
"files": [
"README.md",
"matrix.ts"
],
"testFiles": [
"test.ts"
],
"public": true,
"dependencies": {
"core": "file:../core"
}
}

1
libs/matrix/test.ts Normal file
View File

@ -0,0 +1 @@
// add tests here

View File

@ -33,34 +33,34 @@
"music.stopAllSounds|block": "stop all sounds", "music.stopAllSounds|block": "stop all sounds",
"music.tempo|block": "tempo (bpm)", "music.tempo|block": "tempo (bpm)",
"music|block": "music", "music|block": "music",
"sounds.animalsCatPurr|block": "animals cat purr", "sounds.animalsCatPurr|block": "Animals cat purr",
"sounds.animalsDogBark1|block": "animals dog bark 1", "sounds.animalsDogBark1|block": "Animals dog bark 1",
"sounds.animalsDogBark2|block": "animals dog bark 2", "sounds.animalsDogBark2|block": "Animals dog bark 2",
"sounds.animalsDogGrowl|block": "animals dog growl", "sounds.animalsDogGrowl|block": "Animals dog growl",
"sounds.animalsDogSniff|block": "animals dog sniff", "sounds.animalsDogSniff|block": "Animals dog sniff",
"sounds.animalsDogWhine|block": "animals dog whine", "sounds.animalsDogWhine|block": "Animals dog whine",
"sounds.animalsElephantCall|block": "animals elephant call", "sounds.animalsElephantCall|block": "Animals elephant call",
"sounds.animalsInsectBuzz1|block": "animals insect buzz1", "sounds.animalsInsectBuzz1|block": "Animals insect buzz1",
"sounds.animalsInsectBuzz2|block": "animals insect buzz2", "sounds.animalsInsectBuzz2|block": "Animals insect buzz2",
"sounds.animalsInsectChirp|block": "animals insect chirp", "sounds.animalsInsectChirp|block": "Animals insect chirp",
"sounds.animalsSnakeHiss|block": "animals snake hiss", "sounds.animalsSnakeHiss|block": "Animals snake hiss",
"sounds.animalsSnakeRattle|block": "animals snake rattle", "sounds.animalsSnakeRattle|block": "Animals snake rattle",
"sounds.animalsTRexRoar|block": "animals trex roar", "sounds.animalsTRexRoar|block": "Animals trex roar",
"sounds.colorsBlack|block": "colors black", "sounds.colorsBlack|block": "Colors black",
"sounds.colorsBlue|block": "colors blue", "sounds.colorsBlue|block": "Colors blue",
"sounds.colorsBrown|block": "colors brown", "sounds.colorsBrown|block": "Colors brown",
"sounds.colorsGreen|block": "colors green", "sounds.colorsGreen|block": "Colors green",
"sounds.colorsRed|block": "colors red", "sounds.colorsRed|block": "Colors red",
"sounds.colorsWhite|block": "colors white", "sounds.colorsWhite|block": "Colors white",
"sounds.colorsYellow|block": "colors yellow", "sounds.colorsYellow|block": "Colors yellow",
"sounds.communicationBravo|block": "communication bravo", "sounds.communicationBravo|block": "Communication bravo",
"sounds.communicationEv3|block": "communication ev3", "sounds.communicationEv3|block": "Communication ev3",
"sounds.communicationFantastic|block": "communication fantastic", "sounds.communicationFantastic|block": "Communication fantastic",
"sounds.communicationGameOver|block": "communication game over", "sounds.communicationGameOver|block": "Communication game over",
"sounds.communicationGoodJob|block": "communicationGoodJob", "sounds.communicationGoodJob|block": "communicationGoodJob",
"sounds.communicationGoodbye|block": "communication goodbye", "sounds.communicationGoodbye|block": "communication goodbye",
"sounds.communicationGood|block": "communication good", "sounds.communicationGood|block": "communication good",
"sounds.communicationGo|block": "communication go", "sounds.communicationGo|block": "Communication go",
"sounds.communicationHello|block": "communication hello", "sounds.communicationHello|block": "communication hello",
"sounds.communicationHi|block": "communication hi", "sounds.communicationHi|block": "communication hi",
"sounds.communicationLego|block": "communication lego", "sounds.communicationLego|block": "communication lego",
@ -159,7 +159,7 @@
"sounds.systemOverpower|block": "system overpower", "sounds.systemOverpower|block": "system overpower",
"sounds.systemPowerDown|block": "system power down", "sounds.systemPowerDown|block": "system power down",
"sounds.systemReady|block": "system ready", "sounds.systemReady|block": "system ready",
"sounds.systemStartUp|block": "system start up", "sounds.systemStartUp|block": "S",
"{id:category}Music": "Music", "{id:category}Music": "Music",
"{id:category}Sound": "Sound", "{id:category}Sound": "Sound",
"{id:category}Sounds": "Sounds" "{id:category}Sounds": "Sounds"

View File

@ -1,53 +1,53 @@
namespace sounds { namespace sounds {
//% fixedInstance jres block="animals cat purr" //% fixedInstance jres block="Animals cat purr"
export const animalsCatPurr = music.fromWAV(hex``); export const animalsCatPurr = music.fromWAV(hex``);
//% fixedInstance jres block="animals dog bark 1" //% fixedInstance jres block="Animals dog bark 1"
export const animalsDogBark1 = music.fromWAV(hex``); export const animalsDogBark1 = music.fromWAV(hex``);
//% fixedInstance jres block="animals dog bark 2" //% fixedInstance jres block="Animals dog bark 2"
export const animalsDogBark2 = music.fromWAV(hex``); export const animalsDogBark2 = music.fromWAV(hex``);
//% fixedInstance jres block="animals dog growl" //% fixedInstance jres block="Animals dog growl"
export const animalsDogGrowl = music.fromWAV(hex``); export const animalsDogGrowl = music.fromWAV(hex``);
//% fixedInstance jres block="animals dog sniff" //% fixedInstance jres block="Animals dog sniff"
export const animalsDogSniff = music.fromWAV(hex``); export const animalsDogSniff = music.fromWAV(hex``);
//% fixedInstance jres block="animals dog whine" //% fixedInstance jres block="Animals dog whine"
export const animalsDogWhine = music.fromWAV(hex``); export const animalsDogWhine = music.fromWAV(hex``);
//% fixedInstance jres block="animals elephant call" //% fixedInstance jres block="Animals elephant call"
export const animalsElephantCall = music.fromWAV(hex``); export const animalsElephantCall = music.fromWAV(hex``);
//% fixedInstance jres block="animals insect buzz1" //% fixedInstance jres block="Animals insect buzz1"
export const animalsInsectBuzz1 = music.fromWAV(hex``); export const animalsInsectBuzz1 = music.fromWAV(hex``);
//% fixedInstance jres block="animals insect buzz2" //% fixedInstance jres block="Animals insect buzz2"
export const animalsInsectBuzz2 = music.fromWAV(hex``); export const animalsInsectBuzz2 = music.fromWAV(hex``);
//% fixedInstance jres block="animals insect chirp" //% fixedInstance jres block="Animals insect chirp"
export const animalsInsectChirp = music.fromWAV(hex``); export const animalsInsectChirp = music.fromWAV(hex``);
//% fixedInstance jres block="animals snake hiss" //% fixedInstance jres block="Animals snake hiss"
export const animalsSnakeHiss = music.fromWAV(hex``); export const animalsSnakeHiss = music.fromWAV(hex``);
//% fixedInstance jres block="animals snake rattle" //% fixedInstance jres block="Animals snake rattle"
export const animalsSnakeRattle = music.fromWAV(hex``); export const animalsSnakeRattle = music.fromWAV(hex``);
//% fixedInstance jres block="animals trex roar" //% fixedInstance jres block="Animals trex roar"
export const animalsTRexRoar = music.fromWAV(hex``); export const animalsTRexRoar = music.fromWAV(hex``);
//% fixedInstance jres block="colors black" //% fixedInstance jres block="Colors black"
export const colorsBlack = music.fromWAV(hex``); export const colorsBlack = music.fromWAV(hex``);
//% fixedInstance jres block="colors blue" //% fixedInstance jres block="Colors blue"
export const colorsBlue = music.fromWAV(hex``); export const colorsBlue = music.fromWAV(hex``);
//% fixedInstance jres block="colors brown" //% fixedInstance jres block="Colors brown"
export const colorsBrown = music.fromWAV(hex``); export const colorsBrown = music.fromWAV(hex``);
//% fixedInstance jres block="colors green" //% fixedInstance jres block="Colors green"
export const colorsGreen = music.fromWAV(hex``); export const colorsGreen = music.fromWAV(hex``);
//% fixedInstance jres block="colors red" //% fixedInstance jres block="Colors red"
export const colorsRed = music.fromWAV(hex``); export const colorsRed = music.fromWAV(hex``);
//% fixedInstance jres block="colors white" //% fixedInstance jres block="Colors white"
export const colorsWhite = music.fromWAV(hex``); export const colorsWhite = music.fromWAV(hex``);
//% fixedInstance jres block="colors yellow" //% fixedInstance jres block="Colors yellow"
export const colorsYellow = music.fromWAV(hex``); export const colorsYellow = music.fromWAV(hex``);
//% fixedInstance jres block="communication bravo" //% fixedInstance jres block="Communication bravo"
export const communicationBravo = music.fromWAV(hex``); export const communicationBravo = music.fromWAV(hex``);
//% fixedInstance jres block="communication ev3" //% fixedInstance jres block="Communication ev3"
export const communicationEv3 = music.fromWAV(hex``); export const communicationEv3 = music.fromWAV(hex``);
//% fixedInstance jres block="communication fantastic" //% fixedInstance jres block="Communication fantastic"
export const communicationFantastic = music.fromWAV(hex``); export const communicationFantastic = music.fromWAV(hex``);
//% fixedInstance jres block="communication game over" //% fixedInstance jres block="Communication game over"
export const communicationGameOver = music.fromWAV(hex``); export const communicationGameOver = music.fromWAV(hex``);
//% fixedInstance jres block="communication go" //% fixedInstance jres block="Communication go"
export const communicationGo = music.fromWAV(hex``); export const communicationGo = music.fromWAV(hex``);
//% fixedInstance jres block="communicationGoodJob" //% fixedInstance jres block="communicationGoodJob"
export const communicationGoodJob = music.fromWAV(hex``); export const communicationGoodJob = music.fromWAV(hex``);
@ -251,7 +251,7 @@ namespace sounds {
export const systemPowerDown = music.fromWAV(hex``); export const systemPowerDown = music.fromWAV(hex``);
//% fixedInstance jres block="system ready" //% fixedInstance jres block="system ready"
export const systemReady = music.fromWAV(hex``); export const systemReady = music.fromWAV(hex``);
//% fixedInstance jres block="system start up" //% fixedInstance jres block=S
export const systemStartUp = music.fromWAV(hex``); export const systemStartUp = music.fromWAV(hex``);
} }

View File

@ -1,29 +0,0 @@
{
"storage.Storage.append": "Append string data to a new or existing file.",
"storage.Storage.appendBuffer": "Append a buffer to a new or existing file.",
"storage.Storage.appendCSV": "Append a row of CSV data",
"storage.Storage.appendCSVHeaders": "Append a row of CSV headers",
"storage.Storage.appendCSVHeaders|param|filename": "the file name to append data, eg: \"data.csv\"",
"storage.Storage.appendCSVHeaders|param|headers": "the data to append",
"storage.Storage.appendCSV|param|data": "the data to append",
"storage.Storage.appendCSV|param|filename": "the file name to append data, eg: \"data.csv\"",
"storage.Storage.appendLine": "Appends a new line of data in the file",
"storage.Storage.appendLine|param|data": "the data to append",
"storage.Storage.appendLine|param|filename": "the file name to append data, eg: \"data.txt\"",
"storage.Storage.append|param|data": "the data to append",
"storage.Storage.append|param|filename": "the file name to append data, eg: \"data.txt\"",
"storage.Storage.exists": "Tests if a file exists",
"storage.Storage.exists|param|filename": "the file name to append data, eg: \"data.txt\"",
"storage.Storage.limit": "Resizing the size of a file to stay under the limit",
"storage.Storage.limit|param|filename": "name of the file to drop",
"storage.Storage.limit|param|size": "maximum length",
"storage.Storage.overwrite": "Overwrite file with string data.",
"storage.Storage.overwriteWithBuffer": "Overwrite file with a buffer.",
"storage.Storage.overwrite|param|data": "the data to append",
"storage.Storage.overwrite|param|filename": "the file name to append data, eg: \"data.txt\"",
"storage.Storage.read": "Read contents of file as a string.",
"storage.Storage.readAsBuffer": "Read contents of file as a buffer.",
"storage.Storage.remove": "Delete a file, or do nothing if it doesn't exist.",
"storage.Storage.size": "Return the size of the file, or -1 if it doesn't exists.",
"storage.temporary": "Temporary storage in memory, deleted when the device restarts."
}

View File

@ -1,15 +0,0 @@
{
"storage.Storage.appendCSVHeaders|block": "storage %source|%filename|append CSV headers %headers",
"storage.Storage.appendCSV|block": "storage %source|%filename|append CSV %data",
"storage.Storage.appendLine|block": "storage %source|%filename|append line %data",
"storage.Storage.append|block": "storage %source|%filename|append %data",
"storage.Storage.exists|block": "storage %source|%filename|exists",
"storage.Storage.limit|block": "storage %source|limit %filename|to %size|bytes",
"storage.Storage.overwrite|block": "storage %source|%filename|overwrite with|%data",
"storage.Storage.read|block": "storage %source|read %filename|as string",
"storage.Storage.remove|block": "storage %source|remove %filename",
"storage.Storage.size|block": "storage %source|%filename|size",
"storage.temporary|block": "temporary",
"storage|block": "storage",
"{id:category}Storage": "Storage"
}

View File

@ -1,14 +0,0 @@
{
"name": "storage",
"description": "USB Pen-drive support and flash storage",
"files": [
"storage.cpp",
"storage-core.ts",
"storage.ts",
"shims.d.ts"
],
"public": true,
"dependencies": {
"core": "file:../core"
}
}

View File

@ -1,17 +0,0 @@
// Auto-generated. Do not edit.
declare namespace storage {
/** Will be moved. */
//% shim=storage::__stringToBuffer
function __stringToBuffer(s: string): Buffer;
/** Will be moved. */
//% shim=storage::__bufferToString
function __bufferToString(s: Buffer): string;
/** Create named directory. */
//% shim=storage::__mkdir
function __mkdir(filename: string): void;
}
// Auto-generated. Do not edit. Really.

View File

@ -1,197 +0,0 @@
namespace storage {
//% shim=storage::__unlink
function __unlink(filename: string): void { }
//% shim=storage::__truncate
function __truncate(filename: string): void { }
//% fixedInstances
export class Storage {
csvSeparator: string;
constructor() {
this.csvSeparator = ",";
}
protected mapFilename(filename: string) {
return filename;
}
private getFile(filename: string): MMap {
filename = this.mapFilename(filename)
let r = control.mmap(filename, 0, 0)
if (!r) {
__mkdir(this.dirname(filename))
__truncate(filename)
r = control.mmap(filename, 0, 0)
}
if (!r)
control.panic(906)
return r
}
dirname(filename: string) {
let last = 0
for (let i = 0; i < filename.length; ++i)
if (filename[i] == "/")
last = i
return filename.substr(0, last)
}
/**
* Append string data to a new or existing file.
* @param filename the file name to append data, eg: "data.txt"
* @param data the data to append
*/
//% blockId=storageAppend block="storage %source|%filename|append %data"
append(filename: string, data: string): void {
this.appendBuffer(filename, __stringToBuffer(data))
}
/**
* Appends a new line of data in the file
* @param filename the file name to append data, eg: "data.txt"
* @param data the data to append
*/
//% blockId=storageAppendLine block="storage %source|%filename|append line %data"
appendLine(filename: string, data: string): void {
this.append(filename, data + "\r\n");
}
/** Append a buffer to a new or existing file. */
appendBuffer(filename: string, data: Buffer): void {
let f = this.getFile(filename);
f.lseek(0, SeekWhence.End)
f.write(data)
}
/**
* Append a row of CSV headers
* @param filename the file name to append data, eg: "data.csv"
* @param headers the data to append
*/
//% blockId=storageAppendCSVHeaders block="storage %source|%filename|append CSV headers %headers"
appendCSVHeaders(filename: string, headers: string[]) {
let s = ""
for (const d of headers) {
if (s) s += this.csvSeparator;
s = s + d;
}
s += "\r\n"
this.append(filename, s)
}
/**
* Append a row of CSV data
* @param filename the file name to append data, eg: "data.csv"
* @param data the data to append
*/
//% blockId=storageAppendCSV block="storage %source|%filename|append CSV %data"
appendCSV(filename: string, data: number[]) {
let s = ""
for (const d of data) {
if (s) s += this.csvSeparator;
s = s + d;
}
s += "\r\n"
this.append(filename, s)
}
/** Overwrite file with string data.
* @param filename the file name to append data, eg: "data.txt"
* @param data the data to append
*/
//% blockId=storageOverwrite block="storage %source|%filename|overwrite with|%data"
overwrite(filename: string, data: string): void {
this.overwriteWithBuffer(filename, __stringToBuffer(data))
}
/** Overwrite file with a buffer. */
overwriteWithBuffer(filename: string, data: Buffer): void {
__truncate(this.mapFilename(filename))
this.appendBuffer(filename, data)
}
/** Tests if a file exists
* @param filename the file name to append data, eg: "data.txt"
*/
//% blockId=storageExists block="storage %source|%filename|exists"
exists(filename: string): boolean {
return !!control.mmap(this.mapFilename(filename), 0, 0);
}
/** Delete a file, or do nothing if it doesn't exist. */
//% blockId=storageRemove block="storage %source|remove %filename"
remove(filename: string): void {
__unlink(this.mapFilename(filename))
}
/** Return the size of the file, or -1 if it doesn't exists. */
//% blockId=storageSize block="storage %source|%filename|size"
size(filename: string): int32 {
let f = control.mmap(this.mapFilename(filename), 0, 0)
if (!f) return -1;
return f.lseek(0, SeekWhence.End)
}
/** Read contents of file as a string. */
//% blockId=storageRead block="storage %source|read %filename|as string"
read(filename: string): string {
return __bufferToString(this.readAsBuffer(filename))
}
/** Read contents of file as a buffer. */
//%
readAsBuffer(filename: string): Buffer {
let f = this.getFile(filename)
let sz = f.lseek(0, SeekWhence.End)
let b = output.createBuffer(sz)
f.lseek(0, SeekWhence.Set);
f.read(b)
return b
}
/**
* Resizing the size of a file to stay under the limit
* @param filename name of the file to drop
* @param size maximum length
*/
//% blockId=storageLimit block="storage %source|limit %filename|to %size|bytes"
limit(filename: string, size: number) {
if (!this.exists(filename) || size < 0) return;
const sz = storage.temporary.size(filename);
if (sz > size) {
let buf = storage.temporary.readAsBuffer(filename)
buf = buf.slice(buf.length / 2);
storage.temporary.overwriteWithBuffer(filename, buf);
}
}
}
class TemporaryStorage extends Storage {
constructor() {
super();
}
protected mapFilename(filename: string) {
if (filename[0] == '/') filename = filename.substr(1);
return '/tmp/logs/' + filename;
}
}
/**
* Temporary storage in memory, deleted when the device restarts.
*/
//% whenUsed fixedInstance block="temporary"
export const temporary: Storage = new TemporaryStorage();
class PermanentStorage extends Storage {
constructor() {
super()
}
protected mapFilename(filename: string) {
if (filename[0] == '/') return filename;
return '/' + filename;
}
}
}

View File

@ -1,44 +0,0 @@
#include "pxt.h"
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
namespace storage {
/** Will be moved. */
//%
Buffer __stringToBuffer(String s) {
return mkBuffer((uint8_t *)s->data, s->length);
}
/** Will be moved. */
//%
String __bufferToString(Buffer s) {
return mkString((char*)s->data, s->length);
}
//%
void __init() {
// do nothing
}
//%
void __unlink(String filename) {
::unlink(filename->data);
}
//%
void __truncate(String filename) {
int fd = open(filename->data, O_CREAT | O_TRUNC | O_WRONLY, 0777);
close(fd);
}
/** Create named directory. */
//%
void __mkdir(String filename) {
::mkdir(filename->data, 0777);
}
} // namespace storage

View File

@ -1,11 +0,0 @@
namespace storage {
// automatically send console output to temp storage
storage.temporary.remove("console.txt");
console.addListener(function(line) {
const fn = "console.txt";
const mxs = 65536;
const t = control.millis();
storage.temporary.appendLine(fn, `${t}> ${line}`);
storage.temporary.limit(fn, 65536);
})
}

View File

@ -2,8 +2,5 @@
"sensors.UltraSonicSensor.distance": "Gets the distance from the sonar in centimeters", "sensors.UltraSonicSensor.distance": "Gets the distance from the sonar in centimeters",
"sensors.UltraSonicSensor.onEvent": "Registers code to run when the given color is close", "sensors.UltraSonicSensor.onEvent": "Registers code to run when the given color is close",
"sensors.UltraSonicSensor.onEvent|param|handler": "the code to run when detected", "sensors.UltraSonicSensor.onEvent|param|handler": "the code to run when detected",
"sensors.UltraSonicSensor.pauseUntil": "Waits for the event to occur", "sensors.UltraSonicSensor.pauseUntil": "Waits for the event to occur"
"sensors.UltraSonicSensor.setThreshold": "Sets a threshold value",
"sensors.UltraSonicSensor.setThreshold|param|condition": "the dark or bright light condition",
"sensors.UltraSonicSensor.setThreshold|param|value": "the value threshold"
} }

View File

@ -5,12 +5,10 @@
"sensors.UltraSonicSensor.distance|block": "%sensor|distance", "sensors.UltraSonicSensor.distance|block": "%sensor|distance",
"sensors.UltraSonicSensor.onEvent|block": "on %sensor|%event", "sensors.UltraSonicSensor.onEvent|block": "on %sensor|%event",
"sensors.UltraSonicSensor.pauseUntil|block": "pause until %sensor| %event", "sensors.UltraSonicSensor.pauseUntil|block": "pause until %sensor| %event",
"sensors.UltraSonicSensor.setThreshold|block": "set %sensor|%condition|to %value",
"sensors.ultrasonic1|block": "ultrasonic 1", "sensors.ultrasonic1|block": "ultrasonic 1",
"sensors.ultrasonic2|block": "ultrasonic 2", "sensors.ultrasonic2|block": "ultrasonic 2",
"sensors.ultrasonic3|block": "ultrasonic 3", "sensors.ultrasonic3|block": "ultrasonic 3",
"sensors.ultrasonic4|block": "ultrasonic 4", "sensors.ultrasonic4|block": "ultrasonic 4",
"{id:category}Sensors": "Sensors", "{id:category}Sensors": "Sensors",
"{id:group}Threshold": "Threshold",
"{id:group}Ultrasonic Sensor": "Ultrasonic Sensor" "{id:group}Ultrasonic Sensor": "Ultrasonic Sensor"
} }

View File

@ -85,23 +85,6 @@ namespace sensors {
this._setMode(0) this._setMode(0)
return this._query(); return this._query();
} }
/**
* Sets a threshold value
* @param condition the dark or bright light condition
* @param value the value threshold
*/
//% blockId=ultrasonicSetThreshold block="set %sensor|%condition|to %value"
//% group="Threshold" blockGap=8
//% value.min=0 value.max=255
setThreshold(condition: UltrasonicSensorEvent, value: number) {
switch(condition) {
case UltrasonicSensorEvent.ObjectNear: this.promixityThreshold.setLowThreshold(value); break;
case UltrasonicSensorEvent.ObjectFar: this.promixityThreshold.setHighThreshold(value); break;
case UltrasonicSensorEvent.ObjectDetected: this.movementThreshold = value; break;
}
}
} }
//% fixedInstance whenUsed block="ultrasonic 4" jres=icons.port4 //% fixedInstance whenUsed block="ultrasonic 4" jres=icons.port4

87
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "pxt-ev3", "name": "pxt-ev3",
"version": "0.0.64", "version": "0.0.51",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -399,7 +399,7 @@
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
"requires": { "requires": {
"bn.js": "4.11.8", "bn.js": "4.11.8",
"randombytes": "2.0.6" "randombytes": "2.0.5"
} }
}, },
"browserify-sign": { "browserify-sign": {
@ -792,7 +792,7 @@
"inherits": "2.0.3", "inherits": "2.0.3",
"pbkdf2": "3.0.14", "pbkdf2": "3.0.14",
"public-encrypt": "4.0.0", "public-encrypt": "4.0.0",
"randombytes": "2.0.6", "randombytes": "2.0.5",
"randomfill": "1.0.3" "randomfill": "1.0.3"
} }
}, },
@ -956,7 +956,7 @@
"requires": { "requires": {
"bn.js": "4.11.8", "bn.js": "4.11.8",
"miller-rabin": "4.0.1", "miller-rabin": "4.0.1",
"randombytes": "2.0.6" "randombytes": "2.0.5"
} }
}, },
"domain-browser": { "domain-browser": {
@ -1009,9 +1009,9 @@
} }
}, },
"end-of-stream": { "end-of-stream": {
"version": "1.4.1", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz",
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=",
"requires": { "requires": {
"once": "1.4.0" "once": "1.4.0"
} }
@ -1562,15 +1562,6 @@
"verror": "1.10.0" "verror": "1.10.0"
} }
}, },
"keytar": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/keytar/-/keytar-3.0.2.tgz",
"integrity": "sha1-TcFd01I/4wYx+dOIV4pAFRpgWG8=",
"optional": true,
"requires": {
"nan": "2.3.2"
}
},
"kind-of": { "kind-of": {
"version": "3.2.2", "version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
@ -1842,9 +1833,9 @@
"integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=" "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI="
}, },
"marked": { "marked": {
"version": "0.3.12", "version": "0.3.9",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.12.tgz", "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.9.tgz",
"integrity": "sha512-k4NaW+vS7ytQn6MgJn3fYpQt20/mOgYM5Ft9BYMfQJDz2QT6yEeS9XJ8k2Nw8JTeWK/znPPW2n3UJGzyYEiMoA==" "integrity": "sha512-nW5u0dxpXxHfkHzzrveY45gCbi+R4PaO4WRZYqZNl+vB0hVGeqlFn0aOg1c8AKL63TrNFn9Bm2UP4AdiZ9TPLw=="
}, },
"math-expression-evaluator": { "math-expression-evaluator": {
"version": "1.2.17", "version": "1.2.17",
@ -1975,7 +1966,8 @@
"nan": { "nan": {
"version": "2.3.2", "version": "2.3.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.3.2.tgz", "resolved": "https://registry.npmjs.org/nan/-/nan-2.3.2.tgz",
"integrity": "sha1-TU7PF+HaTpie+08nPY0AIBytCH4=" "integrity": "sha1-TU7PF+HaTpie+08nPY0AIBytCH4=",
"dev": true
}, },
"neatequal": { "neatequal": {
"version": "1.0.0", "version": "1.0.0",
@ -2518,7 +2510,7 @@
"npmlog": "4.1.2", "npmlog": "4.1.2",
"os-homedir": "1.0.2", "os-homedir": "1.0.2",
"pump": "1.0.3", "pump": "1.0.3",
"rc": "1.2.3", "rc": "1.2.2",
"simple-get": "1.4.3", "simple-get": "1.4.3",
"tar-fs": "1.16.0", "tar-fs": "1.16.0",
"tunnel-agent": "0.6.0", "tunnel-agent": "0.6.0",
@ -2566,7 +2558,7 @@
"browserify-rsa": "4.0.1", "browserify-rsa": "4.0.1",
"create-hash": "1.1.3", "create-hash": "1.1.3",
"parse-asn1": "5.1.0", "parse-asn1": "5.1.0",
"randombytes": "2.0.6" "randombytes": "2.0.5"
} }
}, },
"pump": { "pump": {
@ -2574,7 +2566,7 @@
"resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
"integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
"requires": { "requires": {
"end-of-stream": "1.4.1", "end-of-stream": "1.4.0",
"once": "1.4.0" "once": "1.4.0"
} }
}, },
@ -2584,19 +2576,19 @@
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
}, },
"pxt-common-packages": { "pxt-common-packages": {
"version": "0.15.4", "version": "0.14.13",
"resolved": "https://registry.npmjs.org/pxt-common-packages/-/pxt-common-packages-0.15.4.tgz", "resolved": "https://registry.npmjs.org/pxt-common-packages/-/pxt-common-packages-0.14.13.tgz",
"integrity": "sha1-hI1q5+UQ7vIuBqlOrIy66PmiePo=", "integrity": "sha1-L/axrdv7I1g6xjGC8JXNx/Bv0Ss=",
"requires": { "requires": {
"autoprefixer": "6.7.7", "autoprefixer": "6.7.7",
"pxt-core": "3.0.8", "pxt-core": "3.0.2",
"rtlcss": "2.2.1" "rtlcss": "2.2.1"
} }
}, },
"pxt-core": { "pxt-core": {
"version": "3.0.8", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/pxt-core/-/pxt-core-3.0.8.tgz", "resolved": "https://registry.npmjs.org/pxt-core/-/pxt-core-3.0.2.tgz",
"integrity": "sha1-wmvgLvyX1lV5ZB6EM9APj22/gIo=", "integrity": "sha1-q7aCkAXRwvsmhPaeHR1S9osLK98=",
"requires": { "requires": {
"bluebird": "3.5.1", "bluebird": "3.5.1",
"browserify": "13.3.0", "browserify": "13.3.0",
@ -2604,16 +2596,15 @@
"faye-websocket": "0.11.1", "faye-websocket": "0.11.1",
"fuse.js": "2.6.1", "fuse.js": "2.6.1",
"highlight.js": "9.12.0", "highlight.js": "9.12.0",
"keytar": "3.0.2",
"lzma": "2.3.2", "lzma": "2.3.2",
"marked": "0.3.12", "marked": "0.3.9",
"node-hid": "0.5.7", "node-hid": "0.5.7",
"postcss": "6.0.16", "postcss": "6.0.15",
"request": "2.83.0", "request": "2.83.0",
"rimraf": "2.5.4", "rimraf": "2.5.4",
"rtlcss": "2.2.1", "rtlcss": "2.2.1",
"serialport": "4.0.7", "serialport": "4.0.7",
"uglify-js": "3.3.5" "uglify-js": "3.3.4"
}, },
"dependencies": { "dependencies": {
"ansi-styles": { "ansi-styles": {
@ -2650,9 +2641,9 @@
"integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
}, },
"postcss": { "postcss": {
"version": "6.0.16", "version": "6.0.15",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.15.tgz",
"integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==", "integrity": "sha512-v/SpyMzLbtkmh45zUdaqLAaqXqzPdSrw8p4cQVO0/w6YiYfpj4k+Wkzhn68qk9br+H+0qfddhdPEVnbmBPfXVQ==",
"requires": { "requires": {
"chalk": "2.3.0", "chalk": "2.3.0",
"source-map": "0.6.1", "source-map": "0.6.1",
@ -2704,9 +2695,9 @@
"integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM="
}, },
"randombytes": { "randombytes": {
"version": "2.0.6", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz",
"integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==",
"requires": { "requires": {
"safe-buffer": "5.1.1" "safe-buffer": "5.1.1"
} }
@ -2716,14 +2707,14 @@
"resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz",
"integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==",
"requires": { "requires": {
"randombytes": "2.0.6", "randombytes": "2.0.5",
"safe-buffer": "5.1.1" "safe-buffer": "5.1.1"
} }
}, },
"rc": { "rc": {
"version": "1.2.3", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.3.tgz", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz",
"integrity": "sha1-UVdakA+N1oOBxxC0cSwhVMPiA1s=", "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=",
"optional": true, "optional": true,
"requires": { "requires": {
"deep-extend": "0.4.2", "deep-extend": "0.4.2",
@ -4319,7 +4310,7 @@
"optional": true, "optional": true,
"requires": { "requires": {
"bl": "1.2.1", "bl": "1.2.1",
"end-of-stream": "1.4.1", "end-of-stream": "1.4.0",
"readable-stream": "2.3.3", "readable-stream": "2.3.3",
"xtend": "4.0.1" "xtend": "4.0.1"
} }
@ -4431,9 +4422,9 @@
"dev": true "dev": true
}, },
"uglify-js": { "uglify-js": {
"version": "3.3.5", "version": "3.3.4",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.5.tgz", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.4.tgz",
"integrity": "sha512-ZebM2kgBL/UI9rKeAbsS2J0UPPv7SBy5hJNZml/YxB1zC6JK8IztcPs+cxilE4pu0li6vadVSFqiO7xFTKuSrg==", "integrity": "sha512-hfIwuAQI5dlXP30UtdmWoYF9k+ypVqBXIdmd6ZKBiaNHHvA8ty7ZloMe3+7S5AEKVkxHbjByl4DfRHQ7QpZquw==",
"requires": { "requires": {
"commander": "2.12.2", "commander": "2.12.2",
"source-map": "0.6.1" "source-map": "0.6.1"

View File

@ -1,6 +1,6 @@
{ {
"name": "pxt-ev3", "name": "pxt-ev3",
"version": "0.0.65", "version": "0.0.57",
"description": "LEGO Mindstorms EV3 for Microsoft MakeCode", "description": "LEGO Mindstorms EV3 for Microsoft MakeCode",
"private": true, "private": true,
"keywords": [ "keywords": [
@ -44,8 +44,8 @@
"webfonts-generator": "^0.4.0" "webfonts-generator": "^0.4.0"
}, },
"dependencies": { "dependencies": {
"pxt-common-packages": "0.15.5", "pxt-common-packages": "0.15.4",
"pxt-core": "3.0.11" "pxt-core": "3.0.5"
}, },
"scripts": { "scripts": {
"test": "node node_modules/pxt-core/built/pxt.js travis" "test": "node node_modules/pxt-core/built/pxt.js travis"

View File

@ -17,10 +17,9 @@
"libs/gyro-sensor", "libs/gyro-sensor",
"libs/chassis", "libs/chassis",
"libs/ev3", "libs/ev3",
"libs/storage",
"libs/datalog",
"libs/tests", "libs/tests",
"libs/behaviors" "libs/behaviors",
"libs/matrix"
], ],
"simulator": { "simulator": {
"autoRun": true, "autoRun": true,

View File

@ -30,8 +30,8 @@ namespace pxsim {
data, data,
beforeMemRead: () => { beforeMemRead: () => {
//console.log("analog before read"); //console.log("analog before read");
util.map16Bit(data, AnalogOff.BatteryTemp, 21); data[AnalogOff.BatteryTemp] = 21; // TODO simulate this
util.map16Bit(data, AnalogOff.BatteryCurrent, 900); data[AnalogOff.BatteryCurrent] = 100; // TODO simulate this
const inputNodes = ev3board().getInputNodes(); const inputNodes = ev3board().getInputNodes();
for (let port = 0; port < DAL.NUM_INPUTS; port++) { for (let port = 0; port < DAL.NUM_INPUTS; port++) {
const node = inputNodes[port]; const node = inputNodes[port];

View File

@ -8,7 +8,6 @@ namespace pxsim.MMapMethods {
read?: (d: Buffer) => number; read?: (d: Buffer) => number;
write?: (d: Buffer) => number; write?: (d: Buffer) => number;
ioctl?: (id: number, d: Buffer) => number; ioctl?: (id: number, d: Buffer) => number;
lseek?: (offset: number, whence: number) => number;
} }
import BM = pxsim.BufferMethods import BM = pxsim.BufferMethods
@ -24,7 +23,6 @@ namespace pxsim.MMapMethods {
if (!impl.read) impl.read = () => 0 if (!impl.read) impl.read = () => 0
if (!impl.write) impl.write = () => 0 if (!impl.write) impl.write = () => 0
if (!impl.ioctl) impl.ioctl = () => -1 if (!impl.ioctl) impl.ioctl = () => -1
if (!impl.lseek) impl.lseek = (offset, whence) => -1
} }
destroy() { destroy() {
} }
@ -70,10 +68,6 @@ namespace pxsim.MMapMethods {
export function read(m: MMap, data: Buffer): number { export function read(m: MMap, data: Buffer): number {
return m.impl.read(data) return m.impl.read(data)
} }
export function lseek(m: MMap, offset: number, whence: number): number {
return m.impl.lseek(offset, whence);
}
} }
namespace pxsim.control { namespace pxsim.control {

View File

@ -17,8 +17,6 @@ namespace pxsim {
private speedCmdTime: number; private speedCmdTime: number;
private _synchedMotor: MotorNode; // non-null if synchronized private _synchedMotor: MotorNode; // non-null if synchronized
private manualSpeed: number = undefined;
constructor(port: number, large: boolean) { constructor(port: number, large: boolean) {
super(port); super(port);
this.setLarge(large); this.setLarge(large);
@ -42,10 +40,6 @@ namespace pxsim {
} }
setSpeedCmd(cmd: DAL, values: number[]) { setSpeedCmd(cmd: DAL, values: number[]) {
if (this.speedCmd != cmd ||
JSON.stringify(this.speedCmdValues) != JSON.stringify(values))
this.setChangedState();
// new command TODO: values
this.speedCmd = cmd; this.speedCmd = cmd;
this.speedCmdValues = values; this.speedCmdValues = values;
this.speedCmdTacho = this.angle; this.speedCmdTacho = this.angle;
@ -98,17 +92,6 @@ namespace pxsim {
this.started = true; this.started = true;
} }
manualMotorDown() {
}
manualMotorMove(speed: number) {
this.manualSpeed = speed;
}
manualMotorUp() {
this.manualSpeed = undefined;
}
updateState(elapsed: number) { updateState(elapsed: number) {
//console.log(`motor: ${elapsed}ms - ${this.speed}% - ${this.angle}> - ${this.tacho}|`) //console.log(`motor: ${elapsed}ms - ${this.speed}% - ${this.angle}> - ${this.tacho}|`)
const interval = Math.min(20, elapsed); const interval = Math.min(20, elapsed);
@ -122,7 +105,6 @@ namespace pxsim {
} }
private updateStateStep(elapsed: number) { private updateStateStep(elapsed: number) {
if (!this.manualSpeed) {
// compute new speed // compute new speed
switch (this.speedCmd) { switch (this.speedCmd) {
case DAL.opOutputSpeed: case DAL.opOutputSpeed:
@ -196,10 +178,6 @@ namespace pxsim {
break; break;
} }
} }
}
else {
this.speed = this.manualSpeed;
}
this.speed = Math.round(this.speed); // integer only this.speed = Math.round(this.speed); // integer only
// compute delta angle // compute delta angle

View File

@ -97,7 +97,6 @@ namespace pxsim {
motors.forEach(motor => motor.stop()); motors.forEach(motor => motor.stop());
return 2; return 2;
} }
case DAL.opOutputPower:
case DAL.opOutputSpeed: { case DAL.opOutputSpeed: {
// setSpeed // setSpeed
const port = buf.data[1]; const port = buf.data[1];

View File

@ -1,23 +0,0 @@
namespace pxsim.storage {
export function __stringToBuffer(s: string): RefBuffer {
// TODO
return new RefBuffer(new Uint8Array([]));
}
export function __bufferToString(b: RefBuffer): string {
// TODO
return "";
}
export function __mkdir(fn: string) {
// TODO
}
export function __unlink(filename: string): void {
// TODO
}
export function __truncate(filename: string): void {
// TODO
}
}

View File

@ -1,74 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 82 156">
<svg width="82px" height="156px" viewBox="0 0 82 156" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs>
<!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch --> <clipPath id="clip-path" transform="translate(0.98 1.9)">
<path d="M79,17.05A17.07,17.07,0,0,1,64.92,33.86l.36.39V70c0,.42-.14.4-.39.68L54,81.22v10l.75.78v.79h6.79a4,4,0,0,1,4,4v25.82a4,4,0,0,1-4,4H54.75v8.18A5.79,5.79,0,0,1,49,140.61h-6.5v7.57a4,4,0,0,1-2.9,3.84v1a.6.6,0,0,1-.6.6H12.69a.6.6,0,0,1-.6-.6h0v-1.29a4,4,0,0,1-2.17-3.55v-7.57H6.3a5.78,5.78,0,0,1-5.78-5.79h0V105.18C10.89,91.12,18.65,81.32,18.65,81.32h.59l13.68.1,0-11.8H26a4,4,0,0,1-4-4V39.79a4,4,0,0,1,4-4h6.78l0-11.77c0-.84.15-.84.46-1.14l10.41-10.1.22-.19a1.53,1.53,0,0,1,1.59.23A17.07,17.07,0,0,1,79,17.05Z" style="fill: none"/>
</clipPath>
<clipPath id="clip-path-2" transform="translate(0.98 1.9)">
<path d="M49,140.61H6.3a5.78,5.78,0,0,1-5.78-5.79h0V105.18C10.89,91.12,18.65,81.32,18.65,81.32h.59s19.46.14,23.87.14a2.27,2.27,0,0,1,2.37,1L54.75,92v42.79A5.79,5.79,0,0,1,49,140.61Z" style="fill: none"/>
</clipPath>
<clipPath id="clip-path-3" transform="translate(0.98 1.9)">
<path d="M43.18,135.24H12.09a5.78,5.78,0,0,1-5.79-5.78h0V107.21C15,95.94,21.86,86.8,21.86,86.8H43.18A5.78,5.78,0,0,1,49,92.58h0v36.88a5.78,5.78,0,0,1-5.78,5.78Z" style="fill: none"/>
</clipPath>
</defs>
<title>Large Motor</title> <title>Large Motor</title>
<desc>Created with Sketch.</desc> <g style="isolation: isolate">
<defs></defs> <g id="e13b39e7-895d-4931-9be9-7aecaf709784">
<g id="Artboard" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(-66.000000, -54.000000)"> <g style="clip-path: url(#clip-path)">
<g id="Large-Motor" transform="translate(66.000000, 54.000000)"> <g id="Large_Motor" data-name="Large Motor">
<path d="M39.98,155.52 L13.67,155.52 C13.3386292,155.52 13.07,155.251371 13.07,154.92 L13.07,149.62 C13.07,149.288629 13.3386292,149.02 13.67,149.02 L39.98,149.02 C40.3113708,149.02 40.58,149.288629 40.58,149.62 L40.58,154.9 C40.5854219,155.062566 40.5246096,155.220368 40.4114947,155.337253 C40.2983799,155.454138 40.1426565,155.52009 39.98,155.52 Z" id="LM_back2" fill="#A8AAA8" fill-rule="nonzero"></path> <path id="LM_back2" data-name="LM back2" d="M39,153.62H12.69a.6.6,0,0,1-.6-.6h0v-5.3a.6.6,0,0,1,.6-.6H39a.6.6,0,0,1,.6.6V153A.6.6,0,0,1,39,153.62Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
<g id="Group" transform="translate(9.000000, 136.000000)"> <g>
<image id="Bitmap" opacity="0.3" style="mix-blend-mode: multiply;" x="0" y="0" width="36" height="20" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAVCAYAAADB5CeuAAAAAXNSR0IArs4c6QAAAMRJREFUSA3tlrERwjAMRW2OEmYgPQMwFrMwAytBT1iB9OY/x05J1IAopLtv2Y5yevfPhXIpJWVF+oMQSwEDmJ00tKzkFpM6P8Q1bbUZpLN0lLwcw6G7dJFuQOEUQCfJE0rtK0sCigCmq144LIshG4fmqy0DatWiVhBOhVNWB6x18abCKasD1rr+puocY/3pS3ULA1DMMU/pJfHBQ/SGAZY6JYzKVw6Kw5x+vnYGcsptHN5rDxCzlUfg0CgWHJuhPCg+9XwDDy9ID0K8XgsAAAAASUVORK5CYII="></image> <image width="36" height="20" transform="translate(9 136)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAVCAYAAADB5CeuAAAACXBIWXMAAAsSAAALEgHS3X78AAAAp0lEQVRIS+3WsW3DMBBG4Y+GSmcGp/cAHsuzeIasFPdWVpD6c0FKcBWwOxV8wIEgSIAPvOL+EhFKKcUBiIiAgjO+25rJildErJMqdMdVlcwg8MQDv5P6Q1fc5ErRujW1TfmoLPa3T//dymJI9TKkehlSvQypXoZUL5vUNhAz2R1Oao75w9IOMmpRHVZqSpjxo3KRw+YwQ2lx+EsVykqfK+aIWGhSR+MNDy9ID5XUCOsAAAAASUVORK5CYII=" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path d="M33.84,18.07 L2.51,18.07 C2.17862915,18.07 1.91,17.8013708 1.91,17.47 L1.91,2.77 C1.91,2.43862915 2.17862915,2.17 2.51,2.17 L33.84,2.17 C34.1713708,2.17 34.44,2.43862915 34.44,2.77 L34.44,17.47 C34.44,17.8013708 34.1713708,18.07 33.84,18.07 Z" id="LM_back1-2" fill="#A8AAA8" fill-rule="nonzero"></path> <path id="LM_back1-2" data-name="LM back1-2" d="M41.86,152.17H10.53a.6.6,0,0,1-.6-.6v-14.7a.6.6,0,0,1,.6-.6H41.86a.6.6,0,0,1,.6.6h0v14.7A.6.6,0,0,1,41.86,152.17Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
</g> </g>
<g id="LM_rightside" transform="translate(22.000000, 37.000000)" fill-rule="nonzero"> <g id="LM_rightside" data-name="LM rightside">
<path d="M12.06,34.51 L6.45,34.51 C4.99937339,34.5153259 3.60647912,33.9421088 2.57978624,32.9172929 C1.55309337,31.892477 0.977328505,30.5006339 0.98,29.05 L0.98,6.15 C0.977339027,4.70110385 1.55173283,3.31078487 2.57625885,2.28625885 C3.60078487,1.26173283 4.99110385,0.687339027 6.44,0.69 L12.05,0.69 C15.0654747,0.69 17.51,3.13452527 17.51,6.15 L17.51,29.05 C17.5126553,30.4971617 16.939633,31.8859609 15.9172718,32.910198 C14.8949106,33.9344351 13.5071641,34.5100024 12.06,34.51 Z" id="LM_rightside5" fill="#A8AAA8"></path> <path id="LM_rightside5" data-name="LM rightside5" d="M33.08,69.61H27.47A5.45,5.45,0,0,1,22,64.15h0V41.25a5.45,5.45,0,0,1,5.46-5.46h5.61a5.46,5.46,0,0,1,5.46,5.46v22.9A5.45,5.45,0,0,1,33.08,69.61Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
<circle id="LM_rightside4" fill="#FFFFFF" cx="6.3" cy="29.21" r="3.79"></circle> <circle id="LM_rightside4" data-name="LM rightside4" cx="28.3" cy="66.21" r="3.79" style="fill: #fff"/>
<circle id="LM_rightside3" fill="#FFFFFF" cx="6.3" cy="6" r="3.79"></circle> <circle id="LM_rightside3" data-name="LM rightside3" cx="28.3" cy="43" r="3.79" style="fill: #fff"/>
<path d="M3.38,24.59 C4.07351535,24.1313154 4.88857129,23.8909784 5.72,23.9 C6.76862292,23.8298668 7.81405119,24.0772848 8.72,24.61 C9.97,25.54 9.95,24.51 9.95,24.51 L9.95,22.71 C9.95,22.26 9.39,21.86 8.72,22.25 L7.72,22.83 C7.72,22.83 7.36,23.02 7.36,22.5 L7.36,19.9 C7.36,19.9 7.36,19.11 8.09,19.13 C8.82,19.15 9.47,19.13 9.47,19.13 C9.47,19.13 9.76,18.88 9.76,17.74 C9.76,16.6 9.47,16.42 9.47,16.42 L8.08,16.42 C8.08,16.42 7.35,16.42 7.35,15.77 L7.35,14.47 C7.35,14.47 7.12,14.11 6.18,14.17 C5.6978322,14.1741563 5.22153417,14.2762201 4.78,14.47 L4.78,15.77 C4.77453579,16.1305967 4.48063814,16.4200414 4.12,16.42 C3.49,16.42 2.86,16.42 2.86,16.42 C2.86,16.42 2.61,16.61 2.57,17.74 C2.53,18.87 2.86,19.13 2.86,19.13 L4.12,19.13 C4.12,19.13 4.92,19.18 4.94,19.9 C4.96,20.62 4.94,22.52 4.94,22.52 C4.94,22.52 4.94,23.03 4.6,22.85 L3.39,22.27 C3.39,22.27 2.56,21.86 2.57,22.73 C2.58,23.6 2.57,24.53 2.57,24.53 C2.57,24.53 2.65,25.02 3.38,24.59 Z" id="LM_rightside2" fill="#FFFFFF"></path> <path id="LM_rightside2" data-name="LM rightside2" d="M24.4,59.69A4.16,4.16,0,0,1,26.74,59a5.23,5.23,0,0,1,3,.71c1.25.93,1.23-.1,1.23-.1v-1.8c0-.45-.56-.85-1.23-.46l-1,.58s-.36.19-.36-.33V55s0-.79.73-.77,1.38,0,1.38,0,.29-.25.29-1.39-.29-1.32-.29-1.32H29.1s-.73,0-.73-.65v-1.3s-.23-.36-1.17-.3a3.56,3.56,0,0,0-1.4.3v1.3a.66.66,0,0,1-.66.65c-.63,0-1.26,0-1.26,0s-.25.19-.29,1.32.29,1.39.29,1.39h1.26s.8.05.82.77,0,2.62,0,2.62,0,.51-.34.33l-1.21-.58s-.83-.41-.82.46,0,1.8,0,1.8S23.67,60.12,24.4,59.69Z" transform="translate(0.98 1.9)" style="fill: #fff"/>
<path d="M10.23,12.79 C10.1913976,13.0147775 10.0630557,13.2141964 9.87446015,13.3424414 C9.68586455,13.4706864 9.453229,13.5167322 9.23,13.47 C9.14591061,13.4523039 9.06499079,13.421959 8.99,13.38 C8.1099436,12.9124008 7.1357966,12.6492102 6.14,12.61 C5.162003,12.5962776 4.20061308,12.8635231 3.37,13.38 C2.54,13.78 2.3,12.79 2.3,12.79 L2.3,11.03 C2.33192589,10.6400455 2.66941985,10.3469587 3.06,10.37 C3.16998614,10.3773249 3.27646607,10.4116733 3.37,10.47 C4.20732336,10.980005 5.16044012,11.2690368 6.14,11.31 C7.13850164,11.2335413 8.10964397,10.9473099 8.99,10.47 C8.99,10.47 10.17,10.23 10.19,11.03 C10.21,11.83 10.23,12.79 10.23,12.79 Z" id="LM_rightside1" fill="#FFFFFF"></path> <path id="LM_rightside1" data-name="LM rightside1" d="M31.25,47.89a.84.84,0,0,1-1,.68.85.85,0,0,1-.24-.09,6.63,6.63,0,0,0-2.85-.77,5.11,5.11,0,0,0-2.77.77c-.83.4-1.07-.59-1.07-.59V46.13a.72.72,0,0,1,.76-.66.67.67,0,0,1,.31.1,5.79,5.79,0,0,0,2.77.84,7.12,7.12,0,0,0,2.85-.84s1.18-.24,1.2.56S31.25,47.89,31.25,47.89Z" transform="translate(0.98 1.9)" style="fill: #fff"/>
</g> </g>
<g id="Group" transform="translate(32.000000, 12.000000)"> <g>
<image id="Bitmap" opacity="0.3" style="mix-blend-mode: multiply;" x="0" y="0" width="36" height="76" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAABNCAYAAAAhOa00AAAAAXNSR0IArs4c6QAAAnlJREFUaAXtmsFRwzAQRROGI6EEwhmGEqABTtyhACqiAC4cOVBBaAEKCB0AuYf/hdbjBMcrbYTlw+7MZp3IWr98OZIn2ul6vZ7k2BTG89Evr2PGRaY5ucEzQ+55zL9EXP0HXDJUBLoCyG2EekZ8hy8B9h0/KxKSoFpA97jqJZxDSKUI9QhflAQ7RMJe2wKiUhxC2jn8BH7ENzivGFgvVA9Q4MDLMZygwUqB7YRSgISDkcoVBeuEygASuLJgnBLaHr/5NeIL/AvO+SjVP3HuE/wCHn5E7dypxwfo3JhBoaZvPKBiZ9F5bDOhR28msSrUVpLqUmXmmkn+nBiGjp1jEsuQtYHkeC8wsBQH2huMv745/A7Omdp+H6DzljGXaaogFGdkzswlgZAumAlM5qnwOCKZCsdsMIEqzPEnXRbYUFCkTAYbEioZbGioJLAaUCpYLahesJpQO8FqQwkYV5MVnM/9bxuPLjyjknG64KoSnvfHAkUtmlVlTFAEC+ZQooQWXSlNIWl3pUQJLbpSmkLS7kqJElp0pTSFpN2VEiW06EppCkm7KyVKaNGV0hSSdldKlNCiK6UpJO2ulCihRVdKU0jaXSlRQouulKaQtI9JKW7JBRsLFCtAPuD8M3YyBigCvcJZCcJ/h6tDEWgBf2DEPnOomampVCcQ4KoptROoFlQvUA0oFWhoqCSgIaGSgYaCygIaAiobiFCy3yelIPyM1uwo/b41vZqAeCVCcb1hwR+NMNxzY6lJ2HtDtBiBuHRszNSpiQTiFB0EgkA3cEarcQ0zVzWGajAUc7WHq4RSYetV1rLcb9ZZ57kFmZsznA8g3qcm64QyZSrY6Qey39wRVmjftAAAAABJRU5ErkJggg=="></image> <image width="36" height="76" transform="translate(32 12)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAABNCAYAAAAhOa00AAAACXBIWXMAAAsSAAALEgHS3X78AAACAElEQVRoQ+3avVHDMBiA4VdcypgREmo4RggLpKKHAZiIAWgoKZggrEAGCBsQpxeFpNgJ/vkkK5YLvXe6g2Cb53zE9oVPaa3xSSmlALTvjh4pn2MrpQpgab/dAYdL4MQoC3oAnuxLH8AW2Gmty9YdAxKhaqAXYAUozJnaAm/AJiZs1rfBGegBKOyP7oAFMLfbRYN1ojpAYM7WtX3dbR8F1orqAdVz27n9BsMaUR4gV1yY1vpkYX7BGvgE9oD2WL/AO3CPfROFrKs6MOAMnVcAt3b57lsV6QzV194eYw0UfWelacUGRYFdAjQYNsPcy54xV+rwv4P/Bb8jZ5gr8oK4IFcQzF2nVOdWw/KG9d77IuUFGwsFHrAxUSCEjY0CASwFCnpgqVDQAUuJghZYahQY2Ao4YJ77v08eXRJWUHvenwoKaneVKaGOZZS0jJKWUdIySlpGScsoaRklLaOkZZS0jJKWUdIySlpGScsoaRklLaOkTQml3RdTQZXAD+bD2EmgSuALMwmyg/SoEtgAr9RGU1KiGkGQDtUKgjSoThCMj+oFwbgoEQjGQ4lBMA7KCwSXR3mDoPonpBsFccWYUwgCgUEdMAN/YDBzzKjJvG0nQe7W4Q2CCnFDhVgCj1TznCHtGDDVqLTWxylXW4wzdWDA/GfjnOcZMijddGBhouHTsfsDst/cEY24RzwAAAAASUVORK5CYII=" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path d="M33.89,60.6 L20.48,73.53 L1.91,72.9 L1.74,13.9 C1.74,13.06 1.9,13.06 2.2,12.77 L12.62,2.67 L12.83,2.48 C13.42,2.08 14.83,2.59 14.83,3.43 L34.27,24.15 L34.27,59.9 C34.28,60.34 34.14,60.33 33.89,60.6 Z" id="LM_level4-2" fill="#A8AAA8" fill-rule="nonzero"></path> <path id="LM_level4-2" data-name="LM level4-2" d="M64.91,70.7,51.5,83.63,32.93,83,32.76,24c0-.84.16-.84.46-1.13l10.42-10.1.21-.19c.59-.4,2,.11,2,.95L65.29,34.25V70C65.3,70.44,65.16,70.43,64.91,70.7Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
</g> </g>
<g id="Group" transform="translate(32.000000, 69.000000)"> <g>
<image id="Bitmap" opacity="0.3" style="mix-blend-mode: multiply;" x="0" y="0" width="25" height="27" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAYAAAB/E6/TAAAAAXNSR0IArs4c6QAAAZhJREFUSA3tlj1SwzAQRnEmJanogYoChiOQC1BxAA7AcTgDDQfgBLlDekxNQ5LefE/WeizHGa9l07Ezny3L2n36W9lFVVVnXStk3Trvs+IdB5Rz0a0XY6X6K+ncG7zV7qByqZj7Vl0oJqAIWevNswRsrJVyeJM2XdjSIrUgL6p7kBjZWLuVQ5gJxUthcepYk3vpXfqRmOdc7eT7IT1KK+IjGxG9pzcoZyRyawx/ZiSsl0a2FahaxCnjBetyLWXvOPmaAbuUmg210AOLDgTY1NEoRGNJhwFBhT4npKFZARCW0Ouqea8GmjdqT7R/UM+k+KosYe0U8HhlbRxAZPA2EoaCkArkHfehtjFkfQP0Kb1KTRarfMqAPEl3EmV37i11DB04j+TkMdohQJwmfFJcsLBGHHpy8Ng+dupLjZlyzAWzzVC7OK6xUzsBN63mg7DRIAsuIKNzw7JBAMfAJoFOwPjcHO3gyaAeGJuEL3XyJzQLqAMrI+imDUt+t3CYatognBhM3YX0rXUMaTA7yDoKMKZCqPozkAHt/gsh4I9CsIZ80gAAAABJRU5ErkJggg=="></image> <image width="25" height="27" transform="translate(32 69)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAYAAAB/E6/TAAAACXBIWXMAAAsSAAALEgHS3X78AAABYUlEQVRIS+2WvVXDMBRG7/NxGVf0CRVFchghWSAVA2QAxmEGGgZgguzgHlPTELv/KCSD/BMs2wkV9xwf2/LPlZ70JJkk2piZdQojUd8PAWuXm1kGrIBF3wcDVEAhqWw/aIi8ZAcccLKxFMAzcGzL0voikDwCWyBjPGt8JMysKfMtMuAeeAE+Ac04TsArsAcySUj6blGGq82aaS0JyXARqYDCzHJJSnzItrh+ucW1bi4ZsCQYUAmu0w9M75dzNCqc4KxLLivpkPjzJcL1Kwl/xL9oMnXC1lkdw6SBk+IyOPf3Qz9Z8DOzD73bIAXegCfiloUV8ABs/HV07qWSKjPLiSP3xwY3m+yIlKVwflXsofSVeseFHCJlKSPxlTqZ2TEoHpSNFtVIKsfIJotgnGyWCHplW3pG8GwRdGQVbqXu35zMJZAVONEdgayzr5uL33wugBvgQ1IFVxDVmJmF+Xk1UZsvIeCPQjWq5BoAAAAASUVORK5CYII=" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path d="M22.9800421,24.9 L22.98,7.6 C22.9824406,7.20649401 22.8788083,6.81960003 22.68,6.48 C22.4,6.21 19.16,2.86 19.16,2.86 C18.8448174,2.57277854 18.4252272,2.42809227 18,2.46 C17.25,2.46 6.38,2.46 6.38,2.46 L1.98,7.16 L1.98,15.16 L12.64,15.73 L22.9800421,24.9 Z" id="LM_level3-2" fill="#A8AAA8" fill-rule="nonzero"></path> <path id="LM_level3-2" data-name="LM level3-2" d="M54,92V74.7a2.19,2.19,0,0,0-.3-1.12c-.28-.27-3.52-3.62-3.52-3.62a1.55,1.55,0,0,0-1.16-.4c-.75,0-11.62,0-11.62,0L33,74.26v8l10.66.57Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
</g> </g>
<g id="LM_leftside" transform="translate(49.000000, 94.000000)" fill-rule="nonzero"> <g id="LM_leftside" data-name="LM leftside">
<path d="M12.06,34.54 L6.45,34.54 C4.99937339,34.5453259 3.60647912,33.9721088 2.57978624,32.9472929 C1.55309337,31.922477 0.977328505,30.5306339 0.98,29.08 L0.98,6.18 C0.98,3.16452527 3.42452527,0.72 6.44,0.72 L12.05,0.72 C15.0631921,0.725503561 17.5044964,3.16680786 17.51,6.18 L17.51,29.08 C17.5126553,30.5271617 16.939633,31.9159609 15.9172718,32.940198 C14.8949106,33.9644351 13.5071641,34.5400024 12.06,34.54 Z" id="LM_leftside5" fill="#A8AAA8"></path> <path id="LM_leftside5" data-name="LM leftside5" d="M60.08,126.64H54.47A5.45,5.45,0,0,1,49,121.18h0V98.28a5.46,5.46,0,0,1,5.46-5.46h5.61a5.47,5.47,0,0,1,5.46,5.46v22.9A5.45,5.45,0,0,1,60.08,126.64Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
<circle id="LM_leftside4" fill="#FFFFFF" cx="12.67" cy="29.24" r="3.79"></circle> <circle id="LM_leftside4" data-name="LM leftside4" cx="61.67" cy="123.24" r="3.79" style="fill: #fff"/>
<circle id="LM_leftside3" fill="#FFFFFF" cx="12.67" cy="6.03" r="3.79"></circle> <circle id="LM_leftside3" data-name="LM leftside3" cx="61.67" cy="100.03" r="3.79" style="fill: #fff"/>
<path d="M9.75,24.62 C10.4421225,24.1572205 11.2574415,23.9133217 12.09,23.92 C13.1380484,23.8411302 14.1850856,24.0854388 15.09,24.62 C16.34,25.55 16.32,24.52 16.32,24.52 L16.32,22.72 C16.32,22.27 15.76,21.88 15.09,22.26 L14.09,22.84 C14.09,22.84 13.73,23.03 13.73,22.51 L13.73,19.9 C13.73,19.9 13.73,19.11 14.46,19.13 C15.19,19.15 15.84,19.13 15.84,19.13 C15.84,19.13 16.13,18.88 16.13,17.75 C16.13,16.62 15.84,16.42 15.84,16.42 L14.45,16.42 C14.45,16.42 13.72,16.42 13.72,15.78 L13.72,14.48 C13.72,14.48 13.49,14.12 12.55,14.17 C12.0671703,14.1775857 11.5908982,14.283046 11.15,14.48 L11.15,15.78 C11.1391868,16.1366743 10.8468382,16.4201639 10.49,16.42 L9.23,16.42 C9.23,16.42 8.98,16.62 8.94,17.75 C8.9,18.88 9.23,19.13 9.23,19.13 L10.49,19.13 C10.49,19.13 11.29,19.13 11.31,19.9 C11.33,20.67 11.31,22.52 11.31,22.52 C11.31,22.52 11.31,23.03 10.97,22.85 L9.76,22.27 C9.76,22.27 8.93,21.87 8.94,22.73 C8.95,23.59 8.94,24.53 8.94,24.53 C8.94,24.53 8.98,25.06 9.75,24.62 Z" id="LM_leftside2" fill="#FFFFFF"></path> <path id="LM_leftside2" data-name="LM leftside2" d="M57.77,116.72a4.15,4.15,0,0,1,2.34-.7,5.14,5.14,0,0,1,3,.7c1.25.93,1.23-.1,1.23-.1v-1.8c0-.45-.56-.84-1.23-.46l-1,.58s-.36.19-.36-.33V112s0-.79.73-.77,1.38,0,1.38,0,.29-.25.29-1.38-.29-1.33-.29-1.33H62.47s-.73,0-.73-.64v-1.3s-.23-.36-1.17-.31a3.57,3.57,0,0,0-1.4.31v1.3a.66.66,0,0,1-.66.64H57.25s-.25.2-.29,1.33.29,1.38.29,1.38h1.26s.8,0,.82.77,0,2.62,0,2.62,0,.51-.34.33l-1.21-.58s-.83-.4-.82.46,0,1.8,0,1.8S57,117.16,57.77,116.72Z" transform="translate(0.98 1.9)" style="fill: #fff"/>
<path d="M16.6,12.82 C16.5640845,13.0461448 16.4363396,13.2474057 16.2469908,13.3761629 C16.057642,13.5049201 15.8235128,13.5497335 15.6,13.5 C15.5157002,13.4885804 15.4342916,13.4614442 15.36,13.42 C14.4821686,12.9467916 13.506699,12.6832437 12.51,12.65 C11.5311949,12.6299456 10.5680375,12.8976825 9.74,13.42 C8.91,13.82 8.67,12.82 8.67,12.82 L8.67,11.06 C8.70188656,10.6714097 9.04116607,10.3812364 9.43,10.41 C9.53837526,10.4186243 9.6438555,10.4492476 9.74,10.5 C10.5773234,11.010005 11.5304401,11.2990368 12.51,11.34 C13.5091637,11.2671668 14.4810541,10.9807149 15.36,10.5 C15.36,10.5 16.54,10.26 16.56,11.06 C16.58,11.86 16.6,12.82 16.6,12.82 Z" id="LM_leftside1" fill="#FFFFFF"></path> <path id="LM_leftside1" data-name="LM leftside1" d="M64.62,104.92a.83.83,0,0,1-1,.68.68.68,0,0,1-.24-.08,6.46,6.46,0,0,0-2.85-.77,5,5,0,0,0-2.77.77c-.83.4-1.07-.6-1.07-.6v-1.76a.71.71,0,0,1,.76-.65.8.8,0,0,1,.31.09,5.79,5.79,0,0,0,2.77.84,7,7,0,0,0,2.85-.84s1.18-.24,1.2.56S64.62,104.92,64.62,104.92Z" transform="translate(0.98 1.9)" style="fill: #fff"/>
</g> </g>
<g id="Group" transform="translate(0.000000, 81.000000)"> <g>
<image id="Bitmap" opacity="0.3" style="mix-blend-mode: multiply;" x="0" y="0" width="58" height="64" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADsAAABBCAYAAABvnNwUAAAAAXNSR0IArs4c6QAAAqRJREFUaAXtm01OwzAQhSlUYgNbJDalaxBHgAtwBg7AiVixYsOODScoN0DqAcoNoJUQq/CecaK64zhOm7T1yCNNf+zUns/P4xjkDIqiOOjKBrCu2mpqB3G3Dnywxm+8cYDzFBUX8BPvBd0WLtDcDL5oA90JrAW9Ref3cAL3bQR9hU/hMwDPYzrcGHYJ9AEd3sCpcN9WKkvYZ/gkBni4SVQroFR2G6AMmf1cwUdwkzaIpRmYObuO2w7v8P4G/4ZzwdiFf6HfF/g13MzUOp5DXNDaMIpcdcdw5ui2pi668hpVvrQenFlrwaLh6A684XVb6Ay8TS1vD61z1jZGNanqGM7Odm0cfK4ZxhCjN39bwVpQNsqVd5sL0j9F+LUROBoWoM50Qb/B/AjH1VttEDga1sJFLQS9ocQ1XAscBWun777laQidwIzXbD4Q/xS3o6JxNbag+5qnTcAjXFDt1YOwAE0hT0PAzp0iCItWOB1SyNMQcFVXC2unb0p5WkHVffDCJpyndZymXMAqyNNaYAGLK1Xl6TK5A6sxT72wWvNUwGrOUwGLArV56sBqz1MHFl/4r0/+Ic4NBBVWa1yNuVHmhlk1KBUsbz3OhpkVGq2E1cgmmDKsGBIlBVlZJUIKjKysGBIlBVlZJUIKjKysGBIlBVlZJUIKjKysGBIlBVlZJUIKjKysGBIlBVlZJUIKjKysGBIlBVlZJUIKjKysGBIlBVlZJUIKjFJZnu3XaA4XYXly8xMe9WxMQiNCHnKRz9gRXn/gfILiDH4OP4anbgR9hz/BP3D69pdAQ3yY41zFhF+spX7coAR9BI/zrIA5XL0CTNl5ziJVmyFw71NczuNp9uQMQasDyQkSm9PjFHA1dgeWlfYA2Op1SX0HqLMKl8EL2LJC4/sftL72OnfR538AAAAASUVORK5CYII="></image> <image width="58" height="64" transform="translate(0 81)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADsAAABBCAYAAABvnNwUAAAACXBIWXMAAAsSAAALEgHS3X78AAACFElEQVRoQ+2bQY7TMBSGvxcqsaFbJDbDrEEcYeYCcwYOwIlYsWLDjg0nGG6A1ANkbgCNhGb1WNgBpxPbaUjT+smf5E3lxPlq/25S5YmqshQiIrk+S6EzLlxmHDOKiGyB18CLXN8F6IAW6I6RXkTWi94C73HCp6YFvgI7oFXVfaY/sIBsIPoBuAG26SMWoZ/ZHfAZuJ8ivMl1SHEgess6ouDGeQtc4WMjInlhVZ3VcAPeAd+AX4Ceqf0EvgDv8Cs11hpm4Hfda1xG11q6MbbAG9+S1zFLliMGWIHBF++jNcrRmfUnu8Gd/Bo32Lnp9w4gnt+jZM+4IU0hKzxZ9sJyGiMpPFmWy8ppiqjwJNkLzWmK/no7oBWRnapqdje+8Jym2BLcdEDmp6eQnKYYrMDczJaS00lEZQvMaZZR2YJzmuSJrIGcRhmbWVM5DRnIWsxpyF9ZqzkNacB2TkP6mTWb05DGek5DGtxfn6aXb0+Du1G+wrgo/Mus2aUbknsQMEWVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUovq8le5TLwanBvbj4A2VKRwtjjvLr+g2fAb1wFxUvgFfB89NCy2APfgU/AD1V9BNio6l5E7oOOpb9u0It+5KC4aQNwINyxTonZqWiJVHENytNk3eLBU9ERqc97UovnXwArGj2U8vx34WFJ/AG0vvY6LSeZMAAAAABJRU5ErkJggg==" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path d="M49.98,61.51 L7.29,61.51 C4.09779415,61.51 1.51,58.9222059 1.51,55.73 L1.51,26.09 C11.87,12.03 19.63,2.22 19.63,2.22 L20.23,2.22 C20.23,2.22 39.69,2.37 44.09,2.37 C45.013529,2.18179526 45.9580478,2.5786519 46.47,3.37 L55.73,12.9 L55.73,55.7 C55.7379772,57.2329575 55.1366519,58.7062958 54.0583133,59.7958867 C52.9799747,60.8854775 51.5129577,61.5020641 49.98,61.51 Z" id="LM_level2_grey-2" fill="#A8AAA8" fill-rule="nonzero"></path> <path id="LM_level2_grey-2" data-name="LM level2 grey-2" d="M49,140.61H6.31a5.78,5.78,0,0,1-5.78-5.78h0V105.19C10.89,91.13,18.65,81.32,18.65,81.32h.6s19.46.15,23.86.15a2.29,2.29,0,0,1,2.38,1L54.75,92v42.8A5.78,5.78,0,0,1,49,140.61Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
</g> </g>
<g id="LM_total"> <g id="LM_total" data-name="LM total">
<g id="LM_whitepart" transform="translate(0.000000, 89.000000)" fill="#F1F1F1" fill-rule="nonzero"> <g id="LM_whitepart" data-name="LM whitepart">
<g id="LM_whitepart_combined"> <g style="clip-path: url(#clip-path-2)">
<polygon id="LM_whitepart_top" points="44.46 53.9 37.31 46.53 13.52 15.46 13.52 0.6 0.46 16.74 0.46 47.96 1.46 55.65"></polygon> <g id="LM_whitepart_combined" data-name="LM whitepart combined">
<path id="LM_whitepart_top" data-name="LM whitepart top" d="M43.48,141l-7.15-7.37L12.54,102.56V87.7L-.52,103.84v31.22l1,7.69Z" transform="translate(0.98 1.9)" style="fill: #f1f1f1"/>
</g> </g>
</g> </g>
<g id="Group" transform="translate(5.000000, 87.000000)">
<image id="Bitmap" opacity="0.3" style="mix-blend-mode: multiply;" x="0" y="0" width="47" height="52" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAA1CAYAAAAHz2g0AAAAAXNSR0IArs4c6QAAAhhJREFUaAXtWttRwzAQxAyfpAWSb4YWoAFqoIBURAH8UAAVhEpMBxD+za6xFMmyQcqNLWnmbmbHj1in3btTYjvXdF13IbUGJvURMx5cA7LNxLkYX/YacN/gYAtc25PL7HzDbQu+R9e9SMBA/gEOnwCKWNJaOH8BDq6Iq3NndMjv4eMeYCaWtFs477OMuU8iWEKpgCOSfQTegC+AtbkGPjHPK3AH9NVziZ0kg3ou2B3Aslkj8pjGGgN3A9j1liwAg+mE6SSWLhtMEZj3jZckYKh7Rp3R3wGeMxyvbtECBvL8xuGi5TZH9IMARQnIXPcBafdElIAh2jnr3uXs7f8roMS6dxX8KaDUuo8SUAN5CpnMQMmL1o3+rAB8kPvHasxz9jjIQOmLdqzEE1BL3bsirICa6n5SAE5WU/eBgNrq3hMwlA4fB3Pc37tczto3a4APCHxQKOIOM0WJEcAx2e/tU4iba10B5lxVWxWQO12aAc2AMAJaQsIAiodrBsQhFDrQDAgDKB6uGRCHUOhAMyAMoHi4ZkAcQqEDzYAwgOLhmgFxCIUO3Azwn/YazONpBLAT5APwOkEKVEN+5Em+v8Y+CRjfyOXofeDksWBPBnszyHNj+jv6bhUcHPGO9IAPjK3dA2Hmndsy8u/AM3DqVMGBbbcZiWCKtkAp1oJI0CtEckHD0/CqneRtRwgvzGwMaNCtRU6BgMxEk6f/AY1G0nHf2MzkAAAAAElFTkSuQmCC"></image>
<path d="M39.16,50.44 L8.07,50.44 C6.5353168,50.4426552 5.06258085,49.834865 3.97645681,48.7506168 C2.89033276,47.6663686 2.2799977,46.1946855 2.28,44.66 L2.28,22.41 C10.98,11.14 17.84,2 17.84,2 L39.16,2 C40.6998701,1.9893432 42.1803327,2.59359794 43.2729596,3.67871541 C44.3655865,4.76383288 44.9800369,6.24009301 44.98,7.78 L44.98,44.66 C44.98,46.1929513 44.3710375,47.6631169 43.2870772,48.7470772 C42.2031169,49.8310375 40.7329513,50.44 39.2,50.44 L39.16,50.44 Z" id="LM_top_grey-2" fill="#A8AAA8" fill-rule="nonzero"></path>
</g> </g>
<g id="LM_top" transform="translate(17.000000, 112.000000)" fill="#6A6A6A" fill-rule="nonzero"> <g>
<g id="LM_top_total"> <image width="47" height="52" transform="translate(5 87)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAA1CAYAAAAHz2g0AAAACXBIWXMAAAsSAAALEgHS3X78AAABnElEQVRoQ+2azXHCMBBG3zIccQuBM5MWoIHUkAJSUQrIJQWkAlIJ6SDYd+UgGWTjHxQHr5TRm9HFIzz75G8Z8KwYY5iKiMjYnr/AdBQrUwVEpADWwGps70Qq4GiMKf2LkwRc8XvgGStxT47AG3DwJZb9+4fxin8BdkAx/InJbHFPWUQuEsaY4IUt9gn4AE6AmWl9A+/AIy49CwJxDbvBxmaOk/cpgAe8fgsWwN5k69acxdc0vvGCBFzud9jT39C6mQY3C7Sado/O6V9xk4By7ge5SQD93PcyKhBj7n0GBWLNvU+vQArFQ49AzE3bpu8JRNu0ba4EYm/aNg2BVHLvcxZIKfc+/hNIJvc+C0gv9z4LF501iUWnpo7QCvtHIaniodkDycTGZ/THXOxkAW2ygDZZQJssoE0W0CYLaJMFtMkC2mQBbbKANv9K4PdDE/PSqLMWqIAvoDEJEiElts7qfEV59iFknbD1PQFFPbexBDDGlCJy4EJs70hL4BN4pW/cpiVRcf/5nxA6Z4WgY+BpxgmsEDqntWDixFYM/ACNRtJx4q2GRAAAAABJRU5ErkJggg==" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path d="M2.58,1.95 L2.58,29.42 C2.53732346,30.0007732 2.04187943,30.443134 1.46,30.42 C0.901094365,30.4156223 0.441619994,29.9780276 0.41,29.42 L0.41,1.95 C0.449349984,1.38861093 0.909606462,0.949468178 1.47222361,0.93650465 C2.03484076,0.923541121 2.51483504,1.34101911 2.58,1.9 L2.58,1.95 Z M6.19,1.95 L6.19,29.42 C6.2296472,29.8325035 6.03195189,30.231808 5.67986701,30.4503653 C5.32778212,30.6689226 4.88221788,30.6689226 4.53013299,30.4503653 C4.17804811,30.231808 3.9803528,29.8325035 4.02,29.42 L4.02,1.95 C3.9803528,1.53749648 4.17804811,1.138192 4.53013299,0.919634704 C4.88221788,0.701077408 5.32778212,0.701077408 5.67986701,0.919634704 C6.03195189,1.138192 6.2296472,1.53749648 6.19,1.95 Z M9.81,1.95 L9.81,29.42 C9.8496472,29.8325035 9.65195189,30.231808 9.29986701,30.4503653 C8.94778212,30.6689226 8.50221788,30.6689226 8.15013299,30.4503653 C7.79804811,30.231808 7.6003528,29.8325035 7.64,29.42 L7.64,1.95 C7.6003528,1.53749648 7.79804811,1.138192 8.15013299,0.919634704 C8.50221788,0.701077408 8.94778212,0.701077408 9.29986701,0.919634704 C9.65195189,1.138192 9.8496472,1.53749648 9.81,1.95 Z M13.42,1.95 L13.42,29.42 C13.3873113,29.9829764 12.9306072,30.4280683 12.3669758,30.44625 C11.8033444,30.4644316 11.318904,30.0496992 11.25,29.49 L11.25,1.95 C11.2826887,1.38702361 11.7393928,0.941931677 12.3030242,0.923750018 C12.8666556,0.905568359 13.351096,1.3203008 13.42,1.88 L13.42,1.95 Z M17.04,1.95 L17.04,29.42 C17.0513034,30.0199642 16.5796777,30.5182857 15.98,30.54 C15.401933,30.5576338 14.9125708,30.1167669 14.87,29.54 L14.87,1.95 C14.9026887,1.38702361 15.3593928,0.941931677 15.9230242,0.923750018 C16.4866556,0.905568359 16.971096,1.3203008 17.04,1.88 L17.04,1.95 Z" id="LM_top_lines"></path> <path id="LM_top_grey-2" data-name="LM top grey-2" d="M43.18,135.54H12.09a5.78,5.78,0,0,1-5.79-5.78h0V107.51C15,96.24,21.86,87.1,21.86,87.1H43.18A5.78,5.78,0,0,1,49,92.88h0v36.88a5.78,5.78,0,0,1-5.78,5.78Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
</g>
<g id="LM_top" data-name="LM top">
<g style="clip-path: url(#clip-path-3)">
<g id="LM_top_total" data-name="LM top total">
<path id="LM_top_lines" data-name="LM top lines" d="M18.6,112.05v27.47a1.08,1.08,0,0,1-1.12,1,1.06,1.06,0,0,1-1.05-1V112.05A1.09,1.09,0,0,1,18.6,112Zm3.61,0v27.47a1.09,1.09,0,1,1-2.17,0V112.05a1.09,1.09,0,1,1,2.17,0Zm3.62,0v27.47a1.09,1.09,0,1,1-2.17,0V112.05a1.09,1.09,0,1,1,2.17,0Zm3.61,0v27.47a1.09,1.09,0,0,1-2.17.07V112.05a1.09,1.09,0,0,1,2.17-.07Zm3.62,0v27.47A1.1,1.1,0,0,1,32,140.64a1.08,1.08,0,0,1-1.11-1V112.05a1.09,1.09,0,0,1,2.17-.07Z" transform="translate(0.98 1.9)" style="fill: #6a6a6a"/>
</g> </g>
</g> </g>
<circle id="LM_detail_2" fill="#9A9A9A" fill-rule="nonzero" cx="50.32" cy="137.11" r="2.24"></circle>
<image id="Bitmap" opacity="0.3" style="mix-blend-mode: multiply;" x="44" y="0" width="38" height="38" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACcAAAAnCAYAAACMo1E1AAAAAXNSR0IArs4c6QAAAu1JREFUWAnNmD1y1EAQhb1bhJgjsMT8HAEuQGJHRJyOhAwCTmAyQqpMvOsbYDtGvE/Mm+oZaWUtaHfoqt75n/70WquSZtV13dkhtpKF+Y9V38gpbfeq7OSU2RTnsEBauZq7JkHVMIBdyiltgH2SU9oy8CGQs+AEdq4oALyQR5gaFpgMQiOZga/V3gnwzgNT5SRcUguw1/L3cuCAjGlcqV1bV3UYGLgP8q/yu4dUfFRtkpuVWoABCOgYTF6XKvUc1nFhT+VcGH6tGJMqjiqXwN5og6gWAZYwUkqareLV3jRr4Cy6FgHxVv5F/lP+S06alnT2ZG9iEOs8Mrheg5GOV/KPchYvCTS2FzGIRcw+iwajXKszGqo9T0792DYdz6SiYKLTeav62JUeo49Yo+nt06rBU6ezvkin9yUsFsxp5a99ynQqXGFkbSOHI9s6PWgZuJQ/k6NiCwOsAIzK+QHZAgxBLNAmCVb8W1spZjFQrhDIyrUGMyAcmQW4AbFnNigLFuByrlXP1A3AiB1Z+nuuoG0AFUMWLL7n4oSWdd77buSUvXJFB52NrFPcnTy/4qNc7GBCSyuEAq7oaEmWYmeBfM/ljsZwBYfhYCoGGkAOMmi4wcCJ4RAm3/t6ZeqFWqeKB7aa1EpBBIKDsreo3A/14LM+eP8sX+zXX2QZrN/Zb51q/J+v6QHwiSDfyb/Lj/FJyC0Tfe/3A0xOq9b0hrynSi8Xv5X3xxOCGdxOBZwmcFV5ger+ClN1UQOEL/5vqRyAEW1wVsIV6DX5ikEZNyhnHBs59+S/GhcPCAc5KAbgNomiammjZyVMSeclQAEXD3L6YX4OMKD8qPAZyYMnTQPlHDApyEY3aWM2B5Z3LpeqZlulGiDRIhRvHOy5Y/84aay+V7k4OahoMD4jAbS5n3bxIE3tDKX2/b40sjjaLDgW+HNNVYNQ2gC9SI3PKgG0WbnZUF44G84LKAOouw1Mu1aOI4861V43Wf4V3OSOCw7+BmjmA7QisxQnAAAAAElFTkSuQmCC"></image>
<circle id="LM_detail_1" fill="#9A9A9A" fill-rule="nonzero" cx="21.66" cy="86.59" r="2.24"></circle>
<g id="hole" transform="translate(45.000000, 1.000000)" fill-rule="nonzero">
<g id="Group" fill="#D42715">
<circle id="LM_red-2" cx="17.96" cy="17.95" r="17.06"></circle>
</g> </g>
<g id="LM_details_in_red" transform="translate(2.000000, 2.000000)"> <circle id="LM_detail_2" data-name="LM detail 2" cx="50.32" cy="137.11" r="2.24" style="fill: #9a9a9a"/>
<circle id="LM_detail_red_hole4" fill="#393939" cx="12.9" cy="27.01" r="3.79"></circle> <circle id="LM_detail_1" data-name="LM detail 1" cx="21.66" cy="86.59" r="2.24" style="fill: #9a9a9a"/>
<circle id="LM_detail_red_hole3" fill="#393939" cx="4.75" cy="12.89" r="3.79"></circle> <g id="hole">
<circle id="LM_detail_red_hole2" fill="#393939" cx="18.87" cy="4.74" r="3.79"></circle> <g>
<circle id="LM_detail_red_hole1" fill="#393939" cx="27.02" cy="18.86" r="3.79"></circle> <image width="38" height="38" transform="translate(44)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACcAAAAnCAYAAACMo1E1AAAACXBIWXMAAAsSAAALEgHS3X78AAACRklEQVRYR9WYPXLbMBBGHzgpxRwhTJ3ER0gukMauUvl0btIlhU9gdSkzQ9dWbmBTtTYFdiUA/BGh0ILyzWBAUiTx+C0JYdeJCDlyzrlgdwU02pu2wEb7vSR3IMDNvUahUpgGuNHetAF+aG/aA+dAzoJzztV4gI/EMHOdM+AW2IhIxwxNwqlbNfAZuMXDpTBhmE3pTQ24Be6ANdAdc/HN2A+JW7d4wJphmFTpOTX+Pu/wD7YCWufcpIuDzinYF2K36t6Jp6kjdvFhFFBEooaH+ArcA8/ADh+mJdtO732vY9Uph4iQgjngCviuFx8b5F/bs451hUYxbBWxauCDtqXCOKXp8UbC+cLxp16qvTAS3lLhTJuF9xNBeC2sK84bzlQ2bYXzJ5VOtA1+5n/PvHnsNdT7twmdswmyhEKDGltchF9rKcdMPYMMrjSYyRGwVJQPaaiIpSJek5V0MHrv4D9w7pK0Bf5oT5UeKCghWeJXyQEZvfQ8uljnTHuD7J0r7Zgp4gg/iNKAvQgaXOnQRh+DZWWVbtgPT5RzsJfvhs49apuV8C4sy8jiyF38Mj0AfAt8A37zOinhbLCh7KvjfOHd4d/xO2AtA4l1BKcfx/4CDuFdWh0+4/+l/aARvVqJiHTOuQfd3bJsOULwIGu8AS3wZFNHqtEq00QhB/LXfcIJlabRKpM62HKYnLccsiPrQxlwOlgIlVWjyy0eGlhazbTjcKRwSEZ1cxYcRLXgIeca4Fq3f7JAyRUy4EIlRWuYdo5cKNNJcOfSX2jmA7RYwAeRAAAAAElFTkSuQmCC" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path d="M18.18,15.31 C17.9816076,15.2705154 17.8089761,15.149396 17.7043432,14.9762761 C17.5997103,14.8031562 17.5727287,14.5940066 17.63,14.4 C17.84,13.68 17.99,13.07 17.99,13.07 C17.99,13.07 17.82,12.72 16.72,12.43 C15.62,12.14 15.37,12.37 15.37,12.37 L14.98,13.7 C14.98,13.7 14.82,14.42 14.17,14.24 L12.98,13.9 C12.98,13.9 12.58,14.03 12.38,14.96 C12.2599627,15.4271881 12.2395203,15.9143986 12.32,16.39 L13.57,16.72 C13.9132251,16.8260991 14.1147049,17.1808788 14.03,17.53 C13.87,18.14 13.7,18.74 13.7,18.74 C13.7,18.74 13.82,19.04 14.9,19.36 C15.98,19.68 16.32,19.45 16.32,19.45 L16.64,18.23 C16.64,18.23 16.9,17.47 17.64,17.64 C18.04,17.7533333 18.44,17.8833333 18.84,18.03 C19.3790257,17.4116231 19.6330766,16.5950309 19.54,15.78 C18.89,15.55 18.18,15.31 18.18,15.31 Z" id="LM_detail_hole" fill="#1F1F1F"></path> <circle id="LM_red-2" data-name="LM red-2" cx="62.96" cy="18.95" r="17.06" style="fill: #d42715"/>
<path d="M15.62,23.13 L14.07,22.9 L12.54,22.33 C12.29437,22.2663058 12.1467122,22.015735 12.21,21.77 L12.76,19.72 C12.8281001,19.4784149 13.0772913,19.3360199 13.32,19.4 L14.77,20 L16.4,20.22 C16.64563,20.2836942 16.7932878,20.534265 16.73,20.78 L16.18,22.83 C16.1519467,22.9468655 16.0773095,23.0471692 15.9734274,23.1076097 C15.8695454,23.1680501 15.7454609,23.1833663 15.63,23.15 L15.62,23.13 Z" id="LM_detail_red4" fill="#393939"></path> </g>
<path d="M23.13,16.2 L22.87,17.75 L22.3,19.27 C22.2716803,19.3872072 22.1975067,19.4881458 22.0941102,19.5501837 C21.9907137,19.6122216 21.8667451,19.6301684 21.75,19.6 L19.69,19.05 C19.4484149,18.9818999 19.3060199,18.7327087 19.37,18.49 L19.98,17.05 L20.2,15.42 C20.2283197,15.3027928 20.3024933,15.2018542 20.4058898,15.1398163 C20.5092863,15.0777784 20.6332549,15.0598316 20.75,15.09 L22.75,15.64 C22.9915851,15.7081001 23.1339801,15.9572913 23.07,16.2 L23.13,16.2 Z" id="LM_detail_red3" fill="#393939"></path> <g id="LM_details_in_red" data-name="LM details in red">
<path d="M16.19,8.69 L17.74,8.94 L19.27,9.51 C19.5107539,9.57376787 19.6570302,9.81756168 19.6,10.06 L19.05,12.11 C18.9818999,12.3515851 18.7327087,12.4939801 18.49,12.43 L17.04,11.83 L15.41,11.61 C15.167847,11.5417439 15.0223875,11.2949036 15.08,11.05 L15.63,9 C15.6580533,8.88313454 15.7326905,8.78283079 15.8365726,8.72239033 C15.9404546,8.66194987 16.0645391,8.64663373 16.18,8.68 L16.19,8.69 Z" id="LM_detail_red2" fill="#393939"></path> <circle id="LM_detail_red_hole4" data-name="LM detail red hole4" cx="59.9" cy="30.01" r="3.79" style="fill: #393939"/>
<path d="M8.68,15.62 L8.98,14.07 L9.55,12.55 C9.57831973,12.4327928 9.65249325,12.3318542 9.75588978,12.2698163 C9.85928631,12.2077784 9.98325491,12.1898316 10.1,12.22 L12.16,12.77 C12.4015851,12.8381001 12.5439801,13.0872913 12.48,13.33 L11.87,14.77 L11.65,16.4 C11.6216803,16.5172072 11.5475067,16.6181458 11.4441102,16.6801837 C11.3407137,16.7422216 11.2167451,16.7601684 11.1,16.73 L9.1,16.18 C8.85841494,16.1118999 8.71601994,15.8627087 8.78,15.62 L8.68,15.62 Z" id="LM_detail_red1" fill="#393939"></path> <circle id="LM_detail_red_hole3" data-name="LM detail red hole3" cx="51.75" cy="15.89" r="3.79" style="fill: #393939"/>
<circle id="LM_detail_red_hole2" data-name="LM detail red hole2" cx="65.87" cy="7.74" r="3.79" style="fill: #393939"/>
<circle id="LM_detail_red_hole1" data-name="LM detail red hole1" cx="74.02" cy="21.86" r="3.79" style="fill: #393939"/>
<path id="LM_detail_hole" data-name="LM detail hole" d="M64.2,16.41a.72.72,0,0,1-.55-.91c.21-.72.36-1.33.36-1.33s-.17-.35-1.27-.64-1.35-.06-1.35-.06L61,14.8s-.16.72-.81.54L59,15s-.4.13-.6,1.06a3.44,3.44,0,0,0-.06,1.43l1.25.33a.68.68,0,0,1,.46.81c-.16.61-.33,1.21-.33,1.21s.12.3,1.2.62,1.42.09,1.42.09l.32-1.22s.26-.76,1-.59q.6.17,1.2.39a2.92,2.92,0,0,0,.7-2.25C64.91,16.65,64.2,16.41,64.2,16.41Z" transform="translate(0.98 1.9)" style="fill: #1f1f1f"/>
<path id="LM_detail_red4" data-name="LM detail red4" d="M61.64,24.23,60.09,24l-1.53-.57a.46.46,0,0,1-.33-.56h0l.55-2.05a.46.46,0,0,1,.56-.32l1.45.6,1.63.22a.46.46,0,0,1,.33.56h0l-.55,2.05a.44.44,0,0,1-.55.32Z" transform="translate(0.98 1.9)" style="fill: #393939"/>
<path id="LM_detail_red3" data-name="LM detail red3" d="M69.15,17.3l-.26,1.55-.57,1.52a.45.45,0,0,1-.55.33h0l-2.06-.55a.46.46,0,0,1-.32-.56L66,18.15l.22-1.63a.45.45,0,0,1,.55-.33h0l2,.55a.46.46,0,0,1,.32.56Z" transform="translate(0.98 1.9)" style="fill: #393939"/>
<path id="LM_detail_red2" data-name="LM detail red2" d="M62.21,9.79l1.55.25,1.53.57a.46.46,0,0,1,.33.55h0l-.55,2.05a.46.46,0,0,1-.56.32l-1.45-.6-1.63-.22a.47.47,0,0,1-.33-.56h0l.55-2.05a.44.44,0,0,1,.55-.32Z" transform="translate(0.98 1.9)" style="fill: #393939"/>
<path id="LM_detail_red1" data-name="LM detail red1" d="M54.7,16.72,55,15.17l.57-1.52a.45.45,0,0,1,.55-.33h0l2.06.55a.46.46,0,0,1,.32.56l-.61,1.44-.22,1.63a.45.45,0,0,1-.55.33h0l-2-.55a.46.46,0,0,1-.32-.56Z" transform="translate(0.98 1.9)" style="fill: #393939"/>
</g>
</g>
</g> </g>
</g> </g>
</g> </g>

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,75 +1,90 @@
namespace pxsim { namespace pxsim {
export const LARGE_MOTOR_SVG = `<?xml version="1.0" encoding="UTF-8"?> export const LARGE_MOTOR_SVG = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 82 156">
<svg width="82px" height="156px" viewBox="0 0 82 156" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs>
<!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch --> <clipPath id="clip-path" transform="translate(0.98 1.9)">
<path d="M79,17.05A17.07,17.07,0,0,1,64.92,33.86l.36.39V70c0,.42-.14.4-.39.68L54,81.22v10l.75.78v.79h6.79a4,4,0,0,1,4,4v25.82a4,4,0,0,1-4,4H54.75v8.18A5.79,5.79,0,0,1,49,140.61h-6.5v7.57a4,4,0,0,1-2.9,3.84v1a.6.6,0,0,1-.6.6H12.69a.6.6,0,0,1-.6-.6h0v-1.29a4,4,0,0,1-2.17-3.55v-7.57H6.3a5.78,5.78,0,0,1-5.78-5.79h0V105.18C10.89,91.12,18.65,81.32,18.65,81.32h.59l13.68.1,0-11.8H26a4,4,0,0,1-4-4V39.79a4,4,0,0,1,4-4h6.78l0-11.77c0-.84.15-.84.46-1.14l10.41-10.1.22-.19a1.53,1.53,0,0,1,1.59.23A17.07,17.07,0,0,1,79,17.05Z" style="fill: none"/>
</clipPath>
<clipPath id="clip-path-2" transform="translate(0.98 1.9)">
<path d="M49,140.61H6.3a5.78,5.78,0,0,1-5.78-5.79h0V105.18C10.89,91.12,18.65,81.32,18.65,81.32h.59s19.46.14,23.87.14a2.27,2.27,0,0,1,2.37,1L54.75,92v42.79A5.79,5.79,0,0,1,49,140.61Z" style="fill: none"/>
</clipPath>
<clipPath id="clip-path-3" transform="translate(0.98 1.9)">
<path d="M43.18,135.24H12.09a5.78,5.78,0,0,1-5.79-5.78h0V107.21C15,95.94,21.86,86.8,21.86,86.8H43.18A5.78,5.78,0,0,1,49,92.58h0v36.88a5.78,5.78,0,0,1-5.78,5.78Z" style="fill: none"/>
</clipPath>
</defs>
<title>Large Motor</title> <title>Large Motor</title>
<desc>Created with Sketch.</desc> <g style="isolation: isolate">
<defs></defs> <g id="e13b39e7-895d-4931-9be9-7aecaf709784">
<g id="Artboard" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(-66.000000, -54.000000)"> <g style="clip-path: url(#clip-path)">
<g id="Large-Motor" transform="translate(66.000000, 54.000000)"> <g id="Large_Motor" data-name="Large Motor">
<path d="M39.98,155.52 L13.67,155.52 C13.3386292,155.52 13.07,155.251371 13.07,154.92 L13.07,149.62 C13.07,149.288629 13.3386292,149.02 13.67,149.02 L39.98,149.02 C40.3113708,149.02 40.58,149.288629 40.58,149.62 L40.58,154.9 C40.5854219,155.062566 40.5246096,155.220368 40.4114947,155.337253 C40.2983799,155.454138 40.1426565,155.52009 39.98,155.52 Z" id="LM_back2" fill="#A8AAA8" fill-rule="nonzero"></path> <path id="LM_back2" data-name="LM back2" d="M39,153.62H12.69a.6.6,0,0,1-.6-.6h0v-5.3a.6.6,0,0,1,.6-.6H39a.6.6,0,0,1,.6.6V153A.6.6,0,0,1,39,153.62Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
<g id="Group" transform="translate(9.000000, 136.000000)"> <g>
<image id="Bitmap" opacity="0.3" style="mix-blend-mode: multiply;" x="0" y="0" width="36" height="20" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAVCAYAAADB5CeuAAAAAXNSR0IArs4c6QAAAMRJREFUSA3tlrERwjAMRW2OEmYgPQMwFrMwAytBT1iB9OY/x05J1IAopLtv2Y5yevfPhXIpJWVF+oMQSwEDmJ00tKzkFpM6P8Q1bbUZpLN0lLwcw6G7dJFuQOEUQCfJE0rtK0sCigCmq144LIshG4fmqy0DatWiVhBOhVNWB6x18abCKasD1rr+puocY/3pS3ULA1DMMU/pJfHBQ/SGAZY6JYzKVw6Kw5x+vnYGcsptHN5rDxCzlUfg0CgWHJuhPCg+9XwDDy9ID0K8XgsAAAAASUVORK5CYII="></image> <image width="36" height="20" transform="translate(9 136)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAVCAYAAADB5CeuAAAACXBIWXMAAAsSAAALEgHS3X78AAAAp0lEQVRIS+3WsW3DMBBG4Y+GSmcGp/cAHsuzeIasFPdWVpD6c0FKcBWwOxV8wIEgSIAPvOL+EhFKKcUBiIiAgjO+25rJildErJMqdMdVlcwg8MQDv5P6Q1fc5ErRujW1TfmoLPa3T//dymJI9TKkehlSvQypXoZUL5vUNhAz2R1Oao75w9IOMmpRHVZqSpjxo3KRw+YwQ2lx+EsVykqfK+aIWGhSR+MNDy9ID5XUCOsAAAAASUVORK5CYII=" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path d="M33.84,18.07 L2.51,18.07 C2.17862915,18.07 1.91,17.8013708 1.91,17.47 L1.91,2.77 C1.91,2.43862915 2.17862915,2.17 2.51,2.17 L33.84,2.17 C34.1713708,2.17 34.44,2.43862915 34.44,2.77 L34.44,17.47 C34.44,17.8013708 34.1713708,18.07 33.84,18.07 Z" id="LM_back1-2" fill="#A8AAA8" fill-rule="nonzero"></path> <path id="LM_back1-2" data-name="LM back1-2" d="M41.86,152.17H10.53a.6.6,0,0,1-.6-.6v-14.7a.6.6,0,0,1,.6-.6H41.86a.6.6,0,0,1,.6.6h0v14.7A.6.6,0,0,1,41.86,152.17Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
</g> </g>
<g id="LM_rightside" transform="translate(22.000000, 37.000000)" fill-rule="nonzero"> <g id="LM_rightside" data-name="LM rightside">
<path d="M12.06,34.51 L6.45,34.51 C4.99937339,34.5153259 3.60647912,33.9421088 2.57978624,32.9172929 C1.55309337,31.892477 0.977328505,30.5006339 0.98,29.05 L0.98,6.15 C0.977339027,4.70110385 1.55173283,3.31078487 2.57625885,2.28625885 C3.60078487,1.26173283 4.99110385,0.687339027 6.44,0.69 L12.05,0.69 C15.0654747,0.69 17.51,3.13452527 17.51,6.15 L17.51,29.05 C17.5126553,30.4971617 16.939633,31.8859609 15.9172718,32.910198 C14.8949106,33.9344351 13.5071641,34.5100024 12.06,34.51 Z" id="LM_rightside5" fill="#A8AAA8"></path> <path id="LM_rightside5" data-name="LM rightside5" d="M33.08,69.61H27.47A5.45,5.45,0,0,1,22,64.15h0V41.25a5.45,5.45,0,0,1,5.46-5.46h5.61a5.46,5.46,0,0,1,5.46,5.46v22.9A5.45,5.45,0,0,1,33.08,69.61Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
<circle id="LM_rightside4" fill="#FFFFFF" cx="6.3" cy="29.21" r="3.79"></circle> <circle id="LM_rightside4" data-name="LM rightside4" cx="28.3" cy="66.21" r="3.79" style="fill: #fff"/>
<circle id="LM_rightside3" fill="#FFFFFF" cx="6.3" cy="6" r="3.79"></circle> <circle id="LM_rightside3" data-name="LM rightside3" cx="28.3" cy="43" r="3.79" style="fill: #fff"/>
<path d="M3.38,24.59 C4.07351535,24.1313154 4.88857129,23.8909784 5.72,23.9 C6.76862292,23.8298668 7.81405119,24.0772848 8.72,24.61 C9.97,25.54 9.95,24.51 9.95,24.51 L9.95,22.71 C9.95,22.26 9.39,21.86 8.72,22.25 L7.72,22.83 C7.72,22.83 7.36,23.02 7.36,22.5 L7.36,19.9 C7.36,19.9 7.36,19.11 8.09,19.13 C8.82,19.15 9.47,19.13 9.47,19.13 C9.47,19.13 9.76,18.88 9.76,17.74 C9.76,16.6 9.47,16.42 9.47,16.42 L8.08,16.42 C8.08,16.42 7.35,16.42 7.35,15.77 L7.35,14.47 C7.35,14.47 7.12,14.11 6.18,14.17 C5.6978322,14.1741563 5.22153417,14.2762201 4.78,14.47 L4.78,15.77 C4.77453579,16.1305967 4.48063814,16.4200414 4.12,16.42 C3.49,16.42 2.86,16.42 2.86,16.42 C2.86,16.42 2.61,16.61 2.57,17.74 C2.53,18.87 2.86,19.13 2.86,19.13 L4.12,19.13 C4.12,19.13 4.92,19.18 4.94,19.9 C4.96,20.62 4.94,22.52 4.94,22.52 C4.94,22.52 4.94,23.03 4.6,22.85 L3.39,22.27 C3.39,22.27 2.56,21.86 2.57,22.73 C2.58,23.6 2.57,24.53 2.57,24.53 C2.57,24.53 2.65,25.02 3.38,24.59 Z" id="LM_rightside2" fill="#FFFFFF"></path> <path id="LM_rightside2" data-name="LM rightside2" d="M24.4,59.69A4.16,4.16,0,0,1,26.74,59a5.23,5.23,0,0,1,3,.71c1.25.93,1.23-.1,1.23-.1v-1.8c0-.45-.56-.85-1.23-.46l-1,.58s-.36.19-.36-.33V55s0-.79.73-.77,1.38,0,1.38,0,.29-.25.29-1.39-.29-1.32-.29-1.32H29.1s-.73,0-.73-.65v-1.3s-.23-.36-1.17-.3a3.56,3.56,0,0,0-1.4.3v1.3a.66.66,0,0,1-.66.65c-.63,0-1.26,0-1.26,0s-.25.19-.29,1.32.29,1.39.29,1.39h1.26s.8.05.82.77,0,2.62,0,2.62,0,.51-.34.33l-1.21-.58s-.83-.41-.82.46,0,1.8,0,1.8S23.67,60.12,24.4,59.69Z" transform="translate(0.98 1.9)" style="fill: #fff"/>
<path d="M10.23,12.79 C10.1913976,13.0147775 10.0630557,13.2141964 9.87446015,13.3424414 C9.68586455,13.4706864 9.453229,13.5167322 9.23,13.47 C9.14591061,13.4523039 9.06499079,13.421959 8.99,13.38 C8.1099436,12.9124008 7.1357966,12.6492102 6.14,12.61 C5.162003,12.5962776 4.20061308,12.8635231 3.37,13.38 C2.54,13.78 2.3,12.79 2.3,12.79 L2.3,11.03 C2.33192589,10.6400455 2.66941985,10.3469587 3.06,10.37 C3.16998614,10.3773249 3.27646607,10.4116733 3.37,10.47 C4.20732336,10.980005 5.16044012,11.2690368 6.14,11.31 C7.13850164,11.2335413 8.10964397,10.9473099 8.99,10.47 C8.99,10.47 10.17,10.23 10.19,11.03 C10.21,11.83 10.23,12.79 10.23,12.79 Z" id="LM_rightside1" fill="#FFFFFF"></path> <path id="LM_rightside1" data-name="LM rightside1" d="M31.25,47.89a.84.84,0,0,1-1,.68.85.85,0,0,1-.24-.09,6.63,6.63,0,0,0-2.85-.77,5.11,5.11,0,0,0-2.77.77c-.83.4-1.07-.59-1.07-.59V46.13a.72.72,0,0,1,.76-.66.67.67,0,0,1,.31.1,5.79,5.79,0,0,0,2.77.84,7.12,7.12,0,0,0,2.85-.84s1.18-.24,1.2.56S31.25,47.89,31.25,47.89Z" transform="translate(0.98 1.9)" style="fill: #fff"/>
</g> </g>
<g id="Group" transform="translate(32.000000, 12.000000)"> <g>
<image id="Bitmap" opacity="0.3" style="mix-blend-mode: multiply;" x="0" y="0" width="36" height="76" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAABNCAYAAAAhOa00AAAAAXNSR0IArs4c6QAAAnlJREFUaAXtmsFRwzAQRROGI6EEwhmGEqABTtyhACqiAC4cOVBBaAEKCB0AuYf/hdbjBMcrbYTlw+7MZp3IWr98OZIn2ul6vZ7k2BTG89Evr2PGRaY5ucEzQ+55zL9EXP0HXDJUBLoCyG2EekZ8hy8B9h0/KxKSoFpA97jqJZxDSKUI9QhflAQ7RMJe2wKiUhxC2jn8BH7ENzivGFgvVA9Q4MDLMZygwUqB7YRSgISDkcoVBeuEygASuLJgnBLaHr/5NeIL/AvO+SjVP3HuE/wCHn5E7dypxwfo3JhBoaZvPKBiZ9F5bDOhR28msSrUVpLqUmXmmkn+nBiGjp1jEsuQtYHkeC8wsBQH2huMv745/A7Omdp+H6DzljGXaaogFGdkzswlgZAumAlM5qnwOCKZCsdsMIEqzPEnXRbYUFCkTAYbEioZbGioJLAaUCpYLahesJpQO8FqQwkYV5MVnM/9bxuPLjyjknG64KoSnvfHAkUtmlVlTFAEC+ZQooQWXSlNIWl3pUQJLbpSmkLS7kqJElp0pTSFpN2VEiW06EppCkm7KyVKaNGV0hSSdldKlNCiK6UpJO2ulCihRVdKU0jaXSlRQouulKaQtI9JKW7JBRsLFCtAPuD8M3YyBigCvcJZCcJ/h6tDEWgBf2DEPnOomampVCcQ4KoptROoFlQvUA0oFWhoqCSgIaGSgYaCygIaAiobiFCy3yelIPyM1uwo/b41vZqAeCVCcb1hwR+NMNxzY6lJ2HtDtBiBuHRszNSpiQTiFB0EgkA3cEarcQ0zVzWGajAUc7WHq4RSYetV1rLcb9ZZ57kFmZsznA8g3qcm64QyZSrY6Qey39wRVmjftAAAAABJRU5ErkJggg=="></image> <image width="36" height="76" transform="translate(32 12)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAABNCAYAAAAhOa00AAAACXBIWXMAAAsSAAALEgHS3X78AAACAElEQVRoQ+3avVHDMBiA4VdcypgREmo4RggLpKKHAZiIAWgoKZggrEAGCBsQpxeFpNgJ/vkkK5YLvXe6g2Cb53zE9oVPaa3xSSmlALTvjh4pn2MrpQpgab/dAYdL4MQoC3oAnuxLH8AW2Gmty9YdAxKhaqAXYAUozJnaAm/AJiZs1rfBGegBKOyP7oAFMLfbRYN1ojpAYM7WtX3dbR8F1orqAdVz27n9BsMaUR4gV1yY1vpkYX7BGvgE9oD2WL/AO3CPfROFrKs6MOAMnVcAt3b57lsV6QzV194eYw0UfWelacUGRYFdAjQYNsPcy54xV+rwv4P/Bb8jZ5gr8oK4IFcQzF2nVOdWw/KG9d77IuUFGwsFHrAxUSCEjY0CASwFCnpgqVDQAUuJghZYahQY2Ao4YJ77v08eXRJWUHvenwoKaneVKaGOZZS0jJKWUdIySlpGScsoaRklLaOkZZS0jJKWUdIySlpGScsoaRklLaOkTQml3RdTQZXAD+bD2EmgSuALMwmyg/SoEtgAr9RGU1KiGkGQDtUKgjSoThCMj+oFwbgoEQjGQ4lBMA7KCwSXR3mDoPonpBsFccWYUwgCgUEdMAN/YDBzzKjJvG0nQe7W4Q2CCnFDhVgCj1TznCHtGDDVqLTWxylXW4wzdWDA/GfjnOcZMijddGBhouHTsfsDst/cEY24RzwAAAAASUVORK5CYII=" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path d="M33.89,60.6 L20.48,73.53 L1.91,72.9 L1.74,13.9 C1.74,13.06 1.9,13.06 2.2,12.77 L12.62,2.67 L12.83,2.48 C13.42,2.08 14.83,2.59 14.83,3.43 L34.27,24.15 L34.27,59.9 C34.28,60.34 34.14,60.33 33.89,60.6 Z" id="LM_level4-2" fill="#A8AAA8" fill-rule="nonzero"></path> <path id="LM_level4-2" data-name="LM level4-2" d="M64.91,70.7,51.5,83.63,32.93,83,32.76,24c0-.84.16-.84.46-1.13l10.42-10.1.21-.19c.59-.4,2,.11,2,.95L65.29,34.25V70C65.3,70.44,65.16,70.43,64.91,70.7Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
</g> </g>
<g id="Group" transform="translate(32.000000, 69.000000)"> <g>
<image id="Bitmap" opacity="0.3" style="mix-blend-mode: multiply;" x="0" y="0" width="25" height="27" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAYAAAB/E6/TAAAAAXNSR0IArs4c6QAAAZhJREFUSA3tlj1SwzAQRnEmJanogYoChiOQC1BxAA7AcTgDDQfgBLlDekxNQ5LefE/WeizHGa9l07Ezny3L2n36W9lFVVVnXStk3Trvs+IdB5Rz0a0XY6X6K+ncG7zV7qByqZj7Vl0oJqAIWevNswRsrJVyeJM2XdjSIrUgL6p7kBjZWLuVQ5gJxUthcepYk3vpXfqRmOdc7eT7IT1KK+IjGxG9pzcoZyRyawx/ZiSsl0a2FahaxCnjBetyLWXvOPmaAbuUmg210AOLDgTY1NEoRGNJhwFBhT4npKFZARCW0Ouqea8GmjdqT7R/UM+k+KosYe0U8HhlbRxAZPA2EoaCkArkHfehtjFkfQP0Kb1KTRarfMqAPEl3EmV37i11DB04j+TkMdohQJwmfFJcsLBGHHpy8Ng+dupLjZlyzAWzzVC7OK6xUzsBN63mg7DRIAsuIKNzw7JBAMfAJoFOwPjcHO3gyaAeGJuEL3XyJzQLqAMrI+imDUt+t3CYatognBhM3YX0rXUMaTA7yDoKMKZCqPozkAHt/gsh4I9CsIZ80gAAAABJRU5ErkJggg=="></image> <image width="25" height="27" transform="translate(32 69)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAYAAAB/E6/TAAAACXBIWXMAAAsSAAALEgHS3X78AAABYUlEQVRIS+2WvVXDMBRG7/NxGVf0CRVFchghWSAVA2QAxmEGGgZgguzgHlPTELv/KCSD/BMs2wkV9xwf2/LPlZ70JJkk2piZdQojUd8PAWuXm1kGrIBF3wcDVEAhqWw/aIi8ZAcccLKxFMAzcGzL0voikDwCWyBjPGt8JMysKfMtMuAeeAE+Ac04TsArsAcySUj6blGGq82aaS0JyXARqYDCzHJJSnzItrh+ucW1bi4ZsCQYUAmu0w9M75dzNCqc4KxLLivpkPjzJcL1Kwl/xL9oMnXC1lkdw6SBk+IyOPf3Qz9Z8DOzD73bIAXegCfiloUV8ABs/HV07qWSKjPLiSP3xwY3m+yIlKVwflXsofSVeseFHCJlKSPxlTqZ2TEoHpSNFtVIKsfIJotgnGyWCHplW3pG8GwRdGQVbqXu35zMJZAVONEdgayzr5uL33wugBvgQ1IFVxDVmJmF+Xk1UZsvIeCPQjWq5BoAAAAASUVORK5CYII=" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path d="M22.9800421,24.9 L22.98,7.6 C22.9824406,7.20649401 22.8788083,6.81960003 22.68,6.48 C22.4,6.21 19.16,2.86 19.16,2.86 C18.8448174,2.57277854 18.4252272,2.42809227 18,2.46 C17.25,2.46 6.38,2.46 6.38,2.46 L1.98,7.16 L1.98,15.16 L12.64,15.73 L22.9800421,24.9 Z" id="LM_level3-2" fill="#A8AAA8" fill-rule="nonzero"></path> <path id="LM_level3-2" data-name="LM level3-2" d="M54,92V74.7a2.19,2.19,0,0,0-.3-1.12c-.28-.27-3.52-3.62-3.52-3.62a1.55,1.55,0,0,0-1.16-.4c-.75,0-11.62,0-11.62,0L33,74.26v8l10.66.57Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
</g> </g>
<g id="LM_leftside" transform="translate(49.000000, 94.000000)" fill-rule="nonzero"> <g id="LM_leftside" data-name="LM leftside">
<path d="M12.06,34.54 L6.45,34.54 C4.99937339,34.5453259 3.60647912,33.9721088 2.57978624,32.9472929 C1.55309337,31.922477 0.977328505,30.5306339 0.98,29.08 L0.98,6.18 C0.98,3.16452527 3.42452527,0.72 6.44,0.72 L12.05,0.72 C15.0631921,0.725503561 17.5044964,3.16680786 17.51,6.18 L17.51,29.08 C17.5126553,30.5271617 16.939633,31.9159609 15.9172718,32.940198 C14.8949106,33.9644351 13.5071641,34.5400024 12.06,34.54 Z" id="LM_leftside5" fill="#A8AAA8"></path> <path id="LM_leftside5" data-name="LM leftside5" d="M60.08,126.64H54.47A5.45,5.45,0,0,1,49,121.18h0V98.28a5.46,5.46,0,0,1,5.46-5.46h5.61a5.47,5.47,0,0,1,5.46,5.46v22.9A5.45,5.45,0,0,1,60.08,126.64Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
<circle id="LM_leftside4" fill="#FFFFFF" cx="12.67" cy="29.24" r="3.79"></circle> <circle id="LM_leftside4" data-name="LM leftside4" cx="61.67" cy="123.24" r="3.79" style="fill: #fff"/>
<circle id="LM_leftside3" fill="#FFFFFF" cx="12.67" cy="6.03" r="3.79"></circle> <circle id="LM_leftside3" data-name="LM leftside3" cx="61.67" cy="100.03" r="3.79" style="fill: #fff"/>
<path d="M9.75,24.62 C10.4421225,24.1572205 11.2574415,23.9133217 12.09,23.92 C13.1380484,23.8411302 14.1850856,24.0854388 15.09,24.62 C16.34,25.55 16.32,24.52 16.32,24.52 L16.32,22.72 C16.32,22.27 15.76,21.88 15.09,22.26 L14.09,22.84 C14.09,22.84 13.73,23.03 13.73,22.51 L13.73,19.9 C13.73,19.9 13.73,19.11 14.46,19.13 C15.19,19.15 15.84,19.13 15.84,19.13 C15.84,19.13 16.13,18.88 16.13,17.75 C16.13,16.62 15.84,16.42 15.84,16.42 L14.45,16.42 C14.45,16.42 13.72,16.42 13.72,15.78 L13.72,14.48 C13.72,14.48 13.49,14.12 12.55,14.17 C12.0671703,14.1775857 11.5908982,14.283046 11.15,14.48 L11.15,15.78 C11.1391868,16.1366743 10.8468382,16.4201639 10.49,16.42 L9.23,16.42 C9.23,16.42 8.98,16.62 8.94,17.75 C8.9,18.88 9.23,19.13 9.23,19.13 L10.49,19.13 C10.49,19.13 11.29,19.13 11.31,19.9 C11.33,20.67 11.31,22.52 11.31,22.52 C11.31,22.52 11.31,23.03 10.97,22.85 L9.76,22.27 C9.76,22.27 8.93,21.87 8.94,22.73 C8.95,23.59 8.94,24.53 8.94,24.53 C8.94,24.53 8.98,25.06 9.75,24.62 Z" id="LM_leftside2" fill="#FFFFFF"></path> <path id="LM_leftside2" data-name="LM leftside2" d="M57.77,116.72a4.15,4.15,0,0,1,2.34-.7,5.14,5.14,0,0,1,3,.7c1.25.93,1.23-.1,1.23-.1v-1.8c0-.45-.56-.84-1.23-.46l-1,.58s-.36.19-.36-.33V112s0-.79.73-.77,1.38,0,1.38,0,.29-.25.29-1.38-.29-1.33-.29-1.33H62.47s-.73,0-.73-.64v-1.3s-.23-.36-1.17-.31a3.57,3.57,0,0,0-1.4.31v1.3a.66.66,0,0,1-.66.64H57.25s-.25.2-.29,1.33.29,1.38.29,1.38h1.26s.8,0,.82.77,0,2.62,0,2.62,0,.51-.34.33l-1.21-.58s-.83-.4-.82.46,0,1.8,0,1.8S57,117.16,57.77,116.72Z" transform="translate(0.98 1.9)" style="fill: #fff"/>
<path d="M16.6,12.82 C16.5640845,13.0461448 16.4363396,13.2474057 16.2469908,13.3761629 C16.057642,13.5049201 15.8235128,13.5497335 15.6,13.5 C15.5157002,13.4885804 15.4342916,13.4614442 15.36,13.42 C14.4821686,12.9467916 13.506699,12.6832437 12.51,12.65 C11.5311949,12.6299456 10.5680375,12.8976825 9.74,13.42 C8.91,13.82 8.67,12.82 8.67,12.82 L8.67,11.06 C8.70188656,10.6714097 9.04116607,10.3812364 9.43,10.41 C9.53837526,10.4186243 9.6438555,10.4492476 9.74,10.5 C10.5773234,11.010005 11.5304401,11.2990368 12.51,11.34 C13.5091637,11.2671668 14.4810541,10.9807149 15.36,10.5 C15.36,10.5 16.54,10.26 16.56,11.06 C16.58,11.86 16.6,12.82 16.6,12.82 Z" id="LM_leftside1" fill="#FFFFFF"></path> <path id="LM_leftside1" data-name="LM leftside1" d="M64.62,104.92a.83.83,0,0,1-1,.68.68.68,0,0,1-.24-.08,6.46,6.46,0,0,0-2.85-.77,5,5,0,0,0-2.77.77c-.83.4-1.07-.6-1.07-.6v-1.76a.71.71,0,0,1,.76-.65.8.8,0,0,1,.31.09,5.79,5.79,0,0,0,2.77.84,7,7,0,0,0,2.85-.84s1.18-.24,1.2.56S64.62,104.92,64.62,104.92Z" transform="translate(0.98 1.9)" style="fill: #fff"/>
</g> </g>
<g id="Group" transform="translate(0.000000, 81.000000)"> <g>
<image id="Bitmap" opacity="0.3" style="mix-blend-mode: multiply;" x="0" y="0" width="58" height="64" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADsAAABBCAYAAABvnNwUAAAAAXNSR0IArs4c6QAAAqRJREFUaAXtm01OwzAQhSlUYgNbJDalaxBHgAtwBg7AiVixYsOODScoN0DqAcoNoJUQq/CecaK64zhOm7T1yCNNf+zUns/P4xjkDIqiOOjKBrCu2mpqB3G3Dnywxm+8cYDzFBUX8BPvBd0WLtDcDL5oA90JrAW9Ref3cAL3bQR9hU/hMwDPYzrcGHYJ9AEd3sCpcN9WKkvYZ/gkBni4SVQroFR2G6AMmf1cwUdwkzaIpRmYObuO2w7v8P4G/4ZzwdiFf6HfF/g13MzUOp5DXNDaMIpcdcdw5ui2pi668hpVvrQenFlrwaLh6A684XVb6Ay8TS1vD61z1jZGNanqGM7Odm0cfK4ZxhCjN39bwVpQNsqVd5sL0j9F+LUROBoWoM50Qb/B/AjH1VttEDga1sJFLQS9ocQ1XAscBWun777laQidwIzXbD4Q/xS3o6JxNbag+5qnTcAjXFDt1YOwAE0hT0PAzp0iCItWOB1SyNMQcFVXC2unb0p5WkHVffDCJpyndZymXMAqyNNaYAGLK1Xl6TK5A6sxT72wWvNUwGrOUwGLArV56sBqz1MHFl/4r0/+Ic4NBBVWa1yNuVHmhlk1KBUsbz3OhpkVGq2E1cgmmDKsGBIlBVlZJUIKjKysGBIlBVlZJUIKjKysGBIlBVlZJUIKjKysGBIlBVlZJUIKjKysGBIlBVlZJUIKjKysGBIlBVlZJUIKjKysGBIlBVlZJUIKjFJZnu3XaA4XYXly8xMe9WxMQiNCHnKRz9gRXn/gfILiDH4OP4anbgR9hz/BP3D69pdAQ3yY41zFhF+spX7coAR9BI/zrIA5XL0CTNl5ziJVmyFw71NczuNp9uQMQasDyQkSm9PjFHA1dgeWlfYA2Op1SX0HqLMKl8EL2LJC4/sftL72OnfR538AAAAASUVORK5CYII="></image> <image width="58" height="64" transform="translate(0 81)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADsAAABBCAYAAABvnNwUAAAACXBIWXMAAAsSAAALEgHS3X78AAACFElEQVRoQ+2bQY7TMBSGvxcqsaFbJDbDrEEcYeYCcwYOwIlYsWLDjg0nGG6A1ANkbgCNhGb1WNgBpxPbaUjT+smf5E3lxPlq/25S5YmqshQiIrk+S6EzLlxmHDOKiGyB18CLXN8F6IAW6I6RXkTWi94C73HCp6YFvgI7oFXVfaY/sIBsIPoBuAG26SMWoZ/ZHfAZuJ8ivMl1SHEgess6ouDGeQtc4WMjInlhVZ3VcAPeAd+AX4Ceqf0EvgDv8Cs11hpm4Hfda1xG11q6MbbAG9+S1zFLliMGWIHBF++jNcrRmfUnu8Gd/Bo32Lnp9w4gnt+jZM+4IU0hKzxZ9sJyGiMpPFmWy8ppiqjwJNkLzWmK/no7oBWRnapqdje+8Jym2BLcdEDmp6eQnKYYrMDczJaS00lEZQvMaZZR2YJzmuSJrIGcRhmbWVM5DRnIWsxpyF9ZqzkNacB2TkP6mTWb05DGek5DGtxfn6aXb0+Du1G+wrgo/Mus2aUbknsQMEWVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUqVtUovq8le5TLwanBvbj4A2VKRwtjjvLr+g2fAb1wFxUvgFfB89NCy2APfgU/AD1V9BNio6l5E7oOOpb9u0It+5KC4aQNwINyxTonZqWiJVHENytNk3eLBU9ERqc97UovnXwArGj2U8vx34WFJ/AG0vvY6LSeZMAAAAABJRU5ErkJggg==" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path d="M49.98,61.51 L7.29,61.51 C4.09779415,61.51 1.51,58.9222059 1.51,55.73 L1.51,26.09 C11.87,12.03 19.63,2.22 19.63,2.22 L20.23,2.22 C20.23,2.22 39.69,2.37 44.09,2.37 C45.013529,2.18179526 45.9580478,2.5786519 46.47,3.37 L55.73,12.9 L55.73,55.7 C55.7379772,57.2329575 55.1366519,58.7062958 54.0583133,59.7958867 C52.9799747,60.8854775 51.5129577,61.5020641 49.98,61.51 Z" id="LM_level2_grey-2" fill="#A8AAA8" fill-rule="nonzero"></path> <path id="LM_level2_grey-2" data-name="LM level2 grey-2" d="M49,140.61H6.31a5.78,5.78,0,0,1-5.78-5.78h0V105.19C10.89,91.13,18.65,81.32,18.65,81.32h.6s19.46.15,23.86.15a2.29,2.29,0,0,1,2.38,1L54.75,92v42.8A5.78,5.78,0,0,1,49,140.61Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
</g> </g>
<g id="LM_total"> <g id="LM_total" data-name="LM total">
<g id="LM_whitepart" transform="translate(0.000000, 89.000000)" fill="#F1F1F1" fill-rule="nonzero"> <g id="LM_whitepart" data-name="LM whitepart">
<g id="LM_whitepart_combined"> <g style="clip-path: url(#clip-path-2)">
<polygon id="LM_whitepart_top" points="44.46 53.9 37.31 46.53 13.52 15.46 13.52 0.6 0.46 16.74 0.46 47.96 1.46 55.65"></polygon> <g id="LM_whitepart_combined" data-name="LM whitepart combined">
<path id="LM_whitepart_top" data-name="LM whitepart top" d="M43.48,141l-7.15-7.37L12.54,102.56V87.7L-.52,103.84v31.22l1,7.69Z" transform="translate(0.98 1.9)" style="fill: #f1f1f1"/>
</g> </g>
</g> </g>
<g id="Group" transform="translate(5.000000, 87.000000)">
<image id="Bitmap" opacity="0.3" style="mix-blend-mode: multiply;" x="0" y="0" width="47" height="52" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAA1CAYAAAAHz2g0AAAAAXNSR0IArs4c6QAAAhhJREFUaAXtWttRwzAQxAyfpAWSb4YWoAFqoIBURAH8UAAVhEpMBxD+za6xFMmyQcqNLWnmbmbHj1in3btTYjvXdF13IbUGJvURMx5cA7LNxLkYX/YacN/gYAtc25PL7HzDbQu+R9e9SMBA/gEOnwCKWNJaOH8BDq6Iq3NndMjv4eMeYCaWtFs477OMuU8iWEKpgCOSfQTegC+AtbkGPjHPK3AH9NVziZ0kg3ou2B3Aslkj8pjGGgN3A9j1liwAg+mE6SSWLhtMEZj3jZckYKh7Rp3R3wGeMxyvbtECBvL8xuGi5TZH9IMARQnIXPcBafdElIAh2jnr3uXs7f8roMS6dxX8KaDUuo8SUAN5CpnMQMmL1o3+rAB8kPvHasxz9jjIQOmLdqzEE1BL3bsirICa6n5SAE5WU/eBgNrq3hMwlA4fB3Pc37tczto3a4APCHxQKOIOM0WJEcAx2e/tU4iba10B5lxVWxWQO12aAc2AMAJaQsIAiodrBsQhFDrQDAgDKB6uGRCHUOhAMyAMoHi4ZkAcQqEDzYAwgOLhmgFxCIUO3Azwn/YazONpBLAT5APwOkEKVEN+5Em+v8Y+CRjfyOXofeDksWBPBnszyHNj+jv6bhUcHPGO9IAPjK3dA2Hmndsy8u/AM3DqVMGBbbcZiWCKtkAp1oJI0CtEckHD0/CqneRtRwgvzGwMaNCtRU6BgMxEk6f/AY1G0nHf2MzkAAAAAElFTkSuQmCC"></image>
<path d="M39.16,50.44 L8.07,50.44 C6.5353168,50.4426552 5.06258085,49.834865 3.97645681,48.7506168 C2.89033276,47.6663686 2.2799977,46.1946855 2.28,44.66 L2.28,22.41 C10.98,11.14 17.84,2 17.84,2 L39.16,2 C40.6998701,1.9893432 42.1803327,2.59359794 43.2729596,3.67871541 C44.3655865,4.76383288 44.9800369,6.24009301 44.98,7.78 L44.98,44.66 C44.98,46.1929513 44.3710375,47.6631169 43.2870772,48.7470772 C42.2031169,49.8310375 40.7329513,50.44 39.2,50.44 L39.16,50.44 Z" id="LM_top_grey-2" fill="#A8AAA8" fill-rule="nonzero"></path>
</g> </g>
<g id="LM_top" transform="translate(17.000000, 112.000000)" fill="#6A6A6A" fill-rule="nonzero"> <g>
<g id="LM_top_total"> <image width="47" height="52" transform="translate(5 87)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAA1CAYAAAAHz2g0AAAACXBIWXMAAAsSAAALEgHS3X78AAABnElEQVRoQ+2azXHCMBBG3zIccQuBM5MWoIHUkAJSUQrIJQWkAlIJ6SDYd+UgGWTjHxQHr5TRm9HFIzz75G8Z8KwYY5iKiMjYnr/AdBQrUwVEpADWwGps70Qq4GiMKf2LkwRc8XvgGStxT47AG3DwJZb9+4fxin8BdkAx/InJbHFPWUQuEsaY4IUt9gn4AE6AmWl9A+/AIy49CwJxDbvBxmaOk/cpgAe8fgsWwN5k69acxdc0vvGCBFzud9jT39C6mQY3C7Sado/O6V9xk4By7ge5SQD93PcyKhBj7n0GBWLNvU+vQArFQ49AzE3bpu8JRNu0ba4EYm/aNg2BVHLvcxZIKfc+/hNIJvc+C0gv9z4LF501iUWnpo7QCvtHIaniodkDycTGZ/THXOxkAW2ygDZZQJssoE0W0CYLaJMFtMkC2mQBbbKANv9K4PdDE/PSqLMWqIAvoDEJEiElts7qfEV59iFknbD1PQFFPbexBDDGlCJy4EJs70hL4BN4pW/cpiVRcf/5nxA6Z4WgY+BpxgmsEDqntWDixFYM/ACNRtJx4q2GRAAAAABJRU5ErkJggg==" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path d="M2.58,1.95 L2.58,29.42 C2.53732346,30.0007732 2.04187943,30.443134 1.46,30.42 C0.901094365,30.4156223 0.441619994,29.9780276 0.41,29.42 L0.41,1.95 C0.449349984,1.38861093 0.909606462,0.949468178 1.47222361,0.93650465 C2.03484076,0.923541121 2.51483504,1.34101911 2.58,1.9 L2.58,1.95 Z M6.19,1.95 L6.19,29.42 C6.2296472,29.8325035 6.03195189,30.231808 5.67986701,30.4503653 C5.32778212,30.6689226 4.88221788,30.6689226 4.53013299,30.4503653 C4.17804811,30.231808 3.9803528,29.8325035 4.02,29.42 L4.02,1.95 C3.9803528,1.53749648 4.17804811,1.138192 4.53013299,0.919634704 C4.88221788,0.701077408 5.32778212,0.701077408 5.67986701,0.919634704 C6.03195189,1.138192 6.2296472,1.53749648 6.19,1.95 Z M9.81,1.95 L9.81,29.42 C9.8496472,29.8325035 9.65195189,30.231808 9.29986701,30.4503653 C8.94778212,30.6689226 8.50221788,30.6689226 8.15013299,30.4503653 C7.79804811,30.231808 7.6003528,29.8325035 7.64,29.42 L7.64,1.95 C7.6003528,1.53749648 7.79804811,1.138192 8.15013299,0.919634704 C8.50221788,0.701077408 8.94778212,0.701077408 9.29986701,0.919634704 C9.65195189,1.138192 9.8496472,1.53749648 9.81,1.95 Z M13.42,1.95 L13.42,29.42 C13.3873113,29.9829764 12.9306072,30.4280683 12.3669758,30.44625 C11.8033444,30.4644316 11.318904,30.0496992 11.25,29.49 L11.25,1.95 C11.2826887,1.38702361 11.7393928,0.941931677 12.3030242,0.923750018 C12.8666556,0.905568359 13.351096,1.3203008 13.42,1.88 L13.42,1.95 Z M17.04,1.95 L17.04,29.42 C17.0513034,30.0199642 16.5796777,30.5182857 15.98,30.54 C15.401933,30.5576338 14.9125708,30.1167669 14.87,29.54 L14.87,1.95 C14.9026887,1.38702361 15.3593928,0.941931677 15.9230242,0.923750018 C16.4866556,0.905568359 16.971096,1.3203008 17.04,1.88 L17.04,1.95 Z" id="LM_top_lines"></path> <path id="LM_top_grey-2" data-name="LM top grey-2" d="M43.18,135.54H12.09a5.78,5.78,0,0,1-5.79-5.78h0V107.51C15,96.24,21.86,87.1,21.86,87.1H43.18A5.78,5.78,0,0,1,49,92.88h0v36.88a5.78,5.78,0,0,1-5.78,5.78Z" transform="translate(0.98 1.9)" style="fill: #a8aaa8"/>
</g>
<g id="LM_top" data-name="LM top">
<g style="clip-path: url(#clip-path-3)">
<g id="LM_top_total" data-name="LM top total">
<path id="LM_top_lines" data-name="LM top lines" d="M18.6,112.05v27.47a1.08,1.08,0,0,1-1.12,1,1.06,1.06,0,0,1-1.05-1V112.05A1.09,1.09,0,0,1,18.6,112Zm3.61,0v27.47a1.09,1.09,0,1,1-2.17,0V112.05a1.09,1.09,0,1,1,2.17,0Zm3.62,0v27.47a1.09,1.09,0,1,1-2.17,0V112.05a1.09,1.09,0,1,1,2.17,0Zm3.61,0v27.47a1.09,1.09,0,0,1-2.17.07V112.05a1.09,1.09,0,0,1,2.17-.07Zm3.62,0v27.47A1.1,1.1,0,0,1,32,140.64a1.08,1.08,0,0,1-1.11-1V112.05a1.09,1.09,0,0,1,2.17-.07Z" transform="translate(0.98 1.9)" style="fill: #6a6a6a"/>
</g> </g>
</g> </g>
<circle id="LM_detail_2" fill="#9A9A9A" fill-rule="nonzero" cx="50.32" cy="137.11" r="2.24"></circle>
<image id="Bitmap" opacity="0.3" style="mix-blend-mode: multiply;" x="44" y="0" width="38" height="38" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACcAAAAnCAYAAACMo1E1AAAAAXNSR0IArs4c6QAAAu1JREFUWAnNmD1y1EAQhb1bhJgjsMT8HAEuQGJHRJyOhAwCTmAyQqpMvOsbYDtGvE/Mm+oZaWUtaHfoqt75n/70WquSZtV13dkhtpKF+Y9V38gpbfeq7OSU2RTnsEBauZq7JkHVMIBdyiltgH2SU9oy8CGQs+AEdq4oALyQR5gaFpgMQiOZga/V3gnwzgNT5SRcUguw1/L3cuCAjGlcqV1bV3UYGLgP8q/yu4dUfFRtkpuVWoABCOgYTF6XKvUc1nFhT+VcGH6tGJMqjiqXwN5og6gWAZYwUkqareLV3jRr4Cy6FgHxVv5F/lP+S06alnT2ZG9iEOs8Mrheg5GOV/KPchYvCTS2FzGIRcw+iwajXKszGqo9T0792DYdz6SiYKLTeav62JUeo49Yo+nt06rBU6ezvkin9yUsFsxp5a99ynQqXGFkbSOHI9s6PWgZuJQ/k6NiCwOsAIzK+QHZAgxBLNAmCVb8W1spZjFQrhDIyrUGMyAcmQW4AbFnNigLFuByrlXP1A3AiB1Z+nuuoG0AFUMWLL7n4oSWdd77buSUvXJFB52NrFPcnTy/4qNc7GBCSyuEAq7oaEmWYmeBfM/ljsZwBYfhYCoGGkAOMmi4wcCJ4RAm3/t6ZeqFWqeKB7aa1EpBBIKDsreo3A/14LM+eP8sX+zXX2QZrN/Zb51q/J+v6QHwiSDfyb/Lj/FJyC0Tfe/3A0xOq9b0hrynSi8Xv5X3xxOCGdxOBZwmcFV5ger+ClN1UQOEL/5vqRyAEW1wVsIV6DX5ikEZNyhnHBs59+S/GhcPCAc5KAbgNomiammjZyVMSeclQAEXD3L6YX4OMKD8qPAZyYMnTQPlHDApyEY3aWM2B5Z3LpeqZlulGiDRIhRvHOy5Y/84aay+V7k4OahoMD4jAbS5n3bxIE3tDKX2/b40sjjaLDgW+HNNVYNQ2gC9SI3PKgG0WbnZUF44G84LKAOouw1Mu1aOI4861V43Wf4V3OSOCw7+BmjmA7QisxQnAAAAAElFTkSuQmCC"></image>
<circle id="LM_detail_1" fill="#9A9A9A" fill-rule="nonzero" cx="21.66" cy="86.59" r="2.24"></circle>
<g id="hole" transform="translate(45.000000, 1.000000)" fill-rule="nonzero">
<g id="Group" fill="#D42715">
<circle id="LM_red-2" cx="17.96" cy="17.95" r="17.06"></circle>
</g> </g>
<g id="LM_details_in_red" transform="translate(2.000000, 2.000000)"> <circle id="LM_detail_2" data-name="LM detail 2" cx="50.32" cy="137.11" r="2.24" style="fill: #9a9a9a"/>
<circle id="LM_detail_red_hole4" fill="#393939" cx="12.9" cy="27.01" r="3.79"></circle> <circle id="LM_detail_1" data-name="LM detail 1" cx="21.66" cy="86.59" r="2.24" style="fill: #9a9a9a"/>
<circle id="LM_detail_red_hole3" fill="#393939" cx="4.75" cy="12.89" r="3.79"></circle> <g id="hole">
<circle id="LM_detail_red_hole2" fill="#393939" cx="18.87" cy="4.74" r="3.79"></circle> <g>
<circle id="LM_detail_red_hole1" fill="#393939" cx="27.02" cy="18.86" r="3.79"></circle> <image width="38" height="38" transform="translate(44)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACcAAAAnCAYAAACMo1E1AAAACXBIWXMAAAsSAAALEgHS3X78AAACRklEQVRYR9WYPXLbMBBGHzgpxRwhTJ3ER0gukMauUvl0btIlhU9gdSkzQ9dWbmBTtTYFdiUA/BGh0ILyzWBAUiTx+C0JYdeJCDlyzrlgdwU02pu2wEb7vSR3IMDNvUahUpgGuNHetAF+aG/aA+dAzoJzztV4gI/EMHOdM+AW2IhIxwxNwqlbNfAZuMXDpTBhmE3pTQ24Be6ANdAdc/HN2A+JW7d4wJphmFTpOTX+Pu/wD7YCWufcpIuDzinYF2K36t6Jp6kjdvFhFFBEooaH+ArcA8/ADh+mJdtO732vY9Uph4iQgjngCviuFx8b5F/bs451hUYxbBWxauCDtqXCOKXp8UbC+cLxp16qvTAS3lLhTJuF9xNBeC2sK84bzlQ2bYXzJ5VOtA1+5n/PvHnsNdT7twmdswmyhEKDGltchF9rKcdMPYMMrjSYyRGwVJQPaaiIpSJek5V0MHrv4D9w7pK0Bf5oT5UeKCghWeJXyQEZvfQ8uljnTHuD7J0r7Zgp4gg/iNKAvQgaXOnQRh+DZWWVbtgPT5RzsJfvhs49apuV8C4sy8jiyF38Mj0AfAt8A37zOinhbLCh7KvjfOHd4d/xO2AtA4l1BKcfx/4CDuFdWh0+4/+l/aARvVqJiHTOuQfd3bJsOULwIGu8AS3wZFNHqtEq00QhB/LXfcIJlabRKpM62HKYnLccsiPrQxlwOlgIlVWjyy0eGlhazbTjcKRwSEZ1cxYcRLXgIeca4Fq3f7JAyRUy4EIlRWuYdo5cKNNJcOfSX2jmA7RYwAeRAAAAAElFTkSuQmCC" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path d="M18.18,15.31 C17.9816076,15.2705154 17.8089761,15.149396 17.7043432,14.9762761 C17.5997103,14.8031562 17.5727287,14.5940066 17.63,14.4 C17.84,13.68 17.99,13.07 17.99,13.07 C17.99,13.07 17.82,12.72 16.72,12.43 C15.62,12.14 15.37,12.37 15.37,12.37 L14.98,13.7 C14.98,13.7 14.82,14.42 14.17,14.24 L12.98,13.9 C12.98,13.9 12.58,14.03 12.38,14.96 C12.2599627,15.4271881 12.2395203,15.9143986 12.32,16.39 L13.57,16.72 C13.9132251,16.8260991 14.1147049,17.1808788 14.03,17.53 C13.87,18.14 13.7,18.74 13.7,18.74 C13.7,18.74 13.82,19.04 14.9,19.36 C15.98,19.68 16.32,19.45 16.32,19.45 L16.64,18.23 C16.64,18.23 16.9,17.47 17.64,17.64 C18.04,17.7533333 18.44,17.8833333 18.84,18.03 C19.3790257,17.4116231 19.6330766,16.5950309 19.54,15.78 C18.89,15.55 18.18,15.31 18.18,15.31 Z" id="LM_detail_hole" fill="#1F1F1F"></path> <circle id="LM_red-2" data-name="LM red-2" cx="62.96" cy="18.95" r="17.06" style="fill: #d42715"/>
<path d="M15.62,23.13 L14.07,22.9 L12.54,22.33 C12.29437,22.2663058 12.1467122,22.015735 12.21,21.77 L12.76,19.72 C12.8281001,19.4784149 13.0772913,19.3360199 13.32,19.4 L14.77,20 L16.4,20.22 C16.64563,20.2836942 16.7932878,20.534265 16.73,20.78 L16.18,22.83 C16.1519467,22.9468655 16.0773095,23.0471692 15.9734274,23.1076097 C15.8695454,23.1680501 15.7454609,23.1833663 15.63,23.15 L15.62,23.13 Z" id="LM_detail_red4" fill="#393939"></path> </g>
<path d="M23.13,16.2 L22.87,17.75 L22.3,19.27 C22.2716803,19.3872072 22.1975067,19.4881458 22.0941102,19.5501837 C21.9907137,19.6122216 21.8667451,19.6301684 21.75,19.6 L19.69,19.05 C19.4484149,18.9818999 19.3060199,18.7327087 19.37,18.49 L19.98,17.05 L20.2,15.42 C20.2283197,15.3027928 20.3024933,15.2018542 20.4058898,15.1398163 C20.5092863,15.0777784 20.6332549,15.0598316 20.75,15.09 L22.75,15.64 C22.9915851,15.7081001 23.1339801,15.9572913 23.07,16.2 L23.13,16.2 Z" id="LM_detail_red3" fill="#393939"></path> <g id="LM_details_in_red" data-name="LM details in red">
<path d="M16.19,8.69 L17.74,8.94 L19.27,9.51 C19.5107539,9.57376787 19.6570302,9.81756168 19.6,10.06 L19.05,12.11 C18.9818999,12.3515851 18.7327087,12.4939801 18.49,12.43 L17.04,11.83 L15.41,11.61 C15.167847,11.5417439 15.0223875,11.2949036 15.08,11.05 L15.63,9 C15.6580533,8.88313454 15.7326905,8.78283079 15.8365726,8.72239033 C15.9404546,8.66194987 16.0645391,8.64663373 16.18,8.68 L16.19,8.69 Z" id="LM_detail_red2" fill="#393939"></path> <circle id="LM_detail_red_hole4" data-name="LM detail red hole4" cx="59.9" cy="30.01" r="3.79" style="fill: #393939"/>
<path d="M8.68,15.62 L8.98,14.07 L9.55,12.55 C9.57831973,12.4327928 9.65249325,12.3318542 9.75588978,12.2698163 C9.85928631,12.2077784 9.98325491,12.1898316 10.1,12.22 L12.16,12.77 C12.4015851,12.8381001 12.5439801,13.0872913 12.48,13.33 L11.87,14.77 L11.65,16.4 C11.6216803,16.5172072 11.5475067,16.6181458 11.4441102,16.6801837 C11.3407137,16.7422216 11.2167451,16.7601684 11.1,16.73 L9.1,16.18 C8.85841494,16.1118999 8.71601994,15.8627087 8.78,15.62 L8.68,15.62 Z" id="LM_detail_red1" fill="#393939"></path> <circle id="LM_detail_red_hole3" data-name="LM detail red hole3" cx="51.75" cy="15.89" r="3.79" style="fill: #393939"/>
<circle id="LM_detail_red_hole2" data-name="LM detail red hole2" cx="65.87" cy="7.74" r="3.79" style="fill: #393939"/>
<circle id="LM_detail_red_hole1" data-name="LM detail red hole1" cx="74.02" cy="21.86" r="3.79" style="fill: #393939"/>
<path id="LM_detail_hole" data-name="LM detail hole" d="M64.2,16.41a.72.72,0,0,1-.55-.91c.21-.72.36-1.33.36-1.33s-.17-.35-1.27-.64-1.35-.06-1.35-.06L61,14.8s-.16.72-.81.54L59,15s-.4.13-.6,1.06a3.44,3.44,0,0,0-.06,1.43l1.25.33a.68.68,0,0,1,.46.81c-.16.61-.33,1.21-.33,1.21s.12.3,1.2.62,1.42.09,1.42.09l.32-1.22s.26-.76,1-.59q.6.17,1.2.39a2.92,2.92,0,0,0,.7-2.25C64.91,16.65,64.2,16.41,64.2,16.41Z" transform="translate(0.98 1.9)" style="fill: #1f1f1f"/>
<path id="LM_detail_red4" data-name="LM detail red4" d="M61.64,24.23,60.09,24l-1.53-.57a.46.46,0,0,1-.33-.56h0l.55-2.05a.46.46,0,0,1,.56-.32l1.45.6,1.63.22a.46.46,0,0,1,.33.56h0l-.55,2.05a.44.44,0,0,1-.55.32Z" transform="translate(0.98 1.9)" style="fill: #393939"/>
<path id="LM_detail_red3" data-name="LM detail red3" d="M69.15,17.3l-.26,1.55-.57,1.52a.45.45,0,0,1-.55.33h0l-2.06-.55a.46.46,0,0,1-.32-.56L66,18.15l.22-1.63a.45.45,0,0,1,.55-.33h0l2,.55a.46.46,0,0,1,.32.56Z" transform="translate(0.98 1.9)" style="fill: #393939"/>
<path id="LM_detail_red2" data-name="LM detail red2" d="M62.21,9.79l1.55.25,1.53.57a.46.46,0,0,1,.33.55h0l-.55,2.05a.46.46,0,0,1-.56.32l-1.45-.6-1.63-.22a.47.47,0,0,1-.33-.56h0l.55-2.05a.44.44,0,0,1,.55-.32Z" transform="translate(0.98 1.9)" style="fill: #393939"/>
<path id="LM_detail_red1" data-name="LM detail red1" d="M54.7,16.72,55,15.17l.57-1.52a.45.45,0,0,1,.55-.33h0l2.06.55a.46.46,0,0,1,.32.56l-.61,1.44-.22,1.63a.45.45,0,0,1-.55.33h0l-2-.55a.46.46,0,0,1-.32-.56Z" transform="translate(0.98 1.9)" style="fill: #393939"/>
</g>
</g>
</g> </g>
</g> </g>
</g> </g>

View File

@ -44,21 +44,12 @@ namespace pxsim.visuals {
} }
.sim-text.number { .sim-text.number {
font-family: Courier, Lato, Work Sans, PT Serif, Source Serif Pro; font-family: Courier, Lato, Work Sans, PT Serif, Source Serif Pro;
/*font-weight: bold;*/ font-weight: bold;
} }
.sim-text.inverted { .sim-text.inverted {
fill:#5A5A5A; fill:#5A5A5A;
} }
.no-drag, .sim-text, .sim-text-pin {
user-drag: none;
user-select: none;
-moz-user-select: none;
-webkit-user-drag: none;
-webkit-user-select: none;
-ms-user-select: none;
}
/* Color Grid */ /* Color Grid */
.sim-color-grid-circle:hover { .sim-color-grid-circle:hover {
stroke-width: 0.4; stroke-width: 0.4;
@ -71,15 +62,6 @@ namespace pxsim.visuals {
fill: gray !important; fill: gray !important;
cursor: pointer; cursor: pointer;
} }
/* Motor slider */
.sim-motor-btn {
cursor: pointer;
}
.sim-motor-btn:hover .btn {
stroke-width: 2px;
stroke: black !important;
}
`; `;
const EV3_WIDTH = 99.984346; const EV3_WIDTH = 99.984346;
@ -231,8 +213,9 @@ namespace pxsim.visuals {
} }
case NodeType.MediumMotor: case NodeType.MediumMotor:
case NodeType.LargeMotor: { case NodeType.LargeMotor: {
// TODO: figure out if the motor is in "input" or "output" mode
const state = ev3board().getMotors()[port]; const state = ev3board().getMotors()[port];
view = new MotorSliderControl(this.element, this.defs, state, port); view = new MotorReporterControl(this.element, this.defs, state, port);
break; break;
} }
} }

View File

@ -27,8 +27,8 @@ namespace pxsim.visuals {
this.group = svg.elt("g") as SVGGElement; this.group = svg.elt("g") as SVGGElement;
const reporterGroup = pxsim.svg.child(this.group, "g"); const reporterGroup = pxsim.svg.child(this.group, "g");
reporterGroup.setAttribute("transform", `translate(${this.getWidth() / 2}, 42)`); reporterGroup.setAttribute("transform", `translate(31, 42)`);
this.reporter = pxsim.svg.child(reporterGroup, "text", { 'text-anchor': 'middle', 'x': 0, 'y': '0', 'class': 'sim-text number large inverted' }) as SVGTextElement; this.reporter = pxsim.svg.child(reporterGroup, "text", { 'x': 0, 'y': '0', 'class': 'sim-text number large inverted' }) as SVGTextElement;
const sliderGroup = pxsim.svg.child(this.group, "g"); const sliderGroup = pxsim.svg.child(this.group, "g");
sliderGroup.setAttribute("transform", `translate(${this.getWidth() / 2 - this.getSliderWidth() / 2}, ${this.getReporterHeight()})`) sliderGroup.setAttribute("transform", `translate(${this.getWidth() / 2 - this.getSliderWidth() / 2}, ${this.getReporterHeight()})`)
@ -60,15 +60,12 @@ namespace pxsim.visuals {
}, ev => { }, ev => {
captured = true; captured = true;
if ((ev as MouseEvent).clientY != undefined) { if ((ev as MouseEvent).clientY != undefined) {
dragSurface.setAttribute('cursor', '-webkit-grabbing');
this.updateSliderValue(pt, parent, ev as MouseEvent); this.updateSliderValue(pt, parent, ev as MouseEvent);
} }
}, () => { }, () => {
captured = false; captured = false;
dragSurface.setAttribute('cursor', '-webkit-grab');
}, () => { }, () => {
captured = false; captured = false;
dragSurface.setAttribute('cursor', '-webkit-grab');
}) })
return this.group; return this.group;

View File

@ -1,167 +0,0 @@
namespace pxsim.visuals {
export class MotorSliderControl extends ControlView<MotorNode> {
private group: SVGGElement;
private gradient: SVGLinearGradientElement;
private slider: SVGGElement;
private reporter: SVGTextElement;
private dial: SVGGElement;
private static SLIDER_RADIUS = 100;
private internalSpeed: number = 0;
getInnerView(parent: SVGSVGElement, globalDefs: SVGDefsElement) {
this.group = svg.elt("g") as SVGGElement;
const slider = pxsim.svg.child(this.group, 'g', { 'transform': 'translate(25,25)' })
const outerCircle = pxsim.svg.child(slider, "circle", {
'stroke-dasharray': '565.48', 'stroke-dashoffset': '0',
'cx': 100, 'cy': 100, 'r': '90', 'style': `fill:transparent;`,
'stroke': '#a8aaa8', 'stroke-width': '1rem'
}) as SVGCircleElement;
this.reporter = pxsim.svg.child(this.group, "text", {
'x': this.getInnerWidth() / 2, 'y': this.getInnerHeight() / 2,
'text-anchor': 'middle', 'alignment-baseline': 'middle',
'style': 'font-size: 50px',
'class': 'sim-text inverted number'
}) as SVGTextElement;
this.dial = pxsim.svg.child(slider, "g", { 'cursor': '-webkit-grab' }) as SVGGElement;
const handleInner = pxsim.svg.child(this.dial, "g");
pxsim.svg.child(handleInner, "circle", { 'cx': 0, 'cy': 0, 'r': 30, 'style': 'fill: #f12a21;' });
pxsim.svg.child(handleInner, "circle", { 'cx': 0, 'cy': 0, 'r': 29.5, 'style': 'fill: none;stroke: #b32e29' });
this.updateDial();
let pt = parent.createSVGPoint();
let captured = false;
const dragSurface = svg.child(this.group, "rect", {
x: 0,
y: 0,
width: this.getInnerWidth(),
height: this.getInnerHeight(),
opacity: 0,
cursor: '-webkit-grab'
})
touchEvents(dragSurface, ev => {
if (captured && (ev as MouseEvent).clientY != undefined) {
ev.preventDefault();
this.updateSliderValue(pt, parent, ev as MouseEvent);
this.handleSliderMove();
}
}, ev => {
captured = true;
if ((ev as MouseEvent).clientY != undefined) {
this.updateSliderValue(pt, parent, ev as MouseEvent);
this.handleSliderDown();
}
}, () => {
captured = false;
this.handleSliderUp();
}, () => {
captured = false;
this.handleSliderUp();
})
return this.group;
}
getInnerWidth() {
return 250;
}
getInnerHeight() {
return 250;
}
private lastPosition: number;
private prevVal: number;
private updateSliderValue(pt: SVGPoint, parent: SVGSVGElement, ev: MouseEvent) {
let cur = svg.cursorPoint(pt, parent, ev);
const coords = {
x: cur.x / this.scaleFactor - this.left / this.scaleFactor,
y: cur.y / this.scaleFactor - this.top / this.scaleFactor
};
const radius = MotorSliderControl.SLIDER_RADIUS / 2;
const dx = coords.x - radius;
const dy = coords.y - radius;
const atan = Math.atan(-dy / dx);
let deg = Math.ceil(atan * (180 / Math.PI));
if (dx < 0) {
deg -= 270;
} else if (dy > 0) {
deg -= 450;
} else if (dx >= 0 && dy <= 0) {
deg = 90 - deg;
}
const value = Math.abs(Math.ceil((deg % 360) / 360 * this.getMax()));
this.internalSpeed = value;
this.updateDial();
this.prevVal = deg;
this.lastPosition = cur.x;
}
private handleSliderDown() {
const state = this.state;
state.manualMotorDown();
}
private handleSliderMove() {
this.dial.setAttribute('cursor', '-webkit-grabbing');
const state = this.state;
state.manualMotorMove(this.internalSpeed);
}
private handleSliderUp() {
this.dial.setAttribute('cursor', '-webkit-grab');
const state = this.state;
state.manualMotorUp();
this.internalSpeed = 0;
this.updateDial();
}
private updateDial() {
let speed = this.internalSpeed;
// Update dial position
const deg = speed / this.getMax() * 360; // degrees
const radius = MotorSliderControl.SLIDER_RADIUS;
const dialRadius = 5;
const x = Math.ceil((radius - dialRadius) * Math.sin(deg * Math.PI / 180)) + radius;
const y = Math.ceil((radius - dialRadius) * -Math.cos(deg * Math.PI / 180)) + radius;
this.dial.setAttribute('transform', `translate(${x}, ${y})`);
}
updateState() {
if (!this.visible) {
return;
}
const node = this.state;
const speed = node.getSpeed();
// Update reporter
this.reporter.textContent = `${speed}`;
}
private getMin() {
return 0;
}
private getMax() {
return 100;
}
}
}

View File

@ -173,15 +173,15 @@ namespace pxsim.visuals {
} }
// Inject all ports // Inject all ports
this.setInput(0, new PortView(0, '1')); this.setInput(0, new PortView(0, 'A'));
this.setInput(1, new PortView(1, '2')); this.setInput(1, new PortView(1, 'B'));
this.setInput(2, new PortView(2, '3')); this.setInput(2, new PortView(2, 'C'));
this.setInput(3, new PortView(3, '4')); this.setInput(3, new PortView(3, 'D'));
this.setOutput(0, new PortView(0, 'A')); this.setOutput(0, new PortView(0, '1'));
this.setOutput(1, new PortView(1, 'B')); this.setOutput(1, new PortView(1, '2'));
this.setOutput(2, new PortView(2, 'C')); this.setOutput(2, new PortView(2, '3'));
this.setOutput(3, new PortView(3, 'D')); this.setOutput(3, new PortView(3, '4'));
return this.contentGroup; return this.contentGroup;
} }

View File

@ -34,21 +34,21 @@ namespace pxsim.visuals {
this.syncedLabelG = pxsim.svg.child(this.element, 'g', {'transform': 'scale(0.5)'}) as SVGGElement; this.syncedLabelG = pxsim.svg.child(this.element, 'g', {'transform': 'scale(0.5)'}) as SVGGElement;
pxsim.svg.child(this.syncedLabelG, 'rect', {'rx': 15, 'ry': 15, 'x': 0, 'y': 0, 'width': 84, 'height': 34, 'fill': '#A8A9A8'}); pxsim.svg.child(this.syncedLabelG, 'rect', {'rx': 15, 'ry': 15, 'x': 0, 'y': 0, 'width': 84, 'height': 34, 'fill': '#A8A9A8'});
pxsim.svg.child(this.syncedLabelG, 'circle', {'cx': 17, 'cy': 17, 'r': 15, 'fill': 'white'}); pxsim.svg.child(this.syncedLabelG, 'circle', {'cx': 17, 'cy': 17, 'r': 15, 'fill': 'white'});
const leftLabel = pxsim.svg.child(this.syncedLabelG, 'text', {'transform': 'translate(11, 22)', 'class': 'no-drag', 'style': 'isolation: isolate;font-size: 16px;fill: #A8A9A8;font-family: ArialMT, Arial'}); const leftLabel = pxsim.svg.child(this.syncedLabelG, 'text', {'transform': 'translate(11, 22)', 'style': 'isolation: isolate;font-size: 16px;fill: #A8A9A8;font-family: ArialMT, Arial'});
leftLabel.textContent = a; leftLabel.textContent = a;
pxsim.svg.child(this.syncedLabelG, 'rect', {'rx': 0, 'ry': 0, 'x': 37, 'y': 12, 'width': 10, 'height': 3, 'fill': '#ffffff'}); pxsim.svg.child(this.syncedLabelG, 'rect', {'rx': 0, 'ry': 0, 'x': 37, 'y': 12, 'width': 10, 'height': 3, 'fill': '#ffffff'});
pxsim.svg.child(this.syncedLabelG, 'rect', {'rx': 0, 'ry': 0, 'x': 37, 'y': 18, 'width': 10, 'height': 3, 'fill': '#ffffff'}); pxsim.svg.child(this.syncedLabelG, 'rect', {'rx': 0, 'ry': 0, 'x': 37, 'y': 18, 'width': 10, 'height': 3, 'fill': '#ffffff'});
pxsim.svg.child(this.syncedLabelG, 'circle', {'cx': 67, 'cy': 17, 'r': 15, 'fill': 'white'}); pxsim.svg.child(this.syncedLabelG, 'circle', {'cx': 67, 'cy': 17, 'r': 15, 'fill': 'white'});
const rightLabel = pxsim.svg.child(this.syncedLabelG, 'text', {'transform': 'translate(61, 22)', 'class': 'no-drag', 'style': 'isolation: isolate;font-size: 16px;fill: #A8A9A8;font-family: ArialMT, Arial'}); const rightLabel = pxsim.svg.child(this.syncedLabelG, 'text', {'transform': 'translate(61, 22)', 'style': 'isolation: isolate;font-size: 16px;fill: #A8A9A8;font-family: ArialMT, Arial'});
rightLabel.textContent = b; rightLabel.textContent = b;
} }
protected renderMotorAngle(holeEl: Element, angle: number) { protected renderMotorAngle(holeEl: Element, angle: number) {
const width = 35.92; const width = 125.92;
const height = 35.9; const height = 37.9;
const transform = `translate(45.000000, 1.000000) rotate(${angle} ${width / 2} ${height / 2})`; const transform = `rotate(${angle} ${width / 2} ${height / 2})`;
holeEl.setAttribute("transform", transform); holeEl.setAttribute("transform", transform);
} }

View File

@ -18,7 +18,7 @@
} }
.blocklyFlyoutLabel .blocklyFlyoutLabelIcon { .blocklyFlyoutLabel .blocklyFlyoutLabelIcon {
font-family: 'legoIcons' !important; font-family: 'legoIcons';
} }
span.blocklyTreeIcon { span.blocklyTreeIcon {