{
	"metadata": {
		"type": "ohcode",
		"name": "OHCode",
		"company": "开源大师兄",
		"website": "https://www.oh-code.com/",
		"boardtype": "V2"
	},
	"sourcedata": {
		"xml": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"when_start\" id=\"T2XpqjIDZ}u46yU9thu)\" x=\"90\" y=\"-70\"><next><block type=\"while_true\" id=\"dSB^03_0(B0cPIMFf(c@\"><statement name=\"event_handler\"><block type=\"screen_show_ohcode\" id=\"nmpL|)R3|=VrKyERh4mY\"><value name=\"TEXT\"><shadow type=\"text\" id=\":/HG#6zPZo)pOkUFDXD3\"><field name=\"TEXT\">您好，中国！</field></shadow><block type=\"get_ambientlight\" id=\"``F-mmzFC,ZcuC*;cip4\"/></value></block></statement></block></next></block><block type=\"when_ambient_light_less_than\" id=\"6=y^n1o%m3-mjKuU9;G5\" x=\"410\" y=\"-70\"><value name=\"LIGHT\"><shadow type=\"math_number\" id=\"(tY?:Oy)pv`ST;S%HV.g\"><field name=\"NUM\">30</field></shadow></value><next><block type=\"set_rgb_light\" id=\"$@tiB!]s#;@!jSWKYD.Y\"><field name=\"LIGHT\">-1</field><field name=\"COLOR\">white</field></block></next></block><block type=\"when_ambient_light_more_than\" id=\"FV^{o31CUR.a5mkTftY.\" x=\"410\" y=\"90\"><value name=\"LIGHT\"><shadow type=\"math_number\" id=\"H;^Ci4.qwv:+Sp8;63/7\"><field name=\"NUM\">50</field></shadow></value><next><block type=\"clear_rgb_light\" id=\"Yc*x[{=NiyZ@RDV3^[2s\"><field name=\"LIGHT\">-1</field></block></next></block></xml>"
	},
	"extenddata": "{\"519b099adbfe36504f88502146df25f4\":{\"category\":{\"kind\":\"CATEGORY\",\"name\":\"扩展\",\"colour\":\"#d4237a\",\"contents\":[{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_screen_show\",\"inputs\":{\"TEXT\":{\"shadow\":{\"type\":\"text\",\"fields\":{\"TEXT\":\"OHCode Extend Success\"}}}}},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_screen_clean\"},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_screen_line_show\",\"inputs\":{\"TEXT\":{\"shadow\":{\"type\":\"text\",\"fields\":{\"TEXT\":\"Hello World\"}}}}},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_while_condition\",\"inputs\":{\"CONDITION\":{\"shadow\":{\"type\":\"logic_boolean\"}}}},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_math_modulo\",\"inputs\":{\"DIVIDEND\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":54}}},\"DIVISOR\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":10}}}}},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_logic_negate\"},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_calculator_add\",\"inputs\":{\"NUM1\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":5}}},\"NUM2\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":10}}}}},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_thisblock_current_time\"}],\"cssConfig\":{\"icon\":\"blocklyTreeIcon ohcodeextend2dc90225b8033d17c41b08f39fa42de2Icon\"}},\"blocksdef\":\"/**\\r\\n * category.json里引用的每个代码块都需要在这里实现相应的定义及python代码生成定义！\\r\\n * 以下行注释简单描述了相关的功能，可删除\\r\\n */\\r\\nBlockly.Blocks['ohcode_extend_screen_show'] = {\\r\\n    init: function () {\\r\\n        this.appendDummyInput()\\r\\n            .appendField(\\\"扩展插件之屏幕显示\\\");\\r\\n        this.appendValueInput(\\\"TEXT\\\") //字段名称自取，但是注意pythonGenerator处理逻辑\\r\\n            .setCheck(null);//限制输入类型 String/Number/Boolen/null  null为不限制 可以支持不同类型的代码块组合，但是注意pythonGenerator处理逻辑\\r\\n        this.appendDummyInput(\\\"TEXT\\\")\\r\\n            .appendField(\\\" \\\");\\r\\n        this.setPreviousStatement(true, null);//是否可以接入上一个代码块\\r\\n        this.setNextStatement(true, null);//是否可以接入下一个代码块\\r\\n        this.setColour(\\\"#d4237a\\\");\\r\\n        this.setTooltip(\\\"扩展插件之在屏幕第1行显示的内容。\\\");\\r\\n        this.setHelpUrl(\\\"\\\");\\r\\n    }\\r\\n};\\r\\n/**\\r\\n * 严格使用pythonGenerator.forBlock\\r\\n * return的内容最后必须加换行[\\\\n]！前面没有要求。\\r\\n */\\r\\npythonGenerator.forBlock['ohcode_extend_screen_show'] = function (block) {\\r\\n    const text = pythonGenerator.valueToCode(block, 'TEXT', pythonGenerator.ORDER_ATOMIC);//由于值是不确定的，使用pythonGenerator.valueToCode获取最终表达式\\r\\n\\r\\n    pythonGenerator.definitions_[\\\"import_oled\\\"] = \\\"from device import OLED\\\\n\\\"\\r\\n    pythonGenerator.definitions_[\\\"oled_init\\\"] = \\\"oled = OLED(0x3c)\\\\n\\\"\\r\\n    return `\\\\noled.fill_screen(0)\\\\noled.show_str_line(str(${text}),int(1),1)\\\\noled.flush()\\\\n`\\r\\n};\\r\\n\\r\\nBlockly.Blocks['ohcode_extend_screen_clean'] = {\\r\\n    init: function () {\\r\\n        this.appendDummyInput()\\r\\n            .appendField(\\\"扩展插件之清空屏幕\\\");\\r\\n        this.setPreviousStatement(true, null);\\r\\n        this.setNextStatement(true, null);\\r\\n        this.setColour(\\\"#d4237a\\\");\\r\\n        this.setTooltip(\\\"扩展插件之清除屏幕显示的内容。\\\");\\r\\n        this.setHelpUrl(\\\"\\\");\\r\\n    }\\r\\n};\\r\\n\\r\\npythonGenerator.forBlock['ohcode_extend_screen_clean'] = function (block) {\\r\\n    pythonGenerator.definitions_[\\\"import_oled\\\"] = \\\"from device import OLED\\\\n\\\"\\r\\n    pythonGenerator.definitions_[\\\"oled_init\\\"] = \\\"oled = OLED(0x3c)\\\\n\\\"\\r\\n    return `\\\\noled.fill_screen(0)\\\\noled.flush()\\\\n`\\r\\n};\\r\\n\\r\\nBlockly.Blocks['ohcode_extend_screen_line_show'] = {\\r\\n    init: function () {\\r\\n        this.appendDummyInput()\\r\\n            .appendField(\\\"扩展插件之OLED第\\\")\\r\\n            .appendField(new Blockly.FieldDropdown([\\r\\n                ['1', '1'],\\r\\n                ['2', '2'],\\r\\n                ['3', '3']\\r\\n            ]), \\\"LINE\\\"); //添加下拉选择框\\r\\n        this.appendDummyInput(\\\"LINE\\\")\\r\\n            .appendField(\\\"行显示\\\");\\r\\n        this.appendValueInput(\\\"TEXT\\\")\\r\\n            .setCheck(null);\\r\\n        this.appendDummyInput(\\\"TEXT\\\")\\r\\n            .appendField(\\\" \\\");\\r\\n        this.setInputsInline(true);\\r\\n        this.setPreviousStatement(true, null);\\r\\n        this.setNextStatement(true, null);\\r\\n        this.setColour(\\\"#d4237a\\\");\\r\\n        this.setTooltip(\\\"\\\");\\r\\n        this.setHelpUrl(\\\"\\\");\\r\\n    }\\r\\n};\\r\\n\\r\\npythonGenerator.forBlock['ohcode_extend_screen_line_show'] = function (block) {\\r\\n    const line = block.getFieldValue('LINE');//由于下拉选择框的值是唯一的，所以直接可以使用getFieldValue\\r\\n    const text = pythonGenerator.valueToCode(block, 'TEXT', pythonGenerator.ORDER_ATOMIC);\\r\\n\\r\\n    pythonGenerator.definitions_[\\\"import_oled\\\"] = \\\"from device import OLED\\\\n\\\"\\r\\n    pythonGenerator.definitions_[\\\"oled_init\\\"] = \\\"oled = OLED(0x3c)\\\\n\\\"\\r\\n\\r\\n    return `\\\\noled.show_str_line(str(${text}),int(${line}),1)\\\\n`\\r\\n};\\r\\n\\r\\n/**\\r\\n * 以下是事件类代码块的示例\\r\\n */\\r\\nBlockly.Blocks['ohcode_extend_while_condition'] = {\\r\\n    init: function () {\\r\\n        this.appendDummyInput()\\r\\n            .appendField(\\\"扩展插件之当条件为\\\");\\r\\n        this.appendValueInput(\\\"CONDITION\\\")\\r\\n            .setCheck(\\\"Boolean\\\");\\r\\n        this.appendDummyInput()\\r\\n            .appendField(\\\"执行\\\");\\r\\n        this.appendStatementInput(\\\"event_handler\\\")\\r\\n            .setCheck(null);\\r\\n        this.setPreviousStatement(true, null);\\r\\n        this.setNextStatement(true, null);\\r\\n        this.setColour(\\\"#d4237a\\\");\\r\\n        this.setTooltip(\\\"扩展插件之重复执行的功能。\\\");\\r\\n        this.setHelpUrl(\\\"\\\");\\r\\n    }\\r\\n};\\r\\n\\r\\npythonGenerator.forBlock['ohcode_extend_while_condition'] = function (block) {\\r\\n    const condition = pythonGenerator.valueToCode(block, 'CONDITION', pythonGenerator.ORDER_ATOMIC) || 'False';\\r\\n    let statements_event_handler = pythonGenerator.statementToCode(block, 'event_handler');\\r\\n    statements_event_handler = statements_event_handler ? statements_event_handler : \\\"\\\\tpass\\\\n\\\";\\r\\n    statements_event_handler = pythonGenerator.prefixLines(statements_event_handler, pythonGenerator.INDENT);\\r\\n\\r\\n    return `while ${condition}:\\\\n${statements_event_handler}`;\\r\\n};\\r\\n\\r\\n/**\\r\\n * 以下是有输出值的代码块示例\\r\\n */\\r\\nBlockly.Blocks['ohcode_extend_math_modulo'] = {\\r\\n    init: function () {\\r\\n        this.appendDummyInput()\\r\\n            .appendField(\\\"扩展插件之\\\");\\r\\n        this.appendValueInput(\\\"DIVIDEND\\\")\\r\\n            .setCheck(\\\"Number\\\");\\r\\n        this.appendDummyInput()\\r\\n            .appendField(\\\"÷\\\");\\r\\n        this.appendValueInput(\\\"DIVISOR\\\")\\r\\n            .setCheck(\\\"Number\\\");\\r\\n        this.appendDummyInput()\\r\\n            .appendField(\\\"的余数\\\");\\r\\n        this.setOutput(true, \\\"Number\\\");\\r\\n        this.setColour(\\\"#d4237a\\\");\\r\\n        this.setInputsInline(true);\\r\\n        this.setTooltip(\\\"扩展插件之取模运算\\\");\\r\\n    }\\r\\n};\\r\\n\\r\\npythonGenerator.forBlock['ohcode_extend_math_modulo'] = function (block) {\\r\\n    const dividend = pythonGenerator.valueToCode(block, 'DIVIDEND', pythonGenerator.ORDER_ATOMIC) || '0';\\r\\n    const divisor = pythonGenerator.valueToCode(block, 'DIVISOR', pythonGenerator.ORDER_ATOMIC) || '1';\\r\\n\\r\\n    return [`${dividend} % ${divisor}`, pythonGenerator.ORDER_ATOMIC];\\r\\n};\\r\\n\\r\\nBlockly.Blocks['ohcode_extend_logic_negate'] = {\\r\\n    init: function () {\\r\\n        this.appendDummyInput()\\r\\n            .appendField(\\\"扩展插件之非\\\")\\r\\n        this.appendValueInput(\\\"BOOL\\\")\\r\\n            .setCheck(\\\"Boolean\\\");\\r\\n        this.setOutput(true, \\\"Boolean\\\");\\r\\n        this.setInputsInline(true);\\r\\n        this.setColour(\\\"#d4237a\\\");\\r\\n        this.setTooltip(\\\"扩展插件之对布尔值取反。\\\");\\r\\n        this.setHelpUrl(\\\"\\\");\\r\\n    }\\r\\n};\\r\\n\\r\\npythonGenerator.forBlock['ohcode_extend_logic_negate'] = function (block) {\\r\\n    const bool = pythonGenerator.valueToCode(block, 'BOOL', pythonGenerator.ORDER_ATOMIC);\\r\\n    return [`(not ${bool})`, pythonGenerator.ORDER_ATOMIC];\\r\\n};\\r\\n\\r\\nBlockly.Blocks['ohcode_extend_calculator_add'] = {\\r\\n    init: function () {\\r\\n        this.appendDummyInput()\\r\\n            .appendField(\\\"扩展插件加法运算(使用外部库文件)\\\")\\r\\n        this.appendValueInput(\\\"NUM1\\\")\\r\\n            .setCheck(\\\"Number\\\");\\r\\n        this.appendDummyInput()\\r\\n            .appendField(\\\"和\\\")\\r\\n        this.appendValueInput(\\\"NUM2\\\")\\r\\n            .setCheck(\\\"Number\\\");\\r\\n        this.setOutput(true, \\\"Number\\\");\\r\\n        this.setInputsInline(true);\\r\\n        this.setColour(\\\"#d4237a\\\");\\r\\n        this.setTooltip(\\\"扩展插件加法运算(使用外部库文件)。\\\");\\r\\n        this.setHelpUrl(\\\"\\\");\\r\\n    }\\r\\n};\\r\\n\\r\\npythonGenerator.forBlock['ohcode_extend_calculator_add'] = function (block) {\\r\\n    const num1 = pythonGenerator.valueToCode(block, 'NUM1', pythonGenerator.ORDER_ATOMIC) || '0';\\r\\n    const num2 = pythonGenerator.valueToCode(block, 'NUM2', pythonGenerator.ORDER_ATOMIC) || '0';\\r\\n    pythonGenerator.definitions_[\\\"import_extend_calculator\\\"] = \\\"from extend_calculator import calculator_add\\\\n\\\"\\r\\n    return [`calculator_add(${num1}, ${num2})`, pythonGenerator.ORDER_ATOMIC];\\r\\n};\\r\\n\\r\\nBlockly.Blocks['ohcode_extend_thisblock_current_time'] = {\\r\\n    init: function () {\\r\\n        this.appendDummyInput()\\r\\n            .appendField(\\\"扩展插件之获取此块诞生格式化时间(使用外部库文件)\\\")\\r\\n        this.setOutput(true, \\\"Number\\\");\\r\\n        this.setInputsInline(true);\\r\\n        this.setColour(\\\"#d4237a\\\");\\r\\n        this.setTooltip(\\\"扩展插件之获取此块诞生格式化时间(使用外部库文件)。\\\");\\r\\n        this.setHelpUrl(\\\"\\\");\\r\\n    }\\r\\n};\\r\\n\\r\\npythonGenerator.forBlock['ohcode_extend_thisblock_current_time'] = function (block) {\\r\\n    pythonGenerator.definitions_[\\\"import_extend_format_time\\\"] = \\\"from extend_format_time import FormatDateTime\\\\n\\\"\\r\\n    pythonGenerator.definitions_[\\\"extend_format_datetime_init\\\"] = \\\"format_datetime = FormatDateTime(2024, 03, 16, 19, 10, 30)\\\\n\\\"\\r\\n    return [`format_datetime.format()`, pythonGenerator.ORDER_ATOMIC];\\r\\n};\",\"categoryiconcss\":{\"cssname\":\"ohcodeextend2dc90225b8033d17c41b08f39fa42de2Icon\",\"backgroundimage\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzA4Njk0NzMyNDU0IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjIzMDUiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTQ4MC4xMjggNzM2LjU5NzMzM0ExOTQuMzA0IDE5NC4zMDQgMCAwIDEgMjg3LjQwMjY2NyA5MzguNjY2NjY3IDIwMi4wNjkzMzMgMjAyLjA2OTMzMyAwIDAgMSA4NS4zMzMzMzMgNzM2LjU5NzMzM2ExOTMuOTIgMTkzLjkyIDAgMCAxIDIwMi4wNjkzMzQtMTkyLjI1NmgxOTIuNzI1MzMzeiBtNjQuMjU2IDBBMTkzLjgzNDY2NyAxOTMuODM0NjY3IDAgMCAwIDczNi41OTczMzMgOTM4LjY2NjY2NyAyMDIuMDY5MzMzIDIwMi4wNjkzMzMgMCAwIDAgOTM4LjY2NjY2NyA3MzYuNTk3MzMzYTE5My45MiAxOTMuOTIgMCAwIDAtMjAyLjA2OTMzNC0xOTIuMjU2aC0xOTJ2MTkyLjI1NnpNNDgwLjEyOCAyODcuNDAyNjY3QTE5NC4zMDQgMTk0LjMwNCAwIDAgMCAyODcuNDAyNjY3IDg1LjMzMzMzMyAyMDIuMDY5MzMzIDIwMi4wNjkzMzMgMCAwIDAgODUuMzMzMzMzIDI4Ny40MDI2NjdhMTk0LjQ3NDY2NyAxOTQuNDc0NjY3IDAgMCAwIDIwMi4wNjkzMzQgMTkyLjkzODY2NmgxOTIuNzI1MzMzVjI4Ny40MDI2Njd6IG02NC4yNTYgMEExOTMuODM0NjY3IDE5My44MzQ2NjcgMCAwIDEgNzM2LjU5NzMzMyA4NS4zMzMzMzMgMjAyLjA2OTMzMyAyMDIuMDY5MzMzIDAgMCAxIDkzOC42NjY2NjcgMjg3LjQwMjY2N2ExOTQuNDc0NjY3IDE5NC40NzQ2NjcgMCAwIDEtMjAyLjA2OTMzNCAxOTIuOTM4NjY2aC0xOTJWMjg3LjQwMjY2N3ogbTAgMCIgZmlsbD0iI2Q0MjM3YSIgcC1pZD0iMjMwNiI+PC9wYXRoPjwvc3ZnPg==\",\"backgroundimageselected\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzA4Njk0NzMyNDU0IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjIzMDUiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTQ4MC4xMjggNzM2LjU5NzMzM0ExOTQuMzA0IDE5NC4zMDQgMCAwIDEgMjg3LjQwMjY2NyA5MzguNjY2NjY3IDIwMi4wNjkzMzMgMjAyLjA2OTMzMyAwIDAgMSA4NS4zMzMzMzMgNzM2LjU5NzMzM2ExOTMuOTIgMTkzLjkyIDAgMCAxIDIwMi4wNjkzMzQtMTkyLjI1NmgxOTIuNzI1MzMzeiBtNjQuMjU2IDBBMTkzLjgzNDY2NyAxOTMuODM0NjY3IDAgMCAwIDczNi41OTczMzMgOTM4LjY2NjY2NyAyMDIuMDY5MzMzIDIwMi4wNjkzMzMgMCAwIDAgOTM4LjY2NjY2NyA3MzYuNTk3MzMzYTE5My45MiAxOTMuOTIgMCAwIDAtMjAyLjA2OTMzNC0xOTIuMjU2aC0xOTJ2MTkyLjI1NnpNNDgwLjEyOCAyODcuNDAyNjY3QTE5NC4zMDQgMTk0LjMwNCAwIDAgMCAyODcuNDAyNjY3IDg1LjMzMzMzMyAyMDIuMDY5MzMzIDIwMi4wNjkzMzMgMCAwIDAgODUuMzMzMzMzIDI4Ny40MDI2NjdhMTk0LjQ3NDY2NyAxOTQuNDc0NjY3IDAgMCAwIDIwMi4wNjkzMzQgMTkyLjkzODY2NmgxOTIuNzI1MzMzVjI4Ny40MDI2Njd6IG02NC4yNTYgMEExOTMuODM0NjY3IDE5My44MzQ2NjcgMCAwIDEgNzM2LjU5NzMzMyA4NS4zMzMzMzMgMjAyLjA2OTMzMyAyMDIuMDY5MzMzIDAgMCAxIDkzOC42NjY2NjcgMjg3LjQwMjY2N2ExOTQuNDc0NjY3IDE5NC40NzQ2NjcgMCAwIDEtMjAyLjA2OTMzNCAxOTIuOTM4NjY2aC0xOTJWMjg3LjQwMjY2N3ogbTAgMCIgZmlsbD0iI2ZmZmZmZiIgcC1pZD0iMjMwNiI+PC9wYXRoPjwvc3ZnPg==\"},\"library\":{\"extend_calculator.py\":\"def calculator_add(a, b):\\n    return a + b\\n\\ndef calculator_subtract(a, b):\\n    return a - b\\n\\ndef calculator_multiply(a, b):\\n    return a * b\\n\\ndef calculator_divide(a, b):\\n    return a / b\",\"extend_format_time.py\":\"class FormatDateTime():\\n    def __init__(self, year, month, day, hour=0, minute=0, second=0):\\n        self.year = year\\n        self.month = month\\n        self.day = day\\n        self.hour = hour\\n        self.minute = minute\\n        self.second = second\\n\\n    def format(self):\\n        return '{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}'.format(self.year, self.month, self.day, self.hour, self.minute, self.second)\",\"extend_motor.py\":\"class RobotBit(object):\\n    def __init__(self, address=0x40):\\n        self.i2c = I2C(0,freq=100000)\\n        self.address = address\\n        self.inited = False\\n    def initRobotBit(self):\\n        if not (0x70 in self.i2c.scan()):\\n            print(\\\"No robotbit detected\\\")\\n            return\\n        self.i2c.write(self.address, bytearray([0x00, 0x00]))\\n        self.i2c.write(self.address, bytearray([0x00, 0x00]))\\n        self.i2c.write(self.address, bytearray([0x01, 0x04]))\\n        self.i2c.write(self.address, bytearray([0x00, 0x01]))\\n        msleep(5)\\n        self.i2c.write(self.address, bytearray([0x00]))\\n        mode1 = self.i2c.read(self.address,1)[0]\\n        mode1 = mode1 & ~0x10\\n        self.i2c.write(self.address, bytearray([0x00, mode1]))\\n        msleep(5)\\n        self.set_pwm_freq(50)\\n        self.inited = True\\n    def set_pwm_freq(self, freq_hz):\\n        prescaleval = 25000000.0\\n        prescaleval /= 4096.0\\n        prescaleval /= float(freq_hz)\\n        prescaleval -= 1.0\\n        prescale = int(math.floor(prescaleval + 0.5))\\n        self.i2c.write(self.address, bytearray([0x00]))\\n        oldmode = self.i2c.read(self.address, 1)[0]\\n        newmode = (oldmode & 0x7F) | 0x10\\n        self.i2c.write(self.address, bytearray([0x00, newmode]))\\n        self.i2c.write(self.address, bytearray([0xFE, prescale]))\\n        self.i2c.write(self.address, bytearray([0x00, oldmode]))\\n        msleep(5)\\n        self.i2c.write(self.address, bytearray([0x00, oldmode | 0x80]))\\n    def set_pwm(self, channel, on, off):\\n        if not self.inited:\\n            self.initRobotBit()\\n        if on is None or off is None:\\n            data = self.i2c.mem_read(4, self.address, 0x06+4*channel)\\n            return data\\n        self.i2c.write(self.address, bytearray([0x06+4*channel, on & 0xFF]))\\n        self.i2c.write(self.address, bytearray([0x07+4*channel, on >> 8]))\\n        self.i2c.write(self.address, bytearray([0x08+4*channel, off & 0xFF]))\\n        self.i2c.write(self.address, bytearray([0x09+4*channel, off >> 8]))\\n    def pulse_width(self, index, v):\\n        value = int(v/20000*4095)\\n        self.set_pwm(index+7, 0, value)\\n    def servo(self, index, degree):\\n        value = int(degree*4096/20000)\\n        self.set_pwm(index+7, 0, value)\\n    def motorRun(self, index, speed):\\n        if index>4 or index<=0:\\n            return\\n        speed = 4095/255 *speed\\n        pp = (index-1)*2\\n        pn = (index-1)*2+1\\n        if speed >= 0:\\n            self.set_pwm(pp, 0, int(speed))\\n            self.set_pwm(pn, 0, 0)\\n        else:\\n            self.set_pwm(pp, 0, 0)\\n            self.set_pwm(pn, 0, int(-speed))\\n    def motorStopAll(self):\\n        for idx in range(1,5):\\n            self.motorRun(idx,0)\",\"extend_Sentry.py\":\"__version__ = \\\"Sentry2 v1.1.2\\\"\\n__author__ = \\\"weiyanfengv@gmail.com\\\"\\n__license__ = \\\"http://unlicense.org\\\"\\n\\nimport ustruct  # pylint: disable=import-error\\nfrom time import sleep_ms  # pylint: disable=no-name-in-module\\n\\nSENTRY_FIRMWARE_VERSION = 0xFF\\n\\nSENTRY_MAX_RESULT = 25\\n\\nSENTRY_OK = 0x00\\nSENTRY_FAIL = 0x01\\nSENTRY_WRITE_TIMEOUT = 0x02\\nSENTRY_READ_TIMEOUT = 0x03\\nSENTRY_CHECK_ERROR = 0x04\\nSENTRY_UNSUPPORT_PARAM = 0x10\\nSENTRY_UNKNOWN_PROTOCOL = 0x11\\n\\n# Protocol Error Type\\nSENTRY_PROTOC_OK = 0xE0\\nSENTRY_PROTOC_FAIL = 0xE1\\nSENTRY_PROTOC_UNKNOWN = 0xE2\\nSENTRY_PROTOC_TIMEOUT = 0xE3\\nSENTRY_PROTOC_CHECK_ERROR = 0xE4\\nSENTRY_PROTOC_LENGTH_ERROR = 0xE5\\nSENTRY_PROTOC_UNSUPPORT_COMMAND = 0xE6\\nSENTRY_PROTOC_UNSUPPORT_REG_ADDRESS = 0xE7\\nSENTRY_PROTOC_UNSUPPORT_REG_VALUE = 0xE8\\nSENTRY_PROTOC_READ_ONLY = 0xE9\\nSENTRY_PROTOC_RESTART_ERROR = 0xEA\\nSENTRY_PROTOC_RESULT_NOT_END = 0xEC\\n\\n# Protocol\\nSENTRY_PROTOC_START = 0xFF\\nSENTRY_PROTOC_END = 0xED\\nSENTRY_PROTOC_COMMADN_SET = 0x01\\nSENTRY_PROTOC_COMMADN_GET = 0x02\\nSENTRY_PROTOC_SET_PARAM = 0x21\\nSENTRY_PROTOC_GET_RESULT = 0x23\\nSENTRY_PROTOC_MESSAGE = 0x11\\n\\n# sentry_reg\\nkRegDeviceId = 0x01\\nkRegFirmwareVersion = 0x02\\nkRegRestart = 0x03\\nkRegSensorConfig1 = 0x04\\nkRegLock = 0x05\\nkRegLed = 0x06\\nkRegLedLevel = 0x08\\nkRegUart = 0x09\\nkRegUSBCongig = 0x0B\\nkRegLcdCongig = 0x0C\\nkRegHWConfig = 0x0F\\nkRegCameraConfig1 = 0x10\\nkRegCameraConfig2 = 0x11\\nkRegCameraConfig3 = 0x12\\nkRegCameraConfig4 = 0x13\\nkRegCameraConfig5 = 0x14\\nkRegFrameWidthH = 0x1B\\nkRegFrameWidthL = 0x1C\\nkRegFrameHeightH = 0x1D\\nkRegFrameHeightL = 0x1E\\nkRegFrameCount = 0x1F\\nkRegVisionId = 0x20\\nkRegVisionConfig1 = 0x21\\nkRegVisionConfig2 = 0x22\\nkRegParamNum = 0x23\\nkRegParamId = 0x24\\nkRegVisionStatus1 = 0x2A\\nkRegVisionStatus2 = 0x2B\\nkRegVisionDetect1 = 0x30\\nkRegVisionDetect2 = 0x31\\nkRegResultNumber = 0x34\\nkRegResultId = 0x35\\nkRegReadStatus1 = 0x36\\nkRegParamValue1H = 0x70\\nkRegParamValue1L = 0x71\\nkRegParamValue2H = 0x72\\nkRegParamValue2L = 0x73\\nkRegParamValue3H = 0x74\\nkRegParamValue3L = 0x75\\nkRegParamValue4H = 0x76\\nkRegParamValue4L = 0x77\\nkRegParamValue5H = 0x78\\nkRegParamValue5L = 0x79\\nkRegResultData1H = 0x80\\nkRegResultData1L = 0x81\\nkRegResultData2H = 0x82\\nkRegResultData2L = 0x83\\nkRegResultData3H = 0x84\\nkRegResultData3L = 0x85\\nkRegResultData4H = 0x86\\nkRegResultData4L = 0x87\\nkRegResultData5H = 0x88\\nkRegResultData5L = 0x89\\nkRegSn = 0xD0\\n\\n\\n# sentry_obj_info\\nclass sentry_obj_info_e:\\n    kStatus = 1\\n    kXValue = 2\\n    kYValue = 3\\n    kWidthValue = 4\\n    kHeightValue = 5\\n    kLabel = 6\\n    kRValue = 7\\n    kGValue = 8\\n    kBValue = 9\\n\\n# sentry_mode\\nclass sentry_mode_e:\\n    kSerialMode = 0x00\\n    kI2CMode = 0x01\\n    kUnknownMode = 0x02\\n\\n# sentry_led_color\\nclass sentry_led_color_e:\\n    kLedClose = 0\\n    kLedRed = 1\\n    kLedGreen = 2\\n    kLedYellow = 3\\n    kLedBlue = 4\\n    kLedPurple = 5\\n    kLedCyan = 6\\n    kLedWhite = 7\\n\\n# sentry_baudrate\\nclass sentry_baudrate_e:\\n    kBaud9600 = 0x00\\n    kBaud19200 = 0x01\\n    kBaud38400 = 0x02\\n    kBaud57600 = 0x03\\n    kBaud115200 = 0x04\\n    kBaud921600 = 0x05\\n    kBaud1152000 = 0x06\\n    kBaud2000000 = 0x07\\n\\n# sentry_camera_zoom\\nclass sentry_camera_zoom_e:\\n    kZoomDefault = 0\\n    kZoom1 = 1\\n    kZoom2 = 2\\n    kZoom3 = 3\\n    kZoom4 = 4\\n    kZoom5 = 5\\n\\n# sentry_camera_fps\\nclass sentry_camera_fps_e:\\n    kFPSNormal = 0\\n    kFPSHigh = 1\\n\\n# sentry_camera_white_balance\\nclass sentry_camera_white_balance_e:\\n    kAutoWhiteBalance = 0\\n    kLockWhiteBalance = 1\\n    kWhiteLight = 2\\n    kYellowLight = 3\\n    kWhiteBalanceCalibrating = 4\\n\\n# Sentry color label\\nclass color_label_e:\\n    kColorBlack = 1\\n    kColorWhite = 2\\n    kColorRed = 3\\n    kColorGreen = 4\\n    kColorBlue = 5\\n    kColorYellow = 6\\n\\n# Sentry1 vision\\nclass sentry1_vision_e:\\n    kVisionColor = 1\\n    kVisionBlob = 2\\n    kVisionBall = 3\\n    kVisionLine = 4\\n    kVisionCard = 6\\n    kVisionBody = 7\\n    kVisionMaxType = 8\\n\\n# Sentry1 card label\\nclass sentry1_card_label_e:\\n    kCardForward = 1\\n    kCardLeft = 2\\n    kCardRight = 3\\n    kCardTurnAround = 4\\n    kCardPark = 5\\n\\nclass sentry1_ball_label_e:\\n    kBallTableTennis = 1\\n    kBallTennis = 2\\n\\n# Sentry1 shape label\\nclass sentry1_shape_card_e:\\n    kCardCheck = 11\\n    kCardCross = 12\\n    kCardCircle = 13\\n    kCardSquare = 14\\n    kCardTriangle = 15\\n\\n# Sentry2 vision\\nclass sentry2_vision_e:\\n    kVisionColor = 1\\n    kVisionBlob = 2\\n    kVisionAprilTag = 3\\n    kVisionLine = 4\\n    kVisionLearning = 5\\n    kVisionCard = 6\\n    kVisionFace = 7\\n    kVision20Classes = 8\\n    kVisionQrCode = 9\\n    kVisionObjTrack = 10\\n    kVisionMotionDetect = 11\\n    kVisionMaxType = 12\\n\\n# Sentry card label\\nclass sentry2_card_label_e:\\n    kCardForward = 1\\n    kCardLeft = 2\\n    kCardRight = 3\\n    kCardTurnAround = 4\\n    kCardPark = 5\\n    kCardGreenLight = 6\\n    kCardRedLight = 7\\n    kCardSpeed40 = 8\\n    kCardSpeed60 = 9\\n    kCardSpeed80 = 10\\n    kCardCheck = 11\\n    kCardCross = 12\\n    kCardCircle = 13\\n    kCardSquare = 14\\n    kCardTriangle = 15\\n    kCardPlus = 16\\n    kCardMinus = 17\\n    kCardDivide = 18\\n    kCardEqual = 19\\n    kCardZero = 20\\n    kCardOne = 21\\n    kCardTwo = 22\\n    kCardThree = 23\\n    kCardFour = 24\\n    kCardFive = 25\\n    kCardSix = 26\\n    kCardSeven = 27\\n    kCardEight = 28\\n    kCardNine = 29\\n    kCardA = 31\\n    kCardB = 32\\n    kCardC = 33\\n    kCardD = 34\\n    kCardE = 35\\n    kCardF = 36\\n    kCardG = 37\\n    kCardH = 38\\n    kCardI = 39\\n    kCardJ = 40\\n    kCardK = 41\\n    kCardL = 42\\n    kCardM = 43\\n    kCardN = 44\\n    kCardO = 45\\n    kCardP = 46\\n    kCardQ = 47\\n    kCardR = 48\\n    kCardS = 49\\n    kCardT = 50\\n    kCardU = 51\\n    kCardV = 52\\n    kCardW = 53\\n    kCardX = 54\\n    kCardY = 55\\n    kCardZ = 56\\n\\n# SentryFactory 20 classes label\\nclass class20_label_e:\\n    kAirplane = 1\\n    kBicycle = 2\\n    kBird = 3\\n    kBoat = 4\\n    kBottle = 5\\n    kBus = 6\\n    kCar = 7\\n    kCat = 8\\n    kChair = 9\\n    kCow = 10\\n    kTable = 11\\n    kDog = 12\\n    kHorse = 13\\n    kMotorBike = 14\\n    kPerson = 15\\n    kPlant = 16\\n    kSheep = 17\\n    kSofa = 18\\n    kTrain = 19\\n    kMonitor = 20\\n\\n\\n\\nLOG_OFF = 60\\nLOG_CRITICAL = 50\\nLOG_ERROR = 40\\nLOG_WARNING = 30\\nLOG_INFO = 20\\nLOG_DEBUG = 10\\nLOG_NOTSET = 0\\n\\nglobal __level__\\nclass SentryLogger:\\n    global __level__\\n    __level__ = LOG_INFO\\n    _level_dict = {\\n        LOG_CRITICAL: \\\"CRIT\\\",\\n        LOG_ERROR: \\\"ERROR\\\",\\n        LOG_WARNING: \\\"WARN\\\",\\n        LOG_INFO: \\\"INFO\\\",\\n        LOG_DEBUG: \\\"DEBUG\\\",\\n    }\\n\\n    def _level_str(self, level):\\n        l = self._level_dict.get(level)\\n        if l is not None:\\n            return l\\n        return \\\"LVL%s\\\" % level\\n\\n    def setLevel(self, level):\\n        global __level__\\n        __level__ = level\\n\\n    def isEnabledFor(self, level):\\n        global __level__\\n        return level >= __level__\\n\\n    def log(self, name, level, msg, *args):\\n        if self.isEnabledFor(level):\\n            levelname = self._level_str(level)\\n            msgformat = [\\\"%s.%s:\\\" % (name, levelname)]\\n            len_arg = len(args)\\n\\n            if type(msg) == type(\\\"str\\\") and len_arg > 0:\\n                len_msg = msg.count('%')\\n                if len_msg >= len_arg and len_msg > 0:\\n                    msgformat.append(msg % args)\\n                else:\\n                    msgformat.append(msg)\\n                    msgformat += args\\n            else:\\n                msgformat.append(msg)\\n                msgformat += args\\n\\n            print(*msgformat, sep=\\\" \\\")\\n\\n\\nclass result:\\n    result_data1 = 0\\n    result_data2 = 0\\n    result_data3 = 0\\n    result_data4 = 0\\n    result_data5 = 0\\n    bytestr = \\\"\\\"\\n\\n\\nclass VisionState:\\n    def __init__(self, vision_type):\\n        self.vision_type = vision_type\\n        self.frame = 0\\n        self.detect = 0\\n        self.result = []\\n\\n        for _ in range(SENTRY_MAX_RESULT):\\n            self.result.append(result())\\n\\n\\nclass SentryI2CMethod:\\n    \\\"\\\"\\\"\\n\\n    \\\"\\\"\\\"\\n\\n    def __init__(self, address, communication_port, logger=None):\\n        self.__mu_address = address\\n        self.__communication_port = communication_port\\n        self.__logger = logger\\n\\n        if address not in communication_port.scan():\\n            raise ValueError(\\n                \\\"SentryI2CMethod Init Error!!! address %#x cannot found!\\\" % address)\\n\\n    def Logger(self, *arg):  # level, format, args\\n        if self.__logger:\\n            self.__logger(self.__class__.__name__, *arg)\\n\\n    def Set(self, reg_address, value):\\n        data = ustruct.pack(\\\"<b\\\", value)\\n        self.__communication_port.writeto_mem(\\n            self.__mu_address, reg_address, data)\\n\\n        self.Logger(LOG_DEBUG, \\\"set-> reg:%#x var:%#x\\\",\\n                    reg_address, value)\\n\\n        return SENTRY_OK\\n\\n    def Get(self, reg_address):\\n        data = ustruct.pack(\\\"<b\\\", reg_address)\\n        self.__communication_port.writeto(self.__mu_address, data)\\n\\n        value = self.__communication_port.readfrom(\\n            self.__mu_address, 1)\\n        if value:\\n            self.Logger(LOG_DEBUG, \\\"Get-> reg:%#x var:%#x\\\",\\n                        reg_address, value[0])\\n            return (SENTRY_OK, value[0])\\n        else:\\n            self.Logger(LOG_ERROR, \\\"Get-> reg:%#x TimeOut!\\\",\\n                        reg_address)\\n\\n            return (SENTRY_READ_TIMEOUT, 0)\\n\\n    def __get_result_data(self, kRegResultDataL, kRegResultDataH):\\n        err, result_data_tmp1 = self.Get(kRegResultDataL)\\n        if err:\\n            return (err, 0)\\n        err, result_data_tmp2 = self.Get(kRegResultDataH)\\n        if err:\\n            return (err, 0)\\n\\n        return (err, result_data_tmp2 << 8 | result_data_tmp1)\\n\\n    def Read(self, vision_type, vision_state):\\n        err = self.Set(kRegVisionId, vision_type)\\n        if err:\\n            return (err, vision_state)\\n\\n        err, vision_state.frame = self.Get(kRegFrameCount)\\n        if err:\\n            return (err, vision_state)\\n\\n        err, vision_state.detect = self.Get(kRegResultNumber)\\n        if err:\\n            return (err, vision_state)\\n\\n        if not vision_state.detect:\\n            return (SENTRY_OK, vision_state)\\n\\n        vision_state.detect = SENTRY_MAX_RESULT if SENTRY_MAX_RESULT < vision_state.detect else vision_state.detect\\n\\n        if sentry2_vision_e.kVisionQrCode == vision_type:\\n            vision_state.detect = 1\\n\\n        for i in range(vision_state.detect):\\n            err = self.Set(kRegResultId, i+1)\\n            if err:\\n                return (err, vision_state)\\n\\n            err, vision_state.result[i].data1 = self.__get_result_data(\\n                kRegResultData1L, kRegResultData1H)\\n            if err:\\n                return (err, vision_state)\\n            err, vision_state.result[i].data2 = self.__get_result_data(\\n                kRegResultData2L, kRegResultData2H)\\n            if err:\\n                return (err, vision_state)\\n            err, vision_state.result[i].data3 = self.__get_result_data(\\n                kRegResultData3L, kRegResultData3H)\\n            if err:\\n                return (err, vision_state)\\n            err, vision_state.result[i].data4 = self.__get_result_data(\\n                kRegResultData4L, kRegResultData4H)\\n            if err:\\n                return (err, vision_state)\\n            err, vision_state.result[i].data5 = self.__get_result_data(\\n                kRegResultData5L, kRegResultData5H)\\n            if err:\\n                return (err, vision_state)\\n\\n            if sentry2_vision_e.kVisionQrCode == vision_type:\\n                vision_state.result[i].bytestr = \\\"\\\"\\n                for j in range(vision_state.result[i].data5):\\n                    result_id = int(j / 5 + 2)\\n                    offset = j % 5\\n                    if 0 == j % 5:\\n                        err = self.Set(kRegResultId, result_id)\\n                        if err:\\n                            return err, None\\n\\n                    err, bytec = self.Get(kRegResultData1L + 2 * offset)\\n                    if err:\\n                        return err, vision_state\\n                    vision_state.result[i].bytestr += chr(bytec)\\n\\n        return (SENTRY_OK, vision_state)\\n\\n    def SetParam(self, vision_id, param, param_id):\\n        err = self.Set(kRegVisionId, vision_id)\\n        if err:\\n            return err\\n\\n        err = self.Set(kRegParamId, param_id)\\n        if err:\\n            return err\\n\\n        self.Set(kRegParamValue1H, param[0])\\n        self.Set(kRegParamValue1L, param[1])\\n        self.Set(kRegParamValue2H, param[2])\\n        self.Set(kRegParamValue2L, param[3])\\n        self.Set(kRegParamValue3H, param[4])\\n        self.Set(kRegParamValue3L, param[5])\\n        self.Set(kRegParamValue4H, param[6])\\n        self.Set(kRegParamValue4L, param[7])\\n        self.Set(kRegParamValue5H, param[8])\\n        self.Set(kRegParamValue5L, param[9])\\n\\n        return SENTRY_OK\\n\\n\\n\\nclass Sentry1(SentryBase):\\n    SENTRY1_DEVICE_ID = 0x05\\n    def __init__(self, address=0x60, log_level=LOG_ERROR):\\n        super().__init__(self.SENTRY1_DEVICE_ID,address,log_level)\\n\\nclass Sentry2(SentryBase):\\n    SENTRY2_DEVICE_ID = 0x04\\n    def __init__(self, address=0x60, log_level=LOG_ERROR):\\n        super().__init__(self.SENTRY2_DEVICE_ID,address,log_level)\"}},\"700f2347e6a6334e0d26198eead3b4f5\":{\"category\":{\"kind\":\"CATEGORY\",\"name\":\"五路巡线传感器\",\"colour\":\"#1772b4\",\"contents\":[{\"kind\":\"label\",\"text\":\"五路巡线传感器\"},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extend_linefollow\"}],\"cssConfig\":{\"icon\":\"blocklyTreeIcon ohcodeextendef724b2de021679567dfb3d19377f9dcIcon\"}},\"blocksdef\":\"var globalcolor = '#1772b4'\\n\\nBlockly.Blocks['ohcode_extend_linefollow'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"获取五路巡线通道 \\\")\\n        .appendField(new Blockly.FieldDropdown([[\\\"0\\\",\\\"0\\\"], [\\\"1\\\",\\\"1\\\"], [\\\"2\\\",\\\"2\\\"], [\\\"3\\\",\\\"3\\\"], [\\\"4\\\",\\\"4\\\"]]), \\\"line_channel\\\")\\n        .appendField(\\\" 模拟值\\\");\\n    this.setInputsInline(true);\\n    this.setOutput(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"读取五路巡线传感器指定通道的模拟值\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extend_linefollow'] = function(block) {\\n  var line_follow_channel = block.getFieldValue('line_channel');\\n  pythonGenerator.definitions_[\\\"import_I2C\\\"] = \\\"from machine import I2C\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"import_ustrucu\\\"] = \\\"import ustruct\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"I2C_init\\\"] = \\\"i2c = I2C(0,freq=400000)\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_readlineanalog\\\"] = `def read_linefollow_analog(channel,c=i2c):\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(0x50, bytes([0x02]))\\\\n${pythonGenerator.INDENT.repeat(2)}analog_num = ustruct.unpack('HHHHH', i2c.read(0x50, 10))\\\\n${pythonGenerator.INDENT.repeat(2)}return analog_num[channel]\\\\n`\\n  return [`read_linefollow_analog(${line_follow_channel})`,pythonGenerator.ORDER_ATOMIC]\\n};\\n\\n\",\"categoryiconcss\":{\"cssname\":\"ohcodeextendef724b2de021679567dfb3d19377f9dcIcon\",\"backgroundimage\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzEwNTE3MTg1MjYwIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjgzMjgiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTE5NS41IDk0My41Yy0xMC41IDAtMjAuOC01LjItMjYuOS0xNC43LTkuNi0xNC45LTUuMy0zNC43IDkuNS00NC4ybDUxOC0zMzQuMi0xNzYtMjkzLjRjLTUtOC4zLTUuOS0xOC40LTIuNi0yNy41IDMuMy05LjEgMTAuNi0xNi4yIDE5LjgtMTkuM2wzNzctMTI4YzE2LjctNS43IDM0LjkgMy4zIDQwLjYgMjAgNS43IDE2LjctMy4zIDM0LjktMjAgNDAuNkw1OTUuMyAyNTguMWwxNzEuNiAyODZjOC45IDE0LjggNC40IDM0LTEwLjEgNDMuNGwtNTQ0IDM1MWMtNS4zIDMuMy0xMS4zIDUtMTcuMyA1eiIgcC1pZD0iODMyOSIgZmlsbD0iIzE2YWM5ZSI+PC9wYXRoPjxwYXRoIGQ9Ik0xOTUuNSA5MTZsLTIzLjYtMjUuOWMtMS0xLjEtMjUuOC0yOC40LTUwLjgtNjUtMzUuNi01Mi4xLTUzLjYtOTYuNy01My42LTEzMi42IDAtMzUuOCA5LjktNjYuOCAyOC43LTg5LjggMTUuOC0xOS4zIDQ1LjgtNDIuMiA5OS4zLTQyLjIgNTMuNiAwIDgzLjUgMjIuNSA5OS4xIDQxLjMgMTguOSAyMi43IDI4LjkgNTQuMSAyOC45IDkwLjcgMCAzNS45LTE4IDgwLjUtNTMuNiAxMzIuNS0yNSAzNi42LTQ5LjcgNjMuOS01MC44IDY1bC0yMy42IDI2eiBtMC0yOTEuNWMtMTUuOCAwLTY0IDAtNjQgNjggMCAxMi44IDUuNSA0Mi40IDQyLjQgOTYuNSA3LjUgMTAuOSAxNC45IDIxIDIxLjYgMjkuNSA2LjgtOC43IDE0LjQtMTkgMjItMzAuMSAzNi41LTUzLjcgNDItODMuMSA0Mi05NS44IDAtNjEuMS0zNi41LTY4LjEtNjQtNjguMXoiIHAtaWQ9IjgzMzAiIGZpbGw9IiMxNmFjOWUiPjwvcGF0aD48L3N2Zz4=\",\"backgroundimageselected\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzEwNTE3MTg1MjYwIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjgzMjgiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTE5NS41IDk0My41Yy0xMC41IDAtMjAuOC01LjItMjYuOS0xNC43LTkuNi0xNC45LTUuMy0zNC43IDkuNS00NC4ybDUxOC0zMzQuMi0xNzYtMjkzLjRjLTUtOC4zLTUuOS0xOC40LTIuNi0yNy41IDMuMy05LjEgMTAuNi0xNi4yIDE5LjgtMTkuM2wzNzctMTI4YzE2LjctNS43IDM0LjkgMy4zIDQwLjYgMjAgNS43IDE2LjctMy4zIDM0LjktMjAgNDAuNkw1OTUuMyAyNTguMWwxNzEuNiAyODZjOC45IDE0LjggNC40IDM0LTEwLjEgNDMuNGwtNTQ0IDM1MWMtNS4zIDMuMy0xMS4zIDUtMTcuMyA1eiIgcC1pZD0iODMyOSIgZmlsbD0iI2ZmZmZmZiI+PC9wYXRoPjxwYXRoIGQ9Ik0xOTUuNSA5MTZsLTIzLjYtMjUuOWMtMS0xLjEtMjUuOC0yOC40LTUwLjgtNjUtMzUuNi01Mi4xLTUzLjYtOTYuNy01My42LTEzMi42IDAtMzUuOCA5LjktNjYuOCAyOC43LTg5LjggMTUuOC0xOS4zIDQ1LjgtNDIuMiA5OS4zLTQyLjIgNTMuNiAwIDgzLjUgMjIuNSA5OS4xIDQxLjMgMTguOSAyMi43IDI4LjkgNTQuMSAyOC45IDkwLjcgMCAzNS45LTE4IDgwLjUtNTMuNiAxMzIuNS0yNSAzNi42LTQ5LjcgNjMuOS01MC44IDY1bC0yMy42IDI2eiBtMC0yOTEuNWMtMTUuOCAwLTY0IDAtNjQgNjggMCAxMi44IDUuNSA0Mi40IDQyLjQgOTYuNSA3LjUgMTAuOSAxNC45IDIxIDIxLjYgMjkuNSA2LjgtOC43IDE0LjQtMTkgMjItMzAuMSAzNi41LTUzLjcgNDItODMuMSA0Mi05NS44IDAtNjEuMS0zNi41LTY4LjEtNjQtNjguMXoiIHAtaWQ9IjgzMzAiIGZpbGw9IiNmZmZmZmYiPjwvcGF0aD48L3N2Zz4=\"}},\"2f91336f833e2262d74c68a70414f294\":{\"category\":{\"kind\":\"CATEGORY\",\"name\":\"R1电机扩展板\",\"colour\":\"#ff9933\",\"contents\":[{\"kind\":\"label\",\"text\":\"初始化\"},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extend_r1_start\"},{\"kind\":\"label\",\"text\":\"电机\",\"gap\":\"50\"},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extend_r1_motor_re\"},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extend_r1_rmileage\"},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_r1_setsinglemotor\",\"gap\":\"40\",\"inputs\":{\"NUMBER\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":50}}}}},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_r1_setspeedtime\",\"gap\":\"40\",\"inputs\":{\"MOTOR_SPEED\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":50}}},\"TIME\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":2}}}}},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extned_r1_setpwore\",\"inputs\":{\"M1_POWER\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":50}}},\"M2_POWER\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":50}}},\"M3_POWER\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":50}}},\"M4_POWER\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":50}}}}},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extend_r1_stopmotor\"},{\"kind\":\"label\",\"text\":\"舵机\",\"gap\":\"50\"},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extend_r1_set_servo\",\"inputs\":{\"ANGLE\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":50}}}}},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extend_r1_setservomap\",\"inputs\":{\"ANGLE\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":90}}},\"MAX_ANGLE\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":180}}},\"START_MAP\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":0.5}}},\"END_MAP\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":2.5}}},\"CYCLE\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":20}}}}},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_r1_setratio\",\"gap\":\"40\",\"inputs\":{\"DUTYRATIO_RUO\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":0}}}}},{\"kind\":\"label\",\"text\":\"工具\",\"gap\":\"50\"},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_r1_control\",\"gap\":\"40\",\"inputs\":{\"INPUT_NUM\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":512}}}}},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extend_r1_readult\"}],\"cssConfig\":{\"icon\":\"blocklyTreeIcon ohcodeextend2827fcf61576ba4fbec69b190af9b755Icon\"}},\"blocksdef\":\"var globalcolor = '#ff9933'\\nBlockly.Blocks['ohcode_extend_r1_start'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"启动R1电机扩展板\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"初始化R1扩展板\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extend_r1_start'] = function(block) {\\n  pythonGenerator.definitions_[\\\"import_I2C\\\"] = \\\"from machine import I2C\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"import_ustrucu\\\"] = \\\"import ustruct\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"import_time\\\"] = \\\"import time\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"I2C_init\\\"] = \\\"i2c = I2C(0,freq=400000)\\\\n\\\";\\n  return `global i2c\\\\ni2c.write(16,bytes([255,255]))\\\\ntime.sleep(1)\\\\n`\\n};\\n\\nBlockly.Blocks['ohcode_extend_r1_motor_re'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"清空电机 \\\");\\n    this.appendDummyInput()\\n        .appendField(new Blockly.FieldDropdown([[\\\"M1\\\",\\\"0\\\"], [\\\"M2\\\",\\\"1\\\"], [\\\"M3\\\",\\\"2\\\"], [\\\"M4\\\",\\\"3\\\"]]), \\\"motor_port\\\")\\n        .appendField(\\\" 编码值\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"清空电机的编码值\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extend_r1_motor_re'] = function(block) {\\n  var dropdown_motor_port = block.getFieldValue('motor_port');\\n  pythonGenerator.definitions_[\\\"I2C_init\\\"] = \\\"i2c = I2C(0,freq=400000)\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_reset\\\"] = `def r1mem_reset_mileage(motor_id,c):\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(16,bytes([32+motor_id*4,0,0,0,0]))\\\\n${pythonGenerator.INDENT.repeat(2)}time.sleep(0.005)\\\\n`\\n \\n  return `r1mem_reset_mileage(${dropdown_motor_port},i2c)\\\\n`\\n};\\n\\nBlockly.Blocks['ohcode_extend_r1_rmileage'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"电机 \\\")\\n        .appendField(new Blockly.FieldDropdown([[\\\"M1\\\",\\\"0\\\"], [\\\"M2\\\",\\\"1\\\"], [\\\"M3\\\",\\\"2\\\"], [\\\"M4\\\",\\\"3\\\"]]), \\\"motor_port\\\")\\n        .appendField(\\\" 编码值\\\");\\n    this.setInputsInline(true);\\n    this.setOutput(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"读取接口上电机的编码值\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extend_r1_rmileage'] = function(block) {\\n  var dropdown_motort_port = block.getFieldValue('motor_port');\\n  pythonGenerator.definitions_[\\\"I2C_init\\\"] = \\\"i2c = I2C(0,freq=400000)\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_readmileage\\\"] = `def r1mem_get_mileage(port,c):\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(16,bytes([254, 32+4*port]))\\\\n${pythonGenerator.INDENT.repeat(2)}ta=c.read(16, 4)\\\\n${pythonGenerator.INDENT.repeat(2)}return ustruct.unpack('f', ta)[0]\\\\n`\\n  return [`r1mem_get_mileage(${dropdown_motort_port},i2c)`,pythonGenerator.ORDER_ATOMIC]\\n};\\n\\nBlockly.Blocks['ohcode_extend_r1_setsinglemotor'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"设置电机\\\")\\n        .appendField(new Blockly.FieldDropdown([[\\\"M1\\\",\\\"0\\\"], [\\\"M2\\\",\\\"1\\\"], [\\\"M3\\\",\\\"2\\\"], [\\\"M4\\\",\\\"3\\\"]]), \\\"MOTOR_PORT\\\");\\n    this.appendValueInput(\\\"NUMBER\\\")\\n        .setCheck(null)\\n        .appendField(\\\"功率为\\\");\\n    this.appendDummyInput()\\n        .appendField(\\\"%\\\")\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"设置单个电机的运行功率\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extend_r1_setsinglemotor'] = function(block) {\\n  var dropdown_motor_port = block.getFieldValue('MOTOR_PORT');\\n  var value_number = pythonGenerator.valueToCode(block, 'NUMBER', pythonGenerator.ORDER_ATOMIC);\\n  pythonGenerator.definitions_[\\\"I2C_init\\\"] = \\\"i2c = I2C(0,freq=400000)\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_setsinglemotor\\\"] = `\\\\ndef r1memn_set_motor_spd(motor_id, spd,c=i2c):\\\\n${pythonGenerator.INDENT.repeat(2)}sc = ustruct.pack('<f', spd)\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(16,bytes([motor_id*4])+sc)\\\\n`;\\n  return `r1memn_set_motor_spd(${dropdown_motor_port},${value_number})\\\\n`;\\n};\\n\\nBlockly.Blocks['ohcode_extend_r1_setspeedtime'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"设置电机\\\")\\n        .appendField(new Blockly.FieldDropdown([[\\\"M1\\\",\\\"0\\\"], [\\\"M2\\\",\\\"1\\\"], [\\\"M3\\\",\\\"2\\\"], [\\\"M4\\\",\\\"3\\\"]]), \\\"MOTOR_PORT\\\")\\n        .appendField(\\\"功率为\\\");\\n    this.appendValueInput(\\\"MOTOR_SPEED\\\")\\n        .setCheck(\\\"Number\\\");\\n    this.appendDummyInput()\\n        .appendField(\\\"%，运行\\\");\\n    this.appendValueInput(\\\"TIME\\\")\\n        .setCheck(\\\"Number\\\");\\n    this.appendDummyInput()\\n        .appendField(\\\"秒\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"设置编码电机运行速度和运行时间\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\npythonGenerator.forBlock['ohcode_extend_r1_setspeedtime'] = function(block) {\\n  var dropdown_motor_port = block.getFieldValue('MOTOR_PORT');\\n  var value_motor_speed = pythonGenerator.valueToCode(block, 'MOTOR_SPEED', pythonGenerator.ORDER_ATOMIC);\\n  var value_time = pythonGenerator.valueToCode(block, 'TIME', pythonGenerator.ORDER_ATOMIC);\\n  pythonGenerator.definitions_[\\\"I2C_init\\\"] = \\\"i2c = I2C(0,freq=400000)\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_setmotorspeed\\\"] = `\\\\ndef r1memn_set_motor_spd_duration(motor_id, spd, duration,c=i2c):\\\\n${pythonGenerator.INDENT.repeat(2)}mk = ustruct.pack('<f', spd)\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(16,bytes([motor_id*4]) + mk)\\\\n${pythonGenerator.INDENT.repeat(2)}time.sleep(duration)\\\\n${pythonGenerator.INDENT.repeat(2)}ck = ustruct.pack('<f', 0)\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(16,bytes([motor_id*4])+ck)\\\\n`;\\n\\n  return `r1memn_set_motor_spd_duration(${dropdown_motor_port},${value_motor_speed},${value_time},i2c)\\\\n`;\\n};\\n\\nBlockly.Blocks['ohcode_extned_r1_setpwore'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"设置电机功率，M1为\\\");\\n    this.appendValueInput(\\\"M1_POWER\\\")\\n        .setCheck(\\\"Number\\\");\\n    this.appendValueInput(\\\"M2_POWER\\\")\\n        .setCheck(\\\"Number\\\")\\n        .appendField(\\\"%，M2为\\\");\\n    this.appendValueInput(\\\"M3_POWER\\\")\\n        .setCheck(\\\"Number\\\")\\n        .appendField(\\\"%，M3为\\\");\\n    this.appendValueInput(\\\"M4_POWER\\\")\\n        .setCheck(\\\"Number\\\")\\n        .appendField(\\\"%，M4为\\\");\\n    this.appendDummyInput()\\n        .appendField(\\\"%\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"分别设置每个电机的运行速度\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extned_r1_setpwore'] = function(block) {\\n  var value_m1_power = pythonGenerator.valueToCode(block, 'M1_POWER', pythonGenerator.ORDER_ATOMIC);\\n  var value_m2_power = pythonGenerator.valueToCode(block, 'M2_POWER', pythonGenerator.ORDER_ATOMIC);\\n  var value_m3_power = pythonGenerator.valueToCode(block, 'M3_POWER', pythonGenerator.ORDER_ATOMIC);\\n  var value_m4_power = pythonGenerator.valueToCode(block, 'M4_POWER', pythonGenerator.ORDER_ATOMIC);\\n  pythonGenerator.definitions_[\\\"I2C_init\\\"] = \\\"i2c = I2C(0,freq=400000)\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_setmotorpower\\\"] = `\\\\ndef r1memn_set_power_all(spd1, spd2, spd3, spd4,c=i2c):\\\\n${pythonGenerator.INDENT.repeat(2)}sk=ustruct.pack('<4f', spd1, spd2, spd3, spd4)\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(16,bytes([0x00])+sk)\\\\n`;\\n  return `r1memn_set_power_all(${value_m1_power},${value_m2_power},${value_m3_power},${value_m4_power},i2c)\\\\n`;\\n};\\n\\nBlockly.Blocks['ohcode_extend_r1_stopmotor'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"停止\\\");\\n    this.appendDummyInput()\\n        .appendField(new Blockly.FieldDropdown([[\\\"全部\\\",\\\"9\\\"], [\\\"M1\\\",\\\"0\\\"], [\\\"M2\\\",\\\"1\\\"], [\\\"M3\\\",\\\"2\\\"], [\\\"M4\\\",\\\"3\\\"]]), \\\"MOTOR_PORT\\\")\\n        .appendField(\\\"电机运行\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"控制电机停止运转\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extend_r1_stopmotor'] = function(block) {\\n  var dropdown_motor_port = block.getFieldValue('MOTOR_PORT');\\n  pythonGenerator.definitions_[\\\"I2C_init\\\"] = \\\"i2c = I2C(0,freq=400000)\\\\n\\\";\\n  if (dropdown_motor_port === '9'){\\n\\n     pythonGenerator.definitions_[\\\"def_stopallmotor\\\"] = `\\\\ndef r1memn_set_motor_stop_all(c=i2c):\\\\n${pythonGenerator.INDENT.repeat(2)}sk=ustruct.pack('<4f', 0, 0, 0, 0)\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(16,bytes([0x00]) +sk)\\\\n`;\\n     return `r1memn_set_motor_stop_all(i2c)\\\\n`;\\n  }else{\\n     pythonGenerator.definitions_[\\\"def_stopmotor\\\"] = `\\\\ndef r1memn_set_motor_stop(motor_id,c=i2c):\\\\n${pythonGenerator.INDENT.repeat(2)}sk=ustruct.pack('<f', 0)\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(16,bytes([4*motor_id]) +sk)\\\\n`;\\n     return `r1memn_set_motor_stop(${dropdown_motor_port},i2c)\\\\n`;\\n  }\\n\\n};\\n\\nBlockly.Blocks['ohcode_extend_r1_set_servo'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"设置舵机\\\")\\n        .appendField(new Blockly.FieldDropdown([[\\\"S1\\\",\\\"0\\\"], [\\\"S2\\\",\\\"1\\\"], [\\\"S3\\\",\\\"2\\\"], [\\\"S4\\\",\\\"3\\\"]]), \\\"SERVO_PORT\\\");\\n    this.appendValueInput(\\\"ANGLE\\\")\\n        .setCheck(\\\"Number\\\")\\n        .appendField(\\\" 角度\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"设置舵机的旋转角度\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\npythonGenerator.forBlock['ohcode_extend_r1_set_servo'] = function(block) {\\n  var dropdown_servo_port = block.getFieldValue('SERVO_PORT');\\n  var value_angle = pythonGenerator.valueToCode(block, 'ANGLE', pythonGenerator.ORDER_ATOMIC);\\n  pythonGenerator.definitions_[\\\"I2C_init\\\"] = \\\"i2c = I2C(0,freq=400000)\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_setservoangle\\\"] = `\\\\ndef r1mem_set_servo(servo_id, deg, min_t=0.5,max_t=2.5, max_angle=180, t=20,c=i2c):\\\\n${pythonGenerator.INDENT.repeat(2)}duty = (min_t+(deg/max_angle)*(max_t-min_t))/t*100\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(16,bytes([16 + servo_id*4]) + ustruct.pack('<f', duty))\\\\n`;\\n  return `r1mem_set_servo(${dropdown_servo_port},${value_angle})\\\\n`;\\n};\\n\\nBlockly.Blocks['ohcode_extend_r1_setservomap'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"设置舵机\\\")\\n        .appendField(new Blockly.FieldDropdown([[\\\"S1\\\",\\\"0\\\"], [\\\"S2\\\",\\\"1\\\"], [\\\"S3\\\",\\\"2\\\"], [\\\"S4\\\",\\\"3\\\"]]), \\\"SERVO_PORT\\\");\\n    this.appendValueInput(\\\"ANGLE\\\")\\n        .setCheck(null)\\n        .appendField(\\\"角度\\\");\\n    this.appendValueInput(\\\"MAX_ANGLE\\\")\\n        .setCheck(\\\"Number\\\")\\n        .appendField(\\\"最大角度\\\");\\n    this.appendValueInput(\\\"START_MAP\\\")\\n        .setCheck(\\\"Number\\\")\\n        .appendField(\\\"起始脉冲\\\");\\n    this.appendValueInput(\\\"END_MAP\\\")\\n        .setCheck(\\\"Number\\\")\\n        .appendField(\\\"终止脉宽\\\");\\n    this.appendValueInput(\\\"CYCLE\\\")\\n        .setCheck(\\\"Number\\\")\\n        .appendField(\\\"时基周期\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(\\\"#ff9933\\\");\\n this.setTooltip(\\\"设置舵机的脉冲\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extend_r1_setservomap'] = function(block) {\\n  var dropdown_servo_port = block.getFieldValue('SERVO_PORT');\\n  var value_angle = pythonGenerator.valueToCode(block, 'ANGLE', pythonGenerator.ORDER_ATOMIC);\\n  var value_max_angle = pythonGenerator.valueToCode(block, 'MAX_ANGLE', pythonGenerator.ORDER_ATOMIC);\\n  var value_start_map = pythonGenerator.valueToCode(block, 'START_MAP', pythonGenerator.ORDER_ATOMIC);\\n  var value_end_map = pythonGenerator.valueToCode(block, 'END_MAP', pythonGenerator.ORDER_ATOMIC);\\n  var value_cycle = pythonGenerator.valueToCode(block, 'CYCLE', pythonGenerator.ORDER_ATOMIC);\\n  pythonGenerator.definitions_[\\\"I2C_init\\\"] = \\\"i2c = I2C(0,freq=400000)\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_setservomap\\\"] = `\\\\ndef r1mem_set_servo(servo_id, deg, min_t=0.5,max_t=2.5, t=20, max_angle=180,c=i2c):\\\\n${pythonGenerator.INDENT.repeat(2)}duty = (min_t+(deg/max_angle)*(max_t-min_t))/t*100\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(16,bytes([16 + servo_id*4]) + ustruct.pack('<f', duty))\\\\n`;\\n  return `r1mem_set_servo(${dropdown_servo_port},${value_angle},${value_start_map},${value_end_map},${value_max_angle},${value_cycle})\\\\n`;\\n};\\n\\nBlockly.Blocks['ohcode_extend_r1_setratio'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"设置舵机\\\")\\n        .appendField(new Blockly.FieldDropdown([[\\\"S1\\\",\\\"0\\\"], [\\\"S2\\\",\\\"1\\\"], [\\\"S3\\\",\\\"2\\\"], [\\\"S4\\\",\\\"3\\\"]]), \\\"SERVO_PORT\\\");\\n    this.appendValueInput(\\\"DUTYRATIO_RUO\\\")\\n        .setCheck(\\\"Number\\\")\\n        .appendField(\\\" 占空比\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(\\\"#ff9933\\\");\\n this.setTooltip(\\\"设置舵机的占空比\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extend_r1_setratio'] = function(block) {\\n  var dropdown_servo_port = block.getFieldValue('SERVO_PORT');\\n  var value_dutyratio = pythonGenerator.valueToCode(block, 'DUTYRATIO_RUO', pythonGenerator.ORDER_ATOMIC);\\n  pythonGenerator.definitions_[\\\"I2C_init\\\"] = \\\"i2c = I2C(0,freq=400000)\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_setservoduty\\\"] = `\\\\ndef r1mem_set_servo_duty(servo_id, duty,c=i2c):\\\\n${pythonGenerator.INDENT.repeat(2)}fh = ustruct.pack('<f', duty)\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(16,bytes([16 + servo_id*4]) +fh )\\\\n`;\\n  return `r1mem_set_servo_duty(${dropdown_servo_port},${value_dutyratio})\\\\n`;\\n};\\n\\n\\nBlockly.Blocks['ohcode_extend_r1_control'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"约束\\\");\\n    this.appendValueInput(\\\"INPUT_NUM\\\")\\n        .setCheck(\\\"Number\\\");\\n    this.appendDummyInput()\\n        .appendField(\\\" 介于(最小值)\\\")\\n        .appendField(new Blockly.FieldTextInput(\\\"0\\\"), \\\"CONTROL_MIN\\\")\\n        .appendField(\\\"和(最大值)\\\")\\n        .appendField(new Blockly.FieldTextInput(\\\"512\\\"), \\\"CONTROL_MAX\\\");\\n    this.setInputsInline(true);\\n    this.setOutput(true, \\\"Number\\\");\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"限制数值在最大值和最小值之间\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extend_r1_control'] = function(block) {\\n  var value_input_num = pythonGenerator.valueToCode(block, 'INPUT_NUM', pythonGenerator.ORDER_ATOMIC);\\n  var text_control_min = block.getFieldValue('CONTROL_MIN');\\n  var text_control_max = block.getFieldValue('CONTROL_MAX');\\n  pythonGenerator.definitions_[\\\"def_control_num\\\"] = `\\\\ndef r1memu_limit_value_range(value, min, max):\\\\n${pythonGenerator.INDENT.repeat(2)}if value < min:\\\\n${pythonGenerator.INDENT.repeat(4)}value = min\\\\n${pythonGenerator.INDENT.repeat(2)}if value > max:\\\\n${pythonGenerator.INDENT.repeat(4)}value = max\\\\n${pythonGenerator.INDENT.repeat(2)}return value\\\\n`;\\n  return [`r1memu_limit_value_range(int(${value_input_num}),int(${text_control_min}),int(${text_control_max}))`,pythonGenerator.ORDER_ATOMIC];\\n\\n};\\n\\nBlockly.Blocks['ohcode_extend_r1_readult'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"获取超声波传感器距离(厘米)\\\");\\n    this.setInputsInline(true);\\n    this.setOutput(true, \\\"Number\\\");\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"通过IIC获取超声波传感器的距离值\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extend_r1_readult'] = function(block) {\\n    pythonGenerator.definitions_[\\\"I2C_init\\\"] = \\\"i2c = I2C(0,freq=400000)\\\\n\\\";\\n    pythonGenerator.definitions_[\\\"def_readULT\\\"] = `\\\\ndef r1mem_get_sonic_value(c = i2c):\\\\n${pythonGenerator.INDENT.repeat(2)}c.write(16,bytes([254, 48]))\\\\n${pythonGenerator.INDENT.repeat(2)}a=c.read(16, 4)\\\\n${pythonGenerator.INDENT.repeat(2)}return int(ustruct.unpack('f', a)[0])\\\\n`\\n    return [`r1mem_get_sonic_value()`,pythonGenerator.ORDER_ATOMIC];\\n\\n};\",\"categoryiconcss\":{\"cssname\":\"ohcodeextend2827fcf61576ba4fbec69b190af9b755Icon\",\"backgroundimage\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzA4NDk0Mjk3MDM5IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjEyMTYzIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiPjxwYXRoIGQ9Ik04MzUuMDggNzQ2LjAxYy01LjgyIDAtMTEuNy0xLjU4LTE2Ljk5LTQuOTEtMTQuOTYtOS40LTE5LjQ4LTI5LjE1LTEwLjA3LTQ0LjEyYTMzNC42ODggMzM0LjY4OCAwIDAgMCAyNy4wNS01Mi45OWM2LjYtMTYuMzkgMjUuMjMtMjQuMzQgNDEuNjMtMTcuNzQgMTYuMzkgNi42IDI0LjM0IDI1LjI0IDE3Ljc0IDQxLjYzLTguOCAyMS44Ni0xOS42NCA0My4xLTMyLjIzIDYzLjE0LTYuMDggOS42OC0xNi40OSAxNC45OS0yNy4xMyAxNC45OXoiIGZpbGw9IiNmZjk5MzMiIHAtaWQ9IjEyMTY0Ij48L3BhdGg+PHBhdGggZD0iTTE5My45MiA3NDYuMDFjLTEwLjY0IDAtMjEuMDUtNS4zMS0yNy4xMy0xNC45OEMxMjcuMDIgNjY3LjcyIDEwNiA1OTQuNzMgMTA2IDUxOS45NWMwLTU0LjMyIDEwLjgzLTEwNy4wMiAzMi4xOS0xNTYuNjUgMjAuNjEtNDcuODggNTAuMS05MC44NyA4Ny42NS0xMjcuNzcgMzcuNTEtMzYuODYgODEuMTktNjUuOCAxMjkuODItODYuMDFDNDA2IDEyOC42MSA0NTkuNDQgMTE4IDUxNC41IDExOHMxMDguNSAxMC42MSAxNTguODMgMzEuNTJjNDguNjMgMjAuMjEgOTIuMzEgNDkuMTUgMTI5LjgyIDg2LjAxIDM3LjU1IDM2LjkgNjcuMDQgNzkuODggODcuNjUgMTI3Ljc3IDIxLjM3IDQ5LjYzIDMyLjIgMTAyLjMzIDMyLjIgMTU2LjY1IDAgNTEuMDctOS42MSAxMDAuODQtMjguNTYgMTQ3LjkzLTYuNiAxNi4zOS0yNS4yNCAyNC4zNC00MS42MyAxNy43NC0xNi40LTYuNi0yNC4zNC0yNS4yNC0xNy43NC00MS42MyAxNS44OC0zOS40NiAyMy45NC04MS4yIDIzLjk0LTEyNC4wNEM4NTkgMzMzLjYgNzA0LjQ2IDE4MiA1MTQuNSAxODJTMTcwIDMzMy42IDE3MCA1MTkuOTVjMCA2Mi43MiAxNy42MyAxMjMuOTMgNTAuOTkgMTc3LjAzIDkuNCAxNC45NyA0Ljg5IDM0LjcyLTEwLjA3IDQ0LjEyYTMxLjg5NiAzMS44OTYgMCAwIDEtMTcgNC45MXoiIGZpbGw9IiNmZjk5MzMiIHAtaWQ9IjEyMTY1Ij48L3BhdGg+PHBhdGggZD0iTTExOC44MyA4ODUuMjJhMzEuNzYgMzEuNzYgMCAwIDEtMTUuMjEtMy44N2MtMTUuNTQtOC40Mi0yMS4zMi0yNy44NC0xMi45LTQzLjM4bDc0Ljk2LTEzOC40MmM4LjQyLTE1LjU0IDI3Ljg0LTIxLjMyIDQzLjM4LTEyLjkgMTUuNTQgOC40MiAyMS4zMiAyNy44NCAxMi45IDQzLjM4TDE0NyA4NjguNDVjLTUuNzkgMTAuNy0xNi44IDE2Ljc3LTI4LjE3IDE2Ljc3ek05MDkuODUgODg1LjIyYy0xMS4zNyAwLTIyLjM3LTYuMDctMjguMTctMTYuNzdsLTc0Ljk2LTEzOC40MmMtOC40Mi0xNS41NC0yLjY0LTM0Ljk2IDEyLjktNDMuMzggMTUuNTQtOC40MiAzNC45Ni0yLjY0IDQzLjM4IDEyLjlsNzQuOTYgMTM4LjQyYzguNDIgMTUuNTQgMi42NCAzNC45Ni0xMi45IDQzLjM4YTMxLjg3NCAzMS44NzQgMCAwIDEtMTUuMjEgMy44N3oiIGZpbGw9IiNmZjk5MzMiIHAtaWQ9IjEyMTY2Ij48L3BhdGg+PHBhdGggZD0iTTkwOS41IDg4NmgtNzkxYy0xNy42NyAwLTMyLTE0LjMzLTMyLTMyczE0LjMzLTMyIDMyLTMyaDc5MWMxNy42NyAwIDMyIDE0LjMzIDMyIDMycy0xNC4zMyAzMi0zMiAzMnpNNjg5LjExIDU0NS4zYy0xLjM4IDAtMi43OC0wLjA5LTQuMTgtMC4yN2wtMTc3LjQ2LTIzLjE4Yy0xNy41Mi0yLjI5LTI5Ljg4LTE4LjM1LTI3LjU5LTM1Ljg4IDIuMjktMTcuNTIgMTguMzUtMjkuODcgMzUuODgtMjcuNTlsMTc3LjQ2IDIzLjE4YzE3LjUyIDIuMjkgMjkuODggMTguMzUgMjcuNTkgMzUuODgtMi4xMSAxNi4xMi0xNS44NyAyNy44Ni0zMS43IDI3Ljg2eiIgZmlsbD0iI2ZmOTkzMyIgcC1pZD0iMTIxNjciPjwvcGF0aD48cGF0aCBkPSJNMzg5LjI0IDY0NC43NmMtOC40NCAwLTE2Ljg2LTMuMzItMjMuMTUtOS45LTEyLjItMTIuNzgtMTEuNzQtMzMuMDQgMS4wNS00NS4yNGwxMjkuNDQtMTIzLjU5YzEyLjc5LTEyLjIxIDMzLjA0LTExLjc0IDQ1LjI0IDEuMDUgMTIuMiAxMi43OCAxMS43NCAzMy4wNC0xLjA1IDQ1LjI0TDQxMS4zMyA2MzUuOTFhMzEuOTE4IDMxLjkxOCAwIDAgMS0yMi4wOSA4Ljg1eiIgZmlsbD0iI2ZmOTkzMyIgcC1pZD0iMTIxNjgiPjwvcGF0aD48cGF0aCBkPSJNNTE5LjE5IDUyNy40NGMtMTEuNzIgMC0yMy02LjQ2LTI4LjYyLTE3LjY0bC04MC4zNi0xNTkuOTFjLTcuOTQtMTUuNzktMS41Ny0zNS4wMyAxNC4yMi00Mi45NiAxNS43OS03Ljk0IDM1LjAzLTEuNTcgNDIuOTYgMTQuMjJsODAuMzYgMTU5LjkxYzcuOTQgMTUuNzkgMS41NyAzNS4wMy0xNC4yMiA0Mi45NmEzMS44MTYgMzEuODE2IDAgMCAxLTE0LjM0IDMuNDJ6TTY4Mi43MiA2MjEuNDFjLTEgMC0yLTAuMDUtMy4wMS0wLjE0LTE3LjYtMS42NC0zMC41My0xNy4yNC0yOC44OS0zNC44M2w3LjEtNzYuMTJjMS42NC0xNy42IDE3LjI0LTMwLjUzIDM0LjgzLTI4Ljg5IDE3LjYgMS42NCAzMC41MyAxNy4yNCAyOC44OSAzNC44M2wtNy4xIDc2LjEyYy0xLjU0IDE2LjU5LTE1LjQ4IDI5LjAzLTMxLjgyIDI5LjAzek0zODguNTQgNjQ1LjQxYy04LjUzIDAtMTcuMDQtMy4zOS0yMy4zNC0xMC4xbC01Mi4zNi01NS43OGMtMTIuMDktMTIuODktMTEuNDUtMzMuMTQgMS40My00NS4yMyAxMi44OC0xMi4wOSAzMy4xNC0xMS40NSA0NS4yMyAxLjQzbDUyLjM2IDU1Ljc4YzEyLjA5IDEyLjg5IDExLjQ1IDMzLjE0LTEuNDMgNDUuMjMtNi4xNyA1LjgtMTQuMDQgOC42Ny0yMS44OSA4LjY3eiIgZmlsbD0iI2ZmOTkzMyIgcC1pZD0iMTIxNjkiPjwvcGF0aD48cGF0aCBkPSJNNDM4LjczIDM2Ny4xOWMtMTIuNDggMC0yNC4zMy03LjM0LTI5LjQ5LTE5LjU2LTYuODgtMTYuMjggMC43NS0zNS4wNSAxNy4wMy00MS45M2w3MC40OC0yOS43NmMxNi4yOC02Ljg3IDM1LjA1IDAuNzUgNDEuOTMgMTcuMDMgNi44OCAxNi4yOC0wLjc1IDM1LjA1LTE3LjAzIDQxLjkzbC03MC40OCAyOS43NmEzMi4wNjUgMzIuMDY1IDAgMCAxLTEyLjQ0IDIuNTN6IiBmaWxsPSIjZmY5OTMzIiBwLWlkPSIxMjE3MCI+PC9wYXRoPjwvc3ZnPg==\",\"backgroundimageselected\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzA4NDk0Mjk3MDM5IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjEyMTYzIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiPjxwYXRoIGQ9Ik04MzUuMDggNzQ2LjAxYy01LjgyIDAtMTEuNy0xLjU4LTE2Ljk5LTQuOTEtMTQuOTYtOS40LTE5LjQ4LTI5LjE1LTEwLjA3LTQ0LjEyYTMzNC42ODggMzM0LjY4OCAwIDAgMCAyNy4wNS01Mi45OWM2LjYtMTYuMzkgMjUuMjMtMjQuMzQgNDEuNjMtMTcuNzQgMTYuMzkgNi42IDI0LjM0IDI1LjI0IDE3Ljc0IDQxLjYzLTguOCAyMS44Ni0xOS42NCA0My4xLTMyLjIzIDYzLjE0LTYuMDggOS42OC0xNi40OSAxNC45OS0yNy4xMyAxNC45OXoiIGZpbGw9IiNmZmZmZmYiIHAtaWQ9IjEyMTY0Ij48L3BhdGg+PHBhdGggZD0iTTE5My45MiA3NDYuMDFjLTEwLjY0IDAtMjEuMDUtNS4zMS0yNy4xMy0xNC45OEMxMjcuMDIgNjY3LjcyIDEwNiA1OTQuNzMgMTA2IDUxOS45NWMwLTU0LjMyIDEwLjgzLTEwNy4wMiAzMi4xOS0xNTYuNjUgMjAuNjEtNDcuODggNTAuMS05MC44NyA4Ny42NS0xMjcuNzcgMzcuNTEtMzYuODYgODEuMTktNjUuOCAxMjkuODItODYuMDFDNDA2IDEyOC42MSA0NTkuNDQgMTE4IDUxNC41IDExOHMxMDguNSAxMC42MSAxNTguODMgMzEuNTJjNDguNjMgMjAuMjEgOTIuMzEgNDkuMTUgMTI5LjgyIDg2LjAxIDM3LjU1IDM2LjkgNjcuMDQgNzkuODggODcuNjUgMTI3Ljc3IDIxLjM3IDQ5LjYzIDMyLjIgMTAyLjMzIDMyLjIgMTU2LjY1IDAgNTEuMDctOS42MSAxMDAuODQtMjguNTYgMTQ3LjkzLTYuNiAxNi4zOS0yNS4yNCAyNC4zNC00MS42MyAxNy43NC0xNi40LTYuNi0yNC4zNC0yNS4yNC0xNy43NC00MS42MyAxNS44OC0zOS40NiAyMy45NC04MS4yIDIzLjk0LTEyNC4wNEM4NTkgMzMzLjYgNzA0LjQ2IDE4MiA1MTQuNSAxODJTMTcwIDMzMy42IDE3MCA1MTkuOTVjMCA2Mi43MiAxNy42MyAxMjMuOTMgNTAuOTkgMTc3LjAzIDkuNCAxNC45NyA0Ljg5IDM0LjcyLTEwLjA3IDQ0LjEyYTMxLjg5NiAzMS44OTYgMCAwIDEtMTcgNC45MXoiIGZpbGw9IiNmZmZmZmYiIHAtaWQ9IjEyMTY1Ij48L3BhdGg+PHBhdGggZD0iTTExOC44MyA4ODUuMjJhMzEuNzYgMzEuNzYgMCAwIDEtMTUuMjEtMy44N2MtMTUuNTQtOC40Mi0yMS4zMi0yNy44NC0xMi45LTQzLjM4bDc0Ljk2LTEzOC40MmM4LjQyLTE1LjU0IDI3Ljg0LTIxLjMyIDQzLjM4LTEyLjkgMTUuNTQgOC40MiAyMS4zMiAyNy44NCAxMi45IDQzLjM4TDE0NyA4NjguNDVjLTUuNzkgMTAuNy0xNi44IDE2Ljc3LTI4LjE3IDE2Ljc3ek05MDkuODUgODg1LjIyYy0xMS4zNyAwLTIyLjM3LTYuMDctMjguMTctMTYuNzdsLTc0Ljk2LTEzOC40MmMtOC40Mi0xNS41NC0yLjY0LTM0Ljk2IDEyLjktNDMuMzggMTUuNTQtOC40MiAzNC45Ni0yLjY0IDQzLjM4IDEyLjlsNzQuOTYgMTM4LjQyYzguNDIgMTUuNTQgMi42NCAzNC45Ni0xMi45IDQzLjM4YTMxLjg3NCAzMS44NzQgMCAwIDEtMTUuMjEgMy44N3oiIGZpbGw9IiNmZmZmZmYiIHAtaWQ9IjEyMTY2Ij48L3BhdGg+PHBhdGggZD0iTTkwOS41IDg4NmgtNzkxYy0xNy42NyAwLTMyLTE0LjMzLTMyLTMyczE0LjMzLTMyIDMyLTMyaDc5MWMxNy42NyAwIDMyIDE0LjMzIDMyIDMycy0xNC4zMyAzMi0zMiAzMnpNNjg5LjExIDU0NS4zYy0xLjM4IDAtMi43OC0wLjA5LTQuMTgtMC4yN2wtMTc3LjQ2LTIzLjE4Yy0xNy41Mi0yLjI5LTI5Ljg4LTE4LjM1LTI3LjU5LTM1Ljg4IDIuMjktMTcuNTIgMTguMzUtMjkuODcgMzUuODgtMjcuNTlsMTc3LjQ2IDIzLjE4YzE3LjUyIDIuMjkgMjkuODggMTguMzUgMjcuNTkgMzUuODgtMi4xMSAxNi4xMi0xNS44NyAyNy44Ni0zMS43IDI3Ljg2eiIgZmlsbD0iI2ZmZmZmZiIgcC1pZD0iMTIxNjciPjwvcGF0aD48cGF0aCBkPSJNMzg5LjI0IDY0NC43NmMtOC40NCAwLTE2Ljg2LTMuMzItMjMuMTUtOS45LTEyLjItMTIuNzgtMTEuNzQtMzMuMDQgMS4wNS00NS4yNGwxMjkuNDQtMTIzLjU5YzEyLjc5LTEyLjIxIDMzLjA0LTExLjc0IDQ1LjI0IDEuMDUgMTIuMiAxMi43OCAxMS43NCAzMy4wNC0xLjA1IDQ1LjI0TDQxMS4zMyA2MzUuOTFhMzEuOTE4IDMxLjkxOCAwIDAgMS0yMi4wOSA4Ljg1eiIgZmlsbD0iI2ZmZmZmZiIgcC1pZD0iMTIxNjgiPjwvcGF0aD48cGF0aCBkPSJNNTE5LjE5IDUyNy40NGMtMTEuNzIgMC0yMy02LjQ2LTI4LjYyLTE3LjY0bC04MC4zNi0xNTkuOTFjLTcuOTQtMTUuNzktMS41Ny0zNS4wMyAxNC4yMi00Mi45NiAxNS43OS03Ljk0IDM1LjAzLTEuNTcgNDIuOTYgMTQuMjJsODAuMzYgMTU5LjkxYzcuOTQgMTUuNzkgMS41NyAzNS4wMy0xNC4yMiA0Mi45NmEzMS44MTYgMzEuODE2IDAgMCAxLTE0LjM0IDMuNDJ6TTY4Mi43MiA2MjEuNDFjLTEgMC0yLTAuMDUtMy4wMS0wLjE0LTE3LjYtMS42NC0zMC41My0xNy4yNC0yOC44OS0zNC44M2w3LjEtNzYuMTJjMS42NC0xNy42IDE3LjI0LTMwLjUzIDM0LjgzLTI4Ljg5IDE3LjYgMS42NCAzMC41MyAxNy4yNCAyOC44OSAzNC44M2wtNy4xIDc2LjEyYy0xLjU0IDE2LjU5LTE1LjQ4IDI5LjAzLTMxLjgyIDI5LjAzek0zODguNTQgNjQ1LjQxYy04LjUzIDAtMTcuMDQtMy4zOS0yMy4zNC0xMC4xbC01Mi4zNi01NS43OGMtMTIuMDktMTIuODktMTEuNDUtMzMuMTQgMS40My00NS4yMyAxMi44OC0xMi4wOSAzMy4xNC0xMS40NSA0NS4yMyAxLjQzbDUyLjM2IDU1Ljc4YzEyLjA5IDEyLjg5IDExLjQ1IDMzLjE0LTEuNDMgNDUuMjMtNi4xNyA1LjgtMTQuMDQgOC42Ny0yMS44OSA4LjY3eiIgZmlsbD0iI2ZmZmZmZiIgcC1pZD0iMTIxNjkiPjwvcGF0aD48cGF0aCBkPSJNNDM4LjczIDM2Ny4xOWMtMTIuNDggMC0yNC4zMy03LjM0LTI5LjQ5LTE5LjU2LTYuODgtMTYuMjggMC43NS0zNS4wNSAxNy4wMy00MS45M2w3MC40OC0yOS43NmMxNi4yOC02Ljg3IDM1LjA1IDAuNzUgNDEuOTMgMTcuMDMgNi44OCAxNi4yOC0wLjc1IDM1LjA1LTE3LjAzIDQxLjkzbC03MC40OCAyOS43NmEzMi4wNjUgMzIuMDY1IDAgMCAxLTEyLjQ0IDIuNTN6IiBmaWxsPSIjZmZmZmZmIiBwLWlkPSIxMjE3MCI+PC9wYXRoPjwvc3ZnPg==\"}},\"aed76156d493820f7014f81c1c784d2a\":{\"category\":{\"kind\":\"CATEGORY\",\"name\":\"舵机\",\"colour\":\"#03aa74\",\"contents\":[{\"kind\":\"label\",\"text\":\"舵机\"},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extend_useful_3_servo\",\"inputs\":{\"SERVO_ANGLE\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":90}}}}}],\"cssConfig\":{\"icon\":\"blocklyTreeIcon ohcodeextend126bb89021fe9f149f2d309104deb75bIcon\"}},\"blocksdef\":\"var globalcolor = '#03aa74'\\n\\n\\n\\nBlockly.Blocks['ohcode_extend_useful_3_servo'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"设置舵机\\\");\\n    this.appendDummyInput()\\n        .appendField(new Blockly.FieldDropdown([[\\\"P1\\\",\\\"1\\\"], [\\\"P2\\\",\\\"2\\\"], [\\\"P5\\\",\\\"5\\\"], [\\\"P8\\\",\\\"8\\\"], [\\\"P13\\\",\\\"13\\\"], [\\\"P14\\\",\\\"14\\\"], [\\\"P15\\\",\\\"15\\\"]]), \\\"SERVO_PORT\\\")\\n        .appendField(\\\"角度为\\\");\\n    this.appendValueInput(\\\"SERVO_ANGLE\\\")\\n        .setCheck(\\\"Number\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"设置舵机旋转到的角度\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\n\\npythonGenerator.forBlock['ohcode_extend_useful_3_servo'] = function(block) {\\n  var dropdown_servo_port = block.getFieldValue('SERVO_PORT');\\n  var value_servo_angle = pythonGenerator.valueToCode(block, 'SERVO_ANGLE', pythonGenerator.ORDER_ATOMIC);\\n  pythonGenerator.definitions_[\\\"import_servo\\\"] = \\\"from ext_device import Servo\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"start_servo\\\"] = `def set_servo_angle(port,angle):\\\\n${pythonGenerator.INDENT.repeat(2)}servo_${dropdown_servo_port} = Servo(port)\\\\n${pythonGenerator.INDENT.repeat(2)}servo_${dropdown_servo_port}.angle(angle)\\\\n`;\\n  return `set_servo_angle(${dropdown_servo_port},${value_servo_angle})\\\\n`;\\n};\\n\\n\\n\",\"categoryiconcss\":{\"cssname\":\"ohcodeextend126bb89021fe9f149f2d309104deb75bIcon\",\"backgroundimage\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzA5NTYxNjI4MDc2IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQ0MzciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTg3Mi43NTQgMjUzLjUwN2wtMjE5LjY3MS0xOS44ODR2LTQuNzM0YzAtNTMuMDI1LTQxLjY2My05Ni41OC05My43MzgtOTkuNDJ2LTUyLjA3OGMwLTIzLjY3MS0xOC45MzgtNDIuNjA5LTQyLjYwOS00Mi42MDloLTM0LjA4NWMtMTcuOTg5IDAtMzMuMTQgMTEuMzYyLTM5Ljc2OSAyOC40MDUtMS44OTQgNS42ODItNy41NzQgOS40NjktMTMuMjU3IDkuNDY5cy0xMS4zNjItMy43ODgtMTMuMjU3LTkuNDY5Yy02LjYyNy0xNy4wNDQtMjEuNzc4LTI4LjQwNS0zOS43NjktMjguNDA1aC02OS4xMjFjLTE3Ljk4OSAwLTMzLjE0IDExLjM2Mi0zOS43NjkgMjguNDA1LTEuODk0IDUuNjgyLTcuNTc0IDkuNDY5LTEzLjI1NyA5LjQ2OXMtMTEuMzYyLTMuNzg4LTEzLjI1Ny05LjQ2OWMtNi42MjctMTcuMDQ0LTIxLjc3OC0yOC40MDUtMzkuNzY5LTI4LjQwNWgtMzQuMDg1Yy0yMy42NzEgMC00Mi42MDkgMTguOTM4LTQyLjYwOSA0Mi42MDl2NTIuMDc4Yy01Mi4wNzggMi44MzktOTMuNzM4IDQ2LjM5Ny05My43MzggOTkuNDJ2NTY3LjE3MWMwIDUzLjAyNSA0MS42NjMgOTYuNTggOTMuNzM4IDk5LjQydjUyLjA3OGMwIDIzLjY3MSAxOC45MzggNDIuNjA5IDQyLjYwOSA0Mi42MDloMzQuMDg1YzE3Ljk4OSAwIDMzLjE0LTExLjM2MiAzOS43NjktMjguNDA1IDEuODk0LTUuNjgyIDcuNTc0LTkuNDY5IDEzLjI1Ny05LjQ2OXMxMS4zNjIgMy43ODggMTMuMjU3IDkuNDY5YzYuNjI3IDE3LjA0NCAyMS43NzggMjguNDA1IDM5Ljc2OSAyOC40MDVoNjkuMTIxYzE3Ljk4OSAwIDMzLjE0LTExLjM2MiAzOS43NjktMjguNDA1IDEuODk0LTUuNjgyIDcuNTc0LTkuNDY5IDEzLjI1Ny05LjQ2OXMxMS4zNjIgMy43ODggMTMuMjU3IDkuNDY5YzYuNjI3IDE3LjA0NCAyMS43NzggMjguNDA1IDM5Ljc2OSAyOC40MDVoMzQuMDg1YzIzLjY3MSAwIDQyLjYwOS0xOC45MzggNDIuNjA5LTQyLjYwOXYtNTIuMDc4YzUyLjA3OC0yLjgzOSA5My43MzgtNDYuMzk3IDkzLjczOC05OS40MnYtMjg3Ljg0NmwyMTkuNjcxLTE5Ljg4NGM2NC4zODctMC45NDYgMTE2LjQ2NS01My4wMjUgMTE2LjQ2NS0xMTcuNDExcy01Mi4wNzgtMTE2LjQ2NS0xMTYuNDY1LTExNy40MTF6TTE3My45NyA4NC4wMThoMjUuNTY2YzkuNDY5IDIyLjcyMyAzMi4xOTMgMzcuODczIDU2LjgxMyAzNy44NzNzNDcuMzQzLTE1LjE1IDU2LjgxMy0zNy44NzNoNjAuNTk5YzkuNDY5IDIyLjcyMyAzMi4xOTMgMzcuODczIDU2LjgxMyAzNy44NzNzNDcuMzQzLTE1LjE1IDU2LjgxMy0zNy44NzNoMjQuNjE4djQ2LjM5N2gtMzM4LjAzMHYtNDYuMzk3ek01MTIgOTQxLjg3NmgtMjUuNTY2Yy05LjQ2OS0yMi43MjMtMzIuMTkzLTM3Ljg3My01Ni44MTMtMzcuODczcy00Ny4zNDMgMTUuMTUtNTYuODEzIDM3Ljg3M2gtNjAuNTk5Yy05LjQ2OS0yMi43MjMtMzIuMTkzLTM3Ljg3My01Ni44MTMtMzcuODczcy00Ny4zNDMgMTUuMTUtNTYuODEzIDM3Ljg3M2gtMjUuNTY2di00Ni4zOTdoMzM4Ljk3N3Y0Ni4zOTd6TTYwNS43MzggNzk2LjA2MGMwIDI4LjQwNS0yMy42NzEgNTIuMDc4LTUyLjA3OCA1Mi4wNzhoLTQyMS4zNTVjLTI4LjQwNSAwLTUyLjA3OC0yMy42NzEtNTIuMDc4LTUyLjA3OHYtNTY2LjIyNGMwLTI4LjQwNSAyMy42NzEtNTIuMDc4IDUyLjA3OC01Mi4wNzhoNDIxLjM1NWMyOC40MDUgMCA1Mi4wNzggMjMuNjcxIDUyLjA3OCA1Mi4wNzhsLTIzNi43MTUtMjAuODMxYy05LjQ2OS0xLjg5NC0xNy45ODktMS44OTQtMjUuNTY2LTEuODk0LTkwLjg5OCAwLTE2NC43NTUgNzMuODU0LTE2NC43NTUgMTY0Ljc1NXM3My44NTQgMTY0Ljc1NSAxNjQuNzU1IDE2NC43NTVjOC41MjIgMCAxNy4wNDQtMC45NDYgMjUuNTY2LTEuODk0bDIzNi43MTUtMjAuODMxdjI4Mi4xNjV6TTg3MS44MDkgNDQxLjkzMmwtNTA5LjQxMiA0NC41MDNjLTYuNjI3IDAuOTQ2LTEzLjI1NyAxLjg5NC0xOC45MzggMS44OTQtNjQuMzg3IDAtMTE3LjQxMS01Mi4wNzgtMTE3LjQxMS0xMTcuNDExczUyLjA3OC0xMTcuNDExIDExNy40MTEtMTE3LjQxMWM1LjY4MiAwIDEyLjMwOSAwLjk0NiAxOC45MzggMS44OTRsNTA5LjQxMiA0NS40NTFjMzguODIyIDAgNzAuMDY4IDMxLjI0NiA3MC4wNjggNzAuMDY4cy0zMi4xOTMgNzEuMDE0LTcwLjA2OCA3MS4wMTR6IiBmaWxsPSIjMDNhYTc0IiBwLWlkPSI0NDM4Ij48L3BhdGg+PHBhdGggZD0iTTM0Mi41MTIgMjgzLjgwNmMtNDguMjkxIDAtODguMDU5IDM5Ljc2OS04OC4wNTkgODguMDU5czM5Ljc2OSA4OC4wNTkgODguMDU5IDg4LjA1OSA4OC4wNTktMzkuNzY5IDg4LjA1OS04OC4wNTktMzguODIyLTg4LjA1OS04OC4wNTktODguMDU5ek0zNDIuNTEyIDQ0MC4wMzdjLTM3Ljg3MyAwLTY5LjEyMS0zMS4yNDYtNjkuMTIxLTY5LjEyMXMzMS4yNDYtNjkuMTIxIDY5LjEyMS02OS4xMjEgNjkuMTIxIDMxLjI0NiA2OS4xMjEgNjkuMTIxLTMxLjI0NiA2OS4xMjEtNjkuMTIxIDY5LjEyMXoiIGZpbGw9IiMwM2FhNzQiIHAtaWQ9IjQ0MzkiPjwvcGF0aD48L3N2Zz4=\",\"backgroundimageselected\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzA5NTYxNjI4MDc2IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQ0MzciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTg3Mi43NTQgMjUzLjUwN2wtMjE5LjY3MS0xOS44ODR2LTQuNzM0YzAtNTMuMDI1LTQxLjY2My05Ni41OC05My43MzgtOTkuNDJ2LTUyLjA3OGMwLTIzLjY3MS0xOC45MzgtNDIuNjA5LTQyLjYwOS00Mi42MDloLTM0LjA4NWMtMTcuOTg5IDAtMzMuMTQgMTEuMzYyLTM5Ljc2OSAyOC40MDUtMS44OTQgNS42ODItNy41NzQgOS40NjktMTMuMjU3IDkuNDY5cy0xMS4zNjItMy43ODgtMTMuMjU3LTkuNDY5Yy02LjYyNy0xNy4wNDQtMjEuNzc4LTI4LjQwNS0zOS43NjktMjguNDA1aC02OS4xMjFjLTE3Ljk4OSAwLTMzLjE0IDExLjM2Mi0zOS43NjkgMjguNDA1LTEuODk0IDUuNjgyLTcuNTc0IDkuNDY5LTEzLjI1NyA5LjQ2OXMtMTEuMzYyLTMuNzg4LTEzLjI1Ny05LjQ2OWMtNi42MjctMTcuMDQ0LTIxLjc3OC0yOC40MDUtMzkuNzY5LTI4LjQwNWgtMzQuMDg1Yy0yMy42NzEgMC00Mi42MDkgMTguOTM4LTQyLjYwOSA0Mi42MDl2NTIuMDc4Yy01Mi4wNzggMi44MzktOTMuNzM4IDQ2LjM5Ny05My43MzggOTkuNDJ2NTY3LjE3MWMwIDUzLjAyNSA0MS42NjMgOTYuNTggOTMuNzM4IDk5LjQydjUyLjA3OGMwIDIzLjY3MSAxOC45MzggNDIuNjA5IDQyLjYwOSA0Mi42MDloMzQuMDg1YzE3Ljk4OSAwIDMzLjE0LTExLjM2MiAzOS43NjktMjguNDA1IDEuODk0LTUuNjgyIDcuNTc0LTkuNDY5IDEzLjI1Ny05LjQ2OXMxMS4zNjIgMy43ODggMTMuMjU3IDkuNDY5YzYuNjI3IDE3LjA0NCAyMS43NzggMjguNDA1IDM5Ljc2OSAyOC40MDVoNjkuMTIxYzE3Ljk4OSAwIDMzLjE0LTExLjM2MiAzOS43NjktMjguNDA1IDEuODk0LTUuNjgyIDcuNTc0LTkuNDY5IDEzLjI1Ny05LjQ2OXMxMS4zNjIgMy43ODggMTMuMjU3IDkuNDY5YzYuNjI3IDE3LjA0NCAyMS43NzggMjguNDA1IDM5Ljc2OSAyOC40MDVoMzQuMDg1YzIzLjY3MSAwIDQyLjYwOS0xOC45MzggNDIuNjA5LTQyLjYwOXYtNTIuMDc4YzUyLjA3OC0yLjgzOSA5My43MzgtNDYuMzk3IDkzLjczOC05OS40MnYtMjg3Ljg0NmwyMTkuNjcxLTE5Ljg4NGM2NC4zODctMC45NDYgMTE2LjQ2NS01My4wMjUgMTE2LjQ2NS0xMTcuNDExcy01Mi4wNzgtMTE2LjQ2NS0xMTYuNDY1LTExNy40MTF6TTE3My45NyA4NC4wMThoMjUuNTY2YzkuNDY5IDIyLjcyMyAzMi4xOTMgMzcuODczIDU2LjgxMyAzNy44NzNzNDcuMzQzLTE1LjE1IDU2LjgxMy0zNy44NzNoNjAuNTk5YzkuNDY5IDIyLjcyMyAzMi4xOTMgMzcuODczIDU2LjgxMyAzNy44NzNzNDcuMzQzLTE1LjE1IDU2LjgxMy0zNy44NzNoMjQuNjE4djQ2LjM5N2gtMzM4LjAzMHYtNDYuMzk3ek01MTIgOTQxLjg3NmgtMjUuNTY2Yy05LjQ2OS0yMi43MjMtMzIuMTkzLTM3Ljg3My01Ni44MTMtMzcuODczcy00Ny4zNDMgMTUuMTUtNTYuODEzIDM3Ljg3M2gtNjAuNTk5Yy05LjQ2OS0yMi43MjMtMzIuMTkzLTM3Ljg3My01Ni44MTMtMzcuODczcy00Ny4zNDMgMTUuMTUtNTYuODEzIDM3Ljg3M2gtMjUuNTY2di00Ni4zOTdoMzM4Ljk3N3Y0Ni4zOTd6TTYwNS43MzggNzk2LjA2MGMwIDI4LjQwNS0yMy42NzEgNTIuMDc4LTUyLjA3OCA1Mi4wNzhoLTQyMS4zNTVjLTI4LjQwNSAwLTUyLjA3OC0yMy42NzEtNTIuMDc4LTUyLjA3OHYtNTY2LjIyNGMwLTI4LjQwNSAyMy42NzEtNTIuMDc4IDUyLjA3OC01Mi4wNzhoNDIxLjM1NWMyOC40MDUgMCA1Mi4wNzggMjMuNjcxIDUyLjA3OCA1Mi4wNzhsLTIzNi43MTUtMjAuODMxYy05LjQ2OS0xLjg5NC0xNy45ODktMS44OTQtMjUuNTY2LTEuODk0LTkwLjg5OCAwLTE2NC43NTUgNzMuODU0LTE2NC43NTUgMTY0Ljc1NXM3My44NTQgMTY0Ljc1NSAxNjQuNzU1IDE2NC43NTVjOC41MjIgMCAxNy4wNDQtMC45NDYgMjUuNTY2LTEuODk0bDIzNi43MTUtMjAuODMxdjI4Mi4xNjV6TTg3MS44MDkgNDQxLjkzMmwtNTA5LjQxMiA0NC41MDNjLTYuNjI3IDAuOTQ2LTEzLjI1NyAxLjg5NC0xOC45MzggMS44OTQtNjQuMzg3IDAtMTE3LjQxMS01Mi4wNzgtMTE3LjQxMS0xMTcuNDExczUyLjA3OC0xMTcuNDExIDExNy40MTEtMTE3LjQxMWM1LjY4MiAwIDEyLjMwOSAwLjk0NiAxOC45MzggMS44OTRsNTA5LjQxMiA0NS40NTFjMzguODIyIDAgNzAuMDY4IDMxLjI0NiA3MC4wNjggNzAuMDY4cy0zMi4xOTMgNzEuMDE0LTcwLjA2OCA3MS4wMTR6IiBmaWxsPSIjZmZmZmZmIiBwLWlkPSI0NDM4Ij48L3BhdGg+PHBhdGggZD0iTTM0Mi41MTIgMjgzLjgwNmMtNDguMjkxIDAtODguMDU5IDM5Ljc2OS04OC4wNTkgODguMDU5czM5Ljc2OSA4OC4wNTkgODguMDU5IDg4LjA1OSA4OC4wNTktMzkuNzY5IDg4LjA1OS04OC4wNTktMzguODIyLTg4LjA1OS04OC4wNTktODguMDU5ek0zNDIuNTEyIDQ0MC4wMzdjLTM3Ljg3MyAwLTY5LjEyMS0zMS4yNDYtNjkuMTIxLTY5LjEyMXMzMS4yNDYtNjkuMTIxIDY5LjEyMS02OS4xMjEgNjkuMTIxIDMxLjI0NiA2OS4xMjEgNjkuMTIxLTMxLjI0NiA2OS4xMjEtNjkuMTIxIDY5LjEyMXoiIGZpbGw9IiNmZmZmZmYiIHAtaWQ9IjQ0MzkiPjwvcGF0aD48L3N2Zz4=\"}},\"aa3528bfb00b055b47d31d0a6d9bdd8e\":{\"category\":{\"kind\":\"CATEGORY\",\"name\":\"风扇模块\",\"colour\":\"#03aa74\",\"contents\":[{\"kind\":\"label\",\"text\":\"风扇\"},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extned_useful_2_openfan\"},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extned_useful_2_closefan\"},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extend_useful_2_fan\",\"inputs\":{\"FAN\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":50}}}}}],\"cssConfig\":{\"icon\":\"blocklyTreeIcon ohcodeextend045f11d8d8a794f6832e9c8e83400ac6Icon\"}},\"blocksdef\":\"var globalcolor = '#03aa74'\\nBlockly.Blocks['ohcode_extned_useful_2_openfan'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"打开风扇\\\")\\n        .appendField(new Blockly.FieldDropdown([[\\\"P1\\\",\\\"1\\\"], [\\\"P2\\\",\\\"2\\\"], [\\\"P3\\\",\\\"5\\\"], [\\\"P8\\\",\\\"8\\\"], [\\\"P11\\\",\\\"11\\\"], [\\\"P12\\\",\\\"12\\\"], [\\\"P13\\\",\\\"13\\\"], [\\\"P14\\\",\\\"14\\\"], [\\\"P15\\\",\\\"15\\\"]]), \\\"fan_PORT\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"打开风扇\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extned_useful_2_openfan'] = function(block) {\\n  var dropdown_fan_port = block.getFieldValue('fan_PORT');\\n  pythonGenerator.definitions_[\\\"import_PIN\\\"] = \\\"from machine import Pin\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_openfan\\\"] = `def set_openPIN(port):\\\\n${pythonGenerator.INDENT.repeat(2)}pin_${dropdown_fan_port} = Pin(port,mode=Pin.OUT,pull=Pin.PULL_UP)\\\\n${pythonGenerator.INDENT.repeat(2)}pin_${dropdown_fan_port}.value(1)\\\\n`;\\n  return `set_openPIN(${dropdown_fan_port})\\\\n`;\\n\\n};\\n\\n\\nBlockly.Blocks['ohcode_extned_useful_2_closefan'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"关闭风扇\\\")\\n        .appendField(new Blockly.FieldDropdown([[\\\"P1\\\",\\\"1\\\"], [\\\"P2\\\",\\\"2\\\"], [\\\"P3\\\",\\\"5\\\"], [\\\"P8\\\",\\\"8\\\"], [\\\"P11\\\",\\\"11\\\"], [\\\"P12\\\",\\\"12\\\"], [\\\"P13\\\",\\\"13\\\"], [\\\"P14\\\",\\\"14\\\"], [\\\"P15\\\",\\\"15\\\"]]), \\\"fan_PORT\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"关闭风扇\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extned_useful_2_closefan'] = function(block) {\\n  var dropdown_fan_port = block.getFieldValue('fan_PORT');\\n  pythonGenerator.definitions_[\\\"import_PIN\\\"] = \\\"from machine import Pin\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_closefan\\\"] = `def set_closePIN(port):\\\\n${pythonGenerator.INDENT.repeat(2)}pin_${dropdown_fan_port} = Pin(port,mode=Pin.OUT,pull=Pin.PULL_UP)\\\\n${pythonGenerator.INDENT.repeat(2)}pin_${dropdown_fan_port}.value(0)\\\\n`;\\n  return `set_closePIN(${dropdown_fan_port})\\\\n`;\\n\\n};\\n\\n\\nBlockly.Blocks['ohcode_extend_useful_2_fan'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"将风扇\\\");\\n    this.appendDummyInput()\\n        .appendField(new Blockly.FieldDropdown([[\\\"P1\\\",\\\"1\\\"], [\\\"P2\\\",\\\"2\\\"], [\\\"P5\\\",\\\"5\\\"], [\\\"P8\\\",\\\"8\\\"], [\\\"P13\\\",\\\"13\\\"], [\\\"P14\\\",\\\"14\\\"], [\\\"P15\\\",\\\"15\\\"]]), \\\"fan_PORT_P\\\")\\n        .appendField(\\\"的速度设为\\\");\\n    this.appendValueInput(\\\"FAN\\\")\\n        .setCheck(\\\"Number\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"通过数值设置风扇的转速\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extend_useful_2_fan'] = function(block) {\\n  var dropdown_fan_port_p = block.getFieldValue('fan_PORT_P');\\n  var value_fan = pythonGenerator.valueToCode(block, 'FAN', pythonGenerator.ORDER_ATOMIC);\\n  pythonGenerator.definitions_[\\\"import_PWM\\\"] = \\\"from machine import PWM\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_setfan_pwm\\\"] = `def set_fan_pwm(port,num):\\\\n${pythonGenerator.INDENT.repeat(2)}pwm_${dropdown_fan_port_p} = PWM(port,freq=1000,duty=0)\\\\n${pythonGenerator.INDENT.repeat(2)}pwm_${dropdown_fan_port_p}.duty(num)\\\\n`;\\n  return `set_fan_pwm(${dropdown_fan_port_p},${value_fan})\\\\n`;\\n\\n};\\n\\n\\n\\n\\n\",\"categoryiconcss\":{\"cssname\":\"ohcodeextend045f11d8d8a794f6832e9c8e83400ac6Icon\",\"backgroundimage\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzA5NTY4NTQwNjg5IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjgxMTMiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTk0Ny4zMDMgNTE3LjkzN2MtMTYuMTYtMTguMTgtMzkuMzkxLTI5LjI4OS02My42MjktMjkuMjg5aC0yNDAuMzc3Yy02LjA2MS0zMC4yOTktMjEuMjEtNTYuNTYtNDQuNDQxLTc1Ljc0OGwxMjAuMTg5LTIwOC4wNThjMTIuMTE5LTIxLjIxIDE0LjE0MS00Ni40NiA2LjA2MS02OS42OXMtMjUuMjQ5LTQwLjM5OC00Ny40Ny00OS40OWMtNTMuNTI5LTIxLjIxLTEwOS4wNzctMzEuMzEtMTY2LjY0OS0zMS4zMXMtMTEzLjExOCAxMC4xLTE2Ni42NDkgMzEuMzFjLTIyLjIyIDkuMDkwLTM5LjM5MSAyNy4yNy00Ny40NyA0OS40OS04LjA3OSAyMy4yMy02LjA2MSA0OC40ODEgNi4wNjEgNjkuNjlsMTIwLjE4OSAyMDguMDU4Yy0yMi4yMiAxOS4xODgtMzguMzc5IDQ2LjQ2LTQ0LjQ0MSA3NS43NDhoLTIzOS4zNjdjLTI0LjIzOCAwLTQ3LjQ3IDExLjEwOS02My42MjkgMjkuMjg5LTE2LjE2IDE4LjE4LTIyLjIyIDQyLjQyLTE5LjE4OCA2Ni42NTkgOS4wOTAgNTYuNTYgMjcuMjcgMTEwLjA4NyA1Ni41NiAxNTkuNTc4IDI4LjI3OCA0OS40OSA2NS42NSA5Mi45MTcgMTEwLjA4NyAxMjguMjY5IDE1LjE0OSAxMi4xMTkgMzMuMzI5IDE4LjE4IDUxLjUxIDE4LjE4IDUuMDUwIDAgMTAuMSAwIDE1LjE0OS0xLjAwOSAyNC4yMzgtNC4wNDEgNDQuNDQxLTE5LjE4OCA1Ni41Ni00MC4zOThsMTIwLjE4OS0yMDguMDU4YzYuMDYxIDIuMDIwIDEyLjExOSA0LjA0MSAxOS4xODggNS4wNTB2Mjg5Ljg2N2MwIDE0LjE0MSAxMS4xMDkgMjUuMjQ5IDI1LjI0OSAyNS4yNDlzMjUuMjQ5LTExLjEwOSAyNS4yNDktMjUuMjQ5di0yODkuODY3YzYuMDYxLTEuMDA5IDEzLjEzLTMuMDI4IDE5LjE4OC01LjA1MGwxMjAuMTg5IDIwOC4wNThjMTIuMTE5IDIxLjIxIDMzLjMyOSAzNS4zNDkgNTYuNTYgNDAuMzk4IDUuMDUwIDEuMDA5IDEwLjEgMS4wMDkgMTUuMTQ5IDEuMDA5IDE4LjE4IDAgMzYuMzU3LTYuMDYxIDUxLjUxLTE4LjE4IDQ0LjQ0MS0zNS4zNDkgODEuODEtNzguNzc4IDExMC4wODctMTI4LjI2OSAyOC4yNzgtNDkuNDkgNDcuNDctMTA0LjAyNyA1Ni41Ni0xNTkuNTc4IDUuMDUwLTIzLjIzLTIuMDIwLTQ3LjQ3LTE4LjE4LTY2LjY1OXpNMzAzLjk0MiA4MjMuOTYxYy01LjA1MCA4LjA3OS0xMy4xMyAxNC4xNDEtMjIuMjIgMTYuMTZzLTE4LjE4LTEuMDA5LTI2LjI1OS02LjA2MWMtMzkuMzkxLTMxLjMxLTcyLjcyLTcwLjctOTcuOTY5LTExNC4xMjctMjUuMjQ5LTQ0LjQ0MS00Mi40Mi05MS45MDgtNTAuNDk5LTE0Mi40MDctMS4wMDktOS4wOTAgMS4wMDktMTguMTggNy4wNjktMjUuMjQ5czE1LjE0OS0xMS4xMDkgMjUuMjQ5LTExLjEwOWgyNDEuMzg3YzYuMDYxIDMwLjI5OSAyMS4yMSA1Ni41NiA0NC40NDEgNzUuNzQ4bC0xMjEuMTk3IDIwNy4wNDd6TTM0Ny4zNzMgMTc5LjU5MWMtNS4wNTAtOC4wNzktNi4wNjEtMTguMTgtMy4wMjgtMjcuMjcgMy4wMjgtOS4wOTAgMTAuMS0xNi4xNiAxOC4xOC0xOS4xODggNDcuNDctMTguMTggOTYuOTU4LTI4LjI3OCAxNDguNDY4LTI4LjI3OHMxMDAuOTk4IDkuMDkwIDE0OC40NjggMjguMjc4YzkuMDkwIDMuMDI4IDE1LjE0OSAxMC4xIDE4LjE4IDE5LjE4OCAzLjAyOCA5LjA5MCAyLjAyMCAxOS4xODgtMy4wMjggMjcuMjdsLTExOC4xNjcgMjA4LjA1OGMtMTQuMTQxLTUuMDUwLTI4LjI3OC03LjA2OS00NC40NDEtNy4wNjlzLTMwLjI5OSAzLjAyOC00NC40NDEgNy4wNjlsLTEyMC4xODktMjA4LjA1OHpNNTEyIDU5OC43MzVjLTQ2LjQ2IDAtODMuODI5LTM3LjM3LTgzLjgyOS04My44MjlzMzcuMzctODMuODI5IDgzLjgyOS04My44MjkgODMuODI5IDM3LjM3IDgzLjgyOSA4My44MjktMzcuMzcgODMuODI5LTgzLjgyOSA4My44Mjl6TTkxNy4wMDYgNTc2LjUxNmMtOC4wNzkgNTAuNDk5LTI0LjIzOCA5Ny45NjktNTAuNDk5IDE0Mi40MDctMjUuMjQ5IDQ0LjQ0MS01OC41NzkgODIuODE4LTk3Ljk2OSAxMTQuMTI3LTcuMDY5IDYuMDYxLTE2LjE2IDguMDc5LTI2LjI1OSA2LjA2MS05LjA5MC0yLjAyMC0xOC4xOC04LjA3OS0yMi4yMi0xNi4xNmwtMTIwLjE4OS0yMDcuMDQ3YzIyLjIyLTE5LjE4OCAzOC4zNzktNDYuNDYgNDQuNDQxLTc1Ljc0OGgyNDAuMzc3YzEwLjEgMCAxOS4xODggNC4wNDEgMjUuMjQ5IDExLjEwOSA1LjA1MCA3LjA2OSA4LjA3OSAxNi4xNiA3LjA2OSAyNS4yNDl6IiBmaWxsPSIjMDNhYTc0IiBwLWlkPSI4MTE0Ij48L3BhdGg+PC9zdmc+\",\"backgroundimageselected\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzA5NTY4NTQwNjg5IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjgxMTMiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTk0Ny4zMDMgNTE3LjkzN2MtMTYuMTYtMTguMTgtMzkuMzkxLTI5LjI4OS02My42MjktMjkuMjg5aC0yNDAuMzc3Yy02LjA2MS0zMC4yOTktMjEuMjEtNTYuNTYtNDQuNDQxLTc1Ljc0OGwxMjAuMTg5LTIwOC4wNThjMTIuMTE5LTIxLjIxIDE0LjE0MS00Ni40NiA2LjA2MS02OS42OXMtMjUuMjQ5LTQwLjM5OC00Ny40Ny00OS40OWMtNTMuNTI5LTIxLjIxLTEwOS4wNzctMzEuMzEtMTY2LjY0OS0zMS4zMXMtMTEzLjExOCAxMC4xLTE2Ni42NDkgMzEuMzFjLTIyLjIyIDkuMDkwLTM5LjM5MSAyNy4yNy00Ny40NyA0OS40OS04LjA3OSAyMy4yMy02LjA2MSA0OC40ODEgNi4wNjEgNjkuNjlsMTIwLjE4OSAyMDguMDU4Yy0yMi4yMiAxOS4xODgtMzguMzc5IDQ2LjQ2LTQ0LjQ0MSA3NS43NDhoLTIzOS4zNjdjLTI0LjIzOCAwLTQ3LjQ3IDExLjEwOS02My42MjkgMjkuMjg5LTE2LjE2IDE4LjE4LTIyLjIyIDQyLjQyLTE5LjE4OCA2Ni42NTkgOS4wOTAgNTYuNTYgMjcuMjcgMTEwLjA4NyA1Ni41NiAxNTkuNTc4IDI4LjI3OCA0OS40OSA2NS42NSA5Mi45MTcgMTEwLjA4NyAxMjguMjY5IDE1LjE0OSAxMi4xMTkgMzMuMzI5IDE4LjE4IDUxLjUxIDE4LjE4IDUuMDUwIDAgMTAuMSAwIDE1LjE0OS0xLjAwOSAyNC4yMzgtNC4wNDEgNDQuNDQxLTE5LjE4OCA1Ni41Ni00MC4zOThsMTIwLjE4OS0yMDguMDU4YzYuMDYxIDIuMDIwIDEyLjExOSA0LjA0MSAxOS4xODggNS4wNTB2Mjg5Ljg2N2MwIDE0LjE0MSAxMS4xMDkgMjUuMjQ5IDI1LjI0OSAyNS4yNDlzMjUuMjQ5LTExLjEwOSAyNS4yNDktMjUuMjQ5di0yODkuODY3YzYuMDYxLTEuMDA5IDEzLjEzLTMuMDI4IDE5LjE4OC01LjA1MGwxMjAuMTg5IDIwOC4wNThjMTIuMTE5IDIxLjIxIDMzLjMyOSAzNS4zNDkgNTYuNTYgNDAuMzk4IDUuMDUwIDEuMDA5IDEwLjEgMS4wMDkgMTUuMTQ5IDEuMDA5IDE4LjE4IDAgMzYuMzU3LTYuMDYxIDUxLjUxLTE4LjE4IDQ0LjQ0MS0zNS4zNDkgODEuODEtNzguNzc4IDExMC4wODctMTI4LjI2OSAyOC4yNzgtNDkuNDkgNDcuNDctMTA0LjAyNyA1Ni41Ni0xNTkuNTc4IDUuMDUwLTIzLjIzLTIuMDIwLTQ3LjQ3LTE4LjE4LTY2LjY1OXpNMzAzLjk0MiA4MjMuOTYxYy01LjA1MCA4LjA3OS0xMy4xMyAxNC4xNDEtMjIuMjIgMTYuMTZzLTE4LjE4LTEuMDA5LTI2LjI1OS02LjA2MWMtMzkuMzkxLTMxLjMxLTcyLjcyLTcwLjctOTcuOTY5LTExNC4xMjctMjUuMjQ5LTQ0LjQ0MS00Mi40Mi05MS45MDgtNTAuNDk5LTE0Mi40MDctMS4wMDktOS4wOTAgMS4wMDktMTguMTggNy4wNjktMjUuMjQ5czE1LjE0OS0xMS4xMDkgMjUuMjQ5LTExLjEwOWgyNDEuMzg3YzYuMDYxIDMwLjI5OSAyMS4yMSA1Ni41NiA0NC40NDEgNzUuNzQ4bC0xMjEuMTk3IDIwNy4wNDd6TTM0Ny4zNzMgMTc5LjU5MWMtNS4wNTAtOC4wNzktNi4wNjEtMTguMTgtMy4wMjgtMjcuMjcgMy4wMjgtOS4wOTAgMTAuMS0xNi4xNiAxOC4xOC0xOS4xODggNDcuNDctMTguMTggOTYuOTU4LTI4LjI3OCAxNDguNDY4LTI4LjI3OHMxMDAuOTk4IDkuMDkwIDE0OC40NjggMjguMjc4YzkuMDkwIDMuMDI4IDE1LjE0OSAxMC4xIDE4LjE4IDE5LjE4OCAzLjAyOCA5LjA5MCAyLjAyMCAxOS4xODgtMy4wMjggMjcuMjdsLTExOC4xNjcgMjA4LjA1OGMtMTQuMTQxLTUuMDUwLTI4LjI3OC03LjA2OS00NC40NDEtNy4wNjlzLTMwLjI5OSAzLjAyOC00NC40NDEgNy4wNjlsLTEyMC4xODktMjA4LjA1OHpNNTEyIDU5OC43MzVjLTQ2LjQ2IDAtODMuODI5LTM3LjM3LTgzLjgyOS04My44MjlzMzcuMzctODMuODI5IDgzLjgyOS04My44MjkgODMuODI5IDM3LjM3IDgzLjgyOSA4My44MjktMzcuMzcgODMuODI5LTgzLjgyOSA4My44Mjl6TTkxNy4wMDYgNTc2LjUxNmMtOC4wNzkgNTAuNDk5LTI0LjIzOCA5Ny45NjktNTAuNDk5IDE0Mi40MDctMjUuMjQ5IDQ0LjQ0MS01OC41NzkgODIuODE4LTk3Ljk2OSAxMTQuMTI3LTcuMDY5IDYuMDYxLTE2LjE2IDguMDc5LTI2LjI1OSA2LjA2MS05LjA5MC0yLjAyMC0xOC4xOC04LjA3OS0yMi4yMi0xNi4xNmwtMTIwLjE4OS0yMDcuMDQ3YzIyLjIyLTE5LjE4OCAzOC4zNzktNDYuNDYgNDQuNDQxLTc1Ljc0OGgyNDAuMzc3YzEwLjEgMCAxOS4xODggNC4wNDEgMjUuMjQ5IDExLjEwOSA1LjA1MCA3LjA2OSA4LjA3OSAxNi4xNiA3LjA2OSAyNS4yNDl6IiBmaWxsPSIjZmZmZmZmIiBwLWlkPSI4MTE0Ij48L3BhdGg+PC9zdmc+\"}},\"a969e1e2e26f6af529ff7f9d254ea2cb\":{\"category\":{\"kind\":\"CATEGORY\",\"name\":\"LED灯\",\"colour\":\"#DC143C\",\"contents\":[{\"kind\":\"label\",\"text\":\"LED灯设置\"},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extned_useful_2_openled\"},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extned_useful_2_closeled\"},{\"kind\":\"BLOCK\",\"gap\":\"40\",\"type\":\"ohcode_extend_useful_2_pwm\",\"inputs\":{\"LIGHT\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":50}}}}}],\"cssConfig\":{\"icon\":\"blocklyTreeIcon ohcodeextend5bdede9d101454ec9d5e86358fef54d1Icon\"}},\"blocksdef\":\"var globalcolor = '#DC143C'\\nBlockly.Blocks['ohcode_extned_useful_2_openled'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"打开灯\\\")\\n        .appendField(new Blockly.FieldDropdown([[\\\"P1\\\",\\\"1\\\"], [\\\"P2\\\",\\\"2\\\"], [\\\"P3\\\",\\\"5\\\"], [\\\"P8\\\",\\\"8\\\"], [\\\"P11\\\",\\\"11\\\"], [\\\"P12\\\",\\\"12\\\"], [\\\"P13\\\",\\\"13\\\"], [\\\"P14\\\",\\\"14\\\"], [\\\"P15\\\",\\\"15\\\"]]), \\\"LED_PORT\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"点亮LED灯\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extned_useful_2_openled'] = function(block) {\\n  var dropdown_led_port = block.getFieldValue('LED_PORT');\\n  pythonGenerator.definitions_[\\\"import_PIN\\\"] = \\\"from machine import Pin\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_openled\\\"] = `def set_openPIN(port):\\\\n${pythonGenerator.INDENT.repeat(2)}pin_${dropdown_led_port} = Pin(port,mode=Pin.OUT,pull=Pin.PULL_UP)\\\\n${pythonGenerator.INDENT.repeat(2)}pin_${dropdown_led_port}.value(1)\\\\n`;\\n  return `set_openPIN(${dropdown_led_port})\\\\n`;\\n\\n};\\n\\n\\nBlockly.Blocks['ohcode_extned_useful_2_closeled'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"关闭灯\\\")\\n        .appendField(new Blockly.FieldDropdown([[\\\"P1\\\",\\\"1\\\"], [\\\"P2\\\",\\\"2\\\"], [\\\"P3\\\",\\\"5\\\"], [\\\"P8\\\",\\\"8\\\"], [\\\"P11\\\",\\\"11\\\"], [\\\"P12\\\",\\\"12\\\"], [\\\"P13\\\",\\\"13\\\"], [\\\"P14\\\",\\\"14\\\"], [\\\"P15\\\",\\\"15\\\"]]), \\\"LED_PORT\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"关闭LED灯\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extned_useful_2_closeled'] = function(block) {\\n  var dropdown_led_port = block.getFieldValue('LED_PORT');\\n  pythonGenerator.definitions_[\\\"import_PIN\\\"] = \\\"from machine import Pin\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_closeled\\\"] = `def set_closePIN(port):\\\\n${pythonGenerator.INDENT.repeat(2)}pin_${dropdown_led_port} = Pin(port,mode=Pin.OUT,pull=Pin.PULL_UP)\\\\n${pythonGenerator.INDENT.repeat(2)}pin_${dropdown_led_port}.value(0)\\\\n`;\\n  return `set_closePIN(${dropdown_led_port})\\\\n`;\\n\\n};\\n\\n\\nBlockly.Blocks['ohcode_extend_useful_2_pwm'] = {\\n  init: function() {\\n    this.appendDummyInput()\\n        .appendField(\\\"设置灯\\\");\\n    this.appendDummyInput()\\n        .appendField(new Blockly.FieldDropdown([[\\\"P1\\\",\\\"1\\\"], [\\\"P2\\\",\\\"2\\\"], [\\\"P5\\\",\\\"5\\\"], [\\\"P8\\\",\\\"8\\\"], [\\\"P13\\\",\\\"13\\\"], [\\\"P14\\\",\\\"14\\\"], [\\\"P15\\\",\\\"15\\\"]]), \\\"LED_PORT_P\\\")\\n        .appendField(\\\"的亮度\\\");\\n    this.appendValueInput(\\\"LIGHT\\\")\\n        .setCheck(\\\"Number\\\");\\n    this.setInputsInline(true);\\n    this.setPreviousStatement(true, null);\\n    this.setNextStatement(true, null);\\n    this.setColour(globalcolor);\\n this.setTooltip(\\\"通过数值设置led灯的亮度\\\");\\n this.setHelpUrl(\\\"\\\");\\n  }\\n};\\n\\npythonGenerator.forBlock['ohcode_extend_useful_2_pwm'] = function(block) {\\n  var dropdown_led_port_p = block.getFieldValue('LED_PORT_P');\\n  var value_light = pythonGenerator.valueToCode(block, 'LIGHT', pythonGenerator.ORDER_ATOMIC);\\n  pythonGenerator.definitions_[\\\"import_PWM\\\"] = \\\"from machine import PWM\\\\n\\\";\\n  pythonGenerator.definitions_[\\\"def_setled_pwm\\\"] = `def set_led_pwm(port,num):\\\\n${pythonGenerator.INDENT.repeat(2)}pwm_${dropdown_led_port_p} = PWM(port,freq=1000,duty=0)\\\\n${pythonGenerator.INDENT.repeat(2)}pwm_${dropdown_led_port_p}.duty(num)\\\\n`;\\n  return `set_led_pwm(${dropdown_led_port_p},${value_light})\\\\n`;\\n\\n};\\n\\n\\n\\n\\n\",\"categoryiconcss\":{\"cssname\":\"ohcodeextend5bdede9d101454ec9d5e86358fef54d1Icon\",\"backgroundimage\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzA5NTY3MjUwMzg5IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjY3MjgiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTUxMiAwaC0wLjdDMjk4LjcgMC40IDEyNi4yIDE3NC44IDEyOCAzODcuNGMxIDExMi4xIDUwIDIxMi44IDEyNy41IDI4Mi40IDUxIDQ1LjggODAuNSAxMTAuOCA4MC41IDE3OS4zdjU3YzAgNjUuMSA1Mi44IDExNy45IDExNy45IDExNy45aDExNi4yYzY1LjEgMCAxMTcuOS01Mi44IDExNy45LTExNy45di01N2MwLTY4LjYgMjkuNi0xMzMuNiA4MC42LTE3OS41Qzg0Ni44IDU5OS4zIDg5NiA0OTcuNCA4OTYgMzg0IDg5NiAxNzEuOSA3MjQuMSAwIDUxMiAweiBtMjEzLjkgNjIyQzY2MS4xIDY4MC4zIDYyNCA3NjMgNjI0IDg0OS4xVjg5NmMwIDM1LjMtMjguNyA2NC02NCA2NGgtOTZjLTM1LjMgMC02NC0yOC43LTY0LTY0di00Ni45YzAtODYuMS0zNy4xLTE2OC45LTEwMS43LTIyNy0zMi44LTI5LjQtNTguNy02NC42LTc3LjEtMTA0LjQtMTktNDEuMi0yOC44LTg1LjItMjkuMi0xMzAuOS0wLjQtNDMuMyA3LjgtODUuNCAyNC4zLTEyNS4xIDE2LTM4LjQgMzktNzIuOSA2OC40LTEwMi43IDI5LjQtMjkuNyA2My43LTUzLjEgMTAxLjktNjkuNSAzOS41LTE2LjkgODEuNS0yNS41IDEyNC44LTI1LjZoMC42YzQzLjIgMCA4NS4xIDguNSAxMjQuNSAyNS4xIDM4LjEgMTYuMSA3Mi4zIDM5LjIgMTAxLjcgNjguNiAyOS40IDI5LjQgNTIuNSA2My42IDY4LjYgMTAxLjdDODIzLjYgMjk4LjkgODMyIDM0MC44IDgzMiAzODRjMCA0Ni4yLTkuNiA5MC44LTI4LjYgMTMyLjVDNzg1IDU1Ni44IDc1OSA1OTIuMyA3MjUuOSA2MjJ6IiBwLWlkPSI2NzI5IiBmaWxsPSIjREMxNDNDIj48L3BhdGg+PHBhdGggZD0iTTUxNi43IDYyNGwxOS40LTE3My4zSDQ2MEw2MjcuMyAyMDhsLTE5LjQgMTczLjNINjg0TDUxNi43IDYyNHpNNTc2IDkxMkg0NDhjLTQuNCAwLTguNC0xLjgtMTEuMy00LjctMi45LTIuOS00LjctNi45LTQuNy0xMS4zIDAtOC44IDcuMi0xNiAxNi0xNmgxMjhjNC40IDAgOC40IDEuOCAxMS4zIDQuNyAyLjkgMi45IDQuNyA2LjkgNC43IDExLjMgMCA4LjgtNy4yIDE2LTE2IDE2eiBtMC02NEg0NDhjLTQuNCAwLTguNC0xLjgtMTEuMy00LjctMi45LTIuOS00LjctNi45LTQuNy0xMS4zIDAtOC44IDcuMi0xNiAxNi0xNmgxMjhjNC40IDAgOC40IDEuOCAxMS4zIDQuNyAyLjkgMi45IDQuNyA2LjkgNC43IDExLjMgMCA4LjgtNy4yIDE2LTE2IDE2eiBtMTYtNjRINDMyYy00LjQgMC04LjQtMS44LTExLjMtNC43LTIuOS0yLjktNC43LTYuOS00LjctMTEuMyAwLTguOCA3LjItMTYgMTYtMTZoMTYwYzQuNCAwIDguNCAxLjggMTEuMyA0LjcgMi45IDIuOSA0LjcgNi45IDQuNyAxMS4zIDAgOC44LTcuMiAxNi0xNiAxNnoiIHAtaWQ9IjY3MzAiIGZpbGw9IiNEQzE0M0MiPjwvcGF0aD48L3N2Zz4=\",\"backgroundimageselected\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzA5NTY3MjUwMzg5IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjY3MjgiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTUxMiAwaC0wLjdDMjk4LjcgMC40IDEyNi4yIDE3NC44IDEyOCAzODcuNGMxIDExMi4xIDUwIDIxMi44IDEyNy41IDI4Mi40IDUxIDQ1LjggODAuNSAxMTAuOCA4MC41IDE3OS4zdjU3YzAgNjUuMSA1Mi44IDExNy45IDExNy45IDExNy45aDExNi4yYzY1LjEgMCAxMTcuOS01Mi44IDExNy45LTExNy45di01N2MwLTY4LjYgMjkuNi0xMzMuNiA4MC42LTE3OS41Qzg0Ni44IDU5OS4zIDg5NiA0OTcuNCA4OTYgMzg0IDg5NiAxNzEuOSA3MjQuMSAwIDUxMiAweiBtMjEzLjkgNjIyQzY2MS4xIDY4MC4zIDYyNCA3NjMgNjI0IDg0OS4xVjg5NmMwIDM1LjMtMjguNyA2NC02NCA2NGgtOTZjLTM1LjMgMC02NC0yOC43LTY0LTY0di00Ni45YzAtODYuMS0zNy4xLTE2OC45LTEwMS43LTIyNy0zMi44LTI5LjQtNTguNy02NC42LTc3LjEtMTA0LjQtMTktNDEuMi0yOC44LTg1LjItMjkuMi0xMzAuOS0wLjQtNDMuMyA3LjgtODUuNCAyNC4zLTEyNS4xIDE2LTM4LjQgMzktNzIuOSA2OC40LTEwMi43IDI5LjQtMjkuNyA2My43LTUzLjEgMTAxLjktNjkuNSAzOS41LTE2LjkgODEuNS0yNS41IDEyNC44LTI1LjZoMC42YzQzLjIgMCA4NS4xIDguNSAxMjQuNSAyNS4xIDM4LjEgMTYuMSA3Mi4zIDM5LjIgMTAxLjcgNjguNiAyOS40IDI5LjQgNTIuNSA2My42IDY4LjYgMTAxLjdDODIzLjYgMjk4LjkgODMyIDM0MC44IDgzMiAzODRjMCA0Ni4yLTkuNiA5MC44LTI4LjYgMTMyLjVDNzg1IDU1Ni44IDc1OSA1OTIuMyA3MjUuOSA2MjJ6IiBwLWlkPSI2NzI5IiBmaWxsPSIjZmZmZmZmIj48L3BhdGg+PHBhdGggZD0iTTUxNi43IDYyNGwxOS40LTE3My4zSDQ2MEw2MjcuMyAyMDhsLTE5LjQgMTczLjNINjg0TDUxNi43IDYyNHpNNTc2IDkxMkg0NDhjLTQuNCAwLTguNC0xLjgtMTEuMy00LjctMi45LTIuOS00LjctNi45LTQuNy0xMS4zIDAtOC44IDcuMi0xNiAxNi0xNmgxMjhjNC40IDAgOC40IDEuOCAxMS4zIDQuNyAyLjkgMi45IDQuNyA2LjkgNC43IDExLjMgMCA4LjgtNy4yIDE2LTE2IDE2eiBtMC02NEg0NDhjLTQuNCAwLTguNC0xLjgtMTEuMy00LjctMi45LTIuOS00LjctNi45LTQuNy0xMS4zIDAtOC44IDcuMi0xNiAxNi0xNmgxMjhjNC40IDAgOC40IDEuOCAxMS4zIDQuNyAyLjkgMi45IDQuNyA2LjkgNC43IDExLjMgMCA4LjgtNy4yIDE2LTE2IDE2eiBtMTYtNjRINDMyYy00LjQgMC04LjQtMS44LTExLjMtNC43LTIuOS0yLjktNC43LTYuOS00LjctMTEuMyAwLTguOCA3LjItMTYgMTYtMTZoMTYwYzQuNCAwIDguNCAxLjggMTEuMyA0LjcgMi45IDIuOSA0LjcgNi45IDQuNyAxMS4zIDAgOC44LTcuMiAxNi0xNiAxNnoiIHAtaWQ9IjY3MzAiIGZpbGw9IiNmZmZmZmYiPjwvcGF0aD48L3N2Zz4=\"}},\"2e209558aa006696e1bbadf32a2ed4a2\":{\"category\":{\"kind\":\"CATEGORY\",\"name\":\"TM1637四位数码管\",\"colour\":\"#e15f76\",\"contents\":[{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_tm1637_digit_led\"},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_tm1637_show\",\"inputs\":{\"CONTEND\":{\"shadow\":{\"type\":\"text\",\"fields\":{\"TEXT\":\"1234\"}}}}},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_tm1637_point_show\"},{\"kind\":\"BLOCK\",\"type\":\"ohcode_extend_tm1637_clear_show\"}],\"cssConfig\":{\"icon\":\"blocklyTreeIcon ohcodeextend6afdf4312fd76e229b2d400068fa76ccIcon\"}},\"blocksdef\":\"var global_color = \\\"#e15f76\\\"\\r\\n\\r\\nBlockly.Blocks['ohcode_extend_tm1637_digit_led'] = {\\r\\n  init: function() {\\r\\n    this.appendDummyInput()\\r\\n        .appendField(\\\"初始化TM1637四位数码管 ｜CLK \\\")\\r\\n        .appendField(new Blockly.FieldDropdown([[\\\"P1\\\",\\\"1\\\"], [\\\"P2\\\",\\\"2\\\"], [\\\"P5\\\",\\\"5\\\"], [\\\"P8\\\",\\\"8\\\"], [\\\"P11\\\",\\\"11\\\"], [\\\"P12\\\",\\\"12\\\"], [\\\"P13\\\",\\\"13\\\"], [\\\"P14\\\",\\\"14\\\"], [\\\"P15\\\",\\\"15\\\"]]), \\\"C_PIN\\\")\\r\\n        .appendField(\\\"DIO\\\")\\r\\n        .appendField(new Blockly.FieldDropdown([[\\\"P1\\\",\\\"1\\\"], [\\\"P2\\\",\\\"2\\\"], [\\\"P5\\\",\\\"5\\\"], [\\\"P8\\\",\\\"8\\\"], [\\\"P11\\\",\\\"11\\\"], [\\\"P12\\\",\\\"12\\\"], [\\\"P13\\\",\\\"13\\\"], [\\\"P14\\\",\\\"14\\\"], [\\\"P15\\\",\\\"15\\\"]]), \\\"D_PIN\\\");\\r\\n    this.setInputsInline(true);\\r\\n    this.setPreviousStatement(true, null);\\r\\n    this.setNextStatement(true, null);\\r\\n    this.setColour(global_color);\\r\\n this.setTooltip(\\\"初始化TM1637数码管的端口\\\");\\r\\n  }\\r\\n};\\r\\n\\r\\npythonGenerator.forBlock['ohcode_extend_tm1637_digit_led'] = function(block, ) {\\r\\n  var dropdown_c_pin = block.getFieldValue('C_PIN');\\r\\n  var dropdown_d_pin = block.getFieldValue('D_PIN');\\r\\n  pythonGenerator.definitions_[\\\"import_EXTEND_TM1637\\\"] = \\\"from TM1637 import *\\\\n\\\";\\r\\n  pythonGenerator.definitions_[\\\"TM1637_INIT\\\"] = `_tm1637 = TM1637(Pin(int(${dropdown_c_pin})), Pin(int(${dropdown_d_pin})))\\\\n`;\\r\\n  pythonGenerator.definitions_[\\\"GLOBAL_TM1637_NUM\\\"] = \\\"global TM1637_NUM\\\\nTM1637_NUM = '    '\\\\n\\\";\\r\\n  return \\\"\\\";\\r\\n};\\r\\n\\r\\n\\r\\nBlockly.Blocks['ohcode_extend_tm1637_show'] = {\\r\\n  init: function() {\\r\\n    this.appendDummyInput()\\r\\n        .appendField(\\\"TM1637四位数码管 ｜ 显示\\\");\\r\\n    this.appendValueInput(\\\"CONTEND\\\")\\r\\n        .setCheck(null);\\r\\n    this.setInputsInline(true);\\r\\n    this.setPreviousStatement(true, null);\\r\\n    this.setNextStatement(true, null);\\r\\n    this.setColour(global_color);\\r\\n this.setTooltip(\\\"显示四位以内的文字内容\\\");\\r\\n this.setHelpUrl(\\\"\\\");\\r\\n  }\\r\\n};\\r\\n\\r\\npythonGenerator.forBlock['ohcode_extend_tm1637_show'] = function(block) {\\r\\n  var value_contend = pythonGenerator.valueToCode(block, 'CONTEND', pythonGenerator.ORDER_ATOMIC);\\r\\n\\r\\n  return `TM1637_NUM = ${value_contend}\\\\n_tm1637.show(TM1637_NUM)\\\\n`;\\r\\n};\\r\\n\\r\\nBlockly.Blocks['ohcode_extend_tm1637_point_show'] = {\\r\\n  init: function() {\\r\\n    this.appendDummyInput()\\r\\n        .appendField(\\\"TM1637四位数码管 ｜ 冒号\\\")\\r\\n        .appendField(new Blockly.FieldDropdown([[\\\"灭\\\",\\\"0\\\"], [\\\"亮\\\",\\\"1\\\"]]), \\\"STATE\\\");\\r\\n    this.setInputsInline(true);\\r\\n    this.setPreviousStatement(true, null);\\r\\n    this.setNextStatement(true, null);\\r\\n    this.setColour(global_color);\\r\\n this.setTooltip(\\\"控制TM1637数码管冒号的亮灭\\\");\\r\\n this.setHelpUrl(\\\"\\\");\\r\\n  }\\r\\n};\\r\\n\\r\\npythonGenerator.forBlock['ohcode_extend_tm1637_point_show'] = function(block) {\\r\\n  var dropdown_state = block.getFieldValue('STATE');\\r\\n  return `_tm1637.encode_point_string(str(${dropdown_state}),TM1637_NUM)\\\\n`;\\r\\n};\\r\\n\\r\\n\\r\\nBlockly.Blocks['ohcode_extend_tm1637_clear_show'] = {\\r\\n  init: function() {\\r\\n    this.appendDummyInput()\\r\\n        .appendField(\\\"TM1637四位数码管 ｜ 清除显示\\\");\\r\\n    this.setInputsInline(true);\\r\\n    this.setPreviousStatement(true, null);\\r\\n    this.setNextStatement(true, null);\\r\\n    this.setColour(global_color);\\r\\n this.setTooltip(\\\"清空数码管的所有显示\\\");\\r\\n this.setHelpUrl(\\\"\\\");\\r\\n  }\\r\\n};\\r\\npythonGenerator.forBlock['ohcode_extend_tm1637_clear_show'] = function(block) {\\r\\n  return \\\"_tm1637.clear()\\\\n\\\";\\r\\n};\",\"categoryiconcss\":{\"cssname\":\"ohcodeextend6afdf4312fd76e229b2d400068fa76ccIcon\",\"backgroundimage\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzE1MjE3NTc1NTYzIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQ2NjciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+PHBhdGggZD0iTTM4Mi41MTAxIDQ0Ny4xNTIxYy04MS42OTU3LTM4LjExMjMtMTI1LjI0NzUtOTkuMzU5Ny0xMzAuNjg4LTE4My43NzYzIDEwLjg4LTEzOC44NDgzIDkyLjU2MDQtMjEyLjM2ODQgMjQ1LjA0MDEtMjIwLjU0NCAxNDcuMDA3NSAxMC44OTY0IDIyNy4zMjggODQuNDE2NSAyNDAuOTU5NSAyMjAuNTQ0LTUuNDU1OSA4Ny4xMzYzLTQ2LjMwNDMgMTQ4LjM4MzctMTIyLjUyNzcgMTgzLjc3NjMgMTAwLjczNiAzOC4xMjc2IDE1My44MjQzIDExMS42NDc3IDE1OS4yODAxIDIyMC41NDQtOC4xNzU2IDEzOC44NjM2LTEwMC43NTI0IDIxMS4wMDc1LTI3Ny43MTE5IDIxNi40NDgtMTc5LjcxMi01LjQzOTUtMjcyLjI3MjQtODAuMzA0MS0yNzcuNzExOS0yMjQuNjIzNkMyMjcuMzEwNiA1NTMuMzQ0IDI4MS43NzQxIDQ4Mi41NDM2IDM4Mi41MTAxIDQ0Ny4xNTIxek00OTIuNzgyNiA0NzkuODIzOWMtMTA4LjkxMTYgNS40NTU5LTE2OC44MTU2IDY1LjM1OTktMTc5LjY5NTYgMTc5LjY5NTYgMTAuODggOTguMDE2MyA3Mi4xNDM5IDE1MS4xMTk5IDE4My43NzYzIDE1OS4yODAxIDExMS42MTYtOC4xNjAzIDE3Mi44Nzk5LTU4LjUyNzcgMTgzLjc3NTItMTUxLjEwMzVDNjcyLjQ2MTggNTQ3LjkwMzUgNjA5LjgzODEgNDg1LjI3OTcgNDkyLjc4MjYgNDc5LjgyMzl6TTQ5Ni44NjIyIDExNi4zNTJjLTg5Ljg1NiA1LjQzOTUtMTM4Ljg2MzYgNTEuNzI4NC0xNDcuMDIzOSAxMzguODQ4MyAyLjcxOTcgMTAwLjc1MjQgNTEuNzI4NCAxNTMuODM5NiAxNDcuMDIzOSAxNTkuMjgwMSA4OS44Mzk2LTIuNzE5NyAxMzcuNDg3NC01My4wODgzIDE0Mi45NDMyLTE1MS4xMDM1QzYzMS42Mjk4IDE3My41MzYzIDU4My45ODIxIDEyNC41Mjc2IDQ5Ni44NjIyIDExNi4zNTJ6IiBwLWlkPSI0NjY4IiBmaWxsPSIjZTE1Zjc2Ij48L3BhdGg+PC9zdmc+\",\"backgroundimageselected\":\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzE1MjE3NTc1NTYzIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQ2NjciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+PHBhdGggZD0iTTM4Mi41MTAxIDQ0Ny4xNTIxYy04MS42OTU3LTM4LjExMjMtMTI1LjI0NzUtOTkuMzU5Ny0xMzAuNjg4LTE4My43NzYzIDEwLjg4LTEzOC44NDgzIDkyLjU2MDQtMjEyLjM2ODQgMjQ1LjA0MDEtMjIwLjU0NCAxNDcuMDA3NSAxMC44OTY0IDIyNy4zMjggODQuNDE2NSAyNDAuOTU5NSAyMjAuNTQ0LTUuNDU1OSA4Ny4xMzYzLTQ2LjMwNDMgMTQ4LjM4MzctMTIyLjUyNzcgMTgzLjc3NjMgMTAwLjczNiAzOC4xMjc2IDE1My44MjQzIDExMS42NDc3IDE1OS4yODAxIDIyMC41NDQtOC4xNzU2IDEzOC44NjM2LTEwMC43NTI0IDIxMS4wMDc1LTI3Ny43MTE5IDIxNi40NDgtMTc5LjcxMi01LjQzOTUtMjcyLjI3MjQtODAuMzA0MS0yNzcuNzExOS0yMjQuNjIzNkMyMjcuMzEwNiA1NTMuMzQ0IDI4MS43NzQxIDQ4Mi41NDM2IDM4Mi41MTAxIDQ0Ny4xNTIxek00OTIuNzgyNiA0NzkuODIzOWMtMTA4LjkxMTYgNS40NTU5LTE2OC44MTU2IDY1LjM1OTktMTc5LjY5NTYgMTc5LjY5NTYgMTAuODggOTguMDE2MyA3Mi4xNDM5IDE1MS4xMTk5IDE4My43NzYzIDE1OS4yODAxIDExMS42MTYtOC4xNjAzIDE3Mi44Nzk5LTU4LjUyNzcgMTgzLjc3NTItMTUxLjEwMzVDNjcyLjQ2MTggNTQ3LjkwMzUgNjA5LjgzODEgNDg1LjI3OTcgNDkyLjc4MjYgNDc5LjgyMzl6TTQ5Ni44NjIyIDExNi4zNTJjLTg5Ljg1NiA1LjQzOTUtMTM4Ljg2MzYgNTEuNzI4NC0xNDcuMDIzOSAxMzguODQ4MyAyLjcxOTcgMTAwLjc1MjQgNTEuNzI4NCAxNTMuODM5NiAxNDcuMDIzOSAxNTkuMjgwMSA4OS44Mzk2LTIuNzE5NyAxMzcuNDg3NC01My4wODgzIDE0Mi45NDMyLTE1MS4xMDM1QzYzMS42Mjk4IDE3My41MzYzIDU4My45ODIxIDEyNC41Mjc2IDQ5Ni44NjIyIDExNi4zNTJ6IiBwLWlkPSI0NjY4IiBmaWxsPSIjZmZmZmZmIj48L3BhdGg+PC9zdmc+\"},\"library\":{\"TM1637.py\":\"from machine import Pin\\nimport time\\n\\nTM1637_CMD1 = 0x40\\nTM1637_CMD2 = 0xC0\\nTM1637_CMD3 = 0x80\\nTM1637_DSP_ON = 0x08\\nTM1637_DELAY = 10\\n\\n_SEGMENTS = bytearray([\\n    0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,\\n    0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x3D, 0x76, 0x06, 0x1E,\\n    0x76, 0x38, 0x55, 0x54, 0x3F, 0x73, 0x67, 0x50, 0x6D, 0x78,\\n    0x3E, 0x1C, 0x2A, 0x76, 0x6E, 0x5B, 0x00, 0x40, 0x63\\n])\\n\\nmax = lambda x, y: x if x >= y else y\\nmin = lambda x, y: x if x <= y else y\\n\\n\\nclass TM1637(object):\\n    def __init__(self, clk, dio, brightness=7):\\n        self.clk = clk\\n        self.dio = dio\\n        if not 0 <= brightness <= 7:\\n            self._brightness = 7\\n        self._brightness = brightness\\n        self.clk.init(Pin.OUT, 0)\\n        self.dio.init(Pin.OUT, 0)\\n        time.usleep(TM1637_DELAY)\\n        self._write_data_cmd()\\n        self._write_dsp_ctrl()\\n\\n    def _start(self):\\n        self.dio.value(0)\\n        time.usleep(TM1637_DELAY)\\n        self.clk.value(0)\\n        time.usleep(TM1637_DELAY)\\n\\n    def _stop(self):\\n        self.dio.value(0)\\n        time.usleep(TM1637_DELAY)\\n        self.clk.value(1)\\n        time.usleep(TM1637_DELAY)\\n        self.dio.value(1)\\n\\n    def _write_data_cmd(self):\\n        self._start()\\n        self._write_byte(TM1637_CMD1)\\n        self._stop()\\n\\n    def _write_dsp_ctrl(self):\\n        self._start()\\n        self._write_byte(TM1637_CMD3 | TM1637_DSP_ON | self._brightness)\\n        self._stop()\\n\\n    def _write_byte(self, b):\\n        for i in range(8):\\n            self.dio.value((b >> i) & 1)\\n            time.usleep(TM1637_DELAY)\\n            self.clk.value(1)\\n            time.usleep(TM1637_DELAY)\\n            self.clk.value(0)\\n            time.usleep(TM1637_DELAY)\\n        self.clk.value(0)\\n        time.usleep(TM1637_DELAY)\\n        self.clk.value(1)\\n        time.usleep(TM1637_DELAY)\\n        self.clk.value(0)\\n        time.usleep(TM1637_DELAY)\\n\\n    def brightness(self, val=None):\\n        if val is None:\\n            return self._brightness\\n        if not 0 <= val <= 7:\\n            return 7\\n        self._brightness = val\\n        self._write_data_cmd()\\n        self._write_dsp_ctrl()\\n\\n    def write(self, segments, pos=0):\\n        if not 0 <= pos <= 5:\\n            return 0\\n        self._write_data_cmd()\\n        self._start()\\n        self._write_byte(TM1637_CMD2 | pos)\\n        for seg in segments:\\n            self._write_byte(seg)\\n        self._stop()\\n        self._write_dsp_ctrl()\\n\\n    def encode_digit(self, digit):\\n        return _SEGMENTS[digit & 0x0f]\\n\\n    def encode_string(self, string):\\n        segments = bytearray(len(string))\\n        for i in range(len(string)):\\n            segments[i] = self.encode_char(string[i])\\n        return segments\\n\\n    def encode_char(self, char):\\n        o = ord(char)\\n        if o == 32:\\n            return _SEGMENTS[36]\\n        if o == 42:\\n            return _SEGMENTS[38]\\n        if o == 45:\\n            return _SEGMENTS[37]\\n        if o >= 65 and o <= 90:\\n            return _SEGMENTS[o - 55]\\n        if o >= 97 and o <= 122:\\n            return _SEGMENTS[o - 87]\\n        if o >= 48 and o <= 57:\\n            return _SEGMENTS[o - 48]\\n        return _SEGMENTS[36]\\n\\n    def hex(self, val):\\n        string = '{:04x}'.format(val & 0xffff)\\n        self.write(self.encode_string(string))\\n\\n    def number(self, num):\\n        num = max(-999, min(num, 9999))\\n        string = '{0: >4d}'.format(num)\\n        self.write(self.encode_string(string))\\n\\n    def numbers(self, num1, num2, colon=True):\\n        num1 = max(-9, min(num1, 99))\\n        num2 = max(-9, min(num2, 99))\\n        segments = self.encode_string('{0:0>2d}{1:0>2d}'.format(num1, num2))\\n        if colon:\\n            segments[1] |= 0x80  # colon on\\n        self.write(segments)\\n\\n    def show(self, striLng, colon=False):\\n        segments = self.encode_string(striLng)\\n        content = []\\n        if len(segments) > 1 and colon:\\n            segments[1] |= 128\\n        for a in range(len(segments)):\\n            content.append(segments[a])\\n        if len(segments) < 4:\\n            content+=[0]*(4-(len(segments)))\\n        self.write(content)\\n\\n    def temperature(self, num):\\n        if num < -9:\\n            self.show('lo')\\n        elif num > 99:\\n            self.show('hi')\\n        else:\\n            string = '{0: >2d}'.format(num)\\n            self.write(self.encode_string(string))\\n        self.write([_SEGMENTS[38], _SEGMENTS[12]], 2)\\n\\n    def clear(self):\\n        self.write([0, 0, 0, 0])\\n\\n\\nclass TM1637Decimal(TM1637):\\n    def encode_string(self, string):\\n        segments = bytearray(len(string.replace('.', '').replace(',','').replace(':','')))\\n        j = 0\\n        for i in range(len(string)):\\n            if (string[i] == '.' or string[i] == ',' or string[i] == ':') and j > 0:\\n                segments[j - 1] |= 0x80\\n                continue\\n            segments[j] = self.encode_char(string[i])\\n            j += 1\\n        return segments\\n    def encode_point_string(self,num,string):\\n        segments = bytearray(len(string))\\n        for i in range(len(string)):\\n            segments[i] = self.encode_char(string[i])\\n\\n        if num == '1':\\n            print(segments)\\n            segments[1] |= 0x80\\n        elif num == '0':\\n            segments[1] &= 0x7F\\n        else:\\n            pass\\n\\n        self.write(segments)\\n\"}},\"b75c851731a75075c0a4d57171d693be\":{\"category\":{\"kind\":\"CATEGORY\",\"name\":\"Sentry2\",\"colour\":\"#EF5411\",\"contents\":[{\"kind\":\"LABEL\",\"text\":\"配置参数\"},{\"kind\":\"BLOCK\",\"type\":\"Sentry2Begin\"},{\"kind\":\"BLOCK\",\"type\":\"Sentry2VisionSetStatus\"},{\"kind\":\"BLOCK\",\"type\":\"Sentry2CameraSetAwb\"},{\"kind\":\"BLOCK\",\"type\":\"Sentry2SetParamNum\",\"inputs\":{\"max_num\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":1}}}}},{\"kind\":\"BLOCK\",\"type\":\"Sentry2SetColorParam\",\"inputs\":{\"x\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":120}}},\"y\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":120}}},\"w\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":20}}},\"h\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":20}}},\"objid\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":1}}}}},{\"kind\":\"BLOCK\",\"type\":\"Sentry2SetBlodParam\",\"inputs\":{\"w\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":15}}},\"h\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":15}}},\"objid\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":1}}}}},{\"kind\":\"BLOCK\",\"type\":\"Sentry2SetVisionParam\",\"inputs\":{\"x\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":0}}},\"y\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":0}}},\"w\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":0}}},\"h\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":0}}},\"lable\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":0}}},\"objid\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":1}}}}},{\"kind\":\"LABEL\",\"text\":\"运行参数\"},{\"kind\":\"BLOCK\",\"type\":\"Sentry2Detected\"},{\"kind\":\"BLOCK\",\"type\":\"Sentry2GetValue\",\"inputs\":{\"objid\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":1}}}}},{\"kind\":\"BLOCK\",\"type\":\"Sentry2GetValueNomal\",\"inputs\":{\"objid\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":1}}}}},{\"kind\":\"BLOCK\",\"type\":\"Sentry2ColorRcgValue\",\"inputs\":{\"objid\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":1}}}}},{\"kind\":\"BLOCK\",\"type\":\"Sentry2QrRcgValue\"},{\"kind\":\"BLOCK\",\"type\":\"Sentry2GetQrCodeValue\"},{\"kind\":\"BLOCK\",\"type\":\"Sentry2LineValue\",\"inputs\":{\"objid\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":1}}}}},{\"kind\":\"BLOCK\",\"type\":\"Sentry2DetectedColor\",\"inputs\":{\"objid\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":1}}}}},{\"kind\":\"BLOCK\",\"type\":\"Sentry2DetectedBlob\",\"inputs\":{\"objid\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":1}}}}},{\"kind\":\"BLOCK\",\"type\":\"Sentry2DetectedCard\",\"inputs\":{\"objid\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":1}}}}},{\"kind\":\"BLOCK\",\"type\":\"Sentry2Detected20Class\",\"inputs\":{\"objid\":{\"shadow\":{\"type\":\"math_number\",\"fields\":{\"NUM\":1}}}}}],\"cssConfig\":{\"icon\":\"blocklyTreeIcon ohcodeextend3794b220994c11b04e097f4a7b746c90Icon\"}},\"blocksdef\":\"\\n// Sentry Enable Disable\\nconst SENTRY_ENABLE = '启用';\\nconst SENTRY_DISABLE = '关闭';\\n\\n// Sentry White Balance Type\\nconst SENTRY_AWB_AUTO = '自动';\\nconst SENTRY_AWB_LOCK = '锁定白平衡';\\nconst SENTRY_AWB_WHITE_LIGHT = '白光模式';\\nconst SENTRY_AWB_YELLOW_LIGHT = '黄光模式';\\n\\n// Sentry State Value Type\\nconst SENTRY_STATE_VALUE = '结果'\\nconst SENTRY_STATE_VALUE_X = '横向坐标';\\nconst SENTRY_STATE_VALUE_Y = '纵向坐标';\\nconst SENTRY_STATE_VALUE_WIDTH = '宽度';\\nconst SENTRY_STATE_VALUE_HEIGHT = '高度';\\nconst SENTRY_STATE_VALUE_LABEL = '标签';\\n\\nconst SENTRY_STATE_VALUE_R = '红色通道';\\nconst SENTRY_STATE_VALUE_G = '绿色通道';\\nconst SENTRY_STATE_VALUE_B = '蓝色通道';\\n\\nconst SENTRY_STATE_LINE_EX = '线段终点X坐标';\\nconst SENTRY_STATE_LINE_EY = '线段终点Y坐标';\\nconst SENTRY_STATE_LINE_SX = '线段起点X坐标';\\nconst SENTRY_STATE_LINE_SY = '线段起点Y坐标';\\nconst SENTRY_STATE_LINE_A = '线段的倾斜角度';\\n\\n// Sentry Color Type\\nconst SENTRY_COLOR_BLACK = '黑色';\\nconst SENTRY_COLOR_WHITE = '白色';\\nconst SENTRY_COLOR_RED = '红色';\\nconst SENTRY_COLOR_GREEN = '绿色';\\nconst SENTRY_COLOR_BLUE = '蓝色';\\nconst SENTRY_COLOR_YELLOW = '黄色';\\nconst SENTRY_COLOR_UNKNOWN = '其他';\\n\\n// Sentry Vision type\\nconst SENTRY_VISION_VISIONCOLOR = '颜色识别';\\nconst SENTRY_VISION_VISIONBLOB = '色块检测';\\nconst SENTRY_VISION_VISIONBALL = '球体检测';\\nconst SENTRY_VISION_VISIONAPRILTAG = 'AprilTag';\\nconst SENTRY_VISION_VISIONLINE = '线段检测';\\nconst SENTRY_VISION_VISIONLEARNING = '机器学习';\\nconst SENTRY_VISION_VISIONCARD = '卡片识别';\\nconst SENTRY_VISION_VISIONBODY = '人体检测';\\nconst SENTRY_VISION_VISIONFACE = '人脸识别';\\nconst SENTRY_VISION_VISION20CLASSES = '20分类识别';\\nconst SENTRY_VISION_VISIONQRCODE = '二维码识别';\\nconst SENTRY_VISION_VISIONOBJTRACK = '物体训练与追踪';\\nconst SENTRY_VISION_VISIONMOTIONDETECT = '运动物体检测';\\nconst SENTRY_VISION_VISIONCUSTOM = '自定义';\\n\\n// Sentry 20 Class Type\\nconst SENTRY_CLASS20_AIRPLANE = '✈️ 飞机';\\nconst SENTRY_CLASS20_BICYCLE = '🚲 自行车';\\nconst SENTRY_CLASS20_BIRD = '🐦 鸟';\\nconst SENTRY_CLASS20_BOAT = '🚤 船';\\nconst SENTRY_CLASS20_BOTTLE = '🍾 瓶子';\\nconst SENTRY_CLASS20_BUS = ' 🚌 公交车';\\nconst SENTRY_CLASS20_CAR = '🚗 小汽车';\\nconst SENTRY_CLASS20_CAT = ' 🐱 猫';\\nconst SENTRY_CLASS20_CHAIR = '🪑 椅子';\\nconst SENTRY_CLASS20_COW = '🐄 奶牛';\\nconst SENTRY_CLASS20_TABLE = '🔲 桌子';\\nconst SENTRY_CLASS20_DOG = '🐕 狗';\\nconst SENTRY_CLASS20_HORSE = '🐎 马';\\nconst SENTRY_CLASS20_MOTORBIKE = '🏍️ 摩托车';\\nconst SENTRY_CLASS20_PERSON = '🤵 人';\\nconst SENTRY_CLASS20_PLANT = '🪴 植物';\\nconst SENTRY_CLASS20_SHEEP = '🐏 羊';\\nconst SENTRY_CLASS20_SOFA = '🛋 沙发';\\nconst SENTRY_CLASS20_TRAIN = '🚆 火车';\\nconst SENTRY_CLASS20_MONITOR = '🖥️ 显示器';\\n\\n// Sentry Card Type\\nconst SENTRY_CARD_FORWARD = '前进';\\nconst SENTRY_CARD_LEFT = '左';\\nconst SENTRY_CARD_RIGHT = '右';\\nconst SENTRY_CARD_TURN_AROUND = '掉头';\\nconst SENTRY_CARD_PARK = '暂停';\\nconst SENTRY_CARD_GREEN_LIGHT = '绿灯';\\nconst SENTRY_CARD_RED_LIGHT = '红灯';\\nconst SENTRY_CARD_SPEED_40 = '速度40';\\nconst SENTRY_CARD_SPEED_60 = '速度60';\\nconst SENTRY_CARD_SPEED_80 = '速度80';\\nconst SENTRY_CARD_CHECK = '对勾';\\nconst SENTRY_CARD_CROSS = '叉号';\\nconst SENTRY_CARD_CIRCLE = '圆圈';\\nconst SENTRY_CARD_SQUARE = '正方形';\\nconst SENTRY_CARD_TRIANGLE = '三角形';\\nconst SENTRY_CARD_PLUS = '加号';\\nconst SENTRY_CARD_MINUS = '减号';\\nconst SENTRY_CARD_DIVIDE = '除号';\\nconst SENTRY_CARD_EQUAL = '等于号';\\nconst SENTRY_CARD_1 = '1';\\nconst SENTRY_CARD_2 = '2';\\nconst SENTRY_CARD_3 = '3';\\nconst SENTRY_CARD_4 = '4';\\nconst SENTRY_CARD_5 = '5';\\nconst SENTRY_CARD_6 = '6';\\nconst SENTRY_CARD_7 = '7';\\nconst SENTRY_CARD_8 = '8';\\nconst SENTRY_CARD_9 = '9';\\nconst SENTRY_CARD_0 = '0';\\n\\n// Sentry2模块文本\\nconst SENTRY2_BEGIN_MESSAGE0 = '初始化 Sentry2 端口 %1 地址 %2';\\nconst SENTRY2_SET_DEFAULT_MESSAGE0 = ' Sentry2 恢复默认参数';\\nconst SENTRY2_VISION_SET_STATUS_MESSAGE0 = 'Sentry2 %1 算法 %2';\\nconst SENTRY2_SET_PARAMNUM_MESSAGE0 = '设置 Sentry2 算法 %1 参数个数 %2';\\nconst SENTRY2_COLORPARAM_MESSAGE0 = '设置 Sentry2 算法 %1 区域中心 横坐标 %2 纵坐标 %3 宽度 %4 高度 %5 索引 %6';\\nconst SENTRY2_BOLDPARAM_MESSAGE0 = '设置 Sentry2 算法 %1 最小宽度 %2 高度 %3 检测标签 %4 索引 %5';\\nconst SENTRY2_VISIONPARAM_MESSAGE0 = '设置 Sentry2 算法 %1 参数1 %2 参数2 %3 参数3 %4 参数4 %5 参数5 %6 索引 %7';\\nconst SENTRY2_CAMERA_SET_AWB_MESSAGE0 = '设置 Sentry2 摄像头白平衡 %1';\\nconst SENTRY2_DETECTED_MESSAGE0 = 'Sentry2 算法 %1 检测结果数量';\\nconst SENTRY2_GET_VALUE_MESSAGE0 = 'Sentry2 算法 %1  %2 索引 %3';\\nconst SENTRY2_COLORRCGVALUE_MESSAGE0 = 'Sentry2 颜色识别 %1 索引 %2';\\nconst SENTRY2_QRRCGVALUE_MESSAGE0 = ' Sentry2 二维码识别 %1';\\nconst SENTRY2_GET_QRCODEVALUE_MESSAGE0 = 'Sentry2 二维码识别结果字符串';\\nconst SENTRY2_LINEVALUE_MESSAGE0 = 'Sentry2 线段检测结果 %1 索引 %2';\\nconst SENTRY2_DETECTEDCOLOR_MESSAGE0 = 'Sentry2 颜色识别算法检测到 %1 索引 %2';\\nconst SENTRY2_DETECTEDBLOB_MESSAGE0 = 'Sentry2 色块检测算法检测到 %1 索引 %2';\\nconst SENTRY2_DETECTEDCARD_MESSAGE0 = 'Sentry2 卡片识别算法检测到 %1 索引 %2';\\nconst SENTRY2_DETECTED20CLASS_MESSAGE0 = 'Sentry2 20分类识别算法检测到 %1 索引 %2';\\n\\n\\nconst Sentry_SetupMode_Color = \\\"#EF5411\\\";\\nconst Sentry_RunMode_Color = \\\"#EAA20A\\\";\\n\\nconst  sentry = [\\n  [\\\"0x60\\\", \\\"0\\\"],\\n  [\\\"0x61\\\", \\\"1\\\"],\\n  [\\\"0x62\\\", \\\"2\\\"],\\n  [\\\"0x63\\\", \\\"3\\\"],\\n];\\n\\n// 初始化 Sentry2\\nBlockly.Blocks[\\\"Sentry2Begin\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_SetupMode_Color,\\n      args0: [\\n        {\\n          name: \\\"InitType\\\",\\n          options: [\\n            [\\\"i2c0\\\", \\\"i2c0\\\"]\\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n        {\\n          name: \\\"sentry\\\",\\n          options: sentry,\\n          type: \\\"field_dropdown\\\",\\n        },\\n      ],\\n      message0: SENTRY2_BEGIN_MESSAGE0,\\n      inputsInline: true,\\n      nextStatement: null,\\n      previousStatement: null,\\n    });\\n  },\\n};\\n\\n// 恢复默认设置\\nBlockly.Blocks[\\\"Sentry2SetDefault\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_SetupMode_Color,\\n\\n      message0: SENTRY2_SET_DEFAULT_MESSAGE0,\\n      inputsInline: true,\\n      nextStatement: null,\\n      previousStatement: null,\\n    });\\n  },\\n};\\n\\n// 启用算法\\nBlockly.Blocks[\\\"Sentry2VisionSetStatus\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_SetupMode_Color,\\n      args0: [\\n        {\\n          name: \\\"VisionStatus\\\",\\n          options: [\\n            [SENTRY_ENABLE, \\\"Begin\\\"],\\n            [SENTRY_DISABLE, \\\"End\\\"],\\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n        {\\n          name: \\\"VisionType\\\",\\n          options: [\\n            [SENTRY_VISION_VISIONCOLOR, \\\"sentry2_vision_e.kVisionColor\\\"],\\n            [SENTRY_VISION_VISIONBLOB, \\\"sentry2_vision_e.kVisionBlob\\\"],\\n            [SENTRY_VISION_VISIONAPRILTAG, \\\"sentry2_vision_e.kVisionAprilTag\\\"],\\n            [SENTRY_VISION_VISIONLINE, \\\"sentry2_vision_e.kVisionLine\\\"],\\n            [SENTRY_VISION_VISIONLEARNING, \\\"sentry2_vision_e.kVisionLearning\\\"],\\n            [SENTRY_VISION_VISIONCARD, \\\"sentry2_vision_e.kVisionCard\\\"],\\n            [SENTRY_VISION_VISIONFACE, \\\"sentry2_vision_e.kVisionFace\\\"],\\n            [SENTRY_VISION_VISION20CLASSES, \\\"sentry2_vision_e.kVision20Classes\\\"],\\n            [SENTRY_VISION_VISIONQRCODE, \\\"sentry2_vision_e.kVisionQrCode\\\"],\\n            [SENTRY_VISION_VISIONCUSTOM, \\\"sentry2_vision_e.kVisionCustom\\\"],\\n            [SENTRY_VISION_VISIONMOTIONDETECT, \\\"sentry2_vision_e.kVisionMotionDetect\\\"],\\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n      ],\\n      message0: SENTRY2_VISION_SET_STATUS_MESSAGE0,\\n      inputsInline: true,\\n      nextStatement: null,\\n      previousStatement: null,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2SetParamNum\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_SetupMode_Color,\\n      args0: [\\n        {\\n          name: \\\"VisionType\\\",\\n          options: [\\n            [SENTRY_VISION_VISIONCOLOR, \\\"sentry2_vision_e.kVisionColor\\\"],\\n            [SENTRY_VISION_VISIONBLOB, \\\"sentry2_vision_e.kVisionBlob\\\"],\\n            [SENTRY_VISION_VISIONAPRILTAG, \\\"sentry2_vision_e.kVisionAprilTag\\\"],\\n            [SENTRY_VISION_VISIONLINE, \\\"sentry2_vision_e.kVisionLine\\\"],\\n            [SENTRY_VISION_VISIONLEARNING, \\\"sentry2_vision_e.kVisionLearning\\\"],\\n            [SENTRY_VISION_VISIONCARD, \\\"sentry2_vision_e.kVisionCard\\\"],\\n            [SENTRY_VISION_VISIONFACE, \\\"sentry2_vision_e.kVisionFace\\\"],\\n            [SENTRY_VISION_VISION20CLASSES, \\\"sentry2_vision_e.kVision20Classes\\\"],\\n            [SENTRY_VISION_VISIONQRCODE, \\\"sentry2_vision_e.kVisionQrCode\\\"],\\n            [SENTRY_VISION_VISIONCUSTOM, \\\"sentry2_vision_e.kVisionCustom\\\"],\\n            [SENTRY_VISION_VISIONMOTIONDETECT, \\\"sentry2_vision_e.kVisionMotionDetect\\\"],\\n            \\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"max_num\\\",\\n        },\\n      ],\\n      nextStatement: null,\\n      previousStatement: null,\\n      inputsInline: true,\\n      message0: SENTRY2_SET_PARAMNUM_MESSAGE0,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2SetColorParam\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_SetupMode_Color,\\n      args0: [\\n        {\\n          name: \\\"VisionType\\\",\\n          options: [\\n            [SENTRY_VISION_VISIONCOLOR, \\\"sentry2_vision_e.kVisionColor\\\"],\\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"x\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"y\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"w\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"h\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"objid\\\",\\n        },\\n      ],\\n      inputsInline: true,\\n      nextStatement: null,\\n      previousStatement: null,\\n      message0: SENTRY2_COLORPARAM_MESSAGE0,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2SetVisionParam\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_SetupMode_Color,\\n      args0: [\\n        {\\n          name: \\\"VisionType\\\",\\n          options: [\\n            [SENTRY_VISION_VISIONCOLOR, \\\"sentry2_vision_e.kVisionColor\\\"],\\n            [SENTRY_VISION_VISIONBLOB, \\\"sentry2_vision_e.kVisionBlob\\\"],\\n            [SENTRY_VISION_VISIONAPRILTAG, \\\"sentry2_vision_e.kVisionAprilTag\\\"],\\n            [SENTRY_VISION_VISIONLINE, \\\"sentry2_vision_e.kVisionLine\\\"],\\n            [SENTRY_VISION_VISIONLEARNING, \\\"sentry2_vision_e.kVisionLearning\\\"],\\n            [SENTRY_VISION_VISIONCARD, \\\"sentry2_vision_e.kVisionCard\\\"],\\n            [SENTRY_VISION_VISIONFACE, \\\"sentry2_vision_e.kVisionFace\\\"],\\n            [SENTRY_VISION_VISION20CLASSES, \\\"sentry2_vision_e.kVision20Classes\\\"],\\n            [SENTRY_VISION_VISIONQRCODE, \\\"sentry2_vision_e.kVisionQrCode\\\"],\\n            [SENTRY_VISION_VISIONCUSTOM, \\\"sentry2_vision_e.kVisionCustom\\\"],\\n            [SENTRY_VISION_VISIONMOTIONDETECT, \\\"sentry2_vision_e.kVisionMotionDetect\\\"],\\n            \\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"x\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"y\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"w\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"h\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"lable\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"objid\\\",\\n        },\\n      ],\\n      inputsInline: true,\\n      nextStatement: null,\\n      previousStatement: null,\\n      message0: SENTRY2_VISIONPARAM_MESSAGE0,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2SetBlodParam\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_SetupMode_Color,\\n      args0: [\\n        {\\n          name: \\\"VisionType\\\",\\n          options: [\\n            [SENTRY_VISION_VISIONBLOB, \\\"sentry2_vision_e.kVisionBlob\\\"],\\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"w\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"h\\\",\\n        },\\n        {\\n          type: \\\"field_dropdown\\\",\\n          name: \\\"lable\\\",\\n          options: [\\n            [SENTRY_COLOR_BLACK, \\\"sentry_color_label_e.kColorBlack\\\"],\\n            [SENTRY_COLOR_WHITE, \\\"sentry_color_label_e.kColorWhite\\\"],\\n            [SENTRY_COLOR_RED, \\\"sentry_color_label_e.kColorRed\\\"],\\n            [SENTRY_COLOR_GREEN, \\\"sentry_color_label_e.kColorGreen\\\"],\\n            [SENTRY_COLOR_BLUE, \\\"sentry_color_label_e.kColorBlue\\\"],\\n            [SENTRY_COLOR_YELLOW, \\\"sentry_color_label_e.kColorYellow\\\"],\\n          ],\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"objid\\\",\\n        },\\n      ],\\n      inputsInline: true,\\n      nextStatement: null,\\n      previousStatement: null,\\n      message0: SENTRY2_BOLDPARAM_MESSAGE0,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2CameraSetAwb\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_SetupMode_Color,\\n      args0: [\\n        {\\n          name: \\\"awb\\\",\\n          options: [\\n            [SENTRY_AWB_AUTO, \\\"sentry_camera_white_balance_e.kAutoWhiteBalance\\\"],\\n            [SENTRY_AWB_LOCK, \\\"sentry_camera_white_balance_e.kLockWhiteBalance\\\"],\\n            [SENTRY_AWB_WHITE_LIGHT, \\\"sentry_camera_white_balance_e.kWhiteLight\\\"],\\n            [SENTRY_AWB_YELLOW_LIGHT, \\\"sentry_camera_white_balance_e.kYellowLight\\\"],\\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n      ],\\n      nextStatement: null,\\n      previousStatement: null,\\n      message0: SENTRY2_CAMERA_SET_AWB_MESSAGE0,\\n      inputsInline: true,\\n    });\\n  },\\n};\\n\\n\\nBlockly.Blocks[\\\"Sentry2Detected\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_RunMode_Color,\\n      args0: [\\n        {\\n          name: \\\"VisionType\\\",\\n          options: [\\n            [SENTRY_VISION_VISIONCOLOR, \\\"sentry2_vision_e.kVisionColor\\\"],\\n            [SENTRY_VISION_VISIONBLOB, \\\"sentry2_vision_e.kVisionBlob\\\"],\\n            [SENTRY_VISION_VISIONAPRILTAG, \\\"sentry2_vision_e.kVisionAprilTag\\\"],\\n            [SENTRY_VISION_VISIONLINE, \\\"sentry2_vision_e.kVisionLine\\\"],\\n            [SENTRY_VISION_VISIONLEARNING, \\\"sentry2_vision_e.kVisionLearning\\\"],\\n            [SENTRY_VISION_VISIONCARD, \\\"sentry2_vision_e.kVisionCard\\\"],\\n            [SENTRY_VISION_VISIONFACE, \\\"sentry2_vision_e.kVisionFace\\\"],\\n            [SENTRY_VISION_VISION20CLASSES, \\\"sentry2_vision_e.kVision20Classes\\\"],\\n            [SENTRY_VISION_VISIONQRCODE, \\\"sentry2_vision_e.kVisionQrCode\\\"],\\n            [SENTRY_VISION_VISIONCUSTOM, \\\"sentry2_vision_e.kVisionCustom\\\"],\\n            [SENTRY_VISION_VISIONMOTIONDETECT, \\\"sentry2_vision_e.kVisionMotionDetect\\\"],\\n            \\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n      ],\\n      output: null,\\n      inputsInline: true,\\n      message0: SENTRY2_DETECTED_MESSAGE0,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2GetValue\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_RunMode_Color,\\n      args0: [\\n        {\\n          name: \\\"VisionType\\\",\\n          options: [\\n            [SENTRY_VISION_VISIONCOLOR, \\\"sentry2_vision_e.kVisionColor\\\"],\\n            [SENTRY_VISION_VISIONBLOB, \\\"sentry2_vision_e.kVisionBlob\\\"],\\n            [SENTRY_VISION_VISIONAPRILTAG, \\\"sentry2_vision_e.kVisionAprilTag\\\"],\\n            [SENTRY_VISION_VISIONLINE, \\\"sentry2_vision_e.kVisionLine\\\"],\\n            [SENTRY_VISION_VISIONLEARNING, \\\"sentry2_vision_e.kVisionLearning\\\"],\\n            [SENTRY_VISION_VISIONCARD, \\\"sentry2_vision_e.kVisionCard\\\"],\\n            [SENTRY_VISION_VISIONFACE, \\\"sentry2_vision_e.kVisionFace\\\"],\\n            [SENTRY_VISION_VISION20CLASSES, \\\"sentry2_vision_e.kVision20Classes\\\"],\\n            [SENTRY_VISION_VISIONQRCODE, \\\"sentry2_vision_e.kVisionQrCode\\\"],\\n            [SENTRY_VISION_VISIONCUSTOM, \\\"sentry2_vision_e.kVisionCustom\\\"],\\n            [SENTRY_VISION_VISIONMOTIONDETECT, \\\"sentry2_vision_e.kVisionMotionDetect\\\"],\\n            \\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n        {\\n          type: \\\"field_dropdown\\\",\\n          name: \\\"objinfo\\\",\\n          options: [\\n            [SENTRY_STATE_VALUE_X, \\\"sentry_obj_info_e.kXValue\\\"],\\n            [SENTRY_STATE_VALUE_Y, \\\"sentry_obj_info_e.kYValue\\\"],\\n            [SENTRY_STATE_VALUE_WIDTH, \\\"sentry_obj_info_e.kWidthValue\\\"],\\n            [SENTRY_STATE_VALUE_HEIGHT, \\\"sentry_obj_info_e.kHeightValue\\\"],\\n            [SENTRY_STATE_VALUE_LABEL, \\\"sentry_obj_info_e.kLabel\\\"],\\n          ],\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"objid\\\",\\n        },\\n      ],\\n      output: null,\\n      inputsInline: true,\\n      message0: SENTRY2_GET_VALUE_MESSAGE0,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2GetValueNomal\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_RunMode_Color,\\n      args0: [\\n        {\\n          name: \\\"VisionType\\\",\\n          options: [\\n            [SENTRY_VISION_VISIONCOLOR, \\\"sentry2_vision_e.kVisionColor\\\"],\\n            [SENTRY_VISION_VISIONBLOB, \\\"sentry2_vision_e.kVisionBlob\\\"],\\n            [SENTRY_VISION_VISIONAPRILTAG, \\\"sentry2_vision_e.kVisionAprilTag\\\"],\\n            [SENTRY_VISION_VISIONLINE, \\\"sentry2_vision_e.kVisionLine\\\"],\\n            [SENTRY_VISION_VISIONLEARNING, \\\"sentry2_vision_e.kVisionLearning\\\"],\\n            [SENTRY_VISION_VISIONCARD, \\\"sentry2_vision_e.kVisionCard\\\"],\\n            [SENTRY_VISION_VISIONFACE, \\\"sentry2_vision_e.kVisionFace\\\"],\\n            [SENTRY_VISION_VISION20CLASSES, \\\"sentry2_vision_e.kVision20Classes\\\"],\\n            [SENTRY_VISION_VISIONQRCODE, \\\"sentry2_vision_e.kVisionQrCode\\\"],\\n            [SENTRY_VISION_VISIONCUSTOM, \\\"sentry2_vision_e.kVisionCustom\\\"],\\n            [SENTRY_VISION_VISIONMOTIONDETECT, \\\"sentry2_vision_e.kVisionMotionDetect\\\"], \\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n        {\\n          type: \\\"field_dropdown\\\",\\n          name: \\\"objinfo\\\",\\n          options: [\\n            [SENTRY_STATE_VALUE + '1', \\\"sentry_obj_info_e.kXValue\\\"],\\n            [SENTRY_STATE_VALUE + '2', \\\"sentry_obj_info_e.kYValue\\\"],\\n            [SENTRY_STATE_VALUE + '3', \\\"sentry_obj_info_e.kWidthValue\\\"],\\n            [SENTRY_STATE_VALUE + '4', \\\"sentry_obj_info_e.kHeightValue\\\"],\\n            [SENTRY_STATE_VALUE + '5', \\\"sentry_obj_info_e.kLabel\\\"],\\n          ],\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"objid\\\",\\n        },\\n      ],\\n      output: null,\\n      inputsInline: true,\\n      message0: SENTRY2_GET_VALUE_MESSAGE0,\\n    });\\n  },\\n};\\n\\n\\nBlockly.Blocks[\\\"Sentry2ColorRcgValue\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_RunMode_Color,\\n      args0: [\\n        {\\n          type: \\\"field_dropdown\\\",\\n          name: \\\"objinfo\\\",\\n          options: [\\n            [SENTRY_STATE_VALUE_R, \\\"sentry_obj_info_e.kRValue\\\"],\\n            [SENTRY_STATE_VALUE_G, \\\"sentry_obj_info_e.kGValue\\\"],\\n            [SENTRY_STATE_VALUE_B, \\\"sentry_obj_info_e.kBValue\\\"],\\n            [SENTRY_STATE_VALUE_LABEL, \\\"sentry_obj_info_e.kLabel\\\"],\\n          ],\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"objid\\\",\\n        },\\n      ],\\n      output: null,\\n      inputsInline: true,\\n      message0: SENTRY2_COLORRCGVALUE_MESSAGE0,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2QrRcgValue\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_RunMode_Color,\\n      args0: [\\n        {\\n          type: \\\"field_dropdown\\\",\\n          name: \\\"objinfo\\\",\\n          options: [\\n            [SENTRY_STATE_VALUE_X, \\\"sentry_obj_info_e.kXValue\\\"],\\n            [SENTRY_STATE_VALUE_Y, \\\"sentry_obj_info_e.kYValue\\\"],\\n            [SENTRY_STATE_VALUE_WIDTH, \\\"sentry_obj_info_e.kWidthValue\\\"],\\n            [SENTRY_STATE_VALUE_HEIGHT, \\\"sentry_obj_info_e.kHeightValue\\\"],\\n          ],\\n        },\\n      ],\\n      output: null,\\n      inputsInline: true,\\n      message0: SENTRY2_QRRCGVALUE_MESSAGE0,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2GetQrCodeValue\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_RunMode_Color,\\n\\n      output: null,\\n      inputsInline: true,\\n      message0: SENTRY2_GET_QRCODEVALUE_MESSAGE0,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2LineValue\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_RunMode_Color,\\n      args0: [\\n        {\\n          type: \\\"field_dropdown\\\",\\n          name: \\\"objinfo\\\",\\n          options: [\\n            [SENTRY_STATE_LINE_EX, \\\"sentry_obj_info_e.kXValue\\\"],\\n            [SENTRY_STATE_LINE_EY, \\\"sentry_obj_info_e.kYValue\\\"],\\n            [SENTRY_STATE_LINE_SX, \\\"sentry_obj_info_e.kWidthValue\\\"],\\n            [SENTRY_STATE_LINE_SY, \\\"sentry_obj_info_e.kHeightValue\\\"],\\n            [SENTRY_STATE_LINE_A, \\\"sentry_obj_info_e.kLabel\\\"],\\n          ],\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"objid\\\",\\n        },\\n      ],\\n      output: null,\\n      inputsInline: true,\\n      message0: SENTRY2_LINEVALUE_MESSAGE0,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2DetectedColor\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_RunMode_Color,\\n      args0: [\\n        {\\n          type: \\\"field_dropdown\\\",\\n          name: \\\"ColorLabel\\\",\\n          options: [\\n            [SENTRY_COLOR_BLACK, \\\"sentry_color_label_e.kColorBlack\\\"],\\n            [SENTRY_COLOR_WHITE, \\\"sentry_color_label_e.kColorWhite\\\"],\\n            [SENTRY_COLOR_RED, \\\"sentry_color_label_e.kColorRed\\\"],\\n            [SENTRY_COLOR_GREEN, \\\"sentry_color_label_e.kColorGreen\\\"],\\n            [SENTRY_COLOR_BLUE, \\\"sentry_color_label_e.kColorBlue\\\"],\\n            [SENTRY_COLOR_YELLOW, \\\"sentry_color_label_e.kColorYellow\\\"],\\n            [SENTRY_COLOR_UNKNOWN, \\\"sentry_color_label_e.kColorUnkown\\\"],\\n          ],\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"objid\\\",\\n        },\\n      ],\\n      output: \\\"Boolean\\\",\\n      inputsInline: true,\\n      message0: SENTRY2_DETECTEDCOLOR_MESSAGE0,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2DetectedBlob\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_RunMode_Color,\\n      args0: [\\n        {\\n          type: \\\"field_dropdown\\\",\\n          name: \\\"ColorLabel\\\",\\n          options: [\\n            [SENTRY_COLOR_BLACK, \\\"sentry_color_label_e.kColorBlack\\\"],\\n            [SENTRY_COLOR_WHITE, \\\"sentry_color_label_e.kColorWhite\\\"],\\n            [SENTRY_COLOR_RED, \\\"sentry_color_label_e.kColorRed\\\"],\\n            [SENTRY_COLOR_GREEN, \\\"sentry_color_label_e.kColorGreen\\\"],\\n            [SENTRY_COLOR_BLUE, \\\"sentry_color_label_e.kColorBlue\\\"],\\n            [SENTRY_COLOR_YELLOW, \\\"sentry_color_label_e.kColorYellow\\\"],\\n            [SENTRY_COLOR_UNKNOWN, \\\"sentry_color_label_e.kColorUnkown\\\"],\\n          ],\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"objid\\\",\\n        },\\n      ],\\n      output: \\\"Boolean\\\",\\n      inputsInline: true,\\n      message0: SENTRY2_DETECTEDBLOB_MESSAGE0,\\n    });\\n  },\\n};\\n\\n\\nBlockly.Blocks[\\\"Sentry2DetectedCard\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_RunMode_Color,\\n      args0: [\\n        {\\n          name: \\\"card\\\",\\n          options: [\\n            [SENTRY_CARD_FORWARD, \\\"sentry2_card_label_e.kCardForward\\\"],\\n            [SENTRY_CARD_LEFT, \\\"sentry2_card_label_e.kCardLeft\\\"],\\n            [SENTRY_CARD_RIGHT, \\\"sentry2_card_label_e.kCardRight\\\"],\\n            [SENTRY_CARD_TURN_AROUND, \\\"sentry2_card_label_e.kCardTurnAround\\\"],\\n            [SENTRY_CARD_PARK, \\\"sentry2_card_label_e.kCardPark\\\"],\\n            [SENTRY_CARD_GREEN_LIGHT, \\\"sentry2_card_label_e.kCardGreenLight\\\"],\\n            [SENTRY_CARD_RED_LIGHT, \\\"sentry2_card_label_e.kCardRedLight\\\"],\\n            [SENTRY_CARD_SPEED_40, \\\"sentry2_card_label_e.kCardSpeed40\\\"],\\n            [SENTRY_CARD_SPEED_60, \\\"sentry2_card_label_e.kCardSpeed60\\\"],\\n            [SENTRY_CARD_SPEED_80, \\\"sentry2_card_label_e.kCardSpeed80\\\"],\\n            [SENTRY_CARD_CHECK, \\\"sentry2_card_label_e.kCardCheck\\\"],\\n            [SENTRY_CARD_CROSS, \\\"sentry2_card_label_e.kCardCross\\\"],\\n            [SENTRY_CARD_CIRCLE, \\\"sentry2_card_label_e.kCardCircle\\\"],\\n            [SENTRY_CARD_SQUARE, \\\"sentry2_card_label_e.kCardSquare\\\"],\\n            [SENTRY_CARD_TRIANGLE, \\\"sentry2_card_label_e.kCardTriangle\\\"],\\n            [SENTRY_CARD_PLUS, \\\"sentry2_card_label_e.kCardPlus\\\"],\\n            [SENTRY_CARD_MINUS, \\\"sentry2_card_label_e.kCardMinus\\\"],\\n            [SENTRY_CARD_DIVIDE, \\\"sentry2_card_label_e.kCardDivide\\\"],\\n            [SENTRY_CARD_EQUAL, \\\"sentry2_card_label_e.kCardEqual\\\"],\\n            [SENTRY_CARD_1, \\\"sentry2_card_label_e.kCardOne\\\"],\\n            [SENTRY_CARD_2, \\\"sentry2_card_label_e.kCardTwo\\\"],\\n            [SENTRY_CARD_3, \\\"sentry2_card_label_e.kCardThree\\\"],\\n            [SENTRY_CARD_4, \\\"sentry2_card_label_e.kCardFour\\\"],\\n            [SENTRY_CARD_5, \\\"sentry2_card_label_e.kCardFive\\\"],\\n            [SENTRY_CARD_6, \\\"sentry2_card_label_e.kCardSix\\\"],\\n            [SENTRY_CARD_7, \\\"sentry2_card_label_e.kCardSeven\\\"],\\n            [SENTRY_CARD_8, \\\"sentry2_card_label_e.kCardEight\\\"],\\n            [SENTRY_CARD_9, \\\"sentry2_card_label_e.kCardNine\\\"],\\n            [SENTRY_CARD_0, \\\"sentry2_card_label_e.kCardZero\\\"],\\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"objid\\\",\\n        },\\n      ],\\n      output: \\\"Boolean\\\",\\n      inputsInline: true,\\n      message0: SENTRY2_DETECTEDCARD_MESSAGE0,\\n    });\\n  },\\n};\\n\\nBlockly.Blocks[\\\"Sentry2Detected20Class\\\"] = {\\n  init: function () {\\n    this.jsonInit({\\n      colour: Sentry_RunMode_Color,\\n      args0: [\\n        {\\n          name: \\\"card\\\",\\n          options: [\\n            [SENTRY_CLASS20_AIRPLANE, \\\"sentry_class20_label_e.kAirplane\\\"],\\n            [SENTRY_CLASS20_BICYCLE, \\\"sentry_class20_label_e.kBicycle\\\"],\\n            [SENTRY_CLASS20_BIRD, \\\"sentry_class20_label_e.kBird\\\"],\\n            [SENTRY_CLASS20_BOAT, \\\"sentry_class20_label_e.kBoat\\\"],\\n            [SENTRY_CLASS20_BOTTLE, \\\"sentry_class20_label_e.kBus\\\"],\\n            [SENTRY_CLASS20_BUS, \\\"sentry_class20_label_e.kCar\\\"],\\n            [SENTRY_CLASS20_CAR, \\\"sentry_class20_label_e.kCat\\\"],\\n            [SENTRY_CLASS20_CAT, \\\"sentry_class20_label_e.kChair\\\"],\\n            [SENTRY_CLASS20_CHAIR, \\\"sentry_class20_label_e.kCow\\\"],\\n            [SENTRY_CLASS20_COW, \\\"sentry_class20_label_e.kTable\\\"],\\n            [SENTRY_CLASS20_TABLE, \\\"sentry_class20_label_e.kDog\\\"],\\n            [SENTRY_CLASS20_DOG, \\\"sentry_class20_label_e.kHorse\\\"],\\n            [SENTRY_CLASS20_HORSE, \\\"sentry_class20_label_e.kMotorBike\\\"],\\n            [SENTRY_CLASS20_MOTORBIKE, \\\"sentry_class20_label_e.kPerson\\\"],\\n            [SENTRY_CLASS20_PERSON, \\\"sentry_class20_label_e.kPlant\\\"],\\n            [SENTRY_CLASS20_PLANT, \\\"sentry_class20_label_e.kSheep\\\"],\\n            [SENTRY_CLASS20_SHEEP, \\\"sentry_class20_label_e.kSheep\\\"],\\n            [SENTRY_CLASS20_SOFA, \\\"sentry_class20_label_e.kSofa\\\"],\\n            [SENTRY_CLASS20_TRAIN, \\\"sentry_class20_label_e.kTrain\\\"],\\n            [SENTRY_CLASS20_MONITOR, \\\"sentry_class20_label_e.kMonitor\\\"],\\n          ],\\n          type: \\\"field_dropdown\\\",\\n        },\\n        {\\n          check: \\\"Number\\\",\\n          type: \\\"input_value\\\",\\n          name: \\\"objid\\\",\\n        },\\n      ],\\n      output: \\\"Boolean\\\",\\n      inputsInline: true,\\n      message0: SENTRY2_DETECTED20CLASS_MESSAGE0,\\n    });\\n  },\\n};\\n\\n\\n// 初始化 Sentry\\npythonGenerator.forBlock['Sentry2Begin'] = function (block) {\\n  var sentry = block.getFieldValue('sentry');\\n  var InitType = block.getFieldValue('InitType');\\n  var code = 'sentry' + '.begin(' + InitType + ')\\\\n';\\n\\n  pythonGenerator.definitions_['import_iic'] = 'from machine import I2C';\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n  pythonGenerator.definitions_['init_IIC'] = 'i2c0 = I2C(0,freq=400000)';\\n  pythonGenerator.definitions_['init_Sentry2' + sentry] = 'sentry' + ' = Sentry(0x4,0x6' + sentry + ')';\\n\\n  return code;\\n};\\n\\n// 恢复默认设置\\npythonGenerator.forBlock['Sentry2SetDefault'] = function (block) {\\n\\n  var code = 'sentry' + '.SensorSetDefault()\\\\n';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return code;\\n};\\n\\n// 启用算法\\npythonGenerator.forBlock['Sentry2VisionSetStatus'] = function (block) {\\n\\n  var VisionStatus = block.getFieldValue('VisionStatus');\\n  var VisionType = block.getFieldValue('VisionType');\\n  var code = 'sentry' + '.Vision' + VisionStatus + '(' + VisionType + ')\\\\n';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return code;\\n};\\n\\n// 设置算法参数\\npythonGenerator.forBlock['Sentry2SetParamNum'] = function (block) {\\n\\n  var VisionType = block.getFieldValue('VisionType');\\n  var max_num = pythonGenerator.valueToCode(block, \\\"max_num\\\", pythonGenerator.ORDER_NONE);\\n  var code = 'sentry' + '.SetParamNum(' + VisionType + ', ' + max_num + ')\\\\n';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return code;\\n};\\n\\n//算法参数\\npythonGenerator.forBlock['Sentry2SetVisionParam'] = function (block) {\\n  var x = pythonGenerator.valueToCode(block, \\\"x\\\", pythonGenerator.ORDER_NONE) || '1';\\n  var y = pythonGenerator.valueToCode(block, \\\"y\\\", pythonGenerator.ORDER_NONE) || '1';\\n  var w = pythonGenerator.valueToCode(block, \\\"w\\\", pythonGenerator.ORDER_NONE) || '1';\\n  var h = pythonGenerator.valueToCode(block, \\\"h\\\", pythonGenerator.ORDER_NONE) || '1';\\n  var lable = pythonGenerator.valueToCode(block, \\\"lable\\\", pythonGenerator.ORDER_NONE) || '1';\\n  var objid = pythonGenerator.valueToCode(block, \\\"objid\\\", pythonGenerator.ORDER_ATOMIC);\\n  var code = 'sentry' + '.SetParam(' + 'sentry2_vision_e.kVisionColor, [' + x + ', ' + y + ', ' + w + ', ' + h + ', '+ lable +']' + ', ' + objid + ')\\\\n';\\n\\n  return code;\\n};\\n\\n// Color 算法参数\\npythonGenerator.forBlock['Sentry2SetColorParam'] = function (block) {\\n  var x = pythonGenerator.valueToCode(block, \\\"x\\\", pythonGenerator.ORDER_NONE) || '1';\\n  var y = pythonGenerator.valueToCode(block, \\\"y\\\", pythonGenerator.ORDER_NONE) || '1';\\n  var w = pythonGenerator.valueToCode(block, \\\"w\\\", pythonGenerator.ORDER_NONE) || '1';\\n  var h = pythonGenerator.valueToCode(block, \\\"h\\\", pythonGenerator.ORDER_NONE) || '1';\\n  var objid = pythonGenerator.valueToCode(block, \\\"objid\\\", pythonGenerator.ORDER_ATOMIC);\\n  var code = 'sentry' + '.SetParam(' + 'sentry2_vision_e.kVisionColor, [' + x + ', ' + y + ', ' + w + ', ' + h + ', 0]' + ', ' + objid + ')\\\\n';\\n\\n  return code;\\n};\\n\\n\\n// Blod 算法参数\\npythonGenerator.forBlock['Sentry2SetBlodParam'] = function (block) {\\n  var w = pythonGenerator.valueToCode(block, \\\"w\\\", pythonGenerator.ORDER_NONE) || '1';\\n  var h = pythonGenerator.valueToCode(block, \\\"h\\\", pythonGenerator.ORDER_NONE) || '1';\\n  var lable = block.getFieldValue('lable');\\n  var objid = pythonGenerator.valueToCode(block, \\\"objid\\\", pythonGenerator.ORDER_ATOMIC);\\n  var code = 'sentry' + '.SetParam(' + 'sentry2_vision_e.kVisionBlob, ' + '[0, 0, ' + w + ', ' + h + ', ' + lable + ']' + ', ' + objid + ')\\\\n';\\n\\n  return code;\\n};\\n\\n\\npythonGenerator.forBlock['Sentry2CameraSetAwb'] = function (block) {\\n\\n\\n  var awb = block.getFieldValue('awb');\\n\\n  var code = 'sentry' + '.CameraSetAwb(' + awb + ')\\\\n';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return code;\\n};\\n\\npythonGenerator.forBlock['Sentry2Detected'] = function (block) {\\n\\n  var VisionType = block.getFieldValue('VisionType');\\n  var code = 'sentry' + '.GetValue(' + VisionType + ', sentry_obj_info_e.kStatus)';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\\n\\npythonGenerator.forBlock['Sentry2GetValue'] = pythonGenerator.forBlock['Sentry2GetValueNomal'] = function (block) {\\n\\n  var VisionType = block.getFieldValue('VisionType');\\n  var objinfo = block.getFieldValue('objinfo');\\n  var objid = pythonGenerator.valueToCode(block, \\\"objid\\\", pythonGenerator.ORDER_NONE) || '0';\\n  var code = 'sentry' + '.GetValue(' + VisionType + ', ' + objinfo + ', ' + objid + ')';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\\n\\npythonGenerator.forBlock['Sentry2ColorRcgValue'] = function (block) {\\n\\n  var objinfo = block.getFieldValue('objinfo');\\n  var objid = pythonGenerator.valueToCode(block, \\\"objid\\\", pythonGenerator.ORDER_NONE) || '0';\\n  var code = 'sentry' + '.GetValue(sentry2_vision_e.kVisionColor, ' + objinfo + ', ' + objid + ')';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\\n\\npythonGenerator.forBlock['Sentry2QrRcgValue'] = function (block) {\\n\\n  var objinfo = block.getFieldValue('objinfo');\\n  var code = 'sentry' + '.GetValue(sentry2_vision_e.kVisionQrCode, ' + objinfo + ')';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\\n\\n\\npythonGenerator.forBlock['Sentry2GetQrCodeValue'] = function (block) {\\n\\n  var code = 'sentry' + '.GetQrCodeValue()';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\\n\\npythonGenerator.forBlock['Sentry2LineValue'] = function (block) {\\n\\n  var objinfo = block.getFieldValue('objinfo');\\n  var objid = pythonGenerator.valueToCode(block, \\\"objid\\\", pythonGenerator.ORDER_NONE) || '0';\\n  var code = 'sentry' + '.GetValue(sentry2_vision_e.kVisionLine, ' + objinfo  + ', ' + objid + ')'\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\\n\\npythonGenerator.forBlock['Sentry2DetectedColor'] = function (block) {\\n\\n  var ColorLabel = block.getFieldValue('ColorLabel');\\n  var objid = pythonGenerator.valueToCode(block, \\\"objid\\\", pythonGenerator.ORDER_NONE) || '0';\\n\\n  var code = '(sentry' + '.GetValue(sentry2_vision_e.kVisionColor, sentry_obj_info_e.kLabel, ' + objid + ') == ' + ColorLabel + ')';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\\n\\npythonGenerator.forBlock['Sentry2DetectedBlob'] = function (block) {\\n\\n  var ColorLabel = block.getFieldValue('ColorLabel');\\n  var objid = pythonGenerator.valueToCode(block, \\\"objid\\\", pythonGenerator.ORDER_NONE) || '0';\\n\\n  var code = '(sentry' + '.GetValue(sentry2_vision_e.kVisionBlob, sentry_obj_info_e.kLabel, ' + objid + ') == ' + ColorLabel + ')';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\\n\\npythonGenerator.forBlock['Sentry2DetectedCard'] = function (block) {\\n\\n  var card = block.getFieldValue('card');\\n  var objid = pythonGenerator.valueToCode(block, \\\"objid\\\", pythonGenerator.ORDER_NONE) || '0';\\n\\n  var code = '(sentry' + '.GetValue(sentry2_vision_e.kVisionCard, sentry_obj_info_e.kLabel, ' + objid + ') == ' + card + ')';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\\n\\n\\npythonGenerator.forBlock['Sentry2Detected20Class'] = function (block) {\\n\\n  var card = block.getFieldValue('card');\\n  var objid = pythonGenerator.valueToCode(block, \\\"objid\\\", pythonGenerator.ORDER_NONE) || '0';\\n\\n  var code = '(sentry' + '.GetValue(sentry2_vision_e.kVision20Classes, sentry_obj_info_e.kLabel, ' + objid + ') == ' + card + ')';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\\n\\n\\npythonGenerator.forBlock['Sentry2GetQrCodeValue'] = function (block) {\\n\\n  var code = 'sentry' + '.GetQrCodeValue()';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\\n\\n\\npythonGenerator.forBlock['Sentry2Rows'] = function (block) {\\n\\n  var code = 'sentry' + '.Rows()';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\\n\\npythonGenerator.forBlock['Sentry2Cols'] = function (block) {\\n\\n  var code = 'sentry' + '.Cols()';\\n\\n  pythonGenerator.definitions_['import_Sentry'] = 'from Sentry import *';\\n\\n  return [code, pythonGenerator.ORDER_ATOMIC];\\n};\",\"categoryiconcss\":{\"cssname\":\"ohcodeextend3794b220994c11b04e097f4a7b746c90Icon\",\"backgroundimage\":\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNFRjU0MTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xNS42IDExLjZMMjIgN3YxMGwtNi40LTQuNXYtMXpNNCA1aDlhMiAyIDAgMCAxIDIgMnYxMGEyIDIgMCAwIDEtMiAySDRhMiAyIDAgMCAxLTItMlY3YzAtMS4xLjktMiAyLTJ6Ii8+PC9zdmc+\",\"backgroundimageselected\":\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmNGYwZjAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xNS42IDExLjZMMjIgN3YxMGwtNi40LTQuNXYtMXpNNCA1aDlhMiAyIDAgMCAxIDIgMnYxMGEyIDIgMCAwIDEtMiAySDRhMiAyIDAgMCAxLTItMlY3YzAtMS4xLjktMiAyLTJ6Ii8+PC9zdmc+\"},\"library\":{}}}"
}