Compare commits

..

76 Commits

Author SHA1 Message Date
a054fdd3d3 1.0.8 2018-09-25 16:58:51 -07:00
a239589913 Move back to 4.0.9 2018-09-25 16:58:40 -07:00
98a046237c bump pxt-core to 4.1.1, 2018-09-25 16:56:45 -07:00
eb385ec532 1.0.7 2018-09-25 10:28:59 -07:00
2fdce16685 Update field motors editor to support localized languages (#803)
* Use the value for options, and hardcode localized versions of first dropdown
2018-09-25 10:28:34 -07:00
74eb77a9ae 1.0.6 2018-09-25 08:42:24 -07:00
4fba96588f Bumping pxt-core to 4.0.8 2018-09-25 07:56:19 -07:00
03c07bdcf5 1.0.5 2018-09-21 20:00:18 -07:00
6da1bc3cb1 bump pxt 2018-09-21 18:49:39 -07:00
dfc9ca1db4 fxing leading / in docs 2018-09-21 14:07:11 -07:00
83b64c1e54 1.0.4 2018-09-21 11:25:26 -07:00
a0cf8655f2 updated pxt 2018-09-21 11:25:13 -07:00
e4cf2c99c0 removoing lightToc 2018-09-21 11:07:04 -07:00
076fb8487e 1.0.3 2018-09-21 09:41:31 -07:00
c725561389 bump pxt 2018-09-21 09:41:19 -07:00
3dc781f4fd remove docs in image paths 2018-09-21 09:38:48 -07:00
4456767f2d Change tables to bullet lists for docs (#789) 2018-09-20 17:07:38 -07:00
6dba240899 1.0.2 2018-09-20 14:24:19 -07:00
d7172a1f3a Light theme docs (#786)
* lighttheme toc

* use LEGO edu logo everywhere

* bump pxt
2018-09-20 14:23:08 -07:00
245ff9d5b2 Adding link instructions (#787) 2018-09-20 14:05:59 -07:00
bfb258ce61 Add 'Explorer' section to editor features page (#785) 2018-09-20 07:35:24 -07:00
63beb2cac7 missing github logo 2018-09-19 21:26:35 -07:00
73d3dce139 missing comma 2018-09-19 16:16:37 -07:00
21be8a5021 1.0.1 2018-09-19 16:09:35 -07:00
03a82d6bcd upgrade to pxt v4 (#783)
* upgrade to v4

* Update pxt-common-packages

* bump to 1.0
2018-09-19 16:09:05 -07:00
60ea0f0cd5 allow for numbers in filename filter 2018-09-19 11:27:30 -07:00
f69a0d5289 enable save in menu 2018-09-19 09:50:21 -07:00
e2e8536b37 enable print (#779) 2018-09-19 09:48:48 -07:00
4096875a88 Removing beta tag (#781) 2018-09-19 09:39:12 -07:00
9825a90df2 Buildfix for lego and bumping common-packages to 0.23.54 (#780)
* fixing build failure

* Bumping common-packages to 0.23.54
2018-09-18 16:31:40 -07:00
7ad5d123a3 Replace brick info images (#777) 2018-09-18 15:46:13 -07:00
3599483ed2 Shorten showString and set default tone (#735) 2018-09-11 13:52:09 -07:00
7a6818931f Derive 'base' package file list from pxt-common-packages (#770) 2018-09-04 08:23:11 -07:00
eda38ebbc4 Fix the double entry for 'About' in SUMMARY (#764) 2018-08-10 14:30:44 -07:00
026f7a3180 0.4.3 2018-07-18 11:35:43 -07:00
f58fcb60e2 Enable additional langs for new translations (#760) 2018-07-18 11:35:10 -07:00
dbda86abb5 Release 0.4.2 (#748)
This is release of latest editor
2018-07-13 16:10:05 -07:00
3c13565e7c Beautify the download (#747) 2018-07-13 14:56:08 -07:00
f8524cf1a7 Release app 0.4.2 (#742)
* Add MacOS download link and update Windows download link

* Update electron manifest to latest app
2018-07-13 16:10:01 -04:00
bf4b1090fc 0.4.2 2018-07-13 10:59:44 -07:00
ea4d8cf66a Bumping pxt-core to 3.21.7 and pxt-common-packages to 0.23.45 2018-07-13 10:57:35 -07:00
b32ae4e61a Give a link to the instructions 2018-07-11 11:29:28 -07:00
1df90a6ea3 0.4.1 2018-06-28 15:49:43 -04:00
09ac2a7a47 Run motors tutorial - step 5 fix 2018-06-25 13:15:34 -07:00
06565995d3 fix offline app url 2018-06-22 14:54:08 -07:00
1a73aec74d Release app 0.3.6 (#732) 2018-06-22 14:52:33 -07:00
5516d041d6 Enable offline download page (#733)
* Enable offline download page

* avoid clashing with docs
2018-06-22 14:52:17 -07:00
7aac8ab5f3 Fix typo in what animal am I tutorial (#731) 2018-06-22 07:06:31 -07:00
73da17a395 Set organizationUrl to https://makecode.com/org so that it redirects to the about page, rather than makecode.com 2018-06-21 16:19:31 -07:00
16197f2987 Move to v0.4 2018-06-21 14:53:23 -07:00
5ec7eb6f04 Release v0.3.6 (#730) 2018-06-21 14:50:51 -07:00
f05ad887b8 0.3.6 2018-06-21 14:22:24 -07:00
c8a7b73101 Fix music field editor font size (#728) 2018-06-21 14:21:40 -07:00
0b9d029ecc 0.3.5 2018-06-21 13:24:13 -07:00
d6f0fee300 bump pxt-core to 3.20.11, bump pxt-common-packages to 0.23.39, 2018-06-21 13:24:08 -07:00
d78b4c5ee3 Merge branch 'master' of https://github.com/microsoft/pxt-ev3 2018-06-21 13:12:51 -07:00
13f5ebd6a7 legoeducation.com -> mindstorms.com 2018-06-21 13:12:44 -07:00
ccbebabc55 Update offline page (#719)
* Update offline page

* Remove const
2018-06-21 13:51:09 -04:00
5c61677ab9 0.3.4 2018-06-20 22:08:04 -07:00
21025b5f83 better handling end of integration step 2018-06-20 22:03:48 -07:00
f9a0729b63 0.3.3 2018-06-20 16:49:36 -07:00
8e456f5c3c bump pxt-core to 3.20.8, bump pxt-common-packages to 0.23.38, 2018-06-20 16:49:30 -07:00
e05e147d6a fix for motor driver (#716) 2018-06-20 16:45:02 -07:00
fc83cc5d5b Fix note field editor authoring such that it limits the notes that show up (#715) 2018-06-20 16:29:03 -07:00
7974f36c31 Fix tank and steer blocks in the simulator, making them ignore polarity just like labview (#713) 2018-06-20 16:10:59 -07:00
6513dbc901 Remove object near tutorial, until we fix the issue with variables and decompile blocks (#710) 2018-06-20 16:00:17 -07:00
97215e894a do a single green pulse when starting 2018-06-20 15:21:09 -07:00
1368ee824b restoring consol eicon 2018-06-20 15:18:31 -07:00
f2344ac52e upgrading comm on packages (#708) 2018-06-20 13:59:20 -07:00
299acea61f Offline app download page (#707) 2018-06-20 16:37:15 -04:00
a99f0212ac Fix browser download (#706) 2018-06-20 13:32:58 -07:00
d128dad3dc Startup sequence (#696)
* set light, play sound, show eyes, wait, clear screen, light

* play a sound, turn on lights
2018-06-20 13:32:00 -07:00
3d7ebeb7b7 fixed 1.10 -> 1.10E 2018-06-18 08:16:16 -07:00
304cbb5ee3 Match Color Sensor ports in the 'Try' tutorial (#689) 2018-06-14 15:01:44 -07:00
0f7ec45db4 Fix home screen close icon background color (#687) 2018-06-14 11:55:14 -07:00
2bc2bda502 Fix extensions dialog header color (#686) 2018-06-14 11:03:20 -07:00
53 changed files with 1217 additions and 645 deletions

View File

@ -2,7 +2,7 @@
[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Private/pxt_project_rainbow/master/pxt-ev3_Push)](https://ci2.dot.net/job/Private/job/pxt_project_rainbow/job/master/job/pxt-ev3_Push/)
This repo contains the editor target hosted at https://makecode.legoeducation.com
This repo contains the editor target hosted at https://makecode.mindstorms.com
LEGO Auth: https://src.education.lego.com/groups/ev3-makecode (use Google Authenticator)
LEGO Chat: https://chat.internal.education.lego.com/make-code/channels/town-square

View File

@ -11,5 +11,8 @@
<div class="ui container horizontal small divided link list">
<a class="ui centered item" href="https://makecode.com/" title="Microsoft MakeCode" target="_blank" rel="noopener">Powered by Microsoft MakeCode</a>
</div>
<div class="ui centered container small list">
<p class="item">LEGO, the LEGO logo, MINDSTORMS and the MINDSTORMS EV3 logo are trademarks and/ or copyrights of the LEGO Group. ©2018 The LEGO Group. All rights reserved.</p>
</div>
</div>
</footer>

View File

@ -82,12 +82,12 @@
* [reset](/reference/sensors/gyro/reset)
* [Ultrasonic](/reference/sensors/ultrasonic)
* [on event](/reference/sensors/ultrasonic/on-event)
* [distance](reference/sensors/ultrasonic/distance)
* [pause until](reference/sensors/ultrasonic/pause-until)
* [distance](/reference/sensors/ultrasonic/distance)
* [pause until](/reference/sensors/ultrasonic/pause-until)
* [Infrared](/reference/sensors/infrared)
* [on event](/reference/sensors/infrared/on-event)
* [distance](reference/sensors/infrared/proximity)
* [pause until](reference/sensors/infrared/pause-until)
* [distance](/reference/sensors/infrared/proximity)
* [pause until](/reference/sensors/infrared/pause-until)
* [Infrared beacon](/reference/sensors/beacon)
* [on event](/reference/sensors/beacon/on-event)
* [pause until](/reference/sensors/beacon/pause-until)
@ -123,3 +123,7 @@
* [log](/reference/console/log)
* [log value](/reference/console/log-value)
* [send to screen](/reference/console/send-to-screen)
## #misc
## devs

View File

@ -70,3 +70,12 @@
| ![Download button](/static/about/download-button.png) |
| Download Button |
#### #explorer-images
| |
|-|
| ![Explorer button](/static/about/explorer-button.png) |
| Explorer Button |
| &nbsp; |
| ![Explorer File View](/static/about/explorer-view.png) |
| Explorer File View |

View File

@ -20,6 +20,12 @@ Build a @boardname@ vehicle that can park itself safely without driver intervent
[![EV3- Robot Driving Base](/static/coding/autonomous-parking/ev3-robot-driving-base.jpg)](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-driving-base-79bebfc16bd491186ea9c9069842155e.pdf)
### ~hint
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
### ~
### Check
Before you program, check:

View File

@ -24,6 +24,12 @@ Build red and green “lights” for your robot to detect. You can use LEGO bric
[![IMAGE: Color Squares](/static/coding/line-detection/ev3-color-squares.jpg)](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/color%20squares-0a88dfd98bb2e64b5b8151fc422bae36.pdf)
### ~hint
If clicking the above images doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
### ~
### Check
Before you program, check:

View File

@ -24,6 +24,12 @@ Build an obstacle for your robot to detect. You can build the **cuboid model** o
[![Cubiod block](/static/coding/object-detection/ev3-cuboid.jpg)](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-cuboid-dc93b2e60bed2981e76b3bac9ea04558.pdf)
### ~hint
If clicking the above images doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
### ~
### Check
Before you program, check:

View File

@ -37,6 +37,12 @@ More building ideas:
[![Color Sensor 2](/static/lessons/make-it-communicate/ev3-color-sensor2.jpg)](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/color%20sensor_v2-e7fd54b6fa3cdfe36f414c1d2510f9cb.pdf)
### ~hint
If clicking the above images doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
### ~
Build a path for your robot to follow. You can use electrical tape on a floor, or marker on paper. You can use objects as milestones to indicate a path that can be detected by either the Touch Sensor, Color Sensor, or Ultrasonic Sensor.
@ -70,6 +76,12 @@ Two copies of the tracks are built: one for the right side and a mirror image fo
[![Track rover assembled](/static/lessons/make-it-communicate/ev3-track-rover2.jpg)](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/track-rover-bi-6aadb1b053df0c58a0dea108b5ce0eea.pdf)
### ~hint
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
### ~
### Sample Program Solution
This program works with the Track Rover. If you create a different robot, adjust the program to fit your solution.

View File

@ -30,6 +30,14 @@ If you want some building help you can follow these instructions.
[![Toddle Bot](/static/lessons/make-it-move/toddle-bot.jpg)](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/toddle%20bot-3dcad146d7f5deac4753f93e9dcc0739.pdf)
Click [here](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/toddle%20bot-3dcad146d7f5deac4753f93e9dcc0739.pdf)
### ~hint
If clicking the above image or link doesn't open the instructions, right-click on the link and choose "Save link as..." to download the PDF.
### ~
### Program
Before you program, think about:

View File

@ -36,22 +36,22 @@ Think about a creatures movement for inspiration. Your mechanism can be attac
More building ideas:
| | | | | |
|-|-|-|-|-|
|[![EV3 Frames](/static/lessons/make-it-smarter/ev3-parts-frames.jpg)][EV3 Frames] | |[![EV3 Color Sensor 1](/static/lessons/make-it-smarter/ev3-parts-color-sensor-1.jpg)][Color Sensor 1] | |[![EV3 Gyro Sensor](/static/lessons/make-it-smarter/ev3-parts-gyro-sensor.jpg)][Gyro Sensor] |
| [EV3 Frames] | | [Color Sensor 1] | | [Gyro Sensor] |
<br/>
| | | | | |
|-|-|-|-|-|
|[![EV3 Ultrasonic Sensor](/static/lessons/make-it-smarter/ev3-parts-ultrasonic-sensor.jpg)][Ultrasonic Sensor] | | [![EV3 Touch Sensor](/static/lessons/make-it-smarter/ev3-parts-touch-sensor.jpg)][Touch Sensor] | | [![EV3 Gyro Sensor](/static/lessons/make-it-smarter/ev3-parts-jaw.jpg)][Jaw] |
| [Ultrasonic Sensor] | | [Touch Sensor] | | [Jaw] |
<br/>
* [EV3 Frames]
* [Color Sensor 1]
* [Gyro Sensor]
* [Ultrasonic Sensor]
* [Touch Sensor]
* [Jaw]
* [Leg 1]
* [Leg 2]
* [Leg 3]
| | | | | |
|-|-|-|-|-|
| [![EV3 Leg 1](/static/lessons/make-it-smarter/ev3-parts-leg-1.jpg)][Leg 1] | | [![EV3 Leg 2](/static/lessons/make-it-smarter/ev3-parts-leg-2.jpg)][Leg 2] | | [![EV3 Leg 3](/static/lessons/make-it-smarter/ev3-parts-leg-3.jpg)][Leg 3] |
| [Leg 1] | | [Leg 2] | | [Leg 3] |
### ~hint
If clicking the above links doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
### ~
### Program
@ -86,6 +86,12 @@ Building Instructions:
[![Insect robot](/static/lessons/make-it-smarter/insect-bot.jpg)](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/insect-94b8a46f0dc5082c9d78ddb734626dc9.pdf)
### ~hint
If clicking the above images or links doesn't open the instructions, right-click on the link and choose "Save link as..." to download the PDF.
### ~
### Sample Solution
This program checks if the Ultrasonic Sensor senses something near.

View File

@ -135,15 +135,15 @@ Keeping the Large Motor connected to **Port D**, connect the Color Sensor to **P
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
sensors.color3.pauseUntilColorDetected(ColorSensorColor.Green)
sensors.color4.pauseUntilColorDetected(ColorSensorColor.Green)
motors.largeD.run(50, 1, MoveUnit.Rotations)
})
```
* Using the same program, replace the ``||sensors:pause until touch 1||`` block with a ``||sensors:pause color sensor 3||`` for color block.
* Using the same program, replace the ``||sensors:pause until touch 1||`` block with a ``||sensors:pause color sensor 4||`` for color block.
```block
sensors.color3.pauseUntilColorDetected(ColorSensorColor.Green)
sensors.color4.pauseUntilColorDetected(ColorSensorColor.Green)
```
* Select the color you want to detect (e.g., green).

View File

@ -20,6 +20,12 @@ Build the robot driving base:
[![EV3 Driving Base](/static/lessons/common/ev3-driving-base.jpg)](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-driving-base-79bebfc16bd491186ea9c9069842155e.pdf)
### ~hint
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
### ~
## Make It Move
**Code it:** Create a program that makes the Driving Base move forward and stop at the finish line, which is ``1`` meter away.
@ -68,6 +74,12 @@ Build and attach an Ultrasonic Sensor to your driving base:
[![EV3 Ultrasonic Sensor Driving Base Building Instructions Main Image](/static/lessons/common/ev3-ultrasonic-sensor-driving-base.jpg)](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-ultrasonic-sensor-driving-base-61ffdfa461aee2470b8ddbeab16e2070.pdf)
### ~hint
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
### ~
## Detect an Object
**Code it:** Create a program that moves the Driving Base and makes it stop ``6`` cm from the Cuboid.

View File

@ -1,3 +1,3 @@
{
"appref": "v0.2.3"
"appref": "v0.4.2"
}

View File

@ -20,6 +20,12 @@ Think about what you have learned, then document it. Describe the problem in you
Start by constructing this model. Read the building instructions [here](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-color-sensor-down-driving-base-d30ed30610c3d6647d56e17bc64cf6e2.pdf) first.
### ~hint
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
### ~
![Color sensor on the driving base](/static/lessons/line-detection/color-sensor-driving.jpg)
## Program

View File

@ -25,6 +25,12 @@ The legs in the Walker Bot are designed to show how to change the rotary motion
Start by reading [these](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/walker-bot-bi-180fc24f9298e1dd6201099627d43903.pdf) instructions first.
### ~hint
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
### ~
![@boardname@ Walker Bot](/static/lessons/make-it-move/walker-bot.jpg)

View File

@ -24,6 +24,12 @@ The legs in the Walker Bot are designed to show how to change the rotary motion
Start by reading [these](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/walker-bot-bi-180fc24f9298e1dd6201099627d43903.pdf) instructions first.
### ~hint
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
### ~
![@boardname@ Walker Bot](/static/lessons/make-it-move/walker-bot.jpg)

View File

@ -42,14 +42,12 @@ This activity uses sensor inputs. You may want to try the [Use](/getting-started
Follow the steps of the _Maker Design Process_ for this lesson:
| | |
|-|-|
| ![Paper sheet icon](/static/maker/design-process-icons/define-problem.png) | **Define the Problem** |
| ![Lightbulb icon](/static/maker/design-process-icons/brainstorming.png) | **Brainstorming** |
| ![Checkmark icon](/static/maker/design-process-icons/define-criteria.png) | **Define the Design Criteria** |
| ![Connector icon](/static/maker/design-process-icons/go-make.png) | **Go Make** |
| ![Redo icon](/static/maker/design-process-icons/review-revise.png) | **Review and Revise Your Solution** |
| ![Speaker icon](/static/maker/design-process-icons/communicate.png) | **Communicate Your Solution** |
* Define the Problem
* Brainstorming
* Define the Design Criteria
* Go Make
* Review and Revise Your Solution
* Communicate Your Solution
### Defining the Problem

View File

@ -41,14 +41,12 @@ This activity uses motor rotations and sensor inputs. You may want to try the [U
Follow the steps of the _Maker Design Process_ for this lesson:
| | |
|-|-|
| ![Paper sheet icon](/static/maker/design-process-icons/define-problem.png) | **Define the Problem** |
| ![Lightbulb icon](/static/maker/design-process-icons/brainstorming.png) | **Brainstorming** |
| ![Checkmark icon](/static/maker/design-process-icons/define-criteria.png) | **Define the Design Criteria** |
| ![Connector icon](/static/maker/design-process-icons/go-make.png) | **Go Make** |
| ![Redo icon](/static/maker/design-process-icons/review-revise.png) | **Review and Revise Your Solution** |
| ![Speaker icon](/static/maker/design-process-icons/communicate.png) | **Communicate Your Solution** |
* Define the Problem
* Brainstorming
* Define the Design Criteria
* Go Make
* Review and Revise Your Solution
* Communicate Your Solution
### Defining the Problem

797
docs/offline-app.html Normal file
View File

@ -0,0 +1,797 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<meta charset="UTF-8">
<title>LEGO® MINDSTORMS® Education EV3 Offline App</title>
<meta name="Description" content="A MakeCode for LEGO® MINDSTORMS® Education EV3 offline app" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- @include indexhead.html -->
<style>
p.item {
color: rgba(0, 0, 0, 0.4);
}
.topbar {
background: rgb(170, 39, 143) !important;
}
.ui.inverted.content {
/* background: #00a5c8; */
background: #2a7af3;
}
.content.segment {
min-height: 80%;
}
.content .welcomeheader {
font-weight: 300;
}
.footer.segment {
padding: 5em 0em;
}
.image.left {
padding-left: 2em;
}
.image.right {
padding-right: 2em;
float: right;
}
.segments {
max-width: 60%;
}
.segments.terms-container {
margin-top: 5em;
}
.terms-container .segment {
background-color: rgb(250, 250, 250);
}
@media only screen and (max-width: 800px) {
.grid .column .image {
display: none;
}
.segments {
max-width: 95%;
}
}
</style>
<!-- Auto-generated styles for the license terms -->
<style type="text/css">
.terms ol {
margin: 0;
padding: 0
}
.terms table td,
.terms table th {
padding: 0
}
.c2 {
margin-left: 22.5pt;
padding-top: 6pt;
text-indent: -18pt;
padding-bottom: 6pt;
line-height: 1.15;
orphans: 2;
widows: 2;
text-align: left
}
.c8 {
margin-left: 40.5pt;
padding-top: 6pt;
text-indent: -18pt;
padding-bottom: 6pt;
line-height: 1.15;
orphans: 2;
widows: 2;
text-align: left
}
.c15 {
padding-top: 0pt;
padding-bottom: 12pt;
line-height: 1.15;
orphans: 2;
widows: 2;
text-align: left;
height: 11pt
}
.c7 {
padding-top: 0pt;
padding-bottom: 0pt;
line-height: 1.15;
orphans: 2;
widows: 2;
text-align: left;
height: 11pt
}
.c0 {
margin-left: 23pt;
padding-top: 6pt;
padding-bottom: 6pt;
line-height: 1.15;
orphans: 2;
widows: 2;
text-align: left
}
.c10 {
margin-left: 40.5pt;
padding-top: 6pt;
padding-bottom: 6pt;
line-height: 1.15;
orphans: 2;
widows: 2;
text-align: left
}
.c6 {
margin-left: 40.5pt;
padding-top: 0pt;
padding-bottom: 0pt;
line-height: 1.15;
orphans: 2;
widows: 2;
text-align: left
}
.c20 {
padding-top: 0pt;
padding-bottom: 0pt;
line-height: 1.15;
orphans: 2;
widows: 2;
text-align: center
}
.c4 {
color: #000000;
font-weight: 700;
text-decoration: none;
vertical-align: baseline;
font-family: "Arial";
font-style: normal
}
.c11 {
padding-top: 0pt;
padding-bottom: 0pt;
line-height: 1.15;
orphans: 2;
widows: 2;
text-align: left
}
.c12 {
padding-top: 6pt;
padding-bottom: 6pt;
line-height: 1.15;
orphans: 2;
widows: 2;
text-align: left
}
.c3 {
color: #000000;
font-weight: 400;
text-decoration: none;
vertical-align: baseline;
font-family: "Arial";
font-style: normal
}
.c16 {
padding-top: 0pt;
padding-bottom: 12pt;
line-height: 1.15;
orphans: 2;
widows: 2;
text-align: left
}
.c13 {
color: #000000;
text-decoration: none;
vertical-align: baseline;
font-family: "Arial";
font-style: italic
}
.c14 {
text-decoration-skip-ink: none;
-webkit-text-decoration-skip: none;
color: #1155cc;
text-decoration: underline
}
.c17 {
background-color: #ffffff;
max-width: 540pt;
padding: 36pt 36pt 36pt 36pt
}
.c18 {
text-decoration-skip-ink: none;
-webkit-text-decoration-skip: none;
text-decoration: underline
}
.c9 {
color: inherit;
text-decoration: inherit
}
.c5 {
font-weight: 700
}
.c1 {
font-size: 10pt
}
.c19 {
font-size: 11pt
}
.terms .title {
padding-top: 0pt;
color: #000000;
font-size: 26pt;
padding-bottom: 3pt;
font-family: "Arial";
line-height: 1.15;
page-break-after: avoid;
orphans: 2;
widows: 2;
text-align: left
}
.terms .subtitle {
padding-top: 0pt;
color: #666666;
font-size: 15pt;
padding-bottom: 16pt;
font-family: "Arial";
line-height: 1.15;
page-break-after: avoid;
orphans: 2;
widows: 2;
text-align: left
}
.terms li {
color: #000000;
font-size: 11pt;
font-family: "Arial"
}
.terms p {
margin: 0;
color: #000000;
font-size: 11pt;
font-family: "Arial"
}
.terms h1 {
padding-top: 20pt;
color: #000000;
font-size: 20pt;
padding-bottom: 6pt;
font-family: "Arial";
line-height: 1.15;
page-break-after: avoid;
orphans: 2;
widows: 2;
text-align: left
}
.terms h2 {
padding-top: 18pt;
color: #000000;
font-size: 16pt;
padding-bottom: 6pt;
font-family: "Arial";
line-height: 1.15;
page-break-after: avoid;
orphans: 2;
widows: 2;
text-align: left
}
.terms h3 {
padding-top: 16pt;
color: #434343;
font-size: 14pt;
padding-bottom: 4pt;
font-family: "Arial";
line-height: 1.15;
page-break-after: avoid;
orphans: 2;
widows: 2;
text-align: left
}
.terms h4 {
padding-top: 14pt;
color: #666666;
font-size: 12pt;
padding-bottom: 4pt;
font-family: "Arial";
line-height: 1.15;
page-break-after: avoid;
orphans: 2;
widows: 2;
text-align: left
}
.terms h5 {
padding-top: 12pt;
color: #666666;
font-size: 11pt;
padding-bottom: 4pt;
font-family: "Arial";
line-height: 1.15;
page-break-after: avoid;
orphans: 2;
widows: 2;
text-align: left
}
.terms h6 {
padding-top: 12pt;
color: #666666;
font-size: 11pt;
padding-bottom: 4pt;
font-family: "Arial";
line-height: 1.15;
page-break-after: avoid;
font-style: italic;
orphans: 2;
widows: 2;
text-align: left
}
</style>
<script>
$(document).ready(function () {
tickEvent = function (id, data) {
if (!pxt.aiTrackEvent) return;
if (!data) pxt.aiTrackEvent(id);
else {
var props = {};
var measures = {};
for (var k in data)
if (typeof data[k] == "string") props[k] = data[k];
else measures[k] = data[k];
pxt.aiTrackEvent(id, props, measures);
}
}
});
function agreeCheckboxChanged() {
var downloadSegment = document.getElementById("download-segment");
downloadSegment.classList.toggle("hidden");
}
function downloadWin64() {
// TODO: Keep this link up-to-date with the desired release version
window.open("https://makecode.com/api/release/ev3/v0.4.2/win64");
tickEvent("offlineapp.download", { "target": "ev3", "platform": "win64" });
}
function downloadMac64() {
// TODO: Keep this link up-to-date with the desired release version
window.open("https://makecode.com/api/release/ev3/v0.4.2/mac64");
tickEvent("offlineapp.download", { "target": "ev3", "platform": "mac64" });
}
</script>
</head>
<body id="root" class="root">
<div class="ui inverted vertical center aligned segment content">
<div class="ui grid topbar">
<div class="three wide column">
<img class="ui small image left" src="/static//lego_education_logo_white.png" />
</div>
<div class="ten wide column">
<h1 class="ui inverted welcomeheader">MakeCode Offline App</h1>
</div>
<div class="three wide column">
<img class="ui small image right" src="/static//Microsoft-logo_rgb_c-white.png" />
</div>
</div>
<div class="ui compact segments terms-container">
<div class="ui secondary center aligned segment">
Please read and accept the following terms to download the app.
</div>
<div class="ui left aligned segment terms">
<div class="c17">
<p class="c11">
<span class="c4 c1">MICROSOFT PRE-RELEASE SOFTWARE LICENSE TERMS</span>
</p>
<p class="c11">
<span class="c4 c1">MICROSOFT MAKECODE FOR LEGO MINDSTORMS EDUCATION EV3</span>
</p>
<p class="c7">
<span class="c4 c1"></span>
</p>
<p class="c11">
<span class="c3 c1">These license terms are an agreement between Microsoft Corporation (or based on where you live, one
of its affiliates) and you. They apply to the software named above. The terms also apply to any
Microsoft services or updates for the software, except to the extent those have additional terms.</span>
</p>
<p class="c7">
<span class="c3 c1"></span>
</p>
<p class="c11">
<span class="c4 c1">IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.</span>
</p>
<p class="c2">
<span class="c5 c1">1.</span>
<span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c5 c1">INSTALLATION AND USE RIGHTS. </span>
<span class="c3 c1">You may install and use any number of copies of the software to evaluate it as you develop and test
your software applications for use with Lego Mindstorms Education EV3 hardware.</span>
</p>
<p class="c2">
<span class="c5 c1">2.</span>
<span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c5 c1">PRE-RELEASE SOFTWARE. </span>
<span class="c3 c1">The software is a pre-release version. It may not work the way a final version of the software will.
Microsoft may change it for the final, commercial version. We also may not release a commercial
version. Microsoft is not obligated to provide maintenance, technical support or updates to you
for the software.</span>
</p>
<p class="c2">
<span class="c5 c1">3.</span>
<span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c5 c1">Associated Online Services.</span>
<span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Some features of the software may provide access
to, or rely on, Azure online services, including an associated Azure online service to the software
currently in development (the &ldquo;corresponding service&rdquo;). The use of those services
(but not the software) is governed by the separate terms and privacy policies in the agreement
under which you obtained the Azure services at</span>
<span class="c1">
<a class="c9" href="https://www.google.com/url?q=https://go.microsoft.com/fwLink/p/?LinkID%3D233178&amp;sa=D&amp;ust=1529596153826000">&nbsp;</a>
</span>
<span class="c1 c18">
<a class="c9" href="https://www.google.com/url?q=https://go.microsoft.com/fwLink/p/?LinkID%3D233178&amp;sa=D&amp;ust=1529596153826000">https://go.microsoft.com/fwLink/p/?LinkID=233178</a>
</span>
<span class="c3 c1">&nbsp;(and, with respect to the corresponding service, the additional terms below). Please read them.
The services may not be available in all regions.</span>
</p>
<p class="c2">
<span class="c5 c1">4.</span>
<span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c5 c1">Licenses for other components.</span>
<span class="c3 c1">&nbsp;The software may include third party components with separate legal notices or governed by
other agreements, as described in the ThirdPartyNotices file accompanying the software. Even
if such components are governed by other agreements, the disclaimers and the limitations on and
exclusions of damages below also apply.</span>
</p>
<p class="c2">
<span class="c5 c1">5.</span>
<span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c1 c4">DATA.</span>
</p>
<p class="c8">
<span class="c5 c1">a.</span>
<span class="c1">&nbsp; &nbsp;</span>
<span class="c1 c5">Data Collection. </span>
<span class="c1">The software may collect information about you and your use of the software, and send that to Microsoft.
Microsoft may use this information to provide services and improve our products and services.
You may opt out of many of these scenarios, but not all, as described in the product documentation.
In using the software, you must comply with applicable law. You can learn more about data collection
and use in the help documentation and the privacy statement at </span>
<span class="c14 c1">
<a class="c9" href="https://www.google.com/url?q=http://go.microsoft.com/fwlink/?LinkId%3D398505&amp;sa=D&amp;ust=1529596153827000">http://go.microsoft.com/fwlink/?LinkId=398505</a>
</span>
<span class="c1">.</span>
<span class="c3 c1">&nbsp;Your use of the software operates as your consent to these practices.</span>
</p>
<p class="c8">
<span class="c5 c1">b.</span>
<span class="c1">&nbsp; &nbsp;</span>
<span class="c5 c1">Processing of Personal Data. </span>
<span class="c1">To the extent Microsoft is a processor or subprocessor of personal data in connection with the software,
Microsoft makes the commitments in the European Union General Data Protection Regulation Terms
of the Online Services Terms to all customers effective May 25, 2018, at </span>
<span class="c1 c14">
<a class="c9" href="https://www.google.com/url?q=http://go.microsoft.com/?linkid%3D9840733&amp;sa=D&amp;ust=1529596153828000">http://go.microsoft.com/?linkid=9840733</a>
</span>
<span class="c3 c1">.</span>
</p>
<p class="c2">
<span class="c5 c1">6.</span>
<span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c5 c1">FEEDBACK. </span>
<span class="c3 c1">If you give feedback about the software to Microsoft, you give to Microsoft, without charge, the
right to use, share and commercialize your feedback in any way and for any purpose. You will
not give feedback that is subject to a license that requires Microsoft to license its software
or documentation to third parties because we include your feedback in them. These rights survive
this agreement.</span>
</p>
<p class="c2">
<span class="c5 c1">7.</span>
<span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c5 c1">SCOPE OF LICENSE.</span>
<span class="c3 c1">&nbsp;The software is licensed, not sold. This agreement only gives you some rights to use the software.
Microsoft reserves all other rights. Unless applicable law gives you more rights despite this
limitation, you may use the software only as expressly permitted in this agreement. &nbsp;In
doing so, you must comply with any technical limitations in the software that only allow you
to use it in certain ways. You may not:</span>
</p>
<p class="c8">
<span class="c3 c1">- &nbsp; &nbsp; work around any technical limitations in the software;</span>
</p>
<p class="c8">
<span class="c3 c1">- &nbsp; &nbsp; reverse engineer, decompile or disassemble the software, or attempt to do so, except
and only to the extent required by third party licensing terms governing use of certain open
source components that may be included with the software;</span>
</p>
<p class="c8">
<span class="c3 c1">- &nbsp; &nbsp; remove, minimize, block or modify any notices of Microsoft or its suppliers in the
software;
</span>
</p>
<p class="c8">
<span class="c3 c1">- &nbsp; &nbsp; use the software in any way that is against the law; or</span>
</p>
<p class="c8">
<span class="c3 c1">- &nbsp; &nbsp; share, publish, rent or lease the software, or provide the software as a stand-alone
offering for others to use.</span>
</p>
<p class="c2">
<span class="c5 c1">8. &nbsp; UPDATES. </span>
<span class="c3 c1">The software may periodically check for updates and download and install them for you. You may obtain
updates only from Microsoft or authorized sources. Microsoft may need to update your system to
provide you with updates. You agree to receive these automatic updates without any additional
notice. Updates may not include or support all existing software features, services, or peripheral
devices.
</span>
</p>
<p class="c2">
<span class="c5 c1">9.</span>
<span class="c1">&nbsp; &nbsp;</span>
<span class="c5 c1">EXPORT RESTRICTIONS.</span>
<span class="c3 c1">&nbsp;You must comply with all domestic and international export laws and regulations that apply
to the software, which include restrictions on destinations, end users and end use. For further
information on export restrictions, visit (aka.ms/exporting).</span>
</p>
<p class="c2">
<span class="c5 c1">10.</span>
<span class="c1">&nbsp;</span>
<span class="c5 c1">SUPPORT SERVICES. </span>
<span class="c3 c1">Because the software is &ldquo;as is,&rdquo; we may not provide support services for it.</span>
</p>
<p class="c2">
<span class="c5 c1">11.</span>
<span class="c1">&nbsp;</span>
<span class="c5 c1">ENTIRE AGREEMENT.</span>
<span class="c3 c1">&nbsp;This agreement, and the terms for supplements, updates, Internet-based services and support
services that you use, are the entire agreement for the software and support services.</span>
</p>
<p class="c2">
<span class="c5 c1">12.</span>
<span class="c1">&nbsp;</span>
<span class="c5 c1">APPLICABLE LAW. </span>
<span class="c3 c1">If you acquired the software in the United States, Washington State law applies to interpretation
of and claims for breach of this agreement, and the laws of the state where you live apply to
all other claims. If you acquired the software in any other country, its laws apply.</span>
</p>
<p class="c2">
<span class="c5 c1">13.</span>
<span class="c1">&nbsp;</span>
<span class="c5 c1">CONSUMER RIGHTS; REGIONAL VARIATIONS. </span>
<span class="c3 c1">This agreement describes certain legal rights. You may have other rights, including consumer rights,
under the laws of your state or country. Separate and apart from your relationship with Microsoft,
you may also have rights with respect to the party from which you acquired the software. This
agreement does not change those other rights if the laws of your state or country do not permit
it to do so. For example, if you acquired the software in one of the below regions, or mandatory
country law applies, then the following provisions apply to you:</span>
</p>
<p class="c8">
<span class="c5 c1">a.</span>
<span class="c1">&nbsp; &nbsp;</span>
<span class="c5 c1">Australia. </span>
<span class="c3 c1">You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is
intended to affect those rights.</span>
</p>
<p class="c8">
<span class="c5 c1">b.</span>
<span class="c1">&nbsp; &nbsp;</span>
<span class="c5 c1">Canada. </span>
<span class="c3 c1">If you acquired the software in Canada, you may stop receiving updates by turning off the automatic
update feature, disconnecting your device from the Internet (if and when you re-connect to the
Internet, however, the software will resume checking for and installing updates), or uninstalling
the software. The product documentation, if any, may also specify how to turn off updates for
your specific device or software.</span>
</p>
<p class="c8">
<span class="c5 c1">c.</span>
<span class="c1">&nbsp; &nbsp;</span>
<span class="c5 c1">Germany and Austria</span>
<span class="c3 c1">.</span>
</p>
<p class="c6">
<span class="c5 c1">(i)</span>
<span class="c1">&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c5 c1">Warranty</span>
<span class="c3 c1">. The properly licensed software will perform substantially as described in any Microsoft materials
that accompany the software. However, Microsoft gives no contractual guarantee in relation to
the licensed software.</span>
</p>
<p class="c6">
<span class="c4 c1">&nbsp;</span>
</p>
<p class="c6">
<span class="c5 c1">(ii)</span>
<span class="c1">&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c5 c1">Limitation of Liability</span>
<span class="c3 c1">. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as
well as, in case of death or personal or physical injury, Microsoft is liable according to the
statutory law.</span>
</p>
<p class="c10">
<span class="c3 c1">Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft
is in breach of such material contractual obligations, the fulfillment of which facilitate the
due performance of this agreement, the breach of which would endanger the purpose of this agreement
and the compliance with which a party may constantly trust in (so-called &quot;cardinal obligations&quot;).
In other cases of slight negligence, Microsoft will not be liable for slight negligence.</span>
</p>
<p class="c2">
<span class="c5 c1">14.</span>
<span class="c1">&nbsp;</span>
<span class="c5 c1">LEGAL EFFECT.</span>
<span class="c3 c1">&nbsp;This agreement describes certain legal rights. You may have other rights under the laws of
your country. You may also have rights with respect to the party from whom you acquired the software.
This agreement does not change your rights under the laws of your country if the laws of your
country do not permit it to do so.</span>
</p>
<p class="c2">
<span class="c5 c1">15.</span>
<span class="c1">&nbsp;</span>
<span class="c4 c1">DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED &ldquo;AS-IS.&rdquo; &nbsp;YOU BEAR THE RISK OF
USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED
UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.</span>
</p>
<p class="c2">
<span class="c5 c1">16.</span>
<span class="c1">&nbsp;</span>
<span class="c4 c1">LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT
DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST
PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.</span>
</p>
<p class="c0">
<span class="c3 c1">This limitation applies to (a) anything related to the software, services, content (including code)
on third party Internet sites, or third party programs; and (b) claims for breach of contract,
breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the
extent permitted by applicable law.</span>
</p>
<p class="c0">
<span class="c3 c1">It also applies even if Microsoft knew or should have known about the possibility of the damages.
The above limitation or exclusion may not apply to you because your country may not allow the
exclusion or limitation of incidental, consequential or other damages.</span>
</p>
<p class="c12">
<span class="c4 c1">Please note: As the software is distributed in Quebec, Canada, some of the clauses in this agreement
are provided below in French.</span>
</p>
<p class="c12">
<span class="c4 c1">Remarque : Ce logiciel &eacute;tant distribu&eacute; au Qu&eacute;bec, Canada, certaines des clauses
dans ce contrat sont fournies ci-dessous en fran&ccedil;ais.</span>
</p>
<p class="c11">
<span class="c5 c1">EXON&Eacute;RATION DE GARANTIE.</span>
<span class="c1 c3">&nbsp;Le logiciel vis&eacute; par une licence est offert &laquo; tel quel &raquo;. Toute utilisation
de ce logiciel est &agrave; votre seule risque et p&eacute;ril. Microsoft n&rsquo;accorde aucune
autre garantie expresse. Vous pouvez b&eacute;n&eacute;ficier de droits additionnels en vertu
du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles
sont permises par le droit locale, les garanties implicites de qualit&eacute; marchande, d&rsquo;ad&eacute;quation
&agrave; un usage particulier et d&rsquo;absence de contrefa&ccedil;on sont exclues.
</span>
</p>
<p class="c11">
<span class="c5 c1">LIMITATION DES DOMMAGES-INT&Eacute;R&Ecirc;TS ET EXCLUSION DE RESPONSABILIT&Eacute; POUR LES DOMMAGES.</span>
<span class="c3 c1">&nbsp;Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages
directs uniquement &agrave; hauteur de 5,00 $ US. Vous ne pouvez pr&eacute;tendre &agrave; aucune
indemnisation pour les autres dommages, y compris les dommages sp&eacute;ciaux, indirects ou
accessoires et pertes de b&eacute;n&eacute;fices.</span>
</p>
<p class="c12">
<span class="c3 c1">Cette limitation concerne :</span>
</p>
<p class="c2">
<span class="c3 c1">- &nbsp; &nbsp; &nbsp; &nbsp; tout ce qui est reli&eacute; au logiciel, aux services ou au contenu
(y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et</span>
</p>
<p class="c2">
<span class="c3 c1">- &nbsp; &nbsp; &nbsp; &nbsp; les r&eacute;clamations au titre de violation de contrat ou de garantie,
ou au titre de responsabilit&eacute; stricte, de n&eacute;gligence ou d&rsquo;une autre faute
dans la limite autoris&eacute;e par la loi en vigueur.</span>
</p>
<p class="c12">
<span class="c3 c1">Elle s&rsquo;applique &eacute;galement, m&ecirc;me si Microsoft connaissait ou devrait conna&icirc;tre
l&rsquo;&eacute;ventualit&eacute; d&rsquo;un tel dommage. Si votre pays n&rsquo;autorise pas
l&rsquo;exclusion ou la limitation de responsabilit&eacute; pour les dommages indirects, accessoires
ou de quelque nature que ce soit, il se peut que la limitation ou l&rsquo;exclusion ci-dessus
ne s&rsquo;appliquera pas &agrave; votre &eacute;gard.</span>
</p>
<p class="c16">
<span class="c5 c1">EFFET JURIDIQUE.</span>
<span class="c3 c1">&nbsp;Le pr&eacute;sent contrat d&eacute;crit certains droits juridiques. Vous pourriez avoir d&rsquo;autres
droits pr&eacute;vus par les lois de votre pays. Le pr&eacute;sent contrat ne modifie pas les
droits que vous conf&egrave;rent les lois de votre pays si celles-ci ne le permettent pas.</span>
</p>
<p class="c15">
<span class="c3 c1"></span>
</p>
<p class="c16">
<span class="c3 c1">&nbsp;</span>
</p>
<p class="c11">
<span class="c3 c1">LEGO, the LEGO logo, MINDSTORMS and the MINDSTORMS EV3 logo are trademarks and/ or copyrights of
the LEGO Group. &copy;2018 The LEGO Group. All rights reserved.</span>
</p>
<p class="c11">
<span class="c3 c1">&nbsp;</span>
</p>
<p class="c20">
<span class="c5 c1 c13">Remainder of this page intentionally left blank.</span>
</p>
<p class="c7">
<span class="c3 c19"></span>
</p>
</div>
</div>
<div class="ui center aligned segment">
<input id="agree-checkbox" type="checkbox" autocomplete="off" onchange="agreeCheckboxChanged(this)">
<label for="agree-checkbox">I agree to these Microsoft Software License Terms and to the
<a href="https://privacy.microsoft.com/en-us/privacystatement">Microsoft Privacy Statement.</a>
</label>
</div>
<div id="download-segment" class="ui center aligned segment hidden">
<div class="ui grid">
<div class="eight wide column">
<h3 class="ui">Windows</h3>
<button class="ui icon button" onclick="downloadWin64()">
<i class="download icon"></i>
makecode-ev3-setup-win64.exe
</button>
</div>
<div class="eight wide column">
<h3 class="ui">Mac OS</h3>
<button class="ui icon button" onclick="downloadMac64()">
<i class="download icon"></i>
makecode-ev3-mac64.zip
</button>
</div>
</div>
</div>
</div>
</div>
<!-- @include footer.html -->
<!-- @include tracking.html -->
</body>
</html>

BIN
docs/static/about/explorer-button.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
docs/static/about/explorer-view.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

1
docs/static/githubfilelogo.svg vendored Normal file
View File

@ -0,0 +1 @@
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M16.097 2.686c-7.64 0-13.834 6.194-13.834 13.835 0 6.113 3.964 11.298 9.462 13.128.692.127.944-.301.944-.667 0-.328-.012-1.199-.019-2.353-3.848.836-4.66-1.855-4.66-1.855-.629-1.598-1.536-2.023-1.536-2.023-1.256-.859.095-.842.095-.842 1.388.099 2.119 1.426 2.119 1.426 1.234 2.114 3.238 1.504 4.027 1.15.125-.894.482-1.504.878-1.85-3.072-.349-6.302-1.536-6.302-6.838 0-1.51.539-2.745 1.424-3.712-.143-.35-.617-1.756.135-3.661 0 0 1.162-.372 3.805 1.418a13.228 13.228 0 0 1 3.464-.465c1.174.005 2.358.158 3.463.465 2.642-1.79 3.801-1.418 3.801-1.418.755 1.905.28 3.311.137 3.661.887.967 1.423 2.202 1.423 3.712 0 5.316-3.235 6.485-6.317 6.827.497.428.939 1.272.939 2.563 0 1.849-.017 3.341-.017 3.795 0 .37.249.8.951.665 5.494-1.833 9.454-7.015 9.454-13.126 0-7.641-6.195-13.835-13.836-13.835" fill="#696969"/></svg>

After

Width:  |  Height:  |  Size: 973 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View File

@ -86,18 +86,6 @@ Step by step guides to coding your @boardname@.
}]
```
## Ultrasonic Sensor
```codecard
[{
"name": "Object Near?",
"description": "Build a program that will detect when an object is nearby.",
"cardType": "tutorial",
"url":"/tutorials/object-near",
"imageUrl":"/static/tutorials/object-near.png"
}]
```
## Infrared Sensor
```codecard

View File

@ -17,10 +17,10 @@ brick.showString("Hello world", 1)
## Step 2
In the ``||brick:show string||`` block, type the text ``"Press my buttons to make music!"`` to replace ``"Hello world"``.
In the ``||brick:show string||`` block, type the text ``"Press my buttons!"`` to replace ``"Hello world"``.
```blocks
brick.showString("Press my buttons to make music!", 1)
brick.showString("Press my buttons!", 1)
```
## Step 3
@ -31,7 +31,7 @@ Open the ``||brick:Brick||`` Toolbox drawer. From the **Buttons** section, drag
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
})
brick.showString("Press my buttons to make music!", 1)
brick.showString("Press my buttons!", 1)
```
## Step 4
@ -40,13 +40,13 @@ Open the ``||music:Music||`` Toolbox drawer. Drag out **5** ``||music:play tone|
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
music.playTone(0, music.beat(BeatFraction.Half))
music.playTone(0, music.beat(BeatFraction.Half))
music.playTone(0, music.beat(BeatFraction.Half))
music.playTone(0, music.beat(BeatFraction.Half))
music.playTone(0, music.beat(BeatFraction.Half))
music.playTone(262, music.beat(BeatFraction.Half))
music.playTone(262, music.beat(BeatFraction.Half))
music.playTone(262, music.beat(BeatFraction.Half))
music.playTone(262, music.beat(BeatFraction.Half))
music.playTone(262, music.beat(BeatFraction.Half))
})
brick.showString("Press my buttons to make music!", 1)
brick.showString("Press my buttons!", 1)
```
## Step 5
@ -63,7 +63,7 @@ brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
music.playTone(196, music.beat(BeatFraction.Half))
music.playTone(294, music.beat(BeatFraction.Whole))
})
brick.showString("Press my buttons to make music!", 1)
brick.showString("Press my buttons!", 1)
```
## Step 6

View File

@ -66,7 +66,7 @@ brick.buttonDown.onEvent(ButtonEvent.Pressed, function () {
## Step 5
Now, lets add a Medium motor, and tell it how many rotations we want it to run for. Open the ``||brick:Brick||`` Toolbox drawer. Drag out **2** ``|brick:on button||`` blocks. In the ``||brick:on button||`` blocks, use the drop-down menu to select the ``left`` and ``right`` buttons.
Open the ``||brick:Brick||`` Toolbox drawer and drag out **2** ``|brick:on button||`` blocks. In the ``||brick:on button||`` blocks, use the drop-down menu to select the ``left`` and ``right`` buttons.
```blocks
brick.buttonUp.onEvent(ButtonEvent.Pressed, function () {
@ -106,9 +106,9 @@ brick.buttonRight.onEvent(ButtonEvent.Pressed, function () {
For the ``||motors:run||`` blocks that are in the ``||brick:on button left||`` and ``||brick:on button right||`` blocks, use the drop-down menu to select a ``medium motor`` on Port ``D``.
| | | |
|-|-|-|
| ![Select a motor type dropdown](/static/tutorials/run-motors/run-motor-dropdown.png) | | | ![Select a motor port dropdown](/static/tutorials/run-motors/motor-port-dropdown.png) |
![Select a motor type dropdown](/static/tutorials/run-motors/run-motor-dropdown.png)
<br/>
![Select a motor port dropdown](/static/tutorials/run-motors/motor-port-dropdown.png)
```blocks
brick.buttonUp.onEvent(ButtonEvent.Pressed, function () {

View File

@ -16,7 +16,7 @@ brick.showString("Hello world", 1)
## Step 2
In the ``||brick:show string||`` block, type the text ``"Guess teh animal"`` to replace ``"Hello world"``.
In the ``||brick:show string||`` block, type the text ``"Guess the animal"`` to replace ``"Hello world"``.
```blocks
brick.showString("Guess the animal", 1)

View File

@ -60,7 +60,7 @@ const rbfTemplate = `
4c45474f580000006d000100000000001c000000000000000e000000821b038405018130813e8053
74617274696e672e2e2e0084006080XX00448581644886488405018130813e80427965210084000a
`
export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
export function deployCoreAsync(resp: pxtc.CompileResult) {
let w: pxt.editor.Ev3Wrapper
let filename = resp.downloadFileBaseName || "pxt"
@ -101,7 +101,7 @@ export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
if (pxt.commands && pxt.commands.electronDeployAsync) {
return pxt.commands.electronDeployAsync(resp);
}
if (!isCli && pxt.commands && pxt.commands.saveOnlyAsync) {
if (pxt.commands && pxt.commands.saveOnlyAsync) {
return pxt.commands.saveOnlyAsync(resp);
}
return Promise.resolve();
@ -121,10 +121,7 @@ export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
.then(() => w.flashAsync(rbfPath, rbfBIN))
.then(() => w.runAsync(rbfPath))
.then(() => {
if (isCli)
return w.disconnectAsync()
else
return Promise.resolve()
//return Promise.delay(1000).then(() => w.dmesgAsync())
}).catch(e => {
// if we failed to initalize, retry

View File

@ -28,9 +28,9 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
<div class="ui grid stackable">
<div class="column five wide" style="background-color: #E2E2E2;">
<div class="ui header">${lf("First time here?")}</div>
<strong style="font-size:small">${lf("You must have version 1.10 or above of the firmware")}</strong>
<strong style="font-size:small">${lf("You must have version 1.10E or above of the firmware")}</strong>
<div style="justify-content: center;display: flex;padding: 1rem;">
<img class="ui image" src="./static/download/firmware.png" style="height:100px;" />
<img class="ui image" src="/static/download/firmware.png" style="height:100px;" />
</div>
<a href="/troubleshoot" target="_blank">${lf("Check your firmware version here and update if needed")}</a>
</div>
@ -42,7 +42,7 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
<div class="column">
<div class="ui">
<div class="image">
<img class="ui medium rounded image" src="./static/download/connect.svg" style="height:109px;width:261px;margin-bottom:1rem;" />
<img class="ui medium rounded image" src="/static/download/connect.svg" style="height:109px;width:261px;margin-bottom:1rem;" />
</div>
<div class="content">
<div class="description">
@ -57,7 +57,7 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
<div class="column">
<div class="ui">
<div class="image">
<img class="ui medium rounded image" src="./static/download/transfer.svg" style="height:109px;width:261px;margin-bottom:1rem;" />
<img class="ui medium rounded image" src="/static/download/transfer.svg" style="height:109px;width:261px;margin-bottom:1rem;" />
</div>
<div class="content">
<div class="description">

View File

@ -133,14 +133,27 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
this.setText(text);
}
getFirstValue(text: string) {
// Get first set of words up until last space
return this.normalizeText_(text.substring(0, text.lastIndexOf(' ')));
getFirstValue(value: string) {
const typeValue = value.indexOf('large') != -1 ? 'large' : 'medium';
const portValue = this.getSecondValue(value);
const isDual = portValue.length > 1;
return `${typeValue} motor${isDual ? 's' : ''}`;
}
getSecondValue(text: string) {
// Get last word
return this.normalizeText_(text.match(/\S*$/)[0]);
getSecondValue(value: string) {
return (value.indexOf('large') != -1) ?
value.substring(value.indexOf('large') + 5) :
value.substring(value.indexOf('medium') + 6);
}
getFirstValueI11n(value: string) {
const firstValue = this.getFirstValue(value);
const motorOptions = {
'medium motor': lf('medium motor'),
'large motor': lf('large motor'),
'large motors': lf('large motors')
}
return motorOptions[firstValue];
}
private normalizeText_(text: string) {
@ -198,8 +211,8 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
if (text === null) {
return text;
}
if (text.indexOf(' ') == -1) {
text = `large motors ${text}`;
if (text.indexOf('|') == -1) {
text = this.sourceBlock_.RTL ? `${text}|${lf("large motors")}` : `${lf("large motors")}|${text}`;
}
return text;
}
@ -296,16 +309,14 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
goog.dom.removeChildren(/** @type {!Element} */(this.textElement_));
goog.dom.removeChildren(/** @type {!Element} */(this.textElement2_));
var text = this.text_;
text = this.patchDualMotorText(text);
// First dropdown
const textNode1 = document.createTextNode(this.getFirstValue(text));
// Use one of the following options, medium motor, large motor or large motors (translated)
const textNode1 = document.createTextNode(this.getFirstValueI11n(this.value_));
this.textElement_.appendChild(textNode1);
// Second dropdown
// Second dropdown, no need to translate. Only port numbers
if (this.textElement2_) {
const textNode2 = document.createTextNode(this.getSecondValue(text));
const textNode2 = document.createTextNode(this.getSecondValue(this.value_));
this.textElement2_.appendChild(textNode2);
}
this.updateWidth();
@ -402,29 +413,28 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
contentDiv.setAttribute('aria-haspopup', 'true');
let options = this.getOptions();
// Hashmap of options
let opts = {};
let conts = {};
let vals = {};
// Go through all option values and split them into groups
for (let opt = 0; opt < options.length; opt++) {
let text = options[opt][0].alt ? options[opt][0].alt : options[opt][0];
if (text.indexOf(' ') == -1) {
// Patch dual motors as they don't have prefixes.
text = this.patchDualMotorText(text);
if (options[opt][0].alt) options[opt][0].alt = text;
}
const value = options[opt][1];
const firstValue = this.getFirstValue(text);
const secondValue = this.getSecondValue(text);
if (!opts[firstValue]) opts[firstValue] = [secondValue];
else opts[firstValue].push(secondValue);
// Store a hash of the original key value pairs for later
const motorValue = value.substring(value.indexOf('.') + 1);
const typeValue = motorValue.indexOf('large') == 0 ? 'large' : 'medium';
const portValue = motorValue.indexOf('large') == 0 ? motorValue.substring(5) : motorValue.substring(6);
const isDual = portValue.length > 1;
const text = `${typeValue} motor${isDual ? 's' : ''}|${portValue}`;
const key = `${typeValue} motor${isDual ? 's' : ''}`;
if (!opts[key]) opts[key] = [];
opts[key].push(portValue);
conts[text] = options[opt][0];
vals[text] = value;
}
const currentFirst = this.getFirstValue(this.text_);
const currentSecond = this.getSecondValue(this.text_);
const currentFirst = this.getFirstValue(this.value_);
const currentSecond = this.getSecondValue(this.value_);
if (!this.isFirst_) {
options = opts[currentFirst];
@ -432,9 +442,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
options = Object.keys(opts);
// Flip the first and second options to make it sorted the way we want it (medium, large, dual)
if (options.length == 3) {
const temp = options[1];
options[1] = options[0];
options[0] = temp;
options = [lf("medium motor"), lf("large motor"), lf("large motors")];
} else {
options.reverse();
}
@ -448,7 +456,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
const columns = options.length;
for (let i = 0, option: any; option = options[i]; i++) {
let text = this.isFirst_ ? option + ' ' + opts[option][0] : currentFirst + ' ' + option;
let text = this.isFirst_ ? option + '|' + (option.indexOf('motors') != -1 ? 'BC' : 'A') : currentFirst + '|' + option;
text = text.replace(/\xA0/g, ' ');
const content: any = conts[text];
const value = vals[text];
@ -466,7 +474,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
button.setAttribute('id', ':' + i); // For aria-activedescendant
button.setAttribute('role', 'menuitem');
button.setAttribute('class', 'blocklyDropDownButton');
button.title = this.isFirst_ ? this.getFirstValue(content.alt) : content.alt;
button.title = this.isFirst_ ? this.getFirstValueI11n(value) : this.getSecondValue(value);
button.style.width = ((this.itemWidth_) - 8) + 'px';
button.style.height = ((this.itemWidth_) - 8) + 'px';
let backgroundColor = this.backgroundColour_;
@ -495,7 +503,15 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
contentDiv.removeAttribute('aria-activedescendant');
});
let buttonImg = document.createElement('img');
buttonImg.src = this.isFirst_ ? isFirstUrl[option.replace(/\xA0/g, ' ')] : content.src;
let imgSrc = content.src;
if (this.isFirst_) {
const motorValue = value.substring(value.indexOf('.') + 1);
// Find out what kind of motor this is based on it's value, possible values: mediumX, largeX, and largeXY
if (motorValue.indexOf('medium') == 0) imgSrc = isFirstUrl['medium motor'];
else if (motorValue.length == 6) imgSrc = isFirstUrl['large motor'];
else imgSrc = isFirstUrl['large motors'];
}
buttonImg.src = imgSrc;
//buttonImg.alt = icon.alt;
// Upon click/touch, we will be able to get the clicked element as e.target
// Store a data attribute on all possible click targets so we can match it to the icon.

View File

@ -20,7 +20,7 @@ export class FieldMusic extends pxtblockly.FieldImages implements Blockly.FieldC
private categoriesCache_: string[];
constructor(text: string, options: FieldMusicOptions, validator?: Function) {
super(text, { sort: true, data: options.data }, validator);
super(text, { blocksInfo: options.blocksInfo, sort: true, data: options.data }, validator);
this.columns_ = parseInt(options.columns) || 4;
this.width_ = parseInt(options.width) || 380;

View File

@ -11,7 +11,7 @@ export class FieldPorts extends pxtblockly.FieldImages implements Blockly.FieldC
public isFieldCustom_ = true;
constructor(text: string, options: FieldPortsOptions, validator?: Function) {
super(text, { sort: true, data: options.data }, validator);
super(text, { blocksInfo: options.blocksInfo, sort: true, data: options.data }, validator);
this.columns_ = parseInt(options.columns) || 4;
this.width_ = parseInt(options.width) || 300;

View File

@ -1,285 +0,0 @@
namespace pxt.editor {
import HF2 = pxt.HF2
import U = pxt.U
function log(msg: string) {
pxt.log("EWRAP: " + msg)
}
export interface DirEntry {
name: string;
md5?: string;
size?: number;
}
const runTemplate = "C00882010084XX0060640301606400"
const usbMagic = 0x3d3f
export class Ev3Wrapper {
msgs = new U.PromiseBuffer<Uint8Array>()
private cmdSeq = U.randomUint32() & 0xffff;
private lock = new U.PromiseQueue();
isStreaming = false;
dataDump = false;
constructor(public io: pxt.HF2.PacketIO) {
io.onData = buf => {
buf = buf.slice(0, HF2.read16(buf, 0) + 2)
if (HF2.read16(buf, 4) == usbMagic) {
let code = HF2.read16(buf, 6)
let payload = buf.slice(8)
if (code == 1) {
let str = U.uint8ArrayToString(payload)
if (Util.isNodeJS)
console.log("SERIAL: " + str.replace(/\n+$/, ""))
else
window.postMessage({
type: 'serial',
id: 'n/a', // TODO?
data: str
}, "*")
} else
console.log("Magic: " + code + ": " + U.toHex(payload))
return
}
if (this.dataDump)
log("RECV: " + U.toHex(buf))
this.msgs.push(buf)
}
}
private allocCore(addSize: number, replyType: number) {
let len = 5 + addSize
let buf = new Uint8Array(len)
HF2.write16(buf, 0, len - 2) // pktLen
HF2.write16(buf, 2, this.cmdSeq++) // msgCount
buf[4] = replyType
return buf
}
private allocSystem(addSize: number, cmd: number, replyType = 1) {
let buf = this.allocCore(addSize + 1, replyType)
buf[5] = cmd
return buf
}
private allocCustom(code: number, addSize = 0) {
let buf = this.allocCore(1 + 2 + addSize, 0)
HF2.write16(buf, 4, usbMagic)
HF2.write16(buf, 6, code)
return buf
}
stopAsync() {
return this.isVmAsync()
.then(vm => {
if (vm) return Promise.resolve();
log(`stopping PXT app`)
let buf = this.allocCustom(2)
return this.justSendAsync(buf)
.then(() => Promise.delay(500))
})
}
dmesgAsync() {
log(`asking for DMESG buffer over serial`)
let buf = this.allocCustom(3)
return this.justSendAsync(buf)
}
runAsync(path: string) {
let codeHex = runTemplate.replace("XX", U.toHex(U.stringToUint8Array(path)))
let code = U.fromHex(codeHex)
let pkt = this.allocCore(2 + code.length, 0)
HF2.write16(pkt, 5, 0x0800)
U.memcpy(pkt, 7, code)
log(`run ${path}`)
return this.justSendAsync(pkt)
}
justSendAsync(buf: Uint8Array) {
return this.lock.enqueue("talk", () => {
this.msgs.drain()
if (this.dataDump)
log("SEND: " + U.toHex(buf))
return this.io.sendPacketAsync(buf)
})
}
talkAsync(buf: Uint8Array, altResponse = 0) {
return this.lock.enqueue("talk", () => {
this.msgs.drain()
if (this.dataDump)
log("TALK: " + U.toHex(buf))
return this.io.sendPacketAsync(buf)
.then(() => this.msgs.shiftAsync(1000))
.then(resp => {
if (resp[2] != buf[2] || resp[3] != buf[3])
U.userError("msg count de-sync")
if (buf[4] == 1) {
if (altResponse != -1 && resp[5] != buf[5])
U.userError("cmd de-sync")
if (altResponse != -1 && resp[6] != 0 && resp[6] != altResponse)
U.userError("cmd error: " + resp[6])
}
return resp
})
})
}
flashAsync(path: string, file: Uint8Array) {
log(`write ${file.length} bytes to ${path}`)
let handle = -1
let loopAsync = (pos: number): Promise<void> => {
if (pos >= file.length) return Promise.resolve()
let size = file.length - pos
if (size > 1000) size = 1000
let upl = this.allocSystem(1 + size, 0x93, 0x1)
upl[6] = handle
U.memcpy(upl, 6 + 1, file, pos, size)
return this.talkAsync(upl, 8) // 8=EOF
.then(() => loopAsync(pos + size))
}
let begin = this.allocSystem(4 + path.length + 1, 0x92)
HF2.write32(begin, 6, file.length) // fileSize
U.memcpy(begin, 10, U.stringToUint8Array(path))
return this.lock.enqueue("file", () =>
this.talkAsync(begin)
.then(resp => {
handle = resp[7]
return loopAsync(0)
}))
}
lsAsync(path: string): Promise<DirEntry[]> {
let lsReq = this.allocSystem(2 + path.length + 1, 0x99)
HF2.write16(lsReq, 6, 1024) // maxRead
U.memcpy(lsReq, 8, U.stringToUint8Array(path))
return this.talkAsync(lsReq, 8)
.then(resp =>
U.uint8ArrayToString(resp.slice(12)).split(/\n/).map(s => {
if (!s) return null as DirEntry
let m = /^([A-F0-9]+) ([A-F0-9]+) ([^\/]*)$/.exec(s)
if (m)
return {
md5: m[1],
size: parseInt(m[2], 16),
name: m[3]
}
else
return {
name: s.replace(/\/$/, "")
}
}).filter(v => !!v))
}
rmAsync(path: string): Promise<void> {
log(`rm ${path}`)
let rmReq = this.allocSystem(path.length + 1, 0x9c)
U.memcpy(rmReq, 6, U.stringToUint8Array(path))
return this.talkAsync(rmReq, 5)
.then(resp => { })
}
isVmAsync(): Promise<boolean> {
let path = "/no/such/dir"
let mkdirReq = this.allocSystem(path.length + 1, 0x9b)
U.memcpy(mkdirReq, 6, U.stringToUint8Array(path))
return this.talkAsync(mkdirReq, -1)
.then(resp => {
let isVM = resp[6] == 0x05
log(`${isVM ? "PXT app" : "VM"} running`)
return isVM
})
}
private streamFileOnceAsync(path: string, cb: (d: Uint8Array) => void) {
let fileSize = 0
let filePtr = 0
let handle = -1
let resp = (buf: Uint8Array): Promise<void> => {
if (buf[6] == 2) {
// handle not ready - file is missing
this.isStreaming = false
return Promise.resolve()
}
if (buf[6] != 0 && buf[6] != 8)
U.userError("bad response when streaming file: " + buf[6] + " " + U.toHex(buf))
this.isStreaming = true
fileSize = HF2.read32(buf, 7)
if (handle == -1) {
handle = buf[11]
log(`stream on, handle=${handle}`)
}
let data = buf.slice(12)
filePtr += data.length
if (data.length > 0)
cb(data)
if (buf[6] == 8) {
// end of file
this.isStreaming = false
return this.rmAsync(path)
}
let contFileReq = this.allocSystem(1 + 2, 0x97)
HF2.write16(contFileReq, 7, 1000) // maxRead
contFileReq[6] = handle
return Promise.delay(data.length > 0 ? 0 : 500)
.then(() => this.talkAsync(contFileReq, -1))
.then(resp)
}
let getFileReq = this.allocSystem(2 + path.length + 1, 0x96)
HF2.write16(getFileReq, 6, 1000) // maxRead
U.memcpy(getFileReq, 8, U.stringToUint8Array(path))
return this.talkAsync(getFileReq, -1).then(resp)
}
streamFileAsync(path: string, cb: (d: Uint8Array) => void) {
let loop = (): Promise<void> =>
this.lock.enqueue("file", () =>
this.streamFileOnceAsync(path, cb))
.then(() => Promise.delay(500))
.then(loop)
return loop()
}
downloadFileAsync(path: string, cb: (d: Uint8Array) => void) {
return this.lock.enqueue("file", () =>
this.streamFileOnceAsync(path, cb))
}
private initAsync() {
return Promise.resolve()
}
private resetState() {
}
reconnectAsync(first = false): Promise<void> {
this.resetState()
if (first) return this.initAsync()
log(`reconnect`);
return this.io.reconnectAsync()
.then(() => this.initAsync())
}
disconnectAsync() {
log(`disconnect`);
return this.io.disconnectAsync()
}
}
}

View File

@ -1,30 +1,3 @@
{
"name": "base",
"description": "The base library",
"files": [
"README.md",
"pxt-core.d.ts",
"pxt.cpp",
"pxtbase.h",
"core.cpp",
"pxt-helpers.ts",
"buffer.cpp",
"shims.d.ts",
"enums.d.ts",
"loops.cpp",
"math.ts",
"ns.ts",
"control.cpp",
"control.ts",
"eventcontext.ts",
"serial.cpp",
"serial.ts",
"fieldeditors.ts"
],
"testFiles": [
"test.ts"
],
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/base",
"public": true,
"dependencies": {}
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/base"
}

17
libs/base/shims.d.ts vendored
View File

@ -142,23 +142,12 @@ declare namespace control {
//% blockId="control_device_serial_number" block="device serial number" weight=9
//% help=control/device-serial-number shim=control::deviceSerialNumber
function deviceSerialNumber(): int32;
}
declare namespace serial {
/**
* Write some text to the serial port.
*
*/
//% help=serial/write-string
//% weight=87 blockHidden=true
//% blockId=serial_writestring block="serial|write string %text" shim=serial::writeString
function writeString(text: string): void;
/**
* Send a buffer across the serial connection.
*/
//% help=serial/write-buffer weight=6 blockHidden=true
//% blockId=serial_writebuffer block="serial|write buffer %buffer" shim=serial::writeBuffer
function writeBuffer(buffer: Buffer): void;
//% shim=control::__log
function __log(text: string): void;
}
// Auto-generated. Do not edit. Really.

View File

@ -1,48 +0,0 @@
/// <reference no-default-lib="true"/>
/**
* Reading and writing data to the console output.
*/
//% weight=12 color=#00451A icon="\uf112"
//% advanced=true
namespace console {
type Listener = (text: string) => void;
const listeners: Listener[] = [
(text: string) => serial.writeLine(text)
];
/**
* Write a line of text to the console output.
* @param value to send
*/
//% weight=90
//% help=console/log blockGap=8
//% blockId=console_log block="console|log %text"
export function log(text: string): void {
for (let i = 0; i < listeners.length; ++i)
listeners[i](text);
}
/**
* Write a name:value pair as a line of text to the console output.
* @param name name of the value stream, eg: "x"
* @param value to write
*/
//% weight=88 blockGap=8
//% help=console/log-value
//% blockId=console_log_value block="console|log value %name|= %value"
export function logValue(name: string, value: number): void {
log(`${name}: ${value}`)
}
/**
* Adds a listener for the log messages
* @param listener
*/
//%
export function addListener(listener: (text: string) => void) {
if (!listener) return;
listeners.push(listener);
}
}

View File

@ -23,3 +23,8 @@ namespace motors {
return turnratio;
}
}
//% icon="\uf112"
namespace console {
}

View File

@ -368,7 +368,8 @@ namespace motors {
}
private __move(steps: boolean, stepsOrTime: number, speed: number) {
step(this._port, {
control.dmesg("motor.__move")
const p = {
useSteps: steps,
step1: 0,
step2: stepsOrTime,
@ -376,7 +377,10 @@ namespace motors {
speed: this._regulated ? speed : undefined,
power: this._regulated ? undefined : speed,
useBrake: this._brake
})
};
control.dmesg("motor.1")
step(this._port, p)
control.dmesg("motor.__move end")
}
/**
@ -706,24 +710,36 @@ namespace motors {
}
function step(out: Output, opts: StepOptions) {
control.dmesg('step')
let op = opts.useSteps ? DAL.opOutputStepSpeed : DAL.opOutputTimeSpeed
let speed = opts.speed
if (speed == null) {
if (undefined == speed) {
speed = opts.power
op = opts.useSteps ? DAL.opOutputStepPower : DAL.opOutputTimePower
if (speed == null)
if (undefined == speed)
return
}
speed = Math.clamp(-100, 100, speed)
control.dmesg('speed: ' + speed)
let b = mkCmd(out, op, 15)
control.dmesg('STEP 5')
b.setNumber(NumberFormat.Int8LE, 2, speed)
// note that b[3] is padding
control.dmesg('STEP 1')
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 0, opts.step1)
control.dmesg('STEP 2')
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 1, opts.step2)
control.dmesg('STEP 3')
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 2, opts.step3)
b.setNumber(NumberFormat.Int8LE, 4 + 4 * 3, opts.useBrake ? 1 : 0)
control.dmesg('STEP 4')
control.dmesg('br ' + opts.useBrake);
const br = !!opts.useBrake ? 1 : 0;
control.dmesg('Step 4.5 ' + br)
b.setNumber(NumberFormat.Int8LE, 4 + 4 * 3, br)
control.dmesg('STEP 5')
writePWM(b)
control.dmesg('end step')
}
const types = [0, 0, 0, 0]

1
libs/core/platform.h Normal file
View File

@ -0,0 +1 @@
// leave empty

View File

@ -10,7 +10,6 @@
"linux.cpp",
"mmap.cpp",
"control.cpp",
"console.ts",
"timer.ts",
"serialnumber.cpp",
"buttons.ts",
@ -25,7 +24,8 @@
"enums.d.ts",
"dal.d.ts",
"icons.jres",
"ns.ts"
"ns.ts",
"platform.h"
],
"testFiles": [
"test.ts"

View File

@ -1,9 +1,16 @@
#ifndef __PXTCORE_H
#define __PXTCORE_H
#include <stdio.h>
namespace pxt {
void dmesg(const char *fmt, ...);
#define DMESG pxt::dmesg
}
static inline void itoa(int v, char *dst) {
snprintf(dst, 30, "%d", v);
}
#endif

View File

@ -1,4 +1,8 @@
// This is the last thing executed before user code
// pulse green, play startup sound, turn off light
brick.setStatusLight(StatusLight.GreenPulse);
// We pause for 100ms to give time to read sensor values, so they work in on_start block
pause(100)
pause(400)
// and we're ready
brick.setStatusLight(StatusLight.Off);

View File

@ -1,19 +1,19 @@
namespace music {
/**
* Get the frequency of a note.
* @param name the note name, eg: Note.C
* @param note the note name, eg: Note.C
*/
//% weight=1 help=music/note-frequency
//% blockId=device_note block="%note"
//% shim=TD_ID
//% color="#FFFFFF" colorSecondary="#FFFFFF" colorTertiary="#D67923"
//% note.fieldEditor="note" note.defl="1046"
//% note.fieldOptions.editorColour="#FF1493" note.fieldOptions.decompileLiterals=true
//% note.fieldOptions.minNote=52 note.fieldOptions.maxNote=75
//% note.fieldOptions.editorColour="#D67923" note.fieldOptions.decompileLiterals=true
//% note.fieldOptions.minNote=40 note.fieldOptions.maxNote=75
//% useEnumVal=1
//% weight=10 blockGap=8
export function noteFrequency(name: Note): number {
export function noteFrequency(note: Note): number {
//TODO fill in actual min/max note values
return name;
return note;
}
}

1
libs/screen/image.d.ts vendored Normal file
View File

@ -0,0 +1 @@
// leave empty

View File

@ -9,5 +9,5 @@ sensors.ultrasonic1.pauseUntil(UltrasonicSensorEvent.ObjectDetected);
## See Also
[on event](/reference/sensors/ultrasonic/on-event),
[distance](reference/sensors/ultrasonic/distance),
[pause until](reference/sensors/ultrasonic/pause-until)
[distance](/reference/sensors/ultrasonic/distance),
[pause until](/reference/sensors/ultrasonic/pause-until)

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "pxt-ev3",
"version": "0.3.2",
"version": "1.0.8",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "pxt-ev3",
"version": "0.3.2",
"version": "1.0.8",
"description": "LEGO MINDSTORMS EV3 for Microsoft MakeCode",
"private": true,
"keywords": [
@ -39,8 +39,8 @@
"webfonts-generator": "^0.4.0"
},
"dependencies": {
"pxt-common-packages": "0.23.15",
"pxt-core": "3.19.4"
"pxt-common-packages": "0.23.56",
"pxt-core": "4.0.9"
},
"scripts": {
"test": "node node_modules/pxt-core/built/pxt.js travis"

View File

@ -79,30 +79,33 @@
},
"appTheme": {
"accentColor": "#0089BF",
"logoWide": true,
"logoUrl": "https://education.lego.com/",
"logo": "./static/lego_education_logo.png",
"docsLogo": "./static/lego-logo.svg",
"portraitLogo": "./static/lego-logo.svg",
"footerLogo": "./static/lego-logo.svg",
"docsLogo": "./static/lego_education_logo.png",
"portraitLogo": "./static/lego_education_logo.png",
"cardLogo": "./static/icons/android-chrome-192x192.png",
"appLogo": "./static/icons/android-chrome-192x192.png",
"organization": "Microsoft MakeCode",
"organizationUrl": "https://makecode.com/",
"organizationUrl": "https://makecode.com/org",
"organizationLogo": "./static/Microsoft-logo_rgb_c-gray-square.png",
"organizationWideLogo": "./static/Microsoft-logo_rgb_c-gray.png",
"homeUrl": "https://makecode.legoeducation.com/",
"embedUrl": "https://makecode.legoeducation.com/",
"homeUrl": "https://makecode.mindstorms.com/",
"embedUrl": "https://makecode.mindstorms.com/",
"privacyUrl": "https://go.microsoft.com/fwlink/?LinkId=521839",
"termsOfUseUrl": "https://go.microsoft.com/fwlink/?LinkID=206977",
"githubUrl": "https://github.com/Microsoft/pxt-ev3",
"betaUrl": "https://makecode.legoeducation.com/about",
"driveDisplayName": "EV3",
"boardName": "LEGO® MINDSTORMS® Education EV3",
"copyrightText": "LEGO, the LEGO logo, MINDSTORMS and the MINDSTORMS EV3 logo are trademarks and/ or copyrights of the LEGO Group. ©2018 The LEGO Group. All rights reserved.",
"crowdinProject": "kindscript",
"selectLanguage": true,
"availableLocales": [
"en"
"en",
"de",
"ja",
"ru",
"zh-CN"
],
"highContrast": true,
"docMenu": [
@ -127,6 +130,7 @@
"path": "/reference"
}
],
"print": true,
"showHomeScreen": true,
"homeScreenHero": "./static/hero.png",
"invertedMenu": false,
@ -135,6 +139,7 @@
"invertedToolbox": false,
"coloredToolbox": true,
"hasAudio": true,
"saveInMenu": true,
"usbHelp": [],
"extendEditor": true,
"extendFieldEditors": true,
@ -172,7 +177,7 @@
"monacoColors": {
"editor.background": "#f9f9f9"
},
"fileNameExclusiveFilter": "[^a-zA-Z]"
"fileNameExclusiveFilter": "[^a-zA-Z0-9]"
},
"ignoreDocsErrors": true
}

View File

@ -30,7 +30,7 @@ namespace pxsim {
}
getSpeed() {
return this.speed * (this.polarity == 0 ? -1 : 1);
return this.speed * (!this._synchedMotor && this.polarity == 0 ? -1 : 1);
}
getAngle() {
@ -49,7 +49,7 @@ namespace pxsim {
// new command TODO: values
this.speedCmd = cmd;
this.speedCmdValues = values;
this.speedCmdTacho = this.angle;
this.speedCmdTacho = this.tacho;
this.speedCmdTime = pxsim.U.now();
delete this._synchedMotor;
}
@ -150,7 +150,8 @@ namespace pxsim {
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)
const isTimeCommand = this.speedCmd == DAL.opOutputTimePower || this.speedCmd == DAL.opOutputTimeSpeed;
const dstep = isTimeCommand
? pxsim.U.now() - this.speedCmdTime
: this.tacho - this.speedCmdTacho;
if (dstep < step1) // rampup
@ -161,6 +162,16 @@ namespace pxsim {
this.speed = speed * (step1 + step2 + step3 - dstep) / (step1 + step2 + step3);
else {
if (brake) this.speed = 0;
if (!isTimeCommand) {
// we need to patch the actual position of the motor when
// finishing the move as our integration step introduce errors
const deltaAngle = -Math.sign(speed) * (dstep - (step1 + step2 + step3));
if (deltaAngle) {
this.angle += deltaAngle;
this.tacho -= Math.abs(deltaAngle);
this.setChangedState();
}
}
this.clearSpeedCmd();
}
break;

View File

@ -15,6 +15,6 @@
"Maker": "maker"
},
"electronManifest": {
"latest": "v0.1.60"
"latest": "v0.4.2"
}
}

View File

@ -33,11 +33,12 @@
/* Music field editor */
.blocklyDropdownText {
.blocklyMusicFieldOptions .blocklyDropdownText, .blocklyMusicFieldCategories .blocklyDropdownText {
display: flex;
justify-content: center;
line-height: 1.5rem;
color: #fff;
font-size: 13px;
}
.blocklyMusicFieldCategories {
@ -47,6 +48,7 @@
right: 0;
top: 0;
width: 100%;
font-size: 13px;
}
.blocklyMusicFieldOptions {
margin-top: 80px;

View File

@ -7,9 +7,6 @@
@headerFont : "Open Sans","Arial Narrow","Helvetica Neue",Helvetica,Arial,sans-serif;
@pageFont : "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
@emSize : 14px;
@fontSize : 13px;
@primaryColor: @blue;
@secondaryColor: @yellow;
@ -31,6 +28,7 @@
@legoGreyDark: #f4f7f9;
@grey: @legoGreyLight;
@darkGrey: #999;
/* Lego official colors */
@ -152,6 +150,8 @@
@homeScreenBackground: #F2F2F2;
@homeCardBorderColor: #F2F2F2;
@homeDetailCloseBackground: @darkGrey;
/*-------------------
Editor
--------------------*/
@ -198,3 +198,9 @@
@serialBackgroundColor: #fff;
@serialGraphBackground: #F2F2F2;
@serialConsoleBackground: @serialGraphBackground;
/*-------------------
Extensions
--------------------*/
@extensionsHeaderBackground: @darkGrey;