mirror of
https://github.com/ocogeclub/ocoge.git
synced 2024-11-21 15:19:48 +00:00
[update] GPIOライブラリをrgpioに変更。PWM関連ブロックからJSコードを削除。動作環境にOrangePi5を追加
This commit is contained in:
parent
7a2997c35a
commit
d0adc9edf7
36
apptool.js
36
apptool.js
@ -31,7 +31,7 @@ class appTool {
|
||||
this.saveFilepath = null;
|
||||
this.wsChanged = false;
|
||||
this.children = [];
|
||||
this.gpio_lib = ugj_const.pig;
|
||||
this.gpio_lib = ugj_const.rg;
|
||||
this.i2c_bus = ugj_const.i2c_defbus;
|
||||
this.lang = ugj_const.lang;
|
||||
this.doc_root = this.path.join(process.env["HOME"], ugj_const.document_root);
|
||||
@ -222,7 +222,6 @@ class appTool {
|
||||
'doc_current': this.doc_current,
|
||||
'i2c_bus': this.i2c_bus,
|
||||
'lang': this.lang,
|
||||
'gpio_lib': this.gpio_lib
|
||||
};
|
||||
let s = JSON.stringify(o);
|
||||
localStorage.setItem(ugj_const.localStorage_fname, s);
|
||||
@ -243,15 +242,15 @@ class appTool {
|
||||
this.ipcRenderer.send('i2c_check_menu', 'i2c-' + this.i2c_bus);
|
||||
}
|
||||
if (o.lang) {
|
||||
let l;
|
||||
if (o.lang == 'js' || o.gpio_lib) {
|
||||
l = o.lang + '-' + o.gpio_lib;
|
||||
} else {
|
||||
l = o.lang;
|
||||
}
|
||||
this.setLang(l);
|
||||
console.log(`l= ${l}`);
|
||||
this.ipcRenderer.send('lang_check_menu', l);
|
||||
// let l;
|
||||
// if (o.lang == 'js' || o.gpio_lib) {
|
||||
// l = o.lang + '-' + o.gpio_lib;
|
||||
// } else {
|
||||
// l = o.lang;
|
||||
// }
|
||||
this.setLang(o.lang);
|
||||
console.log(`lang= ${this.lang}`);
|
||||
this.ipcRenderer.send('lang_check_menu', this.lang);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -271,13 +270,14 @@ class appTool {
|
||||
|
||||
// 言語/GPIOライブラリ変更
|
||||
setLang(l) {
|
||||
if (l == 'js-pigpio') {
|
||||
this.lang = 'js';
|
||||
this.gpio_lib = ugj_const.pig;
|
||||
} else if (l == 'js-rgpio') {
|
||||
this.lang = 'js';
|
||||
this.gpio_lib = ugj_const.rg;
|
||||
} else this.lang = 'py';
|
||||
this.lang = l;
|
||||
// if (l == 'js-pigpio') {
|
||||
// this.lang = 'js';
|
||||
// this.gpio_lib = ugj_const.pig;
|
||||
// } else if (l == 'js-rgpio') {
|
||||
// this.lang = 'js';
|
||||
// this.gpio_lib = ugj_const.rg;
|
||||
// } else this.lang = 'py';
|
||||
|
||||
const exp = document.getElementById('dlgExport');
|
||||
if (this.lang == 'js') {
|
||||
|
@ -465,11 +465,6 @@ var ugjPwmDefinition = {
|
||||
"type": "input_value",
|
||||
"name": "pwm_frequency",
|
||||
"check": "Number"
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "pwm_duty_cycle",
|
||||
"check": "Number"
|
||||
}
|
||||
],
|
||||
"inputsInline": true,
|
||||
@ -484,20 +479,50 @@ Blockly.Blocks['ugj_pwm'] = {
|
||||
this.jsonInit(ugjPwmDefinition);
|
||||
}
|
||||
};
|
||||
Blockly.JavaScript['ugj_pwm'] = function (block) {
|
||||
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var value_pwm_frequency = Blockly.JavaScript.valueToCode(block, 'pwm_frequency', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var value_pwm_duty_cycle = Blockly.JavaScript.valueToCode(block, 'pwm_duty_cycle', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var code = `await _pi.pwm(${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle});\n`;
|
||||
return code;
|
||||
};
|
||||
// Blockly.Python['ugj_pwm'] = function (block) {
|
||||
// var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||||
// var value_pwm_frequency = Blockly.Python.valueToCode(block, 'pwm_frequency', Blockly.Python.ORDER_ATOMIC);
|
||||
// var value_pwm_duty_cycle = Blockly.Python.valueToCode(block, 'pwm_duty_cycle', Blockly.Python.ORDER_ATOMIC);
|
||||
// var code = `await pi.pwm(gpioHand, ${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle})\n`;
|
||||
// Blockly.JavaScript['ugj_pwm'] = function (block) {
|
||||
// var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
// var value_pwm_frequency = Blockly.JavaScript.valueToCode(block, 'pwm_frequency', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
// var value_pwm_duty_cycle = Blockly.JavaScript.valueToCode(block, 'pwm_duty_cycle', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
// var code = `await _pi.pwm(${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle});\n`;
|
||||
// return code;
|
||||
// };
|
||||
Blockly.Python['ugj_pwm'] = function (block) {
|
||||
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||||
var value_pwm_frequency = Blockly.Python.valueToCode(block, 'pwm_frequency', Blockly.Python.ORDER_ATOMIC);
|
||||
var value_pwm_duty_cycle = Blockly.Python.valueToCode(block, 'pwm_duty_cycle', Blockly.Python.ORDER_ATOMIC);
|
||||
Blockly.Python.provideFunction_(
|
||||
'import_pwm', ['from machine import PWM']
|
||||
);
|
||||
var code = `_pin[${value_gpio}] = PWM(Pin(${value_gpio}))
|
||||
_pin[${value_gpio}].freq(${value_pwm_frequency})
|
||||
`;
|
||||
// var code = `await pi.pwm(gpioHand, ${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle})\n`;
|
||||
return code;
|
||||
};
|
||||
Blockly.Blocks['oc_pwm_duty'] = {
|
||||
init: function () {
|
||||
this.appendValueInput("gpio")
|
||||
.setCheck("Number")
|
||||
.appendField("GPIO");
|
||||
this.appendValueInput("duty")
|
||||
.setCheck("Number")
|
||||
.appendField("へデューティ値");
|
||||
this.appendDummyInput()
|
||||
.appendField("でパルスを出力");
|
||||
this.setInputsInline(true);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setTooltip("PWM出力に設定したGPIOへパルスを出力します。デューティ値は 0(0%) ~ 65535(100%) の範囲で指定します。");
|
||||
this.setHelpUrl("");
|
||||
this.setStyle('gpio_blocks');
|
||||
}
|
||||
};
|
||||
Blockly.Python['oc_pwm_duty'] = function (block) {
|
||||
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||||
var value_duty = Blockly.Python.valueToCode(block, 'duty', Blockly.Python.ORDER_ATOMIC);
|
||||
var code = `_pin[${value_gpio}].duty_u16(${value_duty})\n`;
|
||||
return code;
|
||||
};
|
||||
/********************** */
|
||||
/** Open Serial Port ** */
|
||||
/********************** */
|
||||
@ -542,7 +567,8 @@ Blockly.JavaScript['ugj_serial_open'] = function (block) {
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
|
||||
);
|
||||
var code = `await _pi.serial_open('/dev/serial0', ${dropdown_baud});\n`;
|
||||
var code = `await _pi.serial_open('/dev/ttyS0', ${dropdown_baud});\n`;
|
||||
// var code = `await _pi.serial_open('/dev/serial0', ${dropdown_baud});\n`;
|
||||
return code;
|
||||
};
|
||||
// Blockly.Python['ugj_serial_open'] = function (block) {
|
||||
@ -721,6 +747,30 @@ Blockly.Python['ugj_i2c_close'] = function (block) {
|
||||
return code;
|
||||
};
|
||||
|
||||
/*************************************** */
|
||||
/** Sends a single byte to the device ** */
|
||||
/*************************************** */
|
||||
Blockly.Blocks['oc_i2c_write_byte'] = {
|
||||
init: function () {
|
||||
this.appendValueInput("byte_val")
|
||||
.setCheck("Number")
|
||||
.appendField("デバイスに1バイトデータ");
|
||||
this.appendDummyInput()
|
||||
.appendField("を送信");
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setTooltip("i2cデバイスに1バイトデータを送信します。0-0xFF(255)の範囲の数字で入力してください。");
|
||||
this.setHelpUrl("");
|
||||
this.setStyle('gpio_blocks');
|
||||
}
|
||||
};
|
||||
Blockly.JavaScript['oc_i2c_write_byte'] = function (block) {
|
||||
var value_byte_val = Blockly.JavaScript.valueToCode(block, 'byte_val', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
// TODO: Assemble JavaScript into code variable.
|
||||
var code = `await _pi.i2c_write_byte(${value_byte_val});\n`;
|
||||
return code;
|
||||
};
|
||||
|
||||
/****************************************************************** */
|
||||
/** Writes a single byte to the specified register of the device ** */
|
||||
/****************************************************************** */
|
||||
|
@ -30,5 +30,6 @@ registerCategory('sensors', [ // カテゴリディレクトリ名
|
||||
"paj7620",
|
||||
"bme280",
|
||||
"dht11",
|
||||
"pico_slave",
|
||||
"z-line" // フライアウト下端の不可視ライン。スクリプトにカテゴリ名を含むので注意
|
||||
]);
|
||||
|
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const err_msg = 'AMG8833 is already opened. Please close old connection to use new one.';
|
||||
const pig = require('@ocoge.club/pigpio');
|
||||
const pig = require(`@ocoge.club/${apptool.gpio_lib}`);
|
||||
|
||||
let pi = -1;
|
||||
let i2c_hand = -1;
|
||||
@ -12,7 +12,7 @@ exports.init = async (i2c_bus, i2c_addr, wael = null) => {
|
||||
});
|
||||
}
|
||||
if (pi >= 0) { throw new Error(err_msg); return; }
|
||||
pi = await pig._pigpio_start('', '');
|
||||
pi = await pig._gpiod_start('', '');
|
||||
console.log('pi=' + pi);
|
||||
if (i2c_hand >= 0) { throw new Error(err_msg); return; }
|
||||
i2c_hand = await pig._i2c_open(pi, i2c_bus, i2c_addr);
|
||||
@ -45,7 +45,7 @@ exports.stop = async () => {
|
||||
i2c_hand = -1;
|
||||
}
|
||||
if (pi >= 0) {
|
||||
await pig._pigpio_stop(pi);
|
||||
await pig._gpiod_stop(pi);
|
||||
pi = -1;
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const err_msg = 'AMG8833 is already opened. Please close old connection to use new one.';
|
||||
const pig = require('@ocoge.club/rgpio');
|
||||
|
||||
let pi = -1;
|
||||
let i2c_hand = -1;
|
||||
exports.init = async (i2c_bus, i2c_addr, wael = null) => {
|
||||
if (wael !== null) {
|
||||
wael('beforeunload', async () => {
|
||||
await exports.stop();
|
||||
});
|
||||
}
|
||||
if (pi >= 0) { throw new Error(err_msg); return; }
|
||||
pi = await pig._rgpiod_start('', '');
|
||||
console.log('pi=' + pi);
|
||||
if (i2c_hand >= 0) { throw new Error(err_msg); return; }
|
||||
i2c_hand = await pig._i2c_open(pi, i2c_bus, i2c_addr, 0);
|
||||
console.log('i2c_hand=' + i2c_hand);
|
||||
await pig._i2c_write_byte_data(pi, i2c_hand, 0x00, 0x00); //Normal mode
|
||||
await pig._i2c_write_byte_data(pi, i2c_hand, 0x02, 0x00); //10FPS
|
||||
}
|
||||
|
||||
exports.read_thermistor = async () => {
|
||||
let temp = await pig._i2c_read_word_data(pi, i2c_hand, 0x0e);
|
||||
return temp * 0.0625;
|
||||
}
|
||||
|
||||
exports.read_temp_array = async () => {
|
||||
let linedata = [];
|
||||
for (let i = 0; i < 8; i++) {
|
||||
let data = await pig._i2c_read_i2c_block_data(pi, i2c_hand, 0x80 + 0x10 * i, 16);
|
||||
let oneline = [];
|
||||
for (let j = 0; j < 8; j++) {
|
||||
oneline.push(((data[2 * j + 1] & 0x07) * 256 + data[2 * j]) * 0.25);
|
||||
}
|
||||
linedata.push(oneline);
|
||||
}
|
||||
return linedata;
|
||||
}
|
||||
|
||||
exports.stop = async () => {
|
||||
if (i2c_hand >= 0) {
|
||||
await pig._i2c_close(pi, i2c_hand);
|
||||
i2c_hand = -1;
|
||||
}
|
||||
if (pi >= 0) {
|
||||
await pig._rgpiod_stop(pi);
|
||||
pi = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This code was ported from https://www.denshi.club/pc/raspi/5raspberry-pi-zeroiot381i2c-amg8833.html
|
||||
*/
|
@ -56,7 +56,7 @@ Blockly.JavaScript['ugj_grideye_init'] = function (block) {
|
||||
// Blockly.JavaScript.provideFunction_(
|
||||
// 'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
|
||||
// );
|
||||
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'amg8833', `AMG8833x_${apptool.gpio_lib}.js`);
|
||||
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'amg8833', `AMG8833x.js`);
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
'require_amg8833', [`const _amg8833 = require('${modpath}');`]
|
||||
);
|
||||
|
@ -42,8 +42,8 @@ this.REGISTER_TEMP_DATA = 0xFA;
|
||||
this.REGISTER_HUMIDITY_DATA = 0xFD;
|
||||
|
||||
exports.init = async (options) => {
|
||||
this.pig = require('@ocoge.club/pigpio');
|
||||
this.pi = await this.pig._pigpio_start('', '');
|
||||
this.pig = require(`@ocoge.club/${apptool.gpio_lib}`);
|
||||
this.pi = await this.pig._gpiod_start('', '');
|
||||
|
||||
this.i2cBusNo = (options && options.hasOwnProperty('i2cBusNo')) ? options.i2cBusNo : 1;
|
||||
this.i2cAddress = (options && options.hasOwnProperty('i2cAddress')) ? options.i2cAddress : this.BME280_DEFAULT_I2C_ADDRESS();
|
||||
@ -96,7 +96,7 @@ exports.cancel = async () => {
|
||||
if (this.i2cHand >= 0) {
|
||||
await this.pig._i2c_close(this.pi, this.i2cHand);
|
||||
this.i2cHand = null;
|
||||
await this.pig._pigpio_stop(this.pi);
|
||||
await this.pig._gpiod_stop(this.pi);
|
||||
this.pi = null;
|
||||
}
|
||||
}
|
||||
|
@ -17,10 +17,11 @@ Blockly.Blocks['ugj_bme280'] = {
|
||||
};
|
||||
Blockly.JavaScript['ugj_bme280'] = function (block) {
|
||||
var dropdown_addr = block.getFieldValue('addr');
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
|
||||
);
|
||||
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'bme280', 'BME280x.js');
|
||||
// Blockly.JavaScript.provideFunction_(
|
||||
// 'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
|
||||
// );
|
||||
// let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'bme280', 'BME280x.js');
|
||||
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'bme280', `BME280x.js`);
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
'require_bme280', [`const _bme280 = require('${modpath}');`]
|
||||
);
|
||||
|
@ -311,7 +311,7 @@ const initRegisterArray = [
|
||||
//Enable debug message
|
||||
const debug = 1;
|
||||
|
||||
const err_msg = 'AMG8833 is already opened. Please close old connection to use new one.';
|
||||
const err_msg = 'PAJ7620 is already opened. Please close old connection to use new one.';
|
||||
let pig = -1;
|
||||
let pi = -1;
|
||||
let i2c_hand = -1;
|
||||
@ -322,9 +322,9 @@ exports.init = async (i2c_bus, i2c_addr, wael = null) => {
|
||||
await exports.stop();
|
||||
});
|
||||
}
|
||||
pig = require('@ocoge.club/pigpio');
|
||||
pig = require(`@ocoge.club/${apptool.gpio_lib}`);
|
||||
if (pi >= 0) { throw new Error(err_msg); return; }
|
||||
pi = await pig._pigpio_start('', '');
|
||||
pi = await pig._gpiod_start('', '');
|
||||
if (i2c_hand >= 0) { throw new Error(err_msg); return; }
|
||||
i2c_hand = await pig._i2c_open(pi, i2c_bus, i2c_addr);
|
||||
if (debug)
|
||||
@ -461,7 +461,7 @@ exports.stop = async () => {
|
||||
i2c_hand = -1;
|
||||
}
|
||||
if (pi >= 0) {
|
||||
await pig._pigpio_stop(pi);
|
||||
await pig._gpiod_stop(pi);
|
||||
pi = -1;
|
||||
}
|
||||
}
|
||||
|
@ -32,9 +32,9 @@ Blockly.Blocks['ugj_gesture_init'] = {
|
||||
};
|
||||
Blockly.JavaScript['ugj_gesture_init'] = function (block) {
|
||||
var value_i2c_addr = Blockly.JavaScript.valueToCode(block, 'i2c_addr', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
|
||||
);
|
||||
// Blockly.JavaScript.provideFunction_(
|
||||
// 'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
|
||||
// );
|
||||
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'paj7620', 'PAJ7620x.js');
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
'require_paj7620', [`const _paj7620 = require('${modpath}');`]
|
||||
|
66
blocks/sensors/pico_slave/index.js
Normal file
66
blocks/sensors/pico_slave/index.js
Normal file
@ -0,0 +1,66 @@
|
||||
Blockly.Blocks['oc_i2cslave'] = {
|
||||
init: function () {
|
||||
this.appendValueInput("i2c_addr")
|
||||
.setCheck("Number")
|
||||
.appendField("PICOスレーブ:I2Cアドレス");
|
||||
this.appendDummyInput()
|
||||
.appendField(new Blockly.FieldVariable("データ"), "data")
|
||||
.appendField("を受け取ったら");
|
||||
this.appendStatementInput("do")
|
||||
.setCheck(null);
|
||||
this.setInputsInline(false);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setTooltip("Raspberry Pi Pico(及びその互換機)を I2Cスレーブ化します。受信データは1バイトデータです。i2c_slave.py が必要です。");
|
||||
this.setHelpUrl("");
|
||||
this.setStyle('gpio_blocks');
|
||||
}
|
||||
};
|
||||
Blockly.Python['oc_i2cslave'] = function (block) {
|
||||
var value_i2c_addr = Blockly.Python.valueToCode(block, 'i2c_addr', Blockly.Python.ORDER_ATOMIC);
|
||||
var variable_data = Blockly.Python.nameDB_.getName(block.getFieldValue('data'), Blockly.Names.NameType.VARIABLE);
|
||||
var statements_do = Blockly.Python.statementToCode(block, 'do');
|
||||
Blockly.Python.provideFunction_(
|
||||
'import_i2cslave', ['from i2cSlave import i2c_slave']
|
||||
);
|
||||
var code = `_i2cs = i2c_slave(0,sda=0,scl=1,slaveAddress=${value_i2c_addr})
|
||||
while True:
|
||||
${variable_data} = int(_i2cs.get())
|
||||
${statements_do}
|
||||
`;
|
||||
return code;
|
||||
};
|
||||
|
||||
|
||||
flyout_contents = flyout_contents.concat([
|
||||
{
|
||||
"kind": "label",
|
||||
"text": "RPi Pico I2Cスレーブ化",
|
||||
"web-line": "4.0",
|
||||
"web-line-width": "200"
|
||||
}, {
|
||||
"kind": "block",
|
||||
"type": "oc_i2cslave",
|
||||
"fields": {
|
||||
"data": {
|
||||
"name": "データ"
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"i2c_addr": {
|
||||
"shadow": {
|
||||
"type": "ugj_hextodec",
|
||||
"inputs": {
|
||||
"hex": {
|
||||
"shadow": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"TEXT": "41"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
])
|
24
index.html
24
index.html
@ -368,7 +368,7 @@
|
||||
<block type="ugj_pwm">
|
||||
<value name="gpio">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">5</field>
|
||||
<field name="NUM">29</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="pwm_frequency">
|
||||
@ -376,21 +376,16 @@
|
||||
<field name="NUM">50</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="pwm_duty_cycle">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">30</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="ugj_servo">
|
||||
<block type="oc_pwm_duty">
|
||||
<value name="gpio">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">12</field>
|
||||
<field name="NUM">29</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="pulsewidth">
|
||||
<value name="duty">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">1500</field>
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
@ -403,6 +398,13 @@
|
||||
</value>
|
||||
</block>
|
||||
<block type="ugj_i2c_close"></block>
|
||||
<block type="oc_i2c_write_byte">
|
||||
<value name="byte_val">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="ugj_i2c_write_byte_data">
|
||||
<value name="reg">
|
||||
<shadow type="math_number">
|
||||
@ -493,7 +495,7 @@
|
||||
<label text="Extra" web-line="4.0" web-line-width="200"></label>
|
||||
<label text="_" web-line="4.0" web-line-width="200"></label>
|
||||
</category>
|
||||
<category toolboxitemid="category_sensors" name="センサー" css-icon="customIcon fas fa-microchip"
|
||||
<category toolboxitemid="category_sensors" name="モジュール" css-icon="customIcon fas fa-microchip"
|
||||
categorystyle="sensor_category">
|
||||
</category>
|
||||
<category name="マルチメディア" css-icon="customIcon fas fa-gamepad" categorystyle="multimedia_category">
|
||||
|
19
index.js
19
index.js
@ -113,8 +113,8 @@ Blockly.Msg["GPIO_WRITE_TITLE"] = "GPIO %1 の値を %2 にする";
|
||||
Blockly.Msg["GPIO_WRITE_TOOLTIP"] = "GPIO端子の値をデジタル値(0または1)で出力します。";
|
||||
Blockly.Msg["SERVO_TITLE"] = "GPIO %1 のサーボモータの回転を %2 にする";
|
||||
Blockly.Msg["SERVO_TOOLTIP"] = "サーボモータの回転をパルス幅(1000~2000μsec)までの数値で指定します。";
|
||||
Blockly.Msg["PWM_TITLE"] = "PWM : GPIO %1 に、パルス周波数 %2 Hz, デューティー比 %3 %%で出力";
|
||||
Blockly.Msg["PWM_TOOLTIP"] = "パルス周波数をセットして、GPIO端子がPWM出力できるようにします。レンジは100固定です。";
|
||||
Blockly.Msg["PWM_TITLE"] = "GPIO %1 をパルス周波数 %2 Hzの PWM 出力に設定";
|
||||
Blockly.Msg["PWM_TOOLTIP"] = "パルス周波数をセットして、GPIO端子がPWM出力できるようにします。(MicorPython 専用)";
|
||||
Blockly.Msg["I2C_OPEN_TITLE"] = "アドレス %1 の I2C デバイスを開く";
|
||||
Blockly.Msg["I2C_OPEN_TOOLTIP"] = "I2C接続されたデバイスとの通信を開始します。一度にオープンできるI2Cデバイスはひとつだけです。";
|
||||
Blockly.Msg["SERIAL_OPEN_TITLE"] = "シリアルポートを速度 %1 bpsで開く";
|
||||
@ -293,7 +293,7 @@ const ugj_newWorkspace = () => {
|
||||
// ワークスペースをファイルに保存・読込
|
||||
const ugj_saveWorkspaceToFile = async () => {
|
||||
let xml = Blockly.Xml.workspaceToDom(workspace);
|
||||
let xml_text = Blockly.Xml.domToText(xml);
|
||||
let xml_text = Blockly.utils.xml.domToText(xml);
|
||||
if (await apptool.saveWsFile(xml_text) === false) {
|
||||
window.alert('保存できませんでした。');
|
||||
}
|
||||
@ -301,7 +301,7 @@ const ugj_saveWorkspaceToFile = async () => {
|
||||
const ugj_loadWorkspaceFromFile = async () => {
|
||||
let xml_text = await apptool.loadWsFile();
|
||||
if (xml_text.length > 0) {
|
||||
let xml = Blockly.Xml.textToDom(xml_text);
|
||||
let xml = Blockly.utils.xml.textToDom(xml_text);
|
||||
Blockly.Xml.domToWorkspace(xml, workspace);
|
||||
}
|
||||
}
|
||||
@ -316,7 +316,7 @@ const ugj_saveWorkspaceAs = () => {
|
||||
const ugj_saveWorkspace = () => {
|
||||
// Workspace
|
||||
let xml = Blockly.Xml.workspaceToDom(workspace);
|
||||
let xml_text = Blockly.Xml.domToText(xml);
|
||||
let xml_text = Blockly.utils.xml.domToText(xml);
|
||||
localStorage.setItem("ocoge.xml", xml_text);
|
||||
}
|
||||
const ugj_loadWorkspace = () => {
|
||||
@ -324,7 +324,7 @@ const ugj_loadWorkspace = () => {
|
||||
let xml_text = localStorage.getItem("ocoge.xml");
|
||||
if (xml_text !== null) {
|
||||
if (xml_text.length != 0) {
|
||||
let xml = Blockly.Xml.textToDom(xml_text);
|
||||
let xml = Blockly.utils.xml.textToDom(xml_text);
|
||||
Blockly.Xml.domToWorkspace(xml, workspace);
|
||||
}
|
||||
}
|
||||
@ -341,8 +341,13 @@ const ugj_generateCode = () => {
|
||||
code = '';
|
||||
}
|
||||
} else { // Javascript コード出力
|
||||
try {
|
||||
code = Blockly.JavaScript.workspaceToCode(workspace).replace(/(?<=^|\n)function \w+\(.*\)/g, 'async $&');
|
||||
// .replace 以降は、関数の常時非同期化のため
|
||||
} catch (e) { // JSコードを持たないブロックがある場合
|
||||
window.alert('Python 専用ブロックが使用されています。\n' + e.message);
|
||||
code = '';
|
||||
}
|
||||
// .replace 以降は、関数の常時非同期化のため...要するに async 付加
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -14,11 +14,11 @@ let pi = -1;
|
||||
let i2c_hand = -1;
|
||||
let ser_hand = -1;
|
||||
module.exports.gpio_open = async () => {
|
||||
if (pi < 0) pi = await module.exports._pigpio_start('', '');
|
||||
if (pi < 0) pi = await module.exports._gpiod_start('', '');
|
||||
return pi;
|
||||
}
|
||||
module.exports.gpio_close = async () => {
|
||||
if (pi >= 0) await module.exports._pigpio_stop(pi);
|
||||
if (pi >= 0) await module.exports._gpiod_stop(pi);
|
||||
pi = -1;
|
||||
}
|
||||
module.exports.gpio_set_output = async gpio => {
|
||||
|
@ -651,8 +651,8 @@ Promise _i2cWriteDevice(const CallbackInfo &info)
|
||||
Object
|
||||
Init(Env env, Object exports)
|
||||
{
|
||||
exports.Set(String::New(env, "_pigpio_start"), Function::New(env, _pigpioStart));
|
||||
exports.Set(String::New(env, "_pigpio_stop"), Function::New(env, _pigpioStop));
|
||||
exports.Set(String::New(env, "_gpiod_start"), Function::New(env, _pigpioStart));
|
||||
exports.Set(String::New(env, "_gpiod_stop"), Function::New(env, _pigpioStop));
|
||||
exports.Set(String::New(env, "_set_mode"), Function::New(env, _setMode));
|
||||
exports.Set(String::New(env, "_set_pull_up_down"), Function::New(env, _setPullUpDown));
|
||||
exports.Set(String::New(env, "_gpio_read"), Function::New(env, _gpioRead));
|
||||
|
@ -18,7 +18,7 @@ let gpiochip_hand = [];
|
||||
let ser_hand = -1;
|
||||
let i2c_hand = -1;
|
||||
module.exports.gpio_open = async () => {
|
||||
sbc = await module.exports._rgpiod_start('', port);
|
||||
sbc = await module.exports._gpiod_start('', '');
|
||||
if (sbc < 0) return sbc;
|
||||
for (let i = 0; i < CHIP_COUNT; i++) {
|
||||
gpiochip_hand.push(await module.exports._gpiochip_open(sbc, i));
|
||||
@ -26,12 +26,15 @@ module.exports.gpio_open = async () => {
|
||||
return gpiochip_hand;
|
||||
}
|
||||
module.exports.gpio_close = async () => {
|
||||
if (sbc >= 0) {
|
||||
for (let i = 0; i < CHIP_COUNT; i++) {
|
||||
if (gpiochip_hand[i] >= 0)
|
||||
await module.exports._gpiochip_close(sbc, gpiochip_hand[i]);
|
||||
}
|
||||
gpiochip_hand = [];
|
||||
await module.exports._rgpiod_stop(sbc);
|
||||
await module.exports._gpiod_stop(sbc);
|
||||
sbc = -1;
|
||||
}
|
||||
}
|
||||
module.exports.gpio_set_output = async gpio => {
|
||||
let chip = Math.floor(gpio / 32);
|
||||
@ -43,28 +46,62 @@ module.exports.gpio_write = async (gpio, value) => {
|
||||
let pin = Math.floor(gpio % 32);
|
||||
if (gpiochip_hand[chip] >= 0) return await module.exports._gpio_write(sbc, gpiochip_hand[chip], pin, value);
|
||||
}
|
||||
module.exports.serial_open = async (tty, baud) => {
|
||||
if (ser_hand >= 0) await module.exports._serial_close(sbc, ser_hand); // 勝手に閉じる
|
||||
ser_hand = await module.exports._serial_open(sbc, tty, baud);
|
||||
return ser_hand;
|
||||
}
|
||||
module.exports.serial_close = async () => {
|
||||
if (ser_hand >= 0) await module.exports._serial_close(sbc, ser_hand);
|
||||
ser_hand = -1;
|
||||
}
|
||||
module.exports.serial_write = async data => {
|
||||
if (ser_hand >= 0) return await module.exports._serial_write(sbc, ser_hand, Buffer.from(data));
|
||||
}
|
||||
module.exports.serial_read = async count => {
|
||||
if (ser_hand >= 0) return new TextDecoder().decode(await module.exports._serial_read(sbc, ser_hand, count));
|
||||
// if (ser_hand >= 0) return await module.exports._serial_read(pi, ser_hand, count);//.toString('utf8');
|
||||
}
|
||||
module.exports.i2c_open = async (i2c_bus, i2c_address) => {
|
||||
if (i2c_hand >= 0) await module.exports._i2c_close(i2c_hand); // 勝手に閉じる
|
||||
i2c_hand = await module.exports._i2c_open(sbc, i2c_bus, i2c_address, 0);
|
||||
i2c_hand = await module.exports._i2c_open(sbc, i2c_bus, i2c_address);
|
||||
return i2c_hand;
|
||||
}
|
||||
module.exports.i2c_close = async () => {
|
||||
if (i2c_hand >= 0) await module.exports._i2c_close(sbc, i2c_hand);
|
||||
i2c_hand = -1;
|
||||
}
|
||||
|
||||
module.exports.i2c_write_byte = async (byte_val) => {
|
||||
if (i2c_hand >= 0) return await module.exports._i2c_write_byte(sbc, i2c_hand, byte_val);
|
||||
}
|
||||
module.exports.i2c_read_byte = async () => {
|
||||
if (i2c_hand >= 0) return await module.exports._i2c_read_byte(sbc, i2c_hand);
|
||||
}
|
||||
|
||||
|
||||
module.exports.i2c_write_byte_data = async (reg, byte_val) => {
|
||||
if (i2c_hand >= 0) return await module.exports._i2c_write_byte_data(sbc, i2c_hand, reg, byte_val);
|
||||
}
|
||||
module.exports.i2c_read_byte_data = async reg => {
|
||||
if (i2c_hand >= 0) return await module.exports._i2c_read_byte_data(sbc, i2c_hand, reg);
|
||||
}
|
||||
module.exports.i2c_write_i2c_block_data = async (reg, data) => {
|
||||
if (i2c_hand >= 0) return await module.exports._i2c_write_i2c_block_data(sbc, i2c_hand, reg, Buffer.from(data));
|
||||
}
|
||||
module.exports.i2c_read_word_data = async reg => {
|
||||
if (i2c_hand >= 0) return await module.exports._i2c_read_word_data(sbc, i2c_hand, reg);
|
||||
}
|
||||
module.exports.i2c_read_device = async count => {
|
||||
if (i2c_hand >= 0) return new TextDecoder().decode(await module.exports._i2c_read_device(sbc, i2c_hand, count));
|
||||
}
|
||||
module.exports.i2c_write_device = async data => {
|
||||
if (i2c_hand >= 0) return await module.exports._i2c_write_device(sbc, i2c_hand, Buffer.from(data));
|
||||
}
|
||||
|
||||
// 終了処理
|
||||
module.exports.close_all_handle = async () => {
|
||||
await module.exports.gpio_close();
|
||||
// await module.exports.serial_close();
|
||||
await module.exports.serial_close();
|
||||
await module.exports.i2c_close();
|
||||
}
|
@ -159,17 +159,122 @@ Promise _gpioWrite(const CallbackInfo &info)
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// シリアルポートを開く
|
||||
Promise _serialOpen(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 3)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count: _serialOpen").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsString() || !info[2].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types: _serialOpen").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
std::string ser_tty = info[1].As<String>().Utf8Value();
|
||||
int baud = info[2].As<Number>().Uint32Value();
|
||||
deferred.Resolve(Number::New(env, serial_open(sbc, (char *)ser_tty.c_str(), baud, 0)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// シリアルポートを閉じる
|
||||
Promise _serialClose(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 2)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
int handle = info[1].As<Number>().Uint32Value();
|
||||
deferred.Resolve(Number::New(env, serial_close(sbc, handle)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// シリアルデバイスからデータを読む
|
||||
Promise _serialRead(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 3)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
int handle = info[1].As<Number>().Uint32Value();
|
||||
int count = info[2].As<Number>().Uint32Value();
|
||||
|
||||
char buf[count];
|
||||
int rxCount = serial_read(sbc, handle, buf, count);
|
||||
auto outBuf = Buffer<char>::Copy(env, buf, rxCount);
|
||||
deferred.Resolve(outBuf);
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// シリアルデバイスにバイト列を書き込む(data: string)
|
||||
Promise _serialWrite(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 3)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
int handle = info[1].As<Number>().Uint32Value();
|
||||
auto buf = info[2].As<Buffer<char>>();
|
||||
|
||||
int count = buf.Length();
|
||||
deferred.Resolve(Number::New(env, serial_write(sbc, handle, buf.Data(), count)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// I2Cバスアドレスのデバイスのハンドルを返す
|
||||
Promise _i2cOpen(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 4)
|
||||
if (info.Length() != 3)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
@ -179,8 +284,7 @@ Promise _i2cOpen(const CallbackInfo &info)
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
unsigned int i2c_bus = info[1].As<Number>().Uint32Value();
|
||||
unsigned int i2c_addr = info[2].As<Number>().Uint32Value();
|
||||
int flags = 0;
|
||||
deferred.Resolve(Number::New(env, i2c_open(sbc, i2c_bus, i2c_addr, flags)));
|
||||
deferred.Resolve(Number::New(env, i2c_open(sbc, i2c_bus, i2c_addr, 0)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
@ -208,6 +312,54 @@ Promise _i2cClose(const CallbackInfo &info)
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// デバイスに1バイトを送る
|
||||
Promise _i2cWriteByte(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 3)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
unsigned int handle = info[1].As<Number>().Uint32Value();
|
||||
unsigned int bVal = info[2].As<Number>().Uint32Value();
|
||||
deferred.Resolve(Number::New(env, i2c_write_byte(sbc, handle, bVal)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
// デバイスから1バイトを受け取る
|
||||
Promise _i2cReadByte(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 2)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[0].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
unsigned int handle = info[1].As<Number>().Uint32Value();
|
||||
deferred.Resolve(Number::New(env, i2c_read_byte(sbc, handle)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタに1バイトを書き込む
|
||||
Promise _i2cWriteByteData(const CallbackInfo &info)
|
||||
{
|
||||
@ -233,6 +385,30 @@ Promise _i2cWriteByteData(const CallbackInfo &info)
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタから1バイトを読み込む
|
||||
Promise _i2cReadByteData(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 3)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
unsigned int handle = info[1].As<Number>().Uint32Value();
|
||||
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
|
||||
deferred.Resolve(Number::New(env, i2c_read_byte_data(sbc, handle, i2c_reg)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタからcountバイトを読み込む。countは1~32。
|
||||
Promise _i2cReadI2cBlockData(const CallbackInfo &info)
|
||||
@ -315,22 +491,114 @@ Promise _i2cReadWordData(const CallbackInfo &info)
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタに単一の16ビットワードを書き込む
|
||||
Promise _i2cWriteWordData(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 4)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
unsigned int handle = info[1].As<Number>().Uint32Value();
|
||||
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
|
||||
unsigned int wVal = info[3].As<Number>().Uint32Value();
|
||||
|
||||
deferred.Resolve(Number::New(env, i2c_write_word_data(sbc, handle, i2c_reg, wVal)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// i2c デバイスからデータを受け取る
|
||||
Promise _i2cReadDevice(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 3)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
unsigned int handle = info[1].As<Number>().Uint32Value();
|
||||
unsigned int count = info[2].As<Number>().Uint32Value();
|
||||
|
||||
char buf[count];
|
||||
int rxCount = i2c_read_device(sbc, handle, buf, count);
|
||||
auto outBuf = Buffer<char>::Copy(env, buf, rxCount);
|
||||
deferred.Resolve(outBuf);
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// i2c デバイスにバイト列を送る(data: buffer)
|
||||
Promise _i2cWriteDevice(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 3)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
unsigned int handle = info[1].As<Number>().Uint32Value();
|
||||
auto buf = info[2].As<Buffer<char>>();
|
||||
|
||||
unsigned int count = buf.Length();
|
||||
deferred.Resolve(Number::New(env, i2c_write_device(sbc, handle, buf.Data(), count)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
Object
|
||||
Init(Env env, Object exports)
|
||||
{
|
||||
exports.Set(String::New(env, "_rgpiod_start"), Function::New(env, _rgpiodStart));
|
||||
exports.Set(String::New(env, "_rgpiod_stop"), Function::New(env, _rgpiodStop));
|
||||
exports.Set(String::New(env, "_gpiod_start"), Function::New(env, _rgpiodStart));
|
||||
exports.Set(String::New(env, "_gpiod_stop"), Function::New(env, _rgpiodStop));
|
||||
exports.Set(String::New(env, "_gpiochip_open"), Function::New(env, _gpiochipOpen));
|
||||
exports.Set(String::New(env, "_gpiochip_close"), Function::New(env, _gpiochipClose));
|
||||
exports.Set(String::New(env, "_gpio_claim_output"), Function::New(env, _gpioClaimOutput));
|
||||
exports.Set(String::New(env, "_gpio_write"), Function::New(env, _gpioWrite));
|
||||
exports.Set(String::New(env, "_serial_open"), Function::New(env, _serialOpen));
|
||||
exports.Set(String::New(env, "_serial_close"), Function::New(env, _serialClose));
|
||||
exports.Set(String::New(env, "_serial_read"), Function::New(env, _serialRead));
|
||||
exports.Set(String::New(env, "_serial_write"), Function::New(env, _serialWrite));
|
||||
exports.Set(String::New(env, "_i2c_open"), Function::New(env, _i2cOpen));
|
||||
exports.Set(String::New(env, "_i2c_close"), Function::New(env, _i2cClose));
|
||||
exports.Set(String::New(env, "_i2c_write_byte"), Function::New(env, _i2cWriteByte));
|
||||
exports.Set(String::New(env, "_i2c_read_byte"), Function::New(env, _i2cReadByte));
|
||||
exports.Set(String::New(env, "_i2c_write_byte_data"), Function::New(env, _i2cWriteByteData));
|
||||
exports.Set(String::New(env, "_i2c_read_byte_data"), Function::New(env, _i2cReadByteData));
|
||||
exports.Set(String::New(env, "_i2c_read_i2c_block_data"), Function::New(env, _i2cReadI2cBlockData));
|
||||
exports.Set(String::New(env, "_i2c_write_i2c_block_data"), Function::New(env, _i2cWriteI2cBlockData));
|
||||
exports.Set(String::New(env, "_i2c_read_word_data"), Function::New(env, _i2cReadWordData));
|
||||
exports.Set(String::New(env, "_i2c_write_word_data"), Function::New(env, _i2cWriteWordData));
|
||||
exports.Set(String::New(env, "_i2c_write_device"), Function::New(env, _i2cWriteDevice));
|
||||
exports.Set(String::New(env, "_i2c_read_device"), Function::New(env, _i2cReadDevice));
|
||||
return exports;
|
||||
}
|
||||
|
||||
|
23
main.js
23
main.js
@ -60,7 +60,7 @@ const toggleCheck_i2c = checked_id => {
|
||||
|
||||
}
|
||||
const toggleCheck_lang = checked_id => {
|
||||
const menus = ['js-pigpio', 'js-rgpio', 'py'];
|
||||
const menus = ['js', 'py'];
|
||||
menus.forEach(id => {
|
||||
menu.getMenuItemById(id).checked = (id == checked_id);
|
||||
})
|
||||
@ -159,28 +159,15 @@ let template = [
|
||||
label: "Language",
|
||||
submenu: [
|
||||
{
|
||||
label: "JavaScript (pigpio)",
|
||||
id: "js-pigpio",
|
||||
label: "JavaScript",
|
||||
id: "js",
|
||||
type: 'checkbox',
|
||||
checked: true,
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
// menu.getMenuItemById('py').checked = false;
|
||||
toggleCheck_lang("js-pigpio");
|
||||
focusedWindow.webContents.executeJavaScript('apptool.setLang("js-pigpio")');
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "JavaScript (rgpio)",
|
||||
id: "js-rgpio",
|
||||
type: 'checkbox',
|
||||
checked: true,
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
// menu.getMenuItemById('py').checked = false;
|
||||
toggleCheck_lang("js-rgpio");
|
||||
focusedWindow.webContents.executeJavaScript('apptool.setLang("js-rgpio")');
|
||||
toggleCheck_lang("js");
|
||||
focusedWindow.webContents.executeJavaScript('apptool.setLang("js")');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
288
package-lock.json
generated
288
package-lock.json
generated
@ -9,25 +9,25 @@
|
||||
"version": "0.1.11",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@blockly/field-slider": "^4.0.12",
|
||||
"@blockly/field-slider": "^4.0.15",
|
||||
"@tensorflow-models/blazeface": "^0.0.7",
|
||||
"@tensorflow-models/knn-classifier": "^1.2.4",
|
||||
"@tensorflow-models/mobilenet": "^2.1.0",
|
||||
"@tensorflow-models/speech-commands": "^0.5.4",
|
||||
"@tensorflow/tfjs-node": "^4.4.0",
|
||||
"axios": "^1.3.5",
|
||||
"blockly": "^9.3.2",
|
||||
"@tensorflow/tfjs-node": "^4.5.0",
|
||||
"axios": "^1.4.0",
|
||||
"blockly": "^9.3.3",
|
||||
"dracula-prism": "^2.1.13",
|
||||
"js-beautify": "^1.14.7",
|
||||
"node-abi": "^3.35.0",
|
||||
"node-abi": "^3.40.0",
|
||||
"nodemailer": "^6.9.1",
|
||||
"prismjs": "^1.29.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "^6.1.1",
|
||||
"@electron-forge/maker-deb": "^6.1.1",
|
||||
"@electron/rebuild": "^3.2.10",
|
||||
"electron": "^24.0.0"
|
||||
"@electron/rebuild": "^3.2.13",
|
||||
"electron": "^24.2.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@ocoge.club/pigpio": "file:local_modules/pigpio",
|
||||
@ -35,14 +35,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@blockly/field-slider": {
|
||||
"version": "4.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-4.0.12.tgz",
|
||||
"integrity": "sha512-Mw6O8eQ225WURiz5Y3kldOMlbkoPSliTyJM7E20zEAFS6Ww6DFmfBI32UBUx8HeqdAAvIEottXERvGd3ONdE8g==",
|
||||
"version": "4.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-4.0.15.tgz",
|
||||
"integrity": "sha512-8U1nzWXKMSs0g3r5GD5i1DEWutIJOdTMhQn5kjD0a0447ZlA81d9gePdQuV+puTaesFDGWPcVBvuo4FQhJ2Y5w==",
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"blockly": "^9.2.0"
|
||||
"blockly": "^9.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/cli": {
|
||||
@ -423,9 +423,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/rebuild": {
|
||||
"version": "3.2.10",
|
||||
"resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.10.tgz",
|
||||
"integrity": "sha512-SUBM6Mwi3yZaDFQjZzfGKpYTtOp9m60glounwX6tfGeVc/ZOl4jbquktUcyy7gYSLDWFLtKkftkY2xgMJZLQgg==",
|
||||
"version": "3.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.13.tgz",
|
||||
"integrity": "sha512-DH9Ol4JCnHDYVOD0fKWq+Qqbn/0WU1O6QR0mIpMXEVU4YFM4PlaqNC9K36mGShNBxxGFotZCMDrB1wl/iHM12g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@malept/cross-spawn-promise": "^2.0.0",
|
||||
@ -434,7 +434,6 @@
|
||||
"detect-libc": "^2.0.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
"got": "^11.7.0",
|
||||
"lzma-native": "^8.0.5",
|
||||
"node-abi": "^3.0.0",
|
||||
"node-api-version": "^0.1.4",
|
||||
"node-gyp": "^9.0.0",
|
||||
@ -444,7 +443,7 @@
|
||||
"yargs": "^17.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"electron-rebuild": "lib/src/cli.js"
|
||||
"electron-rebuild": "lib/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.13.0"
|
||||
@ -762,16 +761,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tensorflow/tfjs": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.4.0.tgz",
|
||||
"integrity": "sha512-EmCsnzdvawyk4b+4JKaLLuicHcJQRZtL1zSy9AWJLiiHTbDDseYgLxfaCEfLk8v2bUe7SBXwl3n3B7OjgvH11Q==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.5.0.tgz",
|
||||
"integrity": "sha512-GMpFI9GgotUSQKpce500yyBujYY8sWagG0gCpnjTSVzWrYRS8bsL+6Fq/GCamiCX5jtOrlpZ/kRkz/HIqaYXWg==",
|
||||
"dependencies": {
|
||||
"@tensorflow/tfjs-backend-cpu": "4.4.0",
|
||||
"@tensorflow/tfjs-backend-webgl": "4.4.0",
|
||||
"@tensorflow/tfjs-converter": "4.4.0",
|
||||
"@tensorflow/tfjs-core": "4.4.0",
|
||||
"@tensorflow/tfjs-data": "4.4.0",
|
||||
"@tensorflow/tfjs-layers": "4.4.0",
|
||||
"@tensorflow/tfjs-backend-cpu": "4.5.0",
|
||||
"@tensorflow/tfjs-backend-webgl": "4.5.0",
|
||||
"@tensorflow/tfjs-converter": "4.5.0",
|
||||
"@tensorflow/tfjs-core": "4.5.0",
|
||||
"@tensorflow/tfjs-data": "4.5.0",
|
||||
"@tensorflow/tfjs-layers": "4.5.0",
|
||||
"argparse": "^1.0.10",
|
||||
"chalk": "^4.1.0",
|
||||
"core-js": "3.29.1",
|
||||
@ -783,9 +782,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tensorflow/tfjs-backend-cpu": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.4.0.tgz",
|
||||
"integrity": "sha512-d4eln500/qNym78z9IrUUzF0ITBoJGLrxV8xd92kLVoXhg35Mm+zqUXShjFcrH8joOHOFuST0qZ0TbDDqcPzPA==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.5.0.tgz",
|
||||
"integrity": "sha512-TO6tkGeqR0UhifEx2SBa15kv8UlpubCHPGFHAnAfiPqBe3Z+3D7zqMlw2RvOelrzxzCWpTQByppFkB5u1pfiiA==",
|
||||
"dependencies": {
|
||||
"@types/seedrandom": "^2.4.28",
|
||||
"seedrandom": "^3.0.5"
|
||||
@ -794,15 +793,15 @@
|
||||
"yarn": ">= 1.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tensorflow/tfjs-core": "4.4.0"
|
||||
"@tensorflow/tfjs-core": "4.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tensorflow/tfjs-backend-webgl": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.4.0.tgz",
|
||||
"integrity": "sha512-TzQKvfAPgGt9cMG+5bVoTckoG1xr/PVJM/uODkPvzcMqi3j97kuWDXwkYJIgXldStmfiKkU7f5CmyD3Cq3E6BA==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.5.0.tgz",
|
||||
"integrity": "sha512-xBgb3GW9wPbKRKeL8k0hxhyZv21uPnZ1eEXgwnpfgu86rXajToA7ATklh7bCpOlrQDY/n7ixBA8PwvsQEt2Jcw==",
|
||||
"dependencies": {
|
||||
"@tensorflow/tfjs-backend-cpu": "4.4.0",
|
||||
"@tensorflow/tfjs-backend-cpu": "4.5.0",
|
||||
"@types/offscreencanvas": "~2019.3.0",
|
||||
"@types/seedrandom": "^2.4.28",
|
||||
"@types/webgl-ext": "0.0.30",
|
||||
@ -812,21 +811,21 @@
|
||||
"yarn": ">= 1.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tensorflow/tfjs-core": "4.4.0"
|
||||
"@tensorflow/tfjs-core": "4.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tensorflow/tfjs-converter": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.4.0.tgz",
|
||||
"integrity": "sha512-JUjpRStrAuw37tgPd5UENu0UjQVuJT09yF7KpOur4BriJ0uQqrbEZHMPHmvUtr5nYzkqlXJTuXIyxvEY/olNpg==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.5.0.tgz",
|
||||
"integrity": "sha512-gd2DiLPX1YStXk4mkgqzbQuOoiwcuSv4s7tTyYvFEX5Ty9SKmttYmannCCppzmliL6aTzyxTpIZyWnqTPuTxeg==",
|
||||
"peerDependencies": {
|
||||
"@tensorflow/tfjs-core": "4.4.0"
|
||||
"@tensorflow/tfjs-core": "4.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tensorflow/tfjs-core": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.4.0.tgz",
|
||||
"integrity": "sha512-Anxpc7cAOA0Q7EUXdTbQKMg3reFvrdkgDlaYzH9ZfkMq2CgLV4Au6E/s6HmbYn/VrAtWy9mLY5c/lLJqh4764g==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.5.0.tgz",
|
||||
"integrity": "sha512-FrHUnab/5msyzIg7zcjBmMV8W9vf2lj+f4em0zL+ntAczkEBeMAEIykk9BmV7sqMplRiCu2Cfrks8EqHFutSqw==",
|
||||
"dependencies": {
|
||||
"@types/long": "^4.0.1",
|
||||
"@types/offscreencanvas": "~2019.7.0",
|
||||
@ -847,35 +846,35 @@
|
||||
"integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg=="
|
||||
},
|
||||
"node_modules/@tensorflow/tfjs-data": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.4.0.tgz",
|
||||
"integrity": "sha512-aY4eq4cgrsrXeBU6ABZAAN3tV0fG4YcHd0z+cYuNXnCo+VEQLJnPmhn+xymZ4VQZQH4GXbVS4dV9pXMclFNRFw==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.5.0.tgz",
|
||||
"integrity": "sha512-fqTS5K+TrdisyDOOjcKwYQtoGyk9GzYhxwof1X9kpdm2zxpwl0kzeSqqCuVMPGD5DAOKp+EccTWYfAC4MIafcw==",
|
||||
"dependencies": {
|
||||
"@types/node-fetch": "^2.1.2",
|
||||
"node-fetch": "~2.6.1",
|
||||
"string_decoder": "^1.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tensorflow/tfjs-core": "4.4.0",
|
||||
"@tensorflow/tfjs-core": "4.5.0",
|
||||
"seedrandom": "^3.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@tensorflow/tfjs-layers": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.4.0.tgz",
|
||||
"integrity": "sha512-OGC7shfiD9Gc698hINHK4y9slOJvu5m54tVNm4xf+WSNrw/avvgpar6yyoL5bakYIZNQvFNK75Yr8VRPR7oPeQ==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.5.0.tgz",
|
||||
"integrity": "sha512-/Ohzc39SiIszQqOjEb+4DzGyJkdCweGP4uoblUzQQZdolJB/NxsAHJ06YUj0mD5dflTwNVCwYAe3rkdYqNlgvg==",
|
||||
"peerDependencies": {
|
||||
"@tensorflow/tfjs-core": "4.4.0"
|
||||
"@tensorflow/tfjs-core": "4.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tensorflow/tfjs-node": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-4.4.0.tgz",
|
||||
"integrity": "sha512-+JSAddsupjSQUDZeb7QGOFkL3Tty3kjPHx8ethiYFzwTZJHCMvM7wZJd0Fqnjxym6A0KpsmB7SPZgwRRXVIlPA==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-4.5.0.tgz",
|
||||
"integrity": "sha512-KX1Vl9G6kqOvt9WIQhb54S3H9qx8K+rMaOoyy2LMytcUU5hbcOi8ElGju4BGM4xSCrYFtJI3hBsl+Xfgd2hAKg==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@mapbox/node-pre-gyp": "1.0.9",
|
||||
"@tensorflow/tfjs": "4.4.0",
|
||||
"@tensorflow/tfjs": "4.5.0",
|
||||
"adm-zip": "^0.5.2",
|
||||
"google-protobuf": "^3.9.2",
|
||||
"https-proxy-agent": "^2.2.1",
|
||||
@ -1318,9 +1317,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz",
|
||||
"integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==",
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
|
||||
"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.0",
|
||||
"form-data": "^4.0.0",
|
||||
@ -1386,9 +1385,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/blockly": {
|
||||
"version": "9.3.2",
|
||||
"resolved": "https://registry.npmjs.org/blockly/-/blockly-9.3.2.tgz",
|
||||
"integrity": "sha512-VbdvG7AWOJvbUaUAvia/hXhoIE1vznRAWrh4Tz3xDYJICP7KzKHJcS/Q7OF0JuX60rpo8SJ59XPZ6WnqENqLqA==",
|
||||
"version": "9.3.3",
|
||||
"resolved": "https://registry.npmjs.org/blockly/-/blockly-9.3.3.tgz",
|
||||
"integrity": "sha512-L7LlrGXICEN+UaZsYq3Iz2/SF8uF2ks90ozwVXTkpueCpuo/Xt9eu4Skci6b1JUL7alMPPgt+AxIuq+2/p99Cg==",
|
||||
"dependencies": {
|
||||
"jsdom": "21.1.1"
|
||||
}
|
||||
@ -2132,9 +2131,9 @@
|
||||
"integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
|
||||
},
|
||||
"node_modules/electron": {
|
||||
"version": "24.0.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-24.0.0.tgz",
|
||||
"integrity": "sha512-QmL8L53fQ+xOAp8m2mSGNewhDvJqQttCxrcesf0cqndKQDsIq4QvR35wGJqHg7MyPQKcBErLhZj9QvRheO5qnA==",
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-24.2.0.tgz",
|
||||
"integrity": "sha512-fEYAftYqFhveniWJbEHXjNMWjooFFIuqNj/eEFJkGzycInfBJq/c4E/dew++s6s0YLubxFnjoF2qZiqapLj0gA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
@ -3997,24 +3996,6 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/lzma-native": {
|
||||
"version": "8.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz",
|
||||
"integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"node-addon-api": "^3.1.0",
|
||||
"node-gyp-build": "^4.2.1",
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"bin": {
|
||||
"lzmajs": "bin/lzmajs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/make-dir": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
@ -4326,9 +4307,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-abi": {
|
||||
"version": "3.35.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.35.0.tgz",
|
||||
"integrity": "sha512-jAlSOFR1Bls963NmFwxeQkNTzqjUF0NThm8Le7eRIRGzFUVJuMOFZDLv5Y30W/Oaw+KEebEJLAigwO9gQHoEmw==",
|
||||
"version": "3.40.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.40.0.tgz",
|
||||
"integrity": "sha512-zNy02qivjjRosswoYmPi8hIKJRr8MpQyeKT6qlcq/OnOgA3Rhoae+IYOqsM9V5+JnHWmxKnWOT2GxvtqdtOCXA==",
|
||||
"dependencies": {
|
||||
"semver": "^7.3.5"
|
||||
},
|
||||
@ -4336,12 +4317,6 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
|
||||
"integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-api-version": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz",
|
||||
@ -4413,17 +4388,6 @@
|
||||
"node": "^12.13 || ^14.13 || >=16"
|
||||
}
|
||||
},
|
||||
"node_modules/node-gyp-build": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz",
|
||||
"integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"node-gyp-build": "bin.js",
|
||||
"node-gyp-build-optional": "optional.js",
|
||||
"node-gyp-build-test": "build-test.js"
|
||||
}
|
||||
},
|
||||
"node_modules/node-gyp/node_modules/are-we-there-yet": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
|
||||
@ -6340,9 +6304,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@blockly/field-slider": {
|
||||
"version": "4.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-4.0.12.tgz",
|
||||
"integrity": "sha512-Mw6O8eQ225WURiz5Y3kldOMlbkoPSliTyJM7E20zEAFS6Ww6DFmfBI32UBUx8HeqdAAvIEottXERvGd3ONdE8g=="
|
||||
"version": "4.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-4.0.15.tgz",
|
||||
"integrity": "sha512-8U1nzWXKMSs0g3r5GD5i1DEWutIJOdTMhQn5kjD0a0447ZlA81d9gePdQuV+puTaesFDGWPcVBvuo4FQhJ2Y5w=="
|
||||
},
|
||||
"@electron-forge/cli": {
|
||||
"version": "6.1.1",
|
||||
@ -6627,9 +6591,9 @@
|
||||
}
|
||||
},
|
||||
"@electron/rebuild": {
|
||||
"version": "3.2.10",
|
||||
"resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.10.tgz",
|
||||
"integrity": "sha512-SUBM6Mwi3yZaDFQjZzfGKpYTtOp9m60glounwX6tfGeVc/ZOl4jbquktUcyy7gYSLDWFLtKkftkY2xgMJZLQgg==",
|
||||
"version": "3.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.13.tgz",
|
||||
"integrity": "sha512-DH9Ol4JCnHDYVOD0fKWq+Qqbn/0WU1O6QR0mIpMXEVU4YFM4PlaqNC9K36mGShNBxxGFotZCMDrB1wl/iHM12g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@malept/cross-spawn-promise": "^2.0.0",
|
||||
@ -6638,7 +6602,6 @@
|
||||
"detect-libc": "^2.0.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
"got": "^11.7.0",
|
||||
"lzma-native": "^8.0.5",
|
||||
"node-abi": "^3.0.0",
|
||||
"node-api-version": "^0.1.4",
|
||||
"node-gyp": "^9.0.0",
|
||||
@ -6869,16 +6832,16 @@
|
||||
"integrity": "sha512-r0c/MvC15/09xWujx1pKe6mA0nta+4jQWDXGkqfSVkXLo8ARrwcZ4mTGLlfvT43ySfidiveUo0m+P51+UK821Q=="
|
||||
},
|
||||
"@tensorflow/tfjs": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.4.0.tgz",
|
||||
"integrity": "sha512-EmCsnzdvawyk4b+4JKaLLuicHcJQRZtL1zSy9AWJLiiHTbDDseYgLxfaCEfLk8v2bUe7SBXwl3n3B7OjgvH11Q==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.5.0.tgz",
|
||||
"integrity": "sha512-GMpFI9GgotUSQKpce500yyBujYY8sWagG0gCpnjTSVzWrYRS8bsL+6Fq/GCamiCX5jtOrlpZ/kRkz/HIqaYXWg==",
|
||||
"requires": {
|
||||
"@tensorflow/tfjs-backend-cpu": "4.4.0",
|
||||
"@tensorflow/tfjs-backend-webgl": "4.4.0",
|
||||
"@tensorflow/tfjs-converter": "4.4.0",
|
||||
"@tensorflow/tfjs-core": "4.4.0",
|
||||
"@tensorflow/tfjs-data": "4.4.0",
|
||||
"@tensorflow/tfjs-layers": "4.4.0",
|
||||
"@tensorflow/tfjs-backend-cpu": "4.5.0",
|
||||
"@tensorflow/tfjs-backend-webgl": "4.5.0",
|
||||
"@tensorflow/tfjs-converter": "4.5.0",
|
||||
"@tensorflow/tfjs-core": "4.5.0",
|
||||
"@tensorflow/tfjs-data": "4.5.0",
|
||||
"@tensorflow/tfjs-layers": "4.5.0",
|
||||
"argparse": "^1.0.10",
|
||||
"chalk": "^4.1.0",
|
||||
"core-js": "3.29.1",
|
||||
@ -6918,20 +6881,20 @@
|
||||
}
|
||||
},
|
||||
"@tensorflow/tfjs-backend-cpu": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.4.0.tgz",
|
||||
"integrity": "sha512-d4eln500/qNym78z9IrUUzF0ITBoJGLrxV8xd92kLVoXhg35Mm+zqUXShjFcrH8joOHOFuST0qZ0TbDDqcPzPA==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.5.0.tgz",
|
||||
"integrity": "sha512-TO6tkGeqR0UhifEx2SBa15kv8UlpubCHPGFHAnAfiPqBe3Z+3D7zqMlw2RvOelrzxzCWpTQByppFkB5u1pfiiA==",
|
||||
"requires": {
|
||||
"@types/seedrandom": "^2.4.28",
|
||||
"seedrandom": "^3.0.5"
|
||||
}
|
||||
},
|
||||
"@tensorflow/tfjs-backend-webgl": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.4.0.tgz",
|
||||
"integrity": "sha512-TzQKvfAPgGt9cMG+5bVoTckoG1xr/PVJM/uODkPvzcMqi3j97kuWDXwkYJIgXldStmfiKkU7f5CmyD3Cq3E6BA==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.5.0.tgz",
|
||||
"integrity": "sha512-xBgb3GW9wPbKRKeL8k0hxhyZv21uPnZ1eEXgwnpfgu86rXajToA7ATklh7bCpOlrQDY/n7ixBA8PwvsQEt2Jcw==",
|
||||
"requires": {
|
||||
"@tensorflow/tfjs-backend-cpu": "4.4.0",
|
||||
"@tensorflow/tfjs-backend-cpu": "4.5.0",
|
||||
"@types/offscreencanvas": "~2019.3.0",
|
||||
"@types/seedrandom": "^2.4.28",
|
||||
"@types/webgl-ext": "0.0.30",
|
||||
@ -6939,14 +6902,14 @@
|
||||
}
|
||||
},
|
||||
"@tensorflow/tfjs-converter": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.4.0.tgz",
|
||||
"integrity": "sha512-JUjpRStrAuw37tgPd5UENu0UjQVuJT09yF7KpOur4BriJ0uQqrbEZHMPHmvUtr5nYzkqlXJTuXIyxvEY/olNpg=="
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.5.0.tgz",
|
||||
"integrity": "sha512-gd2DiLPX1YStXk4mkgqzbQuOoiwcuSv4s7tTyYvFEX5Ty9SKmttYmannCCppzmliL6aTzyxTpIZyWnqTPuTxeg=="
|
||||
},
|
||||
"@tensorflow/tfjs-core": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.4.0.tgz",
|
||||
"integrity": "sha512-Anxpc7cAOA0Q7EUXdTbQKMg3reFvrdkgDlaYzH9ZfkMq2CgLV4Au6E/s6HmbYn/VrAtWy9mLY5c/lLJqh4764g==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.5.0.tgz",
|
||||
"integrity": "sha512-FrHUnab/5msyzIg7zcjBmMV8W9vf2lj+f4em0zL+ntAczkEBeMAEIykk9BmV7sqMplRiCu2Cfrks8EqHFutSqw==",
|
||||
"requires": {
|
||||
"@types/long": "^4.0.1",
|
||||
"@types/offscreencanvas": "~2019.7.0",
|
||||
@ -6966,9 +6929,9 @@
|
||||
}
|
||||
},
|
||||
"@tensorflow/tfjs-data": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.4.0.tgz",
|
||||
"integrity": "sha512-aY4eq4cgrsrXeBU6ABZAAN3tV0fG4YcHd0z+cYuNXnCo+VEQLJnPmhn+xymZ4VQZQH4GXbVS4dV9pXMclFNRFw==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.5.0.tgz",
|
||||
"integrity": "sha512-fqTS5K+TrdisyDOOjcKwYQtoGyk9GzYhxwof1X9kpdm2zxpwl0kzeSqqCuVMPGD5DAOKp+EccTWYfAC4MIafcw==",
|
||||
"requires": {
|
||||
"@types/node-fetch": "^2.1.2",
|
||||
"node-fetch": "~2.6.1",
|
||||
@ -6976,17 +6939,17 @@
|
||||
}
|
||||
},
|
||||
"@tensorflow/tfjs-layers": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.4.0.tgz",
|
||||
"integrity": "sha512-OGC7shfiD9Gc698hINHK4y9slOJvu5m54tVNm4xf+WSNrw/avvgpar6yyoL5bakYIZNQvFNK75Yr8VRPR7oPeQ=="
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.5.0.tgz",
|
||||
"integrity": "sha512-/Ohzc39SiIszQqOjEb+4DzGyJkdCweGP4uoblUzQQZdolJB/NxsAHJ06YUj0mD5dflTwNVCwYAe3rkdYqNlgvg=="
|
||||
},
|
||||
"@tensorflow/tfjs-node": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-4.4.0.tgz",
|
||||
"integrity": "sha512-+JSAddsupjSQUDZeb7QGOFkL3Tty3kjPHx8ethiYFzwTZJHCMvM7wZJd0Fqnjxym6A0KpsmB7SPZgwRRXVIlPA==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-4.5.0.tgz",
|
||||
"integrity": "sha512-KX1Vl9G6kqOvt9WIQhb54S3H9qx8K+rMaOoyy2LMytcUU5hbcOi8ElGju4BGM4xSCrYFtJI3hBsl+Xfgd2hAKg==",
|
||||
"requires": {
|
||||
"@mapbox/node-pre-gyp": "1.0.9",
|
||||
"@tensorflow/tfjs": "4.4.0",
|
||||
"@tensorflow/tfjs": "4.5.0",
|
||||
"adm-zip": "^0.5.2",
|
||||
"google-protobuf": "^3.9.2",
|
||||
"https-proxy-agent": "^2.2.1",
|
||||
@ -7326,9 +7289,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz",
|
||||
"integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==",
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
|
||||
"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.15.0",
|
||||
"form-data": "^4.0.0",
|
||||
@ -7379,9 +7342,9 @@
|
||||
}
|
||||
},
|
||||
"blockly": {
|
||||
"version": "9.3.2",
|
||||
"resolved": "https://registry.npmjs.org/blockly/-/blockly-9.3.2.tgz",
|
||||
"integrity": "sha512-VbdvG7AWOJvbUaUAvia/hXhoIE1vznRAWrh4Tz3xDYJICP7KzKHJcS/Q7OF0JuX60rpo8SJ59XPZ6WnqENqLqA==",
|
||||
"version": "9.3.3",
|
||||
"resolved": "https://registry.npmjs.org/blockly/-/blockly-9.3.3.tgz",
|
||||
"integrity": "sha512-L7LlrGXICEN+UaZsYq3Iz2/SF8uF2ks90ozwVXTkpueCpuo/Xt9eu4Skci6b1JUL7alMPPgt+AxIuq+2/p99Cg==",
|
||||
"requires": {
|
||||
"jsdom": "21.1.1"
|
||||
}
|
||||
@ -7929,9 +7892,9 @@
|
||||
}
|
||||
},
|
||||
"electron": {
|
||||
"version": "24.0.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-24.0.0.tgz",
|
||||
"integrity": "sha512-QmL8L53fQ+xOAp8m2mSGNewhDvJqQttCxrcesf0cqndKQDsIq4QvR35wGJqHg7MyPQKcBErLhZj9QvRheO5qnA==",
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-24.2.0.tgz",
|
||||
"integrity": "sha512-fEYAftYqFhveniWJbEHXjNMWjooFFIuqNj/eEFJkGzycInfBJq/c4E/dew++s6s0YLubxFnjoF2qZiqapLj0gA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@electron/get": "^2.0.0",
|
||||
@ -9338,17 +9301,6 @@
|
||||
"integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==",
|
||||
"dev": true
|
||||
},
|
||||
"lzma-native": {
|
||||
"version": "8.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz",
|
||||
"integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"node-addon-api": "^3.1.0",
|
||||
"node-gyp-build": "^4.2.1",
|
||||
"readable-stream": "^3.6.0"
|
||||
}
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
@ -9581,19 +9533,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"node-abi": {
|
||||
"version": "3.35.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.35.0.tgz",
|
||||
"integrity": "sha512-jAlSOFR1Bls963NmFwxeQkNTzqjUF0NThm8Le7eRIRGzFUVJuMOFZDLv5Y30W/Oaw+KEebEJLAigwO9gQHoEmw==",
|
||||
"version": "3.40.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.40.0.tgz",
|
||||
"integrity": "sha512-zNy02qivjjRosswoYmPi8hIKJRr8MpQyeKT6qlcq/OnOgA3Rhoae+IYOqsM9V5+JnHWmxKnWOT2GxvtqdtOCXA==",
|
||||
"requires": {
|
||||
"semver": "^7.3.5"
|
||||
}
|
||||
},
|
||||
"node-addon-api": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
|
||||
"integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
|
||||
"dev": true
|
||||
},
|
||||
"node-api-version": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz",
|
||||
@ -9708,12 +9654,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-gyp-build": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz",
|
||||
"integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==",
|
||||
"dev": true
|
||||
},
|
||||
"nodemailer": {
|
||||
"version": "6.9.1",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.1.tgz",
|
||||
|
14
package.json
14
package.json
@ -24,21 +24,21 @@
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "^6.1.1",
|
||||
"@electron-forge/maker-deb": "^6.1.1",
|
||||
"@electron/rebuild": "^3.2.10",
|
||||
"electron": "^24.0.0"
|
||||
"@electron/rebuild": "^3.2.13",
|
||||
"electron": "^24.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@blockly/field-slider": "^4.0.12",
|
||||
"@blockly/field-slider": "^4.0.15",
|
||||
"@tensorflow-models/blazeface": "^0.0.7",
|
||||
"@tensorflow-models/knn-classifier": "^1.2.4",
|
||||
"@tensorflow-models/mobilenet": "^2.1.0",
|
||||
"@tensorflow-models/speech-commands": "^0.5.4",
|
||||
"@tensorflow/tfjs-node": "^4.4.0",
|
||||
"axios": "^1.3.5",
|
||||
"blockly": "^9.3.2",
|
||||
"@tensorflow/tfjs-node": "^4.5.0",
|
||||
"axios": "^1.4.0",
|
||||
"blockly": "^9.3.3",
|
||||
"dracula-prism": "^2.1.13",
|
||||
"js-beautify": "^1.14.7",
|
||||
"node-abi": "^3.35.0",
|
||||
"node-abi": "^3.40.0",
|
||||
"nodemailer": "^6.9.1",
|
||||
"prismjs": "^1.29.0"
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user