diff --git a/.github/lock.yml b/.github/lock.yml
index 974f87a3..a1d7e6e1 100644
--- a/.github/lock.yml
+++ b/.github/lock.yml
@@ -30,13 +30,7 @@ lockLabel: false
# Comment to post before locking. Set to `false` to disable
-lockComment: >
-
- This thread has been automatically locked since there has not been
-
- any recent activity after it was closed. Please open a new issue for
-
- related bugs.
+lockComment: false
diff --git a/.gitignore b/.gitignore
index e0a67323..89b121a8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,4 +33,5 @@ crowdinstats.csv
*.iml
.vscode/.BROWSE.VC.DB-shm
.vscode/.BROWSE.VC.DB-wal
-package-lock.json
\ No newline at end of file
+package-lock.json
+.DS_Store
\ No newline at end of file
diff --git a/docs/examples/rando.md b/docs/examples/rando.md
index 009807ee..00670ad5 100644
--- a/docs/examples/rando.md
+++ b/docs/examples/rando.md
@@ -4,6 +4,6 @@ Generate a random coordinate and display it on the LED screen.
```blocks
basic.forever(() => {
- led.toggle(Math.randomRange(0, 5), Math.randomRange(0, 5))
+ led.toggle(Math.randomRange(0, 4), Math.randomRange(0, 4))
})
```
\ No newline at end of file
diff --git a/docs/projects/love-meter.md b/docs/projects/love-meter.md
index 84e25a75..37fbc01b 100644
--- a/docs/projects/love-meter.md
+++ b/docs/projects/love-meter.md
@@ -3,7 +3,6 @@
## Introduction @unplugged
Make a love meter, how sweet! The @boardname@ is feeling the love, then sometimes not so much!
-Tell everyone who you are. Show you name on the LEDs.
![Love meter banner message](/calliope/tutorials/05_love_meter_animation.gif)
diff --git a/docs/projects/snap-the-dot.md b/docs/projects/snap-the-dot.md
index 715c7260..5d3a0f55 100644
--- a/docs/projects/snap-the-dot.md
+++ b/docs/projects/snap-the-dot.md
@@ -8,13 +8,19 @@ Snap the dot is a game of skill where the player has to press **A** exactly when
This tutorial shows how to use the game engine.
-## Create a sprite @fullscreen
+## Make a sprite variable @fullscreen
-Drag a ``||game:create sprite||`` block onto the workspace. A sprite is a single pixel that can move on the screen. It has an ``x`` and ``y`` position along with a direction of motion.
+Create a new variable called `sprite`. Drag a ``||variables:set sprite to||`` into the ``||basic:on start||`` on the workspace.
```blocks
-let sprite: game.LedSprite = null
-sprite = game.createSprite(2, 2)
+let sprite = 0
+```
+## Create a sprite @fullscreen
+
+Pull out a ``||game:create sprite||`` block and put it in ``||variables:set sprite to||`` replacing the `0`. A sprite is a single pixel that can move on the screen. It has an ``x`` and ``y`` position along with a direction of motion.
+
+```blocks
+let sprite = game.createSprite(2, 2)
```
## Move the dot @fullscreen
@@ -22,8 +28,7 @@ sprite = game.createSprite(2, 2)
The sprite starts in the center facing right. Put a ``||game:move||`` block into the ``||basic:forever||`` to make it move. Notice how it moves to the right but does not bounce back.
```blocks
-let sprite: game.LedSprite = null
-sprite = game.createSprite(2, 2)
+let sprite = game.createSprite(2, 2)
basic.forever(function () {
sprite.move(1)
})
@@ -34,8 +39,7 @@ basic.forever(function () {
Grab a ``||game:if on edge, bounce||`` block to make the sprite bounce on the side of the screen. Also, add a ``||basic:pause||`` block to slow down the sprite.
```blocks
-let sprite: game.LedSprite = null
-sprite = game.createSprite(2, 2)
+let sprite = game.createSprite(2, 2)
basic.forever(function () {
sprite.move(1)
sprite.ifOnEdgeBounce()
@@ -54,13 +58,12 @@ When **A** is pressed, we test if the sprite is in the center or not.
Use a ``||input:on button pressed||`` block to handle the **A** button. Put in a ``||logic:if||`` block and test if ``||game:x||`` is equal to `2`.
```blocks
-let sprite: game.LedSprite = null
+let sprite = game.createSprite(2, 2)
input.onButtonPressed(Button.A, function () {
if (sprite.get(LedSpriteProperty.X) == 2) {
} else {
}
})
-sprite = game.createSprite(2, 2)
basic.forever(function () {
sprite.move(1)
basic.pause(100)
@@ -73,7 +76,7 @@ basic.forever(function () {
Finally, pull out an ``||game:add score||`` and a ``||game:game over||`` block to handle both success (sprite in the center) and failure (sprite not in the center).
```blocks
-let sprite: game.LedSprite = null
+let sprite = game.createSprite(2, 2)
input.onButtonPressed(Button.A, function () {
if (sprite.get(LedSpriteProperty.X) == 2) {
game.addScore(1)
@@ -81,7 +84,6 @@ input.onButtonPressed(Button.A, function () {
game.gameOver()
}
})
-sprite = game.createSprite(2, 2)
basic.forever(function () {
sprite.move(1)
basic.pause(100)
diff --git a/docs/reference/led/plot-bar-graph.md b/docs/reference/led/plot-bar-graph.md
index e64fbee5..cb5bd645 100644
--- a/docs/reference/led/plot-bar-graph.md
+++ b/docs/reference/led/plot-bar-graph.md
@@ -17,6 +17,15 @@ A bar graph is a kind of chart that shows numbers as lines with different length
* **high**: a [number](/types/number) that is the highest
possible number (maximum) that the **value** parameter can be. The lines in the bar graph will reach their highest point when **value** reaches this number. If **high** is `0`, then the largest value recently plotted is used as the maximum.
+### ~hint
+
+#### Serial Output
+
+The ``||led:plot bar graph||`` block also writes the number from **value** to the [serial](/reference/serial) port as a way to help you record
+values.
+
+### ~
+
## Example: chart acceleration
Show a bar graph of the [acceleration](/reference/input/acceleration)
diff --git a/docs/static/configurations/chrome-version.png b/docs/static/configurations/chrome-version.png
new file mode 100644
index 00000000..b7a4db67
Binary files /dev/null and b/docs/static/configurations/chrome-version.png differ
diff --git a/docs/static/configurations/edge-version.png b/docs/static/configurations/edge-version.png
new file mode 100644
index 00000000..f9c9095a
Binary files /dev/null and b/docs/static/configurations/edge-version.png differ
diff --git a/docs/static/configurations/firefox-version.png b/docs/static/configurations/firefox-version.png
new file mode 100644
index 00000000..d9b5684c
Binary files /dev/null and b/docs/static/configurations/firefox-version.png differ
diff --git a/docs/static/configurations/ie-version.png b/docs/static/configurations/ie-version.png
new file mode 100644
index 00000000..3fbc6e7c
Binary files /dev/null and b/docs/static/configurations/ie-version.png differ
diff --git a/docs/static/configurations/osx-version.png b/docs/static/configurations/osx-version.png
new file mode 100644
index 00000000..9457d7e4
Binary files /dev/null and b/docs/static/configurations/osx-version.png differ
diff --git a/docs/static/configurations/safari-version.png b/docs/static/configurations/safari-version.png
new file mode 100644
index 00000000..70d1d871
Binary files /dev/null and b/docs/static/configurations/safari-version.png differ
diff --git a/docs/static/configurations/windows-version.png b/docs/static/configurations/windows-version.png
new file mode 100644
index 00000000..06847ede
Binary files /dev/null and b/docs/static/configurations/windows-version.png differ
diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json
index d86dc4e6..d43084a7 100644
--- a/libs/core/_locales/core-jsdoc-strings.json
+++ b/libs/core/_locales/core-jsdoc-strings.json
@@ -89,8 +89,8 @@
"Gesture.FreeFall": "Raised when the board is falling!",
"Gesture.LogoDown": "Raised when the logo is downward and the screen is vertical",
"Gesture.LogoUp": "Raised when the logo is upward and the screen is vertical",
- "Gesture.ScreenDown": "Raised when the screen is pointing up and the board is horizontal",
- "Gesture.ScreenUp": "Raised when the screen is pointing down and the board is horizontal",
+ "Gesture.ScreenDown": "Raised when the screen is pointing down and the board is horizontal",
+ "Gesture.ScreenUp": "Raised when the screen is pointing up and the board is horizontal",
"Gesture.Shake": "Raised when shaken",
"Gesture.SixG": "Raised when a 6G shock is detected",
"Gesture.ThreeG": "Raised when a 3G shock is detected",
@@ -273,6 +273,8 @@
"control.eventValue": "Gets the value of the last event executed on the bus",
"control.eventValueId": "Returns the value of a C++ runtime constant",
"control.inBackground": "Schedules code that run in the background.",
+ "control.micros": "Gets current time in microseconds. Overflows every ~18 minutes.",
+ "control.millis": "Gets the number of milliseconds elapsed since power on.",
"control.onEvent": "Registers an event handler.",
"control.panic": "Display specified error code and stop the program.",
"control.raiseEvent": "Raises an event in the event bus.",
@@ -281,6 +283,7 @@
"control.raiseEvent|param|value": "Component specific code indicating the cause of the event.",
"control.reset": "Resets the BBC micro:bit.",
"control.runtimeWarning": "Display warning in the simulator.",
+ "control.waitForEvent": "Blocks the calling thread until the specified event is raised.",
"control.waitMicros": "Blocks the current fiber for the given microseconds",
"control.waitMicros|param|micros": "number of micro-seconds to wait. eg: 4",
"convertToText": "Convert any value to text",
@@ -467,9 +470,13 @@
"music.builtInMelody": "Gets the melody array of a built-in melody.",
"music.changeTempoBy": "Change the tempo by the specified amount",
"music.changeTempoBy|param|bpm": "The change in beats per minute to the tempo, eg: 20",
+ "music.melodyEditor": "Create a melody with the melody editor.",
"music.noteFrequency": "Get the frequency of a note.",
"music.noteFrequency|param|name": "the note name, eg: Note.C",
"music.onEvent": "Registers code to run on various melody events",
+ "music.playMelody": "Play a melody from the melody editor.",
+ "music.playMelody|param|melody": "- string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces, which will be played one at a time, ex: \"E D G F B A C5 B \"",
+ "music.playMelody|param|tempo": "- number in beats per minute (bpm), dictating how long each note will play for",
"music.playTone": "Plays a tone through pin ``P0`` for the given duration.",
"music.playTone|param|frequency": "pitch of the tone to play in Hertz (Hz), eg: Note.C",
"music.playTone|param|ms": "tone duration in milliseconds (ms)",
diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json
index 4ecc562e..801407b1 100644
--- a/libs/core/_locales/core-strings.json
+++ b/libs/core/_locales/core-strings.json
@@ -79,9 +79,9 @@
"Gesture.LogoDown|block": "logo down",
"Gesture.LogoUp": "Raised when the logo is upward and the screen is vertical",
"Gesture.LogoUp|block": "logo up",
- "Gesture.ScreenDown": "Raised when the screen is pointing up and the board is horizontal",
+ "Gesture.ScreenDown": "Raised when the screen is pointing down and the board is horizontal",
"Gesture.ScreenDown|block": "screen down",
- "Gesture.ScreenUp": "Raised when the screen is pointing down and the board is horizontal",
+ "Gesture.ScreenUp": "Raised when the screen is pointing up and the board is horizontal",
"Gesture.ScreenUp|block": "screen up",
"Gesture.Shake": "Raised when shaken",
"Gesture.Shake|block": "shake",
@@ -262,9 +262,11 @@
"control.eventValueId|block": "%id",
"control.eventValue|block": "event value",
"control.inBackground|block": "run in background",
+ "control.millis|block": "millis (ms)",
"control.onEvent|block": "on event|from %src=control_event_source_id|with value %value=control_event_value_id",
"control.raiseEvent|block": "raise event|from source %src=control_event_source_id|with value %value=control_event_value_id",
"control.reset|block": "reset",
+ "control.waitForEvent|block": "wait for event|from %src|with value %value",
"control.waitMicros|block": "wait (µs)%micros",
"control|block": "control",
"convertToText|block": "convert $value=math_number to text",
@@ -338,8 +340,10 @@
"music.beginMelody|block": "start melody %melody=device_builtin_melody| repeating %options",
"music.builtInMelody|block": "%melody",
"music.changeTempoBy|block": "change tempo by (bpm)|%value",
+ "music.melodyEditor|block": "$melody",
"music.noteFrequency|block": "%name",
"music.onEvent|block": "music on %value",
+ "music.playMelody|block": "play melody $melody at tempo $tempo|(bpm)",
"music.playTone|block": "play|tone %note=device_note|for %duration=device_beat",
"music.rest|block": "rest(ms)|%duration=device_beat",
"music.ringTone|block": "ring tone (Hz)|%note=device_note",
diff --git a/libs/core/control.cpp b/libs/core/control.cpp
index 0aff221f..c40c8bc6 100644
--- a/libs/core/control.cpp
+++ b/libs/core/control.cpp
@@ -223,6 +223,23 @@ namespace control {
release_fiber();
}
+ /**
+ * Gets the number of milliseconds elapsed since power on.
+ */
+ //% help=control/millis weight=50
+ //% blockId=control_running_time block="millis (ms)"
+ int millis() {
+ return system_timer_current_time();
+ }
+
+ /**
+ * Gets current time in microseconds. Overflows every ~18 minutes.
+ */
+ //%
+ int micros() {
+ return system_timer_current_time_us() & 0x3fffffff;
+ }
+
/**
* Schedules code that run in the background.
*/
@@ -232,6 +249,15 @@ namespace control {
runInParallel(a);
}
+ /**
+ * Blocks the calling thread until the specified event is raised.
+ */
+ //% help=control/wait-for-event async
+ //% blockId=control_wait_for_event block="wait for event|from %src|with value %value"
+ void waitForEvent(int src, int value) {
+ pxt::waitForEvent(src, value);
+ }
+
/**
* Resets the BBC micro:bit.
*/
diff --git a/libs/core/enums.d.ts b/libs/core/enums.d.ts
index 29693dd7..34620484 100644
--- a/libs/core/enums.d.ts
+++ b/libs/core/enums.d.ts
@@ -111,13 +111,13 @@ declare namespace basic {
//% jres=gestures.tiltbackwards
LogoDown = 2, // MICROBIT_ACCELEROMETER_EVT_TILT_DOWN
/**
- * Raised when the screen is pointing down and the board is horizontal
+ * Raised when the screen is pointing up and the board is horizontal
*/
//% block="screen up"
//% jres=gestures.frontsideup
ScreenUp = 5, // MICROBIT_ACCELEROMETER_EVT_FACE_UP
/**
- * Raised when the screen is pointing up and the board is horizontal
+ * Raised when the screen is pointing down and the board is horizontal
*/
//% block="screen down"
//% jres=gestures.backsideup
diff --git a/libs/core/input.cpp b/libs/core/input.cpp
index 03dc9592..d268df2a 100644
--- a/libs/core/input.cpp
+++ b/libs/core/input.cpp
@@ -75,13 +75,13 @@ enum class Gesture {
//% jres=gestures.tiltbackwards
LogoDown = MICROBIT_ACCELEROMETER_EVT_TILT_DOWN,
/**
- * Raised when the screen is pointing down and the board is horizontal
+ * Raised when the screen is pointing up and the board is horizontal
*/
//% block="screen up"
//% jres=gestures.frontsideup
ScreenUp = MICROBIT_ACCELEROMETER_EVT_FACE_UP,
/**
- * Raised when the screen is pointing up and the board is horizontal
+ * Raised when the screen is pointing down and the board is horizontal
*/
//% block="screen down"
//% jres=gestures.backsideup
@@ -363,26 +363,6 @@ namespace input {
return 0;
}
- /**
- * Gets the number of milliseconds elapsed since power on.
- */
- //% help=input/running-time weight=50 blockGap=8
- //% blockId=device_get_running_time block="running time (ms)"
- //% advanced=true
- int runningTime() {
- return system_timer_current_time();
- }
-
- /**
- * Gets the number of microseconds elapsed since power on.
- */
- //% help=input/running-time-micros weight=49
- //% blockId=device_get_running_time_micros block="running time (micros)"
- //% advanced=true
- int runningTimeMicros() {
- return system_timer_current_time_us();
- }
-
/**
* Obsolete, compass calibration is automatic.
*/
diff --git a/libs/core/input.ts b/libs/core/input.ts
index 59377fa3..c6d0a487 100644
--- a/libs/core/input.ts
+++ b/libs/core/input.ts
@@ -55,4 +55,25 @@ namespace input {
export function calibrate() {
input.calibrateCompass();
}
+
+
+ /**
+ * Gets the number of milliseconds elapsed since power on.
+ */
+ //% help=input/running-time weight=50 blockGap=8
+ //% blockId=device_get_running_time block="running time (ms)"
+ //% advanced=true
+ export function runningTime() {
+ return control.millis();
+ }
+
+ /**
+ * Gets the number of microseconds elapsed since power on.
+ */
+ //% help=input/running-time-micros weight=49
+ //% blockId=device_get_running_time_micros block="running time (micros)"
+ //% advanced=true
+ export function runningTimeMicros() {
+ return control.micros();
+ }
}
diff --git a/libs/core/music.ts b/libs/core/music.ts
index 3c619a8a..70c30a8f 100644
--- a/libs/core/music.ts
+++ b/libs/core/music.ts
@@ -174,6 +174,8 @@ enum MusicEvent {
*/
//% color=#DF4600 weight=98 icon="\uf025"
namespace music {
+ const INTERNAL_MELODY_ENDED = 5;
+
let beatsPerMinute: number = 120;
//% whenUsed
const freqs = hex`
@@ -358,14 +360,69 @@ namespace music {
currentBackgroundMelody = null;
control.raiseEvent(MICROBIT_MELODY_ID, MusicEvent.MelodyEnded);
control.raiseEvent(MICROBIT_MELODY_ID, MusicEvent.BackgroundMelodyResumed);
+ control.raiseEvent(MICROBIT_MELODY_ID, INTERNAL_MELODY_ENDED);
}
}
control.raiseEvent(MICROBIT_MELODY_ID, currentMelody.background ? MusicEvent.BackgroundMelodyEnded : MusicEvent.MelodyEnded);
+ if (!currentMelody.background)
+ control.raiseEvent(MICROBIT_MELODY_ID, INTERNAL_MELODY_ENDED);
currentMelody = null;
})
}
}
+
+ /**
+ * Play a melody from the melody editor.
+ * @param melody - string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces, which will be played one at a time, ex: "E D G F B A C5 B "
+ * @param tempo - number in beats per minute (bpm), dictating how long each note will play for
+ */
+ //% block="play melody $melody at tempo $tempo|(bpm)" blockId=playMelody
+ //% weight=85 blockGap=8 help=music/play-melody
+ //% melody.shadow="melody_editor"
+ //% tempo.min=40 tempo.max=500
+ //% tempo.defl=120
+ //% parts=headphone
+ export function playMelody(melody: string, tempo: number) {
+ melody = melody || "";
+ setTempo(tempo);
+ let notes: string[] = melody.split(" ").filter(n => !!n);
+ let newOctave = false;
+
+ // build melody string, replace '-' with 'R' and add tempo
+ // creates format like "C5-174 B4 A G F E D C "
+ for (let i = 0; i < notes.length; i++) {
+ if (notes[i] === "-") {
+ notes[i] = "R";
+ } else if (notes[i] === "C5") {
+ newOctave = true;
+ } else if (newOctave) { // change the octave if necesary
+ notes[i] += "4";
+ newOctave = false;
+ }
+ }
+
+ music.beginMelody(notes, MelodyOptions.Once)
+ control.waitForEvent(MICROBIT_MELODY_ID, INTERNAL_MELODY_ENDED);
+ }
+
+ /**
+ * Create a melody with the melody editor.
+ * @param melody
+ */
+ //% block="$melody" blockId=melody_editor
+ //% blockHidden = true
+ //% weight=85 blockGap=8
+ //% duplicateShadowOnDrag
+ //% melody.fieldEditor="melody"
+ //% melody.fieldOptions.decompileLiterals=true
+ //% melody.fieldOptions.decompileIndirectFixedInstances="true"
+ //% melody.fieldOptions.onParentBlock="true"
+ //% shim=TD_ID
+ export function melodyEditor(melody: string): string {
+ return melody;
+ }
+
/**
* Stops the melodies
* @param options which melody to stop
diff --git a/libs/core/shims.d.ts b/libs/core/shims.d.ts
index eb554327..9d21058b 100644
--- a/libs/core/shims.d.ts
+++ b/libs/core/shims.d.ts
@@ -346,22 +346,6 @@ declare namespace input {
//% advanced=true shim=input::magneticForce
function magneticForce(dimension: Dimension): int32;
- /**
- * Gets the number of milliseconds elapsed since power on.
- */
- //% help=input/running-time weight=50 blockGap=8
- //% blockId=device_get_running_time block="running time (ms)"
- //% advanced=true shim=input::runningTime
- function runningTime(): int32;
-
- /**
- * Gets the number of microseconds elapsed since power on.
- */
- //% help=input/running-time-micros weight=49
- //% blockId=device_get_running_time_micros block="running time (micros)"
- //% advanced=true shim=input::runningTimeMicros
- function runningTimeMicros(): int32;
-
/**
* Obsolete, compass calibration is automatic.
*/
@@ -388,6 +372,19 @@ declare namespace input {
//% advanced=true
declare namespace control {
+ /**
+ * Gets the number of milliseconds elapsed since power on.
+ */
+ //% help=control/millis weight=50
+ //% blockId=control_running_time block="millis (ms)" shim=control::millis
+ function millis(): int32;
+
+ /**
+ * Gets current time in microseconds. Overflows every ~18 minutes.
+ */
+ //% shim=control::micros
+ function micros(): int32;
+
/**
* Schedules code that run in the background.
*/
@@ -395,6 +392,13 @@ declare namespace control {
//% blockId="control_in_background" block="run in background" blockGap=8 shim=control::inBackground
function inBackground(a: () => void): void;
+ /**
+ * Blocks the calling thread until the specified event is raised.
+ */
+ //% help=control/wait-for-event async
+ //% blockId=control_wait_for_event block="wait for event|from %src|with value %value" shim=control::waitForEvent
+ function waitForEvent(src: int32, value: int32): void;
+
/**
* Resets the BBC micro:bit.
*/
diff --git a/libs/radio-broadcast/pxt.json b/libs/radio-broadcast/pxt.json
index b24a64b3..82f9ad60 100644
--- a/libs/radio-broadcast/pxt.json
+++ b/libs/radio-broadcast/pxt.json
@@ -1,12 +1,3 @@
{
- "name": "radio-broadcast",
- "description": "Adds new blocks for message communication in the radio category",
- "files": [
- "pxt.json",
- "radio-broadcast.ts"
- ],
- "dependencies": {
- "core": "file:../core",
- "radio": "file:../radio"
- }
+ "additionalFilePath": "../../node_modules/pxt-common-packages/libs/radio-broadcast"
}
diff --git a/libs/radio-broadcast/radio-broadcast.ts b/libs/radio-broadcast/radio-broadcast.ts
deleted file mode 100644
index c8b71835..00000000
--- a/libs/radio-broadcast/radio-broadcast.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-namespace radio {
- /**
- * Gets the message code
- */
- //% blockHidden=1 shim=ENUM_GET
- //% blockId=radioMessageCode block="$msg" enumInitialMembers="message1"
- //% enumName=RadioMessage enumMemberName=msg enumPromptHint="e.g. Start, Stop, Jump..."
- //% enumIsHash=1
- export function __message(msg: number): number {
- return msg;
- }
-
- /**
- * Broadcasts a message over radio
- * @param msg
- */
- //% blockId=radioBroadcastMessage block="radio send $msg"
- //% msg.shadow=radioMessageCode draggableParameters
- //% weight=200
- //% blockGap=8
- //% help=radio/send-message
- export function sendMessage(msg: number): void {
- // 0 is MICROBIT_EVT_ANY, shifting by 1
- radio.raiseEvent(DAL.MES_BROADCAST_GENERAL_ID, msg + 1);
- }
-
- /**
- * Registers code to run for a particular message
- * @param msg
- * @param handler
- */
- //% blockId=radioOnMessageReceived block="on radio $msg received"
- //% msg.shadow=radioMessageCode draggableParameters
- //% weight=199
- //% help=radio/on-received-message
- export function onReceivedMessage(msg: number, handler: () => void) {
- control.onEvent(DAL.MES_BROADCAST_GENERAL_ID, msg + 1, handler);
- }
-}
\ No newline at end of file
diff --git a/libs/radio/README.md b/libs/radio/README.md
deleted file mode 100644
index 1ffdf2b7..00000000
--- a/libs/radio/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# radio
-
-The radio library.
-
diff --git a/libs/radio/_locales/radio-jsdoc-strings.json b/libs/radio/_locales/radio-jsdoc-strings.json
index b4f635f1..a8018f54 100644
--- a/libs/radio/_locales/radio-jsdoc-strings.json
+++ b/libs/radio/_locales/radio-jsdoc-strings.json
@@ -9,7 +9,7 @@
"radio._packetProperty": "Gets a packet property.",
"radio._packetProperty|param|type": "the packet property type, eg: PacketProperty.time",
"radio.onDataPacketReceived": "Deprecated. Use onDataReceived() instead\nRegisters code to run when the radio receives a packet. Also takes the\nreceived packet from the radio queue.",
- "radio.onDataReceived": "Registers code to run when a packet is received over radio.",
+ "radio.onDataReceived": "Used internally by the library.",
"radio.onReceivedBuffer": "Registers code to run when the radio receives a buffer.",
"radio.onReceivedBufferDeprecated": "Registers code to run when the radio receives a buffer. Deprecated, use\nonReceivedBuffer instead.",
"radio.onReceivedNumber": "Registers code to run when the radio receives a number.",
diff --git a/libs/radio/pxt.json b/libs/radio/pxt.json
index 9a1374cc..3eb5331a 100644
--- a/libs/radio/pxt.json
+++ b/libs/radio/pxt.json
@@ -1,19 +1,5 @@
{
- "name": "radio",
- "description": "The radio services",
- "files": [
- "README.md",
- "shims.d.ts",
- "enums.d.ts",
- "radio.cpp",
- "radio.ts",
- "deprecated.ts"
- ],
- "icon": "./static/packages/radio/icon.png",
- "public": true,
- "dependencies": {
- "core": "file:../core"
- },
+ "additionalFilePath": "../../node_modules/pxt-common-packages/libs/radio",
"yotta": {
"config": {
"microbit-dal": {
@@ -22,6 +8,5 @@
}
}
}
- },
- "installedVersion": "rlfgis"
+ }
}
\ No newline at end of file
diff --git a/libs/radio/radio.cpp b/libs/radio/radio.cpp
deleted file mode 100644
index b4b324de..00000000
--- a/libs/radio/radio.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-#include "pxt.h"
-
-using namespace pxt;
-
-//% color=#E3008C weight=96 icon="\uf012"
-namespace radio {
-
- bool radioEnabled = false;
-
- int radioEnable() {
- int r = uBit.radio.enable();
- if (r != MICROBIT_OK) {
- uBit.panic(43);
- return r;
- }
- if (!radioEnabled) {
- uBit.radio.setGroup(pxt::programHash());
- uBit.radio.setTransmitPower(6); // start with high power by default
- radioEnabled = true;
- }
- return r;
- }
-
- /**
- * Sends an event over radio to neigboring devices
- */
- //% blockId=radioRaiseEvent block="radio raise event|from source %src=control_event_source_id|with value %value=control_event_value_id"
- //% blockExternalInputs=1
- //% advanced=true
- //% weight=1
- //% help=radio/raise-event
- void raiseEvent(int src, int value) {
- if (radioEnable() != MICROBIT_OK) return;
-
- uBit.radio.event.eventReceived(MicroBitEvent(src, value, CREATE_ONLY));
- }
-
- /**
- * Internal use only. Takes the next packet from the radio queue and returns its contents + RSSI in a Buffer
- */
- //%
- Buffer readRawPacket() {
- if (radioEnable() != MICROBIT_OK) return mkBuffer(NULL, 0);
-
- PacketBuffer p = uBit.radio.datagram.recv();
- if (p == PacketBuffer::EmptyPacket)
- return mkBuffer(NULL, 0);
-
- int rssi = p.getRSSI();
- uint8_t buf[MICROBIT_RADIO_MAX_PACKET_SIZE + sizeof(int)]; // packet length + rssi
- memset(buf, 0, sizeof(buf));
- memcpy(buf, p.getBytes(), p.length()); // data
- memcpy(buf + MICROBIT_RADIO_MAX_PACKET_SIZE, &rssi, sizeof(int)); // RSSi - assumes Int32LE layout
- return mkBuffer(buf, sizeof(buf));
- }
-
- /**
- * Internal use only. Sends a raw packet through the radio (assumes RSSI appened to packet)
- */
- //% async
- void sendRawPacket(Buffer msg) {
- if (radioEnable() != MICROBIT_OK || NULL == msg) return;
-
- // don't send RSSI data; and make sure no buffer underflow
- int len = msg->length - sizeof(int);
- if (len > 0)
- uBit.radio.datagram.send(msg->data, len);
- }
-
- /**
- * Registers code to run when a packet is received over radio.
- */
- //% help=radio/on-data-received
- //% weight=50
- //% blockId=radio_datagram_received_event block="radio on data received" blockGap=8
- //% deprecated=true
- void onDataReceived(Action body) {
- if (radioEnable() != MICROBIT_OK) return;
-
- registerWithDal(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, body);
- uBit.radio.datagram.recv(); // wake up read code
- }
-
- /**
- * Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.
- * @param id the group id between ``0`` and ``255``, eg: 1
- */
- //% help=radio/set-group
- //% weight=100
- //% blockId=radio_set_group block="radio set group %ID"
- //% id.min=0 id.max=255
- void setGroup(int id) {
- if (radioEnable() != MICROBIT_OK) return;
-
- uBit.radio.setGroup(id);
- }
-
- /**
- * Change the output power level of the transmitter to the given value.
- * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7
- */
- //% help=radio/set-transmit-power
- //% weight=9 blockGap=8
- //% blockId=radio_set_transmit_power block="radio set transmit power %power"
- //% power.min=0 power.max=7
- //% advanced=true
- void setTransmitPower(int power) {
- if (radioEnable() != MICROBIT_OK) return;
-
- uBit.radio.setTransmitPower(power);
- }
-
- /**
- * Change the transmission and reception band of the radio to the given channel
- * @param band a frequency band in the range 0 - 83. Each step is 1MHz wide, based at 2400MHz.
- **/
- //% help=radio/set-frequency-band
- //% weight=8 blockGap=8
- //% blockId=radio_set_frequency_band block="radio set frequency band %band"
- //% band.min=0 band.max=83
- //% advanced=true
- void setFrequencyBand(int band) {
- if (radioEnable() != MICROBIT_OK) return;
- uBit.radio.setFrequencyBand(band);
- }
-}
diff --git a/libs/radio/radio.ts b/libs/radio/radio.ts
deleted file mode 100644
index 2f564e8c..00000000
--- a/libs/radio/radio.ts
+++ /dev/null
@@ -1,444 +0,0 @@
-
-enum RadioPacketProperty {
- //% blockIdentity=radio._packetProperty
- //% block="signal strength"
- SignalStrength = 2,
- //% blockIdentity=radio._packetProperty
- //% block="time"
- Time = 0,
- //% block="serial number"
- //% blockIdentity=radio._packetProperty
- SerialNumber = 1
-}
-
-/**
- * Communicate data using radio packets
- */
-//% color=#E3008C weight=96 icon="\uf012"
-namespace radio {
-
- const MAX_FIELD_DOUBLE_NAME_LENGTH = 8;
- const MAX_PAYLOAD_LENGTH = 20;
- const PACKET_PREFIX_LENGTH = 9;
- const VALUE_PACKET_NAME_LEN_OFFSET = 13;
- const DOUBLE_VALUE_PACKET_NAME_LEN_OFFSET = 17;
-
- // Packet Spec:
- // | 0 | 1 ... 4 | 5 ... 8 | 9 ... 28
- // ----------------------------------------------------------------
- // | packet type | system time | serial number | payload
- //
- // Serial number defaults to 0 unless enabled by user
-
- // payload: number (9 ... 12)
- const PACKET_TYPE_NUMBER = 0;
- // payload: number (9 ... 12), name length (13), name (14 ... 26)
- const PACKET_TYPE_VALUE = 1;
- // payload: string length (9), string (10 ... 28)
- const PACKET_TYPE_STRING = 2;
- // payload: buffer length (9), buffer (10 ... 28)
- const PACKET_TYPE_BUFFER = 3;
- // payload: number (9 ... 16)
- const PACKET_TYPE_DOUBLE = 4;
- // payload: number (9 ... 16), name length (17), name (18 ... 26)
- const PACKET_TYPE_DOUBLE_VALUE = 5;
-
- let transmittingSerial: boolean;
- let initialized = false;
-
- export let lastPacket: RadioPacket;
- let onReceivedNumberHandler: (receivedNumber: number) => void;
- let onReceivedValueHandler: (name: string, value: number) => void;
- let onReceivedStringHandler: (receivedString: string) => void;
- let onReceivedBufferHandler: (receivedBuffer: Buffer) => void;
-
- function init() {
- if (initialized) return;
- initialized = true;
- onDataReceived(handleDataReceived);
- }
-
- function handleDataReceived() {
- let buffer: Buffer = readRawPacket();
- while (buffer && buffer.length) {
- lastPacket = RadioPacket.getPacket(buffer);
- switch (lastPacket.packetType) {
- case PACKET_TYPE_NUMBER:
- case PACKET_TYPE_DOUBLE:
- if (onReceivedNumberHandler)
- onReceivedNumberHandler(lastPacket.numberPayload);
- break;
- case PACKET_TYPE_VALUE:
- case PACKET_TYPE_DOUBLE_VALUE:
- if (onReceivedValueHandler)
- onReceivedValueHandler(lastPacket.stringPayload, lastPacket.numberPayload);
- break;
- case PACKET_TYPE_BUFFER:
- if (onReceivedBufferHandler)
- onReceivedBufferHandler(lastPacket.bufferPayload);
- break;
- case PACKET_TYPE_STRING:
- if (onReceivedStringHandler)
- onReceivedStringHandler(lastPacket.stringPayload);
- break;
- }
-
- // read next packet if any
- buffer = readRawPacket();
- }
- }
-
- /**
- * Registers code to run when the radio receives a number.
- */
- //% help=radio/on-received-number
- //% blockId=radio_on_number_drag block="on radio received" blockGap=16
- //% useLoc="radio.onDataPacketReceived" draggableParameters=reporter
- export function onReceivedNumber(cb: (receivedNumber: number) => void) {
- init();
- onReceivedNumberHandler = cb;
- }
-
- /**
- * Registers code to run when the radio receives a key value pair.
- */
- //% help=radio/on-received-value
- //% blockId=radio_on_value_drag block="on radio received" blockGap=16
- //% useLoc="radio.onDataPacketReceived" draggableParameters=reporter
- export function onReceivedValue(cb: (name: string, value: number) => void) {
- init();
- onReceivedValueHandler = cb;
- }
-
- /**
- * Registers code to run when the radio receives a string.
- */
- //% help=radio/on-received-string
- //% blockId=radio_on_string_drag block="on radio received" blockGap=16
- //% useLoc="radio.onDataPacketReceived" draggableParameters=reporter
- export function onReceivedString(cb: (receivedString: string) => void) {
- init();
- onReceivedStringHandler = cb;
- }
-
- /**
- * Registers code to run when the radio receives a buffer.
- */
- //% help=radio/on-received-buffer blockHidden=1
- //% blockId=radio_on_buffer_drag block="on radio received" blockGap=16
- //% useLoc="radio.onDataPacketReceived" draggableParameters=reporter
- export function onReceivedBuffer(cb: (receivedBuffer: Buffer) => void) {
- init();
- onReceivedBufferHandler = cb;
- }
-
- /**
- * Returns properties of the last radio packet received.
- * @param type the type of property to retrieve from the last packet
- */
- //% help=radio/received-packet
- //% weight=11 blockGap=8
- //% blockId=radio_received_packet block="received packet %type=radio_packet_property" blockGap=16
- export function receivedPacket(type: number) {
- if (lastPacket) {
- switch (type) {
- case RadioPacketProperty.Time: return lastPacket.time;
- case RadioPacketProperty.SerialNumber: return lastPacket.serial;
- case RadioPacketProperty.SignalStrength: return lastPacket.signal;
- }
- }
- return 0;
- }
-
- /**
- * Gets a packet property.
- * @param type the packet property type, eg: PacketProperty.time
- */
- //% blockId=radio_packet_property block="%note"
- //% shim=TD_ID blockHidden=1
- export function _packetProperty(type: RadioPacketProperty): number {
- return type;
- }
-
- export class RadioPacket {
- public static getPacket(data: Buffer) {
- // last 4 bytes is RSSi
- return new RadioPacket(data);
- }
-
- public static mkPacket(packetType: number) {
- const res = new RadioPacket();
- res.data[0] = packetType;
- return res;
- }
-
- private constructor(public readonly data?: Buffer) {
- if (!data) this.data = control.createBuffer(DAL.MICROBIT_RADIO_MAX_PACKET_SIZE + 4);
- }
-
- get signal() {
- return this.data.getNumber(NumberFormat.Int32LE, this.data.length - 4);
- }
-
- get packetType() {
- return this.data[0];
- }
-
- get time() {
- return this.data.getNumber(NumberFormat.Int32LE, 1);
- }
-
- set time(val: number) {
- this.data.setNumber(NumberFormat.Int32LE, 1, val);
- }
-
- get serial() {
- return this.data.getNumber(NumberFormat.Int32LE, 5);
- }
-
- set serial(val: number) {
- this.data.setNumber(NumberFormat.Int32LE, 5, val);
- }
-
- get stringPayload() {
- const offset = getStringOffset(this.packetType) as number;
- return offset ? this.data.slice(offset + 1, this.data[offset]).toString() : undefined;
- }
-
- set stringPayload(val: string) {
- const offset = getStringOffset(this.packetType) as number;
- if (offset) {
- const buf = control.createBufferFromUTF8(truncateString(val, getMaxStringLength(this.packetType)));
- this.data[offset] = buf.length;
- this.data.write(offset + 1, buf);
- }
- }
-
- get numberPayload() {
- switch (this.packetType) {
- case PACKET_TYPE_NUMBER:
- case PACKET_TYPE_VALUE:
- return this.data.getNumber(NumberFormat.Int32LE, PACKET_PREFIX_LENGTH);
- case PACKET_TYPE_DOUBLE:
- case PACKET_TYPE_DOUBLE_VALUE:
- return this.data.getNumber(NumberFormat.Float64LE, PACKET_PREFIX_LENGTH);
- }
- return undefined;
- }
-
- set numberPayload(val: number) {
- switch (this.packetType) {
- case PACKET_TYPE_NUMBER:
- case PACKET_TYPE_VALUE:
- this.data.setNumber(NumberFormat.Int32LE, PACKET_PREFIX_LENGTH, val);
- break;
- case PACKET_TYPE_DOUBLE:
- case PACKET_TYPE_DOUBLE_VALUE:
- this.data.setNumber(NumberFormat.Float64LE, PACKET_PREFIX_LENGTH, val);
- break;
- }
- }
-
- get bufferPayload() {
- const len = this.data[PACKET_PREFIX_LENGTH];
- return this.data.slice(PACKET_PREFIX_LENGTH + 1, len);
- }
-
- set bufferPayload(b: Buffer) {
- const len = Math.min(b.length, MAX_PAYLOAD_LENGTH - 1);
- this.data[PACKET_PREFIX_LENGTH] = len;
- this.data.write(PACKET_PREFIX_LENGTH + 1, b.slice(0, len));
- }
-
- hasString() {
- return this.packetType === PACKET_TYPE_STRING ||
- this.packetType === PACKET_TYPE_VALUE ||
- this.packetType === PACKET_TYPE_DOUBLE_VALUE;
- }
-
- hasNumber() {
- return this.packetType === PACKET_TYPE_NUMBER ||
- this.packetType === PACKET_TYPE_DOUBLE ||
- this.packetType === PACKET_TYPE_VALUE ||
- this.packetType === PACKET_TYPE_DOUBLE_VALUE;
- }
- }
-
-
- /**
- * Broadcasts a number over radio to any connected micro:bit in the group.
- */
- //% help=radio/send-number
- //% weight=60
- //% blockId=radio_datagram_send block="radio send number %value" blockGap=8
- export function sendNumber(value: number) {
- let packet: RadioPacket;
-
- if (value === (value | 0)) {
- packet = RadioPacket.mkPacket(PACKET_TYPE_NUMBER);
- }
- else {
- packet = RadioPacket.mkPacket(PACKET_TYPE_DOUBLE);
- }
-
- packet.numberPayload = value;
- sendPacket(packet);
- }
-
- /**
- * Broadcasts a name / value pair along with the device serial number
- * and running time to any connected micro:bit in the group. The name can
- * include no more than 8 characters.
- * @param name the field name (max 8 characters), eg: "name"
- * @param value the numeric value
- */
- //% help=radio/send-value
- //% weight=59
- //% blockId=radio_datagram_send_value block="radio send|value %name|= %value" blockGap=8
- export function sendValue(name: string, value: number) {
- let packet: RadioPacket;
-
- if (value === (value | 0)) {
- packet = RadioPacket.mkPacket(PACKET_TYPE_VALUE);
- }
- else {
- packet = RadioPacket.mkPacket(PACKET_TYPE_DOUBLE_VALUE);
- }
-
- packet.numberPayload = value;
- packet.stringPayload = name;
- sendPacket(packet);
- }
-
- /**
- * Broadcasts a string along with the device serial number
- * and running time to any connected micro:bit in the group.
- */
- //% help=radio/send-string
- //% weight=58
- //% blockId=radio_datagram_send_string block="radio send string %msg"
- //% msg.shadowOptions.toString=true
- export function sendString(value: string) {
- const packet = RadioPacket.mkPacket(PACKET_TYPE_STRING);
- packet.stringPayload = value;
- sendPacket(packet);
- }
-
- /**
- * Broadcasts a buffer (up to 19 bytes long) along with the device serial number
- * and running time to any connected micro:bit in the group.
- */
- //% help=radio/send-buffer
- //% weight=57
- //% advanced=true
- export function sendBuffer(msg: Buffer) {
- const packet = RadioPacket.mkPacket(PACKET_TYPE_BUFFER);
- packet.bufferPayload = msg;
- sendPacket(packet);
- }
-
- /**
- * Writes the last received packet to serial as JSON. This should be called
- * within an ``onDataPacketReceived`` callback.
- */
- //% help=radio/write-received-packet-to-serial
- //% weight=3
- //% blockId=radio_write_packet_serial block="radio write received packet to serial"
- //% advanced=true
- export function writeReceivedPacketToSerial() {
- if (lastPacket) writeToSerial(lastPacket)
- }
-
- /**
- * Set the radio to transmit the serial number in each message.
- * @param transmit value indicating if the serial number is transmitted, eg: true
- */
- //% help=radio/set-transmit-serial-number
- //% weight=8 blockGap=8
- //% blockId=radio_set_transmit_serial_number block="radio set transmit serial number %transmit"
- //% advanced=true
- export function setTransmitSerialNumber(transmit: boolean) {
- transmittingSerial = transmit;
- }
-
- /**
- * Gets the received signal strength indicator (RSSI) from the last packet taken
- * from the radio queue (via ``receiveNumber``, ``receiveString``, etc). Not supported in simulator.
- */
- //% help=radio/received-signal-strength
- //% weight=40
- //% blockId=radio_datagram_rssi block="radio received signal strength"
- //% deprecated=true blockHidden=true
- export function receivedSignalStrength(): number {
- return lastPacket ? lastPacket.signal : 0;
- }
-
- export function writeToSerial(packet: RadioPacket) {
- serial.writeString("{");
- serial.writeString("\"t\":");
- serial.writeString("" + packet.time);
- serial.writeString(",\"s\":");
- serial.writeString("" + packet.serial);
-
- if (packet.hasString()) {
- serial.writeString(",\"n\":\"");
- serial.writeString(packet.stringPayload);
- serial.writeString("\"");
- }
- if (packet.packetType == PACKET_TYPE_BUFFER) {
- serial.writeString(",\"b\":\"");
- // TODO: proper base64 encoding
- serial.writeString(packet.bufferPayload.toString());
- serial.writeString("\"");
- }
- if (packet.hasNumber()) {
- serial.writeString(",\"v\":");
- serial.writeString("" + packet.numberPayload);
- }
-
- serial.writeString("}\r\n");
- }
-
- function sendPacket(packet: RadioPacket) {
- packet.time = input.runningTime();
- packet.serial = transmittingSerial ? control.deviceSerialNumber() : 0;
- radio.sendRawPacket(packet.data);
- }
-
- function truncateString(str: string, bytes: number) {
- str = str.substr(0, bytes);
- let buff = control.createBufferFromUTF8(str);
-
- while (buff.length > bytes) {
- str = str.substr(0, str.length - 1);
- buff = control.createBufferFromUTF8(str);
- }
-
- return str;
- }
-
- function getStringOffset(packetType: number) {
- switch (packetType) {
- case PACKET_TYPE_STRING:
- return PACKET_PREFIX_LENGTH;
- case PACKET_TYPE_VALUE:
- return VALUE_PACKET_NAME_LEN_OFFSET;
- case PACKET_TYPE_DOUBLE_VALUE:
- return DOUBLE_VALUE_PACKET_NAME_LEN_OFFSET;
- default:
- return undefined;
- }
- }
-
- function getMaxStringLength(packetType: number) {
- switch (packetType) {
- case PACKET_TYPE_STRING:
- return MAX_PAYLOAD_LENGTH - 2;
- case PACKET_TYPE_VALUE:
- case PACKET_TYPE_DOUBLE_VALUE:
- return MAX_FIELD_DOUBLE_NAME_LENGTH;
- default:
- return undefined;
- }
- }
-}
\ No newline at end of file
diff --git a/libs/radio/shims.d.ts b/libs/radio/shims.d.ts
index e7983bad..e7f3d06f 100644
--- a/libs/radio/shims.d.ts
+++ b/libs/radio/shims.d.ts
@@ -28,12 +28,12 @@ declare namespace radio {
function sendRawPacket(msg: Buffer): void;
/**
- * Registers code to run when a packet is received over radio.
+ * Used internally by the library.
*/
//% help=radio/on-data-received
- //% weight=50
+ //% weight=0
//% blockId=radio_datagram_received_event block="radio on data received" blockGap=8
- //% deprecated=true shim=radio::onDataReceived
+ //% deprecated=true blockHidden=1 shim=radio::onDataReceived
function onDataReceived(body: () => void): void;
/**
diff --git a/libs/radio/deprecated.ts b/libs/radio/targetoverrides.ts
similarity index 79%
rename from libs/radio/deprecated.ts
rename to libs/radio/targetoverrides.ts
index 3677a650..1dab5c14 100644
--- a/libs/radio/deprecated.ts
+++ b/libs/radio/targetoverrides.ts
@@ -97,19 +97,6 @@ namespace radio {
onReceivedBuffer(cb);
}
- /**
- * Reads the next packet from the radio queue and and writes it to serial
- * as JSON.
- */
- //% help=radio/write-value-to-serial
- //% weight=3
- //% blockId=radio_write_value_serial block="radio write value to serial"
- //% deprecated=true
- export function writeValueToSerial() {
- const p = RadioPacket.getPacket(radio.readRawPacket());
- writeToSerial(p);
- }
-
/**
* Returns the number payload from the last packet taken from the radio queue
* (via ``receiveNumber``, ``receiveString``, etc) or 0 if that packet did not
@@ -185,4 +172,67 @@ namespace radio {
lastPacket = RadioPacket.getPacket(readRawPacket());
return receivedString();
}
+
+ /**
+ * Gets the received signal strength indicator (RSSI) from the last packet taken
+ * from the radio queue (via ``receiveNumber``, ``receiveString``, etc). Not supported in simulator.
+ */
+ //% help=radio/received-signal-strength
+ //% weight=40
+ //% blockId=radio_datagram_rssi block="radio received signal strength"
+ //% deprecated=true blockHidden=true
+ export function receivedSignalStrength(): number {
+ return lastPacket ? lastPacket.signal : 0;
+ }
+
+ /**
+ * Reads the next packet from the radio queue and and writes it to serial
+ * as JSON.
+ */
+ //% help=radio/write-value-to-serial
+ //% weight=3
+ //% blockId=radio_write_value_serial block="radio write value to serial"
+ //% deprecated=true
+ export function writeValueToSerial() {
+ const p = RadioPacket.getPacket(radio.readRawPacket());
+ writeToSerial(p);
+ }
+
+ /**
+ * Writes the last received packet to serial as JSON. This should be called
+ * within an ``onDataPacketReceived`` callback.
+ */
+ //% help=radio/write-received-packet-to-serial
+ //% weight=3
+ //% blockId=radio_write_packet_serial block="radio write received packet to serial"
+ //% advanced=true deprecated=true
+ export function writeReceivedPacketToSerial() {
+ if (lastPacket) writeToSerial(lastPacket)
+ }
+
+ function writeToSerial(packet: RadioPacket) {
+ serial.writeString("{");
+ serial.writeString("\"t\":");
+ serial.writeString("" + packet.time);
+ serial.writeString(",\"s\":");
+ serial.writeString("" + packet.serial);
+
+ if (packet.hasString()) {
+ serial.writeString(",\"n\":\"");
+ serial.writeString(packet.stringPayload);
+ serial.writeString("\"");
+ }
+ if (packet.packetType == PACKET_TYPE_BUFFER) {
+ serial.writeString(",\"b\":\"");
+ // TODO: proper base64 encoding
+ serial.writeString(packet.bufferPayload.toString());
+ serial.writeString("\"");
+ }
+ if (packet.hasNumber()) {
+ serial.writeString(",\"v\":");
+ serial.writeString("" + packet.numberPayload);
+ }
+
+ serial.writeString("}\r\n");
+ }
}
\ No newline at end of file
diff --git a/libs/radio/test.ts b/libs/radio/test.ts
deleted file mode 100644
index 78182f64..00000000
--- a/libs/radio/test.ts
+++ /dev/null
@@ -1,349 +0,0 @@
-/**
- * Tests for the radio. Press A on mbit 1 and B on mbit 2 to run the tests.
- * Sends random ints, doubles, strings, and buffers and checks them on
- * the other side
- */
-
-class FastRandom {
- private lfsr: number;
- public seed: number;
-
- constructor(seed?: number) {
- if (seed === undefined) seed = Math.randomRange(0x0001, 0xFFFF);
- this.seed = seed;
- this.lfsr = seed;
- }
-
- next(): number {
- return this.lfsr = (this.lfsr >> 1) ^ ((-(this.lfsr & 1)) & 0xb400);
- }
-
- randomRange(min: number, max: number): number {
- return min + (max > min ? this.next() % (max - min + 1) : 0);
- }
-
- reset() {
- this.lfsr = this.seed;
- }
-}
-
-enum TestStage {
- Integer,
- String,
- Double,
- IntValue,
- DblValue,
- Buffer
-}
-
-const TEST_COUNT = 30;
-
-radio.setGroup(78)
-const rand = new FastRandom(1234);
-
-let stage = TestStage.Integer;
-
-function initSender() {
- let lastReceived: number;
- let lastString: string;
- let testIndex = 0;
- let lastBuf: Buffer;
-
- let lastAck = -1;
-
- rand.reset();
- basic.clearScreen();
-
- // Send loop
- control.inBackground(function () {
- while (true) {
- for (let i = 0; i < TEST_COUNT; i++) {
- toggle(testIndex);
-
- if (stage === TestStage.Integer) {
- lastReceived = getNextInt();
- }
- else if (stage === TestStage.Double) {
- lastReceived = getNextDouble();
- }
- else if (stage === TestStage.IntValue) {
- lastString = getNextName();
- console.log(truncateString(lastString, 8))
- lastReceived = getNextInt();
- }
- else if (stage === TestStage.DblValue) {
- lastString = getNextName();
- lastReceived = getNextDouble();
- }
- else if (stage === TestStage.String) {
- lastString = getNextString();
- console.log(truncateString(lastString, 19))
- }
- else if (stage === TestStage.Buffer) {
- lastBuf = getNextBuffer();
- }
-
- while (lastAck !== testIndex) {
- if (stage === TestStage.Integer || stage === TestStage.Double) {
- radio.sendNumber(lastReceived)
- }
- else if (stage === TestStage.IntValue || stage === TestStage.DblValue) {
- radio.sendValue(lastString, lastReceived)
- }
- else if (stage === TestStage.String) {
- radio.sendString(lastString);
- }
- else if (stage === TestStage.Buffer) {
- radio.sendBuffer(lastBuf);
- }
- basic.pause(10);
- }
- testIndex++;
- }
-
- stage++;
- if (stage > TestStage.Buffer) {
- basic.showIcon(IconNames.Yes);
- return;
- }
- }
- })
-
- radio.onReceivedNumber(function (receivedNumber: number) {
- if (receivedNumber > lastAck) {
- lastAck = receivedNumber;
- }
- });
-}
-
-let lastReceived: number;
-let lastString: string;
-let testIndex = -1;
-let running = true;
-let lastBuf: Buffer;
-
-let lastPacket = new radio.Packet();
-let currentPacket = new radio.Packet();
-
-function truncateString(str: string, bytes: number) {
- str = str.substr(0, bytes);
- let buff = control.createBufferFromUTF8(str);
-
- while (buff.length > bytes) {
- str = str.substr(0, str.length - 1);
- buff = control.createBufferFromUTF8(str);
- }
-
- return str;
-}
-
-function initReceiver() {
-
- rand.reset();
-
- basic.clearScreen();
-
- radio.onDataReceived(function () {
- radio.receiveNumber();
-
- currentPacket.receivedNumber = radio.receivedNumber();
- currentPacket.receivedString = radio.receivedString();
- currentPacket.receivedBuffer = radio.receivedBuffer();
-
- if (currentPacket.receivedNumber === lastPacket.receivedNumber &&
- currentPacket.receivedString === lastPacket.receivedString &&
- checkBufferEqual(currentPacket.receivedBuffer, lastPacket.receivedBuffer)) {
- return;
- }
-
- lastPacket.receivedNumber = currentPacket.receivedNumber
- lastPacket.receivedString = currentPacket.receivedString
- lastPacket.receivedBuffer = currentPacket.receivedBuffer
-
- switch (stage) {
- case TestStage.Integer:
- verifyInt(radio.receivedNumber());
- break;
- case TestStage.Double:
- verifyDouble(radio.receivedNumber());
- break;
- case TestStage.IntValue:
- verifyIntValue(radio.receivedString(), radio.receivedNumber());
- break;
- case TestStage.DblValue:
- verifyDblValue(radio.receivedString(), radio.receivedNumber());
- break;
- case TestStage.String:
- verifyString(radio.receivedString());
- break;
- case TestStage.Buffer:
- verifyBuffer(radio.receivedBuffer());
- break;
- }
- })
-
- control.inBackground(function () {
- while (running) {
- radio.sendNumber(testIndex);
- basic.pause(10)
- }
- })
-}
-
-function nextTest() {
- testIndex++;
- toggle(testIndex);
- console.log(`test ${testIndex}`)
- if (((testIndex + 1) % TEST_COUNT) === 0) {
- stage++;
-
- if (stage > TestStage.Buffer) {
- basic.showIcon(IconNames.Yes)
- running = false;
- }
- }
-}
-
-function verifyInt(int: number) {
- if (int === lastReceived) return;
- lastReceived = int;
- if (lastReceived != getNextInt()) fail();
- nextTest()
-}
-
-function verifyDouble(dbl: number) {
- if (dbl === lastReceived) return;
- lastReceived = dbl;
- if (lastReceived != getNextDouble()) fail();
- nextTest()
-}
-
-function verifyIntValue(name: string, val: number) {
- if (val === lastReceived) return;
- lastReceived = val;
-
- if (name != truncateString(getNextName(), 8) || lastReceived != getNextInt()) fail();
- nextTest()
-}
-
-function verifyDblValue(name: string, val: number) {
- if (val === lastReceived) return;
- lastReceived = val;
-
- if (name != truncateString(getNextName(), 8) || lastReceived != getNextDouble()) fail();
- nextTest()
-}
-
-function verifyString(str: string) {
- if (!str || str === lastString) return;
-
- lastString = str;
- let next = truncateString(getNextString(), 19);
-
- if (lastString !== next) {
- console.log(`got ${control.createBufferFromUTF8(lastString).toHex()} expected ${control.createBufferFromUTF8(next).toHex()}`)
- }
- nextTest()
-}
-
-function verifyBuffer(buf: Buffer) {
- if (checkBufferEqual(lastBuf, buf)) return;
-
- lastBuf = buf;
-
- if (!checkBufferEqual(lastBuf, getNextBuffer())) {
- fail();
- }
- nextTest()
-}
-
-function fail() {
- control.panic(testIndex);
-}
-
-
-let _lastInt: number;
-let _lastDbl: number;
-let _lastStr: string;
-let _lastBuf: Buffer;
-let _lastNam: string;
-
-function getNextInt(): number {
- let res = rand.next();
- if (!res || res === _lastInt) return getNextInt();
- _lastInt = res;
- return res;
-}
-
-function getNextDouble(): number {
- let res = rand.next() / rand.next();
- if (res === _lastDbl) return getNextDouble();
- _lastDbl = res;
- return res;
-}
-
-function getNextString(): string {
- let len = rand.randomRange(1, 19);
- let res = "";
- for (let i = 0; i < len; i++) {
- res += String.fromCharCode(rand.next() & 0xbfff);
- }
-
- if (res === _lastStr) return getNextString();
-
- _lastStr = res;
- return res;
-}
-
-function getNextName(): string {
- let len = rand.randomRange(1, 8);
- let res = "";
- for (let i = 0; i < len; i++) {
- res += String.fromCharCode(rand.next() & 0xbfff);
- }
-
- if (res === _lastNam) return getNextName();
-
- _lastNam = res;
- return res;
-}
-
-function getNextBuffer(): Buffer {
- let len = rand.randomRange(0, 8);
- let res = control.createBuffer(len);
-
- for (let i = 0; i < len; i++) {
- res[i] = rand.next() & 0xff;
- }
-
- if (checkBufferEqual(_lastBuf, res)) return getNextBuffer();
-
- _lastBuf = res;
- return res;
-}
-
-function checkBufferEqual(a: Buffer, b: Buffer) {
- if (a === b) return true;
- if ((!a && b) || (a && !b)) return false;
- if (a.length != b.length) return false;
- for (let i = 0; i < a.length; i++) {
- if (a[i] !== b[i]) return false;
- }
- return true;
-}
-
-input.onButtonPressed(Button.A, function () {
- basic.showString("S");
- initSender();
-})
-
-input.onButtonPressed(Button.B, function () {
- basic.showString("R");
- initReceiver();
-})
-
-function toggle(index: number) {
- const x = index % 5;
- const y = Math.idiv(index, 5) % 5;
- led.toggle(x, y);
-}
diff --git a/package-lock.json b/package-lock.json
index b7fca913..35a29d04 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -215,6 +215,13 @@
"bn.js": "^4.0.0",
"inherits": "^2.0.1",
"minimalistic-assert": "^1.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ }
}
},
"assert": {
@@ -368,9 +375,9 @@
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
},
"bn.js": {
- "version": "4.11.8",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
- "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz",
+ "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA=="
},
"body-parser": {
"version": "1.19.0",
@@ -554,20 +561,40 @@
"requires": {
"bn.js": "^4.1.0",
"randombytes": "^2.0.1"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ }
}
},
"browserify-sign": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
- "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz",
+ "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==",
"requires": {
- "bn.js": "^4.1.1",
- "browserify-rsa": "^4.0.0",
- "create-hash": "^1.1.0",
- "create-hmac": "^1.1.2",
- "elliptic": "^6.0.0",
- "inherits": "^2.0.1",
- "parse-asn1": "^5.0.0"
+ "bn.js": "^5.1.1",
+ "browserify-rsa": "^4.0.1",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "elliptic": "^6.5.2",
+ "inherits": "^2.0.4",
+ "parse-asn1": "^5.1.5",
+ "readable-stream": "^3.6.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
}
},
"browserify-zlib": {
@@ -579,12 +606,12 @@
}
},
"browserslist": {
- "version": "4.11.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.1.tgz",
- "integrity": "sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g==",
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz",
+ "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==",
"requires": {
- "caniuse-lite": "^1.0.30001038",
- "electron-to-chromium": "^1.3.390",
+ "caniuse-lite": "^1.0.30001043",
+ "electron-to-chromium": "^1.3.413",
"node-releases": "^1.1.53",
"pkg-up": "^2.0.0"
}
@@ -692,9 +719,9 @@
}
},
"caniuse-lite": {
- "version": "1.0.30001043",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001043.tgz",
- "integrity": "sha512-MrBDRPJPDBYwACtSQvxg9+fkna5jPXhJlKmuxenl/ml9uf8LHKlDmLpElu+zTW/bEz7lC1m0wTDD7jiIB+hgFg=="
+ "version": "1.0.30001051",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001051.tgz",
+ "integrity": "sha512-sw8UUnTlRevawTMZKN7vpfwSjCBVoiMPlYd8oT2VwNylyPCBdMAUmLGUApnYYTtIm5JXsQegUAY7GPHqgfDzjw=="
},
"caseless": {
"version": "0.12.0",
@@ -732,9 +759,9 @@
}
},
"chokidar": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz",
- "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==",
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
+ "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
"requires": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
@@ -743,7 +770,7 @@
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
- "readdirp": "~3.3.0"
+ "readdirp": "~3.4.0"
}
},
"chownr": {
@@ -936,6 +963,13 @@
"requires": {
"bn.js": "^4.1.0",
"elliptic": "^6.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ }
}
},
"create-hash": {
@@ -1005,9 +1039,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -1075,9 +1109,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -1129,9 +1163,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -1164,9 +1198,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -1361,6 +1395,13 @@
"bn.js": "^4.1.0",
"miller-rabin": "^4.0.0",
"randombytes": "^2.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ }
}
},
"dom-serialize": {
@@ -1460,9 +1501,9 @@
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"electron-to-chromium": {
- "version": "1.3.413",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.413.tgz",
- "integrity": "sha512-Jm1Rrd3siqYHO3jftZwDljL2LYQafj3Kki5r+udqE58d0i91SkjItVJ5RwlJn9yko8i7MOcoidVKjQlgSdd1hg=="
+ "version": "1.3.428",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.428.tgz",
+ "integrity": "sha512-u3+5jEfgLKq/hGO96YfAoOAM1tgFnRDTCD5mLuev44tttcXix+INtVegAkmGzUcfDsnzkPt51XXurXZLLwXt0w=="
},
"elliptic": {
"version": "6.5.2",
@@ -1476,6 +1517,13 @@
"inherits": "^2.0.1",
"minimalistic-assert": "^1.0.0",
"minimalistic-crypto-utils": "^1.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ }
}
},
"encodeurl": {
@@ -1831,9 +1879,9 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fsevents": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz",
- "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+ "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
"optional": true
},
"function-bind": {
@@ -1993,12 +2041,30 @@
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
},
"hash-base": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
- "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+ "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
"requires": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+ "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
+ }
}
},
"hash.js": {
@@ -2761,12 +2827,19 @@
"requires": {
"bn.js": "^4.0.0",
"brorand": "^1.0.1"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ }
}
},
"mime": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
- "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA=="
+ "version": "2.4.5",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz",
+ "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w=="
},
"mime-db": {
"version": "1.42.0",
@@ -2825,9 +2898,9 @@
}
},
"mkdirp-classic": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz",
- "integrity": "sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g=="
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
},
"mocha": {
"version": "5.1.0",
@@ -2926,17 +2999,17 @@
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
"node-abi": {
- "version": "2.15.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.15.0.tgz",
- "integrity": "sha512-FeLpTS0F39U7hHZU1srAK4Vx+5AHNVOTP+hxBNQknR/54laTHSFIJkDWDqiquY1LeLUgTfPN7sLPhMubx0PLAg==",
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.16.0.tgz",
+ "integrity": "sha512-+sa0XNlWDA6T+bDLmkCUYn6W5k5W6BPRL6mqzSCs6H/xUgtl4D5x2fORKDzopKiU6wsyn/+wXlRXwXeSp+mtoA==",
"requires": {
"semver": "^5.4.1"
}
},
"node-releases": {
- "version": "1.1.53",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz",
- "integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ=="
+ "version": "1.1.55",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.55.tgz",
+ "integrity": "sha512-H3R3YR/8TjT5WPin/wOoHOUPHgvj8leuU/Keta/rwelEQN9pA/S2Dx8/se4pZ2LBxSd0nAGzsNzhqwa77v7F1w=="
},
"noop-logger": {
"version": "0.1.1",
@@ -3254,9 +3327,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3283,9 +3356,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3314,9 +3387,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3344,9 +3417,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3369,9 +3442,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3394,9 +3467,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3419,9 +3492,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3447,9 +3520,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3482,9 +3555,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3518,9 +3591,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3551,9 +3624,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3586,9 +3659,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3619,9 +3692,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3654,9 +3727,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3681,9 +3754,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3714,9 +3787,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3747,9 +3820,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3779,9 +3852,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3811,9 +3884,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3843,9 +3916,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3876,9 +3949,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3907,9 +3980,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3939,9 +4012,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -3972,9 +4045,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -4000,9 +4073,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -4043,9 +4116,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -4075,9 +4148,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -4092,9 +4165,9 @@
}
},
"postcss-value-parser": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz",
- "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg=="
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
+ "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ=="
},
"prebuild-install": {
"version": "5.3.3",
@@ -4185,6 +4258,13 @@
"parse-asn1": "^5.0.0",
"randombytes": "^2.0.1",
"safe-buffer": "^5.1.2"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ }
}
},
"pump": {
@@ -4250,18 +4330,18 @@
}
},
"pxt-common-packages": {
- "version": "6.21.9",
- "resolved": "https://registry.npmjs.org/pxt-common-packages/-/pxt-common-packages-6.21.9.tgz",
- "integrity": "sha512-vbUtA4GDE+N4YCaWdC9mBVr0B1xHMj5Ad4NtxFRxbpkeuceZDd0OvGfZvFYHn624t9jUcfuwl4dmhZrXUAPclg==",
+ "version": "6.21.10",
+ "resolved": "https://registry.npmjs.org/pxt-common-packages/-/pxt-common-packages-6.21.10.tgz",
+ "integrity": "sha512-GsNfjTe0YWQX4nn5lMiXST79yeb8OGCZbeJAP6I0dFfahoCM1H2tQqY/hMEPAznY1QZEgHkYvpw8SEWJvbK6Vw==",
"requires": {
"@jacdac/jacdac-ts": "^0.0.9",
- "pxt-core": "^5.34.1"
+ "pxt-core": "^5.36.2"
}
},
"pxt-core": {
- "version": "5.36.1",
- "resolved": "https://registry.npmjs.org/pxt-core/-/pxt-core-5.36.1.tgz",
- "integrity": "sha512-tls8in91gUL1IVG+iLnAsJqEwWsva645snPNvuzM/fzxmna6kA1ZwlHFDAPcpFukZ32cIORyRxRq8ZsplaKVTw==",
+ "version": "5.36.9",
+ "resolved": "https://registry.npmjs.org/pxt-core/-/pxt-core-5.36.9.tgz",
+ "integrity": "sha512-2rrKF+dSrYRwc0GjhPKNR4onzrN4njaWoXQrb9fBvOxsDvpRdrcNnzOi3X7aMv4ocoBYG6wEkCZnk+Ti+AOEFw==",
"requires": {
"applicationinsights-js": "^1.0.20",
"bluebird": "3.5.1",
@@ -4399,11 +4479,11 @@
}
},
"readdirp": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz",
- "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==",
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
+ "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
"requires": {
- "picomatch": "^2.0.7"
+ "picomatch": "^2.2.1"
}
},
"request": {
@@ -4504,9 +4584,9 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"resolve": {
- "version": "1.16.1",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.1.tgz",
- "integrity": "sha512-rmAglCSqWWMrrBv/XM6sW0NuRFiKViw/W4d9EbC4pt+49H8JwHy+mcGmALTEg504AUDcLTvb1T2q3E9AnmY+ig==",
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+ "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
"requires": {
"path-parse": "^1.0.6"
}
@@ -4588,9 +4668,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -5001,9 +5081,9 @@
},
"dependencies": {
"postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+ "version": "7.0.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
+ "integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
diff --git a/package.json b/package.json
index 519b09f6..98b4be38 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
"typescript": "^3.7.5"
},
"dependencies": {
- "pxt-common-packages": "6.21.9",
- "pxt-core": "5.36.1"
+ "pxt-common-packages": "6.21.10",
+ "pxt-core": "5.36.9"
}
}
diff --git a/pxtarget.json b/pxtarget.json
index ca6c140e..05be91a8 100644
--- a/pxtarget.json
+++ b/pxtarget.json
@@ -302,14 +302,11 @@
"experiments": [
"allowPackageExtensions",
"instructions",
- "debugger",
"debugExtensionCode",
"bluetoothUartConsole",
"bluetoothPartialFlashing",
"simScreenshot",
- "simGif",
- "qrCode",
- "githubBlocksDiff"
+ "simGif"
],
"bluetoothUartFilters": [
{
@@ -325,14 +322,6 @@
"name": "Reference",
"path": "/reference"
},
- {
- "name": "Blocks",
- "path": "/blocks"
- },
- {
- "name": "JavaScript",
- "path": "/javascript"
- },
{
"name": "Hardware",
"path": "/device"
@@ -347,6 +336,12 @@
"coloredToolbox": true,
"monacoToolbox": true,
"hasAudio": true,
+ "socialOptions": {
+ "orgTwitterHandle": "MSMakeCode",
+ "hashtags": "MakeCode",
+ "discourse": "https://forum.makecode.com/",
+ "discourseCategory": "micro:bit"
+ },
"blocklyOptions": {
"grid": {
"spacing": 45,
@@ -373,6 +368,7 @@
},
"highContrast": true,
"greenScreen": true,
+ "accessibleBlocks": true,
"print": true,
"selectLanguage": true,
"availableLocales": [
@@ -391,7 +387,7 @@
"ja",
"ko",
"nl",
- "no",
+ "nb",
"pl",
"pt-BR",
"pt-PT",
@@ -416,6 +412,7 @@
},
"showProjectSettings": true,
"scriptManager": true,
+ "debugger": true,
"simGifTransparent": "rgba(0,0,0,0)",
"simGifMaxFrames": 44,
"simScreenshotMaxUriLength": 300000,
diff --git a/sim/dalboard.ts b/sim/dalboard.ts
index de2b9da4..6f18e9cd 100644
--- a/sim/dalboard.ts
+++ b/sim/dalboard.ts
@@ -1,7 +1,8 @@
///
namespace pxsim {
- export class DalBoard extends CoreBoard {
+ export class DalBoard extends CoreBoard
+ implements RadioBoard {
// state & update logic for component services
ledMatrixState: LedMatrixState;
edgeConnectorState: EdgeConnectorState;
@@ -67,7 +68,10 @@ namespace pxsim {
"P3": DAL.MICROBIT_ID_IO_P16
}
});
- this.builtinParts["radio"] = this.radioState = new RadioState(runtime);
+ this.builtinParts["radio"] = this.radioState = new RadioState(runtime, {
+ ID_RADIO: DAL.MICROBIT_ID_RADIO,
+ RADIO_EVT_DATAGRAM: DAL.MICROBIT_RADIO_EVT_DATAGRAM
+ });
this.builtinParts["accelerometer"] = this.accelerometerState = new AccelerometerState(runtime);
this.builtinParts["serial"] = this.serialState = new SerialState();
this.builtinParts["thermometer"] = this.thermometerState = new ThermometerState();
@@ -173,7 +177,7 @@ namespace pxsim {
pxsim.initCurrentRuntime = initRuntimeWithDalBoard;
}
- export function board() {
+ export function board(): DalBoard {
return runtime.board as DalBoard;
}
}
diff --git a/sim/state/edgeconnectorsim.ts b/sim/state/edgeconnectorsim.ts
index d4e04a45..b136fbd7 100644
--- a/sim/state/edgeconnectorsim.ts
+++ b/sim/state/edgeconnectorsim.ts
@@ -32,6 +32,11 @@ namespace pxsim {
setPull(pull: number) {
this.pull = pull;
+ switch(pull) {
+ case PinPullMode.PullDown: this.value = 0; break;
+ case PinPullMode.PullUp: this.value = 1023; break;
+ default: this.value = Math_.randomRange(0, 1023); break;
+ }
}
analogReadPin(): number {
diff --git a/sim/state/misc.ts b/sim/state/misc.ts
index c1e4a099..d672b190 100644
--- a/sim/state/misc.ts
+++ b/sim/state/misc.ts
@@ -47,6 +47,19 @@ namespace pxsim.control {
export function waitMicros(micros: number) {
// TODO
}
+ export function waitForEvent(id: number, evid: number) {
+ const cb = getResume();
+ board().bus.wait(id, evid, cb);
+ }
+
+ export function millis(): number {
+ return runtime.runningTime();
+ }
+
+ export function micros(): number {
+ return runtime.runningTimeUs();
+ }
+
export function deviceName(): string {
let b = board();
@@ -94,14 +107,6 @@ namespace pxsim.pxtcore {
}
namespace pxsim.input {
- export function runningTime(): number {
- return runtime.runningTime();
- }
-
- export function runningTimeMicros(): number {
- return runtime.runningTimeUs();
- }
-
export function calibrateCompass() {
// device calibrates...
}
diff --git a/sim/state/radio.ts b/sim/state/radio.ts
deleted file mode 100644
index 72edb713..00000000
--- a/sim/state/radio.ts
+++ /dev/null
@@ -1,147 +0,0 @@
-namespace pxsim {
- export interface PacketBuffer {
- payload: SimulatorRadioPacketPayload;
- rssi: number;
- serial: number;
- time: number;
- }
-
- // Extends interface in pxt-core
- export interface SimulatorRadioPacketPayload {
- bufferData?: Uint8Array;
- }
-
- export class RadioDatagram {
- datagram: PacketBuffer[] = [];
- lastReceived: PacketBuffer = RadioDatagram.defaultPacket();
-
- constructor(private runtime: Runtime) {
- }
-
- queue(packet: PacketBuffer) {
- if (this.datagram.length < 4) {
- this.datagram.push(packet);
- }
- (runtime.board).bus.queue(DAL.MICROBIT_ID_RADIO, DAL.MICROBIT_RADIO_EVT_DATAGRAM);
- }
-
- send(payload: SimulatorRadioPacketPayload) {
- const b = board();
- Runtime.postMessage({
- type: "radiopacket",
- broadcast: true,
- rssi: -42, // -42 is the strongest signal
- serial: b.radioState.transmitSerialNumber ? pxsim.control.deviceSerialNumber() : 0,
- time: new Date().getTime(),
- payload
- })
- }
-
- recv(): PacketBuffer {
- let r = this.datagram.shift();
- if (!r) r = RadioDatagram.defaultPacket();
- return this.lastReceived = r;
- }
-
- private static defaultPacket(): PacketBuffer {
- return {
- rssi: -1,
- serial: 0,
- time: 0,
- payload: { type: -1, groupId: 0, bufferData: new Uint8Array(0) }
- };
- }
- }
-
- export class RadioState {
- power = 0;
- transmitSerialNumber = false;
- datagram: RadioDatagram;
- groupId: number;
- band: number;
-
- constructor(runtime: Runtime) {
- this.datagram = new RadioDatagram(runtime);
- this.power = 6; // default value
- this.groupId = 0;
- this.band = 7; // https://github.com/lancaster-university/microbit-dal/blob/master/inc/core/MicroBitConfig.h#L320
- }
-
- public setGroup(id: number) {
- this.groupId = id & 0xff; // byte only
- }
-
- setTransmitPower(power: number) {
- power = power | 0;
- this.power = Math.max(0, Math.min(7, power));
- }
-
- setTransmitSerialNumber(sn: boolean) {
- this.transmitSerialNumber = !!sn;
- }
-
- setFrequencyBand(band: number) {
- band = band | 0;
- if (band < 0 || band > 83) return;
- this.band = band;
- }
-
- raiseEvent(id: number, eventid: number) {
- Runtime.postMessage({
- type: "eventbus",
- broadcast: true,
- id,
- eventid,
- power: this.power,
- group: this.groupId
- })
- }
-
- receivePacket(packet: SimulatorRadioPacketMessage) {
- if (this.groupId == packet.payload.groupId)
- this.datagram.queue(packet)
- }
- }
-}
-
-namespace pxsim.radio {
- export function raiseEvent(id: number, eventid: number): void {
- board().radioState.raiseEvent(id, eventid);
- }
-
- export function setGroup(id: number): void {
- board().radioState.setGroup(id);
- }
-
- export function setTransmitPower(power: number): void {
- board().radioState.setTransmitPower(power);
- }
-
- export function setFrequencyBand(band: number) {
- board().radioState.setFrequencyBand(band);
- }
-
- export function sendRawPacket(buf: RefBuffer) {
- let cb = getResume();
- board().radioState.datagram.send({
- type: 0,
- groupId: board().radioState.groupId,
- bufferData: buf.data
- });
- setTimeout(cb, 1);
- }
-
- export function readRawPacket() {
- const packet = board().radioState.datagram.recv();
- return new RefBuffer(packet.payload.bufferData)
- }
-
- export function receivedSignalStrength(): number {
- return board().radioState.datagram.lastReceived.rssi;
- }
-
- export function onDataReceived(handler: RefAction): void {
- pxtcore.registerWithDal(DAL.MICROBIT_ID_RADIO, DAL.MICROBIT_RADIO_EVT_DATAGRAM, handler);
- readRawPacket();
- }
-}
\ No newline at end of file
diff --git a/sim/tsconfig.json b/sim/tsconfig.json
index d043b21a..2fa70fa6 100644
--- a/sim/tsconfig.json
+++ b/sim/tsconfig.json
@@ -11,5 +11,11 @@
"lib": ["dom", "dom.iterable", "scripthost", "es6"],
"types": ["bluebird"],
"typeRoots": ["../node_modules/@types"]
- }
+ },
+ "include": [
+ "*.ts",
+ "state/*.ts",
+ "visuals/*.ts",
+ "../node_modules/pxt-common-packages/libs/radio/sim/*.ts"
+ ]
}
diff --git a/sim/visuals/microbit.ts b/sim/visuals/microbit.ts
index c1c4bd14..f7e1fa7b 100644
--- a/sim/visuals/microbit.ts
+++ b/sim/visuals/microbit.ts
@@ -1106,10 +1106,10 @@ namespace pxsim.visuals {
}
else if (pin.mode & PinFlags.Touch) {
v = pin.touched ? "0%" : "100%";
- if (text) text.textContent = "";
+ if (text) text.textContent = "TOUCHED";
} else {
v = "100%";
- if (text) text.textContent = "";
+ if (text) text.textContent = "unused";
}
if (v) svg.setGradientValue(this.pinGradients[index], v);
}
@@ -1558,4 +1558,4 @@ namespace pxsim.visuals {
})
}
}
-}
\ No newline at end of file
+}
diff --git a/targetconfig.json b/targetconfig.json
index b5c30d3e..4b55f7ed 100644
--- a/targetconfig.json
+++ b/targetconfig.json
@@ -185,7 +185,18 @@
"EBOTICS/pxt-eboticsMIBO",
"KitronikLtd/pxt-kitronik-halohd",
"dugbraden/pxt-climate-action-kit",
- "alsrobot-microbit-makecode-packages/MiniCruise"
+ "alsrobot-microbit-makecode-packages/MiniCruise",
+ "4tronix/ServoBit",
+ "DFRobot/pxt-maqueen",
+ "DFRobot/pxt-DFRobot-microIoT",
+ "mu-opensource/pxt-muvision",
+ "KitronikLtd/pxt-kitronik-clip-detector",
+ "DFRobot/pxt-DFRobot-NaturalScience",
+ "strawbees/pxt-robotic-inventions",
+ "daferdur/pxt-myHX711",
+ "CytronTechnologies/pxt-edubit",
+ "MakeAndLearn/pxt-microshield",
+ "elecfreaks/pxt-TPBot"
],
"preferredRepos": [
"Microsoft/pxt-neopixel",
@@ -199,33 +210,6 @@
"MKleinSB/pxt-foldio"
]
},
- "languages": [
- "en",
- "ar",
- "cs",
- "da",
- "de",
- "el",
- "es-ES",
- "fi",
- "fr",
- "hu",
- "it",
- "ja",
- "ko",
- "nl",
- "no",
- "pt-BR",
- "pt-PT",
- "ru",
- "si-LK",
- "sk",
- "sv-SE",
- "tr",
- "uk",
- "zh-CN",
- "zh-TW"
- ],
"galleries": {
"First Steps": "calliope/firststeps",
"Tutorials": "calliope/tutorials",
diff --git a/theme/site/elements/button.overrides b/theme/site/elements/button.overrides
index cba59efe..c172e5f5 100644
--- a/theme/site/elements/button.overrides
+++ b/theme/site/elements/button.overrides
@@ -1,3 +1,3 @@
/*******************************
Site Overrides
-*******************************/
+*******************************/
\ No newline at end of file
diff --git a/theme/site/globals/site.variables b/theme/site/globals/site.variables
old mode 100644
new mode 100755