fetch pxt-microbit v2.2.30 (#102)
* undo buttonEvent * fetch microbit v2.2.30 Co-authored-by: Amerlander <gitkraken@juriwolf.de>
8
.github/lock.yml
vendored
@ -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
|
||||
|
||||
|
||||
|
||||
|
1
.gitignore
vendored
@ -34,3 +34,4 @@ crowdinstats.csv
|
||||
.vscode/.BROWSE.VC.DB-shm
|
||||
.vscode/.BROWSE.VC.DB-wal
|
||||
package-lock.json
|
||||
.DS_Store
|
@ -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))
|
||||
})
|
||||
```
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
BIN
docs/static/configurations/chrome-version.png
vendored
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
docs/static/configurations/edge-version.png
vendored
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
docs/static/configurations/firefox-version.png
vendored
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
docs/static/configurations/ie-version.png
vendored
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
docs/static/configurations/osx-version.png
vendored
Normal file
After Width: | Height: | Size: 128 KiB |
BIN
docs/static/configurations/safari-version.png
vendored
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
docs/static/configurations/windows-version.png
vendored
Normal file
After Width: | Height: | Size: 82 KiB |
@ -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)",
|
||||
|
@ -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",
|
||||
|
@ -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.
|
||||
*/
|
||||
|
4
libs/core/enums.d.ts
vendored
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
36
libs/core/shims.d.ts
vendored
@ -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.
|
||||
*/
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
# radio
|
||||
|
||||
The radio library.
|
||||
|
@ -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.",
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
6
libs/radio/shims.d.ts
vendored
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
408
package-lock.json
generated
@ -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",
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -1,7 +1,8 @@
|
||||
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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...
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
(<DalBoard>runtime.board).bus.queue(DAL.MICROBIT_ID_RADIO, DAL.MICROBIT_RADIO_EVT_DATAGRAM);
|
||||
}
|
||||
|
||||
send(payload: SimulatorRadioPacketPayload) {
|
||||
const b = board();
|
||||
Runtime.postMessage(<SimulatorRadioPacketMessage>{
|
||||
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(<SimulatorEventBusMessage>{
|
||||
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();
|
||||
}
|
||||
}
|
@ -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"
|
||||
]
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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",
|
||||
|