Merge branch 'master' into field_ports

This commit is contained in:
Sam El-Husseini 2018-01-03 15:12:35 -08:00
commit d6d8b0655b
69 changed files with 11947 additions and 702 deletions

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont";
src: url("iconfont.eot?e05611aaee246c1da118a83eaf515de9?#iefix") format("embedded-opentype"),
url("iconfont.woff2?e05611aaee246c1da118a83eaf515de9") format("woff2"),
url("iconfont.woff?e05611aaee246c1da118a83eaf515de9") format("woff");
src: url("iconfont.eot?ad71e317f2f29e57a52275d9c2058dc8?#iefix") format("embedded-opentype"),
url("iconfont.woff2?ad71e317f2f29e57a52275d9c2058dc8") format("woff2"),
url("iconfont.woff?ad71e317f2f29e57a52275d9c2058dc8") format("woff");
}
.icon {
@ -28,3 +28,60 @@ url("iconfont.woff?e05611aaee246c1da118a83eaf515de9") format("woff");
.icon-gyro:before {
content: "\f104";
}
.icon-addpackage:before {
content: "\f105";
}
.icon-brick:before {
content: "\f106";
}
.icon-controls:before {
content: "\f107";
}
.icon-functions:before {
content: "\f108";
}
.icon-list:before {
content: "\f109";
}
.icon-logic:before {
content: "\f10a";
}
.icon-loops:before {
content: "\f10b";
}
.icon-math:before {
content: "\f10c";
}
.icon-motors:before {
content: "\f10d";
}
.icon-music:before {
content: "\f10e";
}
.icon-sensors:before {
content: "\f10f";
}
.icon-text:before {
content: "\f110";
}
.icon-variables:before {
content: "\f111";
}
.icon-cancel:before {
content: "\f112";
}
.icon-check:before {
content: "\f113";
}
.icon-download:before {
content: "\f114";
}
.icon-save:before {
content: "\f115";
}
.icon-advancedcollapsed:before {
content: "\f116";
}
.icon-advancedexpanded:before {
content: "\f117";
}

Binary file not shown.

View File

@ -19,6 +19,63 @@
<glyph glyph-name="gyro"
unicode="&#xF104;"
horiz-adv-x="23.578015492438215" d=" M17 0H6.4A5.901881224640355 5.901881224640355 0 0 0 5.1 0.3H2.3A1.283659166359277 1.283659166359277 0 0 0 1 1.6V4.5H0.5A0.5016599040944301 0.5016599040944301 0 0 0 0 5V35.4A0.5016599040944301 0.5016599040944301 0 0 0 0.5 35.9H1V38.7A1.283659166359277 1.283659166359277 0 0 0 2.3 40H10.6V39.6H12.8V40H21.2A1.283659166359277 1.283659166359277 0 0 0 22.5 38.7V35.9H23.1A0.5016599040944301 0.5016599040944301 0 0 0 23.6 35.4V5.1A0.5016599040944301 0.5016599040944301 0 0 0 23.1 4.6H22.5V1.6A1.283659166359277 1.283659166359277 0 0 0 21.2 0.4H18.5C18.4 0.1 17.2 0 17 0zM6.2 34.5L3.7 33.8A1.0033198081888601 1.0033198081888601 0 0 1 3.4 33.7A0.2360752489856142 0.2360752489856142 0 0 1 3.3 33.5A0.20656584286241245 0.20656584286241245 0 0 1 3.4 33.3L4.1 32.8A7.657690888970861 7.657690888970861 0 0 1 3.1 30A8.51346366654371 8.51346366654371 0 0 1 4.8 23.5C5.8 24.2 6.5 24.7 6.5 24.7A7.377351530800443 7.377351530800443 0 0 0 5.4 26.9A6.300258207303577 6.300258207303577 0 0 0 6 31.8L6.5 31.5H6.5L6.6 31.5A0.3541128734784213 0.3541128734784213 0 0 1 6.8 31.4A0.17705643673921065 0.17705643673921065 0 0 1 7 31.5A0.6344522316488379 0.6344522316488379 0 0 1 7 32L6.2 34.5zM17.5 31.8H17.5A6.300258207303577 6.300258207303577 0 0 0 18 26.9A7.510143858354851 7.510143858354851 0 0 0 17 24.7L17.1 24.6L18.6 23.5A8.631501291036518 8.631501291036518 0 0 1 20.3 30A7.657690888970861 7.657690888970861 0 0 1 19.3 32.8L19.8 33.1L20 33.2A0.22132054592401326 0.22132054592401326 0 0 1 20.1 33.4A0.26558465510881596 0.26558465510881596 0 0 1 20 33.6A1.0033198081888601 1.0033198081888601 0 0 1 19.7 33.7L17.2 34.5S17.1 34.1 17 33.6S16.6 32.3 16.5 32A0.619697528587237 0.619697528587237 0 0 1 16.5 31.5A0.17705643673921065 0.17705643673921065 0 0 1 16.6 31.4A0.48690520103282936 0.48690520103282936 0 0 1 16.8 31.4L16.8 31.4L17.4 31.7zM11.7 30.6A1.9918849133161198 1.9918849133161198 0 1 1 13.7 28.6A1.9918849133161198 1.9918849133161198 0 0 1 11.7 30.6H11.7z" />
<glyph glyph-name="addpackage"
unicode="&#xF105;"
horiz-adv-x="40" d=" M4.3 19.1C4.3 10.5 11.4 3.5 20 3.5C28.6 3.5 35.7 10.5 35.7 19.1C35.7 27.8 28.6 34.8 20 34.8C11.4 34.8 4.3 27.8 4.3 19.1z M30.4 20.9L21.7 20.9L21.7 29.6L18.3 29.6L18.3 20.9L9.6 20.9L9.6 17.4L18.3 17.4L18.3 8.7L21.7 8.7L21.7 17.4L30.4 17.4z" />
<glyph glyph-name="brick"
unicode="&#xF106;"
horiz-adv-x="40" d=" M34.3 0.9H5.7V39.1H34.4V0.9zM10.4 32.7V18.4H29.6V32.7H10.4z" />
<glyph glyph-name="controls"
unicode="&#xF107;"
horiz-adv-x="40" d=" M6.1 33H9.6V5.2H6.1V33z M18.3 33H21.7V5.2H18.3V33z M30.4 33H33.9V5.2H30.4V33z M2.6 15.7H13V7H2.6V15.7z M14.8 31.3H25.2V22.6H14.8V31.3z M27 22.6H37.4V13.9H27V22.6z" />
<glyph glyph-name="functions"
unicode="&#xF108;"
horiz-adv-x="40" d=" M12.2 25.4H9.1C9.1 26.3 9.1 26.5 9.9 26.5C11.5 26.5 12.5 27.2 13.1 28.6C13.8 30.1 14.8 31.5 15.7 33.1C16.5 34.3 18.1 35.3 19.7 35.5C20.7 35.7 21.9 35.3 22.5 34.5C22.8 33.9 22.8 33.4 22.6 32.7C22.3 32.2 21.8 32 21.1 32.2C20.5 32.2 20.2 32.7 20.2 33.3C20.2 33.4 20.2 33.4 20.2 33.6C20.2 33.9 20.4 34.3 20.4 34.6C20 34.6 19.5 34.8 19.2 34.6C18.5 34.3 17.9 33.9 17.4 33.1C16.7 32 16.2 30.6 15.7 29.4C15.3 28.6 15 27.3 14.8 26.5H17.2C17.1 26.1 17.1 25.8 16.9 25.4H14.5C13.9 23.5 13.6 21.9 12.9 20.2C12.2 16.7 10.8 13.4 9.4 10.1C8.7 8.6 7.7 7.3 6.6 6.3C5.8 5.4 4.5 4.9 3.3 4.9C2.6 4.7 1.8 5.1 1.1 5.4C0.7 5.8 0.5 6.5 0.7 7.2C1.1 7.7 1.6 8 2.5 7.9C3 7.9 3.2 7.3 3.2 6.8C3.2 6.6 3 6.5 3 6.5C2.8 6.3 2.8 6.1 2.8 5.9C3 5.9 3.2 5.8 3.5 5.8C4.4 5.8 5.4 6.3 5.9 7.2C6.5 8 7 9.1 7.2 9.9C8.5 15.2 10.1 20.4 11.7 25.4C12.2 25.3 12.2 25.3 12.2 25.4z M32.5 4.7C32.7 4.9 32.7 5.1 32.9 5.3C34.8 6.3 36 8.4 36.4 10.5C37.1 13.9 37.1 17.4 36.2 20.9C35.7 22.8 34.5 24.2 33.1 25.4C32.9 25.6 32.7 25.8 32.7 25.9C36 24.7 39.2 20.6 39.2 15.3C39.3 10.8 36.7 6.5 32.5 4.7z M23.9 25.8C23.9 25.6 23.7 25.4 23.7 25.4C21.8 24.4 20.5 22.3 20.2 20.2C19.5 16.7 19.5 13.3 20.4 9.6C20.9 7.7 22.1 6.3 23.5 5.1C23.7 4.9 23.9 4.9 23.9 4.6C20 6.5 17.4 10.5 17.6 15C17.4 20.7 20.9 24.9 23.9 25.8z M32 12.2C32 12.2 32.2 12.2 32.4 12C32.4 12 32.4 12 32.4 11.9C31.9 11 31.3 10.1 30.3 9.6C29.9 9.3 29.2 9.1 28.5 9.6C28.4 9.8 28.2 9.9 28.2 10.3C27.9 11.3 27.7 12.4 27.5 13.4C27.5 13.6 27.5 13.6 27.3 13.8C27.2 13.4 27 13.1 26.6 12.7C26.1 12 25.6 11 24.7 10.3C24.4 9.9 24 9.6 23.5 9.4C23 9.3 22.5 9.4 21.9 9.9V10.1C21.9 10.5 21.9 10.8 22.3 11C22.5 11.2 22.8 11.2 23.2 11L23.3 10.8C23.9 10.5 24 10.3 24.4 11C25.1 12 25.9 13.4 26.8 14.5C26.8 14.6 26.8 14.8 26.8 15C26.6 15.7 26.5 16.6 26.3 17.3C25.9 18.5 25.4 19 24 19H23.9C23.7 19.2 23.9 19.3 24 19.3C24.7 19.5 25.8 19.7 26.5 19.7C26.6 19.7 26.8 19.7 27 19.5C27.5 18.8 27.9 18.1 28 17.1C28 16.9 28.2 16.6 28.2 16.4C28.4 16.7 28.7 17.3 29.1 17.6C29.6 18.1 30.1 18.8 30.8 19.3C31.2 19.5 31.5 19.7 31.9 19.7C32.4 19.7 32.7 19.3 32.7 18.8V18.6C32.5 18.1 32.2 17.9 31.7 18.1L31.7 18.1C31.5 18.1 31.5 18.1 31.3 18.1C30.8 18.5 30.1 18.3 29.6 17.8L29.6 17.8C29.2 17.3 28.7 16.6 28.4 15.9C28.4 15.7 28.4 15.7 28.4 15.5C28.7 14.3 28.9 12.9 29.2 11.5C29.2 11.3 29.2 11.3 29.4 11.2C29.6 10.6 29.9 10.5 30.3 11C31.3 11.3 31.5 11.9 32 12.2z" />
<glyph glyph-name="list"
unicode="&#xF109;"
horiz-adv-x="40" d=" M11.1 30.4H36.9V27.3H11.1V30.4z M11.1 22.4H36.9V19.3H11.1V22.4z M11.1 14.4H36.9V11.3H11.1V14.4z M5.6 27.3H3.8V33.6H2.4V34.6C3.3 34.6 4 35.1 4.2 36.2H5.6V27.3z M7.7 17.6V16H1.4V16.7C1.4 18.8 2.8 19.7 4 20.3C5.7 21.2 5.7 21.6 5.7 22.1C5.7 22.6 5.4 23.1 4.5 23.1C3.7 23.1 3.1 22.4 3.1 21.6H1.4C1.4 23.1 2.4 24.7 4.5 24.7C6.6 24.7 7.5 23.3 7.5 22.1C7.5 20.3 6.3 19.8 4.9 19C4 18.4 3.3 17.9 3.3 17.4H7.7z M4.5 4.5C2.4 4.5 1.4 5.9 1.2 7.5H3C3 6.6 3.5 6.1 4.5 6.1C5.6 6.1 6.1 6.6 6.1 7.3C6.1 8 5.6 8.5 4.7 8.5H4.2V9.9H4.5C5.6 9.9 5.9 10.4 5.9 11C5.9 11.7 5.4 12 4.7 12C3.8 12 3.3 11.3 3.3 10.6H1.6C1.6 12.2 2.6 13.6 4.5 13.6C6.4 13.6 7.5 12.3 7.5 11.1C7.5 10.4 7.1 9.7 6.3 9.4C7.3 9 7.7 8.2 7.7 7.3C7.8 6.1 6.8 4.5 4.5 4.5z" />
<glyph glyph-name="logic"
unicode="&#xF10A;"
horiz-adv-x="40" d=" M2.8 14.1H7.4C10 14.2 12.2 16 13.1 18.6C15 23.1 18.3 31.3 23.7 31.3S29.8 31.3 29.8 31.3V35.8L36.9 28.3L29.8 21.5V26.4H24.9C22.3 25.7 20.2 24 19.4 21.5C17.3 17 15.2 9.4 8.2 9.2C5.1 9.2 3 9.2 3 9.2V14.1z M2.8 31.1V26.2H8.2C8.2 26.2 11.4 26.2 13.1 22.1C13.8 23.8 14.7 25.4 15.7 26.9C15.7 26.9 12.2 30.9 8.4 30.9S2.8 31.1 2.8 31.1z M19.5 18.4C19.5 18.4 21.8 13.9 24.4 13.9H30V18.4L37.3 11.3L30 4.2V9H23.7C23.7 9 20.2 9 16.9 13.4C18 14.9 18.8 16.7 19.5 18.4z" />
<glyph glyph-name="loops"
unicode="&#xF10B;"
horiz-adv-x="40" d=" M6.3 12.7C4.5 15.2 2.6 17.4 0.9 20H4.5C4.5 24.2 6.3 28.4 9.2 31.3C11.3 33.4 13.7 34.8 16.7 35.3C21.9 36.6 27.3 35 31.1 31.2C30.3 30.3 29.4 29.4 28.7 28.7C24.2 32.6 19.3 33.3 14.1 30.5C10.3 28.4 8.2 24.4 8.2 20.2H11.8C9.7 17.6 7.8 15 6.3 12.7z M32.2 20H28.5C30.4 22.5 32.2 24.7 33.9 27.3C35.8 24.9 37.6 22.6 39.3 20H35.6C35.6 15.7 33.7 11.5 30.6 8.6C28.5 6.6 26.1 5.3 23.3 4.7C18.1 3.5 12.7 5.1 8.9 8.9L11.3 11.3C15.6 7.5 20.7 6.6 25.9 9.6C29.9 11.7 32.2 15.7 32.2 20z" />
<glyph glyph-name="math"
unicode="&#xF10C;"
horiz-adv-x="40" d=" M15.2 5.3C14.9 4.9 14.2 4.2 13.8 3.9L9.3 8.4C7.6 6.7 6.2 5.3 4.8 3.9C4.4 4.2 3.8 4.9 3.4 5.3L7.9 9.8C6.2 11.5 4.8 12.9 3.4 14.3C3.8 14.7 4.4 15.4 4.8 15.7L9.3 11.2L13.8 15.7C14.2 15.4 14.9 14.7 15.2 14.3L10.7 9.8C12.1 8.2 13.7 6.7 15.2 5.3z M1.5 28V30H7.9V36.4C8.6 36.4 9.1 36.4 9.8 36.4V30H16.3V28H9.8V21.6H7.8V28H1.5z M38.4 10.7H22V14.1H38.4V10.7z M38.4 7.2V3.7H22V7.2H38.4z M38.4 31V27.5H22V31H38.4z" />
<glyph glyph-name="motors"
unicode="&#xF10D;"
horiz-adv-x="40" d=" M28.9 25.8C27.5 24.4 25.9 22.9 24.5 21.5H35.7V32.6L32.2 29.1C29.6 32.3 25.9 34.3 21.8 34.9C18.3 35.4 14.6 34.5 11.7 32.6C4.2 28.1 1.9 18.3 6.5 10.9S20.7 1.1 28.2 5.6C30.8 7.2 32.7 9.5 34.1 12.1C32.7 12.6 31.3 13.3 29.9 13.8C28.5 11 25.9 9 23 8.1C20.7 7.4 18.3 7.6 16 8.4C10.3 10.7 7.3 17.1 9.4 22.9C10.6 26.3 13.6 29 17.1 29.8C21.6 31.2 26.3 29.5 28.9 25.8z M16.7 19C16.7 17.1 18.3 15.7 20 15.7S23.3 17.3 23.3 19C23.3 21 21.8 22.3 20 22.3C18.1 22.5 16.7 21 16.7 19C16.7 19 16.7 19 16.7 19z" />
<glyph glyph-name="music"
unicode="&#xF10E;"
horiz-adv-x="40" d=" M24.2 17.7C27.1 17.2 29.9 15.7 31.7 13.2C32.5 13.2 33.4 13.2 33.4 13.2S36 20.9 30.3 26.3S13.4 31.7 9.2 26.3C6.3 22.6 5.2 17.6 6.8 13.2C7.3 13.2 7.7 13.2 8.2 13.2C8.2 13.2 11.1 17.6 15.8 17.7C15.7 10.1 15.7 3.5 15.7 3.5C12.3 4.2 9.6 6.3 8 9.4C4.5 10.1 1.7 13.2 1.7 17C1.7 28.3 10.3 34.8 20 34.8S38.8 27.3 38.1 17C37.7 9.9 31.8 9.4 31.8 9.4C30.4 6.3 27.7 4 24.3 3.5C24.2 11.3 24.2 17.7 24.2 17.7z" />
<glyph glyph-name="sensors"
unicode="&#xF10F;"
horiz-adv-x="40" d=" M20 36.9C10.6 36.9 3 29.2 3 19.8C3 10.4 10.6 2.8 20 2.8S37 10.4 37 19.8C36.9 29.4 29.4 36.9 20 36.9zM20 8.2C13.4 8.2 8.2 13.6 8.2 20S13.6 31.8 20 31.8S31.8 26.4 31.8 20S26.6 8.2 20 8.2z M13.2 20C13.2 16.3 16.3 13.2 20 13.2C23.7 13.2 26.8 16.3 26.8 20C26.8 23.7 23.7 26.8 20 26.8C16.3 26.8 13.2 23.7 13.2 20z" />
<glyph glyph-name="text"
unicode="&#xF110;"
horiz-adv-x="40" d=" M23.1 30.6V2.8H16.5V30.6H7.7V36.7H32.3V30.6H23.1z" />
<glyph glyph-name="variables"
unicode="&#xF111;"
horiz-adv-x="40" d=" M36.8 12V7.8H3.4V12H36.8z M36.8 22.1V17.9H3.4V22.1H36.8z M36.7 32.2V28H3.3V32.2H36.7z" />
<glyph glyph-name="cancel"
unicode="&#xF112;"
horiz-adv-x="40" d=" M4285.9 23284.1H4308.1V23280.4H4285.9V23284.1z M4285.9 23302.6H4289.6V23280.4H4285.9V23302.6z" />
<glyph glyph-name="check"
unicode="&#xF113;"
horiz-adv-x="40" d=" M4209.2 23456H4231.3V23452.3H4209.2V23456z M4201.2 23463.4H4204.9V23452.3H4201.2V23463.4z" />
<glyph glyph-name="download"
unicode="&#xF114;"
horiz-adv-x="40" d=" M5.2 15.7H36.5V1.7H5.2V15.7z M28.5 24.2L26.1 26.6L22.6 23.1L22.6 36.5L19.1 36.5L19.1 23.5L16 26.6L13.6 24.2L20.9 16.7L21 16.9L21.2 16.7z" />
<glyph glyph-name="save"
unicode="&#xF115;"
horiz-adv-x="40" d=" M25 34.5C25 33.6 25 32.8 25 31.9C25 31 24.7 30.9 24 30.9C23.5 30.9 22.8 30.9 22.4 30.9C22.1 30.9 21.4 31 21.4 31.7V31.9V36.9C21.4 37.3 21.6 37.8 22.3 38C22.3 38 22.3 38 22.4 38C23 38 23.7 38 24.2 38C24.7 38 25.2 37.6 25.2 37.1C25.2 37.1 25.2 37.1 25.2 36.9C25 36.3 25 35.2 25 34.5z M37.6 31.2C35.8 32.9 34.3 34.5 32.5 36.3C31 37.8 31 37.8 28.5 37.8C27.5 37.8 27.3 37.6 27.3 36.6V28.4C27.3 27.4 27.1 27.2 26.1 27.2H14.3C13.2 27.2 13 27.4 13 28.4V36.4C13 37.6 12.9 37.8 11.7 37.8H3.8C2.6 37.8 2.4 37.6 2.4 36.4V19.9C2.4 14.3 2.4 8.9 2.4 3.2C2.4 2 2.6 1.8 3.7 1.8H36.9C37.9 1.8 38.1 2.2 38.1 3.2V29.6C38.3 30.5 37.9 30.9 37.6 31.2zM33.7 6.7H7.1V23H33.7V6.7z" />
<glyph glyph-name="advancedcollapsed"
unicode="&#xF116;"
horiz-adv-x="40" d=" M39.7 28.2L36.2 31.5L20 15.3L3.8 31.5L0.3 28.2L18.3 10.3L18.3 10.3L20 8.5L20.5 9L20.5 9z" />
<glyph glyph-name="advancedexpanded"
unicode="&#xF117;"
horiz-adv-x="40" d=" M39.3 12L21.7 29.6L21.7 29.6L20 31.3L19.5 30.8L19.5 30.8L0.7 12L4 8.7L20 24.7L36 8.7z" />
</font>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -139,8 +139,98 @@ namespace pxt.editor {
})
}
/**
* Update the shape of Blockly blocks with square corners
*/
function updateBlocklyShape() {
/**
* Rounded corner radius.
* @const
*/
(Blockly.BlockSvg as any).CORNER_RADIUS = 0 * (Blockly.BlockSvg as any).GRID_UNIT;
/**
* Inner space between edge of statement input and notch.
* @const
*/
(Blockly.BlockSvg as any).STATEMENT_INPUT_INNER_SPACE = 3 * (Blockly.BlockSvg as any).GRID_UNIT;
/**
* SVG path for drawing next/previous notch from left to right.
* @const
*/
(Blockly.BlockSvg as any).NOTCH_PATH_LEFT = (
'l 8,8 ' +
'h 16 ' +
'l 8,-8 '
);
/**
* SVG path for drawing next/previous notch from right to left.
* @const
*/
(Blockly.BlockSvg as any).NOTCH_PATH_RIGHT = (
'l -8,8 ' +
'h -16 ' +
'l -8,-8 '
);
/**
* SVG start point for drawing the top-left corner.
* @const
*/
(Blockly.BlockSvg as any).TOP_LEFT_CORNER_START =
'm 0,' + 0;
/**
* SVG path for drawing the rounded top-left corner.
* @const
*/
(Blockly.BlockSvg as any).TOP_LEFT_CORNER =
'l ' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',0 ';
/**
* SVG path for drawing the rounded top-right corner.
* @const
*/
(Blockly.BlockSvg as any).TOP_RIGHT_CORNER =
'l ' + 0 + ',' + (Blockly.BlockSvg as any).CORNER_RADIUS;
/**
* SVG path for drawing the rounded bottom-right corner.
* @const
*/
(Blockly.BlockSvg as any).BOTTOM_RIGHT_CORNER =
'l 0,' + (Blockly.BlockSvg as any).CORNER_RADIUS;
/**
* SVG path for drawing the rounded bottom-left corner.
* @const
*/
(Blockly.BlockSvg as any).BOTTOM_LEFT_CORNER =
'l -' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',0';
/**
* SVG path for drawing the top-left corner of a statement input.
* @const
*/
(Blockly.BlockSvg as any).INNER_TOP_LEFT_CORNER =
'l ' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',-' + 0;
/**
* SVG path for drawing the bottom-left corner of a statement input.
* Includes the rounded inside corner.
* @const
*/
(Blockly.BlockSvg as any).INNER_BOTTOM_LEFT_CORNER =
'l ' + 0 + ',' + (Blockly.BlockSvg as any).CORNER_RADIUS * 2 +
'l ' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',' + 0;
}
initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): Promise<pxt.editor.ExtensionResult> {
pxt.debug('loading pxt-ev3 target extensions...')
updateBlocklyShape();
const res: pxt.editor.ExtensionResult = {
fieldEditors: [{
selector: "ports",

File diff suppressed because one or more lines are too long

View File

@ -56,6 +56,7 @@ namespace sensors {
constructor(port: number) {
super(port)
this._setMode(ColorSensorMode.None);
this.thresholdDetector = new sensors.internal.ThresholdDetector(this.id());
}

View File

@ -21,8 +21,6 @@
"brick.Button.pauseUntil": "Waits until the event is raised",
"brick.Button.pauseUntil|param|ev": "the event to wait for",
"brick.Button.wasPressed": "See if the button was pressed again since the last time you checked.",
"brick._imagePicker": "An image",
"brick._imagePicker|param|image": "the image",
"brick.buttonDown": "Down button on the EV3 Brick.",
"brick.buttonEnter": "Enter button on the EV3 Brick.",
"brick.buttonLeft": "Left button on the EV3 Brick.",
@ -31,17 +29,12 @@
"brick.clearScreen": "Clears the screen",
"brick.lightPattern": "Pattern block.",
"brick.lightPattern|param|pattern": "the lights pattern to use. eg: LightsPattern.Green",
"brick.print": "Show text on the screen.",
"brick.printLine": "Show text on the screen at a specific line.",
"brick.printLine|param|line": "the line number to print the text at, eg: 0",
"brick.printLine|param|text": "the text to print on the screen, eg: \"Hello world\"",
"brick.printPorts": "Prints the port states on the screen",
"brick.print|param|text": "the text to print on the screen, eg: \"Hello world\"",
"brick.print|param|x": "the starting position's x coordinate, eg: 0",
"brick.print|param|y": "the starting position's x coordinate, eg: 0",
"brick.setLight": "Set lights.",
"brick.setLight|param|pattern": "the lights pattern to use.",
"brick.setPixel": "Sets a pixel on or off",
"brick.setPixel|param|on": "a value indicating if the pixel should be on or off",
"brick.setPixel|param|x": "the starting position's x coordinate, eg: 0",
"brick.setPixel|param|y": "the starting position's x coordinate, eg: 0",
"brick.showImage": "Shows an image on screen",
"brick.showImage|param|image": "image to draw",
"console": "Reading and writing data to the console output.\n\nReading and writing data to the console output.",
@ -77,9 +70,15 @@
"motors.MotorBase.setSpeed": "Sets the speed of the motor.",
"motors.MotorBase.setSpeed|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50",
"motors.MotorBase.stop": "Stops the motor(s).",
"motors.SynchedMotorPair.drive": "Makes a differential drive robot move with a given speed (%) and rotation rate (deg/s)\nusing a unicycle model.",
"motors.SynchedMotorPair.drive|param|rotationSpeed": "rotation of the robot around the center point, eg: 30",
"motors.SynchedMotorPair.drive|param|speed": "speed of the center point between motors, eg: 10",
"motors.SynchedMotorPair.drive|param|value": "the amount of movement, eg: 2",
"motors.SynchedMotorPair.setDimensions": "Sets the wheels radius and base length of a directional drive robot",
"motors.SynchedMotorPair.setDimensions|param|wheelRadius": "@param baseLength ",
"motors.SynchedMotorPair.steer": "Turns the motor and the follower motor by a number of rotations",
"motors.SynchedMotorPair.steer|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50",
"motors.SynchedMotorPair.steer|param|steering": "the ratio of power sent to the follower motor, from ``-100`` to ``100``",
"motors.SynchedMotorPair.steer|param|turnRatio": "the ratio of power sent to the follower motor, from ``-200`` to ``200``, eg: 0",
"motors.SynchedMotorPair.steer|param|unit": "the meaning of the value",
"motors.SynchedMotorPair.steer|param|value": "the move quantity, eg: 2",
"motors.SynchedMotorPair.tank": "The Move Tank block can make a robot drive forward, backward, turn, or stop. \nUse the Move Tank block for robot vehicles that have two Large Motors, \nwith one motor driving the left side of the vehicle and the other the right side. \nYou can make the two motors go at different speeds or in different directions \nto make your robot turn.",

View File

@ -28,7 +28,6 @@
"brick.Button.onEvent|block": "on %button|%event",
"brick.Button.pauseUntil|block": "pause until %button|%event",
"brick.Button.wasPressed|block": "%button|was pressed",
"brick._imagePicker|block": "%image",
"brick.buttonDown|block": "down",
"brick.buttonEnter|block": "enter",
"brick.buttonLeft|block": "left",
@ -36,10 +35,9 @@
"brick.buttonUp|block": "up",
"brick.clearScreen|block": "clear screen",
"brick.lightPattern|block": "%pattern",
"brick.printLine|block": "print %text| at line %line",
"brick.printPorts|block": "print ports",
"brick.print|block": "print %text| at x: %x| y: %y",
"brick.setLight|block": "set light to %pattern=led_pattern",
"brick.setPixel|block": "set pixel %on| at x: %x| y: %y",
"brick.showImage|block": "show image %image=screen_image_picker",
"brick|block": "brick",
"console.logValue|block": "console|log value %name|= %value",
@ -55,8 +53,9 @@
"motors.MotorBase.setBrake|block": "set %motor|brake %brake",
"motors.MotorBase.setReversed|block": "set %motor|reversed %reversed",
"motors.MotorBase.setSpeed|block": "set speed of %motor|to %speed|%",
"motors.SynchedMotorPair.steer|block": "steer %chassis|%steering|%|at speed %speed|%|by %value|%unit",
"motors.SynchedMotorPair.tank|block": "tank %chassis|left %speedLeft|%|right %speedRight|%|by %value|%unit",
"motors.SynchedMotorPair.drive|block": "drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s|for %value|%unit",
"motors.SynchedMotorPair.steer|block": "steer %chassis turn by|%turnRatio|at speed %speed|%|for %value|%unit",
"motors.SynchedMotorPair.tank|block": "tank %chassis|left %speedLeft|%|right %speedRight|%|for %value|%unit",
"motors.largeAB|block": "large A+B",
"motors.largeAD|block": "large A+D",
"motors.largeA|block": "large A",

View File

@ -66,6 +66,7 @@ namespace brick {
//% hidden
_update(curr: boolean) {
if (this == null) return
if (this._isPressed == curr) return
this._isPressed = curr
if (curr) {
@ -104,7 +105,7 @@ namespace brick {
//% blockId=buttonWasPressed
//% parts="brick"
//% blockNamespace=brick
//% weight=80 blockGap=8
//% weight=80
//% group="Buttons"
wasPressed() {
const r = this._wasPressed

View File

@ -1,260 +1,260 @@
namespace images {
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsBigSmile = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsHeartLarge = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsHeartSmall = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsMouth1open = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsMouth1shut = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsMouth2open = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsMouth2shut = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsSad = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsSick = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsSmile = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsSwearing = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsTalking = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsWink = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const expressionsZzz = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesAngry = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesAwake = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesBlackEye = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesBottomLeft = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesBottomRight = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesCrazy1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesCrazy2 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesDisappointed = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesDizzy = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesDown = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesEvil = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesHurt = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesKnockedOut = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesLove = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesMiddleLeft = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesMiddleRight = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesNeutral = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesNuclear = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesPinchLeft = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesPinchMiddle = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesPinchRight = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesSleeping = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesTear = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesTiredLeft = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesTiredMiddle = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesTiredRight = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesToxic = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesUp = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const eyesWinking = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationAccept = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationBackward = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationDecline = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationForward = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationLeft = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationNoGo = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationQuestionMark = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationRight = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationStop1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationStop2 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationThumbsDown = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationThumbsUp = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const informationWarning = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoColorSensor = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoEv3icon = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoEv3 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoGyroSensor = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoIrBeacon = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoIrSensor = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoLego = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoLargeMotor = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoMindstorms = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoMediumMotor = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoSoundSensor = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoTempSensor = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoTouchSensor = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const legoUsSensor = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const objectsBomb = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const objectsBoom = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const objectsFire = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const objectsFlowers = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const objectsForest = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const objectsLightOff = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const objectsLightOn = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const objectsLightning = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const objectsNight = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const objectsPirate = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const objectsSnow = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const objectsTarget = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressBar0 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressBar1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressBar2 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressBar3 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressBar4 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressDial0 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressDial1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressDial2 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressDial3 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressDial4 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressDots0 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressDots1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressDots2 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressDots3 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressHourglass0 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressHourglass1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressHourglass2 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressTimer0 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressTimer1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressTimer2 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressTimer3 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressTimer4 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressWaterLevel0 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressWaterLevel1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressWaterLevel2 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const progressWaterLevel3 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemAccept1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
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
//% fixedInstance jres blockIdentity=brick.__imagePicker
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
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemBusy1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemDecline1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
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
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemDotFull = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemEv3small = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemPlay = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider0 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider1 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider2 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider3 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider4 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider5 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider6 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider7 = screen.unpackPNG(hex``);
//% fixedInstance jres blockIdentity=brick._imagePicker
//% fixedInstance jres blockIdentity=brick.__imagePicker
export const systemSlider8 = screen.unpackPNG(hex``);
}

View File

@ -214,6 +214,7 @@ namespace sensors.internal {
}
public setLevel(level: number) {
if (this == null) return
this.level = this.clampValue(level);
if (this.level >= this.highThreshold) {

View File

@ -14,7 +14,7 @@ enum Output {
//% block="C+D"
CD = Output.C | Output.D,
//% block="A+D"
AD = Output.B | Output.C,
AD = Output.A | Output.D,
//% block="All"
ALL = 0x0f
}
@ -399,9 +399,13 @@ namespace motors {
//% fixedInstances
export class SynchedMotorPair extends MotorBase {
private wheelRadius: number;
private baseLength: number;
constructor(ports: Output) {
super(ports, () => this.__init(), (speed) => this.__setSpeed(speed), (steps, stepsOrTime, speed) => this.__move(steps, stepsOrTime, speed));
this.wheelRadius = 3;
this.baseLength = 12;
this.markUsed();
}
@ -438,18 +442,82 @@ namespace motors {
}
/**
* Turns the motor and the follower motor by a number of rotations
* @param value the move quantity, eg: 2
* @param unit the meaning of the value
* @param steering the ratio of power sent to the follower motor, from ``-100`` to ``100``
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
* The Move Tank block can make a robot drive forward, backward, turn, or stop.
* Use the Move Tank block for robot vehicles that have two Large Motors,
* with one motor driving the left side of the vehicle and the other the right side.
* You can make the two motors go at different speeds or in different directions
* to make your robot turn.
* @param value the amount of movement, eg: 2
* @param unit
* @param speedLeft the speed on the left motor, eg: 50
* @param speedRight the speed on the right motor, eg: 50
*/
//% blockId=motorPairTurn block="steer %chassis|%steering|%|at speed %speed|%|by %value|%unit"
//% blockId=motorPairTank block="tank %chassis|left %speedLeft|%|right %speedRight|%|for %value|%unit"
//% weight=9 blockGap=8
//% steering.min=-100 steering=100
//% speedLeft.min=-100 speedLeft=100
//% speedRight.min=-100 speedRight=100
//% inlineInputMode=inline
//% group="Chassis"
steer(steering: number, speed: number, value: number, unit: MoveUnit) {
tank(speedLeft: number, speedRight: number, value: number, unit: MoveUnit) {
this.init();
speedLeft = Math.clamp(-100, 100, speedLeft >> 0);
speedRight = Math.clamp(-100, 100, speedRight >> 0);
const speed = Math.abs(speedLeft) > Math.abs(speedRight) ? speedLeft : speedRight;
const turnRatio = speedLeft == speed
? (100 - speedRight / speedLeft * 100)
: (speedLeft / speedRight * 100 - 100);
this.steer(turnRatio, speed, value, unit);
}
/**
* Makes a differential drive robot move with a given speed (%) 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=motorDrive block="drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s|for %value|%unit"
//% inlineInputMode=inline
//% group="Chassis"
//% weight=8 blockGap=8
drive(speed: number, rotationSpeed: number, value: number, unit: MoveUnit) {
this.init();
// speed is expressed in %
const R = this.wheelRadius; // cm
const L = this.baseLength; // cm
const PI = 3.14;
const maxw = 170 / 60 * 2 * PI; // rad / s
const maxv = maxw * R; // cm / s
// speed is cm / s
const v = speed; // cm / s
const w = rotationSpeed / 360 * 2 * PI; // rad / s
const vr = (2 * v + w * L) / (2 * R); // rad / s
const vl = (2 * v - w * L) / (2 * R); // rad / s
const sr = vr / maxw * 100; // %
const sl = vl / maxw * 100; // %
this.tank(sr, sl, value, unit)
}
/**
* Turns the motor and the follower motor by a number of rotations
* @param turnRatio the ratio of power sent to the follower motor, from ``-200`` to ``200``, eg: 0
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
* @param value the move quantity, eg: 2
* @param unit the meaning of the value
*/
//% blockId=motorPairTurn block="steer %chassis turn by|%turnRatio|at speed %speed|%|for %value|%unit"
//% weight=6 blockGap=8
//% turnRatio.min=-200 turnRatio=200
//% inlineInputMode=inline
//% group="Chassis"
steer(turnRatio: number, speed: number, value: number, unit: MoveUnit) {
this.init();
speed = Math.clamp(-100, 100, speed >> 0);
if (!speed) {
@ -457,7 +525,7 @@ namespace motors {
return;
}
const turnRatio = Math.clamp(-200, 200, steering + 100 >> 0);
turnRatio = Math.clamp(-200, 200, turnRatio >> 0);
let useSteps: boolean;
let stepsOrTime: number;
switch (unit) {
@ -470,7 +538,7 @@ namespace motors {
useSteps = true;
break;
default:
stepsOrTime = value;
stepsOrTime = value >> 0;
useSteps = false;
break;
}
@ -482,30 +550,17 @@ namespace motors {
stepsOrTime: stepsOrTime,
useBrake: this._brake
});
}
}
/**
* The Move Tank block can make a robot drive forward, backward, turn, or stop.
* Use the Move Tank block for robot vehicles that have two Large Motors,
* with one motor driving the left side of the vehicle and the other the right side.
* You can make the two motors go at different speeds or in different directions
* to make your robot turn.
* @param value the amount of movement, eg: 2
* @param unit
* @param speedLeft the speed on the left motor, eg: 50
* @param speedRight the speed on the right motor, eg: 50
* Sets the wheels radius and base length of a directional drive robot
* @param wheelRadius
* @param baseLength
*/
//% blockId=motorPairTank block="tank %chassis|left %speedLeft|%|right %speedRight|%|by %value|%unit"
//% weight=9 blockGap=8
//% speedLeft.min=-100 speedLeft=100
//% speedRight.min=-100 speedRight=100
//% inlineInputMode=inline
//% group="Chassis"
tank(speedLeft: number, speedRight: number, value: number, unit: MoveUnit) {
speedLeft = Math.clamp(speedLeft >> 0, -100, 100);
speedRight = Math.clamp(speedRight >> 0, -100, 100);
const steering = (speedRight * 100 / speedLeft) >> 0;
this.steer(speedLeft, steering, value, unit);
setDimensions(wheelRadius: number, baseLength: number): void {
this.wheelRadius = wheelRadius;
this.baseLength = baseLength;
}
/**
@ -513,6 +568,8 @@ namespace motors {
*/
//%
toString(): string {
this.init();
let r = outputToName(this._port);
for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
if (this._port & (1 << i)) {

View File

@ -80,15 +80,6 @@ namespace brick {
}
}
/**
* Sets a pixel on or off
* @param on a value indicating if the pixel should be on or off
* @param x the starting position's x coordinate, eg: 0
* @param y the starting position's x coordinate, eg: 0
*/
//% blockId=screen_setpixel block="set pixel %on| at x: %x| y: %y"
//% weight=98 group="Screen"
//% x.min=0 x.max=178 y.min=0 y.max=128 on.fieldEditor=toggleonoff
export function setPixel(on: boolean, x: number, y: number) {
x |= 0
y |= 0
@ -97,14 +88,20 @@ namespace brick {
}
/**
* Show text on the screen.
* Show text on the screen at a specific line.
* @param text the text to print on the screen, eg: "Hello world"
* @param x the starting position's x coordinate, eg: 0
* @param y the starting position's x coordinate, eg: 0
* @param line the line number to print the text at, eg: 0
*/
//% blockId=screen_print block="print %text| at x: %x| y: %y"
//% weight=99 group="Screen" inlineInputMode="inline" blockGap=8
//% x.min=0 x.max=178 y.min=0 y.max=128
//% blockId=screen_print block="print %text| at line %line"
//% weight=98 group="Screen" inlineInputMode="inline" blockGap=8
//% line.min=0 line.max=9
export function printLine(text: string, line: number) {
const NUM_LINES = 9;
const offset = 5;
const y = offset + (Math.clamp(0, NUM_LINES, line) / (NUM_LINES + 2)) * DAL.LCD_HEIGHT;
brick.print(text, offset, y);
}
export function print(text: string, x: number, y: number, mode = Draw.Normal) {
x |= 0
y |= 0
@ -140,7 +137,7 @@ namespace brick {
* @param image image to draw
*/
//% blockId=screen_show_image block="show image %image=screen_image_picker"
//% weight=95 group="Screen" blockGap=8
//% weight=100 group="Screen" blockGap=8
export function showImage(image: Image, delay: number = 400) {
if (!image) return;
image.draw(0, 0, Draw.Normal);
@ -158,7 +155,7 @@ namespace brick {
//% image.fieldOptions.columns=6
//% image.fieldOptions.hasSearchBar=true
//% group="Screen" weight=0 blockHidden=1
export function _imagePicker(image: Image): Image {
export function __imagePicker(image: Image): Image {
return image;
}
@ -166,7 +163,7 @@ namespace brick {
* Clears the screen
*/
//% blockId=screen_clear_screen block="clear screen"
//% weight=94 group="Screen" blockGap=8
//% weight=90 group="Screen"
export function clearScreen() {
screen.clear();
}
@ -221,10 +218,14 @@ namespace brick {
// motors
const datas = motors.getAllMotorData();
for(let i = 0; i < datas.length; ++i) {
const x = i * 52;
const data = datas[i];
if (!data.actualSpeed && !data.count) continue;
const x = i * 52;
print(`${data.actualSpeed}%`, x, brick.LINE_HEIGHT)
print(`${data.count}>`, x, 2 * brick.LINE_HEIGHT)
console.logValue(`speed.` + "ABCD"[i], data.actualSpeed);
console.logValue(`angle.` + "ABCD"[i], data.count);
}
// sensors
@ -232,7 +233,10 @@ namespace brick {
for(let i =0; i < sis.length; ++i) {
const si = sis[i];
const x = (si.port() - 1) * 52;
print(`${si._query()}`, x, 9 * brick.LINE_HEIGHT)
const v = si._query();
print(`${v}`, x, 9 * brick.LINE_HEIGHT)
console.logValue(`sensor.` + si.port(), v);
}
}
}

View File

@ -1,30 +1,30 @@
//% color="#68C3E2" weight=100
//% color="#68C3E2" weight=100 icon="\uf106"
//% groups='["Buttons", "Screen"]'
//% labelLineWidth=0
namespace brick {
}
//% color="#C8509B" weight=95 icon="\uf192"
//% color="#C8509B" weight=95 icon="\uf10f"
//% labelLineWidth=0
//% groups='["Ultrasonic Sensor", "Touch Sensor", "Color Sensor", "Infrared Sensor", "Remote Infrared Beacon", "Gyro Sensor"]'
//% groupIcons='["\uf101","\uf103","\uf102","","","\uf104"]'
namespace sensors {
}
//% color="#A5CA18" weight=90 icon="\uf185"
//% color="#A5CA18" weight=90 icon="\uf10d"
//% groups='["Motion", "Sensors", "Chassis"]'
//% labelLineWidth=0
namespace motors {
}
//% color="#D67923" weight=80
//% color="#D67923" weight=80 icon="\uf10e"
namespace music {
}
//% color="#5F3109"
//% color="#5F3109" icon="\uf107"
namespace control {
}

View File

@ -112,7 +112,7 @@ namespace sensors {
//% blockId=remotebuttonWasPressed
//% parts="remote"
//% blockNamespace=sensors
//% weight=80 blockGap=8
//% weight=80
//% group="Remote Infrared Beacon"
wasPressed() {
return this.button.wasPressed();
@ -238,7 +238,7 @@ namespace sensors {
//% blockId=infraredGetRemoteCommand
//% parts="infrared"
//% blockNamespace=sensors
//% weight=65 blockGap=8
//% weight=65
//% group="Infrared Sensor"
remoteCommand(): number {
this._setMode(IrSensorMode.RemoteControl)

View File

@ -2,8 +2,6 @@
"Sound.buffer": "Returns the underlaying Buffer object.",
"Sound.play": "Play sound.",
"music": "Generation of music tones.",
"music._soundPicker": "A sound",
"music._soundPicker|param|sound": "the sound",
"music.beat": "Return the duration of a beat in milliseconds (the beat fraction).",
"music.beat|param|fraction": "the fraction of the current whole note, eg: BeatFraction.Half",
"music.changeTempoBy": "Change the tempo up or down by some amount of beats per minute (bpm).",

View File

@ -20,7 +20,6 @@
"Note.GSharp|block": "G#",
"SoundOutputDestination.Pin|block": "pin",
"SoundOutputDestination.Speaker|block": "speaker",
"music._soundPicker|block": "%sound",
"music.beat|block": "%fraction|beat",
"music.changeTempoBy|block": "change tempo by %value|(bpm)",
"music.noteFrequency|block": "%note",

View File

@ -170,7 +170,7 @@ void playTone(int frequency, int ms) {
//% blockId=music_stop_all_sounds block="stop all sounds"
//% parts="headphone"
//% blockNamespace=music
//% weight=76 blockGap=8
//% weight=97
void stopAllSounds() {
if (currentSample) {
samplePtr = currentSample->length;

View File

@ -32,7 +32,7 @@ declare namespace music {
//% blockId=music_stop_all_sounds block="stop all sounds"
//% parts="headphone"
//% blockNamespace=music
//% weight=76 blockGap=8 shim=music::stopAllSounds
//% weight=97 shim=music::stopAllSounds
function stopAllSounds(): void;
/** Makes a sound bound to a buffer in WAV format. */

View File

@ -264,7 +264,7 @@ namespace music {
* @param sound the sound to play
*/
//% blockId=music_play_sound_effect_until_done block="play sound effect %sound|until done"
//% weight=98
//% weight=98 blockGap=8
export function playSoundEffectUntilDone(sound: Sound) {
if (!sound) return;
sound.play();
@ -276,7 +276,7 @@ namespace music {
*/
//% blockId=music_sound_picker block="%sound" shim=TD_ID
//% weight=0 blockHidden=1
export function _soundPicker(sound: Sound): Sound {
export function __soundPicker(sound: Sound): Sound {
return sound;
}
@ -285,7 +285,7 @@ namespace music {
* @param sound the sound to play
*/
//% blockId=music_play_sound_effect block="play sound effect %sound"
//% weight=99
//% weight=99 blockGap=8
export function playSoundEffect(sound: Sound) {
if (!sound || numSoundsPlaying >= soundsLimit) return;
numSoundsPlaying++;

View File

@ -78,7 +78,7 @@ namespace sensors {
//% parts="touch"
//% blockNamespace=sensors
//% sensor.fieldEditor="ports"
//% weight=81 blockGap=8
//% weight=81
//% group="Touch Sensor"
isPressed() {
return this.button.isPressed();

View File

@ -78,7 +78,7 @@ namespace sensors {
//% parts="ultrasonicsensor"
//% blockNamespace=sensors
//% sensor.fieldEditor="ports"
//% weight=65 blockGap=8
//% weight=65
//% group="Ultrasonic Sensor"
distance(): number {
// it supposedly also has an inch mode, but we stick to cm

4683
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "pxt-ev3",
"version": "0.0.45",
"version": "0.0.49",
"description": "LEGO Mindstorms EV3 for Microsoft MakeCode",
"private": true,
"keywords": [
@ -45,7 +45,7 @@
},
"dependencies": {
"pxt-common-packages": "0.14.13",
"pxt-core": "3.0.2"
"pxt-core": "3.0.5"
},
"scripts": {
"test": "node node_modules/pxt-core/built/pxt.js travis"

View File

@ -137,6 +137,15 @@
"functions": "#19325A",
"arrays": "#901F76"
},
"blockIcons": {
"loops": "\uf10b",
"logic": "\uf10a",
"math": "\uf10c",
"variables": "\uf111",
"text": "\uf110",
"functions": "\uf108",
"arrays": "\uf109"
},
"monacoColors": {
"editor.background": "#ecf6ff"
}

View File

@ -115,14 +115,29 @@ namespace pxsim {
return this.brickNode;
}
motorUsed(port:number, large: boolean) {
for(let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
const p = 1 << i;
if (port & p) {
const motorPort = this.motorMap[p];
if (!this.outputNodes[motorPort])
this.outputNodes[motorPort] = new MotorNode(motorPort, large);
}
}
}
getMotor(port: number, large?: boolean): MotorNode[] {
if (port == 0xFF) return this.getMotors(); // Return all motors
const motorPort = this.motorMap[port];
if (this.outputNodes[motorPort] == undefined) {
this.outputNodes[motorPort] = large ?
new LargeMotorNode(motorPort) : new MediumMotorNode(motorPort);
const r = [];
for(let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
const p = 1 << i;
if (port & p) {
const motorPort = this.motorMap[p];
const outputNode = this.outputNodes[motorPort];
if (outputNode)
r.push(outputNode);
}
}
return [this.outputNodes[motorPort]];
return r;
}
getMotors() {
@ -130,7 +145,7 @@ namespace pxsim {
}
getSensor(port: number, type: number): SensorNode {
if (this.inputNodes[port] == undefined) {
if (!this.inputNodes[port]) {
switch (type) {
case DAL.DEVICE_TYPE_GYRO: this.inputNodes[port] = new GyroSensorNode(port); break;
case DAL.DEVICE_TYPE_COLOR: this.inputNodes[port] = new ColorSensorNode(port); break;

View File

@ -3,12 +3,13 @@
namespace pxsim {
export enum ColorSensorMode {
None = -1,
Reflected = 0,
Ambient = 1,
Colors = 2,
RefRaw = 3,
RgbRaw = 4,
ColorCal = 5
ColorCal = 5,
}
export enum ThresholdState {
@ -24,6 +25,7 @@ namespace pxsim {
constructor(port: number) {
super(port);
this.mode = -1;
}
getDeviceType() {

View File

@ -81,7 +81,6 @@ namespace pxsim.control {
export function dmesg(s: string) {
console.log("DMESG: " + s)
}
}
namespace pxsim.output {

View File

@ -2,8 +2,8 @@
namespace pxsim.motors {
export function __motorUsed(port: number, large: boolean) {
console.log("MOTOR INIT " + port);
const motors = ev3board().getMotor(port, large);
//console.log("MOTOR INIT " + port);
ev3board().motorUsed(port, large);
runtime.queueDisplayUpdate();
}
}
@ -11,7 +11,7 @@ namespace pxsim.motors {
namespace pxsim.sensors {
export function __sensorUsed(port: number, type: number) {
console.log("SENSOR INIT " + port + ", type: " + type);
//console.log("SENSOR INIT " + port + ", type: " + type);
const sensor = ev3board().getSensor(port, type);
runtime.queueDisplayUpdate();
}

View File

@ -19,8 +19,8 @@ namespace pxsim {
// console.log("motor before read");
for (let port = 0; port < DAL.NUM_OUTPUTS; ++port) {
const output = outputs[port];
const speed = output ? Math.round(outputs[port].getSpeed()) : 0;
const angle = output ? Math.round(outputs[port].getAngle()) : 0;
const speed = output ? outputs[port].getSpeed() : 0;
const angle = output ? outputs[port].getAngle() : 0;
const tci = MotorDataOff.TachoCounts + port * MotorDataOff.Size;
const tsi = MotorDataOff.TachoSensor + port * MotorDataOff.Size;
data[tci] = data[tci + 1] = data[tci + 2] = data[tci + 3] = 0; // Tacho count

182
sim/state/motornode.ts Normal file
View File

@ -0,0 +1,182 @@
namespace pxsim {
export class MotorNode extends BaseNode {
isOutput = true;
private rotationsPerMilliSecond: number;
// current state
private angle: number = 0;
private tacho: number = 0;
private speed: number = 0;
private polarity: number = 1; // -1, 1 or -1
private started: boolean;
private speedCmd: DAL;
private speedCmdValues: number[];
private speedCmdTacho: number;
private speedCmdTime: number;
private _synchedMotor: MotorNode; // non-null if master motor
constructor(port: number, large: boolean) {
super(port);
this.setLarge(large);
}
getSpeed() {
return this.speed * (this.polarity == 0 ? -1 : 1);
}
getAngle() {
return this.angle;
}
// returns the slave motor if any
getSynchedMotor() {
return this._synchedMotor;
}
setSpeedCmd(cmd: DAL, values: number[]) {
this.speedCmd = cmd;
this.speedCmdValues = values;
this.speedCmdTacho = this.angle;
this.speedCmdTime = pxsim.U.now();
delete this._synchedMotor;
}
setSyncCmd(motor: MotorNode, cmd: DAL, values: number[]) {
this.setSpeedCmd(cmd, values);
this._synchedMotor = motor;
}
clearSpeedCmd() {
delete this.speedCmd;
delete this._synchedMotor;
}
setLarge(large: boolean) {
this.id = large ? NodeType.LargeMotor : NodeType.MediumMotor;
// large 170 rpm (https://education.lego.com/en-us/products/ev3-large-servo-motor/45502)
this.rotationsPerMilliSecond = (large ? 170 : 250) / 60000;
}
setPolarity(polarity: number) {
// Either 1 or 255 (reverse)
/*
-1 : Motor will run backward
0 : Motor will run opposite direction
1 : Motor will run forward
*/
this.polarity = polarity;
}
reset() {
// not sure what reset does...
}
clearCount() {
this.tacho = 0;
this.angle = 0;
}
stop() {
this.started = false;
this.clearSpeedCmd();
}
start() {
this.started = true;
}
updateState(elapsed: number) {
console.log(`motor: ${elapsed}ms - ${this.speed}% - ${this.angle}> - ${this.tacho}|`)
const interval = Math.min(20, elapsed);
let t = 0;
while (t < elapsed) {
let dt = interval;
if (t + dt > elapsed) dt = elapsed - t;
this.updateStateStep(dt);
t += dt;
}
}
private updateStateStep(elapsed: number) {
// compute new speed
switch (this.speedCmd) {
case DAL.opOutputSpeed:
case DAL.opOutputPower:
// assume power == speed
// TODO: PID
this.speed = this.speedCmdValues[0];
break;
case DAL.opOutputTimeSpeed:
case DAL.opOutputTimePower:
case DAL.opOutputStepPower:
case DAL.opOutputStepSpeed: {
// ramp up, run, ramp down, <brake> using time
const speed = this.speedCmdValues[0];
const step1 = this.speedCmdValues[1];
const step2 = this.speedCmdValues[2];
const step3 = this.speedCmdValues[3];
const brake = this.speedCmdValues[4];
const dstep = (this.speedCmd == DAL.opOutputTimePower || this.speedCmd == DAL.opOutputTimeSpeed)
? pxsim.U.now() - this.speedCmdTime
: this.tacho - this.speedCmdTacho;
if (dstep < step1) // rampup
this.speed = speed * dstep / step1;
else if (dstep < step1 + step2) // run
this.speed = speed;
else if (dstep < step1 + step2 + step3)
this.speed = speed * (step1 + step2 + step3 - dstep) / (step1 + step2 + step3);
else {
if (brake) this.speed = 0;
this.clearSpeedCmd();
}
break;
}
case DAL.opOutputStepSync:
case DAL.opOutputTimeSync: {
if (!this._synchedMotor) // handled in other motor code
break;
const otherMotor = this._synchedMotor;
const speed = this.speedCmdValues[0];
const turnRatio = this.speedCmdValues[1];
const stepsOrTime = this.speedCmdValues[2];
const brake = this.speedCmdValues[3];
const dstep = this.speedCmd == DAL.opOutputTimeSync
? pxsim.U.now() - this.speedCmdTime
: this.tacho - this.speedCmdTacho;
// 0 is special case, run infinite
if (!stepsOrTime || dstep < stepsOrTime)
this.speed = speed;
else {
if (brake) this.speed = 0;
this.clearSpeedCmd();
}
// send synched motor state
otherMotor.speed = Math.floor(this.speed * turnRatio / 100);
if (!this._synchedMotor)
otherMotor.clearSpeedCmd();
break;
}
}
this.speed = Math.round(this.speed); // integer only
// compute delta angle
const rotations = this.getSpeed() / 100 * this.rotationsPerMilliSecond * elapsed;
const deltaAngle = Math.round(rotations * 360);
if (deltaAngle) {
this.angle += deltaAngle;
this.tacho += Math.abs(deltaAngle);
this.setChangedState();
}
// if the motor was stopped or there are no speed commands,
// let it coast to speed 0
if (this.speed && !(this.started || this.speedCmd)) {
// decay speed 5% per tick
this.speed = Math.round(Math.max(0, Math.abs(this.speed) - 10) * Math.sign(this.speed));
}
}
}
}

View File

@ -1,88 +0,0 @@
namespace pxsim {
export abstract class MotorNode extends BaseNode {
isOutput = true;
protected angle: number = 0;
private rotationsPerMilliSecond: number;
private speed: number;
private large: boolean;
private rotation: number;
private polarity: boolean;
constructor(port: number, rpm: number) {
super(port);
this.rotationsPerMilliSecond = rpm / 60000;
}
setSpeed(speed: number) {
if (this.speed != speed) {
this.speed = speed;
this.changed = true;
this.setChangedState();
}
}
setLarge(large: boolean) {
this.large = large;
}
getSpeed() {
return this.speed;
}
stepSpeed(speed: number, angle: number, brake: boolean) {
// TODO: implement
}
setPolarity(polarity: number) {
// Either 1 or 255 (reverse)
this.polarity = polarity === 255;
// TODO: implement
}
reset() {
// TODO: implement
}
stop() {
// TODO: implement
this.setSpeed(0);
}
start() {
// TODO: implement
this.setChangedState();
}
public getAngle() {
return this.angle;
}
updateState(elapsed: number) {
const rotations = this.getSpeed() / 100 * this.rotationsPerMilliSecond * elapsed;
const angle = rotations * 360;
if (angle) {
this.angle += angle;
this.setChangedState();
}
}
}
export class MediumMotorNode extends MotorNode {
id = NodeType.MediumMotor;
constructor(port: number) {
super(port, 250);
}
}
export class LargeMotorNode extends MotorNode {
id = NodeType.LargeMotor;
constructor(port: number) {
super(port, 170);
}
}
}

View File

@ -34,24 +34,51 @@ namespace pxsim {
motors.forEach(motor => motor.reset());
return 2;
}
case DAL.opOutputStepSpeed: {
case DAL.opOutputClearCount:
const port = buf.data[1];
const motors = ev3board().getMotor(port);
motors.forEach(motor => motor.clearCount());
break;
case DAL.opOutputStepPower:
case DAL.opOutputStepSpeed:
case DAL.opOutputTimePower:
case DAL.opOutputTimeSpeed: {
// step speed
const port = buf.data[1];
const speed = buf.data[2] << 24 >> 24; // signed byte
// note that b[3] is padding
const step1 = buf.data[4];
const step2 = buf.data[5]; // angle
const step3 = buf.data[6];
const brake = buf.data[7];
const speed = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2); // signed byte
// note that b[3] is padding
const step1 = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int32LE, 4);
const step2 = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int32LE, 8);
const step3 = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int32LE, 12);
const brake = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 16);
//console.log(buf);
const motors = ev3board().getMotor(port);
motors.forEach(motor => motor.stepSpeed(speed, step2, brake === 1));
motors.forEach(motor => motor.setSpeedCmd(cmd, [speed, step1, step2, step3, brake]));
return 2;
}
case DAL.opOutputStepSync:
case DAL.opOutputTimeSync: {
const port = buf.data[1];
const speed = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2); // signed byte
// note that b[3] is padding
const turnRatio = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int16LE, 4);
// b[6], b[7] is padding
const stepsOrTime = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int32LE, 8);
const brake = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 12);
const motors = ev3board().getMotor(port);
for (const motor of motors) {
const otherMotor = motors.filter(m => m.port != motor.port)[0];
motor.setSyncCmd(
motor.port < otherMotor.port ? otherMotor : undefined,
cmd, [speed, turnRatio, stepsOrTime, brake]);
}
return 2;
}
case DAL.opOutputStop: {
// stop
const port = buf.data[1];
const brake = buf.data[2];
const brake = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2);
const motors = ev3board().getMotor(port);
motors.forEach(motor => motor.stop());
return 2;
@ -59,9 +86,9 @@ namespace pxsim {
case DAL.opOutputSpeed: {
// setSpeed
const port = buf.data[1];
const speed = buf.data[2] << 24 >> 24; // signed byte
const speed = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2);
const motors = ev3board().getMotor(port);
motors.forEach(motor => motor.setSpeed(speed));
motors.forEach(motor => motor.setSpeedCmd(cmd, [speed]));
return 2;
}
case DAL.opOutputStart: {
@ -74,7 +101,7 @@ namespace pxsim {
case DAL.opOutputPolarity: {
// reverse
const port = buf.data[1];
const polarity = buf.data[2];
const polarity = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2);
const motors = ev3board().getMotor(port);
motors.forEach(motor => motor.setPolarity(polarity));
return 2;
@ -86,6 +113,9 @@ namespace pxsim {
motors.forEach(motor => motor.setLarge(large));
return 2;
}
default:
console.warn('unknown cmd: ' + cmd);
break;
}
console.log("pwm write");

View File

@ -5,6 +5,7 @@ namespace pxsim {
protected mode: number;
protected valueChanged: boolean;
protected modeChanged: boolean;
constructor(port: number) {
super(port);
@ -24,6 +25,8 @@ namespace pxsim {
setMode(mode: number) {
this.mode = mode;
this.changed = true;
this.modeChanged = true;
}
getMode() {
@ -44,6 +47,12 @@ namespace pxsim {
return res;
}
modeChange() {
const res = this.modeChanged;
this.modeChanged = false;
return res;
}
setChangedState() {
this.changed = true;
this.valueChanged = false;

View File

@ -1,69 +1,87 @@
<svg id="e13b39e7-895d-4931-9be9-7aecaf709784" data-name="46d2506d-be16-4175-90b0-aabf357ea333" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 79.56 153.61">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 82 156">
<defs>
<clipPath id="7dd75c25-af24-4f64-9ea1-f270fbd17872">
<path d="M12.82.54a17.07,17.07,0,0,1,20.77,12.3,1.53,1.53,0,0,1,1.6-.24l.21.19,10.41,10.1c.31.3.47.3.47,1.14V35.81h6.79a4,4,0,0,1,4,4V65.63a4,4,0,0,1-4,4H46.15v11.8l13.68-.1h.61s7.76,9.81,18.12,23.87v29.64h0a5.78,5.78,0,0,1-5.78,5.78H69.17v7.57A4,4,0,0,1,67,151.75V153h0a.63.63,0,0,1-.61.61H40.08a.6.6,0,0,1-.64-.56V152a4,4,0,0,1-2.89-3.85v-7.57H30.07a5.78,5.78,0,0,1-5.78-5.78v-8.18h-6.8a4,4,0,0,1-4-4V96.84a4,4,0,0,1,4-4h6.8V92l.75-.78v-10L14.13,70.71c-.25-.27-.39-.25-.39-.67V34.27l.37-.39A17.06,17.06,0,0,1,12.82.54Z" style="fill: none"/>
<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="9d9a0722-eca6-4c98-bf03-49097e654f0e">
<path d="M30.07,140.62a5.78,5.78,0,0,1-5.78-5.78V92l9.26-9.58a2.29,2.29,0,0,1,2.38-1c4.4,0,23.86-.15,23.86-.15h.65s7.76,9.8,18.12,23.87v29.64h0a5.78,5.78,0,0,1-5.78,5.78Z" style="fill: none"/>
<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="0f29df77-bfe3-4749-8432-7a5b3681f927">
<path d="M35.85,135.26a5.78,5.78,0,0,1-5.78-5.78h0V92.6h0a5.78,5.78,0,0,1,5.77-5.79H57.17S64.08,96,72.73,107.22v22.25h0A5.78,5.78,0,0,1,67,135.26H35.85Z" style="fill: none"/>
<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>
<g style="clip-path: url(#7dd75c25-af24-4f64-9ea1-f270fbd17872)">
<g>
<path id="1614620b-40ec-4523-b90a-428aad6bd045" data-name="eadcf40d-5b1f-4f82-8d01-d628e9e4bcbb" d="M40.49,64.16V41.26A5.48,5.48,0,0,1,46,35.8h5.62A5.48,5.48,0,0,1,57,41.26v22.9h0a5.45,5.45,0,0,1-5.46,5.46H46A5.45,5.45,0,0,1,40.49,64.16Z" style="fill: #a8a9a8"/>
<circle id="1a43435f-56ec-4b4e-a3ae-b40d13b2f218" data-name="93612c19-30fe-4c1d-bb05-67002522431d" cx="51.72" cy="64.32" r="3.79" style="fill: #fff"/>
<circle id="43fd443a-13b5-48ef-af02-32d5de3e95b1" data-name="aee14a95-6af8-4dce-8543-2eda3545de29" cx="51.72" cy="41.11" r="3.79" style="fill: #fff"/>
<path id="7bfb4e09-fb97-433a-8104-a0426c319fe6" data-name="1d2e9494-7cc7-48f0-9562-12d1d83b7bb0" d="M39.44,153v-5.29a.61.61,0,0,1,.61-.61H66.34a.61.61,0,0,1,.61.61h0V153h0a.63.63,0,0,1-.61.61H40.08a.61.61,0,0,1-.64-.58Z" style="fill: #a8a9a8"/>
<path id="ded8d34f-3eb8-4d18-bbd7-80e03d734fef" data-name="ccd9d8b0-00ff-4f0b-bfdc-94153d199419" d="M36.58,151.58V136.89a.61.61,0,0,1,.61-.61H68.51a.61.61,0,0,1,.61.61h0v14.69a.61.61,0,0,1-.61.61H37.19a.61.61,0,0,1-.61-.61Z" style="fill: #a8a9a8"/>
<path id="a30c6f9d-adb5-4251-ad04-1bd8bfaab7af" data-name="e8b462c5-81f0-4111-9486-bb5fc1221c77" d="M55.44,59.6V57.8c0-.87-.81-.46-.81-.46l-1.19.59c-.38.18-.33-.34-.33-.34V55c0-.72.82-.77.82-.77h1.25s.26-.2.26-1.38-.29-1.32-.29-1.32H53.9a.68.68,0,0,1-.66-.65v-1.3a3.57,3.57,0,0,0-1.4-.31c-1-.05-1.17.31-1.17.31v1.3c0,.67-.73.65-.73.65H48.56s-.3.18-.3,1.32.3,1.38.3,1.38h1.38a.73.73,0,0,1,.73.77v2.62c0,.52-.36.34-.36.34l-1-.59c-.68-.38-1.23,0-1.23.46v1.8s0,1,1.23.1a5.08,5.08,0,0,1,3-.7,4.18,4.18,0,0,1,2.35.7C55.37,60.14,55.44,59.6,55.44,59.6Z" style="fill: #fff"/>
<path id="c7805530-90df-4e25-868f-c9475cacc294" data-name="51a46c0a-a8a3-4420-b297-1d82512a0b32" d="M47.79,46.14c0-.8,1.2-.56,1.2-.56a7,7,0,0,0,2.85.84,5.72,5.72,0,0,0,2.76-.84.85.85,0,0,1,.31-.09.71.71,0,0,1,.76.65V47.9s-.24,1-1.07.6a5,5,0,0,0-2.76-.77A6.46,6.46,0,0,0,49,48.5a.68.68,0,0,1-.24.08.83.83,0,0,1-1-.61s0,0,0-.07S47.76,46.94,47.79,46.14Z" style="fill: #fff"/>
<path id="f8fcbff1-7e8c-4c85-8f0e-222f81e36654" data-name="be4fbc2c-74e0-495a-bfad-cf557a83a287" d="M13.75,70V34.27L33.21,13.56c0-.84,1.4-1.36,2-1l.21.19,10.42,10.1c.31.3.46.3.46,1.14l-.19,59-18.57.67-13.4-13C13.89,70.44,13.75,70.46,13.75,70Z" style="fill: #a8a9a8"/>
<path id="1dc809f3-4ab0-4e83-b8a0-ab178c9c843d" data-name="4d02192d-b81d-48fe-8732-1ddf5bded46b" d="M35.44,82.8l10.67-.57v-8l-4.43-4.7H30.05a1.6,1.6,0,0,0-1.16.4L25.34,73.6c-.28.27-.3,1.12-.3,1.12V92Z" style="fill: #a8a9a8"/>
<g id="e0794b99-de5a-4337-b43b-7cdb158e4272" data-name="233cb9b7-9706-41a9-a0a4-7b51b61b2ff5">
<path id="c86708aa-fcc1-4e15-8d85-6e5415398b0c" data-name="6ed465b7-465a-4389-8ebc-d8f92a4226dd" d="M13.49,121.2V98.29A5.46,5.46,0,0,1,19,92.84h5.62A5.45,5.45,0,0,1,30,98.3v22.9h0a5.48,5.48,0,0,1-5.46,5.46H19A5.48,5.48,0,0,1,13.49,121.2Z" style="fill: #a8a9a8"/>
<circle id="0355a228-ed20-4633-ba10-c36cf551e228" data-name="955ad5d6-af09-42ad-8d56-9ff62c40912d" cx="18.35" cy="121.35" r="3.79" style="fill: #fff"/>
<circle id="73922eab-afce-48dd-9bae-80da92a8b392" data-name="75a0ff09-d40c-46e3-aaf0-c5878f2efdac" cx="18.35" cy="98.14" r="3.79" style="fill: #fff"/>
<path id="e9f7b6a6-dcdd-4d55-a7bb-ad3951bb1e39" data-name="eeb5a6b6-ef4a-4f05-95cd-8b1c3eb419c4" d="M22.07,116.64v-1.8c0-.86-.81-.46-.81-.46L20,115c-.38.18-.33-.34-.33-.34V112c0-.72.82-.76.82-.76h1.25s.32-.26.29-1.39-.29-1.32-.29-1.32H20.53a.67.67,0,0,1-.66-.65v-1.3a3.57,3.57,0,0,0-1.4-.31c-1,0-1.17.31-1.17.31v1.3c0,.67-.73.65-.73.65H15.19s-.3.18-.3,1.32.3,1.39.3,1.39h1.38a.71.71,0,0,1,.73.69v2.69c0,.52-.36.34-.36.34l-1-.58c-.68-.39-1.23,0-1.23.46v1.8s0,1,1.23.1a5.09,5.09,0,0,1,3-.71,4.16,4.16,0,0,1,2.35.71C22,117.17,22.07,116.64,22.07,116.64Z" style="fill: #fff"/>
<path id="82138da6-9b2a-4b9a-952e-568841e5ed52" data-name="80481c02-bb01-43aa-bd64-15ab30fbbb5e" d="M14.44,103.18c0-.8,1.2-.56,1.2-.56a7,7,0,0,0,2.85.83,5.78,5.78,0,0,0,2.77-.83.7.7,0,0,1,1,.25.67.67,0,0,1,.1.31v1.76s-.24,1-1.07.59a5,5,0,0,0-2.77-.77,6.59,6.59,0,0,0-2.85.77.68.68,0,0,1-.24.08.83.83,0,0,1-1-.63v0S14.44,104,14.44,103.18Z" style="fill: #fff"/>
</g>
<path id="aa62b88a-4cd5-4c76-acaf-e85a7fd45341" data-name="6b63d025-68d6-47eb-ba62-60017f4a1dd4" d="M30.07,140.62a5.78,5.78,0,0,1-5.78-5.78h0V92l9.26-9.57a2.29,2.29,0,0,1,2.38-1c4.4,0,23.87-.14,23.87-.14h.64s7.76,9.8,18.13,23.86v29.64h0a5.79,5.79,0,0,1-5.79,5.79Z" style="fill: #a8a9a8"/>
<g>
<g id="1172473e-5b0c-4dd6-85c5-28f5593b9312" data-name="a0498222-7e69-48db-90b7-05f2ce124a03">
<g style="clip-path: url(#9d9a0722-eca6-4c98-bf03-49097e654f0e)">
<g id="da9d77a3-c9b0-4118-a8e3-c65ec5cbe7d4" data-name="8270fb93-0862-4480-a5b8-675cc77ac153">
<path id="77253f44-139e-4b90-82df-465a787cab9c" data-name="bb0a4ec3-45a5-4c91-b064-db5494e447e6" d="M78.56,142.76l1-7.69V103.85L66.49,87.72v14.86L42.7,133.66,35.55,141Z" style="fill: #f2f2f2"/>
</g>
<g style="isolation: isolate">
<g id="e13b39e7-895d-4931-9be9-7aecaf709784">
<g style="clip-path: url(#clip-path)">
<g id="Large_Motor" data-name="Large Motor">
<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>
<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 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>
<path id="9d05c10c-72eb-4f9f-8517-e403ec636357" data-name="74e07bdd-431b-40c1-b0f3-71128f2a0c08" d="M35.85,135.56a5.78,5.78,0,0,1-5.78-5.78h0V92.9h0a5.78,5.78,0,0,1,5.77-5.79H57.17s6.91,9.15,15.56,20.41v22.25h0A5.78,5.78,0,0,1,67,135.56H35.85Z" style="fill: #a8a9a8"/>
<g id="6df8eb1f-3187-427f-8d99-bc7a37e6cc25" data-name="9bbfb3ec-86c2-4d27-8275-76f2f9737a7f">
<g id="e4d7143c-1fb6-45a4-a205-1c920b8a823c" data-name="7e017c33-f09b-4d39-803f-1bedf1ebf566">
<g id="3a4e493d-cd17-48c4-97b6-da7ee3c4898e" data-name="69e3df75-72a6-4499-baab-f65ec194e193">
<g style="clip-path: url(#0f29df77-bfe3-4749-8432-7a5b3681f927)">
<g id="7cada08f-1e90-4ef2-8ae4-3f2adfd3e953" data-name="b7007e32-15c9-40b3-a885-a7231fd104d1">
<path id="02e64b51-bd56-4079-9736-8a269cb37029" data-name="c599a4f4-ae5d-411c-902d-dbcde04a2d6e" d="M60.44,112a1.09,1.09,0,0,1,2.18-.14,1.34,1.34,0,0,1,0,.2V139.6a1.08,1.08,0,0,1-1.11,1.05h0a1.07,1.07,0,0,1-1-1.11V112Zm-3.62,0a1.1,1.1,0,0,1,1.12-1.06,1.08,1.08,0,0,1,1,1.12V139.6a1.09,1.09,0,0,1-2.17-.06V112Zm-3.61,0a1.09,1.09,0,1,1,2.18-.14,1.34,1.34,0,0,1,0,.2V139.6a1.08,1.08,0,0,1-1.11,1.05h0a1.07,1.07,0,0,1-1-1.11V112Zm-3.62,0a1.1,1.1,0,0,1,1.12-1.06,1.08,1.08,0,0,1,1,1.12V139.6a1.09,1.09,0,0,1-2.17-.06V112ZM46,112a1.09,1.09,0,0,1,2.18-.14,1.34,1.34,0,0,1,0,.2V139.6A1.08,1.08,0,0,1,47,140.65h0a1.07,1.07,0,0,1-1-1.11V112Z" style="fill: #6a6a6a"/>
<g id="LM_rightside" data-name="LM rightside">
<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" data-name="LM rightside4" cx="28.3" cy="66.21" r="3.79" style="fill: #fff"/>
<circle id="LM_rightside3" data-name="LM rightside3" cx="28.3" cy="43" r="3.79" style="fill: #fff"/>
<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 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>
<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 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>
<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 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 id="LM_leftside" data-name="LM leftside">
<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" data-name="LM leftside4" cx="61.67" cy="123.24" r="3.79" style="fill: #fff"/>
<circle id="LM_leftside3" data-name="LM leftside3" cx="61.67" cy="100.03" r="3.79" style="fill: #fff"/>
<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 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>
<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 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 id="LM_total" data-name="LM total">
<g id="LM_whitepart" data-name="LM whitepart">
<g style="clip-path: url(#clip-path-2)">
<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>
<circle id="a5a29926-0401-43af-b098-0c7439485e7c" data-name="bcdc8e69-90f7-4365-8f7a-7c1567704161" cx="29.69" cy="135.22" r="2.24" style="fill: #9a9a9a"/>
<circle id="313e9fdc-7bbb-4d49-9d19-2415450fb691" data-name="b7785d8e-a2e4-41a7-9c34-4d9f6aebd906" cx="58.36" cy="84.71" r="2.24" style="fill: #9a9a9a"/>
<g id="1eb2ae58-2419-47d4-86bf-4f26a7f0cf61" data-name="KNOB">
<g id="26377a78-5df7-4bea-8daa-669ea612118c" data-name="5301e639-3e28-489d-96ec-91bda6d459b7">
<circle id="13e05316-9dcc-4be0-9e0e-4b1df48fad92" data-name="f1bc8b30-bdb2-4084-8c02-e322d1c0b9bf" cx="17.06" cy="17.06" r="17.06" style="fill: #b72b1c"/>
<g>
<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 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>
<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_1" data-name="LM detail 1" cx="21.66" cy="86.59" r="2.24" style="fill: #9a9a9a"/>
<g id="hole">
<g>
<circle id="58277aee-b73f-4f42-94ef-3b959dc26807" data-name="ce4b2c57-9b3b-4aed-902e-31d9f366dc61" cx="20.12" cy="28.12" r="3.79" style="fill: #3c3c3c"/>
<circle id="980a54d2-804e-408d-8655-debf2e5856d0" data-name="6a44a65a-f04b-4564-81a2-4eefa438c5f1" cx="28.27" cy="14" r="3.79" style="fill: #3c3c3c"/>
<circle id="9b2e3cd0-e4bd-42ce-b558-4f4bc46eaf23" data-name="d5fea8d1-47c1-448e-adb6-8519e2516216" cx="14.15" cy="5.85" r="3.79" style="fill: #3c3c3c"/>
<circle id="06781f30-70ec-4914-81c3-4083325e7c18" data-name="1faf9727-3903-4be3-a3d3-4ab2d5d92b1f" cx="6" cy="19.97" r="3.79" style="fill: #3c3c3c"/>
<path id="f1de636f-1fd2-4419-ae5c-d6a853c5834d" data-name="9e52c672-4ec8-4d92-9380-e44b4f69f848" d="M13.56,16.89a2.91,2.91,0,0,0,.7,2.26,12,12,0,0,1,1.2-.39c.69-.18.95.59.95.59l.33,1.21s.33.24,1.41-.08,1.2-.62,1.2-.62-.17-.6-.32-1.22a.66.66,0,0,1,.45-.8l1.26-.34a3.63,3.63,0,0,0-.07-1.43c-.19-.93-.6-1.05-.6-1.05l-1.25.34c-.65.17-.82-.54-.82-.54l-.36-1.33s-.25-.24-1.35,0-1.26.64-1.26.64.14.61.35,1.34a.7.7,0,0,1-.48.88l-.07,0Z" style="fill: #242424"/>
<path id="e8012624-d689-4ee7-a77a-99e9713ea199" data-name="3179af54-0c25-42bc-9804-f3575e0b1b0b" d="M17.44,24.25a.47.47,0,0,1-.56-.32l-.55-2.06h0a.45.45,0,0,1,.32-.55h0l1.63-.23,1.44-.6a.47.47,0,0,1,.56.32l.55,2.05h0a.45.45,0,0,1-.32.55h0L18.94,24Z" style="fill: #3c3c3c"/>
<path id="31a64bab-6b92-41d0-afe9-392c1fae8ddb" data-name="841a583e-aa25-4a7e-8907-fbe64ce57066" d="M9.88,17.31a.46.46,0,0,1,.33-.56l2-.55h0a.47.47,0,0,1,.56.33L13,18.16l.6,1.45a.43.43,0,0,1-.3.54h0l-2,.55h0a.46.46,0,0,1-.55-.33l-.57-1.53L9.84,17.3Z" style="fill: #3c3c3c"/>
<path id="2b1c6b9e-6fda-40be-8bb8-318c30b7dca4" data-name="42515acc-688f-41c7-884c-80b8a90e09c0" d="M16.82,9.8a.47.47,0,0,1,.56.32l.55,2.05h0a.46.46,0,0,1-.33.55L16,13l-1.45.61a.45.45,0,0,1-.55-.32h0l-.53-2.1h0a.45.45,0,0,1,.31-.56h0l1.53-.57,1.55-.25Z" style="fill: #3c3c3c"/>
<path id="be04cab5-eaac-4d03-a1ee-dbe70dd5bf90" data-name="8690082b-7091-4631-a199-b79823698dd6" d="M24.33,16.74a.43.43,0,0,1-.3.54h0l-2,.55h0a.46.46,0,0,1-.55-.33l-.22-1.64-.6-1.44a.45.45,0,0,1,.31-.56h0l2-.55h0a.46.46,0,0,1,.56.33l.57,1.53.25,1.55Z" style="fill: #3c3c3c"/>
<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"/>
<circle id="LM_red-2" data-name="LM red-2" cx="62.96" cy="18.95" r="17.06" style="fill: #d42715"/>
</g>
<g id="LM_details_in_red" data-name="LM details in red">
<circle id="LM_detail_red_hole4" data-name="LM detail red hole4" cx="59.9" cy="30.01" r="3.79" style="fill: #393939"/>
<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>

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,70 +1,88 @@
namespace pxsim {
export const LARGE_MOTOR_SVG = `<svg id="e13b39e7-895d-4931-9be9-7aecaf709784" data-name="46d2506d-be16-4175-90b0-aabf357ea333" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 79.56 153.61">
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">
<defs>
<clipPath id="7dd75c25-af24-4f64-9ea1-f270fbd17872">
<path d="M12.82.54a17.07,17.07,0,0,1,20.77,12.3,1.53,1.53,0,0,1,1.6-.24l.21.19,10.41,10.1c.31.3.47.3.47,1.14V35.81h6.79a4,4,0,0,1,4,4V65.63a4,4,0,0,1-4,4H46.15v11.8l13.68-.1h.61s7.76,9.81,18.12,23.87v29.64h0a5.78,5.78,0,0,1-5.78,5.78H69.17v7.57A4,4,0,0,1,67,151.75V153h0a.63.63,0,0,1-.61.61H40.08a.6.6,0,0,1-.64-.56V152a4,4,0,0,1-2.89-3.85v-7.57H30.07a5.78,5.78,0,0,1-5.78-5.78v-8.18h-6.8a4,4,0,0,1-4-4V96.84a4,4,0,0,1,4-4h6.8V92l.75-.78v-10L14.13,70.71c-.25-.27-.39-.25-.39-.67V34.27l.37-.39A17.06,17.06,0,0,1,12.82.54Z" style="fill: none"/>
<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="9d9a0722-eca6-4c98-bf03-49097e654f0e">
<path d="M30.07,140.62a5.78,5.78,0,0,1-5.78-5.78V92l9.26-9.58a2.29,2.29,0,0,1,2.38-1c4.4,0,23.86-.15,23.86-.15h.65s7.76,9.8,18.12,23.87v29.64h0a5.78,5.78,0,0,1-5.78,5.78Z" style="fill: none"/>
<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="0f29df77-bfe3-4749-8432-7a5b3681f927">
<path d="M35.85,135.26a5.78,5.78,0,0,1-5.78-5.78h0V92.6h0a5.78,5.78,0,0,1,5.77-5.79H57.17S64.08,96,72.73,107.22v22.25h0A5.78,5.78,0,0,1,67,135.26H35.85Z" style="fill: none"/>
<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>
<g style="clip-path: url(#7dd75c25-af24-4f64-9ea1-f270fbd17872)">
<g>
<path id="1614620b-40ec-4523-b90a-428aad6bd045" data-name="eadcf40d-5b1f-4f82-8d01-d628e9e4bcbb" d="M40.49,64.16V41.26A5.48,5.48,0,0,1,46,35.8h5.62A5.48,5.48,0,0,1,57,41.26v22.9h0a5.45,5.45,0,0,1-5.46,5.46H46A5.45,5.45,0,0,1,40.49,64.16Z" style="fill: #a8a9a8"/>
<circle id="1a43435f-56ec-4b4e-a3ae-b40d13b2f218" data-name="93612c19-30fe-4c1d-bb05-67002522431d" cx="51.72" cy="64.32" r="3.79" style="fill: #fff"/>
<circle id="43fd443a-13b5-48ef-af02-32d5de3e95b1" data-name="aee14a95-6af8-4dce-8543-2eda3545de29" cx="51.72" cy="41.11" r="3.79" style="fill: #fff"/>
<path id="7bfb4e09-fb97-433a-8104-a0426c319fe6" data-name="1d2e9494-7cc7-48f0-9562-12d1d83b7bb0" d="M39.44,153v-5.29a.61.61,0,0,1,.61-.61H66.34a.61.61,0,0,1,.61.61h0V153h0a.63.63,0,0,1-.61.61H40.08a.61.61,0,0,1-.64-.58Z" style="fill: #a8a9a8"/>
<path id="ded8d34f-3eb8-4d18-bbd7-80e03d734fef" data-name="ccd9d8b0-00ff-4f0b-bfdc-94153d199419" d="M36.58,151.58V136.89a.61.61,0,0,1,.61-.61H68.51a.61.61,0,0,1,.61.61h0v14.69a.61.61,0,0,1-.61.61H37.19a.61.61,0,0,1-.61-.61Z" style="fill: #a8a9a8"/>
<path id="a30c6f9d-adb5-4251-ad04-1bd8bfaab7af" data-name="e8b462c5-81f0-4111-9486-bb5fc1221c77" d="M55.44,59.6V57.8c0-.87-.81-.46-.81-.46l-1.19.59c-.38.18-.33-.34-.33-.34V55c0-.72.82-.77.82-.77h1.25s.26-.2.26-1.38-.29-1.32-.29-1.32H53.9a.68.68,0,0,1-.66-.65v-1.3a3.57,3.57,0,0,0-1.4-.31c-1-.05-1.17.31-1.17.31v1.3c0,.67-.73.65-.73.65H48.56s-.3.18-.3,1.32.3,1.38.3,1.38h1.38a.73.73,0,0,1,.73.77v2.62c0,.52-.36.34-.36.34l-1-.59c-.68-.38-1.23,0-1.23.46v1.8s0,1,1.23.1a5.08,5.08,0,0,1,3-.7,4.18,4.18,0,0,1,2.35.7C55.37,60.14,55.44,59.6,55.44,59.6Z" style="fill: #fff"/>
<path id="c7805530-90df-4e25-868f-c9475cacc294" data-name="51a46c0a-a8a3-4420-b297-1d82512a0b32" d="M47.79,46.14c0-.8,1.2-.56,1.2-.56a7,7,0,0,0,2.85.84,5.72,5.72,0,0,0,2.76-.84.85.85,0,0,1,.31-.09.71.71,0,0,1,.76.65V47.9s-.24,1-1.07.6a5,5,0,0,0-2.76-.77A6.46,6.46,0,0,0,49,48.5a.68.68,0,0,1-.24.08.83.83,0,0,1-1-.61s0,0,0-.07S47.76,46.94,47.79,46.14Z" style="fill: #fff"/>
<path id="f8fcbff1-7e8c-4c85-8f0e-222f81e36654" data-name="be4fbc2c-74e0-495a-bfad-cf557a83a287" d="M13.75,70V34.27L33.21,13.56c0-.84,1.4-1.36,2-1l.21.19,10.42,10.1c.31.3.46.3.46,1.14l-.19,59-18.57.67-13.4-13C13.89,70.44,13.75,70.46,13.75,70Z" style="fill: #a8a9a8"/>
<path id="1dc809f3-4ab0-4e83-b8a0-ab178c9c843d" data-name="4d02192d-b81d-48fe-8732-1ddf5bded46b" d="M35.44,82.8l10.67-.57v-8l-4.43-4.7H30.05a1.6,1.6,0,0,0-1.16.4L25.34,73.6c-.28.27-.3,1.12-.3,1.12V92Z" style="fill: #a8a9a8"/>
<g id="e0794b99-de5a-4337-b43b-7cdb158e4272" data-name="233cb9b7-9706-41a9-a0a4-7b51b61b2ff5">
<path id="c86708aa-fcc1-4e15-8d85-6e5415398b0c" data-name="6ed465b7-465a-4389-8ebc-d8f92a4226dd" d="M13.49,121.2V98.29A5.46,5.46,0,0,1,19,92.84h5.62A5.45,5.45,0,0,1,30,98.3v22.9h0a5.48,5.48,0,0,1-5.46,5.46H19A5.48,5.48,0,0,1,13.49,121.2Z" style="fill: #a8a9a8"/>
<circle id="0355a228-ed20-4633-ba10-c36cf551e228" data-name="955ad5d6-af09-42ad-8d56-9ff62c40912d" cx="18.35" cy="121.35" r="3.79" style="fill: #fff"/>
<circle id="73922eab-afce-48dd-9bae-80da92a8b392" data-name="75a0ff09-d40c-46e3-aaf0-c5878f2efdac" cx="18.35" cy="98.14" r="3.79" style="fill: #fff"/>
<path id="e9f7b6a6-dcdd-4d55-a7bb-ad3951bb1e39" data-name="eeb5a6b6-ef4a-4f05-95cd-8b1c3eb419c4" d="M22.07,116.64v-1.8c0-.86-.81-.46-.81-.46L20,115c-.38.18-.33-.34-.33-.34V112c0-.72.82-.76.82-.76h1.25s.32-.26.29-1.39-.29-1.32-.29-1.32H20.53a.67.67,0,0,1-.66-.65v-1.3a3.57,3.57,0,0,0-1.4-.31c-1,0-1.17.31-1.17.31v1.3c0,.67-.73.65-.73.65H15.19s-.3.18-.3,1.32.3,1.39.3,1.39h1.38a.71.71,0,0,1,.73.69v2.69c0,.52-.36.34-.36.34l-1-.58c-.68-.39-1.23,0-1.23.46v1.8s0,1,1.23.1a5.09,5.09,0,0,1,3-.71,4.16,4.16,0,0,1,2.35.71C22,117.17,22.07,116.64,22.07,116.64Z" style="fill: #fff"/>
<path id="82138da6-9b2a-4b9a-952e-568841e5ed52" data-name="80481c02-bb01-43aa-bd64-15ab30fbbb5e" d="M14.44,103.18c0-.8,1.2-.56,1.2-.56a7,7,0,0,0,2.85.83,5.78,5.78,0,0,0,2.77-.83.7.7,0,0,1,1,.25.67.67,0,0,1,.1.31v1.76s-.24,1-1.07.59a5,5,0,0,0-2.77-.77,6.59,6.59,0,0,0-2.85.77.68.68,0,0,1-.24.08.83.83,0,0,1-1-.63v0S14.44,104,14.44,103.18Z" style="fill: #fff"/>
</g>
<path id="aa62b88a-4cd5-4c76-acaf-e85a7fd45341" data-name="6b63d025-68d6-47eb-ba62-60017f4a1dd4" d="M30.07,140.62a5.78,5.78,0,0,1-5.78-5.78h0V92l9.26-9.57a2.29,2.29,0,0,1,2.38-1c4.4,0,23.87-.14,23.87-.14h.64s7.76,9.8,18.13,23.86v29.64h0a5.79,5.79,0,0,1-5.79,5.79Z" style="fill: #a8a9a8"/>
<g>
<g id="1172473e-5b0c-4dd6-85c5-28f5593b9312" data-name="a0498222-7e69-48db-90b7-05f2ce124a03">
<g style="clip-path: url(#9d9a0722-eca6-4c98-bf03-49097e654f0e)">
<g id="da9d77a3-c9b0-4118-a8e3-c65ec5cbe7d4" data-name="8270fb93-0862-4480-a5b8-675cc77ac153">
<path id="77253f44-139e-4b90-82df-465a787cab9c" data-name="bb0a4ec3-45a5-4c91-b064-db5494e447e6" d="M78.56,142.76l1-7.69V103.85L66.49,87.72v14.86L42.7,133.66,35.55,141Z" style="fill: #f2f2f2"/>
</g>
<g style="isolation: isolate">
<g id="e13b39e7-895d-4931-9be9-7aecaf709784">
<g style="clip-path: url(#clip-path)">
<g id="Large_Motor" data-name="Large Motor">
<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>
<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 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>
<path id="9d05c10c-72eb-4f9f-8517-e403ec636357" data-name="74e07bdd-431b-40c1-b0f3-71128f2a0c08" d="M35.85,135.56a5.78,5.78,0,0,1-5.78-5.78h0V92.9h0a5.78,5.78,0,0,1,5.77-5.79H57.17s6.91,9.15,15.56,20.41v22.25h0A5.78,5.78,0,0,1,67,135.56H35.85Z" style="fill: #a8a9a8"/>
<g id="6df8eb1f-3187-427f-8d99-bc7a37e6cc25" data-name="9bbfb3ec-86c2-4d27-8275-76f2f9737a7f">
<g id="e4d7143c-1fb6-45a4-a205-1c920b8a823c" data-name="7e017c33-f09b-4d39-803f-1bedf1ebf566">
<g id="3a4e493d-cd17-48c4-97b6-da7ee3c4898e" data-name="69e3df75-72a6-4499-baab-f65ec194e193">
<g style="clip-path: url(#0f29df77-bfe3-4749-8432-7a5b3681f927)">
<g id="7cada08f-1e90-4ef2-8ae4-3f2adfd3e953" data-name="b7007e32-15c9-40b3-a885-a7231fd104d1">
<path id="02e64b51-bd56-4079-9736-8a269cb37029" data-name="c599a4f4-ae5d-411c-902d-dbcde04a2d6e" d="M60.44,112a1.09,1.09,0,0,1,2.18-.14,1.34,1.34,0,0,1,0,.2V139.6a1.08,1.08,0,0,1-1.11,1.05h0a1.07,1.07,0,0,1-1-1.11V112Zm-3.62,0a1.1,1.1,0,0,1,1.12-1.06,1.08,1.08,0,0,1,1,1.12V139.6a1.09,1.09,0,0,1-2.17-.06V112Zm-3.61,0a1.09,1.09,0,1,1,2.18-.14,1.34,1.34,0,0,1,0,.2V139.6a1.08,1.08,0,0,1-1.11,1.05h0a1.07,1.07,0,0,1-1-1.11V112Zm-3.62,0a1.1,1.1,0,0,1,1.12-1.06,1.08,1.08,0,0,1,1,1.12V139.6a1.09,1.09,0,0,1-2.17-.06V112ZM46,112a1.09,1.09,0,0,1,2.18-.14,1.34,1.34,0,0,1,0,.2V139.6A1.08,1.08,0,0,1,47,140.65h0a1.07,1.07,0,0,1-1-1.11V112Z" style="fill: #6a6a6a"/>
<g id="LM_rightside" data-name="LM rightside">
<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" data-name="LM rightside4" cx="28.3" cy="66.21" r="3.79" style="fill: #fff"/>
<circle id="LM_rightside3" data-name="LM rightside3" cx="28.3" cy="43" r="3.79" style="fill: #fff"/>
<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 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>
<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 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>
<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 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 id="LM_leftside" data-name="LM leftside">
<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" data-name="LM leftside4" cx="61.67" cy="123.24" r="3.79" style="fill: #fff"/>
<circle id="LM_leftside3" data-name="LM leftside3" cx="61.67" cy="100.03" r="3.79" style="fill: #fff"/>
<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 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>
<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 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 id="LM_total" data-name="LM total">
<g id="LM_whitepart" data-name="LM whitepart">
<g style="clip-path: url(#clip-path-2)">
<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>
<circle id="a5a29926-0401-43af-b098-0c7439485e7c" data-name="bcdc8e69-90f7-4365-8f7a-7c1567704161" cx="29.69" cy="135.22" r="2.24" style="fill: #9a9a9a"/>
<circle id="313e9fdc-7bbb-4d49-9d19-2415450fb691" data-name="b7785d8e-a2e4-41a7-9c34-4d9f6aebd906" cx="58.36" cy="84.71" r="2.24" style="fill: #9a9a9a"/>
<g id="1eb2ae58-2419-47d4-86bf-4f26a7f0cf61" data-name="KNOB">
<g id="26377a78-5df7-4bea-8daa-669ea612118c" data-name="5301e639-3e28-489d-96ec-91bda6d459b7">
<circle id="13e05316-9dcc-4be0-9e0e-4b1df48fad92" data-name="f1bc8b30-bdb2-4084-8c02-e322d1c0b9bf" cx="17.06" cy="17.06" r="17.06" style="fill: #b72b1c"/>
<g>
<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 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>
<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_1" data-name="LM detail 1" cx="21.66" cy="86.59" r="2.24" style="fill: #9a9a9a"/>
<g id="hole">
<g>
<circle id="58277aee-b73f-4f42-94ef-3b959dc26807" data-name="ce4b2c57-9b3b-4aed-902e-31d9f366dc61" cx="20.12" cy="28.12" r="3.79" style="fill: #3c3c3c"/>
<circle id="980a54d2-804e-408d-8655-debf2e5856d0" data-name="6a44a65a-f04b-4564-81a2-4eefa438c5f1" cx="28.27" cy="14" r="3.79" style="fill: #3c3c3c"/>
<circle id="9b2e3cd0-e4bd-42ce-b558-4f4bc46eaf23" data-name="d5fea8d1-47c1-448e-adb6-8519e2516216" cx="14.15" cy="5.85" r="3.79" style="fill: #3c3c3c"/>
<circle id="06781f30-70ec-4914-81c3-4083325e7c18" data-name="1faf9727-3903-4be3-a3d3-4ab2d5d92b1f" cx="6" cy="19.97" r="3.79" style="fill: #3c3c3c"/>
<path id="f1de636f-1fd2-4419-ae5c-d6a853c5834d" data-name="9e52c672-4ec8-4d92-9380-e44b4f69f848" d="M13.56,16.89a2.91,2.91,0,0,0,.7,2.26,12,12,0,0,1,1.2-.39c.69-.18.95.59.95.59l.33,1.21s.33.24,1.41-.08,1.2-.62,1.2-.62-.17-.6-.32-1.22a.66.66,0,0,1,.45-.8l1.26-.34a3.63,3.63,0,0,0-.07-1.43c-.19-.93-.6-1.05-.6-1.05l-1.25.34c-.65.17-.82-.54-.82-.54l-.36-1.33s-.25-.24-1.35,0-1.26.64-1.26.64.14.61.35,1.34a.7.7,0,0,1-.48.88l-.07,0Z" style="fill: #242424"/>
<path id="e8012624-d689-4ee7-a77a-99e9713ea199" data-name="3179af54-0c25-42bc-9804-f3575e0b1b0b" d="M17.44,24.25a.47.47,0,0,1-.56-.32l-.55-2.06h0a.45.45,0,0,1,.32-.55h0l1.63-.23,1.44-.6a.47.47,0,0,1,.56.32l.55,2.05h0a.45.45,0,0,1-.32.55h0L18.94,24Z" style="fill: #3c3c3c"/>
<path id="31a64bab-6b92-41d0-afe9-392c1fae8ddb" data-name="841a583e-aa25-4a7e-8907-fbe64ce57066" d="M9.88,17.31a.46.46,0,0,1,.33-.56l2-.55h0a.47.47,0,0,1,.56.33L13,18.16l.6,1.45a.43.43,0,0,1-.3.54h0l-2,.55h0a.46.46,0,0,1-.55-.33l-.57-1.53L9.84,17.3Z" style="fill: #3c3c3c"/>
<path id="2b1c6b9e-6fda-40be-8bb8-318c30b7dca4" data-name="42515acc-688f-41c7-884c-80b8a90e09c0" d="M16.82,9.8a.47.47,0,0,1,.56.32l.55,2.05h0a.46.46,0,0,1-.33.55L16,13l-1.45.61a.45.45,0,0,1-.55-.32h0l-.53-2.1h0a.45.45,0,0,1,.31-.56h0l1.53-.57,1.55-.25Z" style="fill: #3c3c3c"/>
<path id="be04cab5-eaac-4d03-a1ee-dbe70dd5bf90" data-name="8690082b-7091-4631-a199-b79823698dd6" d="M24.33,16.74a.43.43,0,0,1-.3.54h0l-2,.55h0a.46.46,0,0,1-.55-.33l-.22-1.64-.6-1.44a.45.45,0,0,1,.31-.56h0l2-.55h0a.46.46,0,0,1,.56.33l.57,1.53.25,1.55Z" style="fill: #3c3c3c"/>
<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"/>
<circle id="LM_red-2" data-name="LM red-2" cx="62.96" cy="18.95" r="17.06" style="fill: #d42715"/>
</g>
<g id="LM_details_in_red" data-name="LM details in red">
<circle id="LM_detail_red_hole4" data-name="LM detail red hole4" cx="59.9" cy="30.01" r="3.79" style="fill: #393939"/>
<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>

View File

@ -1,28 +1,33 @@
<svg id="svg7610" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 44.14 44.15">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 48">
<defs>
<linearGradient id="motor-linear-gradient" x1="-313.1" y1="551.59" x2="-313.1" y2="551.43" gradientTransform="matrix(44.14, 0, 0, -44.15, 13843.7, 24396.04)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#a8a9a8"/>
<stop offset="1" stop-color="#545554"/>
<linearGradient id="linear-gradient" x1="-427.2" y1="440.79" x2="-427.2" y2="440.63" gradientTransform="matrix(44.14, 0, 0, -44.15, 18878.72, 19502.57)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#a8aaa8"/>
<stop offset="1" stop-color="#535453"/>
</linearGradient>
</defs>
<title>MediumMotor</title>
<g id="Medium_Motor" data-name="Medium Motor">
<g id="Group_4" data-name="Group 4">
<path id="Path_1" data-name="Path 1" d="M4.07,1.5h39a2.36,2.36,0,0,1,2.57,2V43.82c0,1-1.1,1.82-2.57,1.82h-39c-1.47,0-2.57-.81-2.57-1.82V3.47A2.36,2.36,0,0,1,4.07,1.5Z" transform="translate(-1.5 -1.49)" style="fill: url(#motor-linear-gradient)"/>
</g>
<g id="Group_7" data-name="Group 7">
<g id="g7596">
<path id="Union_1-2" data-name="Union 1-2" d="M1.5,22.74a6.21,6.21,0,0,1,6.22-6.22h8.8V7.72A6.22,6.22,0,0,1,22.74,1.5H24.4a6.21,6.21,0,0,1,6.22,6.22v8.8h8.8a6.21,6.21,0,0,1,6.22,6.22V24.4a6.22,6.22,0,0,1-6.22,6.22h-8.8v8.8a6.22,6.22,0,0,1-6.22,6.22H22.74a6.23,6.23,0,0,1-6.22-6.22h0v-8.8H7.72A6.22,6.22,0,0,1,1.5,24.4h0Z" transform="translate(-1.5 -1.49)" style="fill: #a8a9a8"/>
<g style="isolation: isolate">
<g id="svg7610">
<g id="Medium_Motor" data-name="Medium Motor">
<g id="medmotor_box" data-name="medmotor box">
<path id="medmotor_box_wgradient" data-name="medmotor box wgradient" d="M2.57,0h39a2.36,2.36,0,0,1,2.57,2V42.33c0,1-1.1,1.82-2.57,1.82h-39C1.1,44.15,0,43.34,0,42.33V2A2.36,2.36,0,0,1,2.57,0Z" transform="translate(2 1.84)" style="fill: url(#linear-gradient)"/>
</g>
<g id="medmotor_star" data-name="medmotor star">
<g>
<image width="48" height="48" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAxCAYAAACcXioiAAAACXBIWXMAAAsSAAALEgHS3X78AAACfElEQVRoQ+2aPXLbMBBG32ZUijlCnDo/R1AukCoHyAFS5Sw5g5t0bnwCu0ofpTZ9A1usvSmwoClRJEEAI4gzejMcqliS+2FB4AMoUVVyISICrIErO3dpgBpoNONDJde9RKTCJf4R+Ga/u9TADbAFalXdkYEsAiz5L8B3nICxCmyBa+Auh4jVVMAUneR/ABugAuRIaIUT9w4TJyLJIpIEWJ+/wrX8Bng7fgViMRtcRR5F5G/KO/FmKiCANa5Vq6nADhXwwY7DrjaLHALgeJcZQ4D32MtulYwil4AYfOXOogKxRLe8p7SAZC4CSnMRUJrBmThwbBbSRxIh4HFDs3VPwIQl7oXj/M1U3BBr3PUAY3aiEZGjVnzPjQZY4mOscbNqjIgGeLDzGINWvBUQaImHSOlGIUZu2IqbgAr4CtwCT8AL7sbndLzgcrvF5Vq1jQ98An5bwNSNSh9PuFw/A+KH0RhLXIo9K96dB1L68SnZs+JLnchaK75UAWA9ZskCgGULUFiugAZ4BJquAB0IPjcUZz9ugNoL8IqSNplOxA74Z0ezUlU1p3eNG5787tocUuaQOZXfAfe4XB9UVVcAqroTkTsLaghzoZ5TuFGPb+jWzA3Z6dBk/Hrgp53nVEJx7vKXnUMq0XBgp/cWNFaJbe+yYXzCoS14SINL/g9hAnors96KbM5Gqy0Dg+MHUNxjo+6z1Hmg5SKgNBcBpSktIGrk6VJSQOsopwLHKCVAed2sqmPnAMgnICaB9sv9VOAYOQTEWPEdGZKHRAFWeu8Q74Fnpjemnnm1xEndBxI/dEOUFe9Z4hSy/FcCZlnxniVOIZsACPhKYaR2my5ZBZTgP7HrUIs43RAaAAAAAElFTkSuQmCC" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path id="medmotor_cut-2" data-name="medmotor cut-2" d="M0,21.25A6.21,6.21,0,0,1,6.22,15H15V6.23A6.22,6.22,0,0,1,21.24,0H22.9a6.22,6.22,0,0,1,6.22,6.22V15h8.8a6.21,6.21,0,0,1,6.22,6.22v1.66a6.21,6.21,0,0,1-6.22,6.22h-8.8v8.8a6.21,6.21,0,0,1-6.22,6.22H21.24A6.22,6.22,0,0,1,15,37.93v-8.8H6.22A6.22,6.22,0,0,1,0,22.92H0Z" transform="translate(2 1.84)" style="fill: #a8aaa8"/>
</g>
<circle id="medmotor_hole_4" data-name="medmotor hole 4" cx="39.77" cy="24" r="4.85" style="fill: #393939"/>
<circle id="medmotor_hole_3" data-name="medmotor hole 3" cx="8.37" cy="24" r="4.85" style="fill: #393939"/>
<circle id="medmotor_hole_2" data-name="medmotor hole 2" cx="24.15" cy="8.22" r="4.85" style="fill: #393939"/>
<circle id="medmotor_hole_1" data-name="medmotor hole 1" cx="24.15" cy="39.62" r="4.85" style="fill: #393939"/>
</g>
<g id="medmotor_red" data-name="medmotor red">
<circle cx="24.3" cy="24" r="6.75" style="fill: #d42715"/>
<circle cx="24.3" cy="24" r="6.63" style="fill: none;stroke: #a20800;stroke-width: 0.25px"/>
</g>
<path id="medmotor_Hole" data-name="medmotor Hole" d="M20.59,19.46s-.05,1-.77,1-1.46,0-1.46,0a2.38,2.38,0,0,0-.45,1.69c0,1.27.36,1.6.36,1.6h1.62a.64.64,0,0,1,.7.59.21.21,0,0,1,0,.11v1.67a4,4,0,0,0,1.77.29A6.88,6.88,0,0,0,24,26.15V24.48a.73.73,0,0,1,.73-.7,9.89,9.89,0,0,0,1.44-.14s.4-.37.44-1.63-.36-1.64-.36-1.64H24.6a.65.65,0,0,1-.75-.51.49.49,0,0,1,0-.17,11.22,11.22,0,0,1,0-1.64,4.78,4.78,0,0,0-3.25,0C20.58,18.74,20.59,19.46,20.59,19.46Z" transform="translate(2 1.84)"/>
</g>
<circle id="Ellipse_1" data-name="Ellipse 1" cx="37.77" cy="22.16" r="4.85" style="fill: #3c3c3c"/>
<circle id="Ellipse_2" data-name="Ellipse 2" cx="6.37" cy="22.16" r="4.85" style="fill: #3c3c3c"/>
<circle id="Ellipse_1-2" data-name="Ellipse 1-2" cx="22.15" cy="6.38" r="4.85" style="fill: #3c3c3c"/>
<circle id="Ellipse_2-2" data-name="Ellipse 2-2" cx="22.15" cy="37.78" r="4.85" style="fill: #3c3c3c"/>
</g>
<g id="Ellipse_4" data-name="Ellipse 4">
<circle id="ellipse7603" cx="22.3" cy="22.16" r="6.75" style="fill: #b72b1c"/>
<circle id="ellipse7605" cx="22.3" cy="22.16" r="6.63" style="fill: none;stroke: #8b1104;stroke-width: 0.25px"/>
</g>
<path id="Hole" d="M23.9,26.72s.56-.86,1.18-.51,1.27.73,1.27.73a2.37,2.37,0,0,0,1.24-1.23c.63-1.1.49-1.57.49-1.57l-1.41-.81a.64.64,0,0,1-.32-.86l.06-.1.84-1.44a3.9,3.9,0,0,0-1.39-1.13,6,6,0,0,0-1.6-.59l-.83,1.44a.73.73,0,0,1-1,.24,11.15,11.15,0,0,0-1.32-.6s-.54.13-1.2,1.2-.51,1.6-.51,1.6l1.46.84a.64.64,0,0,1,.4.82.55.55,0,0,1-.08.15,11.25,11.25,0,0,1-.82,1.43A4.83,4.83,0,0,0,23.19,28C23.56,27.35,23.9,26.72,23.9,26.72Z" transform="translate(-1.5 -1.49)"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -1,30 +1,35 @@
namespace pxsim.visuals {
export const MEDIUM_MOTOR_SVG = `<svg id="svg7610" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 44.14 44.15">
export const MEDIUM_MOTOR_SVG = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 48">
<defs>
<linearGradient id="motor-linear-gradient" x1="-313.1" y1="551.59" x2="-313.1" y2="551.43" gradientTransform="matrix(44.14, 0, 0, -44.15, 13843.7, 24396.04)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#a8a9a8"/>
<stop offset="1" stop-color="#545554"/>
<linearGradient id="linear-gradient" x1="-427.2" y1="440.79" x2="-427.2" y2="440.63" gradientTransform="matrix(44.14, 0, 0, -44.15, 18878.72, 19502.57)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#a8aaa8"/>
<stop offset="1" stop-color="#535453"/>
</linearGradient>
</defs>
<title>Medium Motor</title>
<g id="Medium_Motor" data-name="Medium Motor">
<g id="Group_4" data-name="Group 4">
<path id="Path_1" data-name="Path 1" d="M4.07,1.5h39a2.36,2.36,0,0,1,2.57,2V43.82c0,1-1.1,1.82-2.57,1.82h-39c-1.47,0-2.57-.81-2.57-1.82V3.47A2.36,2.36,0,0,1,4.07,1.5Z" transform="translate(-1.5 -1.49)" style="fill: url(#motor-linear-gradient)"/>
</g>
<g id="Group_7" data-name="Group 7">
<g id="g7596">
<path id="Union_1-2" data-name="Union 1-2" d="M1.5,22.74a6.21,6.21,0,0,1,6.22-6.22h8.8V7.72A6.22,6.22,0,0,1,22.74,1.5H24.4a6.21,6.21,0,0,1,6.22,6.22v8.8h8.8a6.21,6.21,0,0,1,6.22,6.22V24.4a6.22,6.22,0,0,1-6.22,6.22h-8.8v8.8a6.22,6.22,0,0,1-6.22,6.22H22.74a6.23,6.23,0,0,1-6.22-6.22h0v-8.8H7.72A6.22,6.22,0,0,1,1.5,24.4h0Z" transform="translate(-1.5 -1.49)" style="fill: #a8a9a8"/>
<title>MediumMotor</title>
<g style="isolation: isolate">
<g id="svg7610">
<g id="Medium_Motor" data-name="Medium Motor">
<g id="medmotor_box" data-name="medmotor box">
<path id="medmotor_box_wgradient" data-name="medmotor box wgradient" d="M2.57,0h39a2.36,2.36,0,0,1,2.57,2V42.33c0,1-1.1,1.82-2.57,1.82h-39C1.1,44.15,0,43.34,0,42.33V2A2.36,2.36,0,0,1,2.57,0Z" transform="translate(2 1.84)" style="fill: url(#linear-gradient)"/>
</g>
<g id="medmotor_star" data-name="medmotor star">
<g>
<image width="48" height="48" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAxCAYAAACcXioiAAAACXBIWXMAAAsSAAALEgHS3X78AAACfElEQVRoQ+2aPXLbMBBG32ZUijlCnDo/R1AukCoHyAFS5Sw5g5t0bnwCu0ofpTZ9A1usvSmwoClRJEEAI4gzejMcqliS+2FB4AMoUVVyISICrIErO3dpgBpoNONDJde9RKTCJf4R+Ga/u9TADbAFalXdkYEsAiz5L8B3nICxCmyBa+Auh4jVVMAUneR/ABugAuRIaIUT9w4TJyLJIpIEWJ+/wrX8Bng7fgViMRtcRR5F5G/KO/FmKiCANa5Vq6nADhXwwY7DrjaLHALgeJcZQ4D32MtulYwil4AYfOXOogKxRLe8p7SAZC4CSnMRUJrBmThwbBbSRxIh4HFDs3VPwIQl7oXj/M1U3BBr3PUAY3aiEZGjVnzPjQZY4mOscbNqjIgGeLDzGINWvBUQaImHSOlGIUZu2IqbgAr4CtwCT8AL7sbndLzgcrvF5Vq1jQ98An5bwNSNSh9PuFw/A+KH0RhLXIo9K96dB1L68SnZs+JLnchaK75UAWA9ZskCgGULUFiugAZ4BJquAB0IPjcUZz9ugNoL8IqSNplOxA74Z0ezUlU1p3eNG5787tocUuaQOZXfAfe4XB9UVVcAqroTkTsLaghzoZ5TuFGPb+jWzA3Z6dBk/Hrgp53nVEJx7vKXnUMq0XBgp/cWNFaJbe+yYXzCoS14SINL/g9hAnors96KbM5Gqy0Dg+MHUNxjo+6z1Hmg5SKgNBcBpSktIGrk6VJSQOsopwLHKCVAed2sqmPnAMgnICaB9sv9VOAYOQTEWPEdGZKHRAFWeu8Q74Fnpjemnnm1xEndBxI/dEOUFe9Z4hSy/FcCZlnxniVOIZsACPhKYaR2my5ZBZTgP7HrUIs43RAaAAAAAElFTkSuQmCC" style="opacity: 0.30000000000000004;mix-blend-mode: multiply"/>
<path id="medmotor_cut-2" data-name="medmotor cut-2" d="M0,21.25A6.21,6.21,0,0,1,6.22,15H15V6.23A6.22,6.22,0,0,1,21.24,0H22.9a6.22,6.22,0,0,1,6.22,6.22V15h8.8a6.21,6.21,0,0,1,6.22,6.22v1.66a6.21,6.21,0,0,1-6.22,6.22h-8.8v8.8a6.21,6.21,0,0,1-6.22,6.22H21.24A6.22,6.22,0,0,1,15,37.93v-8.8H6.22A6.22,6.22,0,0,1,0,22.92H0Z" transform="translate(2 1.84)" style="fill: #a8aaa8"/>
</g>
<circle id="medmotor_hole_4" data-name="medmotor hole 4" cx="39.77" cy="24" r="4.85" style="fill: #393939"/>
<circle id="medmotor_hole_3" data-name="medmotor hole 3" cx="8.37" cy="24" r="4.85" style="fill: #393939"/>
<circle id="medmotor_hole_2" data-name="medmotor hole 2" cx="24.15" cy="8.22" r="4.85" style="fill: #393939"/>
<circle id="medmotor_hole_1" data-name="medmotor hole 1" cx="24.15" cy="39.62" r="4.85" style="fill: #393939"/>
</g>
<g id="medmotor_red" data-name="medmotor red">
<circle cx="24.3" cy="24" r="6.75" style="fill: #d42715"/>
<circle cx="24.3" cy="24" r="6.63" style="fill: none;stroke: #a20800;stroke-width: 0.25px"/>
</g>
<path id="medmotor_Hole" data-name="medmotor Hole" d="M20.59,19.46s-.05,1-.77,1-1.46,0-1.46,0a2.38,2.38,0,0,0-.45,1.69c0,1.27.36,1.6.36,1.6h1.62a.64.64,0,0,1,.7.59.21.21,0,0,1,0,.11v1.67a4,4,0,0,0,1.77.29A6.88,6.88,0,0,0,24,26.15V24.48a.73.73,0,0,1,.73-.7,9.89,9.89,0,0,0,1.44-.14s.4-.37.44-1.63-.36-1.64-.36-1.64H24.6a.65.65,0,0,1-.75-.51.49.49,0,0,1,0-.17,11.22,11.22,0,0,1,0-1.64,4.78,4.78,0,0,0-3.25,0C20.58,18.74,20.59,19.46,20.59,19.46Z" transform="translate(2 1.84)"/>
</g>
<circle id="Ellipse_1" data-name="Ellipse 1" cx="37.77" cy="22.16" r="4.85" style="fill: #3c3c3c"/>
<circle id="Ellipse_2" data-name="Ellipse 2" cx="6.37" cy="22.16" r="4.85" style="fill: #3c3c3c"/>
<circle id="Ellipse_1-2" data-name="Ellipse 1-2" cx="22.15" cy="6.38" r="4.85" style="fill: #3c3c3c"/>
<circle id="Ellipse_2-2" data-name="Ellipse 2-2" cx="22.15" cy="37.78" r="4.85" style="fill: #3c3c3c"/>
</g>
<g id="Ellipse_4" data-name="Ellipse 4">
<circle id="ellipse7603" cx="22.3" cy="22.16" r="6.75" style="fill: #b72b1c"/>
<circle id="ellipse7605" cx="22.3" cy="22.16" r="6.63" style="fill: none;stroke: #8b1104;stroke-width: 0.25px"/>
</g>
<path id="Hole" d="M22.09,21s-.05,1-.77,1H19.86a2.37,2.37,0,0,0-.45,1.69c0,1.27.36,1.6.36,1.6h1.62a.64.64,0,0,1,.7.59.2.2,0,0,1,0,.11v1.67a4,4,0,0,0,1.77.29,6.88,6.88,0,0,0,1.68-.29V26a.73.73,0,0,1,.73-.7,9.89,9.89,0,0,0,1.44-.14s.4-.37.44-1.63-.36-1.64-.36-1.64H26.1a.65.65,0,0,1-.75-.51.5.5,0,0,1,0-.17,11.36,11.36,0,0,1,0-1.65,4.9,4.9,0,0,0-3.25,0C22.08,20.23,22.09,21,22.09,21Z" transform="translate(-1.5 -1.49)"/>
</g>
</svg>`;
}

View File

@ -33,13 +33,21 @@ namespace pxsim.visuals {
font-family:"Lucida Console", Monaco, monospace;
font-size:8px;
fill:#fff;
pointer-events: none; user-select: none;
pointer-events: none;
user-select: none;
}
.sim-text.small {
font-size:6px;
}
.sim-text.large {
font-size:30px;
}
.sim-text.number {
font-family: Courier, Lato, Work Sans, PT Serif, Source Serif Pro;
font-weight: bold;
}
.sim-text.inverted {
fill:#000;
fill:#5A5A5A;
}
/* Color Grid */
@ -175,8 +183,8 @@ namespace pxsim.visuals {
this.layoutView.updateTheme(theme);
}
private getControlForNode(id: NodeType, port: number) {
if (this.cachedControlNodes[id] && this.cachedControlNodes[id][port]) {
private getControlForNode(id: NodeType, port: number, useCache = true) {
if (useCache && this.cachedControlNodes[id] && this.cachedControlNodes[id][port]) {
return this.cachedControlNodes[id][port];
}
@ -205,9 +213,10 @@ namespace pxsim.visuals {
}
case NodeType.MediumMotor:
case NodeType.LargeMotor: {
// const state = ev3board().getMotor(port)[0];
// view = new MotorInputControl(this.element, this.defs, state, port);
// break;
// TODO: figure out if the motor is in "input" or "output" mode
const state = ev3board().getMotors()[port];
view = new MotorReporterControl(this.element, this.defs, state, port);
break;
}
}
@ -331,6 +340,28 @@ namespace pxsim.visuals {
cancelAnimationFrame(animationId);
})
}
// Save previous inputs for the next cycle
EV3View.previousSelectedInputs = ev3board().getInputNodes().map((node, index) => (this.getDisplayViewForNode(node.id, index).getSelected()) ? node.id : -1)
EV3View.previousSeletedOutputs = ev3board().getMotors().map((node, index) => (this.getDisplayViewForNode(node.id, index).getSelected()) ? node.id : -1);
}
private static previousSelectedInputs: number[];
private static previousSeletedOutputs: number[];
private static isPreviousInputSelected(index: number, id: number) {
if (EV3View.previousSelectedInputs && EV3View.previousSelectedInputs[index] == id) {
EV3View.previousSelectedInputs[index] = undefined;
return true;
}
return false;
}
private static isPreviousOutputSelected(index: number, id: number) {
if (EV3View.previousSeletedOutputs && EV3View.previousSeletedOutputs[index] == id) {
EV3View.previousSeletedOutputs[index] = undefined;
return true;
}
return false;
}
private begin() {
@ -349,14 +380,14 @@ namespace pxsim.visuals {
if (!this.running) return;
const fps = GAME_LOOP_FPS;
let now;
let then = Date.now();
let then = pxsim.U.now();
let interval = 1000 / fps;
let delta;
let that = this;
function loop() {
const animationId = requestAnimationFrame(loop);
that.lastAnimationIds.push(animationId);
now = Date.now();
now = pxsim.U.now();
delta = now - then;
if (delta > interval) {
then = now;
@ -373,7 +404,9 @@ namespace pxsim.visuals {
const view = this.getDisplayViewForNode(node.id, index);
if (!node.didChange() && !view.didChange()) return;
if (view) {
const control = view.getSelected() ? this.getControlForNode(node.id, index) : undefined;
const isSelected = EV3View.isPreviousInputSelected(index, node.id) || view.getSelected();
if (isSelected && !view.getSelected()) view.setSelected(true);
const control = isSelected ? this.getControlForNode(node.id, index, !node.modeChange()) : undefined;
const closeIcon = control ? this.getCloseIconView() : undefined;
this.layoutView.setInput(index, view, control, closeIcon);
view.updateState();
@ -392,7 +425,9 @@ namespace pxsim.visuals {
const view = this.getDisplayViewForNode(node.id, index);
if (!node.didChange() && !view.didChange()) return;
if (view) {
const control = view.getSelected() ? this.getControlForNode(node.id, index) : undefined;
const isSelected = EV3View.isPreviousOutputSelected(index, node.id) || view.getSelected();
if (isSelected && !view.getSelected()) view.setSelected(true);
const control = isSelected ? this.getControlForNode(node.id, index) : undefined;
const closeIcon = control ? this.getCloseIconView() : undefined;
this.layoutView.setOutput(index, view, control, closeIcon);
view.updateState();

View File

@ -5,6 +5,8 @@ namespace pxsim.visuals {
export const CONTROL_WIDTH = 87.5;
export const CONTROL_HEIGHT = 175;
export const CONTROL_TEXT_COLOR = '#000';
export abstract class ControlView<T extends BaseNode> extends SimView<T> implements LayoutElement {
protected content: SVGSVGElement;
@ -12,6 +14,7 @@ namespace pxsim.visuals {
constructor(protected parent: SVGSVGElement, protected globalDefs: SVGDefsElement, protected state: T, protected port: number) {
super(state);
}
getInnerWidth(): number {
@ -35,7 +38,7 @@ namespace pxsim.visuals {
}
buildDom(): SVGElement {
this.content = svg.elt("svg", { viewBox: `0 0 ${this.getInnerWidth()} ${this.getInnerHeight()}`}) as SVGSVGElement;
this.content = svg.elt("svg", { viewBox: `0 0 ${this.getInnerWidth()} ${this.getInnerHeight()}` }) as SVGSVGElement;
this.content.appendChild(this.getInnerView(this.parent, this.globalDefs));
return this.content;
}
@ -51,13 +54,22 @@ namespace pxsim.visuals {
const currentHeight = this.getInnerHeight();
const newHeight = currentHeight / currentWidth * width;
const newWidth = currentWidth / currentHeight * height;
this.content.setAttribute('width', `${width}`);
this.content.setAttribute('height', `${newHeight}`);
if (newHeight > height) {
// scale width instead
this.content.setAttribute('width', `${newWidth}`);
this.content.setAttribute('height', `${height}`);
// translate to the middle (width)
this.translate(width / 2 - newWidth / 2, 0);
} else {
this.content.setAttribute('width', `${width}`);
this.content.setAttribute('height', `${newHeight}`);
// translate to the middle (height)
this.translate(0, height / 2 - newHeight / 2);
}
}
}
onComponentVisible() {
}
}
}

View File

@ -7,35 +7,44 @@ namespace pxsim.visuals {
getInnerView() {
this.group = svg.elt("g") as SVGGElement;
this.group.setAttribute("transform", `translate(17, ${20 + this.getHeight() / 4}) scale(5)`)
this.group.setAttribute("transform", `translate(2, 2.5) scale(0.6)`)
const colorIds = ['red', 'yellow', 'blue', 'green', 'black', 'grey'];
const colors = ['#f12a21', '#ffd01b', '#006db3', '#00934b', '#000', '#6c2d00'];
const colorIds = ['red', 'yellow', 'blue', 'green', undefined, 'grey'];
const colors = ['#f12a21', '#ffd01b', '#006db3', '#00934b', undefined, '#6c2d00'];
const colorValue = [5, 4, 2, 3, 1, 7];
let cy = -4;
for (let c = 0; c < colorIds.length; c++) {
const cx = c % 2 == 0 ? 2.2 : 8.2;
if (c % 2 == 0) cy += 5;
const circle = pxsim.svg.child(this.group, "circle", { 'class': 'sim-color-grid-circle', 'cx': cx, 'cy': cy, 'r': '2', 'style': `fill: ${colors[c]}` });
circle.addEventListener(pointerEvents.down, ev => {
this.setColor(colorValue[c]);
})
if (colorIds[c]) {
const circle = pxsim.svg.child(this.group, "circle", { 'class': 'sim-color-grid-circle', 'cx': cx, 'cy': cy, 'r': '2', 'style': `fill: ${colors[c]}` });
circle.addEventListener(pointerEvents.down, ev => {
this.setColor(colorValue[c]);
})
}
}
const whiteCircleWrapper = pxsim.svg.child(this.group, "g", { 'id': 'white-cirlce-wrapper' });
pxsim.svg.child(whiteCircleWrapper, "circle", { 'class': 'sim-color-grid-circle', 'cx': 2.2, 'cy': '16', 'r': '2', 'style': `fill: #fff` });
pxsim.svg.child(whiteCircleWrapper, "circle", { 'cx': 2.2, 'cy': '16', 'r': '2', 'style': `fill: none;stroke: #94989b;stroke-width: 0.5px` });
pxsim.svg.child(whiteCircleWrapper, "circle", { 'class': 'sim-color-grid-circle', 'cx': 2.2, 'cy': '11', 'r': '2', 'style': `fill: #fff` });
pxsim.svg.child(whiteCircleWrapper, "circle", { 'cx': 2.2, 'cy': '11', 'r': '2', 'style': `fill: none;stroke: #94989b;stroke-width: 0.1px` });
whiteCircleWrapper.addEventListener(pointerEvents.down, ev => {
this.setColor(6);
})
return this.group;
}
getInnerWidth() {
return 10.2;
}
getInnerHeight() {
return 15;
}
private setColor(color: number) {
const state = this.state;
state.setColor(color);
}
}
}

View File

@ -10,7 +10,7 @@ namespace pxsim.visuals {
getInnerView(parent: SVGSVGElement) {
this.defs = <SVGDefsElement>svg.child(this.element, "defs", {});
this.group = svg.elt("g") as SVGGElement;
this.group.setAttribute("transform", `translate(12, ${this.getHeight() / 2 - 15}) scale(2)`)
this.group.setAttribute("transform", `translate(12, 0) scale(2)`)
let gc = "gradient-color";
this.colorGradient = svg.linearGradient(this.defs, gc, true);
@ -53,6 +53,14 @@ namespace pxsim.visuals {
return this.group;
}
getInnerWidth() {
return CONTROL_WIDTH;
}
getInnerHeight() {
return CONTROL_WIDTH;
}
updateState() {
if (!this.visible) {
return;

View File

@ -7,33 +7,38 @@ namespace pxsim.visuals {
private gradient: SVGLinearGradientElement;
private slider: SVGGElement;
private static SLIDER_HANDLE_HEIGHT = 31;
private reporter: SVGTextElement;
private isVisible = false;
private static SLIDER_HANDLE_HEIGHT = 26;
private static SLIDER_SIDE_PADDING = 6;
getInnerView(parent: SVGSVGElement, globalDefs: SVGDefsElement) {
let gid = "gradient-slider-" + this.getId();
this.group = svg.elt("g") as SVGGElement;
this.gradient = createGradient(gid, this.getGradientDefinition());
this.gradient.setAttribute('x1', '-438.37');
this.gradient.setAttribute('y1', '419.43');
this.gradient.setAttribute('x2', '-438.37');
this.gradient.setAttribute('y2', '418.43');
this.gradient.setAttribute('gradientTransform', 'matrix(50, 0, 0, -110, 21949.45, 46137.67)');
this.gradient.setAttribute('gradientUnits', 'userSpaceOnUse');
this.gradient.setAttribute('x1', '0%');
this.gradient.setAttribute('y1', '0%');
this.gradient.setAttribute('x2', '0%');
this.gradient.setAttribute('y2', '100%');
// this.gradient.setAttribute('gradientTransform', 'matrix(50, 0, 0, -110, 21949.45, 46137.67)');
// this.gradient.setAttribute('gradientUnits', 'userSpaceOnUse');
globalDefs.appendChild(this.gradient);
this.group = svg.elt("g") as SVGGElement;
const sliderGroup = pxsim.svg.child(this.group, "g");
sliderGroup.setAttribute("transform", `translate(0, ${10 + this.getTopPadding()})`)
const reporterGroup = pxsim.svg.child(this.group, "g");
reporterGroup.setAttribute("transform", `translate(31, 42)`);
this.reporter = pxsim.svg.child(reporterGroup, "text", { 'x': 0, 'y': '0', 'class': 'sim-text number large inverted' }) as SVGTextElement;
const rect = pxsim.svg.child(sliderGroup, "rect", { 'x': this.getLeftPadding(), 'y': 2, 'width': this.getWidth() - this.getLeftPadding() * 2, 'height': this.getContentHeight(), 'style': `fill: url(#${gid})` });
const sliderGroup = pxsim.svg.child(this.group, "g");
sliderGroup.setAttribute("transform", `translate(${this.getWidth() / 2 - this.getSliderWidth() / 2}, ${this.getReporterHeight()})`)
const rect = pxsim.svg.child(sliderGroup, "rect", { 'x': DistanceSliderControl.SLIDER_SIDE_PADDING, 'y': 2, 'width': this.getSliderWidth() - DistanceSliderControl.SLIDER_SIDE_PADDING * 2, 'height': this.getSliderHeight(), 'style': `fill: url(#${gid})` });
this.slider = pxsim.svg.child(sliderGroup, "g", { "transform": "translate(0,0)" }) as SVGGElement;
const sliderInner = pxsim.svg.child(this.slider, "g");
pxsim.svg.child(sliderInner, "rect", { 'width': this.getWidth(), 'height': DistanceSliderControl.SLIDER_HANDLE_HEIGHT, 'rx': '2', 'ry': '2', 'style': 'fill: #f12a21' });
pxsim.svg.child(sliderInner, "rect", { 'x': '0.5', 'y': '0.5', 'width': this.getWidth() - 1, 'height': DistanceSliderControl.SLIDER_HANDLE_HEIGHT - 1, 'rx': '1.5', 'ry': '1.5', 'style': 'fill: none;stroke: #b32e29' });
pxsim.svg.child(sliderInner, "rect", { 'width': this.getSliderWidth(), 'height': DistanceSliderControl.SLIDER_HANDLE_HEIGHT, 'rx': '2', 'ry': '2', 'style': 'fill: #f12a21' });
pxsim.svg.child(sliderInner, "rect", { 'x': '0.5', 'y': '0.5', 'width': this.getSliderWidth() - 1, 'height': DistanceSliderControl.SLIDER_HANDLE_HEIGHT - 1, 'rx': '1.5', 'ry': '1.5', 'style': 'fill: none;stroke: #b32e29' });
const dragSurface = svg.child(this.group, "rect", {
x: 0,
@ -66,42 +71,43 @@ namespace pxsim.visuals {
return this.group;
}
private getLeftPadding() {
return this.getInnerWidth() * 0.12;
getInnerHeight() {
return 192;
}
private getTopPadding() {
return this.getInnerHeight() / 4;
getInnerWidth() {
return 111;
}
private getContentHeight() {
return this.getInnerHeight() * 0.6;
private getReporterHeight() {
return 50;
}
private getSliderHeight() {
return 110;
}
private getSliderWidth() {
return 62;
}
updateState() {
if (!this.isVisible) {
if (!this.visible) {
return;
}
const node = this.state;
const percentage = node.getValue() / 10; /* convert back to cm */
const y = this.getContentHeight() * percentage / this.getMax();
const y = this.getSliderHeight() * percentage / this.getMax();
this.slider.setAttribute("transform", `translate(0, ${y - DistanceSliderControl.SLIDER_HANDLE_HEIGHT / 2})`);
}
onComponentVisible() {
super.onComponentVisible();
this.isVisible = true;
}
onComponentHidden() {
this.isVisible = false;
// Update reporter text
this.reporter.textContent = `${parseFloat((percentage).toString()).toFixed(0)}`;
}
private updateSliderValue(pt: SVGPoint, parent: SVGSVGElement, ev: MouseEvent) {
let cur = svg.cursorPoint(pt, parent, ev);
const height = this.getContentHeight(); //DistanceSliderControl.SLIDER_HEIGHT;
const height = this.getSliderHeight();
const bBox = this.content.getBoundingClientRect();
let t = Math.max(0, Math.min(1, (this.getTopPadding() + height + bBox.top / this.scaleFactor - cur.y / this.scaleFactor) / height))
let t = Math.max(0, Math.min(1, (DistanceSliderControl.SLIDER_HANDLE_HEIGHT + height + bBox.top / this.scaleFactor - cur.y / this.scaleFactor) / height))
const state = this.state;
state.setDistance((1 - t) * (this.getMax()));
@ -119,7 +125,7 @@ namespace pxsim.visuals {
return {
stops: [
{ offset: 0, color: '#626262' },
{ offset: 1, color: "#ddd" }
{ offset: 100, color: "#ddd" }
]
};
}

View File

@ -0,0 +1,60 @@
namespace pxsim.visuals {
export class MotorReporterControl extends ControlView<MotorNode> {
private group: SVGGElement;
private circleBar: SVGCircleElement;
private reporter: SVGTextElement;
getInnerView() {
this.group = svg.elt("g") as SVGGElement;
const outerCircle = pxsim.svg.child(this.group, "circle", {
'stroke-dasharray': '565.48', 'stroke-dashoffset': '0',
'cx': 100, 'cy': 100, 'r': '90', 'style': `fill:transparent; transition: stroke-dashoffset 1s linear;`,
'stroke': '#a8aaa8', 'stroke-width': '1rem' }) as SVGCircleElement;
this.circleBar = pxsim.svg.child(this.group, "circle", {
'stroke-dasharray': '565.48', 'stroke-dashoffset': '0',
'cx': 100, 'cy': 100, 'r': '90', 'style': `fill:transparent; transition: stroke-dashoffset 1s linear;`,
'stroke': '#f12a21', 'stroke-width': '1rem' }) as SVGCircleElement;
this.reporter = pxsim.svg.child(this.group, "text", {
'x': this.getWidth() / 2, 'y': this.getHeight() / 2,
'text-anchor': 'middle', 'alignment-baseline': 'middle',
'style': 'font-size: 50px',
'class': 'sim-text inverted number' }) as SVGTextElement;
return this.group;
}
getInnerWidth() {
return 200;
}
getInnerHeight() {
return 200;
}
updateState() {
if (!this.visible) {
return;
}
const node = this.state;
const speed = node.getSpeed();
this.updateSpeed(speed);
// Update reporter
this.reporter.textContent = `${speed}`;
}
private updateSpeed(speed: number) {
let c = Math.PI * (90 * 2);
speed = Math.abs(speed);
let pct = ((100 - speed) / 100) * c;
this.circleBar.setAttribute('stroke-dashoffset', `${pct}`);
}
}
}

View File

@ -6,8 +6,6 @@ namespace pxsim.visuals {
private group: SVGGElement;
private slider: SVGGElement;
private isVisible = false;
private static SLIDER_WIDTH = 70;
private static SLIDER_HEIGHT = 78;
@ -61,7 +59,7 @@ namespace pxsim.visuals {
}
updateState() {
if (!this.isVisible) {
if (!this.visible) {
return;
}
const node = this.state;
@ -71,15 +69,6 @@ namespace pxsim.visuals {
this.slider.setAttribute("transform", `translate(${x}, ${y})`);
}
onComponentVisible() {
super.onComponentVisible();
this.isVisible = true;
}
onComponentHidden() {
this.isVisible = false;
}
private updateSliderValue(pt: SVGPoint, parent: SVGSVGElement, ev: MouseEvent) {
let cur = svg.cursorPoint(pt, parent, ev);
const width = CONTROL_WIDTH; //DistanceSliderControl.SLIDER_HEIGHT;

View File

@ -153,12 +153,6 @@ namespace pxsim.visuals {
this.contentGroup = svg.elt("g") as SVGGElement;
this.scrollGroup = svg.child(this.contentGroup, "g") as SVGGElement;
// Inject all view containers
for (let i = 0; i < 4; i++) {
this.inputContainers[i].inject(this.scrollGroup);
this.outputContainers[i].inject(this.scrollGroup);
}
this.inputs = [];
this.outputs = [];
this.inputControls = [];
@ -172,6 +166,12 @@ namespace pxsim.visuals {
this.inputWires[port].inject(this.scrollGroup);
}
// Inject all view containers
for (let i = 0; i < 4; i++) {
this.inputContainers[i].inject(this.scrollGroup);
this.outputContainers[i].inject(this.scrollGroup);
}
// Inject all ports
this.setInput(0, new PortView(0, 'A'));
this.setInput(1, new PortView(1, 'B'));
@ -222,6 +222,20 @@ namespace pxsim.visuals {
const contentHeight = this.height;
if (!contentHeight) return;
const noConnections = this.outputs.concat(this.inputs).filter(m => m.getId() != NodeType.Port).length == 0;
if (noConnections) {
// No connections render the entire board
this.brick.resize(contentWidth, contentHeight);
this.brick.translate(0, 0);
// Hide all other connections
this.outputs.concat(this.inputs).forEach(m => m.setVisible(false));
return;
} else {
this.outputs.concat(this.inputs).forEach(m => m.setVisible(true));
}
const moduleHeight = this.getModuleHeight();
const brickHeight = this.getBrickHeight();
@ -267,7 +281,7 @@ namespace pxsim.visuals {
currentY = moduleHeight;
const wireBrickSpacing = brickWidth / 5;
const wiringYPadding = 0;
const wiringYPadding = 5;
let wireStartX = 0;
let wireEndX = brickPadding + wireBrickSpacing;
let wireEndY = currentY + this.getWiringHeight() + wiringYPadding;

View File

@ -10,10 +10,11 @@ namespace pxsim.visuals {
}
public getPaddingRatio() {
return 1 / 6;
return 1 / 4;
}
public updateState() {
super.updateState();
// TODO: show different color modes
}
}

View File

@ -8,7 +8,7 @@ namespace pxsim.visuals {
}
public getPaddingRatio() {
return 1 / 4;
return 0.3;
}
}
}

View File

@ -3,13 +3,14 @@
namespace pxsim.visuals {
export class LargeMotorView extends ModuleView implements LayoutElement {
private static ROTATING_ECLIPSE_ID = "1eb2ae58-2419-47d4-86bf-4f26a7f0cf61";
private static ROTATING_ECLIPSE_ID = "hole";
constructor(port: number) {
super(LARGE_MOTOR_SVG, "large-motor", NodeType.LargeMotor, port);
}
updateState() {
super.updateState();
const motorState = ev3board().getMotors()[this.port];
if (!motorState) return;
const speed = motorState.getSpeed();
@ -20,14 +21,14 @@ namespace pxsim.visuals {
private setMotorAngle(angle: number) {
const holeEl = this.content.getElementById(this.normalizeId(LargeMotorView.ROTATING_ECLIPSE_ID))
const width = 34;
const height = 34;
const width = 125.92;
const height = 37.9;
const transform = `rotate(${angle} ${width / 2} ${height / 2})`;
holeEl.setAttribute("transform", transform);
}
getWiringRatio() {
return 0.62;
return 0.37;
}
}
}

View File

@ -6,7 +6,7 @@ namespace pxsim.visuals {
export class MediumMotorView extends ModuleView implements LayoutElement {
private static ROTATING_ECLIPSE_ID = "Hole";
private static ROTATING_ECLIPSE_ID = "medmotor_Hole";
private hasPreviousAngle: boolean;
private previousAngle: number;
@ -20,6 +20,7 @@ namespace pxsim.visuals {
}
updateState() {
super.updateState();
const motorState = ev3board().getMotors()[this.port];
if (!motorState) return;
const speed = motorState.getSpeed();
@ -30,9 +31,9 @@ namespace pxsim.visuals {
private setMotorAngle(angle: number) {
const holeEl = this.content.getElementById(this.normalizeId(MediumMotorView.ROTATING_ECLIPSE_ID))
const width = 47.9;
const height = 47.2;
const transform = `translate(-1.5 -1.49) rotate(${angle} ${width / 2} ${height / 2})`;
const width = 44.45;
const height = 44.45;
const transform = `translate(2 1.84) rotate(${angle} ${width / 2} ${height / 2})`;
holeEl.setAttribute("transform", transform);
}
}

View File

@ -4,7 +4,8 @@ namespace pxsim.visuals {
protected content: SVGSVGElement;
protected controlShown: boolean;
protected selected: boolean;
protected opacity: number;
constructor(protected xml: string, protected prefix: string, protected id: NodeType, protected port: NodeType) {
super();
@ -106,19 +107,24 @@ namespace pxsim.visuals {
this.updateOpacity();
}
public updateState() {
this.updateOpacity();
}
protected updateOpacity() {
if (this.rendered) {
const opacity = this.selected ? "0.2" : "1";
if (this.hasClick()) {
this.setOpacity(opacity);
const opacity = this.selected ? 0.2 : 1;
if (this.hasClick() && this.opacity != opacity) {
this.opacity = opacity;
this.setOpacity(this.opacity);
if (this.selected) this.content.style.cursor = "";
else this.content.style.cursor = "pointer";
}
}
}
protected setOpacity(opacity: string) {
this.element.setAttribute("opacity", opacity);
protected setOpacity(opacity: number) {
this.element.setAttribute("opacity", `${opacity}`);
}
}
}

View File

@ -17,7 +17,7 @@ namespace pxsim.visuals {
}
public getPaddingRatio() {
return 1 / 10;
return 1 / 4;
}
public hasClick() {

View File

@ -219,7 +219,6 @@ namespace pxsim.visuals {
this.changed = false;
return res;
}
}
export abstract class SimView<T extends BaseNode> extends View implements LayoutElement {

View File

@ -35,7 +35,7 @@ namespace pxsim.visuals {
'd': '',
'fill': 'transparent',
'stroke': '#5A5A5A',
'stroke-width': '2px'
'stroke-width': '3px'
}) as SVGPathElement;
this.setSelected(true);
return this.wire;

View File

@ -9,15 +9,7 @@
<title>color</title>
<g id="menu_icn_expansions" transform="translate(-9596 11554)">
<circle id="Ellipse_34" class="st0" cx="9607.5" cy="-11542" r="9"/>
<g id="Rectangle_253_1_" transform="translate(527 574)">
<rect x="9079.5" y="-12122" class="st0" width="2" height="12"/>
<rect x="9080" y="-12121.5" class="st1" width="1" height="11"/>
</g>
<g id="Rectangle_254_1_" transform="translate(522 581) rotate(-90)">
<rect x="12117" y="9084.5" transform="matrix(-2.535182e-06 -1 1 -2.535182e-06 3037.5305 21208.5234)" class="st0" width="12" height="2"/>
<rect x="12117.5" y="9085" transform="matrix(-2.535182e-06 -1 1 -2.535182e-06 3037.5305 21208.5234)" class="st1" width="11" height="1"/>
</g>
<polygon class="st1" points="9613.5,-11543 9608.5,-11543 9608.5,-11548 9606.5,-11548 9606.5,-11543 9601.5,-11543 9601.5,-11541
9606.5,-11541 9606.5,-11536 9608.5,-11536 9608.5,-11541 9613.5,-11541 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 802 B

View File

@ -6,18 +6,5 @@
.st0{fill:#FFFFFF;}
</style>
<title>color</title>
<g id="menu_icn_advanced_closed" transform="translate(-9594 10075)">
<g id="Line_9_1_">
<rect x="9600.7" y="-10067" transform="matrix(0.7071 -0.7071 0.7071 0.7071 9926.6836 3842.5476)" class="st0" width="2" height="11.3"/>
</g>
<g id="Line_10_1_">
<rect x="9603" y="-10062.3" transform="matrix(0.7071 -0.7071 0.7071 0.7071 9928.7334 3847.4973)" class="st0" width="11.3" height="2"/>
</g>
<g id="menu_icn_advanced_closed-2">
<rect x="9604.7" y="-10057.6" transform="matrix(0.7071 -0.7071 0.7071 0.7071 9924.7324 3846.2527)" class="st0" width="1" height="1"/>
</g>
</g>
<polygon class="st0" points="22.8,6.8 20.8,4.9 11.5,14.2 2.2,4.9 0.2,6.8 10.5,17.1 10.5,17.1 11.5,18.1 11.8,17.8 11.8,17.8 "/>
</svg>

Before

Width:  |  Height:  |  Size: 1017 B

After

Width:  |  Height:  |  Size: 552 B

View File

@ -6,18 +6,5 @@
.st0{fill:#FFFFFF;}
</style>
<title>color</title>
<g id="menu_icn_advanced_open" transform="translate(-8544 12422.914) rotate(180)">
<g id="Line_9">
<rect x="-8559.7" y="12406.3" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -11283.3965 -2416.5291)" class="st0" width="2" height="11.3"/>
</g>
<g id="Line_10">
<rect x="-8557.4" y="12411" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -11281.3467 -2411.5793)" class="st0" width="11.3" height="2"/>
</g>
<g id="Rectangle_251">
<rect x="-8555.7" y="12415.7" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -11285.3848 -2412.8174)" class="st0" width="1" height="1"/>
</g>
</g>
<polygon class="st0" points="22.6,16.1 12.5,6 12.5,6 11.5,5 11.2,5.3 11.2,5.3 0.4,16.1 2.3,18 11.5,8.8 20.7,18 "/>
</svg>

Before

Width:  |  Height:  |  Size: 1023 B

After

Width:  |  Height:  |  Size: 540 B

View File

@ -7,25 +7,24 @@
</style>
<title>color</title>
<g id="menu_icn_FX" transform="translate(-9079.886 11883.081)">
<path id="Path_166" class="st0" d="M9087.2-11874.5h-1.7c0-0.5,0-0.6,0.5-0.6c0.8,0,1.4-0.4,1.7-1.1c0.4-0.8,0.9-1.6,1.4-2.4
c0.5-0.7,1.3-1.2,2.2-1.3c0.6-0.1,1.2,0.1,1.5,0.6c0.2,0.3,0.2,0.6,0.1,0.9c-0.2,0.3-0.5,0.4-0.8,0.3c-0.3,0-0.5-0.3-0.5-0.6
c0-0.1,0-0.1,0-0.2c0-0.2,0.1-0.4,0.1-0.6c-0.2,0-0.5-0.1-0.7,0c-0.4,0.2-0.7,0.4-0.9,0.8c-0.4,0.6-0.7,1.3-0.9,2
c-0.2,0.5-0.4,1.1-0.5,1.6h1.3c-0.1,0.2-0.1,0.4-0.2,0.6h-1.3c-0.3,1-0.5,1.9-0.8,2.8c-0.4,1.9-1.1,3.7-1.9,5.5
c-0.4,0.8-0.9,1.5-1.5,2.1c-0.5,0.5-1.1,0.8-1.8,0.8c-0.4,0.1-0.8-0.1-1.2-0.3c-0.2-0.2-0.3-0.6-0.2-0.9c0.2-0.3,0.5-0.5,0.9-0.4
c0.3,0,0.4,0.3,0.4,0.6c0,0.1-0.1,0.2-0.1,0.2c-0.1,0.1-0.1,0.2-0.1,0.3c0.1,0,0.2,0.1,0.4,0.1c0.5,0,1-0.3,1.3-0.8
c0.3-0.5,0.6-1,0.7-1.5c0.8-2.8,1.6-5.6,2.4-8.4C9087.2-11874.4,9087.2-11874.4,9087.2-11874.5z"/>
<path id="Path_167" class="st0" d="M9098.2-11863.3c0.1-0.1,0.1-0.2,0.2-0.3c1-0.6,1.7-1.7,1.9-2.8c0.4-1.9,0.4-3.8-0.1-5.6
c-0.3-1-0.9-1.8-1.7-2.4c-0.1-0.1-0.2-0.2-0.2-0.3c1.8,0.7,3.5,2.9,3.5,5.7C9101.8-11866.6,9100.4-11864.3,9098.2-11863.3z"/>
<path id="Path_168" class="st0" d="M9093.5-11874.7c0,0.1-0.1,0.2-0.1,0.2c-1,0.6-1.7,1.7-1.9,2.8c-0.4,1.9-0.4,3.8,0.1,5.7
c0.3,1,0.9,1.8,1.7,2.4c0.1,0.1,0.2,0.1,0.2,0.3c-2.1-1-3.5-3.2-3.4-5.6C9090-11872,9091.9-11874.2,9093.5-11874.7z"/>
<path id="Path_169" class="st0" d="M9097.9-11867.4c0,0,0.1,0,0.2,0.1c0,0,0,0,0,0.1c-0.3,0.5-0.6,0.9-1.1,1.2
c-0.2,0.2-0.6,0.3-0.9,0c-0.1-0.1-0.2-0.2-0.2-0.4c-0.2-0.6-0.3-1.1-0.4-1.7c0-0.1,0-0.1-0.1-0.2c-0.1,0.2-0.2,0.4-0.4,0.6
c-0.3,0.4-0.6,0.9-1,1.3c-0.2,0.2-0.4,0.4-0.7,0.5c-0.3,0.1-0.6,0-0.8-0.3c0,0,0-0.1,0-0.1c0-0.2,0-0.4,0.2-0.5
c0.1-0.1,0.3-0.1,0.5,0c0,0,0.1,0.1,0.1,0.1c0.3,0.2,0.4,0.3,0.6-0.1c0.4-0.6,0.8-1.3,1.3-1.9c0-0.1,0-0.2,0-0.3
c-0.1-0.4-0.2-0.8-0.3-1.2c-0.2-0.7-0.5-0.9-1.2-0.9h-0.1c-0.1-0.1,0-0.2,0.1-0.2c0.4-0.1,0.9-0.2,1.3-0.2c0.1,0,0.2,0,0.3,0.1
c0.3,0.4,0.5,0.8,0.6,1.3c0,0.1,0.1,0.3,0.1,0.4c0.1-0.2,0.3-0.5,0.5-0.7c0.3-0.3,0.6-0.7,0.9-0.9c0.2-0.1,0.4-0.2,0.6-0.2
c0.3,0,0.5,0.2,0.5,0.5c0,0,0,0.1,0,0.1c-0.1,0.3-0.3,0.4-0.6,0.3c0,0,0,0,0,0c-0.1,0-0.1,0-0.2,0c-0.3-0.2-0.7-0.1-0.9,0.2
c0,0,0,0,0,0c-0.2,0.3-0.5,0.7-0.7,1c0,0.1,0,0.1,0,0.2c0.2,0.7,0.3,1.4,0.5,2.2c0,0.1,0,0.1,0.1,0.2c0.1,0.3,0.3,0.4,0.5,0.1
C9097.5-11866.9,9097.6-11867.2,9097.9-11867.4z"/>
<path id="Path_166" class="st0" d="M9086.9-11874.7h-1.8c0-0.5,0-0.6,0.5-0.6c0.9,0,1.5-0.4,1.8-1.2c0.4-0.9,1-1.7,1.5-2.6
c0.5-0.7,1.4-1.3,2.3-1.4c0.6-0.1,1.3,0.1,1.6,0.6c0.2,0.3,0.2,0.6,0.1,1c-0.2,0.3-0.5,0.4-0.9,0.3c-0.3,0-0.5-0.3-0.5-0.6
c0-0.1,0-0.1,0-0.2c0-0.2,0.1-0.4,0.1-0.6c-0.2,0-0.5-0.1-0.7,0c-0.4,0.2-0.7,0.4-1,0.9c-0.4,0.6-0.7,1.4-1,2.1
c-0.2,0.5-0.4,1.2-0.5,1.7h1.4c-0.1,0.2-0.1,0.4-0.2,0.6h-1.4c-0.3,1.1-0.5,2-0.9,3c-0.4,2-1.2,3.9-2,5.8c-0.4,0.9-1,1.6-1.6,2.2
c-0.5,0.5-1.2,0.8-1.9,0.8c-0.4,0.1-0.9-0.1-1.3-0.3c-0.2-0.2-0.3-0.6-0.2-1c0.2-0.3,0.5-0.5,1-0.4c0.3,0,0.4,0.3,0.4,0.6
c0,0.1-0.1,0.2-0.1,0.2c-0.1,0.1-0.1,0.2-0.1,0.3c0.1,0,0.2,0.1,0.4,0.1c0.5,0,1.1-0.3,1.4-0.8c0.3-0.5,0.6-1.1,0.7-1.6
c0.8-3,1.7-6,2.6-8.9C9086.9-11874.6,9086.9-11874.6,9086.9-11874.7z"/>
<path id="Path_167" class="st0" d="M9098.6-11862.8c0.1-0.1,0.1-0.2,0.2-0.3c1.1-0.6,1.8-1.8,2-3c0.4-2,0.4-4-0.1-6
c-0.3-1.1-1-1.9-1.8-2.6c-0.1-0.1-0.2-0.2-0.2-0.3c1.9,0.7,3.7,3.1,3.7,6.1C9102.5-11866.3,9101-11863.8,9098.6-11862.8z"/>
<path id="Path_168" class="st0" d="M9093.6-11874.9c0,0.1-0.1,0.2-0.1,0.2c-1.1,0.6-1.8,1.8-2,3c-0.4,2-0.4,4,0.1,6.1
c0.3,1.1,1,1.9,1.8,2.6c0.1,0.1,0.2,0.1,0.2,0.3c-2.2-1.1-3.7-3.4-3.6-6C9089.9-11872,9091.9-11874.4,9093.6-11874.9z"/>
<path id="Path_169" class="st0" d="M9098.3-11867.1c0,0,0.1,0,0.2,0.1c0,0,0,0,0,0.1c-0.3,0.5-0.6,1-1.2,1.3c-0.2,0.2-0.6,0.3-1,0
c-0.1-0.1-0.2-0.2-0.2-0.4c-0.2-0.6-0.3-1.2-0.4-1.8c0-0.1,0-0.1-0.1-0.2c-0.1,0.2-0.2,0.4-0.4,0.6c-0.3,0.4-0.6,1-1.1,1.4
c-0.2,0.2-0.4,0.4-0.7,0.5c-0.3,0.1-0.6,0-0.9-0.3v-0.1c0-0.2,0-0.4,0.2-0.5c0.1-0.1,0.3-0.1,0.5,0l0.1,0.1
c0.3,0.2,0.4,0.3,0.6-0.1c0.4-0.6,0.9-1.4,1.4-2c0-0.1,0-0.2,0-0.3c-0.1-0.4-0.2-0.9-0.3-1.3c-0.2-0.7-0.5-1-1.3-1h-0.1
c-0.1-0.1,0-0.2,0.1-0.2c0.4-0.1,1-0.2,1.4-0.2c0.1,0,0.2,0,0.3,0.1c0.3,0.4,0.5,0.8,0.6,1.4c0,0.1,0.1,0.3,0.1,0.4
c0.1-0.2,0.3-0.5,0.5-0.7c0.3-0.3,0.6-0.7,1-1c0.2-0.1,0.4-0.2,0.6-0.2c0.3,0,0.5,0.2,0.5,0.5v0.1c-0.1,0.3-0.3,0.4-0.6,0.3l0,0
c-0.1,0-0.1,0-0.2,0c-0.3-0.2-0.7-0.1-1,0.2l0,0c-0.2,0.3-0.5,0.7-0.7,1.1c0,0.1,0,0.1,0,0.2c0.2,0.7,0.3,1.5,0.5,2.3
c0,0.1,0,0.1,0.1,0.2c0.1,0.3,0.3,0.4,0.5,0.1C9097.9-11866.6,9098-11866.9,9098.3-11867.1z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -7,10 +7,11 @@
</style>
<title>color</title>
<g id="menu_icn_loops" transform="translate(-9080.903 10401.478)">
<path id="Path_141" class="st0" d="M9085.3-10385.5c-0.9-1.3-1.9-2.5-2.8-3.8h1.9c0-2.2,0.9-4.4,2.5-5.9c1.1-1.1,2.4-1.8,3.9-2.1
c2.7-0.6,5.6,0.2,7.6,2.2c-0.5,0.5-0.9,0.9-1.3,1.3c-2.4-2-4.9-2.4-7.7-0.9c-2,1.1-3.1,3.2-3.1,5.4h1.9
C9087.2-10388,9086.2-10386.7,9085.3-10385.5z"/>
<path id="Path_142" class="st0" d="M9098.9-10389.3h-1.9c1-1.3,1.9-2.5,2.8-3.8c1,1.3,1.9,2.5,2.8,3.8h-1.9c0,2.3-1,4.5-2.6,6
c-1.1,1-2.4,1.7-3.8,2c-2.7,0.6-5.6-0.2-7.6-2.2l1.3-1.3c2.3,2,4.9,2.5,7.7,0.9C9097.7-10384.9,9098.9-10387,9098.9-10389.3z"/>
<path id="Path_141" class="st0" d="M9084.5-10385.8c-1-1.4-2.1-2.7-3.1-4.2h2.1c0-2.4,1-4.8,2.7-6.5c1.2-1.2,2.6-2,4.3-2.3
c3-0.7,6.1,0.2,8.3,2.4c-0.5,0.5-1,1-1.4,1.4c-2.6-2.2-5.4-2.6-8.4-1c-2.2,1.2-3.4,3.5-3.4,5.9h2.1
C9086.5-10388.6,9085.4-10387.1,9084.5-10385.8z"/>
<path id="Path_142" class="st0" d="M9099.4-10390h-2.1c1.1-1.4,2.1-2.7,3.1-4.2c1.1,1.4,2.1,2.7,3.1,4.2h-2.1
c0,2.5-1.1,4.9-2.9,6.6c-1.2,1.1-2.6,1.9-4.2,2.2c-3,0.7-6.1-0.2-8.3-2.4l1.4-1.4c2.5,2.2,5.4,2.7,8.4,1
C9098.1-10385.2,9099.4-10387.5,9099.4-10390z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -8,12 +8,12 @@
</style>
<title>color</title>
<g id="menu_icn_math" transform="translate(-9078.442 10583.172)">
<path id="Path_153" class="st0" d="M9087.4-10564.7c-0.2,0.2-0.5,0.5-0.7,0.7l-2.2-2.2c-0.8,0.8-1.5,1.5-2.2,2.2
c-0.2-0.2-0.5-0.5-0.7-0.7l2.2-2.2c-0.8-0.8-1.5-1.5-2.2-2.2c0.2-0.2,0.5-0.5,0.7-0.7l2.2,2.2l2.2-2.2c0.2,0.2,0.5,0.5,0.7,0.7
l-2.2,2.2C9085.9-10566.1,9086.7-10565.4,9087.4-10564.7z"/>
<path id="Path_154" class="st0" d="M9080.9-10575.6v-0.9h3.1v-3.1c0.3,0,0.6,0,0.9,0v3.1h3.1v0.9h-3.1v3.1h-1v-3.1H9080.9z"/>
<path id="Path_155" class="st1" d="M9098.5-10567.3h-7.8v-1.7h7.8V-10567.3z"/>
<path id="Path_156" class="st1" d="M9098.5-10565.6v1.7h-7.8v-1.7H9098.5z"/>
<path id="Path_157" class="st1" d="M9098.5-10577v1.7h-7.8v-1.7H9098.5z"/>
<path id="Path_153" class="st0" d="M9087.2-10563.2c-0.2,0.2-0.6,0.6-0.8,0.8l-2.6-2.6c-1,1-1.8,1.8-2.6,2.6
c-0.2-0.2-0.6-0.6-0.8-0.8l2.6-2.6c-1-1-1.8-1.8-2.6-2.6c0.2-0.2,0.6-0.6,0.8-0.8l2.6,2.6l2.6-2.6c0.2,0.2,0.6,0.6,0.8,0.8
l-2.6,2.6C9085.4-10564.9,9086.3-10564,9087.2-10563.2z"/>
<path id="Path_154" class="st0" d="M9079.3-10576.3v-1.1h3.7v-3.7c0.4,0,0.7,0,1.1,0v3.7h3.7v1.1h-3.7v3.7h-1.2v-3.7H9079.3z"/>
<path id="Path_155" class="st1" d="M9100.5-10566.3h-9.4v-2h9.4V-10566.3z"/>
<path id="Path_156" class="st1" d="M9100.5-10564.3v2h-9.4v-2H9100.5z"/>
<path id="Path_157" class="st1" d="M9100.5-10578v2h-9.4v-2H9100.5z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -3,16 +3,10 @@
<svg version="1.1" id="svg41" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 23 23" style="enable-background:new 0 0 23 23;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{fill:#FFFFFF;}
.st0{fill:#FFFFFF;}
</style>
<title>color</title>
<g id="menu_icn_sensor" transform="translate(-9778 10128)">
<g id="Path_170" transform="translate(697 95)">
<path class="st0" d="M9092.5-10221.5c5.5,0,10,4.5,10,10s-4.5,10-10,10s-10-4.5-10-10S9087-10221.5,9092.5-10221.5z"/>
<path class="st1" d="M9092.5-10204.5c3.9,0,7-3.1,7-7s-3.1-7-7-7s-7,3.1-7,7S9088.6-10204.5,9092.5-10204.5 M9092.5-10201.5
c-5.5,0-10-4.5-10-10s4.5-10,10-10s10,4.5,10,10S9098-10201.5,9092.5-10201.5z"/>
</g>
<path id="Path_171" class="st1" d="M9789.5-10120.5c2.2,0,4,1.8,4,4s-1.8,4-4,4s-4-1.8-4-4S9787.3-10120.5,9789.5-10120.5z"/>
</g>
<path class="st0" d="M11.5,1.8c-5.4,0-9.8,4.4-9.8,9.8c0,5.4,4.4,9.8,9.8,9.8s9.8-4.4,9.8-9.8C21.2,6.1,16.9,1.8,11.5,1.8z
M11.5,18.3c-3.8,0-6.8-3.1-6.8-6.8s3.1-6.8,6.8-6.8s6.8,3.1,6.8,6.8S15.3,18.3,11.5,18.3z"/>
<circle class="st0" cx="11.5" cy="11.5" r="3.9"/>
</svg>

Before

Width:  |  Height:  |  Size: 1010 B

After

Width:  |  Height:  |  Size: 687 B

View File

@ -3,27 +3,18 @@
<svg version="1.1" id="svg41" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 23 23" style="enable-background:new 0 0 23 23;" xml:space="preserve">
<style type="text/css">
.st0{clip-path:url(#SVGID_2_);}
.st1{fill:#FFFFFF;}
.st0{fill:#FFFFFF;}
</style>
<title>color</title>
<g>
<defs>
<rect id="SVGID_1_" x="3" y="5" width="16" height="13"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
</clipPath>
<g id="menu_icn_variables" transform="translate(-9077.432 10524.199)" class="st0">
<g transform="translate(-518.568 -458.199)">
<path id="Path_165" class="st1" d="M9615-10061v2h-16v-2H9615z"/>
</g>
<g transform="translate(-518.568 -453.199)">
<path id="Path_165-2" class="st1" d="M9615-10061v2h-16v-2H9615z"/>
</g>
<g transform="translate(-518.568 -448.199)">
<path id="Path_165-3" class="st1" d="M9615-10061v2h-16v-2H9615z"/>
</g>
<g transform="translate(-518.568 -448.199)">
<path id="Path_165-3" class="st0" d="M539.7,464.3v2.4h-19.2v-2.4H539.7z"/>
</g>
<g transform="translate(-518.568 -453.199)">
<path id="Path_165-2" class="st0" d="M539.7,463.5v2.4h-19.2v-2.4H539.7z"/>
</g>
<g id="menu_icn_variables" transform="translate(-9077.432 10524.199)">
<g transform="translate(-518.568 -458.199)">
<path id="Path_165" class="st0" d="M9617.1-10061.5v2.4h-19.2v-2.4H9617.1z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 884 B

View File

@ -2,10 +2,29 @@ const webfontsGenerator = require('webfonts-generator');
webfontsGenerator({
files: [
'./ultrasonic.svg',
"./ultrasonic.svg",
"./color.svg",
"./touch.svg",
"./gyro.svg"
"./gyro.svg",
"./categories/addpackage.svg",
"./categories/brick.svg",
"./categories/controls.svg",
"./categories/functions.svg",
"./categories/list.svg",
"./categories/logic.svg",
"./categories/loops.svg",
"./categories/math.svg",
"./categories/motors.svg",
"./categories/music.svg",
"./categories/sensors.svg",
"./categories/text.svg",
"./categories/variables.svg",
"./icons/cancel.svg",
"./icons/check.svg",
"./icons/download.svg",
"./icons/save.svg",
"./categories/advancedcollapsed.svg",
"./categories/advancedexpanded.svg"
],
dest: '../docs/static/fonts/icons/',
round: 10

View File

@ -8,12 +8,7 @@
<title>color</title>
<g id="menu_icn_download" transform="translate(-9563 11322)">
<rect id="Rectangle_167" x="9566" y="-11308" class="st0" width="18" height="8"/>
<g id="arrow" transform="translate(6 -5)">
<rect id="Rectangle_168" x="9568" y="-11315" class="st0" width="2" height="10"/>
<rect id="Rectangle_169" x="9567.6" y="-11307.6" transform="matrix(0.7071 -0.7071 0.7071 0.7071 10798.123 3455.804)" class="st0" width="6" height="2"/>
<rect id="Rectangle_170" x="9566.6" y="-11309.6" transform="matrix(0.7071 -0.7071 0.7071 0.7071 10797.2441 3453.6824)" class="st0" width="2" height="6"/>
</g>
<polygon class="st0" points="9579.4,-11312.9 9578,-11314.3 9576,-11312.3 9576,-11320 9574,-11320 9574,-11312.5 9572.2,-11314.3
9570.8,-11312.9 9575,-11308.6 9575.1,-11308.7 9575.2,-11308.6 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 772 B

View File

@ -4,21 +4,15 @@
viewBox="0 0 23 23" style="enable-background:new 0 0 23 23;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:none;}
.st2{fill:none;stroke:#FFFFFF;}
</style>
<title>color</title>
<g id="menu_icn_savedisc" transform="translate(-8886 12201.056)">
<path id="Path_116" class="st0" d="M8888.4-12189.1v-8.4c0-0.6,0.1-0.7,0.7-0.7h4c0.6,0,0.7,0.1,0.7,0.7v4.1c0,0.5,0.1,0.6,0.6,0.6
h6c0.5,0,0.6-0.1,0.6-0.6v-4.2c0-0.5,0.1-0.6,0.6-0.6c1.2,0,1.2,0,2,0.8c0.9,0.9,1.7,1.7,2.6,2.6c0.2,0.2,0.3,0.4,0.3,0.7v13.5
c0,0.5-0.1,0.7-0.6,0.7h-16.9c-0.5,0-0.6-0.1-0.6-0.7C8888.4-12183.5,8888.4-12186.3,8888.4-12189.1z M8897.5-12181.9h6.6
c0.6,0,0.7-0.1,0.7-0.7v-7.7c0-0.5-0.1-0.7-0.7-0.7h-13.2c-0.5,0-0.7,0.1-0.7,0.7v7.7c0,0.6,0.1,0.7,0.7,0.7H8897.5z"/>
<path id="Path_117" class="st0" d="M8899.8-12196.4c0,0.4,0,0.9,0,1.3c0,0.4-0.2,0.5-0.5,0.5c-0.3,0-0.6,0-0.8,0
c-0.2,0-0.5-0.1-0.5-0.4c0,0,0-0.1,0-0.1v-2.6c0-0.2,0.1-0.4,0.4-0.5c0,0,0,0,0.1,0c0.3,0,0.6,0,0.9,0c0.3,0,0.5,0.2,0.5,0.4
c0,0,0,0,0,0.1C8899.8-12197.3,8899.8-12196.8,8899.8-12196.4z"/>
<g id="Rectangle_166" transform="translate(1.445 6.558)">
<rect x="8888.4" y="-12198.2" class="st1" width="15.4" height="10.3"/>
<rect x="8888.9" y="-12197.7" class="st2" width="14.4" height="9.3"/>
</g>
<path id="Path_117" class="st0" d="M8900.4-12197.9c0,0.5,0,1,0,1.5c0,0.5-0.2,0.6-0.6,0.6c-0.3,0-0.7,0-0.9,0
c-0.2,0-0.6-0.1-0.6-0.5v-0.1v-2.9c0-0.2,0.1-0.5,0.5-0.6c0,0,0,0,0.1,0c0.3,0,0.7,0,1,0c0.3,0,0.6,0.2,0.6,0.5c0,0,0,0,0,0.1
C8900.4-12198.9,8900.4-12198.3,8900.4-12197.9z"/>
<path class="st0" d="M8907.6-12196c-1-1-1.9-1.9-2.9-2.9c-0.9-0.9-0.9-0.9-2.3-0.9c-0.6,0-0.7,0.1-0.7,0.7v4.7
c0,0.6-0.1,0.7-0.7,0.7h-6.8c-0.6,0-0.7-0.1-0.7-0.7v-4.6c0-0.7-0.1-0.8-0.8-0.8h-4.5c-0.7,0-0.8,0.1-0.8,0.8v9.5
c0,3.2,0,6.3,0,9.6c0,0.7,0.1,0.8,0.7,0.8h19.1c0.6,0,0.7-0.2,0.7-0.8v-15.2C8908-12195.6,8907.8-12195.8,8907.6-12196z
M8905.4-12181.9h-15.3v-9.4h15.3V-12181.9z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -13,11 +13,18 @@
}
.blocklyFlyoutLabel:not(.blocklyFlyoutHeading) .blocklyFlyoutLabelIcon {
font-family: 'legoIcons';
fill: white;
font-size: 1.7rem;
}
.blocklyFlyoutLabel .blocklyFlyoutLabelIcon {
font-family: 'legoIcons';
}
span.blocklyTreeIcon {
font-family: 'legoIcons' !important;
}
/* Toolbox padding */
.blocklyToolboxDiv, .monacoToolboxDiv {
padding: 0.5rem;
@ -62,9 +69,83 @@ span.blocklyTreeLabel {
border-radius: 1rem !important;
}
/* Square shaped corners */
.blocklyDropDownDiv {
border-radius: 0px !important;
}
/* Mobile */
@media only screen and (max-width: @largestMobileScreen) {
#blocklyTrashIcon {
margin: 0.2rem;
}
}
}
span.blocklyTreeIcon.blocklyTreeIconloops::before {
content: "\f10b";
}
span.blocklyTreeIcon.blocklyTreeIconlogic::before {
content: "\f10a";
}
span.blocklyTreeIcon.blocklyTreeIconvariables::before {
content: "\f111";
}
span.blocklyTreeIcon.blocklyTreeIconmath::before {
content: "\f10c";
}
span.blocklyTreeIcon.blocklyTreeIconfunctions {
font-family: 'legoIcons' !important;
}
span.blocklyTreeIcon.blocklyTreeIconfunctions::before {
content: "\f108";
}
span.blocklyTreeIcon.blocklyTreeIconarrays::before {
content: "\f109";
}
span.blocklyTreeIcon.blocklyTreeIcontext::before {
content: "\f110";
}
span.blocklyTreeIcon.blocklyTreeIconaddpackage::before {
content: "\f105";
}
span.blocklyTreeIcon.blocklyTreeIconadvancedcollapsed::before {
content: "\f116";
}
span.blocklyTreeIcon.blocklyTreeIconadvancedexpanded::before {
content: "\f117";
}
.save-editortools-btn .icon.save,
.download-button .icon.download.icon-and-text,
.button.approve.positive .i.icon.checkmark,
.button.approve.cancel .i.icon.cancel
{
font-family: 'legoIcons';
}
.save-editortools-btn .icon.save:before {
content: "\f115";
}
.download-button .icon.download.icon-and-text:before {
content: "\f114";
}
.button.approve.positive .i.icon.checkmark:before {
content: "\f113";
}
.button.approve.cancel .i.icon.cancel:before {
content: "\f112";
}