mikrojs 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/cliWrapper.js +13 -0
- package/dist/cli/cliWrapper.js.map +1 -1
- package/dist/cli/commands/flash.js +1 -1
- package/dist/cli/commands/sim/dev.d.ts +12 -0
- package/dist/cli/commands/sim/dev.d.ts.map +1 -1
- package/dist/cli/commands/sim/dev.js +265 -139
- package/dist/cli/commands/sim/dev.js.map +1 -1
- package/dist/cli/commands/sim/profile.js +3 -1
- package/dist/cli/commands/sim/profile.js.map +1 -1
- package/dist/cli/commands/sim/test.js +1 -1
- package/dist/cli/commands/sim/test.js.map +1 -1
- package/dist/cli/commands/sim.d.ts +8 -0
- package/dist/cli/commands/sim.d.ts.map +1 -1
- package/dist/cli/commands/test.js +1 -1
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/lib/esptool.js +2 -2
- package/dist/cli/lib/firmware.d.ts.map +1 -1
- package/dist/cli/lib/firmware.js +56 -29
- package/dist/cli/lib/firmware.js.map +1 -1
- package/dist/cli/lib/serial/ReplConsole.js +1 -1
- package/dist/cli/lib/serial/ReplConsole.js.map +1 -1
- package/dist/cli/lib/serial/devSession.d.ts +4 -0
- package/dist/cli/lib/serial/devSession.d.ts.map +1 -1
- package/dist/cli/lib/serial/devSession.js +3 -3
- package/dist/cli/lib/serial/devSession.js.map +1 -1
- package/dist/cli/lib/serial/replStateMachine.d.ts.map +1 -1
- package/dist/cli/lib/serial/replStateMachine.js +9 -2
- package/dist/cli/lib/serial/replStateMachine.js.map +1 -1
- package/dist/cli/lib/simPid.d.ts.map +1 -1
- package/dist/cli/lib/simPid.js +12 -4
- package/dist/cli/lib/simPid.js.map +1 -1
- package/dist/simulator/builtins/ble.d.ts.map +1 -1
- package/dist/simulator/builtins/ble.js +11 -10
- package/dist/simulator/builtins/ble.js.map +1 -1
- package/dist/simulator/builtins/http.d.ts.map +1 -1
- package/dist/simulator/builtins/http.js +73 -15
- package/dist/simulator/builtins/http.js.map +1 -1
- package/dist/simulator/builtins/i2c.d.ts.map +1 -1
- package/dist/simulator/builtins/i2c.js +6 -5
- package/dist/simulator/builtins/i2c.js.map +1 -1
- package/dist/simulator/builtins/kv.d.ts.map +1 -1
- package/dist/simulator/builtins/kv.js +2 -1
- package/dist/simulator/builtins/kv.js.map +1 -1
- package/dist/simulator/builtins/neopixel.d.ts.map +1 -1
- package/dist/simulator/builtins/neopixel.js +7 -5
- package/dist/simulator/builtins/neopixel.js.map +1 -1
- package/dist/simulator/builtins/nvs-kv.d.ts.map +1 -1
- package/dist/simulator/builtins/nvs-kv.js +37 -2
- package/dist/simulator/builtins/nvs-kv.js.map +1 -1
- package/dist/simulator/builtins/pin.d.ts.map +1 -1
- package/dist/simulator/builtins/pin.js +5 -4
- package/dist/simulator/builtins/pin.js.map +1 -1
- package/dist/simulator/builtins/pwm.d.ts.map +1 -1
- package/dist/simulator/builtins/pwm.js +6 -4
- package/dist/simulator/builtins/pwm.js.map +1 -1
- package/dist/simulator/builtins/sleep.d.ts.map +1 -1
- package/dist/simulator/builtins/sleep.js +7 -6
- package/dist/simulator/builtins/sleep.js.map +1 -1
- package/dist/simulator/builtins/sntp.d.ts.map +1 -1
- package/dist/simulator/builtins/sntp.js +3 -1
- package/dist/simulator/builtins/sntp.js.map +1 -1
- package/dist/simulator/builtins/spi.d.ts.map +1 -1
- package/dist/simulator/builtins/spi.js +5 -4
- package/dist/simulator/builtins/spi.js.map +1 -1
- package/dist/simulator/builtins/uart.d.ts.map +1 -1
- package/dist/simulator/builtins/uart.js +6 -4
- package/dist/simulator/builtins/uart.js.map +1 -1
- package/dist/simulator/builtins/wifi.d.ts.map +1 -1
- package/dist/simulator/builtins/wifi.js +20 -19
- package/dist/simulator/builtins/wifi.js.map +1 -1
- package/dist/simulator/devRunner.d.ts.map +1 -1
- package/dist/simulator/devRunner.js +61 -0
- package/dist/simulator/devRunner.js.map +1 -1
- package/dist/simulator/simProcess.js +46 -52
- package/dist/simulator/simProcess.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,32 +1,90 @@
|
|
|
1
|
-
// http
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// http delegates to Node's global fetch via the dev runner's RPC handler
|
|
2
|
+
// ('http.fetch'). The QuickJS-side stub keeps a per-request message queue so
|
|
3
|
+
// nextMessage() can deliver the body as one chunk followed by {kind: 'end'},
|
|
4
|
+
// matching the streaming contract that mikrojs/http expects from native:http.
|
|
4
5
|
export const httpBuiltin = {
|
|
5
6
|
source: `/* eslint-disable no-console */
|
|
6
7
|
// Simulator stub for http
|
|
7
8
|
// Runs inside the mikrojs runtime (QuickJS), not Node.js. Node built-ins are not available.
|
|
9
|
+
import {call} from 'native:host'
|
|
10
|
+
import {err, ok} from 'mikrojs/result'
|
|
8
11
|
import type {SimHttp} from 'mikrojs/sim'
|
|
9
12
|
|
|
10
13
|
let nextId = 0
|
|
14
|
+
const queues = new Map() // id -> message[]
|
|
11
15
|
|
|
16
|
+
function base64ToBytes(b64: string): Uint8Array {
|
|
17
|
+
const bin = atob(b64)
|
|
18
|
+
const out = new Uint8Array(bin.length)
|
|
19
|
+
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i)
|
|
20
|
+
return out
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function bytesToBase64(bytes: Uint8Array): string {
|
|
24
|
+
let bin = ''
|
|
25
|
+
for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]!)
|
|
26
|
+
return btoa(bin)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// request() returns a discriminated union (not a Result) on success, so the
|
|
30
|
+
// outer object is a plain literal. The inner \`headers\` Promise resolves to a
|
|
31
|
+
// Result, which must use ok()/err() so consumers can call .orPanic / .map etc.
|
|
12
32
|
export const request: SimHttp['request'] = (url, options) => {
|
|
13
33
|
console.log('[sim] http.request:', options?.method ?? 'GET', url)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
34
|
+
const id = nextId++
|
|
35
|
+
const queue: any[] = []
|
|
36
|
+
queues.set(id, queue)
|
|
37
|
+
|
|
38
|
+
const args = JSON.stringify({
|
|
39
|
+
url,
|
|
40
|
+
method: options?.method,
|
|
41
|
+
headers: options?.headers,
|
|
42
|
+
body: options?.body ? bytesToBase64(options.body) : undefined,
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const headers = call('http.fetch', args).then(
|
|
46
|
+
(json: string) => {
|
|
47
|
+
const r = JSON.parse(json) as {status: number; headers: [string, string][]; body: string}
|
|
48
|
+
const body = base64ToBytes(r.body)
|
|
49
|
+
if (body.length > 0) queue.push({kind: 'chunk', data: body})
|
|
50
|
+
queue.push({kind: 'end'})
|
|
51
|
+
return ok({status: r.status, headers: r.headers})
|
|
52
|
+
},
|
|
53
|
+
(e: unknown) => {
|
|
54
|
+
const message = e instanceof Error ? e.message : String(e)
|
|
55
|
+
queue.push({kind: 'error', cancelled: false, message})
|
|
56
|
+
return err({name: 'Network', message})
|
|
57
|
+
},
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
return {ok: true as const, id, headers}
|
|
22
61
|
}
|
|
23
62
|
|
|
24
|
-
|
|
25
|
-
|
|
63
|
+
// Polls the queue every microtask until a message is available. The queue is
|
|
64
|
+
// populated when the RPC promise settles, so the first poll is fast in
|
|
65
|
+
// practice; this avoids needing an explicit wakeup channel.
|
|
66
|
+
export const nextMessage: SimHttp['nextMessage'] = async (id) => {
|
|
67
|
+
for (;;) {
|
|
68
|
+
const queue = queues.get(id)
|
|
69
|
+
if (!queue) return {kind: 'end' as const}
|
|
70
|
+
if (queue.length > 0) {
|
|
71
|
+
const msg = queue.shift()
|
|
72
|
+
if (msg.kind === 'end' || msg.kind === 'error') queues.delete(id)
|
|
73
|
+
return msg
|
|
74
|
+
}
|
|
75
|
+
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
76
|
+
}
|
|
77
|
+
}
|
|
26
78
|
|
|
27
|
-
export const cancel: SimHttp['cancel'] = (
|
|
79
|
+
export const cancel: SimHttp['cancel'] = (id) => {
|
|
80
|
+
const queue = queues.get(id)
|
|
81
|
+
if (queue) {
|
|
82
|
+
queue.length = 0
|
|
83
|
+
queue.push({kind: 'error', cancelled: true, message: 'cancelled'})
|
|
84
|
+
}
|
|
85
|
+
}
|
|
28
86
|
|
|
29
|
-
export const pendingCount: SimHttp['pendingCount'] = () =>
|
|
87
|
+
export const pendingCount: SimHttp['pendingCount'] = () => queues.size
|
|
30
88
|
`,
|
|
31
89
|
};
|
|
32
90
|
//# sourceMappingURL=http.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/simulator/builtins/http.ts"],"names":[],"mappings":"AAEA,yEAAyE;AACzE,
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/simulator/builtins/http.ts"],"names":[],"mappings":"AAEA,yEAAyE;AACzE,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,MAAM,CAAC,MAAM,WAAW,GAAsB;IAC5C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkFT;CACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i2c.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/i2c.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"i2c.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/i2c.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,UAAU,EAAE,iBAexB,CAAA"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
export const i2cBuiltin = {
|
|
2
2
|
source: `// Simulator stub for i2c
|
|
3
3
|
// Runs inside the mikrojs runtime (QuickJS), not Node.js. Node built-ins are not available.
|
|
4
|
+
import {ok} from 'mikrojs/result'
|
|
4
5
|
import type {SimI2c} from 'mikrojs/sim'
|
|
5
6
|
|
|
6
7
|
export class I2c implements SimI2c {
|
|
7
8
|
constructor(_busNo: number, _options?: Record<string, unknown>) {}
|
|
8
|
-
begin() { return
|
|
9
|
-
end() { return
|
|
10
|
-
scan() { return
|
|
11
|
-
write(_address: number, _data: Uint8Array, _stop?: boolean) { return
|
|
12
|
-
read(_address: number, bytes: number) { return
|
|
9
|
+
begin() { return ok() }
|
|
10
|
+
end() { return ok() }
|
|
11
|
+
scan() { return ok(new Uint8Array()) }
|
|
12
|
+
write(_address: number, _data: Uint8Array, _stop?: boolean) { return ok() }
|
|
13
|
+
read(_address: number, bytes: number) { return ok(new Uint8Array(bytes)) }
|
|
13
14
|
}
|
|
14
15
|
`,
|
|
15
16
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i2c.js","sourceRoot":"","sources":["../../../src/simulator/builtins/i2c.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"i2c.js","sourceRoot":"","sources":["../../../src/simulator/builtins/i2c.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,MAAM,EAAE;;;;;;;;;;;;;CAaT;CACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kv.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/kv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"kv.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/kv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,SAAS,EAAE,iBAqCvB,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export const kvBuiltin = {
|
|
2
2
|
source: `
|
|
3
3
|
import {encode, decode} from 'native:cbor'
|
|
4
|
+
import {ok} from 'mikrojs/result'
|
|
4
5
|
|
|
5
6
|
const store = new Map()
|
|
6
7
|
|
|
@@ -8,7 +9,7 @@ export function set(key, value) {
|
|
|
8
9
|
const result = encode(value)
|
|
9
10
|
if (!result.ok) return result
|
|
10
11
|
store.set(key, result.value)
|
|
11
|
-
return
|
|
12
|
+
return ok()
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export function get(key) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kv.js","sourceRoot":"","sources":["../../../src/simulator/builtins/kv.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAsB;IAC1C,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"kv.js","sourceRoot":"","sources":["../../../src/simulator/builtins/kv.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAsB;IAC1C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCT;CACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neopixel.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/neopixel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"neopixel.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/neopixel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,eAAe,EAAE,iBAa7B,CAAA"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
export const neopixelBuiltin = {
|
|
2
2
|
source: `
|
|
3
|
+
import {ok} from 'mikrojs/result'
|
|
4
|
+
|
|
3
5
|
export class NeoPixel {
|
|
4
6
|
constructor(_pin, _numLeds, _bytesPerLed) {}
|
|
5
|
-
setPixel() { return
|
|
6
|
-
fill() { return
|
|
7
|
-
show() { return
|
|
8
|
-
clear() { return
|
|
9
|
-
end() { return
|
|
7
|
+
setPixel() { return ok() }
|
|
8
|
+
fill() { return ok() }
|
|
9
|
+
show() { return ok() }
|
|
10
|
+
clear() { return ok() }
|
|
11
|
+
end() { return ok() }
|
|
10
12
|
}
|
|
11
13
|
`,
|
|
12
14
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neopixel.js","sourceRoot":"","sources":["../../../src/simulator/builtins/neopixel.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAsB;IAChD,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"neopixel.js","sourceRoot":"","sources":["../../../src/simulator/builtins/neopixel.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAsB;IAChD,MAAM,EAAE;;;;;;;;;;;CAWT;CACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nvs-kv.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/nvs-kv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"nvs-kv.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/nvs-kv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAQjD,eAAO,MAAM,YAAY,EAAE,iBA6D1B,CAAA"}
|
|
@@ -1,14 +1,46 @@
|
|
|
1
|
+
// nvs_kv mirrors the firmware NVS contract: values must survive process
|
|
2
|
+
// restarts (firmware NVS survives power cycles). The QuickJS-side stub
|
|
3
|
+
// keeps an in-memory cache for fast reads, and rehydrates / persists via
|
|
4
|
+
// RPC to the Node side, which writes a JSON file alongside the env-config
|
|
5
|
+
// `nvs.json`. Values cross the boundary as base64(cbor) blobs so binary
|
|
6
|
+
// data round-trips losslessly.
|
|
1
7
|
export const nvsKvBuiltin = {
|
|
2
8
|
source: `
|
|
3
9
|
import {encode, decode} from 'native:cbor'
|
|
10
|
+
import {call} from 'native:host'
|
|
11
|
+
import {ok} from 'mikrojs/result'
|
|
12
|
+
|
|
13
|
+
function bytesToBase64(bytes) {
|
|
14
|
+
let bin = ''
|
|
15
|
+
for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i])
|
|
16
|
+
return btoa(bin)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function base64ToBytes(b64) {
|
|
20
|
+
const bin = atob(b64)
|
|
21
|
+
const out = new Uint8Array(bin.length)
|
|
22
|
+
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i)
|
|
23
|
+
return out
|
|
24
|
+
}
|
|
4
25
|
|
|
5
26
|
const store = new Map()
|
|
6
27
|
|
|
28
|
+
// Rehydrate from disk synchronously at module init. host.call on a sync
|
|
29
|
+
// Node-side handler returns a JSON string immediately (no Promise bridge).
|
|
30
|
+
const initial = call('nvs_kv.list', '{}')
|
|
31
|
+
if (typeof initial === 'string') {
|
|
32
|
+
const entries = JSON.parse(initial)
|
|
33
|
+
for (const key of Object.keys(entries)) {
|
|
34
|
+
store.set(key, base64ToBytes(entries[key]))
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
7
38
|
export function set(key, value) {
|
|
8
39
|
const result = encode(value)
|
|
9
40
|
if (!result.ok) return result
|
|
10
41
|
store.set(key, result.value)
|
|
11
|
-
|
|
42
|
+
call('nvs_kv.set', JSON.stringify({key, value: bytesToBase64(result.value)}))
|
|
43
|
+
return ok()
|
|
12
44
|
}
|
|
13
45
|
|
|
14
46
|
export function get(key) {
|
|
@@ -19,11 +51,14 @@ export function get(key) {
|
|
|
19
51
|
}
|
|
20
52
|
|
|
21
53
|
export function remove(key) {
|
|
22
|
-
|
|
54
|
+
const existed = store.delete(key)
|
|
55
|
+
if (existed) call('nvs_kv.remove', JSON.stringify({key}))
|
|
56
|
+
return existed
|
|
23
57
|
}
|
|
24
58
|
|
|
25
59
|
export function clear() {
|
|
26
60
|
store.clear()
|
|
61
|
+
call('nvs_kv.clear', '{}')
|
|
27
62
|
}
|
|
28
63
|
|
|
29
64
|
export function info() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nvs-kv.js","sourceRoot":"","sources":["../../../src/simulator/builtins/nvs-kv.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAsB;IAC7C,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"nvs-kv.js","sourceRoot":"","sources":["../../../src/simulator/builtins/nvs-kv.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,uEAAuE;AACvE,yEAAyE;AACzE,0EAA0E;AAC1E,wEAAwE;AACxE,+BAA+B;AAC/B,MAAM,CAAC,MAAM,YAAY,GAAsB;IAC7C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2DT;CACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pin.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/pin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"pin.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/pin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,UAAU,EAAE,iBA8BxB,CAAA"}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
export const pinBuiltin = {
|
|
2
2
|
source: `// Simulator stub for pin
|
|
3
3
|
// Runs inside the mikrojs runtime (QuickJS), not Node.js. Node built-ins are not available.
|
|
4
|
+
import {ok} from 'mikrojs/result'
|
|
4
5
|
import type {SimPin} from 'mikrojs/sim'
|
|
5
6
|
|
|
6
7
|
const state: Record<number, {mode?: number; value?: number}> = {}
|
|
7
8
|
|
|
8
9
|
export const pinMode: SimPin['pinMode'] = (pin, mode) => {
|
|
9
10
|
state[pin] = {...state[pin], mode}
|
|
10
|
-
return
|
|
11
|
+
return ok()
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export const digitalWrite: SimPin['digitalWrite'] = (pin, value) => {
|
|
14
15
|
state[pin] = {...state[pin], value}
|
|
15
|
-
return
|
|
16
|
+
return ok()
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
export const digitalRead: SimPin['digitalRead'] = (pin) => {
|
|
@@ -20,11 +21,11 @@ export const digitalRead: SimPin['digitalRead'] = (pin) => {
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export const analogRead: SimPin['analogRead'] = (_pin, _attenuation) => {
|
|
23
|
-
return
|
|
24
|
+
return ok(Math.floor(Math.random() * 4096))
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export const analogReadMillivolts: SimPin['analogReadMillivolts'] = (_pin, _attenuation) => {
|
|
27
|
-
return
|
|
28
|
+
return ok(Math.floor(Math.random() * 2500))
|
|
28
29
|
}
|
|
29
30
|
`,
|
|
30
31
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pin.js","sourceRoot":"","sources":["../../../src/simulator/builtins/pin.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"pin.js","sourceRoot":"","sources":["../../../src/simulator/builtins/pin.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BT;CACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pwm.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/pwm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAIjD,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"pwm.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/pwm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAIjD,eAAO,MAAM,UAAU,EAAE,iBA2BxB,CAAA"}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// {ok, value: Promise<void>} which can't survive JSON serialization.
|
|
3
3
|
export const pwmBuiltin = {
|
|
4
4
|
source: `
|
|
5
|
+
import {ok} from 'mikrojs/result'
|
|
6
|
+
|
|
5
7
|
export class Pwm {
|
|
6
8
|
#freq
|
|
7
9
|
#duty
|
|
@@ -11,17 +13,17 @@ export class Pwm {
|
|
|
11
13
|
}
|
|
12
14
|
duty(value) {
|
|
13
15
|
if (value !== undefined) this.#duty = value
|
|
14
|
-
return
|
|
16
|
+
return ok(this.#duty)
|
|
15
17
|
}
|
|
16
18
|
freq(value) {
|
|
17
19
|
if (value !== undefined) this.#freq = value
|
|
18
|
-
return
|
|
20
|
+
return ok(this.#freq)
|
|
19
21
|
}
|
|
20
22
|
fade(_target, _durationMs) {
|
|
21
|
-
return
|
|
23
|
+
return ok(Promise.resolve())
|
|
22
24
|
}
|
|
23
25
|
end() {
|
|
24
|
-
return
|
|
26
|
+
return ok()
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pwm.js","sourceRoot":"","sources":["../../../src/simulator/builtins/pwm.ts"],"names":[],"mappings":"AAEA,qEAAqE;AACrE,qEAAqE;AACrE,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"pwm.js","sourceRoot":"","sources":["../../../src/simulator/builtins/pwm.ts"],"names":[],"mappings":"AAEA,qEAAqE;AACrE,qEAAqE;AACrE,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;CAyBT;CACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sleep.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/sleep.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAIjD,eAAO,MAAM,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"sleep.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/sleep.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAIjD,eAAO,MAAM,YAAY,EAAE,iBA6B1B,CAAA"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
export const sleepBuiltin = {
|
|
4
4
|
source: `
|
|
5
5
|
import {restart} from 'native:sys'
|
|
6
|
+
import {ok} from 'mikrojs/result'
|
|
6
7
|
|
|
7
8
|
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))
|
|
8
9
|
|
|
@@ -18,15 +19,15 @@ export function deepSleep(ms) {
|
|
|
18
19
|
export function lightSleep(ms) {
|
|
19
20
|
console.warn('[sim] lightSleep(' + ms + 'ms)')
|
|
20
21
|
// Block-ish: return a result after the delay
|
|
21
|
-
return
|
|
22
|
+
return ok()
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export function getWakeupCause() { return wakeupCause }
|
|
25
|
-
export function enableTimerWakeup() { return
|
|
26
|
-
export function enableGpioWakeup() { return
|
|
27
|
-
export function enableExt0Wakeup() { return
|
|
28
|
-
export function enableExt1Wakeup() { return
|
|
29
|
-
export function disableWakeupSource() { return
|
|
26
|
+
export function enableTimerWakeup() { return ok() }
|
|
27
|
+
export function enableGpioWakeup() { return ok() }
|
|
28
|
+
export function enableExt0Wakeup() { return ok() }
|
|
29
|
+
export function enableExt1Wakeup() { return ok() }
|
|
30
|
+
export function disableWakeupSource() { return ok() }
|
|
30
31
|
`,
|
|
31
32
|
};
|
|
32
33
|
//# sourceMappingURL=sleep.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../../src/simulator/builtins/sleep.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,+CAA+C;AAC/C,MAAM,CAAC,MAAM,YAAY,GAAsB;IAC7C,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../../src/simulator/builtins/sleep.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,+CAA+C;AAC/C,MAAM,CAAC,MAAM,YAAY,GAAsB;IAC7C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BT;CACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sntp.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/sntp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAIjD,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"sntp.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/sntp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAIjD,eAAO,MAAM,WAAW,EAAE,iBAUzB,CAAA"}
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
// returns {ok, value: Promise<...>} which can't survive JSON serialization.
|
|
3
3
|
export const sntpBuiltin = {
|
|
4
4
|
source: `
|
|
5
|
+
import {ok} from 'mikrojs/result'
|
|
6
|
+
|
|
5
7
|
export function sync(_servers, _timezone, _background) {
|
|
6
|
-
return
|
|
8
|
+
return ok(Promise.resolve(ok({time: Date.now()})))
|
|
7
9
|
}
|
|
8
10
|
export function stop() {}
|
|
9
11
|
export function setTimezone(_tz) {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sntp.js","sourceRoot":"","sources":["../../../src/simulator/builtins/sntp.ts"],"names":[],"mappings":"AAEA,yEAAyE;AACzE,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAAsB;IAC5C,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"sntp.js","sourceRoot":"","sources":["../../../src/simulator/builtins/sntp.ts"],"names":[],"mappings":"AAEA,yEAAyE;AACzE,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAAsB;IAC5C,MAAM,EAAE;;;;;;;;CAQT;CACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spi.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/spi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"spi.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/spi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,UAAU,EAAE,iBAcxB,CAAA"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
export const spiBuiltin = {
|
|
2
2
|
source: `// Simulator stub for spi
|
|
3
3
|
// Runs inside the mikrojs runtime (QuickJS), not Node.js. Node built-ins are not available.
|
|
4
|
+
import {ok} from 'mikrojs/result'
|
|
4
5
|
import type {SimSpi} from 'mikrojs/sim'
|
|
5
6
|
|
|
6
7
|
export class Spi implements SimSpi {
|
|
7
8
|
constructor(_hostNo: number, _options: Record<string, unknown>) {}
|
|
8
|
-
begin() { return
|
|
9
|
-
end() { return
|
|
10
|
-
transfer(data: Uint8Array) { return
|
|
11
|
-
write(_data: Uint8Array) { return
|
|
9
|
+
begin() { return ok() }
|
|
10
|
+
end() { return ok() }
|
|
11
|
+
transfer(data: Uint8Array) { return ok(new Uint8Array(data.length)) }
|
|
12
|
+
write(_data: Uint8Array) { return ok() }
|
|
12
13
|
}
|
|
13
14
|
`,
|
|
14
15
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spi.js","sourceRoot":"","sources":["../../../src/simulator/builtins/spi.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"spi.js","sourceRoot":"","sources":["../../../src/simulator/builtins/spi.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,MAAM,EAAE;;;;;;;;;;;;CAYT;CACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uart.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/uart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"uart.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/uart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,WAAW,EAAE,iBAoBzB,CAAA"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export const uartBuiltin = {
|
|
2
2
|
source: `
|
|
3
|
+
import {ok} from 'mikrojs/result'
|
|
4
|
+
|
|
3
5
|
export class Uart {
|
|
4
6
|
constructor(_port, _options) {}
|
|
5
|
-
begin() { return
|
|
6
|
-
end() { return
|
|
7
|
-
write(_data) { return
|
|
7
|
+
begin() { return ok() }
|
|
8
|
+
end() { return ok() }
|
|
9
|
+
write(_data) { return ok() }
|
|
8
10
|
read() {
|
|
9
11
|
// Return an async iterable that never yields (no real UART in sim)
|
|
10
12
|
const iter = {
|
|
@@ -12,7 +14,7 @@ export class Uart {
|
|
|
12
14
|
return() { return Promise.resolve({done: true, value: undefined}) },
|
|
13
15
|
[Symbol.asyncIterator]() { return iter },
|
|
14
16
|
}
|
|
15
|
-
return
|
|
17
|
+
return ok(iter)
|
|
16
18
|
}
|
|
17
19
|
}
|
|
18
20
|
`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uart.js","sourceRoot":"","sources":["../../../src/simulator/builtins/uart.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAsB;IAC5C,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"uart.js","sourceRoot":"","sources":["../../../src/simulator/builtins/uart.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAsB;IAC5C,MAAM,EAAE;;;;;;;;;;;;;;;;;;CAkBT;CACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wifi.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/wifi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAIjD,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"wifi.d.ts","sourceRoot":"","sources":["../../../src/simulator/builtins/wifi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAIjD,eAAO,MAAM,WAAW,EAAE,iBAmDzB,CAAA"}
|
|
@@ -4,6 +4,7 @@ export const wifiBuiltin = {
|
|
|
4
4
|
source: `/* eslint-disable no-console */
|
|
5
5
|
// Simulator stub for wifi
|
|
6
6
|
// Runs inside the mikrojs runtime (QuickJS), not Node.js. Node built-ins are not available.
|
|
7
|
+
import {ok} from 'mikrojs/result'
|
|
7
8
|
import type {SimWifi} from 'mikrojs/sim'
|
|
8
9
|
|
|
9
10
|
let connected = false
|
|
@@ -15,39 +16,39 @@ export class Wifi implements SimWifi {
|
|
|
15
16
|
connected = true
|
|
16
17
|
currentIp = '192.168.1.100'
|
|
17
18
|
const info = {ip: currentIp, netmask: '255.255.255.0', gateway: '192.168.1.1'}
|
|
18
|
-
return
|
|
19
|
+
return ok(Promise.resolve(ok(info)))
|
|
19
20
|
}
|
|
20
|
-
disconnect() { return
|
|
21
|
-
rssi() { return
|
|
21
|
+
disconnect() { return ok() }
|
|
22
|
+
rssi() { return ok(-50) }
|
|
22
23
|
ip() { return currentIp }
|
|
23
24
|
status() { return connected ? 3 : 6 }
|
|
24
|
-
scan() { return
|
|
25
|
+
scan() { return ok(Promise.resolve(ok([] as never[]))) }
|
|
25
26
|
on() {}
|
|
26
27
|
off() {}
|
|
27
|
-
mac() { return
|
|
28
|
+
mac() { return ok('00:00:00:00:00:00') }
|
|
28
29
|
getHostname() { return 'mikrojs-sim' as string | undefined }
|
|
29
|
-
setHostname() { return
|
|
30
|
+
setHostname() { return ok() }
|
|
30
31
|
getIpConfig() {
|
|
31
|
-
if (!connected) return
|
|
32
|
-
return
|
|
32
|
+
if (!connected) return ok(undefined)
|
|
33
|
+
return ok({ip: currentIp, netmask: '255.255.255.0', gateway: '192.168.1.1', dns: '8.8.8.8'})
|
|
33
34
|
}
|
|
34
|
-
setIpConfig() { return
|
|
35
|
-
apStart() { return
|
|
36
|
-
apStop() { return
|
|
35
|
+
setIpConfig() { return ok() }
|
|
36
|
+
apStart() { return ok() }
|
|
37
|
+
apStop() { return ok() }
|
|
37
38
|
apIsActive() { return false }
|
|
38
39
|
apIp() { return undefined }
|
|
39
40
|
apStations() { return [] as {mac: string; rssi: number}[] }
|
|
40
|
-
apDeauthStation() { return
|
|
41
|
-
apGetInactiveTimeout() { return
|
|
42
|
-
apSetInactiveTimeout() { return
|
|
43
|
-
getTxPower() { return
|
|
44
|
-
setTxPower() { return
|
|
41
|
+
apDeauthStation() { return ok() }
|
|
42
|
+
apGetInactiveTimeout() { return ok(300) }
|
|
43
|
+
apSetInactiveTimeout() { return ok() }
|
|
44
|
+
getTxPower() { return ok(20) }
|
|
45
|
+
setTxPower() { return ok() }
|
|
45
46
|
getRssiThreshold() { return -127 }
|
|
46
|
-
setRssiThreshold() { return
|
|
47
|
+
setRssiThreshold() { return ok() }
|
|
47
48
|
getPowerSave() { return 'NONE' }
|
|
48
|
-
setPowerSave() { return
|
|
49
|
+
setPowerSave() { return ok() }
|
|
49
50
|
getCountry() { return undefined }
|
|
50
|
-
setCountry() { return
|
|
51
|
+
setCountry() { return ok() }
|
|
51
52
|
}
|
|
52
53
|
`,
|
|
53
54
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wifi.js","sourceRoot":"","sources":["../../../src/simulator/builtins/wifi.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,2EAA2E;AAC3E,MAAM,CAAC,MAAM,WAAW,GAAsB;IAC5C,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"wifi.js","sourceRoot":"","sources":["../../../src/simulator/builtins/wifi.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,2EAA2E;AAC3E,MAAM,CAAC,MAAM,WAAW,GAAsB;IAC5C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDT;CACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devRunner.d.ts","sourceRoot":"","sources":["../../src/simulator/devRunner.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,KAAK,WAAW,EAAE,YAAY,EAAC,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EAAC,OAAO,EAAC,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"devRunner.d.ts","sourceRoot":"","sources":["../../src/simulator/devRunner.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,KAAK,WAAW,EAAE,YAAY,EAAC,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EAAC,OAAO,EAAC,MAAM,MAAM,CAAA;AAwD5B,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC/B,6EAA6E;IAC7E,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7C,wDAAwD;IACxD,KAAK,IAAI,MAAM,IAAI,CAAA;IACnB,kFAAkF;IAClF,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAA;IAClC,uFAAuF;IACvF,MAAM,EAAE,OAAO,CAAA;IACf,4CAA4C;IAC5C,OAAO,EAAE,YAAY,CAAA;CACtB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAgLpE"}
|