(() => {

'use strict';
   
goog.require('Blockly.Arduino');
Blockly.Arduino.forBlock['make_arduino_describe'] = function(block) {

  return  ' //作  者 ： \n' +
  ' //回到  未来\n' +
  ' //QQ : 375091377\n';
};


//取地址或取地址所对应的值
Blockly.Arduino.forBlock['make_get_address'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type + '(' + value_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['arduino_const_variate'] = function () {
    var value_const_variate_data = Blockly.Arduino.valueToCode(this, 'const_variate_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_const_variate_name = this.getFieldValue('const_variate_name');
    var dropdown_const_variate_type = this.getFieldValue('const_variate_type');
    if (dropdown_const_variate_type == 'String') {
        if (value_const_variate_data == '') {
            Blockly.Arduino.definitions_['var_declare' + text_const_variate_name] = 'const ' + dropdown_const_variate_type + ' ' + text_const_variate_name + ' = ' + '""' + ';';
        }
        else {
            Blockly.Arduino.definitions_['var_declare' + text_const_variate_name] = 'const ' + dropdown_const_variate_type + ' ' + text_const_variate_name + ' = ' + value_const_variate_data + ';';
        }
    }
    else {
        if (value_const_variate_data == '') {
            Blockly.Arduino.definitions_['var_declare' + text_const_variate_name] = 'const ' + dropdown_const_variate_type + ' ' + text_const_variate_name + ' = ' + '0' + ';';
        }
        else {
            Blockly.Arduino.definitions_['var_declare' + text_const_variate_name] = 'const ' + dropdown_const_variate_type + ' ' + text_const_variate_name + ' = ' + value_const_variate_data + ';';
        }
    }

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['arduino_const_variate_1'] = function () {
    var text_const_variate_name = this.getFieldValue('const_variate_name');
    var code = text_const_variate_name;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['arduino_define_global_variate'] = function () {
    var value_global_variate_data = Blockly.Arduino.valueToCode(this, 'global_variate_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_global_variate_name = this.getFieldValue('global_variate_name');
    var dropdown_global_variate_type = this.getFieldValue('global_variate_type');

    if (dropdown_global_variate_type == 'String')
        Blockly.Arduino.definitions_['var_declare' + text_global_variate_name] = dropdown_global_variate_type + ' ' + text_global_variate_name + ';';
    else
        Blockly.Arduino.definitions_['var_declare' + text_global_variate_name] = 'volatile ' + dropdown_global_variate_type + ' ' + text_global_variate_name + ';';
    if (value_global_variate_data == '') {
        if (dropdown_global_variate_type == 'String') {
            Blockly.Arduino.setups_['setup_var' + text_global_variate_name] = text_global_variate_name + ' = "";';
        }
        else {
            Blockly.Arduino.setups_['setup_var' + text_global_variate_name] = text_global_variate_name + ' = 0;';
        }
    }
    else {
        Blockly.Arduino.setups_['setup_var' + text_global_variate_name] = text_global_variate_name + ' = ' + value_global_variate_data + ';';
    }

    var code = '';
    return code;
};



Blockly.Arduino.forBlock['arduino_define_static_global_variate'] = function () {
    var text_static_variate_name = this.getFieldValue('global_static_variate_name');
    var dropdown_static_variate_value = this.getFieldValue('static_variate_value');
    var value_static_variate_get_data = Blockly.Arduino.valueToCode(this, 'static_variate_get_data', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['var_declare' + text_static_variate_name] = 'static' + ' ' + dropdown_static_variate_value + ' ' + text_static_variate_name + ';';

    if (value_static_variate_get_data == '') {
        if (dropdown_static_variate_value == 'String') {
            Blockly.Arduino.setups_['setup_var' + text_static_variate_name] = text_static_variate_name + ' = "";';
        }
        else {
            Blockly.Arduino.setups_['setup_var' + text_static_variate_name] = text_static_variate_name + ' = 0;';
        }
    }
    else {
        Blockly.Arduino.setups_['setup_var' + text_static_variate_name] = text_static_variate_name + ' = ' + value_static_variate_get_data + ';';
    }

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_define_static_global_variate_1'] = function () {
    var value_static_variate_data = Blockly.Arduino.valueToCode(this, 'static_variate_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_static_variate_name = this.getFieldValue('global_static_variate_name');
    var code = text_static_variate_name + ' = ' + value_static_variate_data + ';\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_define_static_global_variate_2'] = function () {
    var text_static_variate_name = this.getFieldValue('global_static_variate_name');
    var code = text_static_variate_name;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['arduino_define_static_local_variate'] = function () {
    var text_static_variate_name = this.getFieldValue('local_static_variate_name');
    var dropdown_static_variate_value = this.getFieldValue('static_variate_value');
    var value_static_variate_get_data = Blockly.Arduino.valueToCode(this, 'static_variate_get_data', Blockly.Arduino.ORDER_ATOMIC);

    var code = '';
    if (!value_static_variate_get_data) {
        if (dropdown_static_variate_value != 'String') {
            code = 'static ' + dropdown_static_variate_value + ' ' + text_static_variate_name + ' = 0;\n';
        }
        else {
            code = 'static ' + dropdown_static_variate_value + ' ' + text_static_variate_name + ' = "";\n';
        }
    }
    else {
        code = 'static ' + dropdown_static_variate_value + ' ' + text_static_variate_name + ' = ' + value_static_variate_get_data + ';\n';
    }

    return code;
};

Blockly.Arduino.forBlock['make_arduino_define_static_local_variate_1'] = function () {
    var value_static_variate_data = Blockly.Arduino.valueToCode(this, 'static_variate_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_static_variate_name = this.getFieldValue('local_static_variate_name');
    var code = text_static_variate_name + ' = ' + value_static_variate_data + ';\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_define_static_local_variate_2'] = function () {
    var text_static_variate_name = this.getFieldValue('local_static_variate_name');
    var code = text_static_variate_name;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_define_local_variate'] = function () {
    var value_local_variate_data = Blockly.Arduino.valueToCode(this, 'local_variate_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_local_variate_name = this.getFieldValue('local_variate_name');
    var dropdown_local_variate_type = this.getFieldValue('local_variate_type');

    var code = '';
    if (!value_local_variate_data) {
        if (dropdown_local_variate_type != 'String') {
            code = dropdown_local_variate_type + ' ' + text_local_variate_name + ' = 0;\n';
        }
        else {
            code = dropdown_local_variate_type + ' ' + text_local_variate_name + ' = "";\n';
        }
    }
    else {
        code = dropdown_local_variate_type + ' ' + text_local_variate_name + ' = ' + value_local_variate_data + ';\n';
    }
    return code;
};

Blockly.Arduino.forBlock['make_arduino_define_local_variate_0'] = function () {
    var text_local_variate_name = this.getFieldValue('local_variate_name');
    var dropdown_local_variate_type = this.getFieldValue('local_variate_type');

    var code = '';
    code = dropdown_local_variate_type + ' ' + text_local_variate_name + ';\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_define_local_variate_1'] = function () {
    var value_local_variate_data = Blockly.Arduino.valueToCode(this, 'local_variate_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_local_variate_name = this.getFieldValue('local_variate_name');
    var code = text_local_variate_name + ' = ' + value_local_variate_data + ';\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_define_local_variate_2'] = function () {
    var text_local_variate_name = this.getFieldValue('local_variate_name');
    var code = text_local_variate_name;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_define_local_variate_3'] = function () {
    var value_local_variate_data = Blockly.Arduino.valueToCode(this, 'local_variate_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_local_variate_name = this.getFieldValue('local_variate_name');
    var dropdown_local_variate_type = this.getFieldValue('local_variate_type');

    var code = '';
    if (!value_local_variate_data) {
        if (dropdown_local_variate_type != 'String') {
            code = dropdown_local_variate_type + ' ' + text_local_variate_name + ' = 0';
        }
        else {
            code = dropdown_local_variate_type + ' ' + text_local_variate_name + ' = ""';
        }
    }
    else {
        code = dropdown_local_variate_type + ' ' + text_local_variate_name + ' = ' + value_local_variate_data + '';
    }
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['arduino_define_global_variate_0'] = function () {
    var text_global_variate_name = this.getFieldValue('global_variate_name');
    var dropdown_global_variate_type = this.getFieldValue('global_variate_type');

    var code = dropdown_global_variate_type + ' ' + text_global_variate_name + ';\n';
    Blockly.Arduino.definitions_['var_declare_' + text_global_variate_name] = code;
    return '';
};

Blockly.Arduino.forBlock['make_arduino_define_global_variate_1'] = function () {
    var value_global_variate_data = Blockly.Arduino.valueToCode(this, 'global_variate_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_global_variate_name = this.getFieldValue('global_variate_name');
    var code = text_global_variate_name + ' = ' + value_global_variate_data + ';\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_define_global_variate_2'] = function () {
    var text_global_variate_name = this.getFieldValue('global_variate_name');
    var code = text_global_variate_name;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_define_local_variate_4'] = function () {
    var value_local_variate_data = Blockly.Arduino.valueToCode(this, 'local_variate_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_local_variate_name = this.getFieldValue('local_variate_name');
    var code = text_local_variate_name + ' = ' + value_local_variate_data + '';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//do-while循环
Blockly.Arduino.forBlock['make_do_while'] = function () {
    var statements_input_data = Blockly.Arduino.statementToCode(this, 'input_data');
    var value_select_data = Blockly.Arduino.valueToCode(this, 'select_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_type = this.getFieldValue('type');
    if (dropdown_type == 'false') {
        var code = 'do{\n'
            + '' + statements_input_data
            + '}while(!(' + value_select_data + '));\n';
    }
    else {
        var code = 'do{\n'
            + '' + statements_input_data
            + '}while(' + value_select_data + ');\n';
    }
    return code;
};

//for
Blockly.Arduino.forBlock['make_for'] = function () {
    var value_variate = Blockly.Arduino.valueToCode(this, 'variate', Blockly.Arduino.ORDER_ATOMIC);
    var value_judge = Blockly.Arduino.valueToCode(this, 'judge', Blockly.Arduino.ORDER_ATOMIC);
    var value_operation = Blockly.Arduino.valueToCode(this, 'operation', Blockly.Arduino.ORDER_ATOMIC);
    var statements_do = Blockly.Arduino.statementToCode(this, 'do');
    var code = 'for(' + value_variate + '; ' + value_judge + '; ' + value_operation + ')\n'
        + '{\n'
        + '' + statements_do
        + '}\n';
    return code;
};

//return;
Blockly.Arduino.forBlock['make_return'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type + ';\n';
    return code;
};

//return+data
Blockly.Arduino.forBlock['make_return_with_data'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'return ' + value_data + ';\n';
    return code;
};
Blockly.Arduino.forBlock['set_pwm_frequency'] = function() {
  // 获取用户输入的频率值
  const frequency = Blockly.Arduino.valueToCode(this, 'FREQUENCY', Blockly.Arduino.ORDER_ATOMIC) ;
  // 在loop函数中添加设置频率的代码
  return `analogWriteFreq(${frequency});`;
};

Blockly.Arduino.forBlock['set_esp32_pwm'] = function() {
  const model = this.getFieldValue('MODEL');
  const channelStr = this.getFieldValue('CHANNEL');
  const channel = parseInt(channelStr);
  let maxChannel;
  switch(model) {
    case 'esp32c3':
      maxChannel = 5; // ESP32-C3有6个通道(0-5)
      break;
    case 'esp32s3':
      maxChannel = 7; // ESP32-S3有8个通道(0-7)
      break;
    default:
      maxChannel = 15; // ESP32/ESP32-S2有16个通道(0-15)
  }
  const safeChannel = Math.min(channel, maxChannel);
  const resolution = this.getFieldValue('RESOLUTION');
  const frequency = this.getFieldValue('FREQUENCY');
  const dutyPercent = Blockly.Arduino.valueToCode(this, 'DUTY', Blockly.Arduino.ORDER_ATOMIC);
  const maxDuty = `(1 << ${resolution}) - 1`;
  const duty = dutyPercent;
  const pin = Blockly.Arduino.valueToCode(this, 'PIN', Blockly.Arduino.ORDER_ATOMIC) || '2';

  // 添加PWM初始化代码到setup
  Blockly.Arduino.setups_[`pwm_setup_${safeChannel}`] = `ledcSetup(${safeChannel}, ${frequency}, ${resolution});`;
  Blockly.Arduino.setups_[`pwm_attach_${safeChannel}`] = `ledcAttachPin(${pin}, ${safeChannel});`;

  // 返回占空比设置代码
  return `ledcWrite(${safeChannel}, ${duty});`;
};
Blockly.Arduino.forBlock['set_esp32_pwm_2'] = function() {
  const model = this.getFieldValue('MODEL');
  const channelStr = this.getFieldValue('CHANNEL');
  const channel = parseInt(channelStr);
  let maxChannel;
  switch(model) {
    case 'esp32c3':
      maxChannel = 5; // ESP32-C3有6个通道(0-5)
      break;
    case 'esp32s3':
      maxChannel = 7; // ESP32-S3有8个通道(0-7)
      break;
    default:
      maxChannel = 15; // ESP32/ESP32-S2有16个通道(0-15)
  }
  const safeChannel = Math.min(channel, maxChannel);
  const frequency = this.getFieldValue('FREQUENCY');
  const dutyPercent = Blockly.Arduino.valueToCode(this, 'DUTY', Blockly.Arduino.ORDER_ATOMIC);
  const maxDuty = 255; // 8位分辨率最大值为255
  const duty = `map(${dutyPercent}, 0, 100, 0, ${maxDuty})`;
  const pin = Blockly.Arduino.valueToCode(this, 'PIN', Blockly.Arduino.ORDER_ATOMIC) || '2';
  // 添加PWM初始化代码到setup
  Blockly.Arduino.setups_[`pwm_setup_${safeChannel}`] = `ledcSetup(${safeChannel}, ${frequency}, 8);`;
  Blockly.Arduino.setups_[`pwm_attach_${safeChannel}`] = `ledcAttachPin(${pin}, ${safeChannel});`;

  // 返回占空比设置代码
  return `ledcWrite(${safeChannel}, ${duty});`;
};


Blockly.Arduino.forBlock['make_arduino_restart_begin'] = function() {

    return 'ESP.restart();';
};


Blockly.Arduino.forBlock['make_arduino_softserial_init'] = function(block) {
    var serialName = this.getFieldValue('SERIAL_NAME');
    var baudRate = this.getFieldValue('BAUD_RATE');
    var rxPin = Blockly.Arduino.valueToCode(this, 'RX_PIN', Blockly.Arduino.ORDER_ATOMIC) || '2';
    var txPin = Blockly.Arduino.valueToCode(this, 'TX_PIN', Blockly.Arduino.ORDER_ATOMIC) || '3';

    Blockly.Arduino.definitions_['include_softwareserial'] = '#include <SoftwareSerial.h>';
    
    Blockly.Arduino.definitions_['var_declare_' + serialName] = 
        `SoftwareSerial ${serialName}(${rxPin}, ${txPin});`;

    Blockly.Arduino.setups_['setup_' + serialName + '_begin'] = 
        `${serialName}.begin(${baudRate});`;

    return '';
};


    // 串口输出十六进制值的代码生成逻辑
    Blockly.Arduino.forBlock['make_arduino_serial_hex_write'] = function(block) {
      // 获取用户选择的串口端口
      var serialPort = this.getFieldValue('SERIAL_PORT');
      var dataType = this.getFieldValue('DATA_TYPE');
      var lineBreak = this.getFieldValue('LINE_BREAK');
      // 使用valueToCode获取值输入（支持阴影输入和积木连接）
      var hexData = Blockly.Arduino.valueToCode(this, 'HEX_DATA', Blockly.Arduino.ORDER_ATOMIC) || '"FF1F34AF"';
      var code = '';

      if (dataType === 'HEX') {
        // 十六进制模式：生成循环发送字节的代码
        code += `{
  String hexStr = String(${hexData});
  hexStr.replace(" ", "");
  for (int i = 0; i < hexStr.length(); i += 2) {
    String byteStr = hexStr.substring(i, i + 2);
    if (byteStr.length() == 2) {
      ${serialPort}.write((byte)strtol(byteStr.c_str(), NULL, 16));
    }
  }\n`;
        // 如果选择换行，在所有字节发送完成后添加回车和换行符
        if (lineBreak === 'NEWLINE') {
          code += `  ${serialPort}.write(0x0D);\n`;
          code += `  ${serialPort}.write(0x0A);\n`;
        }
        code += '}\n';
      } else {
        // 字符模式：生成带空格分隔的字符串并使用Serial.print输出
        if (lineBreak === 'NEWLINE') {
          code += `${serialPort}.println(${hexData});\n`;
        } else {
          code += `${serialPort}.print(${hexData});\n`;
        }
      }
      const setupKey = `setup_${serialPort}_begin`;
      if (!Blockly.Arduino.setups_[setupKey]) {
        Blockly.Arduino.setups_[setupKey] = `${serialPort}.begin(9600);`; // 默认波特率9600
      }

      // 返回生成的代码
      return code;
    };
// 设置按键防抖代码生成器
Blockly.Arduino.forBlock['make_arduino_onebutton_setdebounce'] = function(block) {
  var pin_number = Blockly.Arduino.valueToCode(this, 'pin_number', Blockly.Arduino.ORDER_ATOMIC) || '2';
  var debounce_ms = Blockly.Arduino.valueToCode(this, 'debounce_ms', Blockly.Arduino.ORDER_ATOMIC) || '50';
  
  // 根据引脚号生成按钮变量名
  var button_name = 'button' + pin_number;
  

  // 在setup中添加代码
  var setupCode = button_name + '.setDebounceMs(' + debounce_ms + ');';
  Blockly.Arduino.setups_['setup_' + button_name + '_debounce'] = setupCode;
  
  return '';
};

// 设置单击生效时长代码生成器
Blockly.Arduino.forBlock['make_arduino_onebutton_setclickms'] = function(block) {
  var pin_number = Blockly.Arduino.valueToCode(this, 'pin_number', Blockly.Arduino.ORDER_ATOMIC) || '2';
  var click_ms = Blockly.Arduino.valueToCode(this, 'click_ms', Blockly.Arduino.ORDER_ATOMIC) || '400';
  
  // 根据引脚号生成按钮变量名
  var button_name = 'button' + pin_number;
  

  // 在setup中添加代码
  var setupCode = button_name + '.setClickMs(' + click_ms + ');';
  Blockly.Arduino.setups_['setup_' + button_name + '_click'] = setupCode;
  
  return '';
};

// 设置长按生效时长代码生成器
Blockly.Arduino.forBlock['make_arduino_onebutton_setpressms'] = function(block) {
  var pin_number = Blockly.Arduino.valueToCode(this, 'pin_number', Blockly.Arduino.ORDER_ATOMIC) || '2';
  var press_ms = Blockly.Arduino.valueToCode(this, 'press_ms', Blockly.Arduino.ORDER_ATOMIC) || '800';
  
  // 根据引脚号生成按钮变量名
  var button_name = 'button' + pin_number;
  
 
  // 在setup中添加代码
  var setupCode = button_name + '.setPressMs(' + press_ms + ');';
  Blockly.Arduino.setups_['setup_' + button_name + '_press'] = setupCode;
  
  return '';
};


// 获取引脚是否在长按代码生成器
Blockly.Arduino.forBlock['make_arduino_onebutton_islongpressed'] = function(block) {
  var pin_number = Blockly.Arduino.valueToCode(this, 'pin_number', Blockly.Arduino.ORDER_ATOMIC) || '2';
  
  // 根据引脚号生成按钮变量名
  var button_name = 'button' + pin_number;

  var code = button_name + '.isLongPressed()';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

// 多次点击回调代码生成器
Blockly.Arduino.forBlock['make_arduino_onebutton_multiclick'] = function(block) {
  var pin_number = Blockly.Arduino.valueToCode(this, 'pin_number', Blockly.Arduino.ORDER_ATOMIC) || '2';
  var click_count = Blockly.Arduino.valueToCode(this, 'click_count', Blockly.Arduino.ORDER_ATOMIC) || '3';
  var statements_callback = Blockly.Arduino.statementToCode(block, 'callback');
  
  // 根据引脚号生成按钮变量名和回调函数名
  var button_name = 'button' + pin_number;
  var callback_name = 'onebutton_' + button_name + '_multiclick';
  
  // 添加头文件
  Blockly.Arduino.definitions_['include_onebutton'] = '#include <OneButton.h>';
  
  // 定义按钮对象
  Blockly.Arduino.definitions_['var_' + button_name] = 'OneButton ' + button_name + ';';
  
  // 定义回调函数
  var callbackCode = 'void ' + callback_name + '() {\n';
  callbackCode += '  int clicks = ' + button_name + '.getNumberClicks();\n';
  callbackCode += '  if (' + click_count + ' == clicks) {\n';
  callbackCode += statements_callback;
  callbackCode += '  }\n';
  callbackCode += '}\n';
  Blockly.Arduino.definitions_[callback_name] = callbackCode;
  
  // 在setup中添加代码
  var setupCode = button_name + '.setup(' + pin_number + ', INPUT, true);\n';
  setupCode += button_name + '.attachMultiClick(' + callback_name + ');';
  Blockly.Arduino.setups_['setup_' + button_name] = setupCode;
  
  // 返回loop代码
  return button_name + '.tick();\n';
};

// 获取按键点击次数代码生成器
Blockly.Arduino.forBlock['make_arduino_onebutton_getnumberclicks'] = function(block) {
  var pin_number = Blockly.Arduino.valueToCode(this, 'pin_number', Blockly.Arduino.ORDER_ATOMIC) || '2';
  
  // 根据引脚号生成按钮变量名
  var button_name = 'button' + pin_number;
  
  // 生成代码
  var code = button_name + '.getNumberClicks()';
  
  // 返回代码和优先级
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['lists_create_with_1'] = function () {
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');
    var text_lists_create_length = this.getFieldValue('lists_create_length');

    Blockly.Arduino.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + text_lists_create_length + '];';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['lists_create_with_1_change1'] = function () {
    var value_list_data = Blockly.Arduino.valueToCode(this, 'list_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');

    Blockly.Arduino.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + value_list_data + '];';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['part_lists_create_with_1'] = function () {
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');
    var text_lists_create_length = this.getFieldValue('lists_create_length');
    var code = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + text_lists_create_length + '];\n';
    return code;
};

Blockly.Arduino.forBlock['part_lists_create_with_1_change1'] = function () {
    var value_list_data = Blockly.Arduino.valueToCode(this, 'list_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');

    var code = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + value_list_data + '];\n';
    return code;
};

Blockly.Arduino.forBlock['char_lists_create_with_1'] = function () {
    var value_list_data = Blockly.Arduino.valueToCode(this, 'list_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');

    Blockly.Arduino.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[] = ' + value_list_data + ';';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['part_char_lists_create_with_1'] = function () {
    var value_list_data = Blockly.Arduino.valueToCode(this, 'list_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');

    var code = dropdown_lists_create_type + ' ' + text_lists_create_name + '[] = ' + value_list_data + ';\n';
    return code;
};

Blockly.Arduino.forBlock['part_lists_create_with'] = function () {
    // Create a list with any number of elements of any type.
    var dropdown_type = this.getFieldValue('TYPE');
    var varName = Blockly.Arduino.variableDB_.getName(this.getFieldValue('VAR'),
        Blockly.Variables.NAME_TYPE);
    var code = new Array(this.itemCount_);
    for (var n = 0; n < this.itemCount_; n++) {
        code[n] = Blockly.Arduino.valueToCode(this, 'ADD' + n,
            Blockly.Arduino.ORDER_NONE) || '0';
    }
    var code = dropdown_type + ' ' + varName + '[]' + '=' + '{' + code.join(', ') + '};\n';
    //var code =''+varName+'['+size+"]"+'='+ '{' + code.join(', ') + '};\n';
    //Blockly.Arduino.setups_['setup_lists'+varName] = code;
    return code;
};

Blockly.Arduino.forBlock['part_lists_create_with_text'] = function () {
    var dropdown_type = this.getFieldValue('TYPE');
    var varName = Blockly.Arduino.variableDB_.getName(this.getFieldValue('VAR'),
        Blockly.Variables.NAME_TYPE);
    var text_lists_num = this.getFieldValue('lists_num');
    var text = this.getFieldValue('TEXT');
    var code = dropdown_type + ' ' + varName + '[' + text_lists_num + ']' + '=' + '{' + text + '};\n';
    return code;
};

Blockly.Arduino.forBlock['lists_with_1_get_data'] = function () {
    var value_lists_x = Blockly.Arduino.valueToCode(this, 'lists_x', Blockly.Arduino.ORDER_ATOMIC);
    var text_list_name = this.getFieldValue('list_name');
    var value_lists_data = Blockly.Arduino.valueToCode(this, 'lists_data', Blockly.Arduino.ORDER_ATOMIC);

    var code = text_list_name + '[' + value_lists_x + '] = ' + value_lists_data + ';\n';

    return code;
};

Blockly.Arduino.forBlock['lists_with_1_return_data'] = function () {
    var value_lists_x = Blockly.Arduino.valueToCode(this, 'lists_x', Blockly.Arduino.ORDER_ATOMIC);
    var text_list_name = this.getFieldValue('list_name');
    var code = text_list_name + '[' + value_lists_x + ']';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['lists_create_with_2'] = function () {
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');
    var text_lists_create_length_1 = this.getFieldValue('lists_create_length_1');
    var text_lists_create_length_2 = this.getFieldValue('lists_create_length_2');

    Blockly.Arduino.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + text_lists_create_length_1 + '][' + text_lists_create_length_2 + '];';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['lists_create_with_2_change1'] = function () {
    var value_lists_data1 = Blockly.Arduino.valueToCode(this, 'lists_data1', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');
    var value_lists_data2 = Blockly.Arduino.valueToCode(this, 'lists_data2', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + value_lists_data1 + '][' + value_lists_data2 + '];';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['part_lists_create_with_2'] = function () {
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');
    var text_lists_create_length_1 = this.getFieldValue('lists_create_length_1');
    var text_lists_create_length_2 = this.getFieldValue('lists_create_length_2');

    var code = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + text_lists_create_length_1 + '][' + text_lists_create_length_2 + '];\n';

    return code;
};

Blockly.Arduino.forBlock['part_lists_create_with_2_change1'] = function () {
    var value_lists_data1 = Blockly.Arduino.valueToCode(this, 'lists_data1', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');
    var value_lists_data2 = Blockly.Arduino.valueToCode(this, 'lists_data2', Blockly.Arduino.ORDER_ATOMIC);

    var code = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + value_lists_data1 + '][' + value_lists_data2 + '];\n';

    return code;
};

Blockly.Arduino.forBlock['lists_create_with_2_1'] = function () {
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');
    var statements_lists_with_2_1_data = Blockly.Arduino.statementToCode(this, 'lists_with_2_1_data');

    if (statements_lists_with_2_1_data) {
        var num_x = 0;
        var num_y_data = '';
        var num_y = 0;
        var data = '';
        var choice = false;
        var statements_lists_with_2_1_data1 = '';
        statements_lists_with_2_1_data = statements_lists_with_2_1_data.substring(2, statements_lists_with_2_1_data.length - 1);
        for (var i of statements_lists_with_2_1_data) {
            if (i == '→') {
                statements_lists_with_2_1_data1 += '\n  ';
                choice = true;
                continue;
            }
            if (choice) {
                if (i == '{') {
                    if (num_y < num_y_data - 0)
                        num_y = num_y_data - 0;
                    num_y_data = '';
                    choice = false;
                }
                else {
                    num_y_data = num_y_data + i;
                    continue;
                }
            }
            data = data + i;
            if (data == '},{')
                num_x++;
            if (data.length == 3) {
                data = data.substring(1, 2) + i;
            }
            statements_lists_with_2_1_data1 = statements_lists_with_2_1_data1 + i;
        }
        num_x++;
        /*
        var num_y_1 = 0;
        var num_y_1_old = 0;
        for(var i of statements_lists_with_2_1_data1)
        {
          if(i == '{')
            num_y_1 = 0;
          else if(i == '}')
            if(num_y_1_old < num_y_1)
            {
              num_y_1_old = num_y_1;
            }
          else if(i == ',')
            num_y_1++;
        }
        num_y_1 = num_y_1_old + 1;
        */
        Blockly.Arduino.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + num_x + '][' + num_y + '] = {' + statements_lists_with_2_1_data1 + '\n};';
    }
    else {
        if (dropdown_lists_create_type == 'String')
            Blockly.Arduino.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[2][2] = {{"0","0"},{"0","0"}};';
        else
            Blockly.Arduino.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[2][2] = {{0,0},{0,0}};';
    }

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['part_lists_create_with_2_1'] = function () {
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');
    var statements_lists_with_2_1_data = Blockly.Arduino.statementToCode(this, 'lists_with_2_1_data');

    var code = '';
    if (statements_lists_with_2_1_data) {
        var num_x = 0;
        var num_y_data = '';
        var num_y = 0;
        var data = '';
        var choice = false;
        var statements_lists_with_2_1_data1 = '';
        statements_lists_with_2_1_data = statements_lists_with_2_1_data.substring(2, statements_lists_with_2_1_data.length - 1);
        for (var i of statements_lists_with_2_1_data) {
            if (i == '→') {
                statements_lists_with_2_1_data1 += '\n  ';
                choice = true;
                continue;
            }
            if (choice) {
                if (i == '{') {
                    if (num_y < num_y_data - 0)
                        num_y = num_y_data - 0;
                    num_y_data = '';
                    choice = false;
                }
                else {
                    num_y_data = num_y_data + i;
                    continue;
                }
            }
            data = data + i;
            if (data == '},{')
                num_x++;
            if (data.length == 3) {
                data = data.substring(1, 2) + i;
            }
            statements_lists_with_2_1_data1 = statements_lists_with_2_1_data1 + i;
        }
        num_x++;

        /*
        var num_y_1 = 0;
        var num_y_1_old = 0;
        for(var i of statements_lists_with_2_1_data1)
        {
          if(i == '{')
            num_y_1 = 0;
          else if(i == '}')
            if(num_y_1_old < num_y_1)
            {
              num_y_1_old = num_y_1;
            }
          else if(i == ',')
            num_y_1++;
        }
        num_y_1 = num_y_1_old + 1;
        */
        code = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + num_x + '][' + num_y + '] = {' + statements_lists_with_2_1_data1 + '\n};\n';
    }
    else {
        if (dropdown_lists_create_type == 'String')
            code = dropdown_lists_create_type + ' ' + text_lists_create_name + '[2][2] = {{"0","0"},{"0","0"}};\n';
        else
            code = dropdown_lists_create_type + ' ' + text_lists_create_name + '[2][2] = {{0,0},{0,0}};\n';
    }

    return code;
};

Blockly.Arduino.forBlock['lists_create_with_2_1_new_2019_10_18'] = function () {
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');
    var text_lists_num_1 = this.getFieldValue('lists_num_1');
    var text_lists_num_2 = this.getFieldValue('lists_num_2');
    var statements_lists_with_2_1_data = Blockly.Arduino.statementToCode(this, 'lists_with_2_1_data');

    if (statements_lists_with_2_1_data) {
        var num_x = 0;
        var num_y_data = '';
        var num_y = 0;
        var data = '';
        var choice = false;
        var statements_lists_with_2_1_data1 = '';
        statements_lists_with_2_1_data = statements_lists_with_2_1_data.substring(2, statements_lists_with_2_1_data.length - 1);
        for (var i of statements_lists_with_2_1_data) {
            if (i == '→') {
                statements_lists_with_2_1_data1 += '\n  ';
                choice = true;
                continue;
            }
            if (choice) {
                if (i == '{') {
                    if (num_y < num_y_data - 0)
                        num_y = num_y_data - 0;
                    num_y_data = '';
                    choice = false;
                }
                else {
                    num_y_data = num_y_data + i;
                    continue;
                }
            }
            data = data + i;
            if (data == '},{')
                num_x++;
            if (data.length == 3) {
                data = data.substring(1, 2) + i;
            }
            statements_lists_with_2_1_data1 = statements_lists_with_2_1_data1 + i;
        }
        num_x++;
        Blockly.Arduino.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + text_lists_num_1 + '][' + text_lists_num_2 + '] = {' + statements_lists_with_2_1_data1 + '\n};';
    }
    else {
        if (dropdown_lists_create_type == 'String')
            Blockly.Arduino.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[2][2] = {{"0","0"},{"0","0"}};';
        else
            Blockly.Arduino.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[2][2] = {{0,0},{0,0}};';
    }

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['part_lists_create_with_2_1_new_2019_10_18'] = function () {
    var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
    var text_lists_create_name = this.getFieldValue('lists_create_name');
    var text_lists_num_1 = this.getFieldValue('lists_num_1');
    var text_lists_num_2 = this.getFieldValue('lists_num_2');
    var statements_lists_with_2_1_data = Blockly.Arduino.statementToCode(this, 'lists_with_2_1_data');

    var code = '';
    if (statements_lists_with_2_1_data) {
        var num_x = 0;
        var num_y_data = '';
        var num_y = 0;
        var data = '';
        var choice = false;
        var statements_lists_with_2_1_data1 = '';
        statements_lists_with_2_1_data = statements_lists_with_2_1_data.substring(2, statements_lists_with_2_1_data.length - 1);
        for (var i of statements_lists_with_2_1_data) {
            if (i == '→') {
                statements_lists_with_2_1_data1 += '\n  ';
                choice = true;
                continue;
            }
            if (choice) {
                if (i == '{') {
                    if (num_y < num_y_data - 0)
                        num_y = num_y_data - 0;
                    num_y_data = '';
                    choice = false;
                }
                else {
                    num_y_data = num_y_data + i;
                    continue;
                }
            }
            data = data + i;
            if (data == '},{')
                num_x++;
            if (data.length == 3) {
                data = data.substring(1, 2) + i;
            }
            statements_lists_with_2_1_data1 = statements_lists_with_2_1_data1 + i;
        }
        num_x++;
        code = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + text_lists_num_1 + '][' + text_lists_num_2 + '] = {' + statements_lists_with_2_1_data1 + '\n};\n';
    }
    else {
        if (dropdown_lists_create_type == 'String')
            code = dropdown_lists_create_type + ' ' + text_lists_create_name + '[2][2] = {{"0","0"},{"0","0"}};\n';
        else
            code = dropdown_lists_create_type + ' ' + text_lists_create_name + '[2][2] = {{0,0},{0,0}};\n';
    }

    return code;
};

Blockly.Arduino.forBlock['lists_create_with_2_1_get_data'] = function () {
    // Create a list with any number of elements of any type.
    var code = new Array(this.itemCount_);
    for (var n = 0; n < this.itemCount_; n++) {
        code[n] = Blockly.Arduino.valueToCode(this, 'ADD' + n,
            Blockly.Arduino.ORDER_NONE) || '0';
    }
    var code1 = '';
    var surround_parent = this.getSurroundParent();
    if (surround_parent && surround_parent.type == 'lists_create_with_2_1') {
        for (var n = 0; n < this.itemCount_; n++) {
            code1 = code1 + ', ' + code[n];
        }
        code1 = code1.substring(2);
        code1 = '→' + this.itemCount_ + '{' + code1 + '},';
    }
    else if (surround_parent && surround_parent.type == 'part_lists_create_with_2_1') {
        for (var n = 0; n < this.itemCount_; n++) {
            code1 = code1 + ', ' + code[n];
        }
        code1 = code1.substring(2);
        code1 = '→' + this.itemCount_ + '{' + code1 + '},';
    }
    else if (surround_parent && surround_parent.type == 'lists_create_with_2_1_new_2019_10_18') {
        for (var n = 0; n < this.itemCount_; n++) {
            code1 = code1 + ', ' + code[n];
        }
        code1 = code1.substring(2);
        code1 = '→' + this.itemCount_ + '{' + code1 + '},';
    }
    else if (surround_parent && surround_parent.type == 'part_lists_create_with_2_1_new_2019_10_18') {
        for (var n = 0; n < this.itemCount_; n++) {
            code1 = code1 + ', ' + code[n];
        }
        code1 = code1.substring(2);
        code1 = '→' + this.itemCount_ + '{' + code1 + '},';
    }
    else {
        code1 = '';
    }

    //var code =''+varName+'['+size+"]"+'='+ '{' + code.join(', ') + '};\n';
    //Blockly.Arduino.setups_['setup_lists'+varName] = code;
    return code1;
};

//获取二维数组的行数与列数
Blockly.Arduino.forBlock['lists_with_2_get_length'] = function () {
    var text_list_name = this.getFieldValue('list_name');
    var dropdown_type = this.getFieldValue('type');

    var code = '';
    if (dropdown_type == 'col')
        code = '(sizeof(' + text_list_name + '[0]) / sizeof(' + text_list_name + '[0][0]))';
    else
        code = '(sizeof(' + text_list_name + ') / sizeof(' + text_list_name + '[0]))';

    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['lists_with_2_get_data'] = function () {
    var value_lists_x = Blockly.Arduino.valueToCode(this, 'lists_x', Blockly.Arduino.ORDER_ATOMIC);
    var text_list_name = this.getFieldValue('list_name');
    var value_lists_y = Blockly.Arduino.valueToCode(this, 'lists_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_lists_data = Blockly.Arduino.valueToCode(this, 'lists_data', Blockly.Arduino.ORDER_ATOMIC);

    var code = text_list_name + '[' + value_lists_x + '][' + value_lists_y + '] = ' + value_lists_data + ';\n';

    return code;
};

Blockly.Arduino.forBlock['lists_with_2_return_data'] = function () {
    var value_lists_x = Blockly.Arduino.valueToCode(this, 'lists_x', Blockly.Arduino.ORDER_ATOMIC);
    var text_list_name = this.getFieldValue('list_name');
    var value_lists_y = Blockly.Arduino.valueToCode(this, 'lists_y', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_list_name + '[' + value_lists_x + '][' + value_lists_y + ']';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//变量定义
Blockly.Arduino.forBlock['make_arduino_variate'] = function () {
    var dropdown_variate_type = this.getFieldValue('variate_type');
    var code = dropdown_variate_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//获取某个变量在内存中所占用的字节数
Blockly.Arduino.forBlock['math_sizeof'] = function () {
    this.setTooltip("以字节形式返回某个操作数的储存大小");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'sizeof(' + value_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
//取反
Blockly.Arduino.forBlock['math_negation'] = function() {
  var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
  var code = '~('+value_data+')';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};
*/

//加法
Blockly.Arduino.forBlock['math_add'] = function () {
    // Create a list with any number of elements of any type.
    var dropdown_math_add_type = this.getFieldValue('math_add_type');
    var code = new Array(this.itemCount_);
    for (var n = 0; n < this.itemCount_; n++) {
        code[n] = Blockly.Arduino.valueToCode(this, 'ADD' + n,
            Blockly.Arduino.ORDER_NONE) || '1';
    }

    var code1 = '';
    if (dropdown_math_add_type == '+') {
        for (var n = 0; n < this.itemCount_; n++) {
            var i1 = 0;
            for (var i of code[n]) {
                i1++;
                if (i == '+' || i == '-' || i == '×' || i == '÷' || i == '%' || i == '^') {
                    break;
                }
            }
            if (i1 == code[n].length) code1 = code1 + ' + ' + code[n];
            else code1 = code1 + ' + (' + code[n] + ')';
        }
    }
    else if (dropdown_math_add_type == '-') {
        for (var n = 0; n < this.itemCount_; n++) {
            var i1 = 0;
            for (var i of code[n]) {
                i1++;
                if (i == '+' || i == '-' || i == '×' || i == '÷' || i == '%' || i == '^') {
                    break;
                }
            }
            if (i1 == code[n].length) code1 = code1 + ' - ' + code[n];
            else code1 = code1 + ' - (' + code[n] + ')';
        }
    }
    else if (dropdown_math_add_type == '×') {
        for (var n = 0; n < this.itemCount_; n++) {
            var i1 = 0;
            for (var i of code[n]) {
                i1++;
                if (i == '+' || i == '-' || i == '×' || i == '÷' || i == '%' || i == '^') {
                    break;
                }
            }
            if (i1 == code[n].length) code1 = code1 + ' × ' + code[n];
            else code1 = code1 + ' × (' + code[n] + ')';
        }
    }
    else {
        for (var n = 0; n < this.itemCount_; n++) {
            var i1 = 0;
            for (var i of code[n]) {
                i1++;
                if (i == '+' || i == '-' || i == '×' || i == '÷' || i == '%' || i == '^') {
                    break;
                }
            }
            if (i1 == code[n].length) code1 = code1 + ' ÷ ' + code[n];
            else code1 = code1 + ' ÷ (' + code[n] + ')';
        }
    }
    code1 = '(' + code1.substring(3) + ')';
    //var code =''+varName+'['+size+"]"+'='+ '{' + code.join(', ') + '};\n';
    //Blockly.Arduino.setups_['setup_lists'+varName] = code;
    return [code1, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['math_operation'] = function () {
    var value_math_operation_output = Blockly.Arduino.valueToCode(this, 'math_operation_output', Blockly.Arduino.ORDER_ATOMIC);
    var value_math_operation_input = Blockly.Arduino.valueToCode(this, 'math_operation_input', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_math_operation_type = this.getFieldValue('math_operation_type');

    var code = '';
    if (value_math_operation_output == '' || value_math_operation_input == '') {
        code = '';
        this.setWarningText("缺少输入值，无法生成对应代码");
    }
    else {
        code = value_math_operation_output + ' ' + dropdown_math_operation_type + ' ' + value_math_operation_input + ';\n';
        this.setWarningText(null);
    }
    return code;
};

Blockly.Arduino.forBlock['math_auto_add_minus'] = function () {
    var value_math_auto_add_minus_output = Blockly.Arduino.valueToCode(this, 'math_auto_add_minus_output', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_math_auto_add_minus_type = this.getFieldValue('math_auto_add_minus_type');

    var code = '';
    if (value_math_auto_add_minus_output == '') {
        code = '';
        this.setWarningText("缺少输入值，无法生成对应代码");
    }
    else {
        code = value_math_auto_add_minus_output + dropdown_math_auto_add_minus_type + ';\n';
        this.setWarningText(null);
    }
    return code;
};

Blockly.Arduino.forBlock['math_operation_1'] = function () {
    var value_math_operation_output = Blockly.Arduino.valueToCode(this, 'math_operation_output', Blockly.Arduino.ORDER_ATOMIC);
    var value_math_operation_input = Blockly.Arduino.valueToCode(this, 'math_operation_input', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_math_operation_type = this.getFieldValue('math_operation_type');

    var code = '';
    if (value_math_operation_output == '' || value_math_operation_input == '') {
        code = '';
        this.setWarningText("缺少输入值，无法生成对应代码");
    }
    else {
        code = value_math_operation_output + ' ' + dropdown_math_operation_type + ' ' + value_math_operation_input + '';
        this.setWarningText(null);
    }
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['math_auto_add_minus_1'] = function () {
    var value_math_auto_add_minus_output = Blockly.Arduino.valueToCode(this, 'math_auto_add_minus_output', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_math_auto_add_minus_type = this.getFieldValue('math_auto_add_minus_type');

    var code = '';
    if (value_math_auto_add_minus_output == '') {
        code = '';
        this.setWarningText("缺少输入值，无法生成对应代码");
    }
    else {
        code = value_math_auto_add_minus_output + dropdown_math_auto_add_minus_type + '';
        this.setWarningText(null);
    }
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['math_map_float'] = function () {
    this.setTooltip(
        "将一个小数从第一个区间映射到第二个区间，并返回映射之后的值，返回数据的类型为float"
    );

    var value_x = Blockly.Arduino.valueToCode(this, 'x', Blockly.Arduino.ORDER_ATOMIC);
    var value_in_min = Blockly.Arduino.valueToCode(this, 'in_min', Blockly.Arduino.ORDER_ATOMIC);
    var value_in_max = Blockly.Arduino.valueToCode(this, 'in_max', Blockly.Arduino.ORDER_ATOMIC);
    var value_out_min = Blockly.Arduino.valueToCode(this, 'out_min', Blockly.Arduino.ORDER_ATOMIC);
    var value_out_max = Blockly.Arduino.valueToCode(this, 'out_max', Blockly.Arduino.ORDER_ATOMIC);

    if (value_x == '') value_x = '10.00';

    Blockly.Arduino.definitions_['function_mapfloat'] = 'float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)'
        + '\n{'
        + '\n  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;'
        + '\n}';
    var code = 'mapfloat(' + value_x + ', ' + value_in_min + ', ' + value_in_max + ', ' + value_out_min + ', ' + value_out_max + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//atan2(a, b)
Blockly.Arduino.forBlock['math_atan2'] = function () {
    this.setTooltip("atan2(y,x):返回(0,0)与(x,y)构成的线段在坐标平面上与x轴正方向之间夹角，返回的弧度值介于-π到π之间(不包括-π)");
    var value_a = Blockly.Arduino.valueToCode(this, 'a', Blockly.Arduino.ORDER_ATOMIC);
    var value_b = Blockly.Arduino.valueToCode(this, 'b', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'atan2 (' + value_a + ', ' + value_b + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//获取一个数据的最低位或第二低位的字节数据
Blockly.Arduino.forBlock['math_lowByte_highByte'] = function () {
    this.setTooltip("获取变量的最低位或第二低位的字节数据");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type + '(' + value_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//获取一个数据的某个位的值
Blockly.Arduino.forBlock['math_bitRead'] = function () {
    this.setTooltip("获取变量的某个位的值");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_bit = Blockly.Arduino.valueToCode(this, 'bit', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'bitRead(' + value_data + ', ' + value_bit + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//设置数据某个位的值
Blockly.Arduino.forBlock['math_bitWrite'] = function () {
    this.setTooltip("设置数据某个位的值");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_bit = Blockly.Arduino.valueToCode(this, 'bit', Blockly.Arduino.ORDER_ATOMIC);
    var value_set = Blockly.Arduino.valueToCode(this, 'set', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'bitWrite(' + value_data + ', ' + value_bit + ', ' + value_set + ');\n';
    return code;
};

//对一个数据的某个位置1或置0
Blockly.Arduino.forBlock['math_bitSet_bitClear'] = function () {
    this.setTooltip("对一个数据的某个位置1或置0");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_bit = Blockly.Arduino.valueToCode(this, 'bit', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type + '(' + value_data + ', ' + value_bit + ');\n';
    return code;
};

//计算指定位的值（0位是1，1位是2，2位4，以此类推）
Blockly.Arduino.forBlock['math_Bit'] = function () {
    this.setTooltip("计算指定位的值(0位是1，1位是2，2位4，以此类推)");
    var value_bit = Blockly.Arduino.valueToCode(this, 'bit', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'bit(' + value_bit + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['math_matrix'] = function () {
    var Tooltip_data = "";
    Tooltip_data = "一个矩阵与另一个矩阵进行加、减、乘运算";

    var value_output_matrix = Blockly.Arduino.valueToCode(this, 'output_matrix', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1 = Blockly.Arduino.valueToCode(this, 'input_matrix_1', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_x = Blockly.Arduino.valueToCode(this, 'input_matrix_1_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_y = Blockly.Arduino.valueToCode(this, 'input_matrix_1_y', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_math_matrix_type = this.getFieldValue('math_matrix_type');
    var value_input_matrix_2 = Blockly.Arduino.valueToCode(this, 'input_matrix_2', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_2_x = Blockly.Arduino.valueToCode(this, 'input_matrix_2_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_2_y = Blockly.Arduino.valueToCode(this, 'input_matrix_2_y', Blockly.Arduino.ORDER_ATOMIC);
    if (dropdown_math_matrix_type == '+') {
        if (value_input_matrix_1_x == value_input_matrix_2_x && value_input_matrix_1_y == value_input_matrix_2_y) {
            this.setTooltip(
                Tooltip_data + "\n"
                + value_output_matrix + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "] = "
                + value_input_matrix_1 + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "] + "
                + value_input_matrix_2 + "[" + value_input_matrix_2_x + "][" + value_input_matrix_2_y + "];"
            );
        } else {
            this.setTooltip(
                Tooltip_data + "\n"
                + "输入参数错误!"
            );
        }
    }
    else if (dropdown_math_matrix_type == '-') {
        if (value_input_matrix_1_x == value_input_matrix_2_x && value_input_matrix_1_y == value_input_matrix_2_y) {
            this.setTooltip(
                Tooltip_data + "\n"
                + value_output_matrix + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "] = "
                + value_input_matrix_1 + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "] - "
                + value_input_matrix_2 + "[" + value_input_matrix_2_x + "][" + value_input_matrix_2_y + "];"
            );
        } else {
            this.setTooltip(
                Tooltip_data + "\n"
                + "输入参数错误!"
            );
        }
    }
    else {
        if (value_input_matrix_1_y == value_input_matrix_2_x) {
            this.setTooltip(
                Tooltip_data + "\n"
                + value_output_matrix + "[" + value_input_matrix_1_x + "][" + value_input_matrix_2_y + "] = "
                + value_input_matrix_1 + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "] × "
                + value_input_matrix_2 + "[" + value_input_matrix_2_x + "][" + value_input_matrix_2_y + "];"
            );
        }
        else {
            this.setTooltip(
                Tooltip_data + "\n"
                + "输入参数错误!"
            );
        }
    }

    Blockly.Arduino.definitions_['include_MatrixMath'] = '#include <MatrixMath.h>';

    var code = '';
    if (dropdown_math_matrix_type == '+') {
        if (value_input_matrix_1_x == value_input_matrix_2_x && value_input_matrix_1_y == value_input_matrix_2_y) {
            this.setWarningText(null);
            code = 'Matrix.Add((float*)' + value_input_matrix_1 + ', (float*) ' + value_input_matrix_2 + ', ' + value_input_matrix_1_x + ', ' + value_input_matrix_1_y + ', (float*) ' + value_output_matrix + ');\n';
        } else {
            code = '';
            this.setWarningText("由于矩阵" + value_input_matrix_1 + "的行列值不等于矩阵" + value_input_matrix_2 + "的行列值,所以无法生成代码;请修改输入值");
        }
    }
    else if (dropdown_math_matrix_type == '-') {
        if (value_input_matrix_1_x == value_input_matrix_2_x && value_input_matrix_1_y == value_input_matrix_2_y) {
            this.setWarningText(null);
            code = 'Matrix.Subtract((float*)' + value_input_matrix_1 + ', (float*) ' + value_input_matrix_2 + ', ' + value_input_matrix_1_x + ', ' + value_input_matrix_1_y + ', (float*) ' + value_output_matrix + ');\n';
        } else {
            code = '';
            this.setWarningText("由于矩阵" + value_input_matrix_1 + "的行列值不等于矩阵" + value_input_matrix_2 + "的行列值,所以无法生成代码;请修改输入值");
        }
    }
    else {
        if (value_input_matrix_1_y == value_input_matrix_2_x) {
            this.setWarningText(null);
            code = 'Matrix.Multiply((float*)' + value_input_matrix_1 + ', (float*) ' + value_input_matrix_2 + ', ' + value_input_matrix_1_x + ', ' + value_input_matrix_1_y + ', ' + value_input_matrix_2_y + ', (float*) ' + value_output_matrix + ');\n';
        }
        else {
            code = '';
            this.setWarningText("由于矩阵" + value_input_matrix_1 + "的列值不等于矩阵" + value_input_matrix_2 + "的行值,所以无法生成代码;请修改输入值");
        }
    }

    return code;
};

Blockly.Arduino.forBlock['math_matrix_Scale'] = function () {
    var value_input_matrix_1 = Blockly.Arduino.valueToCode(this, 'input_matrix_1', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_x = Blockly.Arduino.valueToCode(this, 'input_matrix_1_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_y = Blockly.Arduino.valueToCode(this, 'input_matrix_1_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_data = Blockly.Arduino.valueToCode(this, 'input_matrix_data', Blockly.Arduino.ORDER_ATOMIC);

    var Tooltip_data = "";
    Tooltip_data = "矩阵与一个数做乘法运算\n";

    this.setTooltip(
        Tooltip_data
        + value_input_matrix_1 + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "] = "
        + value_input_matrix_1 + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "] × "
        + value_input_matrix_data + ";"
    );

    Blockly.Arduino.definitions_['include_MatrixMath'] = '#include <MatrixMath.h>';

    var code = 'Matrix.Scale((float*) ' + value_input_matrix_1 + ', ' + value_input_matrix_1_x + ', ' + value_input_matrix_1_y + ', ' + value_input_matrix_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['math_matrix_copy'] = function () {
    var value_output_matrix = Blockly.Arduino.valueToCode(this, 'output_matrix', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1 = Blockly.Arduino.valueToCode(this, 'input_matrix_1', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_x = Blockly.Arduino.valueToCode(this, 'input_matrix_1_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_y = Blockly.Arduino.valueToCode(this, 'input_matrix_1_y', Blockly.Arduino.ORDER_ATOMIC);

    var Tooltip_data = "";
    Tooltip_data = "将一个矩阵中的数据拷贝到另一个矩阵\n";
    this.setTooltip(
        Tooltip_data
        + value_output_matrix + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "] = "
        + value_input_matrix_1 + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "];"
    );

    Blockly.Arduino.definitions_['include_MatrixMath'] = '#include <MatrixMath.h>';

    var code = 'Matrix.Copy((float*)' + value_input_matrix_1 + ', ' + value_input_matrix_1_x + ', ' + value_input_matrix_1_y + ', (float*)' + value_output_matrix + ');\n';
    return code;
};

Blockly.Arduino.forBlock['math_matrix_Transpose'] = function () {
    var value_output_matrix = Blockly.Arduino.valueToCode(this, 'output_matrix', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1 = Blockly.Arduino.valueToCode(this, 'input_matrix_1', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_x = Blockly.Arduino.valueToCode(this, 'input_matrix_1_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_y = Blockly.Arduino.valueToCode(this, 'input_matrix_1_y', Blockly.Arduino.ORDER_ATOMIC);

    var Tooltip_data = "";
    Tooltip_data = "将一个矩阵转置后赋值给另一个矩阵\n";
    this.setTooltip(
        Tooltip_data
        + value_output_matrix + "[" + value_input_matrix_1_y + "][" + value_input_matrix_1_x + "] = "
        + value_input_matrix_1 + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "]的转置;"
    );

    Blockly.Arduino.definitions_['include_MatrixMath'] = '#include <MatrixMath.h>';

    var code = 'Matrix.Transpose((float*) ' + value_input_matrix_1 + ', ' + value_input_matrix_1_x + ', ' + value_input_matrix_1_y + ', (float*) ' + value_output_matrix + ');\n';
    return code;
};

Blockly.Arduino.forBlock['math_matrix_Invert'] = function () {
    var value_input_matrix_1 = Blockly.Arduino.valueToCode(this, 'input_matrix_1', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_x = Blockly.Arduino.valueToCode(this, 'input_matrix_1_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_y = Blockly.Arduino.valueToCode(this, 'input_matrix_1_y', Blockly.Arduino.ORDER_ATOMIC);

    var Tooltip_data = "";
    Tooltip_data = "求一个矩阵的逆矩阵\n";
    this.setTooltip(
        Tooltip_data
        + value_input_matrix_1 + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "] = "
        + value_input_matrix_1 + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "]^(-1);"
    );

    Blockly.Arduino.definitions_['include_MatrixMath'] = '#include <MatrixMath.h>';

    if (value_input_matrix_1_y == value_input_matrix_1_x) {
        this.setWarningText(null);
        var code = 'Matrix.Invert((float*)' + value_input_matrix_1 + ', ' + value_input_matrix_1_x + ');\n';
    }
    else {
        var code = '';
        this.setWarningText("由于矩阵" + value_input_matrix_1 + "的行值不等于其列值,所以无法生成代码;请修改输入值");
    }
    return code;
};

Blockly.Arduino.forBlock['math_matrix_Invert_change_2020_01_15'] = function () {
    var value_input_matrix_1 = Blockly.Arduino.valueToCode(this, 'input_matrix_1', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_x = Blockly.Arduino.valueToCode(this, 'input_matrix_1_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_y = Blockly.Arduino.valueToCode(this, 'input_matrix_1_y', Blockly.Arduino.ORDER_ATOMIC);

    var Tooltip_data = "";
    Tooltip_data = "求一个矩阵的逆矩阵，返回数据的类型为int\n";
    this.setTooltip(
        Tooltip_data
        + value_input_matrix_1 + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "] = "
        + value_input_matrix_1 + "[" + value_input_matrix_1_x + "][" + value_input_matrix_1_y + "]^(-1);"
    );

    Blockly.Arduino.definitions_['include_MatrixMath'] = '#include <MatrixMath.h>';

    if (value_input_matrix_1_y == value_input_matrix_1_x) {
        this.setWarningText(null);
        var code = 'Matrix.Invert((float*)' + value_input_matrix_1 + ', ' + value_input_matrix_1_x + ')';
    }
    else {
        var code = '';
        this.setWarningText("由于矩阵" + value_input_matrix_1 + "的行值不等于其列值,所以无法生成代码;请修改输入值");
    }
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['math_matrix_Print'] = function () {
    this.setTooltip(
        "串口打印某个矩阵中的数据"
    );

    var value_matrix_Print_data = Blockly.Arduino.valueToCode(this, 'matrix_Print_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1 = Blockly.Arduino.valueToCode(this, 'input_matrix_1', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_x = Blockly.Arduino.valueToCode(this, 'input_matrix_1_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_input_matrix_1_y = Blockly.Arduino.valueToCode(this, 'input_matrix_1_y', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_MatrixMath'] = '#include <MatrixMath.h>';

    var code = 'Matrix.Print((float*)' + value_input_matrix_1 + ', ' + value_input_matrix_1_x + ', ' + value_input_matrix_1_y + ', ' + value_matrix_Print_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['link_text'] = function () {
    // Create a list with any number of elements of any type.
    var code = new Array(this.itemCount_);
    for (var n = 0; n < this.itemCount_; n++) {
        code[n] = Blockly.Arduino.valueToCode(this, 'ADD' + n,
            Blockly.Arduino.ORDER_NONE) || '0';
    }
    var code1 = '';
    for (var n = 0; n < this.itemCount_; n++) {
        code1 = code1 + ' + ' + 'String(' + code[n] + ')';
    }
    code1 = code1.substring(3);
    //var code =''+varName+'['+size+"]"+'='+ '{' + code.join(', ') + '};\n';
    //Blockly.Arduino.setups_['setup_lists'+varName] = code;
    return [code1, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['text_equalsIgnoreCase'] = function () {
    var value_text_equalsIgnoreCase_str1 = Blockly.Arduino.valueToCode(this, 'text_equalsIgnoreCase_str1', Blockly.Arduino.ORDER_ATOMIC);
    var value_text_equalsIgnoreCase_str2 = Blockly.Arduino.valueToCode(this, 'text_equalsIgnoreCase_str2', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'String(' + value_text_equalsIgnoreCase_str1 + ').equalsIgnoreCase(String(' + value_text_equalsIgnoreCase_str2 + '))';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['text_indexOf'] = function () {
    var value_text_indexOf_input_str1 = Blockly.Arduino.valueToCode(this, 'text_indexOf_input_str1', Blockly.Arduino.ORDER_ATOMIC);
    var value_text_indexOf_input_str2 = Blockly.Arduino.valueToCode(this, 'text_indexOf_input_str2', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'String(' + value_text_indexOf_input_str1 + ').indexOf(String(' + value_text_indexOf_input_str2 + '))';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['text_indexOf_1'] = function () {
    var value_text_indexOf_input_str1 = Blockly.Arduino.valueToCode(this, 'text_indexOf_input_str1', Blockly.Arduino.ORDER_ATOMIC);
    var value_text_indexOf_limit = Blockly.Arduino.valueToCode(this, 'text_indexOf_limit', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_text_indexOf_1_type = this.getFieldValue('text_indexOf_1_type');
    var value_text_indexOf_input_str2 = Blockly.Arduino.valueToCode(this, 'text_indexOf_input_str2', Blockly.Arduino.ORDER_ATOMIC);
    if (dropdown_text_indexOf_1_type == 'ahead')
        var code = 'String(' + value_text_indexOf_input_str1 + ').indexOf(String(' + value_text_indexOf_input_str2 + '), ' + value_text_indexOf_limit + ')';
    else
        var code = 'String(' + value_text_indexOf_input_str1 + ').lastIndexOf(String(' + value_text_indexOf_input_str2 + '), ' + value_text_indexOf_limit + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['text_setCharAt'] = function () {
    var value_text_setCharAt_input_data = Blockly.Arduino.valueToCode(this, 'text_setCharAt_input_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_text_setCharAt_find_data = Blockly.Arduino.valueToCode(this, 'text_setCharAt_find_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_text_setCharAt_replace_data = Blockly.Arduino.valueToCode(this, 'text_setCharAt_replace_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'String(' + value_text_setCharAt_input_data + ').setCharAt(' + value_text_setCharAt_find_data + ', ' + value_text_setCharAt_replace_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['text_toCharArray'] = function () {
    var value_text_toCharArray_input_data = Blockly.Arduino.valueToCode(this, 'text_toCharArray_input_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_text_toCharArray_get_data = Blockly.Arduino.valueToCode(this, 'text_toCharArray_get_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_text_toCharArray_output_data = Blockly.Arduino.valueToCode(this, 'text_toCharArray_output_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_text_toCharArray_get_data1 = myAtoi(value_text_toCharArray_get_data) + 1;
    var code = 'String(' + value_text_toCharArray_input_data + ').toCharArray(' + value_text_toCharArray_output_data + ', ' + value_text_toCharArray_get_data1 + ');\n';
    return code;
};

Blockly.Arduino.forBlock['text_substring_1'] = function () {
    var value_text_substring_input = Blockly.Arduino.valueToCode(this, 'text_substring_input', Blockly.Arduino.ORDER_ATOMIC);
    var value_text_substring_select = Blockly.Arduino.valueToCode(this, 'text_substring_select', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'String(' + value_text_substring_input + ').substring(' + value_text_substring_select + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_Split_string'] = function () {
    var value_Split_string_data = Blockly.Arduino.valueToCode(this, 'Split_string_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_Split_string_char = Blockly.Arduino.valueToCode(this, 'Split_string_char', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_Split_string_front = this.getFieldValue('Split_string_front');

    Blockly.Arduino.definitions_['function_Split_string'] = 'String Split_string(String String2, char Split_char, boolean Front) {'
        + '\n  String Cecha="";'
        + '\n  int accumulation=0;'
        + '\n  for (int i = 0; i <= (String(String2).length() - 1); i = i + 1) {'
        + '\n    if (String(String2).charAt(i) == Split_char) {'
        + '\n      accumulation = i;'
        + '\n      break;'
        + '\n    }'
        + '\n  }'
        + '\n  if (Front == true) {'
        + '\n    for (int i = 0; i <= (accumulation - 1); i = i + 1) {'
        + '\n      Cecha = String(Cecha) + String(String(String2).charAt(i));'
        + '\n    }'
        + '\n  } else {'
        + '\n    for (int i = (accumulation + 1); i <= (String(String2).length()); i = i + 1) {'
        + '\n      Cecha = String(Cecha) + String(String(String2).charAt(i));'
        + '\n    }'
        + '\n  }'
        + '\n  return Cecha;'
        + '\n}';

    var code = 'Split_string(' + value_Split_string_data + ', ' + value_Split_string_char + ', ' + dropdown_Split_string_front + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_String_Left'] = function () {
    var value_String_Left_data = Blockly.Arduino.valueToCode(this, 'String_Left_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_String_Left_char = Blockly.Arduino.valueToCode(this, 'String_Left_char', Blockly.Arduino.ORDER_ATOMIC);

    var code = '';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino.forBlock['make_arduino_search_i2c'] = function () {
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin();';
    // 检查是否已设置串口波特率，如果没有则自动添加
    var hasSerialBegin = false;
    for (var key in Blockly.Arduino.setups_) {
        if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
            hasSerialBegin = true;
            break;
        }
    }
    if (!hasSerialBegin) {
        Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
    }
    Blockly.Arduino.setups_['setup_serial_print'] = 'Serial.println("\\nI2C扫描器");';
    var code = 'byte error, address;'
        + '\nint nDevices;'
        + '\nSerial.println("扫描中...");'
        + '\nnDevices = 0;'
        + '\nfor (address = 1; address < 127; address++){'
        + '\n  Wire.beginTransmission(address);'
        + '\n  error = Wire.endTransmission();'
        + '\n  if (error == 0){'
        + '\n    Serial.print("发现I2C设备，地址: 0x");'
        + '\n    if (address < 16) Serial.print("0");'
        + '\n    Serial.print(address, HEX);'
        + '\n    Serial.println(" !");'
        + '\n    nDevices++;'
        + '\n  }else if (error == 4){'
        + '\n    Serial.print("地址 0x");'
        + '\n    if (address < 16) Serial.print("0");'
        + '\n    Serial.print(address, HEX);'
        + '\n    Serial.println(" 处发生未知错误");'
        + '\n  }'
        + '\n}'
        + '\nif (nDevices == 0) Serial.println("未发现I2C设备\\n");'
        + '\nelse Serial.println("扫描完成\\n");'
        + '\ndelay(5000);'
        ;
    return code;
};
Blockly.Arduino.forBlock['make_arduino_i2c_begin_master'] = function () {
    this.setTooltip(
        "初始化Wire库，并以Master(主机)的形式加入到I2C网络，只能调用一次"
    );

    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    
    // 如果用户设置了引脚，则使用自定义引脚初始化
    if (value_sda && value_scl) {
        // 移除引号，只保留数字
        var sda_pin = value_sda.replace(/"/g, '');
        var scl_pin = value_scl.replace(/"/g, '');
        Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin(' + sda_pin + ', ' + scl_pin + ');';
    } else {
        // 使用默认引脚
        Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin();';
    }
    
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_i2c_begin_slave'] = function () {
    this.setTooltip(
        "初始化Wire库，并以Slaver(从机)的形式加入到I2C网络，只能调用一次"
    );

    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
    var value_i2c_address = Blockly.Arduino.valueToCode(this, 'i2c_address', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    
    // 如果用户设置了引脚，则使用自定义引脚初始化
    if (value_sda && value_scl) {
        // 移除引号，只保留数字
        var sda_pin = value_sda.replace(/"/g, '');
        var scl_pin = value_scl.replace(/"/g, '');
        Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin(' + sda_pin + ', ' + scl_pin + ', ' + value_i2c_address + ');';
    } else {
        // 使用默认引脚
        Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin(' + value_i2c_address + ');';
    }
    
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_i2c_begin_end_transmission'] = function () {
    this.setTooltip(
        "I2C发送数据"
    );

    var value_i2c_address = Blockly.Arduino.valueToCode(this, 'i2c_address', Blockly.Arduino.ORDER_ATOMIC);
    var statements_transmission_data = Blockly.Arduino.statementToCode(this, 'transmission_data');
    var code = 'Wire.beginTransmission(' + value_i2c_address + ');\n'
        + statements_transmission_data
        + 'Wire.endTransmission();\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_i2c_begin_transmission'] = function () {
    this.setTooltip(
        "I2C开启数据发送，发送一个I2C开始字符"
    );

    var value_i2c_address = Blockly.Arduino.valueToCode(this, 'i2c_address', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'Wire.beginTransmission(' + value_i2c_address + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_i2c_write'] = function () {
    this.setTooltip(
        "I2C发送数据"
    );

    var value_i2c_write_data = Blockly.Arduino.valueToCode(this, 'i2c_write_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'Wire.write(' + value_i2c_write_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_i2c_end_transmission_1'] = function () {
    this.setTooltip(
        "结束一个由beginTransmission()开始的并且由write()排列的从机的传输"
    );

    var code = 'Wire.endTransmission();\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_i2c_end_transmission'] = function () {
    this.setTooltip(
        "结束一个由beginTransmission()开始的并且由write()排列的从机的传输"
    );

    var code = 'Wire.endTransmission()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_i2c_onReceive'] = function () {
    this.setTooltip(
        "从机接收到主机发来的数据时，执行此事件"
    );

    var value_onReceive_length = Blockly.Arduino.valueToCode(this, 'onReceive_length', Blockly.Arduino.ORDER_ATOMIC);
    var statements_i2c_onReceive_data = Blockly.Arduino.statementToCode(this, 'i2c_onReceive_data');

    Blockly.Arduino.definitions_['function_receiveEvent'] = 'void receiveEvent(int ' + value_onReceive_length + ')'
        + '\n{\n'
        + '  ' + statements_i2c_onReceive_data
        + '\n}\n'
    Blockly.Arduino.setups_['setup_i2c_receiveEvent'] = 'Wire.onReceive(receiveEvent);';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_i2c_available'] = function () {
    this.setTooltip(
        "用于统计主机读取从机发来数据时read缓冲区剩余的字节数"
    );

    var code = 'Wire.available()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_i2c_read'] = function () {
    this.setTooltip(
        "用于在主机收到从机发来数据时，读取缓存区的数据"
    );

    var code = 'Wire.read()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_i2c_requestFrom'] = function () {
    this.setTooltip(
        "I2C主机请求从机一些字节的数据，这些字节可以被主机用read()或available()接收"
    );

    var value_i2c_address = Blockly.Arduino.valueToCode(this, 'i2c_address', Blockly.Arduino.ORDER_ATOMIC);
    var value_data_length = Blockly.Arduino.valueToCode(this, 'data_length', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'Wire.requestFrom(' + value_i2c_address + ', ' + value_data_length + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_i2c_onRequest'] = function () {
    this.setTooltip(
        "当I2C从机收到主机的数据请求时，执行此事件"
    );

    var statements_i2c_onRequest_data = Blockly.Arduino.statementToCode(this, 'i2c_onRequest_data');

    Blockly.Arduino.definitions_['function_requestEvent'] = 'void requestEvent()'
        + '\n{\n'
        + '  ' + statements_i2c_onRequest_data
        + '\n}\n'
    Blockly.Arduino.setups_['setup_i2c_requestEvent'] = 'Wire.onRequest(requestEvent);';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_spi_begin_master'] = function () {
    var dropdown_spi_begin_divider = this.getFieldValue('spi_begin_divider');
    var value_mosi = Blockly.Arduino.valueToCode(this, 'mosi', Blockly.Arduino.ORDER_ATOMIC);
    var value_miso = Blockly.Arduino.valueToCode(this, 'miso', Blockly.Arduino.ORDER_ATOMIC);
    var value_sck = Blockly.Arduino.valueToCode(this, 'sck', Blockly.Arduino.ORDER_ATOMIC);
    var value_spi_slave_pin = Blockly.Arduino.valueToCode(this, 'spi_slave_pin', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';

    // 如果用户设置了引脚，则使用自定义引脚初始化
    if (value_mosi && value_miso && value_sck) {
        // 移除引号，只保留数字
        var mosi_pin = value_mosi.replace(/"/g, '');
        var miso_pin = value_miso.replace(/"/g, '');
        var sck_pin = value_sck.replace(/"/g, '');
        Blockly.Arduino.setups_['setup_spi'] = 'SPI.begin(' + mosi_pin + ', ' + miso_pin + ', ' + sck_pin + ');';
    } else {
        // 使用默认引脚
        Blockly.Arduino.setups_['setup_spi'] = 'SPI.begin();';
    }
    
    Blockly.Arduino.setups_['setup_spi_divider'] = 'SPI.setClockDivider(SPI_CLOCK_DIV' + dropdown_spi_begin_divider + ');';
    Blockly.Arduino.setups_['setup_spi_pin_' + value_spi_slave_pin] = 'digitalWrite(' + value_spi_slave_pin + ', HIGH);';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_spi_begin_slave'] = function () {
    var value_mosi = Blockly.Arduino.valueToCode(this, 'mosi', Blockly.Arduino.ORDER_ATOMIC);
    var value_miso = Blockly.Arduino.valueToCode(this, 'miso', Blockly.Arduino.ORDER_ATOMIC);
    var value_sck = Blockly.Arduino.valueToCode(this, 'sck', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    
    // 如果用户设置了引脚，则使用自定义引脚初始化
    if (value_mosi && value_miso && value_sck) {
        // 移除引号，只保留数字
        var mosi_pin = value_mosi.replace(/"/g, '');
        var miso_pin = value_miso.replace(/"/g, '');
        var sck_pin = value_sck.replace(/"/g, '');
        Blockly.Arduino.setups_['setup_spi'] = 'SPI.begin(' + mosi_pin + ', ' + miso_pin + ', ' + sck_pin + ');';
    } else {
        // 使用默认引脚
        Blockly.Arduino.setups_['setup_spi'] = 'SPI.begin();';
    }
    
    Blockly.Arduino.setups_['setup_spi_slave'] = 'pinMode(12, OUTPUT);'
        + '\n  SPCR |= _BV(SPE);';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_spi_transfer'] = function () {
    var value_slave_pin = Blockly.Arduino.valueToCode(this, 'slave_pin', Blockly.Arduino.ORDER_ATOMIC);
    var statements_transfer_data = Blockly.Arduino.statementToCode(this, 'transfer_data');
    var code = 'digitalWrite(' + value_slave_pin + ', LOW);\n'
        + statements_transfer_data
        + 'digitalWrite(' + value_slave_pin + ', HIGH);\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_spi_transfer_1'] = function () {
    var value_transfer_data = Blockly.Arduino.valueToCode(this, 'transfer_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'SPI.transfer(' + value_transfer_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_spi_transfer_2'] = function () {
    var value_transfer_data = Blockly.Arduino.valueToCode(this, 'transfer_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'SPI.transfer(' + value_transfer_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_spi_slave_interrupt'] = function () {
    var value_slave_interrupt_input = Blockly.Arduino.valueToCode(this, 'slave_interrupt_input', Blockly.Arduino.ORDER_ATOMIC);
    var statements_slave_interrupt_data = Blockly.Arduino.statementToCode(this, 'slave_interrupt_data');
    Blockly.Arduino.definitions_['function_ISR'] = 'ISR(SPI_STC_vect)'
        + '\n{'
        + '\n' + statements_slave_interrupt_data
        + '\n}\n'
    Blockly.Arduino.setups_['setup_spi_interrupt'] = 'SPI.attachInterrupt();';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_spi_slave_receive'] = function () {
    var value_slave_receive_data = Blockly.Arduino.valueToCode(this, 'slave_receive_data', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['function_SPI_SlaveReceive'] = 'char SPI_SlaveReceive()'
        + '\n{'
        + '\n  while(!(SPSR&(1<<SPIF)));'
        + '\n  return SPDR;'
        + '\n}\n'
    var code = 'SPI_SlaveReceive()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//模拟鼠标开启或关闭
Blockly.Arduino.forBlock['make_arduino_mouse_begin_end'] = function () {
    this.setTooltip("USB鼠标模拟开启或关闭");

    var dropdown_type = this.getFieldValue('type');
    Blockly.Arduino.definitions_['include_Mouse'] = '#include "Mouse.h"';
    var code = 'Mouse.' + dropdown_type + '();\n';
    return code;
};

//操作鼠标，单击、按下、释放鼠标按键
Blockly.Arduino.forBlock['make_arduino_mouse_click'] = function () {
    this.setTooltip(
        "操作鼠标，单击、按下、释放鼠标按键"
    );

    var value_click_location = Blockly.Arduino.valueToCode(this, 'click_location', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_click_type = this.getFieldValue('click_type');
    var code = 'Mouse.' + dropdown_click_type + '(' + value_click_location + ');\n';
    return code;
};

//定义鼠标按键
Blockly.Arduino.forBlock['make_arduino_mouse_click_location'] = function () {
    var dropdown_location_type = this.getFieldValue('location_type');
    var code = dropdown_location_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//移动鼠标
Blockly.Arduino.forBlock['make_arduino_mouse_move'] = function () {
    this.setTooltip(
        "移动鼠标"
    );

    var value_move_x = Blockly.Arduino.valueToCode(this, 'move_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_move_y = Blockly.Arduino.valueToCode(this, 'move_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_move_wheel = Blockly.Arduino.valueToCode(this, 'move_wheel', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'Mouse.move(' + value_move_x + ', ' + value_move_y + ', ' + value_move_wheel + ');\n';
    return code;
};

//检测鼠标按键是否被按下
Blockly.Arduino.forBlock['make_arduino_mouse_isPressed'] = function () {
    this.setTooltip("检测鼠标某个按键是否被按下，返回数据的类型为boolean");

    var value_type = Blockly.Arduino.valueToCode(this, 'type', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'Mouse.isPressed(' + value_type + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//键盘模拟开启或关闭
Blockly.Arduino.forBlock['make_arduino_keyboard_begin_end'] = function () {
    this.setTooltip("USB键盘模拟开启或关闭");

    var dropdown_type = this.getFieldValue('type');
    Blockly.Arduino.definitions_['include_Keyboard'] = '#include "Keyboard.h"';
    var code = 'Keyboard.' + dropdown_type + '();\n';
    return code;
};

//定义键盘的按键类型
Blockly.Arduino.forBlock['make_arduino_keyboard_key'] = function () {
    var dropdown_key_type = this.getFieldValue('key_type');
    var code = dropdown_key_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//操作键盘，按下或释放某个按键
Blockly.Arduino.forBlock['make_arduino_keyboard_press'] = function () {
    this.setTooltip("操作键盘，按下或释放某个按键");

    var value_key = Blockly.Arduino.valueToCode(this, 'key', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_type = this.getFieldValue('type');
    var code = 'Keyboard.' + dropdown_type + '(' + value_key + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_keyboard_press_return'] = function () {
    this.setTooltip("操作键盘，按下或释放某个按键，返回数据的类型为size_t(2字节)");

    var value_key = Blockly.Arduino.valueToCode(this, 'key', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_type = this.getFieldValue('type');
    var code = 'Keyboard.' + dropdown_type + '(' + value_key + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//操作键盘，释放键盘上所有按键
Blockly.Arduino.forBlock['make_arduino_keyboard_releaseAll'] = function () {
    this.setTooltip("操作键盘，释放键盘上所有按键");

    var code = 'Keyboard.releaseAll();\n';
    return code;
};

//键盘向电脑发送字符
Blockly.Arduino.forBlock['make_arduino_keyboard_write'] = function () {
    this.setTooltip("键盘向电脑发送字符");

    var value_write_data = Blockly.Arduino.valueToCode(this, 'write_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'Keyboard.write(' + value_write_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_keyboard_write_return'] = function () {
    this.setTooltip("键盘向电脑发送字符，返回数据的类型为size_t(2字节)");

    var value_write_data = Blockly.Arduino.valueToCode(this, 'write_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'Keyboard.write(' + value_write_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//键盘向电脑发送字符串
Blockly.Arduino.forBlock['make_arduino_keyboard_print'] = function () {
    this.setTooltip("键盘向电脑发送字符串");

    var value_print_data = Blockly.Arduino.valueToCode(this, 'print_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_print_type = this.getFieldValue('print_type');
    var code = 'Keyboard.' + dropdown_print_type + '(' + value_print_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['keypad_1_4_start'] = function () {
    var text_keypad_1_4_name = this.getFieldValue('keypad_1_4_name');
    var text_keypad_1_4_1_1 = this.getFieldValue('keypad_1_4_1_1');
    var text_keypad_1_4_1_2 = this.getFieldValue('keypad_1_4_1_2');
    var text_keypad_1_4_1_3 = this.getFieldValue('keypad_1_4_1_3');
    var text_keypad_1_4_1_4 = this.getFieldValue('keypad_1_4_1_4');

    Blockly.Arduino.definitions_['include_Keypad'] = '#include <Keypad.h>';
    Blockly.Arduino.definitions_['var_declare_keypadstart1' + text_keypad_1_4_name] = 'const byte ' + text_keypad_1_4_name + 'ROWS = 1;';
    Blockly.Arduino.definitions_['var_declare_keypadstart2' + text_keypad_1_4_name] = 'const byte ' + text_keypad_1_4_name + 'COLS = 4;';

    Blockly.Arduino.definitions_['var_declare_keypad' + text_keypad_1_4_name] = 'char ' + text_keypad_1_4_name + 'hexaKeys[' + text_keypad_1_4_name + 'ROWS][' + text_keypad_1_4_name + 'COLS] = {';
    Blockly.Arduino.definitions_['var_declare_keypada' + text_keypad_1_4_name] = '  {\'' + text_keypad_1_4_1_1 + '\',\'' + text_keypad_1_4_1_2 + '\',\'' + text_keypad_1_4_1_3 + '\',\'' + text_keypad_1_4_1_4 + '\'}';
    Blockly.Arduino.definitions_['var_declare_keypade' + text_keypad_1_4_name] = '};';

    // 检查是否已设置串口波特率，如果没有则自动添加
    var hasSerialBegin = false;
    for (var key in Blockly.Arduino.setups_) {
        if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
            hasSerialBegin = true;
            break;
        }
    }
    if (!hasSerialBegin) {
        Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
    }

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['keypad_4_3_start'] = function () {
    var text_keypad_4_3_name = this.getFieldValue('keypad_4_3_name');
    var text_keypad_4_3_1_1 = this.getFieldValue('keypad_4_3_1_1');
    var text_keypad_4_3_1_2 = this.getFieldValue('keypad_4_3_1_2');
    var text_keypad_4_3_1_3 = this.getFieldValue('keypad_4_3_1_3');
    var text_keypad_4_3_2_1 = this.getFieldValue('keypad_4_3_2_1');
    var text_keypad_4_3_2_2 = this.getFieldValue('keypad_4_3_2_2');
    var text_keypad_4_3_2_3 = this.getFieldValue('keypad_4_3_2_3');
    var text_keypad_4_3_3_1 = this.getFieldValue('keypad_4_3_3_1');
    var text_keypad_4_3_3_2 = this.getFieldValue('keypad_4_3_3_2');
    var text_keypad_4_3_3_3 = this.getFieldValue('keypad_4_3_3_3');
    var text_keypad_4_3_4_1 = this.getFieldValue('keypad_4_3_4_1');
    var text_keypad_4_3_4_2 = this.getFieldValue('keypad_4_3_4_2');
    var text_keypad_4_3_4_3 = this.getFieldValue('keypad_4_3_4_3');

    Blockly.Arduino.definitions_['include_Keypad'] = '#include <Keypad.h>';
    Blockly.Arduino.definitions_['var_declare_keypadstart1' + text_keypad_4_3_name] = 'const byte ' + text_keypad_4_3_name + 'ROWS = 4;';
    Blockly.Arduino.definitions_['var_declare_keypadstart2' + text_keypad_4_3_name] = 'const byte ' + text_keypad_4_3_name + 'COLS = 3;';

    Blockly.Arduino.definitions_['var_declare_keypad' + text_keypad_4_3_name] = 'char ' + text_keypad_4_3_name + 'hexaKeys[' + text_keypad_4_3_name + 'ROWS][' + text_keypad_4_3_name + 'COLS] = {';
    Blockly.Arduino.definitions_['var_declare_keypada' + text_keypad_4_3_name] = '  {\'' + text_keypad_4_3_1_1 + '\',\'' + text_keypad_4_3_1_2 + '\',\'' + text_keypad_4_3_1_3 + '\'},';
    Blockly.Arduino.definitions_['var_declare_keypadb' + text_keypad_4_3_name] = '  {\'' + text_keypad_4_3_2_1 + '\',\'' + text_keypad_4_3_2_2 + '\',\'' + text_keypad_4_3_2_3 + '\'},';
    Blockly.Arduino.definitions_['var_declare_keypadc' + text_keypad_4_3_name] = '  {\'' + text_keypad_4_3_3_1 + '\',\'' + text_keypad_4_3_3_2 + '\',\'' + text_keypad_4_3_3_3 + '\'},';
    Blockly.Arduino.definitions_['var_declare_keypadd' + text_keypad_4_3_name] = '  {\'' + text_keypad_4_3_4_1 + '\',\'' + text_keypad_4_3_4_2 + '\',\'' + text_keypad_4_3_4_3 + '\'}';
    Blockly.Arduino.definitions_['var_declare_keypade' + text_keypad_4_3_name] = '};';

    // 检查是否已设置串口波特率，如果没有则自动添加
    var hasSerialBegin = false;
    for (var key in Blockly.Arduino.setups_) {
        if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
            hasSerialBegin = true;
            break;
        }
    }
    if (!hasSerialBegin) {
        Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
    }

    var code = '';
    return code;
};

/*
Blockly.Arduino.forBlock['Arduino_keypad_4_4_start'] = function() {
  var text_keypad_name = this.getFieldValue('keypad_name');
  var text_keypad_row = Blockly.Arduino.valueToCode(this, 'keypad_row',Blockly.Arduino.ORDER_ATOMIC);
  var text_keypad_col = Blockly.Arduino.valueToCode(this, 'keypad_col',Blockly.Arduino.ORDER_ATOMIC);
  var text_keypad_type = Blockly.Arduino.valueToCode(this, 'keypad_type',Blockly.Arduino.ORDER_ATOMIC);

  Blockly.Arduino.definitions_['include_Keypad'] = '#include <Keypad.h>';
  Blockly.Arduino.definitions_['var_declare_keypadstart1' + text_keypad_name] = 'const byte '+text_keypad_name+'_ROWS = 4;';
  Blockly.Arduino.definitions_['var_declare_keypadstart2' + text_keypad_name] = 'const byte '+text_keypad_name+'_COLS = 4;';

  Blockly.Arduino.definitions_['var_declare_keypadstart3' + text_keypad_name] = 'char '+text_keypad_name+'_hexaKeys['+text_keypad_name+'_ROWS]['+text_keypad_name+'_COLS] = {' + '\n' + text_keypad_type + '\n};';
  
  Blockly.Arduino.definitions_['var_declare_keypadstart4' + text_keypad_name] = 'byte '+text_keypad_name+'_rowPins['+text_keypad_name+'_ROWS] = '+text_keypad_row;
  Blockly.Arduino.definitions_['var_declare_keypadstart5' + text_keypad_name] = 'byte '+text_keypad_name+'_colPins['+text_keypad_name+'_COLS] = '+text_keypad_col;

  Blockly.Arduino.definitions_['var_declare_keypadstart6' + text_keypad_name] = 'Keypad '+text_keypad_name+' = Keypad( makeKeymap('+text_keypad_name+'_hexaKeys), '+text_keypad_name+'_rowPins, '+text_keypad_name+'_colPins, '+text_keypad_name+'_ROWS, '+text_keypad_name+'_COLS);';
  
  // 检查是否已设置串口波特率，如果没有则自动添加
  var hasSerialBegin = false;
  for (var key in Blockly.Arduino.setups_) {
      if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
          hasSerialBegin = true;
          break;
      }
  }
  if (!hasSerialBegin) {
      Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
  }

  var code = '';
  return code;
};
*/

/*
Blockly.Arduino.keypad_row_data= function() {
  var pin_keypad_row_1 = Blockly.Arduino.valueToCode(this, 'keypad_row_1',Blockly.Arduino.ORDER_ATOMIC);
  var pin_keypad_row_2 = Blockly.Arduino.valueToCode(this, 'keypad_row_2',Blockly.Arduino.ORDER_ATOMIC);
  var pin_keypad_row_3 = Blockly.Arduino.valueToCode(this, 'keypad_row_3',Blockly.Arduino.ORDER_ATOMIC);
  var pin_keypad_row_4 = Blockly.Arduino.valueToCode(this, 'keypad_row_4',Blockly.Arduino.ORDER_ATOMIC);

  var code = '{'+pin_keypad_row_1+', '+pin_keypad_row_2+', '+pin_keypad_row_3+', '+pin_keypad_row_4+'};';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.keypad_col_data= function() {
  var pin_keypad_col_1 = Blockly.Arduino.valueToCode(this, 'keypad_col_1',Blockly.Arduino.ORDER_ATOMIC);
  var pin_keypad_col_2 = Blockly.Arduino.valueToCode(this, 'keypad_col_2',Blockly.Arduino.ORDER_ATOMIC);
  var pin_keypad_col_3 = Blockly.Arduino.valueToCode(this, 'keypad_col_3',Blockly.Arduino.ORDER_ATOMIC);
  var pin_keypad_col_4 = Blockly.Arduino.valueToCode(this, 'keypad_col_4',Blockly.Arduino.ORDER_ATOMIC);

  var code = '{'+pin_keypad_col_1+', '+pin_keypad_col_2+', '+pin_keypad_col_3+', '+pin_keypad_col_4+'};';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.keypad_type_data= function() {
  var text_keypad_1_1 = this.getFieldValue('keypad_1_1');
  var text_keypad_1_2 = this.getFieldValue('keypad_1_2');
  var text_keypad_1_3 = this.getFieldValue('keypad_1_3');
  var text_keypad_1_4 = this.getFieldValue('keypad_1_4');

  var text_keypad_2_1 = this.getFieldValue('keypad_2_1');
  var text_keypad_2_2 = this.getFieldValue('keypad_2_2');
  var text_keypad_2_3 = this.getFieldValue('keypad_2_3');
  var text_keypad_2_4 = this.getFieldValue('keypad_2_4');

  var text_keypad_3_1 = this.getFieldValue('keypad_3_1');
  var text_keypad_3_2 = this.getFieldValue('keypad_3_2');
  var text_keypad_3_3 = this.getFieldValue('keypad_3_3');
  var text_keypad_3_4 = this.getFieldValue('keypad_3_4');

  var text_keypad_4_1 = this.getFieldValue('keypad_4_1');
  var text_keypad_4_2 = this.getFieldValue('keypad_4_2');
  var text_keypad_4_3 = this.getFieldValue('keypad_4_3');
  var text_keypad_4_4 = this.getFieldValue('keypad_4_4');

  var code =   
     '  {\''+text_keypad_1_1+'\',\''+text_keypad_1_2+'\',\''+text_keypad_1_3+'\',\''+text_keypad_1_4+'\'},'+
   '\n  {\''+text_keypad_2_1+'\',\''+text_keypad_2_2+'\',\''+text_keypad_2_3+'\',\''+text_keypad_2_4+'\'},'+
   '\n  {\''+text_keypad_3_1+'\',\''+text_keypad_3_2+'\',\''+text_keypad_3_3+'\',\''+text_keypad_3_4+'\'},'+
   '\n  {\''+text_keypad_4_1+'\',\''+text_keypad_4_2+'\',\''+text_keypad_4_3+'\',\''+text_keypad_4_4+'\'}';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};
*/

Blockly.Arduino.forBlock['Arduino_keypad_4_3_start'] = function () {
    var text_keypad_name = this.getFieldValue('keypad_name');
    var text_keypad_row = Blockly.Arduino.valueToCode(this, 'keypad_row', Blockly.Arduino.ORDER_ATOMIC);
    var text_keypad_col = Blockly.Arduino.valueToCode(this, 'keypad_col', Blockly.Arduino.ORDER_ATOMIC);
    var text_keypad_type = Blockly.Arduino.valueToCode(this, 'keypad_type', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Keypad'] = '#include <Keypad.h>';
    Blockly.Arduino.definitions_['var_declare_keypadstart1' + text_keypad_name] = 'const byte ' + text_keypad_name + '_ROWS = 4;';
    Blockly.Arduino.definitions_['var_declare_keypadstart2' + text_keypad_name] = 'const byte ' + text_keypad_name + '_COLS = 3;';

    Blockly.Arduino.definitions_['var_declare_keypadstart3' + text_keypad_name] = 'char ' + text_keypad_name + '_hexaKeys[' + text_keypad_name + '_ROWS][' + text_keypad_name + '_COLS] = {' + '\n' + text_keypad_type + '\n};';

    Blockly.Arduino.definitions_['var_declare_keypadstart4' + text_keypad_name] = 'byte ' + text_keypad_name + '_rowPins[' + text_keypad_name + '_ROWS] = ' + text_keypad_row;
    Blockly.Arduino.definitions_['var_declare_keypadstart5' + text_keypad_name] = 'byte ' + text_keypad_name + '_colPins[' + text_keypad_name + '_COLS] = ' + text_keypad_col;

    Blockly.Arduino.definitions_['var_declare_keypadstart6' + text_keypad_name] = 'Keypad ' + text_keypad_name + ' = Keypad( makeKeymap(' + text_keypad_name + '_hexaKeys), ' + text_keypad_name + '_rowPins, ' + text_keypad_name + '_colPins, ' + text_keypad_name + '_ROWS, ' + text_keypad_name + '_COLS);';

    // 检查是否已设置串口波特率，如果没有则自动添加
    var hasSerialBegin = false;
    for (var key in Blockly.Arduino.setups_) {
        if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
            hasSerialBegin = true;
            break;
        }
    }
    if (!hasSerialBegin) {
        Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
    }

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['keypad_4_3_row_data'] = function () {
    var pin_keypad_row_1 = Blockly.Arduino.valueToCode(this, 'keypad_row_1', Blockly.Arduino.ORDER_ATOMIC);
    var pin_keypad_row_2 = Blockly.Arduino.valueToCode(this, 'keypad_row_2', Blockly.Arduino.ORDER_ATOMIC);
    var pin_keypad_row_3 = Blockly.Arduino.valueToCode(this, 'keypad_row_3', Blockly.Arduino.ORDER_ATOMIC);
    var pin_keypad_row_4 = Blockly.Arduino.valueToCode(this, 'keypad_row_4', Blockly.Arduino.ORDER_ATOMIC);

    var code = '{' + pin_keypad_row_1 + ', ' + pin_keypad_row_2 + ', ' + pin_keypad_row_3 + ', ' + pin_keypad_row_4 + '};';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['keypad_4_3_col_data'] = function () {
    var pin_keypad_col_1 = Blockly.Arduino.valueToCode(this, 'keypad_col_1', Blockly.Arduino.ORDER_ATOMIC);
    var pin_keypad_col_2 = Blockly.Arduino.valueToCode(this, 'keypad_col_2', Blockly.Arduino.ORDER_ATOMIC);
    var pin_keypad_col_3 = Blockly.Arduino.valueToCode(this, 'keypad_col_3', Blockly.Arduino.ORDER_ATOMIC);

    var code = '{' + pin_keypad_col_1 + ', ' + pin_keypad_col_2 + ', ' + pin_keypad_col_3 + '};';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['keypad_4_3_type_data'] = function () {
    var text_keypad_1_1 = this.getFieldValue('keypad_1_1');
    var text_keypad_1_2 = this.getFieldValue('keypad_1_2');
    var text_keypad_1_3 = this.getFieldValue('keypad_1_3');

    var text_keypad_2_1 = this.getFieldValue('keypad_2_1');
    var text_keypad_2_2 = this.getFieldValue('keypad_2_2');
    var text_keypad_2_3 = this.getFieldValue('keypad_2_3');

    var text_keypad_3_1 = this.getFieldValue('keypad_3_1');
    var text_keypad_3_2 = this.getFieldValue('keypad_3_2');
    var text_keypad_3_3 = this.getFieldValue('keypad_3_3');

    var text_keypad_4_1 = this.getFieldValue('keypad_4_1');
    var text_keypad_4_2 = this.getFieldValue('keypad_4_2');
    var text_keypad_4_3 = this.getFieldValue('keypad_4_3');

    var code =
        '  {\'' + text_keypad_1_1 + '\',\'' + text_keypad_1_2 + '\',\'' + text_keypad_1_3 + '\'},' +
        '\n  {\'' + text_keypad_2_1 + '\',\'' + text_keypad_2_2 + '\',\'' + text_keypad_2_3 + '\'},' +
        '\n  {\'' + text_keypad_3_1 + '\',\'' + text_keypad_3_2 + '\',\'' + text_keypad_3_3 + '\'},' +
        '\n  {\'' + text_keypad_4_1 + '\',\'' + text_keypad_4_2 + '\',\'' + text_keypad_4_3 + '\'}';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['Arduino_keypad_1_4_start'] = function () {
    var text_keypad_name = this.getFieldValue('keypad_name');
    var text_keypad_row = Blockly.Arduino.valueToCode(this, 'keypad_row', Blockly.Arduino.ORDER_ATOMIC);
    var text_keypad_col = Blockly.Arduino.valueToCode(this, 'keypad_col', Blockly.Arduino.ORDER_ATOMIC);
    var text_keypad_type = Blockly.Arduino.valueToCode(this, 'keypad_type', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Keypad'] = '#include <Keypad.h>';
    Blockly.Arduino.definitions_['var_declare_keypadstart1' + text_keypad_name] = 'const byte ' + text_keypad_name + '_ROWS = 1;';
    Blockly.Arduino.definitions_['var_declare_keypadstart2' + text_keypad_name] = 'const byte ' + text_keypad_name + '_COLS = 4;';

    Blockly.Arduino.definitions_['var_declare_keypadstart3' + text_keypad_name] = 'char ' + text_keypad_name + '_hexaKeys[' + text_keypad_name + '_ROWS][' + text_keypad_name + '_COLS] = {' + '\n' + text_keypad_type + '\n};';

    Blockly.Arduino.definitions_['var_declare_keypadstart4' + text_keypad_name] = 'byte ' + text_keypad_name + '_rowPins[' + text_keypad_name + '_ROWS] = ' + text_keypad_row;
    Blockly.Arduino.definitions_['var_declare_keypadstart5' + text_keypad_name] = 'byte ' + text_keypad_name + '_colPins[' + text_keypad_name + '_COLS] = ' + text_keypad_col;

    Blockly.Arduino.definitions_['var_declare_keypadstart6' + text_keypad_name] = 'Keypad ' + text_keypad_name + ' = Keypad( makeKeymap(' + text_keypad_name + '_hexaKeys), ' + text_keypad_name + '_rowPins, ' + text_keypad_name + '_colPins, ' + text_keypad_name + '_ROWS, ' + text_keypad_name + '_COLS);';

    // 检查是否已设置串口波特率，如果没有则自动添加
    var hasSerialBegin = false;
    for (var key in Blockly.Arduino.setups_) {
        if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
            hasSerialBegin = true;
            break;
        }
    }
    if (!hasSerialBegin) {
        Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
    }

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['keypad_1_4_row_data'] = function () {
    var pin_keypad_row_1 = Blockly.Arduino.valueToCode(this, 'keypad_row_1', Blockly.Arduino.ORDER_ATOMIC);

    var code = '{' + pin_keypad_row_1 + '};';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['keypad_1_4_col_data'] = function () {
    var pin_keypad_col_1 = Blockly.Arduino.valueToCode(this, 'keypad_col_1', Blockly.Arduino.ORDER_ATOMIC);
    var pin_keypad_col_2 = Blockly.Arduino.valueToCode(this, 'keypad_col_2', Blockly.Arduino.ORDER_ATOMIC);
    var pin_keypad_col_3 = Blockly.Arduino.valueToCode(this, 'keypad_col_3', Blockly.Arduino.ORDER_ATOMIC);
    var pin_keypad_col_4 = Blockly.Arduino.valueToCode(this, 'keypad_col_4', Blockly.Arduino.ORDER_ATOMIC);

    var code = '{' + pin_keypad_col_1 + ', ' + pin_keypad_col_2 + ', ' + pin_keypad_col_3 + ', ' + pin_keypad_col_4 + '};';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['keypad_1_4_type_data'] = function () {
    var text_keypad_1_1 = this.getFieldValue('keypad_1_1');
    var text_keypad_1_2 = this.getFieldValue('keypad_1_2');
    var text_keypad_1_3 = this.getFieldValue('keypad_1_3');
    var text_keypad_1_4 = this.getFieldValue('keypad_1_4');

    var code =
        '  {\'' + text_keypad_1_1 + '\',\'' + text_keypad_1_2 + '\',\'' + text_keypad_1_3 + '\',\'' + text_keypad_1_4 + '\'}';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['keypad_n_n_type_data'] = function () {
    var text_keypad_row = this.getFieldValue('keypad_row');
    var text_keypad_col = this.getFieldValue('keypad_col');

    var data = new Array((text_keypad_row - 0) * (text_keypad_col - 0));
    for (var i = 1; i <= text_keypad_row - 0; i++) {
        for (var j = 1; j <= text_keypad_col - 0; j++) {
            data[(i - 1) * (text_keypad_col - 0) + j - 1] = this.getFieldValue('keypad_' + i + '_' + j);
        }
    }
    var code = '';
    for (var i = 1; i <= text_keypad_row - 0; i++) {
        if (i == 1)
            code = code + '  {'
        else
            code = code + '\n  {'
        for (var j = 1; j <= text_keypad_col - 0; j++) {
            if (j == text_keypad_col - 0)
                code = code + '\'' + data[(i - 1) * (text_keypad_col - 0) + j - 1] + '\'';
            else
                code = code + '\'' + data[(i - 1) * (text_keypad_col - 0) + j - 1] + '\',';
        }
        if (i == text_keypad_row - 0)
            code = code + '}'
        else
            code = code + '},'
    }
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
Blockly.Arduino.keypad_n_n_row_col_data= function() {
  var num = this.getFieldValue('keypad_pin_num');
  var data = new Array(num-0);
  for(var i = 1;i <= num-0;i++)
    data[i] = Blockly.Arduino.valueToCode(this, 'keypad_row_col_' + i,Blockly.Arduino.ORDER_ATOMIC);
  var code = '' + num;
  for(var i = 1;i <= num-0;i++)
  {
    if(i == 1)
      code = code + '{' + data[i];
    else if(i == num-0)
      code = code + ',' + data[i] + '};';
    else
      code = code + ',' + data[i];
  }
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};
*/

Blockly.Arduino.forBlock['keypad_n_n_start_1'] = function () {
    var text_keypad_name = this.getFieldValue('keypad_name');
    var text_keypad_row = Blockly.Arduino.valueToCode(this, 'keypad_row', Blockly.Arduino.ORDER_ATOMIC);
    var text_keypad_col = Blockly.Arduino.valueToCode(this, 'keypad_col', Blockly.Arduino.ORDER_ATOMIC);
    var text_keypad_type = Blockly.Arduino.valueToCode(this, 'keypad_type', Blockly.Arduino.ORDER_ATOMIC);

    var keypad_n_n_row = '';
    var keypad_n_n_col = '';

    for (var i = 0; i < text_keypad_row.length; i++) {
        if (text_keypad_row.charAt(i) == ' ')
            continue;
        else if (text_keypad_row.charAt(i) == '{') {
            text_keypad_row = text_keypad_row.substring(i);
            break;
        }
        else
            keypad_n_n_row = keypad_n_n_row + text_keypad_row.charAt(i);
    }

    for (var i = 0; i < text_keypad_col.length; i++) {
        if (text_keypad_col.charAt(i) == ' ')
            continue;
        else if (text_keypad_col.charAt(i) == '{') {
            text_keypad_col = text_keypad_col.substring(i);
            break;
        }
        else
            keypad_n_n_col = keypad_n_n_col + text_keypad_col.charAt(i);
    }
    Blockly.Arduino.definitions_['include_Keypad'] = '#include <Keypad.h>';
    Blockly.Arduino.definitions_['var_declare_keypad_' + text_keypad_name] = 'const byte ' + text_keypad_name + '_ROWS = ' + keypad_n_n_row + ';'
        + '\n' + 'const byte ' + text_keypad_name + '_COLS = ' + keypad_n_n_col + ';'
        + '\n' + 'byte ' + text_keypad_name + '_rowPins[' + text_keypad_name + '_ROWS] = ' + text_keypad_row
        + '\n' + 'byte ' + text_keypad_name + '_colPins[' + text_keypad_name + '_COLS] = ' + text_keypad_col
        + '\n' + 'Keypad ' + text_keypad_name + ' = Keypad(makeKeymap(' + text_keypad_type + '), ' + text_keypad_name + '_rowPins, ' + text_keypad_name + '_colPins, ' + text_keypad_name + '_ROWS, ' + text_keypad_name + '_COLS);';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['keypad_n_n_start'] = function () {
    var text_keypad_name = this.getFieldValue('keypad_name');
    var text_keypad_row = Blockly.Arduino.valueToCode(this, 'keypad_row', Blockly.Arduino.ORDER_ATOMIC);
    var text_keypad_col = Blockly.Arduino.valueToCode(this, 'keypad_col', Blockly.Arduino.ORDER_ATOMIC);
    var text_keypad_type = Blockly.Arduino.valueToCode(this, 'keypad_type', Blockly.Arduino.ORDER_ATOMIC);

    var keypad_n_n_row = '';
    var keypad_n_n_col = '';

    for (var i = 0; i < text_keypad_row.length; i++) {
        if (text_keypad_row.charAt(i) == ' ')
            continue;
        else if (text_keypad_row.charAt(i) == '{') {
            text_keypad_row = text_keypad_row.substring(i);
            break;
        }
        else
            keypad_n_n_row = keypad_n_n_row + text_keypad_row.charAt(i);
    }

    for (var i = 0; i < text_keypad_col.length; i++) {
        if (text_keypad_col.charAt(i) == ' ')
            continue;
        else if (text_keypad_col.charAt(i) == '{') {
            text_keypad_col = text_keypad_col.substring(i);
            break;
        }
        else
            keypad_n_n_col = keypad_n_n_col + text_keypad_col.charAt(i);
    }
    Blockly.Arduino.definitions_['include_Keypad'] = '#include <Keypad.h>';
    Blockly.Arduino.definitions_['var_declare_keypad_' + text_keypad_name] = 'const byte ' + text_keypad_name + '_ROWS = ' + keypad_n_n_row + ';'
        + '\n' + 'const byte ' + text_keypad_name + '_COLS = ' + keypad_n_n_col + ';'
        + '\n' + 'char ' + text_keypad_name + '_hexaKeys[' + text_keypad_name + '_ROWS][' + text_keypad_name + '_COLS] = {' + '\n' + text_keypad_type + '\n};'
        + '\n' + 'byte ' + text_keypad_name + '_rowPins[' + text_keypad_name + '_ROWS] = ' + text_keypad_row
        + '\n' + 'byte ' + text_keypad_name + '_colPins[' + text_keypad_name + '_COLS] = ' + text_keypad_col
        + '\n' + 'Keypad ' + text_keypad_name + ' = Keypad( makeKeymap(' + text_keypad_name + '_hexaKeys), ' + text_keypad_name + '_rowPins, ' + text_keypad_name + '_colPins, ' + text_keypad_name + '_ROWS, ' + text_keypad_name + '_COLS);';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['keypad_n_n_row_col_data_1'] = function () {
    var code = new Array(this.itemCount_);
    for (var n = 0; n < this.itemCount_; n++) {
        code[n] = Blockly.Arduino.valueToCode(this, 'ADD' + n,
            Blockly.Arduino.ORDER_NONE) || '2';
    }

    var code1 = '' + this.itemCount_;
    for (var i = 0; i < this.itemCount_; i++) {
        if (i == 0 && this.itemCount_ == 1) {
            code1 = code1 + '{' + code[i] + '};';
            break;
        }
        else if (i == 0)
            code1 = code1 + '{' + code[i];
        else if (i == this.itemCount_ - 1)
            code1 = code1 + ',' + code[i] + '};';
        else
            code1 = code1 + ',' + code[i];
    }

    return [code1, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['get_keypad_num'] = function () {
    var text_keypad_name = this.getFieldValue('keypad_name');
    var code = '' + text_keypad_name + '.getKey()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['arduino_keypad_event'] = function () {
    var text_keypad_name = this.getFieldValue('keypad_name');
    var value_keypad_event_input = Blockly.Arduino.valueToCode(this, 'keypad_event_input', Blockly.Arduino.ORDER_ATOMIC);
    var text_keypad_start_event_delay = this.getFieldValue('keypad_start_event_delay');
    var statements_keypad_event_data = Blockly.Arduino.statementToCode(this, 'keypad_event_data');

    Blockly.Arduino.definitions_['var_declare_variate_' + value_keypad_event_input] = 'volatile char ' + value_keypad_event_input + ';';
    Blockly.Arduino.definitions_['var_declare_keypadstart7_event' + text_keypad_name] = 'void keypadEvent_' + text_keypad_name + '(KeypadEvent ' + value_keypad_event_input + ') {' +
        '\n' + statements_keypad_event_data +
        '\n}';
    Blockly.Arduino.setups_['setup_keypad_event_and_delay' + text_keypad_name] = text_keypad_name + '.addEventListener(keypadEvent_' + text_keypad_name + ');' +
        '\n  ' + text_keypad_name + '.setHoldTime(' + text_keypad_start_event_delay + ');';

    var code = '';
    return code;
};


Blockly.Arduino.forBlock['arduino_nrf24l01_start'] = function () {
    var value_nrf24l01_pin = Blockly.Arduino.valueToCode(this, 'nrf24l01_pin', Blockly.Arduino.ORDER_ATOMIC);
    var value_nrf24l01_send_channel = Blockly.Arduino.valueToCode(this, 'nrf24l01_send_channel', Blockly.Arduino.ORDER_ATOMIC);
    var value_nrf24l01_id = Blockly.Arduino.valueToCode(this, 'nrf24l01_id', Blockly.Arduino.ORDER_ATOMIC);
    var value_nrf24l01_send_num = Blockly.Arduino.valueToCode(this, 'nrf24l01_send_num', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['include_Mirf'] = '#include <Mirf.h>';
    Blockly.Arduino.definitions_['include_nRF24L01'] = '#include <nRF24L01.h>';
    Blockly.Arduino.definitions_['include_MirfHardwareSpiDriver'] = '#include <MirfHardwareSpiDriver.h>';

    Blockly.Arduino.setups_['setup_nrf24l01_pin'] = value_nrf24l01_pin;
    Blockly.Arduino.setups_['setup_nrf24l01_start_1'] = 'Mirf.spi = &MirfHardwareSpi;';
    Blockly.Arduino.setups_['setup_nrf24l01_start_2'] = 'Mirf.init();\n';

    Blockly.Arduino.setups_['setup_nrf24l01_start_3'] = 'Mirf.setRADDR((byte *)' + value_nrf24l01_id + ');';
    Blockly.Arduino.setups_['setup_nrf24l01_start_4'] = 'Mirf.payload = sizeof(' + value_nrf24l01_send_num + ');';
    Blockly.Arduino.setups_['setup_nrf24l01_start_5'] = 'Mirf.channel = ' + value_nrf24l01_send_channel + ';';
    Blockly.Arduino.setups_['setup_nrf24l01_start_6'] = 'Mirf.config();\n';
    Blockly.Arduino.setups_['setup_nrf24l01_start_7'] = 'byte data[Mirf.payload];';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['arduino_nrf24l01_pin'] = function () {
    var value_nrf24l01_pin_ce = Blockly.Arduino.valueToCode(this, 'nrf24l01_pin_ce', Blockly.Arduino.ORDER_ATOMIC);
    var value_nrf24l01_pin_csn = Blockly.Arduino.valueToCode(this, 'nrf24l01_pin_csn', Blockly.Arduino.ORDER_ATOMIC);

    var code = 'Mirf.cePin = 9;' +
        '\n  Mirf.csnPin = 10;';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['arduino_nrf24l01_send'] = function () {
    var value_nrf24l01_send_data = Blockly.Arduino.valueToCode(this, 'nrf24l01_send_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_nrf24l01_send_rec_id = Blockly.Arduino.valueToCode(this, 'nrf24l01_send_rec_id', Blockly.Arduino.ORDER_ATOMIC);

    //Blockly.Arduino.setups_['setup_nrf24l01_start_7'] = 'byte data[Mirf.payload];';

    var code = 'byte data[Mirf.payload];' +
        '\ndata[0] = ' + value_nrf24l01_send_data + ' & 0xFF;' +
        '\ndata[1] = ' + value_nrf24l01_send_data + ' >> 8;' +
        '\n\nMirf.setTADDR((byte *)' + value_nrf24l01_send_rec_id + ');' +
        '\nMirf.send(data);\n';
    return code;
};

Blockly.Arduino.forBlock['arduino_while'] = function () {
    var dropdown_while_is_true = this.getFieldValue('while_is_true');
    var value_while_condition = Blockly.Arduino.valueToCode(this, 'while_condition', Blockly.Arduino.ORDER_ATOMIC);
    var statements_while_carry_out = Blockly.Arduino.statementToCode(this, 'while_carry_out') || '';
    if (dropdown_while_is_true == "while_true") {
        dropdown_while_is_true = '';
    }
    else if (dropdown_while_is_true == "while_false") {
        dropdown_while_is_true = '!';
    }

    if (value_while_condition == "") {
        value_while_condition = "false";
    }

    var code = 'while (' + dropdown_while_is_true + value_while_condition + ') {' +
        '\n' + statements_while_carry_out +
        '\n}\n';
    return code;
};

Blockly.Arduino.forBlock['arduino_nrf24l01_is_sending'] = function () {

    var code = 'Mirf.isSending()';

    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['arduino_define_variate'] = function () {
    var text_variate_name = this.getFieldValue('variate_name');
    var dropdown_variate_type = this.getFieldValue('variate_type');
    var value_variate_num = Blockly.Arduino.valueToCode(this, 'variate_num', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['var_declare_variate' + text_variate_name] = dropdown_variate_type + ' ' + text_variate_name + ' = ' + value_variate_num + ';';

    var code = '...;\n';
    return code;
};

Blockly.Arduino.forBlock['arduino_nrf24l01_data_ready'] = function () {

    var code = 'Mirf.dataReady()';

    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['arduino_if'] = function () {
    var value_if_is_true = Blockly.Arduino.valueToCode(this, 'if_is_true', Blockly.Arduino.ORDER_ATOMIC);
    var statements_if_carry_out = Blockly.Arduino.statementToCode(this, 'if_carry_out');
    var dropdown_variate_type = this.getFieldValue('variate_type');
    var text_variate_name = this.getFieldValue('variate_name');

    Blockly.Arduino.definitions_['var_declare' + text_variate_name] = dropdown_variate_type + ' ' + text_variate_name + ';';

    if (value_if_is_true == "") {
        value_if_is_true = "false";
    }

    var code = 'if(' + value_if_is_true + ')' +
        '\n{' +
        '\n' + statements_if_carry_out +
        '\n  ' + text_variate_name + ' = (' + dropdown_variate_type + ')((data[1] << 8) | data[0]);' +
        '\n}\n';
    return code;
};

Blockly.Arduino.forBlock['arduino_if_1'] = function () {
    var value_if_is_true = Blockly.Arduino.valueToCode(this, 'if_is_true', Blockly.Arduino.ORDER_ATOMIC);
    var statements_if_carry_out = Blockly.Arduino.statementToCode(this, 'if_carry_out');
    var value_get_variate_1 = Blockly.Arduino.valueToCode(this, 'get_variate_1', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['var_declare' + value_get_variate_1] = 'unsigned int' + ' ' + value_get_variate_1 + ';';

    if (value_if_is_true == "") {
        value_if_is_true = "false";
    }

    var code = 'byte data[Mirf.payload];' +
        '\nif(' + value_if_is_true + ')' +
        '\n{' +
        //'\n' + statements_if_carry_out +
        '\n  Mirf.getData(data);' +
        '\n  ' + value_get_variate_1 + ' = (unsigned int)((data[1] << 8) | data[0]);' +
        '\n' + statements_if_carry_out +
        '\n}\n';
    return code;
};

Blockly.Arduino.forBlock['arduino_nrf24l01_get_data'] = function () {

    var code = 'Mirf.getData(data);\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_nrf24l01_begin'] = function () {
    var value_nrf24l01_ce = Blockly.Arduino.valueToCode(this, 'nrf24l01_ce', Blockly.Arduino.ORDER_ATOMIC);
    var value_nrf24l01_csn = Blockly.Arduino.valueToCode(this, 'nrf24l01_csn', Blockly.Arduino.ORDER_ATOMIC);
    var statements_nrf24l01_setting = Blockly.Arduino.statementToCode(this, 'nrf24l01_setting');

    Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['include_Mirf'] = '#include <Mirf.h>';
    Blockly.Arduino.definitions_['include_nRF24L01'] = '#include <nRF24L01.h>';
    Blockly.Arduino.definitions_['include_MirfHardwareSpiDriver'] = '#include <MirfHardwareSpiDriver.h>';

    Blockly.Arduino.setups_['setup_nrf24l01_begin'] = 'Mirf.cePin = ' + value_nrf24l01_ce + ';'
        + '\n  Mirf.csnPin = ' + value_nrf24l01_csn + ';'
        + '\n  Mirf.spi = &MirfHardwareSpi;'
        + '\n  Mirf.init();'
        + '\n' + statements_nrf24l01_setting + '  Mirf.config();';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_nrf24l01_setRADDR'] = function () {
    var value_nrf24l01_set_data = Blockly.Arduino.valueToCode(this, 'nrf24l01_set_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'Mirf.setRADDR((byte *)' + value_nrf24l01_set_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_nrf24l01_payload'] = function () {
    var value_nrf24l01_set_data = Blockly.Arduino.valueToCode(this, 'nrf24l01_set_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'Mirf.payload = ' + value_nrf24l01_set_data + ';\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_nrf24l01_payload_return'] = function () {
    var code = 'Mirf.payload';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_nrf24l01_channel'] = function () {
    var value_nrf24l01_set_data = Blockly.Arduino.valueToCode(this, 'nrf24l01_set_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'Mirf.channel = ' + value_nrf24l01_set_data + ';\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_nrf24l01_sendData'] = function () {
    var value_nrf24l01_send_data = Blockly.Arduino.valueToCode(this, 'nrf24l01_send_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_nrf24l01_settaddr = Blockly.Arduino.valueToCode(this, 'nrf24l01_settaddr', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'Mirf.setTADDR((byte *)' + value_nrf24l01_settaddr + ');'
        + '\nMirf.send(' + value_nrf24l01_send_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_nrf24l01_isSending'] = function () {
    var code = 'Mirf.isSending()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_nrf24l01_dataReady'] = function () {
    var code = 'Mirf.dataReady()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_nrf24l01_getData'] = function () {
    var value_nrf24l01_get_data = Blockly.Arduino.valueToCode(this, 'nrf24l01_get_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'Mirf.getData(' + value_nrf24l01_get_data + ');\n';
    return code;
};

//初始化nRF24L01无线通信模块
Blockly.Arduino.forBlock['make_arduino_rf24_begin'] = function () {
    var text_name = this.getFieldValue('name');
    var value_ce = Blockly.Arduino.valueToCode(this, 'ce', Blockly.Arduino.ORDER_ATOMIC);
    var value_csn = Blockly.Arduino.valueToCode(this, 'csn', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['include_nRF24L01'] = '#include "nRF24L01.h"';
    Blockly.Arduino.definitions_['include_RF24'] = '#include "RF24.h"';

    Blockly.Arduino.definitions_['var_declare_rf24' + text_name] = 'RF24 ' + text_name + '(' + value_ce + ', ' + value_csn + ');';
    Blockly.Arduino.setups_['setup_rf24_' + text_name] = text_name + '.begin();';
    var code = '';
    return code;
};

//nRF24L01无线通信模块 获取数据
Blockly.Arduino.forBlock['make_arduino_rf24_get_data'] = function () {
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    var code = '';
    if (dropdown_type == 'failureDetected') {
        code = text_name + '.' + dropdown_type;
    }
    else {
        code = text_name + '.' + dropdown_type + '()';
    }
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//nRF24L01无线通信模块 执行某些函数
Blockly.Arduino.forBlock['make_arduino_rf24_do'] = function () {
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    if (dropdown_type == 'printDetails') {
        Blockly.Arduino.definitions_['include_printf'] = '#include "printf.h"';
        Blockly.Arduino.setups_['setup_printf_begin'] = 'printf_begin();';
        var code = text_name + '.' + dropdown_type + '();\n';
    }
    else {
        var code = text_name + '.' + dropdown_type + '();\n';
    }

    return code;
};

//nRF24L01无线通信模块 打开发送管道
Blockly.Arduino.forBlock['make_arduino_rf24_openWritingPipe'] = function () {
    var text_name = this.getFieldValue('name');
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.openWritingPipe(' + value_address + ');\n';
    return code;
};

//nRF24L01无线通信模块 打开接收管道
Blockly.Arduino.forBlock['make_arduino_rf24_openReadingPipe'] = function () {
    var text_name = this.getFieldValue('name');
    var value_number = Blockly.Arduino.valueToCode(this, 'number', Blockly.Arduino.ORDER_ATOMIC);
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.openReadingPipe(' + value_number + ', ' + value_address + ');\n';
    return code;
};

//nRF24L01无线通信模块 接收管道编号
Blockly.Arduino.forBlock['make_arduino_rf24_pipe_type'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//nRF24L01无线通信模块 关闭接收管道
Blockly.Arduino.forBlock['make_arduino_rf24_closeReadingPipe'] = function () {
    var text_name = this.getFieldValue('name');
    var value_number = Blockly.Arduino.valueToCode(this, 'number', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.closeReadingPipe(' + value_number + ');\n';
    return code;
};

//nRF24L01无线通信模块 接收到数据？ 保存接收管道编号到变量
Blockly.Arduino.forBlock['make_arduino_rf24_available'] = function () {
    var text_name = this.getFieldValue('name');
    var value_pipe_num = Blockly.Arduino.valueToCode(this, 'pipe_num', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.available(&' + value_pipe_num + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//nRF24L01无线通信模块 设置地址宽度
Blockly.Arduino.forBlock['make_arduino_rf24_setAddressWidth'] = function () {
    var value_width = Blockly.Arduino.valueToCode(this, 'width', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    var code = text_name + '.setAddressWidth(' + value_width + ');\n';
    return code;
};

//nRF24L01无线通信模块 定义可用的地址宽度
Blockly.Arduino.forBlock['make_arduino_rf24_AddressWidth_data'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//nRF24L01无线通信模块 设置射频通道
Blockly.Arduino.forBlock['make_arduino_rf24_setChannel'] = function () {
    var value_channel = Blockly.Arduino.valueToCode(this, 'channel', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    var code = text_name + '.setChannel(' + value_channel + ');\n';
    return code;
};

//nRF24L01无线通信模块 设置射频功率
Blockly.Arduino.forBlock['make_arduino_rf24_setPALevel'] = function () {
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_name + '.setPALevel(' + dropdown_type + ');\n';
    return code;
};

//nRF24L01无线通信模块 设置空中波特率
Blockly.Arduino.forBlock['make_arduino_rf24_setDataRate'] = function () {
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_name + '.setDataRate(' + dropdown_type + ');\n';
    return code;
};

//nRF24L01无线通信模块 设置CRC校验的校验长度
Blockly.Arduino.forBlock['make_arduino_rf24_setCRCLength'] = function () {
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    var code = text_name + '.setCRCLength(' + value_length + ');\n';
    return code;
};

//nRF24L01无线通信模块 可设置的CRC校验的校验长度类型
Blockly.Arduino.forBlock['make_arduino_rf24_setCRCLength_data'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//nRF24L01无线通信模块 设置静态载荷的长度
Blockly.Arduino.forBlock['make_arduino_rf24_setPayloadSize'] = function () {
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    var code = text_name + '.setPayloadSize(' + value_length + ');\n';
    return code;
};

//nRF24L01无线通信模块 启用或禁用自动应答
Blockly.Arduino.forBlock['make_arduino_rf24_setAutoAck_all'] = function () {
    var value_enable = Blockly.Arduino.valueToCode(this, 'enable', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    var code = text_name + '.setAutoAck(' + value_enable + ');\n';
    return code;
};

//开启 - 关闭
Blockly.Arduino.forBlock['make_arduino_open_close'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//nRF24L01无线通信模块 在某个管道上启用或禁用自动应答
Blockly.Arduino.forBlock['make_arduino_rf24_setAutoAck'] = function () {
    var value_pipe = Blockly.Arduino.valueToCode(this, 'pipe', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    var value_enable = Blockly.Arduino.valueToCode(this, 'enable', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.setAutoAck(' + value_pipe + ', ' + value_enable + ');\n';
    return code;
};

//nRF24L01无线通信模块 设置自动重发延时和发送次数
Blockly.Arduino.forBlock['make_arduino_rf24_setRetries'] = function () {
    var value_delay = Blockly.Arduino.valueToCode(this, 'delay', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    var value_count = Blockly.Arduino.valueToCode(this, 'count', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.setRetries(' + value_delay + ', ' + value_count + ');\n';
    return code;
};

//nRF24L01无线通信模块 屏蔽中断
Blockly.Arduino.forBlock['make_arduino_rf24_maskIRQ'] = function () {
    var text_name = this.getFieldValue('name');
    var value_tx_ok = Blockly.Arduino.valueToCode(this, 'tx_ok', Blockly.Arduino.ORDER_ATOMIC);
    var value_tx_fail = Blockly.Arduino.valueToCode(this, 'tx_fail', Blockly.Arduino.ORDER_ATOMIC);
    var value_rx_ready = Blockly.Arduino.valueToCode(this, 'rx_ready', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.maskIRQ(' + value_tx_ok + ', ' + value_tx_fail + ', ' + value_rx_ready + ');\n';
    return code;
};

//nRF24L01无线通信模块 获取中断
Blockly.Arduino.forBlock['make_arduino_rf24_whatHappened'] = function () {
    var text_name = this.getFieldValue('name');
    var value_tx_ok = Blockly.Arduino.valueToCode(this, 'tx_ok', Blockly.Arduino.ORDER_ATOMIC);
    var value_tx_fail = Blockly.Arduino.valueToCode(this, 'tx_fail', Blockly.Arduino.ORDER_ATOMIC);
    var value_rx_ready = Blockly.Arduino.valueToCode(this, 'rx_ready', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.whatHappened(' + value_tx_ok + ', ' + value_tx_fail + ', ' + value_rx_ready + ');\n';
    return code;
};

//nRF24L01无线通信模块 发送数据
Blockly.Arduino.forBlock['make_arduino_rf24_write'] = function () {
    var text_name = this.getFieldValue('name');
    var value_buf = Blockly.Arduino.valueToCode(this, 'buf', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_type = this.getFieldValue('type');
    var value_len = Blockly.Arduino.valueToCode(this, 'len', Blockly.Arduino.ORDER_ATOMIC);
    var value_multicast = Blockly.Arduino.valueToCode(this, 'multicast', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.' + dropdown_type + '(&' + value_buf + ', ' + value_len + ', ' + value_multicast + ');\n';
    return code;
};

//nRF24L01无线通信模块 发送数据，返回发送结果
Blockly.Arduino.forBlock['make_arduino_rf24_write_return'] = function () {
    var text_name = this.getFieldValue('name');
    var value_buf = Blockly.Arduino.valueToCode(this, 'buf', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_type = this.getFieldValue('type');
    var value_len = Blockly.Arduino.valueToCode(this, 'len', Blockly.Arduino.ORDER_ATOMIC);
    var value_multicast = Blockly.Arduino.valueToCode(this, 'multicast', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.' + dropdown_type + '(&' + value_buf + ', ' + value_len + ', ' + value_multicast + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//nRF24L01无线通信模块 发送数据(可设置超时时间)
Blockly.Arduino.forBlock['make_arduino_rf24_writeBlocking'] = function () {
    var text_name = this.getFieldValue('name');
    var value_buf = Blockly.Arduino.valueToCode(this, 'buf', Blockly.Arduino.ORDER_ATOMIC);
    var value_len = Blockly.Arduino.valueToCode(this, 'len', Blockly.Arduino.ORDER_ATOMIC);
    var value_timeout = Blockly.Arduino.valueToCode(this, 'timeout', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.writeBlocking(&' + value_buf + ', ' + value_len + ', ' + value_timeout + ');\n';
    return code;
};

//nRF24L01无线通信模块 发送数据(可设置超时时间)，返回发送结果
Blockly.Arduino.forBlock['make_arduino_rf24_writeBlocking_return'] = function () {
    var text_name = this.getFieldValue('name');
    var value_buf = Blockly.Arduino.valueToCode(this, 'buf', Blockly.Arduino.ORDER_ATOMIC);
    var value_len = Blockly.Arduino.valueToCode(this, 'len', Blockly.Arduino.ORDER_ATOMIC);
    var value_timeout = Blockly.Arduino.valueToCode(this, 'timeout', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.writeBlocking(&' + value_buf + ', ' + value_len + ', ' + value_timeout + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//nRF24L01无线通信模块 写入ACK数据包
Blockly.Arduino.forBlock['make_arduino_rf24_writeAckPayload'] = function () {
    var text_name = this.getFieldValue('name');
    var value_pipe = Blockly.Arduino.valueToCode(this, 'pipe', Blockly.Arduino.ORDER_ATOMIC);
    var value_buf = Blockly.Arduino.valueToCode(this, 'buf', Blockly.Arduino.ORDER_ATOMIC);
    var value_len = Blockly.Arduino.valueToCode(this, 'len', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.writeAckPayload(' + value_pipe + ', &' + value_buf + ', ' + value_len + ');\n';
    return code;
};

//nRF24L01无线通信模块 读取数据
Blockly.Arduino.forBlock['make_arduino_rf24_read'] = function () {
    var text_name = this.getFieldValue('name');
    var value_buf = Blockly.Arduino.valueToCode(this, 'buf', Blockly.Arduino.ORDER_ATOMIC);
    var value_len = Blockly.Arduino.valueToCode(this, 'len', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.read(&' + value_buf + ', ' + value_len + ');\n';
    return code;
};

//nRF24L01无线通信模块 数据长度定义
Blockly.Arduino.forBlock['make_arduino_rf24_length'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//nRF24L01无线通信模块 射频通道定义
Blockly.Arduino.forBlock['make_arduino_rf24_channel'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//nRF24L01无线通信模块 重发次数定义
Blockly.Arduino.forBlock['make_arduino_rf24_count'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化315/433MHZ无线通信模块的发送管脚
Blockly.Arduino.forBlock['make_arduino_mhz_send_begin'] = function () {
    this.setTooltip("初始化315/433MHZ无线通信模块的发送管脚");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var value_mhz_send_pin = Blockly.Arduino.valueToCode(this, 'mhz_send_pin', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_RCSwitch'] = '#include <RCSwitch.h>';
    Blockly.Arduino.definitions_['var_declare_mhz' + text_mhz_name] = 'RCSwitch ' + text_mhz_name + ' = RCSwitch();';
    Blockly.Arduino.setups_['setup_mhz_' + text_mhz_name + '_send'] = '' + text_mhz_name + '.enableTransmit(' + value_mhz_send_pin + ');';
    var code = '';
    return code;
};

//初始化315/433MHZ无线通信模块的接收管脚
Blockly.Arduino.forBlock['make_arduino_mhz_receive_begin'] = function () {
    this.setTooltip("初始化315/433MHZ无线通信模块的接收管脚");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var value_mhz_receive_pin = Blockly.Arduino.valueToCode(this, 'mhz_receive_pin', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_RCSwitch'] = '#include <RCSwitch.h>';
    Blockly.Arduino.definitions_['var_declare_mhz' + text_mhz_name] = 'RCSwitch ' + text_mhz_name + ' = RCSwitch();';
    Blockly.Arduino.setups_['setup_mhz_' + text_mhz_name + '_receive'] = '' + text_mhz_name + '.enableReceive(' + value_mhz_receive_pin + ');';
    var code = '';
    return code;
};

//初始化315/433MHZ无线通信模块的发送管脚和接收管脚
Blockly.Arduino.forBlock['make_arduino_mhz_send_receive_begin'] = function () {
    this.setTooltip("初始化315/433MHZ无线通信模块的发送管脚和接收管脚");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var value_mhz_send_pin = Blockly.Arduino.valueToCode(this, 'mhz_send_pin', Blockly.Arduino.ORDER_ATOMIC);
    var value_mhz_receive_pin = Blockly.Arduino.valueToCode(this, 'mhz_receive_pin', Blockly.Arduino.ORDER_ATOMIC);


    Blockly.Arduino.definitions_['include_RCSwitch'] = '#include <RCSwitch.h>';
    Blockly.Arduino.definitions_['var_declare_mhz' + text_mhz_name] = 'RCSwitch ' + text_mhz_name + ' = RCSwitch();';
    Blockly.Arduino.setups_['setup_mhz_' + text_mhz_name + '_send'] = '' + text_mhz_name + '.enableTransmit(' + value_mhz_send_pin + ');';
    Blockly.Arduino.setups_['setup_mhz_' + text_mhz_name + '_receive'] = '' + text_mhz_name + '.enableReceive(' + value_mhz_receive_pin + ');';
    var code = '';
    return code;
};

//315/433MHZ无线通信模块设置脉冲长度
Blockly.Arduino.forBlock['make_arduino_mhz_setPulseLength'] = function () {
    this.setTooltip("315/433MHZ无线通信模块设置发送数据时所用的脉冲长度，默认是350微秒");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var value_mhz_pulselength = Blockly.Arduino.valueToCode(this, 'mhz_pulselength', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_mhz_name + '.setPulseLength(' + value_mhz_pulselength + ');\n';
    return code;
};

//315/433MHZ无线通信模块设置发送协议
Blockly.Arduino.forBlock['make_arduino_mhz_setProtocol'] = function () {
    this.setTooltip("315/433MHZ无线通信模块设置发送数据时所用的通信协议，默认使用协议1");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var value_mhz_protocol_type = Blockly.Arduino.valueToCode(this, 'mhz_protocol_type', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_mhz_name + '.setProtocol(' + value_mhz_protocol_type + ');\n';
    return code;
};

//315/433MHZ无线通信模块 协议种类
Blockly.Arduino.forBlock['make_arduino_mhz_setProtocol_type'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//315/433MHZ无线通信模块设置发送端数据发送重复次数
Blockly.Arduino.forBlock['make_arduino_mhz_setRepeatTransmit'] = function () {
    this.setTooltip("315/433MHZ无线通信模块设置发送端数据发送重复次数，默认为10");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var value_mhz_repeat_data = Blockly.Arduino.valueToCode(this, 'mhz_repeat_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_mhz_name + '.setRepeatTransmit(' + value_mhz_repeat_data + ');\n';
    return code;
};

//315/433MHZ无线通信模块设置接收数据允许误差
Blockly.Arduino.forBlock['make_arduino_mhz_setReceiveTolerance'] = function () {
    this.setTooltip("315/433MHZ无线通信模块设置接收数据允许误差，默认为60");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var value_mhz_tolerance_data = Blockly.Arduino.valueToCode(this, 'mhz_tolerance_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_mhz_name + '.setReceiveTolerance(' + value_mhz_tolerance_data + ');\n';
    return code;
};

//315/433MHZ无线通信模块发送十进制数据
Blockly.Arduino.forBlock['make_arduino_mhz_send_decimal_code'] = function () {
    this.setTooltip("315/433MHZ无线通信模块发送十进制数据，发送长度最大为24，若超出则将不会发送数据");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var value_mhz_send_data = Blockly.Arduino.valueToCode(this, 'mhz_send_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_mhz_send_length = Blockly.Arduino.valueToCode(this, 'mhz_send_length', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_mhz_name + '.send(' + value_mhz_send_data + ', ' + value_mhz_send_length + ');\n';
    return code;
};

//315/433MHZ无线通信模块发送二进制数据
Blockly.Arduino.forBlock['make_arduino_mhz_send_binary_code'] = function () {
    this.setTooltip("315/433MHZ无线通信模块发送二进制数据，发送长度最大为24，若超出则将不会发送数据");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var value_mhz_send_data = Blockly.Arduino.valueToCode(this, 'mhz_send_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_mhz_name + '.send(' + value_mhz_send_data + ');\n';
    return code;
};

//315/433MHZ无线通信模块发送三态码
Blockly.Arduino.forBlock['make_arduino_mhz_send_tri_state_code'] = function () {
    this.setTooltip("315/433MHZ无线通信模块发送三态码");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var value_mhz_send_data = Blockly.Arduino.valueToCode(this, 'mhz_send_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_mhz_name + '.sendTriState(' + value_mhz_send_data + ');\n';
    return code;
};

//315/433MHZ无线通信模块 接收到数据？
Blockly.Arduino.forBlock['make_arduino_mhz_available'] = function () {
    this.setTooltip("315/433MHZ是否接收到数据，返回数据的类型为boolean");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var code = '' + text_mhz_name + '.available()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//315/433MHZ无线通信模块 接收数据
Blockly.Arduino.forBlock['make_arduino_mhz_get_data'] = function () {
    this.setTooltip("315/433MHZ无线通信模块 获取数据、比特数、脉冲长度、通信协议、数据包");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var dropdown_get_type = this.getFieldValue('get_type');
    var code = text_mhz_name + '.' + dropdown_get_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//315/433MHZ无线通信模块 重置接收
Blockly.Arduino.forBlock['make_arduino_mhz_resetAvailable'] = function () {
    this.setTooltip("在每次使用mySwitch.available()接受完数据后，都需要用此函数重置一下接收，然后才可以接收下一串数据");

    var text_mhz_name = this.getFieldValue('mhz_name');
    var code = text_mhz_name + '.resetAvailable();\n';
    return code;
};


// BLE服务器初始化代码生成
Blockly.Arduino.forBlock['make_arduino_ble_server_begin'] = function(block) {
  const deviceName = Blockly.Arduino.valueToCode(this, 'DEVICE_NAME', Blockly.Arduino.ORDER_ATOMIC) || '"ESP32_BLE_Server"';

  // 添加BLE库引用
  Blockly.Arduino.definitions_['include_ble_device'] = '#include <BLEDevice.h>';
  Blockly.Arduino.definitions_['include_ble_server'] = '#include <BLEServer.h>';
  Blockly.Arduino.definitions_['include_ble_utils'] = '#include <BLEUtils.h>';
  Blockly.Arduino.definitions_['include_ble_2902'] = '#include <BLE2902.h>';

  // UUID定义 
    const serviceUUID = Blockly.Arduino.valueToCode(this, 'SERVICE_UUID', Blockly.Arduino.ORDER_ATOMIC);
    const characteristicUUID = Blockly.Arduino.valueToCode(this, 'CHARACTERISTIC_UUID', Blockly.Arduino.ORDER_ATOMIC);


    Blockly.Arduino.definitions_['var_ble_service_uuid'] = 'const char* SERVICE_UUID = ' + (serviceUUID || '""') + ';\nconst char* CHARACTERISTIC_UUID = ' + (characteristicUUID || '""') + ';';


  // 全局变量
  Blockly.Arduino.definitions_['var_ble_characteristic'] = 'BLECharacteristic *pCharacteristic;';
  Blockly.Arduino.definitions_['var_device_connected'] = 'bool deviceConnected = false;\n ' +
  'String ClientMessage = "";  // 存储接收到的消息\n' +
  'bool newMessageAvailable = false;  // 新消息标志;';

  // 服务器回调类
  Blockly.Arduino.definitions_['class_my_server_callbacks'] = 
    'class MyServerCallbacks : public BLEServerCallbacks {\n' +
    '  void onConnect(BLEServer* pServer) {\n' +
    '        deviceConnected = true;\n' +
    '        Serial.println("客户端已连接");\n' +
    '  }\n' +
    '  void onDisconnect(BLEServer* pServer) {\n' +
'        deviceConnected = false;\n' +
'        Serial.println("客户端已断开");\n' +
'        pServer->getAdvertising()->start(); // 重启广播以允许重新连接\n' +
    '  }\n' +
    '};';

  // 提取发送功能为单独函数
  Blockly.Arduino.definitions_['function_sendtoclient'] = 'void sendtoclientMessage(String message) {\n' + 
  '  if (pCharacteristic && deviceConnected) {\n' + 
  '    message = message.substring(0, 20); // 限制BLE消息长度\n' + 
  '    pCharacteristic->setValue(message.c_str());\n' + 
  '    pCharacteristic->notify();\n' + 
  '  }\n' + 
  '}';
  // 定义回调函数
  Blockly.Arduino.definitions_['class_my_characteristic_callbacks'] = 
  'class MyCharacteristicCallbacks : public BLECharacteristicCallbacks {\n' +
    'void onWrite(BLECharacteristic *pCharacteristic) {\n' +
    '  std::string value = pCharacteristic->getValue();\n' +
    '  if (!value.empty()) {\n' +
    '  ClientMessage = "";\n' +
    '  for (int i = 0; i < value.length(); i++) {\n' +
    '  ClientMessage += (char)value[i];\n' +
    '    ClientMessage = String(value.c_str());\n' +
    '    newMessageAvailable = true;\n' +
    '    }\n' +
    '   }\n' +
    '  }\n' +
    '};';
  // Setup代码
  Blockly.Arduino.setups_['setup_ble_init'] = 
    'BLEDevice::init(' + deviceName + ');\n' +
    'BLEServer *pServer = BLEDevice::createServer();\n' +
    'pServer->setCallbacks(new MyServerCallbacks());\n' +
    'BLEService *pService = pServer->createService(SERVICE_UUID);\n' +
    'pCharacteristic = pService->createCharacteristic(\n' +
    '  CHARACTERISTIC_UUID,\n' +
    '  BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY\n' +
    ');\n' +
    'pCharacteristic->setCallbacks(new MyCharacteristicCallbacks());\n' +
    'pCharacteristic->addDescriptor(new BLE2902());\n' +
    'pService->start();\n' +
    'pServer->getAdvertising()->start();\n' +
    'Serial.println("等待客户端连接...");';

  return '';
};

// 处理接收到客户端消息
Blockly.Arduino.forBlock['BLEClientMessage'] = function(block) {
    var message = Blockly.Arduino.statementToCode(this, 'DO');
    message = message.replace(/(^\s*)|(\s*$)/g, "");
  return 'if (newMessageAvailable && deviceConnected) {\n' +
         '  String message = ClientMessage.substring(0, 20);\n' +
'  pCharacteristic->setValue(message.c_str());\n' +
'  pCharacteristic->notify();\n' +
'  ' + message + '\n' +
'  newMessageAvailable = false;\n' +
         '}\n';
};

// 发送消息给客户端积木生成器
Blockly.Arduino.forBlock['make_arduino_ble_send_message'] = function(block) {
  const data = Blockly.Arduino.valueToCode(this, 'MESSAGE', Blockly.Arduino.ORDER_ATOMIC);
  return 'sendtoclientMessage(String(' + data + '));\n';
};

// BLE客户端初始化代码生成器
Blockly.Arduino.forBlock['make_arduino_ble_client_begin'] = function(block) {
  const address = Blockly.Arduino.valueToCode(this, 'ADDRESS', Blockly.Arduino.ORDER_ATOMIC);
  var clientName = this.getFieldValue('CLIENT_NAME');

  // 添加BLE客户端库
  Blockly.Arduino.definitions_['include_ble_client'] = '#include <BLEDevice.h>\n' + 
  ' #include <BLEClient.h>\n' + 
  '#include <BLERemoteCharacteristic.h>';

  // 定义客户端和特征变量及UUID
  Blockly.Arduino.definitions_[`var_${clientName}`] = `BLEClient* ${clientName} = nullptr;\nBLERemoteCharacteristic* pRemoteCharacteristic = nullptr;`;
const serviceUuid = Blockly.Arduino.valueToCode(this, 'SERVICE_UUID', Blockly.Arduino.ORDER_ATOMIC);
const charUuid = Blockly.Arduino.valueToCode(this, 'CHAR_UUID', Blockly.Arduino.ORDER_ATOMIC);

Blockly.Arduino.definitions_['var_ble_uuids'] = 'const char* serviceUUID = ' + (serviceUuid || '""') + ';\nconst char* charUUID = ' + (charUuid || '""') + ';';
  Blockly.Arduino.definitions_[`var_${clientName}_address`] = `const char* bleServerAddress = ` + address + ';\n' + 
  '// 添加全局变量存储接收到的消息和发送标志\n' + 
  ' String ServerMessage = "";\n' + 
  ' volatile bool newMessageReceived = false; // 使用volatile确保多线程可见性\n' + 
  ' // 新增变量用于判断是否短时间内重复接收\n' + 
  ' unsigned long lastReceiveTime = 0;\n' + 
  ' const long debounceDelay = 100; // 防抖时间（单位：毫秒）\n' + 
  ' // 新增：发送回显过滤变量\n' + 
  ' String lastSentMessage = "";          // 最后发送的消息\n' + 
  ' unsigned long lastSentTime = 0;       // 最后发送时间\n' + 
  ' const long echoIgnoreWindow = 200;    // 回显忽略时间窗口(ms)';
  // 客户端回调类定义
  Blockly.Arduino.definitions_['class_ble_client_callback'] = 'class MyClientCallback : public BLEClientCallbacks {\n' + 
  ' public:\n ' + 
  '  void onConnect(BLEClient* ESP32BLE) {\n ' + 
  '    Serial.println("已连接到服务器");\n ' + 
  '  }\n ' + 
  '  void onDisconnect(BLEClient* ESP32BLE) {\n ' + 
  '    Serial.println("已断开与服务器的连接");\n ' + 
  '  }\n' + 
  ' };\n' + 
  ' // 提取发送功能为单独函数\n' + 
  ' void sendtoserverMessage(String message) {\n ' + 
  '  if (pRemoteCharacteristic && pRemoteCharacteristic->canWrite()) {\n ' + 
  '    message = message.substring(0, 20); // 限制BLE消息长度\n ' + 
  '    pRemoteCharacteristic->writeValue(message.c_str());\n ' +     // 记录发送的消息和时间
  '    lastSentMessage = message;\n' +
  '    lastSentTime = millis();\n' +
  '  }\n' + 
  ' }'

  // 连接服务器函数
  Blockly.Arduino.definitions_['function_connect_to_server'] = 'void connectToServer(BLEAddress address) {\n' +
  '  if (!ESP32BLE->connect(address)) {\n' +
  '    Serial.println("连接失败");\n' +
  '    return;\n' +
  '  }\n' +
  '\n' +
  '  BLERemoteService* pRemoteService = ESP32BLE->getService(serviceUUID);\n' +
  '  if (pRemoteService == nullptr) {\n' +
  '    Serial.println("未找到服务");\n' +
  '    return;\n' +
  '  }\n' +
  '\n' +
  '  pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);\n' +
  '  if (pRemoteCharacteristic == nullptr) {\n' +
  '    Serial.println("未找到特征");\n' +
  '    return;\n' +
  '  }\n' +
  '\n' +
  '  if (pRemoteCharacteristic->canNotify()) {\n' +
  '    pRemoteCharacteristic->registerForNotify([](BLERemoteCharacteristic* pChar, uint8_t* data, size_t length, bool isNotify) {\n' +
  '      String incoming = String((char*)data, length);\n' +
  '      unsigned long currentMillis = millis();\n' +
  '    if (lastSentMessage != "" && \n' +
  '       incoming == lastSentMessage && \n' +
  '       (currentMillis - lastSentTime) < echoIgnoreWindow) \n' +
  '   {\n' +
  '     lastSentMessage = ""; // 重置标记\n' +
  '     return; // 直接退出，不处理该消息\n' +
  '    }\n' +
  '      // 判断是否在去重时间范围内\n' +
  '      if ((currentMillis - lastReceiveTime) > debounceDelay || incoming != ServerMessage) {\n' +
  '        ServerMessage = incoming;\n' +
  '        newMessageReceived = true;\n' +
  '        lastReceiveTime = currentMillis; // 更新最后收到时间\n' +
  '      } else {\n' +
  '        Serial.println("忽略短时间内重复的消息");\n' +
  '      }\n' +
  '    });\n' +
  '    Serial.println("已订阅特征通知");\n' +
  '  } else {\n' +
  '    Serial.println("特征不支持通知");\n' +
  '  }\n' +
  '}';

  // 初始化代码
  Blockly.Arduino.setups_['setup_ESP32BLE_init'] = ' BLEDevice::init("");\n' + 
  ' ESP32BLE = BLEDevice::createClient();\n' + 
  ' ESP32BLE->setClientCallbacks(new MyClientCallback());';

  // 连接服务器
  Blockly.Arduino.setups_['setup_ESP32BLE_connect'] = 'BLEAddress address(bleServerAddress);\n' + 
  ' connectToServer(address);';

  return 'if (ESP32BLE && !ESP32BLE->isConnected()) {\n' + 
  '   Serial.println("尝试重新连接...");\n ' + 
  '  BLEAddress reconnectAddress(bleServerAddress);\n' + 
  '   connectToServer(reconnectAddress);\n ' + 
  '  delay(1000); // 防止快速重连\n' + 
  '  // 清理过期的发送记录\n' + 
  '  if (lastSentMessage != "" && (millis() - lastSentTime) > echoIgnoreWindow) {\n' + 
  ' lastSentMessage = "";\n' + 
  ' }\n' + 
  ' }\n';
};

Blockly.Arduino.forBlock['BLECServerMessage'] = function () {
    var branch = Blockly.Arduino.statementToCode(this, 'DO');
    branch = branch.replace(/(^\s*)|(\s*$)/g, "");
    return 'if (newMessageReceived) {\n' + 
   '  '  +     branch + '\n' + 
  ' newMessageReceived = false;   // 重置标志\n' +
  ' }\n';
};
// BLE客户端发送消息代码生成器
Blockly.Arduino.forBlock['make_arduino_ble_client_send'] = function(block) {
  const data = Blockly.Arduino.valueToCode(this, 'DATA', Blockly.Arduino.ORDER_ATOMIC);
  return 'sendtoserverMessage(String(' + data + '));\n';
};



Blockly.Arduino.forBlock['make_arduino_ble_scan_begin'] = function(block) {
  const scanTime = block.getFieldValue('SCAN_TIME');

  // 添加BLE扫描库引用
  Blockly.Arduino.definitions_['include_ble_device'] = '#include <BLEDevice.h>  // 包含BLE设备库';
  Blockly.Arduino.definitions_['include_ble_utils'] = '#include <BLEUtils.h>   // 包含BLE工具库';
  Blockly.Arduino.definitions_['include_ble_scan'] = '#include <BLEScan.h>    // 包含BLE扫描库';

  // 广告设备回调类
  Blockly.Arduino.definitions_['class_my_advertised_device_callbacks'] = 
    'class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {\n' +
    'public:\n' +
    '    void onResult(BLEAdvertisedDevice advertisedDevice) {\n' +
    '        Serial.printf("名称: %s\\n", advertisedDevice.getName().c_str());  // 打印设备名称\n' +
    '        Serial.printf("地址: %s\\n", advertisedDevice.getAddress().toString().c_str());  // 打印设备地址\n' +
    '        Serial.printf("信号强度 (RSSI): %d dBm\\n", advertisedDevice.getRSSI());  // 打印信号强度\n' +
    '        if (advertisedDevice.haveServiceUUID()) {  // 检查是否有服务UUID\n' +
    '            Serial.printf("服务UUID: %s\\n", advertisedDevice.getServiceUUID().toString().c_str());  // 打印服务UUID\n' +
    '        }\n' +
    '        if (advertisedDevice.haveManufacturerData()) {  // 检查是否有制造商数据\n' +
    '            std::string mData = advertisedDevice.getManufacturerData();  // 获取制造商数据\n' +
    '            Serial.printf("制造商数据: ");  // 打印制造商数据\n' +
    '            for (size_t i = 0; i < mData.length(); i++) {\n' +
    '                Serial.printf("%02X ", static_cast<uint8_t>(mData[i]));\n' +
    '            }\n' +
    '            Serial.println();\n' +
    '        }\n' +
    '        Serial.println("----------------------------------------");  // 分隔符\n' +
    '    }\n' +
    '};';

  // Setup代码
  // 检查是否已设置串口波特率，如果没有则自动添加
  var hasSerialBegin = false;
  for (var key in Blockly.Arduino.setups_) {
      if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
          hasSerialBegin = true;
          break;
      }
  }
  if (!hasSerialBegin) {
      Blockly.Arduino.setups_['setup_ble_scan_init'] = 
        'Serial.begin(115200);  // 初始化串口通信，波特率为115200\n' +
        'BLEDevice::init("ESP32");  // 初始化BLE设备\n' +
        'BLEScan* pScan = BLEDevice::getScan();  // 创建扫描对象\n' +
        'pScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());  // 设置广告设备回调\n' +
        'pScan->setActiveScan(true);  // 设置为主动扫描模式';
  } else {
      Blockly.Arduino.setups_['setup_ble_scan_init'] = 
        'BLEDevice::init("ESP32");  // 初始化BLE设备\n' +
        'BLEScan* pScan = BLEDevice::getScan();  // 创建扫描对象\n' +
        'pScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());  // 设置广告设备回调\n' +
        'pScan->setActiveScan(true);  // 设置为主动扫描模式';
  }

  // Loop代码
  return 'delay(10000);  // 延迟10秒\n' +
         'BLEScan* pScan = BLEDevice::getScan();  // 获取扫描对象\n' +
         'pScan->clearResults();  // 清除扫描结果\n' +
         'pScan->start(10);  // 再次开始扫描10秒\n';
};





Blockly.Arduino.forBlock['wifi_manager_setup_ESP8266'] = function() {
    var timeout = this.getFieldValue('TIMEOUT');
    var apName = this.getFieldValue('AP_NAME');
    var username = this.getFieldValue('USERNAME');
    var password = this.getFieldValue('PASSWORD');

    var hasSerialBegin = false;
    for (var key in Blockly.Arduino.setups_) {
        if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
            hasSerialBegin = true;
            break;
        }
    }
    if (!hasSerialBegin) {
        Blockly.Arduino.setups_['setup_serial_auto'] = 'Serial.begin(115200);';
    }

    Blockly.Arduino.definitions_['include_WiFiManager'] = '#include <WiFiManager.h>';
    Blockly.Arduino.definitions_['include_HTTPUpdateServer'] = '#include <ESP8266HTTPUpdateServer.h>';
    Blockly.Arduino.definitions_['var_wifi_manager'] = 'WiFiManager wm;';
    Blockly.Arduino.definitions_['var_http_server'] = 'ESP8266WebServer server(80);';
    Blockly.Arduino.definitions_['var_http_updater'] = 'ESP8266HTTPUpdateServer httpUpdater;';
    
    Blockly.Arduino.definitions_['function_wifi_keep_alive'] = 
        'void wifi_keep_alive() {\n' +
        '  wm.process();\n' +
        '  server.handleClient();\n' +
        '  delay(0);\n' +
        '}\n';
    
    Blockly.Arduino.setups_['setup_wifi_manager'] = 
        'wm.setConfigPortalBlocking(false);\n' +
        '  wm.setConfigPortalTimeout(' + timeout + ');\n' +
        '  wm.autoConnect("' + apName + '");\n' +
        '  httpUpdater.setup(&server, "' + username + '", "' + password + '");\n' +
        '  server.begin();\n';
    
    var code = 'wifi_keep_alive();\n';
    return code;
};
Blockly.Arduino.forBlock['wifi_manager_setup_ESP32'] = function() {
    var timeout = this.getFieldValue('TIMEOUT');
    var apName = this.getFieldValue('AP_NAME');
    var username = this.getFieldValue('USERNAME');
    var password = this.getFieldValue('PASSWORD');

    var hasSerialBegin = false;
    for (var key in Blockly.Arduino.setups_) {
        if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
            hasSerialBegin = true;
            break;
        }
    }
    if (!hasSerialBegin) {
        Blockly.Arduino.setups_['setup_serial_auto'] = 'Serial.begin(115200);';
    }

    Blockly.Arduino.definitions_['include_WiFiManager'] = '#include <WiFiManager.h>';
    Blockly.Arduino.definitions_['include_HTTPUpdateServer'] = '#include <HTTPUpdateServer.h>';
    Blockly.Arduino.definitions_['var_http_server'] = 'WebServer server(80);';
    Blockly.Arduino.definitions_['var_http_updater'] = 'HTTPUpdateServer httpUpdater;';
    Blockly.Arduino.definitions_['var_wifi_manager'] = 'WiFiManager wm;';
    
    Blockly.Arduino.definitions_['function_wifi_keep_alive'] = 
        'void wifi_keep_alive() {\n' +
        '  wm.process();\n' +
        '  server.handleClient();\n' +
        '  delay(0);\n' +
        '}\n';
    
    Blockly.Arduino.setups_['setup_wifi_manager'] = 
        'wm.setConfigPortalBlocking(false);\n' +
        '  wm.setConfigPortalTimeout(' + timeout + ');\n' +
        '  wm.autoConnect("' + apName + '");\n' +
        '  httpUpdater.setup(&server, "' + username + '", "' + password + '");\n' +
        '  server.begin();\n';
    
    var code = 'wifi_keep_alive();\n';
    return code;
};
Blockly.Arduino.forBlock['make_arduino_describe2'] = function(block) {

  return  '//此模块只是显示如何使用，没有实际功能 \n';

};
Blockly.Arduino.forBlock['wifi_manager_once_connected'] = function() {
    var branch = Blockly.Arduino.statementToCode(this, 'DO');
    var code = 'if (WiFi.status() == 3) {\n' +
               branch + 
               '}\n';
    return code;
};
    Blockly.Arduino.forBlock['wifi_manager_get_ssid'] = function() {
        var code = 'WiFi.SSID()';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    Blockly.Arduino.forBlock['wifi_manager_get_rssi'] = function() {
        var code = 'WiFi.RSSI()';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };
Blockly.Arduino.forBlock['wifi_manager_status'] = function() {
    var code = 'Serial.println(' +
               '(WiFi.status() == WL_IDLE_STATUS ? "Wi-Fi 空闲模式" : ' +
               'WiFi.status() == WL_NO_SSID_AVAIL ? "没有找到可用的SSID" : ' +
               'WiFi.status() == WL_SCAN_COMPLETED ? "扫描完成" : ' +
               'WiFi.status() == WL_CONNECTED ? "已连接到网络" : ' +
               'WiFi.status() == WL_CONNECT_FAILED ? "连接失败" : ' +
               'WiFi.status() == WL_CONNECTION_LOST ? "连接丢失" : ' +
               'WiFi.status() == WL_DISCONNECTED ? "断开连接" : ' +
               '"未知状态"));\n';
    return code;  // 直接返回代码字符串，不使用ORDER_ATOMIC
};

Blockly.Arduino.forBlock['wifi_manager_reset'] = function() {
    Blockly.Arduino.definitions_['include_WiFiManager'] = '#include <WiFiManager.h>';
    
    // 检查是否已设置串口波特率，如果没有则自动添加
    var hasSerialBegin = false;
    for (var key in Blockly.Arduino.setups_) {
        if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
            hasSerialBegin = true;
            break;
        }
    }
    if (!hasSerialBegin) {
        Blockly.Arduino.setups_['setup_serial'] = 'Serial.begin(9600);';
    }
    
    var code = 'WiFiManager wifiManager;\n' +
    'wifiManager.resetSettings();\n' +
    'Serial.println("配网信息已清除");\n';
    
    return code;
};

Blockly.Arduino.forBlock['wifi_enable_esp8266'] = function() {
    Blockly.Arduino.definitions_['include_ESP8266WiFi'] = '#include <ESP8266WiFi.h>';
    var code = 'WiFi.mode(WIFI_STA);\n' +
               'wm.setWiFiAutoReconnect(true);\n' +
               'wm.autoConnect();\n';
    return code;
};

Blockly.Arduino.forBlock['wifi_disable_esp8266'] = function() {
    Blockly.Arduino.definitions_['include_ESP8266WiFi'] = '#include <ESP8266WiFi.h>';
    var code = 'wm.disconnect();\n' +
               'WiFi.mode(WIFI_OFF);\n' +
               'delay(100);\n';
    return code;
};

Blockly.Arduino.forBlock['wifi_enable_esp32'] = function() {
    Blockly.Arduino.definitions_['include_WiFi'] = '#include <WiFi.h>';
    var code = 'WiFi.mode(WIFI_STA);\n' +
               'wm.setWiFiAutoReconnect(true);\n' +
               'wm.autoConnect();\n';
    return code;
};

Blockly.Arduino.forBlock['wifi_disable_esp32'] = function() {
    Blockly.Arduino.definitions_['include_WiFi'] = '#include <WiFi.h>';
    var code = 'wm.disconnect();\n' +
               'WiFi.mode(WIFI_OFF);\n' +
               'delay(100);\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_espnow_begin_esp32'] = function () {

    var txPower = this.getFieldValue('TX_POWER');
    Blockly.Arduino.definitions_['include_WifiEspNow'] = '#include <WifiEspNow.h>';
    Blockly.Arduino.definitions_['include_WiFi'] = '#include <WiFi.h>';
    
    Blockly.Arduino.setups_['setup_espnow'] = 
        'WiFi.mode(WIFI_STA);\n' +
        '  WiFi.setSleep(false);\n' +
        '  WifiEspNow.begin();\n' +
        '  WiFi.setTxPower(' + txPower + ');\n';
    
    return '';
};

// ESPNOW数据发送函数
Blockly.Arduino.forBlock['espnow_send_data_esp32'] = function() {
    var value_mac = Blockly.Arduino.valueToCode(this, 'mac_address', Blockly.Arduino.ORDER_ATOMIC);
    var value_message = Blockly.Arduino.valueToCode(this, 'message', Blockly.Arduino.ORDER_ATOMIC);
    
    // 生成唯一的变量名
    var macVarName = 'peer_mac_' + value_mac.replace(/[^a-zA-Z0-9]/g, '');
    
    // 转换MAC地址格式
    if (value_mac.includes(':')) {
        value_mac = '{' + value_mac.split(':').map(x => '0x' + x).join(', ') + '}';
        value_mac = value_mac.replace(/"|\'/g, '');
    }
    
    var code = 
    '  String message_' + macVarName + ' =  String(' + value_message + ');\n' +
    '  size_t len_' + macVarName + ' = min(message_' + macVarName + '.length(), static_cast<size_t>(250));\n' +
    '  char data_' + macVarName + '[250];\n' +
    '  strncpy(data_' + macVarName + ', message_' + macVarName + '.c_str(), len_' + macVarName + ');\n' +
    '  data_' + macVarName + '[len_' + macVarName + '] = \'\\0\';\n' +
    '  uint8_t ' + macVarName + '[] = ' + value_mac + ';\n' +
    '  bool ok_' + macVarName + ' = WifiEspNow.addPeer(' + macVarName + ', 0, nullptr, WIFI_IF_STA);\n' +
    '  if (!ok_' + macVarName + ') { \n' +
    '    Serial.println("添加接收设备失败");\n' +
    '    return;\n' +
    '  } \n' +
    '  const int maxRetries_' + macVarName + ' = 2; \n' +
    '  for(int i = 0; i <= maxRetries_' + macVarName + '; i++) { \n' +
    '    if(WifiEspNow.send(' + macVarName + ', reinterpret_cast<const uint8_t*>(data_' + macVarName + '), len_' + macVarName + ')) { \n' +
    '      break; \n' +
    '    } \n' +
    '  } ';

    return code;
};


// ESPNOW遥控器接收处理函数
Blockly.Arduino.forBlock['func_printReceivedMessage_esp32'] = function () {
    var branch = Blockly.Arduino.statementToCode(this, 'DO');
    branch = branch.replace(/(^\s*)|(\s*$)/g, "");
    
    Blockly.Arduino.definitions_['func_printReceivedMessage'] = 'void printReceivedMessage(const uint8_t mac[WIFIESPNOW_H], const uint8_t* buf, size_t count, void* arg) {\n'
        + '  static String message = "";\n'
        + '  for (int i = 0; i < static_cast<int>(count); ++i) {\n'
        + '    message += char(buf[i]);\n'
        + '  }\n'
        + '  if(message.length() > 0) {\n'
        +     branch + '\n'
        + '    message = "";\n'
        + '  }\n'
        +'}\n';
        Blockly.Arduino.setups_['setup_func'] = 
        '  WifiEspNow.onReceive(printReceivedMessage, nullptr);\n';

    return '';
};


Blockly.Arduino.forBlock['make_arduino_espnow_begin_esp8266'] = function () {

    var value_channel = this.getFieldValue('channel');
    var power_level = this.getFieldValue('POWER_LEVEL');

    // 添加头文件包含
    Blockly.Arduino.definitions_['include_WifiEspNow'] = '#include <WifiEspNow.h>';
    Blockly.Arduino.definitions_['include_ESP8266WiFi'] = '#include <ESP8266WiFi.h>';
    
    var channel = parseInt(value_channel);
    channel = Math.max(1, Math.min(14, channel));
    
    Blockly.Arduino.setups_['setup_espnow'] = 
        'WiFi.mode(WIFI_STA);\n' +
        '  WiFi.setSleep(false);\n' +
        '  WifiEspNow.begin();\n' +
        '  WiFi.setOutputPower(' + power_level + ');\n';
    return '';
};

// ESPNOW数据发送函数
Blockly.Arduino.forBlock['espnow_send_data_esp8266'] = function() {
    var value_mac = Blockly.Arduino.valueToCode(this, 'mac_address', Blockly.Arduino.ORDER_ATOMIC);
    var value_message = Blockly.Arduino.valueToCode(this, 'message', Blockly.Arduino.ORDER_ATOMIC);
    
    // 生成唯一的变量名
    var macVarName = 'peer_mac_' + value_mac.replace(/[^a-zA-Z0-9]/g, '');
    
    // 转换MAC地址格式
    if (value_mac.includes(':')) {
        value_mac = '{' + value_mac.split(':').map(x => '0x' + x).join(', ') + '}';
        value_mac = value_mac.replace(/"|\'/g, '');
    }
    
    var code = 
    '  String message_' + macVarName + ' = String(' + value_message + ');\n' +
    '  size_t len_' + macVarName + ' = min(message_' + macVarName + '.length(), static_cast<size_t>(250));\n' +
    '  char data_' + macVarName + '[250];\n' +
    '  strncpy(data_' + macVarName + ', message_' + macVarName + '.c_str(), len_' + macVarName + ');\n' +
    '  data_' + macVarName + '[len_' + macVarName + '] = \'\\0\';\n' +
    '  uint8_t ' + macVarName + '[] = ' + value_mac + ';\n' +
    '  bool ok_' + macVarName + ' = WifiEspNow.addPeer(' + macVarName + ');\n' +
    '  if (ok_' + macVarName + ') {\n' +
    '    WifiEspNow.send(' + macVarName + ', reinterpret_cast<const uint8_t*>(data_' + macVarName + '), len_' + macVarName + ');\n' +
    '  } else {\n' +
    '    Serial.println("添加接收设备失败");\n' +
    '  }\n';

    return code;
};


// ESPNOW遥控器接收处理函数
Blockly.Arduino.forBlock['func_printReceivedMessage_esp8266'] = function () {
    var branch = Blockly.Arduino.statementToCode(this, 'DO');
    branch = branch.replace(/(^\s*)|(\s*$)/g, "");
    
    Blockly.Arduino.definitions_['func_printReceivedMessage'] = 'void printReceivedMessage(const uint8_t mac[WIFIESPNOW_H], const uint8_t* buf, size_t count, void* arg) {\n'
        + '  static String message = "";\n'
        + '  for (int i = 0; i < static_cast<int>(count); ++i) {\n'
        + '    message += char(buf[i]);\n'
        + '  }\n'
        + '  if(message.length() > 0) {\n'
        +     branch + '\n'
        + '    message = "";\n'
        + '  }\n'
        +'}\n';
        Blockly.Arduino.setups_['setup_func'] = 
        '  WifiEspNow.onReceive(printReceivedMessage, nullptr);\n';

    return '';
};




Blockly.Arduino.forBlock['make_arduino_ping'] = function() {
  const pingType = this.getFieldValue('PING_TYPE');
  const target = this.getFieldValue('TARGET');
  Blockly.Arduino.definitions_['include_espping'] = '#include <ESPping.h>';
  // 检查是否已设置串口波特率，如果没有则自动添加
  var hasSerialBegin = false;
  for (var key in Blockly.Arduino.setups_) {
      if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
          hasSerialBegin = true;
          break;
      }
  }
  if (!hasSerialBegin) {
      Blockly.Arduino.setups_['setup_serial'] = 'Serial.begin(9600);';
  }

   
  let code = '';
  if (pingType === 'IP') {
    code = `const IPAddress remote_ip(${target.replace(/\./g, ',')});\n` +
           `Serial.print("Ping ");\n` +
           `Serial.print(remote_ip);\n` +
           `if (Ping.ping(remote_ip) > 0){\n` +
           `  Serial.printf(" 响应时间: %.2f ms\\n",  Ping.averageTime());\n` +
           `} else {\n` +
           `  Serial.println(" 失败!");\n` +
           `}\n`;
  } else {
    code = `const char* remote_host = "${target}";\n` +
           `Serial.print("Ping ");\n` +
           `Serial.print(remote_host);\n` +
           `if (Ping.ping(remote_host) > 0){\n` +
           `  Serial.printf(" 响应时间: %.2f ms\\n",  Ping.averageTime());\n` +
           `} else {\n` +
           `  Serial.println(" 失败!");\n` +
           `}\n`;
  }
  return code;
};

Blockly.Arduino.forBlock['get_ping_average_time'] = function() {
  return ['Ping.averageTime()', Blockly.Arduino.ORDER_ATOMIC];
};



    // 定义 MQTT 发布块的代码生成逻辑
    Blockly.Arduino.forBlock['MQTT_publish1'] = function () {
        var data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC); // 获取数据输入字段的代码
        var topic = Blockly.Arduino.valueToCode(this, 'topic', Blockly.Arduino.ORDER_ATOMIC); // 获取主题输入字段的代码
        // 确保数据和主题是字符串格式
        var code = 'mqtt_client.publish(String(' + topic + ').c_str(), String(' + data + ').c_str());\n'; // 生成发布消息的代码
        return code; // 返回生成的代码
    };

    // 定义 MQTT 接收消息块的代码生成逻辑
    Blockly.Arduino.forBlock['MQTT_received_the_news1'] = function () {
        var topic = Blockly.Arduino.valueToCode(this, 'topic', Blockly.Arduino.ORDER_ATOMIC); // 获取主题输入字段的代码
        var branch = Blockly.Arduino.statementToCode(this, 'function'); // 获取函数语句输入字段的代码
        branch = branch.replace(/(^\s*)|(\s*$)/g, ""); // 移除前后空白字符
        Blockly.Arduino.setups_['setups_topic_' + topic] = 'mqtt_client.subscribe(String(' + topic + ').c_str());\n'; // 生成订阅主题的代码
        var code = 'if (mqtt_status) {\n' // 开始 if 语句检查 mqtt_status 是否为真
            + '  if (mqtt_topic.equals(String(' + topic + ').c_str())) {\n' // 再次检查接收到的主题是否匹配
            + '    ' + branch + '\n' // 插入用户定义的函数代码
            + '    mqtt_status = false;\n' // 将 mqtt_status 置为假
            + '  }\n'
            + '}\n';
        return code; // 返回生成的代码
    };

    // 定义 MQTT 订阅和连接块的代码生成逻辑
    Blockly.Arduino.forBlock['MQTT_subscribe_plus1'] = function () {
        var server = Blockly.Arduino.valueToCode(this, 'server', Blockly.Arduino.ORDER_ATOMIC); // 获取服务器地址输入字段的代码
        var port = Blockly.Arduino.valueToCode(this, 'port', Blockly.Arduino.ORDER_ATOMIC); // 获取端口输入字段的代码
        var client_id = Blockly.Arduino.valueToCode(this, 'client_id', Blockly.Arduino.ORDER_ATOMIC); // 获取客户端ID输入字段的代码
        var mqtt_username = Blockly.Arduino.valueToCode(this, 'mqtt_username', Blockly.Arduino.ORDER_ATOMIC); // 获取用户名输入字段的代码
        var mqtt_password = Blockly.Arduino.valueToCode(this, 'mqtt_password', Blockly.Arduino.ORDER_ATOMIC); // 获取密码输入字段的代码
        var will_topic = Blockly.Arduino.valueToCode(this, 'will_topic', Blockly.Arduino.ORDER_ATOMIC); // 获取遗嘱主题输入字段的代码
        var will_message = Blockly.Arduino.valueToCode(this, 'will_message', Blockly.Arduino.ORDER_ATOMIC); // 获取遗嘱消息输入字段的代码
        var will_qos = this.getFieldValue('will_qos'); // 获取遗嘱QoS默认值
        var will_retain = this.getFieldValue('will_retain') === 'TRUE'; // 获取遗嘱保留默认值
        port = port.replace(/\"/g, ""); // 移除端口字符串中的双引号

        // 添加必要的头文件
        Blockly.Arduino.definitions_['include_PubSubClient'] = '#include <PubSubClient.h>\n';
        Blockly.Arduino.definitions_['var_declare_client'] = 'WiFiClient espClient;\nPubSubClient mqtt_client(espClient);\n';;
        // 连接 MQTT 函数
        Blockly.Arduino.definitions_['reconnect_mqtt'] = 
        'void reconnectMQTT() {\n' +
        '    if (!mqtt_client.connected()) {\n' +
        '        // 遗嘱消息配置\n' +
        '        const char* will_topic = ' + will_topic + ';\n' +
        '        const char* will_message = ' + will_message + ';\n' +
        '        int will_qos = ' + will_qos + ';\n' +
        '        bool will_retain = ' + will_retain + ';\n' +
        '        // 尝试连接MQTT服务器 \n' +
        '        if (mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password, will_topic, will_qos, will_retain, will_message)) {\n' +
        '            // 订阅所有主题 \n' +
        '            mqtt_client.subscribe("+");\n' +
        '            mqtt_client.subscribe("#");\n' +
        '        }\n' +
        '    }\n' +
        '}\n';
        // 声明变量和回调函数
        Blockly.Arduino.definitions_['var_declare_PubSubClient'] = 'const char *mqtt_broker = ' + server + ';\n' // 定义 MQTT 代理地址
            + 'const char *mqtt_username = ' + mqtt_username + ';\n' // 定义 MQTT 用户名
            + 'const char *mqtt_password = ' + mqtt_password + ';\n' // 定义 MQTT 密码
            + 'const int mqtt_port = ' + port + ';\n' // 定义 MQTT 端口
            + 'String mqtt_topic = "";\n' // 定义接收的主题
            + 'String mqtt_data = "";\n' // 定义接收的数据
            + 'boolean mqtt_status = false;\n' // 定义 MQTT 连接状态
            + 'String client_id = ' + client_id + ';\n' // 定义客户端ID为全局变量

            + 'void callback(char *topic, byte *payload, unsigned int length) {\n' // 定义回调函数
            + '  String data = "";\n' // 初始化数据字符串
            + '  for (int i = 0; i < length; i++) {\n' // 循环读取 payload 数据
            + '    data += (char) payload[i];\n' // 将每个字节转换为字符并添加到数据字符串中
            + '  }\n'
            + '  mqtt_topic = String(topic);\n' // 设置接收的主题
            + '  mqtt_data = data;\n' // 设置接收的数据
            + '  mqtt_status = true;\n' // 设置 MQTT 状态为真
            + '}\n';
        // 生成MQTT连接和订阅的初始化代码到setup部分
        Blockly.Arduino.setups_['setups_PubSubClient'] = 'mqtt_client.setServer(mqtt_broker, mqtt_port);\n'
            + 'mqtt_client.setCallback(callback);\n'
            + 'if (!mqtt_client.connected()) {\n'
            + '    const char* will_topic = ' + will_topic + ';\n'
            + '    const char* will_message = ' + will_message + ';\n'
            + '    int will_qos = ' + will_qos + ';\n'
            + '    bool will_retain = ' + will_retain + ';\n'
            + '    mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password, will_topic, will_qos, will_retain, will_message);\n'
            + '}\n'
            + 'if (mqtt_client.connected()) {\n'
            + '    mqtt_client.subscribe("+");\n'
            + '    mqtt_client.subscribe("#");\n'
            + '}\n';
        // 生成保持MQTT连接活动的代码
        var code = 'mqtt_client.loop();\n'+
        '   if (!mqtt_client.connected()) { \n' +
        '       reconnectMQTT(); \n' +
        '   } \n' +
        '   delay(0);\n';
        return code;
    };


   // MQTT连接状态检测
    Blockly.Arduino.forBlock['make_arduino_mqtt_connected'] = function () {
        var code = 'mqtt_client.connected()';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // 定义 MQTT TLS/SSL 连接块的代码生成逻辑
    Blockly.Arduino.forBlock['MQTT_subscribe_tls'] = function () {
        var server = Blockly.Arduino.valueToCode(this, 'server', Blockly.Arduino.ORDER_ATOMIC);
        var port = Blockly.Arduino.valueToCode(this, 'port', Blockly.Arduino.ORDER_ATOMIC);
        var client_id = Blockly.Arduino.valueToCode(this, 'client_id', Blockly.Arduino.ORDER_ATOMIC);
        var mqtt_username = Blockly.Arduino.valueToCode(this, 'mqtt_username', Blockly.Arduino.ORDER_ATOMIC);
        var mqtt_password = Blockly.Arduino.valueToCode(this, 'mqtt_password', Blockly.Arduino.ORDER_ATOMIC);
        var ca_cert = Blockly.Arduino.valueToCode(this, 'ca_cert', Blockly.Arduino.ORDER_ATOMIC);
        var ntp_server = Blockly.Arduino.valueToCode(this, 'ntp_server', Blockly.Arduino.ORDER_ATOMIC);
        var gmt_offset = Blockly.Arduino.valueToCode(this, 'gmt_offset', Blockly.Arduino.ORDER_ATOMIC);
        var will_topic = Blockly.Arduino.valueToCode(this, 'will_topic', Blockly.Arduino.ORDER_ATOMIC);
        var will_message = Blockly.Arduino.valueToCode(this, 'will_message', Blockly.Arduino.ORDER_ATOMIC);
        var will_qos = this.getFieldValue('will_qos');
        var will_retain = this.getFieldValue('will_retain') === 'TRUE';
        
        port = port.replace(/"/g, "");
        
        // 添加头文件 - 只包含必要的库（参考示例代码）
        Blockly.Arduino.definitions_['include_pubsubclient'] = '#include <PubSubClient.h>';
        Blockly.Arduino.definitions_['include_time'] = '#include <time.h>';
        
        // 定义全局变量和对象 - 与示例代码保持一致
        Blockly.Arduino.definitions_['var_declare_tls_client'] = 'BearSSL::WiFiClientSecure espClient;\n' +
            'PubSubClient mqtt_client(espClient);\n';
        
        // 定义MQTT服务器配置
        Blockly.Arduino.definitions_['var_declare_mqtt_config'] = 'const char *mqtt_broker = ' + server + ';\n' +
            'const int mqtt_port = ' + port + ';\n' +
            'const char *mqtt_username = ' + mqtt_username + ';\n' +
            'const char *mqtt_password = ' + mqtt_password + ';\n' +
            'String client_id_str = ' + client_id + ';\n' +
            'const char* client_id = client_id_str.c_str();\n' +
            'unsigned long lastReconnectAttempt = 0;\n';

        // 定义接收消息相关变量（用于MQTT_received_the_news1积木）
        Blockly.Arduino.definitions_['var_declare_mqtt_receive'] = 'String mqtt_topic = "";\n' +
            'String mqtt_data = "";\n' +
            'boolean mqtt_status = false;\n';
        
        // 定义NTP配置
        Blockly.Arduino.definitions_['var_declare_ntp_config'] = 'const char *ntp_server = ' + ntp_server + ';\n' +
            'const long gmt_offset_sec = ' + gmt_offset + ';\n' +
            'const int daylight_offset_sec = 0;\n';
        
        // 定义CA证书 - 修复证书格式问题
        ca_cert = ca_cert.replace(/^"|"$/g, ''); // 移除首尾引号
        
        // 处理转义字符：将\n替换为实际换行符，便于后续处理
        ca_cert = ca_cert.replace(/\\n/g, '\n');
        
        // 更好的证书格式化：确保头部和尾部单独成行，中间内容按64字符分割
        let formatted_cert = '';
        
        // 找到证书的开始和结束标记
        const beginIndex = ca_cert.indexOf('-----BEGIN CERTIFICATE-----');
        const endIndex = ca_cert.indexOf('-----END CERTIFICATE-----');
        
        if (beginIndex !== -1 && endIndex !== -1) {
            // 提取证书头部、主体和尾部
            const header = '-----BEGIN CERTIFICATE-----';
            const footer = '-----END CERTIFICATE-----';
            const body = ca_cert.substring(beginIndex + header.length, endIndex);
            
            // 构建格式化证书 - 使用实际的换行符而不是转义序列
            formatted_cert = header + '\n';
            
            // 处理证书主体，移除所有空白字符后按64字符分割
            const cleanBody = body.replace(/\s/g, ''); // 移除所有空白字符
            for (let i = 0; i < cleanBody.length; i += 64) {
                if (i > 0) formatted_cert += '\n';
                formatted_cert += cleanBody.substring(i, i + 64);
            }
            
            formatted_cert += '\n' + footer;
        } else {
            // 回退到原始方法
            for (let i = 0; i < ca_cert.length; i += 64) {
                if (i > 0) formatted_cert += '\n';
                formatted_cert += ca_cert.substring(i, i + 64);
            }
        }
        
        Blockly.Arduino.definitions_['var_declare_ca_cert'] = 'static const char ca_cert[] PROGMEM = R"EOF(' + formatted_cert + ')EOF";\n';
        
        // 定义回调函数
        Blockly.Arduino.definitions_['callback_function'] = 'void callback(char *topic, byte *payload, unsigned int length) {\n' +
            '  String data = "";\n' +
            '  for (int i = 0; i < length; i++) {\n' +
            '    data += (char) payload[i];\n' +
            '  }\n' +
            '  mqtt_topic = String(topic);\n' +
            '  mqtt_data = data;\n' +
            '  mqtt_status = true;\n' +
            '}\n';
        
        // 定义NTP时间同步函数 - 与示例代码保持一致
        Blockly.Arduino.definitions_['sync_time_function'] = 'void syncTime() {\n' +
            '  configTime(gmt_offset_sec, daylight_offset_sec, ntp_server);\n' +
            '  Serial.print("正在同步NTP时间: ");\n' +
            '  while (time(nullptr) < 8 * 3600 * 2) {\n' +
            '    delay(1000);\n' +
            '    Serial.print(".");\n' +
            '  }\n' +
            '  Serial.println("时间同步完成");\n' +
            '  struct tm timeinfo;\n' +
            '  if (getLocalTime(&timeinfo)) {\n' +
            '    Serial.print("当前时间: ");\n' +
            '    Serial.println(asctime(&timeinfo));\n' +
            '  } else {\n' +
            '    Serial.println("获取本地时间失败");\n' +
            '  }\n' +
            '}\n';
        
        // 定义MQTT连接函数 - 增强TLS配置
        Blockly.Arduino.definitions_['connect_mqtt_function'] = 'void connectToMQTT() {\n' +
            '  // 遗嘱消息配置\n' +
            '  const char* will_topic = ' + will_topic + ';\n' +
            '  const char* will_message = ' + will_message + ';\n' +
            '  int will_qos = ' + will_qos + ';\n' +
            '  bool will_retain = ' + will_retain + ';\n' +
            '  \n' +
            '  Serial.println("正在配置TLS...");\n' +
            '  \n' +
            '  // 设置TLS证书\n' +
            '  BearSSL::X509List serverTrustedCA(ca_cert);\n' +
            '  espClient.setTrustAnchors(&serverTrustedCA);\n' +
            '  \n' +
            '  // 设置ESP8266 TLS参数\n' +
            '  espClient.setBufferSizes(512, 512);\n' +
            '  espClient.setInsecure(); // 如果证书验证失败，可尝试此行\n' +
            '  \n' +
            '  Serial.println("TLS配置完成");\n' +
            '  \n' +
            '  // 配置MQTT客户端\n' +
            '  mqtt_client.setServer(mqtt_broker, mqtt_port);\n' +
            '  mqtt_client.setCallback(callback);\n' +
            '  \n' +
            '  // 尝试连接MQTT服务器\n' +
            '  Serial.println("正在连接MQTT服务器...");\n' +
            '  \n' +
            '  int retries = 0;\n' +
            '  while (!mqtt_client.connected() && retries < 3) {\n' +
            '    Serial.print("尝试连接 (");\n' +
            '    Serial.print(retries + 1);\n' +
            '    Serial.println("/3)...");\n' +
            '    \n' +
            '    // 生成客户端ID\n' +
            '    String clientId = String(client_id) + "-" + String(ESP.getChipId());\n' +
            '    \n' +
            '    // 尝试连接（支持遗嘱消息）\n' +
            '    if (mqtt_client.connect(clientId.c_str(), mqtt_username, mqtt_password, will_topic, will_qos, will_retain, will_message)) {\n' +
            '      Serial.println("连接成功！");\n' +
            '      mqtt_client.subscribe("+");\n' +
            '      mqtt_client.subscribe("#");\n' +
            '      return;\n' +
            '    } else {\n' +
            '      int state = mqtt_client.state();\n' +
            '      char err_buf[128] = {0};\n' +
            '      espClient.getLastSSLError(err_buf, sizeof(err_buf));\n' +
            '      \n' +
            '      Serial.printf("连接失败，状态码=%d\\n", state);\n' +
            '      if (strlen(err_buf) > 0) {\n' +
            '        Serial.printf("SSL错误: %s\\n", err_buf);\n' +
            '      }\n' +
            '      \n' +
            '      retries++;\n' +
            '      if (retries < 3) {\n' +
            '        Serial.println("5秒后重试...");\n' +
            '        delay(5000);\n' +
            '      }\n' +
            '    }\n' +
            '  }\n' +
            '  \n' +
            '  if (!mqtt_client.connected()) {\n' +
            '    Serial.println("3次连接尝试后仍失败");\n' +
            '  }\n' +
            '}\n';
        
        // 定义Setup函数 - 不阻塞等待WiFi，允许配网
        // 检查是否已设置串口波特率，如果没有则自动添加
        var hasSerialBegin = false;
        for (var key in Blockly.Arduino.setups_) {
            if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
                hasSerialBegin = true;
                break;
            }
        }
        if (!hasSerialBegin) {
            Blockly.Arduino.setups_['setup_mqtt_tls'] = 'Serial.begin(9600);\n' +
                '  delay(1000); // 等待串口稳定\n' +
                '  Serial.println("\\n=== ESP8266 MQTT TLS客户端 ===");\n' +
                '  \n' +
                '  mqtt_client.setServer(mqtt_broker, mqtt_port);\n' +
                '  mqtt_client.setCallback(callback);\n';
        } else {
            Blockly.Arduino.setups_['setup_mqtt_tls'] = '  delay(1000); // 等待串口稳定\n' +
                '  Serial.println("\\n=== ESP8266 MQTT TLS客户端 ===");\n' +
                '  \n' +
                '  mqtt_client.setServer(mqtt_broker, mqtt_port);\n' +
                '  mqtt_client.setCallback(callback);\n';
        }
        
        // 主循环代码 - 添加重连控制和心跳，只在WiFi连接后才尝试MQTT连接
        var code = 'if (WiFi.status() == WL_CONNECTED) {\n' +
            '  // 首次连接或重连时同步时间（TLS必需）\n' +
            '  static bool timeSynced = false;\n' +
            '  if (!timeSynced) {\n' +
            '    syncTime();\n' +
            '    timeSynced = true;\n' +
            '  }\n' +
            '  \n' +
            '  // MQTT连接管理\n' +
            '  if (!mqtt_client.connected()) {\n' +
            '    unsigned long now = millis();\n' +
            '    if (now - lastReconnectAttempt > 5000) {\n' +
            '      lastReconnectAttempt = now;\n' +
            '      Serial.println("MQTT断开连接，正在尝试重连...");\n' +
            '      connectToMQTT();\n' +
            '    }\n' +
            '  }\n' +
            '  mqtt_client.loop();\n' +
            '  \n' +
            '  // 定期发布心跳消息\n' +
            '  static unsigned long lastHeartbeat = 0;\n' +
            '  if (mqtt_client.connected() && millis() - lastHeartbeat > 30000) {\n' +
            '    lastHeartbeat = millis();\n' +
            '    String heartbeat = "ESP8266在线: " + String(millis()/1000) + "秒";\n' +
            '    mqtt_client.publish("heartbeat", heartbeat.c_str());\n' +
            '    Serial.print("心跳包已发送: ");\n' +
            '    Serial.println(heartbeat);\n' +
            '  }\n' +
            '}\n';
        
        return code;
    };

    // ESP32专用 MQTT TLS/SSL 连接块的代码生成逻辑
    Blockly.Arduino.forBlock['MQTT_subscribe_tls_esp32'] = function () {
        var server = Blockly.Arduino.valueToCode(this, 'server', Blockly.Arduino.ORDER_ATOMIC);
        var port = Blockly.Arduino.valueToCode(this, 'port', Blockly.Arduino.ORDER_ATOMIC);
        var client_id = Blockly.Arduino.valueToCode(this, 'client_id', Blockly.Arduino.ORDER_ATOMIC);
        var mqtt_username = Blockly.Arduino.valueToCode(this, 'mqtt_username', Blockly.Arduino.ORDER_ATOMIC);
        var mqtt_password = Blockly.Arduino.valueToCode(this, 'mqtt_password', Blockly.Arduino.ORDER_ATOMIC);
        var ca_cert = Blockly.Arduino.valueToCode(this, 'ca_cert', Blockly.Arduino.ORDER_ATOMIC);
        var will_topic = Blockly.Arduino.valueToCode(this, 'will_topic', Blockly.Arduino.ORDER_ATOMIC);
        var will_message = Blockly.Arduino.valueToCode(this, 'will_message', Blockly.Arduino.ORDER_ATOMIC);
        var will_qos = this.getFieldValue('will_qos');
        var will_retain = this.getFieldValue('will_retain') === 'TRUE';
        
        port = port.replace(/"/g, "");
        
        // ESP32专用头文件 - 基于ESP32示例代码
        Blockly.Arduino.definitions_['include_pubsubclient'] = '#include <PubSubClient.h>  // MQTT客户端库';
        Blockly.Arduino.definitions_['include_wificlientsecure'] = '#include <WiFiClientSecure.h>  // 安全WiFi客户端库（支持SSL/TLS）';
        
        // ESP32专用客户端对象 - 使用WiFiClientSecure
        Blockly.Arduino.definitions_['var_declare_esp32_client'] = 'WiFiClientSecure esp_client;    // 创建安全的WiFi客户端（用于SSL连接）\n' +
            'PubSubClient mqtt_client(esp_client);  // 创建MQTT客户端，使用安全WiFi客户端\n';
        
        // ESP32专用MQTT配置
        Blockly.Arduino.definitions_['var_declare_esp32_mqtt_config'] = '// MQTT服务器配置（使用EMQX云服务器）\n' +
            'const char *mqtt_broker = ' + server + ';  // MQTT服务器地址\n' +
            'const char *mqtt_username = ' + mqtt_username + ';         // MQTT用户名\n' +
            'const char *mqtt_password = ' + mqtt_password + ';     // MQTT密码\n' +
            'const int mqtt_port = ' + port + ';                 // MQTT SSL端口（8883是标准SSL端口）\n';

        // 定义接收消息相关变量（用于MQTT_received_the_news1积木）
        Blockly.Arduino.definitions_['var_declare_mqtt_receive'] = 'String mqtt_topic = "";\n' +
            'String mqtt_data = "";\n' +
            'boolean mqtt_status = false;\n';
        
        // ESP32专用CA证书处理 - 修复证书格式问题
        ca_cert = ca_cert.replace(/^"|"$/g, ''); // 移除首尾引号
        
        // 处理转义字符：将\n替换为实际换行符，便于后续处理
        ca_cert = ca_cert.replace(/\\n/g, '\n');
        
        // 更好的证书格式化：确保头部和尾部单独成行，中间内容按64字符分割
        let formatted_cert = '';
        
        // 找到证书的开始和结束标记
        const beginIndex = ca_cert.indexOf('-----BEGIN CERTIFICATE-----');
        const endIndex = ca_cert.indexOf('-----END CERTIFICATE-----');
        
        if (beginIndex !== -1 && endIndex !== -1) {
            // 提取证书头部、主体和尾部
            const header = '-----BEGIN CERTIFICATE-----';
            const footer = '-----END CERTIFICATE-----';
            const body = ca_cert.substring(beginIndex + header.length, endIndex);
            
            // 构建格式化证书 - 使用实际的换行符而不是转义序列
            formatted_cert = header + '\n';
            
            // 处理证书主体，移除所有空白字符后按64字符分割
            const cleanBody = body.replace(/\s/g, ''); // 移除所有空白字符
            for (let i = 0; i < cleanBody.length; i += 64) {
                if (i > 0) formatted_cert += '\n';
                formatted_cert += cleanBody.substring(i, i + 64);
            }
            
            formatted_cert += '\n' + footer;
        } else {
            // 回退到原始方法
            for (let i = 0; i < ca_cert.length; i += 64) {
                if (i > 0) formatted_cert += '\n';
                formatted_cert += ca_cert.substring(i, i + 64);
            }
        }
        
        Blockly.Arduino.definitions_['var_declare_esp32_ca_cert'] = '// 根证书（CA证书）- 用于验证MQTT服务器的身份\n' +
            '// 这是DigiCert Global Root G2证书，EMQX公共代理服务器使用此证书\n' +
            'const char *ca_cert = R"EOF(' + formatted_cert + ')EOF";\n';
        
        // ESP32专用回调函数
        Blockly.Arduino.definitions_['esp32_callback_function'] = '// 回调函数 - 当收到MQTT消息时被调用\n' +
            'void callback(char *topic, byte *payload, unsigned int length) {\n' +
            '  String data = "";\n' +
            '  for (int i = 0; i < length; i++) {\n' +
            '    data += (char) payload[i];\n' +
            '  }\n' +
            '  mqtt_topic = String(topic);\n' +
            '  mqtt_data = data;\n' +
            '  mqtt_status = true;\n' +
            '}\n' +
            '\n' +
            'void connectToMQTT();      // 连接MQTT服务器函数\n';
        
        // ESP32专用Setup配置
        // 检查是否已设置串口波特率，如果没有则自动添加
        var hasSerialBegin = false;
        for (var key in Blockly.Arduino.setups_) {
            if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
                hasSerialBegin = true;
                break;
            }
        }
        if (!hasSerialBegin) {
            Blockly.Arduino.setups_['esp32_setup_mqtt'] = 'Serial.begin(9600);    // 初始化串口通信，波特率9600\n' +
                '  \n' +
                '  // 设置根证书（非常重要：用于SSL/TLS加密连接）\n' +
                '  esp_client.setCACert(ca_cert);\n' +
                '  \n' +
                '  // 配置MQTT客户端\n' +
                '  mqtt_client.setServer(mqtt_broker, mqtt_port);  // 设置MQTT服务器地址和端口\n' +
                '  mqtt_client.setCallback(callback);              // 设置消息接收回调函数\n' +
                '  mqtt_client.setKeepAlive(60);                   // 设置心跳包间隔60秒\n';
        } else {
            Blockly.Arduino.setups_['esp32_setup_mqtt'] = '  // 设置根证书（非常重要：用于SSL/TLS加密连接）\n' +
                '  esp_client.setCACert(ca_cert);\n' +
                '  \n' +
                '  // 配置MQTT客户端\n' +
                '  mqtt_client.setServer(mqtt_broker, mqtt_port);  // 设置MQTT服务器地址和端口\n' +
                '  mqtt_client.setCallback(callback);              // 设置消息接收回调函数\n' +
                '  mqtt_client.setKeepAlive(60);                   // 设置心跳包间隔60秒\n';
        }
        
        // ESP32专用MQTT连接函数
        Blockly.Arduino.definitions_['esp32_connect_mqtt'] = 
            '// 连接MQTT服务器函数\n' +
            'void connectToMQTT() {\n' +
            '  // 遗嘱消息配置\n' +
            '  const char* will_topic = ' + will_topic + ';\n' +
            '  const char* will_message = ' + will_message + ';\n' +
            '  int will_qos = ' + will_qos + ';\n' +
            '  bool will_retain = ' + will_retain + ';\n' +
            '  \n' +
            '  // 生成唯一的客户端ID（使用MAC地址）\n' +
            '  String client_id = "esp32-client-" + String(WiFi.macAddress());\n' +
            '  Serial.printf("正在以客户端ID: %s 连接MQTT服务器...\\n", client_id.c_str());\n' +
            '  \n' +
          '  // 尝试连接MQTT服务器（支持遗嘱消息）\n' +
            '  if (mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password, will_topic, will_qos, will_retain, will_message)) {\n' +
            '    Serial.println("MQTT服务器连接成功！");\n' +
            '    mqtt_client.subscribe("+");\n' +
            '    mqtt_client.subscribe("#");\n' +
            '  } else {\n' +
            '    // 连接失败，打印错误信息\n' +
            '    Serial.print("连接MQTT服务器失败，错误码:");\n' +
            '    Serial.print(mqtt_client.state());\n' +
            '    Serial.println(" 5秒后重试...");\n' +
            '  }\n' +
            '}\n';
        
        // ESP32专用主循环代码 - 只在WiFi连接后才尝试MQTT连接
        var code = 'if (WiFi.status() == WL_CONNECTED) {\n' +
            '  // 检查MQTT连接状态，如果断开则重新连接\n' +
            '  static unsigned long lastReconnectAttempt = 0;\n' +
            '  if (!mqtt_client.connected()) {\n' +
            '    unsigned long now = millis();\n' +
            '    if (now - lastReconnectAttempt > 5000) {\n' +
            '      lastReconnectAttempt = now;\n' +
            '      connectToMQTT();  // 重新连接MQTT服务器\n' +
            '    }\n' +
            '  }\n' +
            '  mqtt_client.loop();   // 处理MQTT客户端任务（必须调用以维持连接）\n' +
            '}\n';
        
        return code;
    };

Blockly.Arduino.forBlock['mqtt_client_setup'] = function() {
    // 获取输入字段的值
    var broker = Blockly.Arduino.valueToCode(this, 'server', Blockly.Arduino.ORDER_ATOMIC) || '"mixio.mixly.cn"';
    var port = Blockly.Arduino.valueToCode(this, 'port', Blockly.Arduino.ORDER_ATOMIC) || '1883';
    var username = Blockly.Arduino.valueToCode(this, 'mqtt_username', Blockly.Arduino.ORDER_ATOMIC) || '"12345678@qq.com"';
    var password = Blockly.Arduino.valueToCode(this, 'mqtt_password', Blockly.Arduino.ORDER_ATOMIC) || '"d86d2e60b813590963e2641b44945154"';
    var project = Blockly.Arduino.valueToCode(this, 'project', Blockly.Arduino.ORDER_ATOMIC) || '"test"';
    var code =`client.loop();\n`; 
    Blockly.Arduino.definitions_['include_PubSubClient'] = '#include <PubSubClient.h>\n';
    Blockly.Arduino.definitions_['mqtt_vars'] = 
        'const char *mqtt_broker = ' + broker + ';\n' +
        'const char *mqtt_username = ' + username + ';\n' +
        'const char *mqtt_password = ' + password + ';\n' +
        'const int mqtt_port = ' + port.replace(/"/g, '') + ';\n' +  // 确保移除双引号
        'String mqtt_topic = "";\n' +
        'String mqtt_data = "";\n' +
        'boolean mqtt_status = false;\n' +
        'String project = ' + project + ';\n' +
        'WiFiClient espClient;\n' +
        'PubSubClient client(espClient);\n';
    
    Blockly.Arduino.definitions_['mqtt_callback'] = 
        'void callback(char *topic, byte *payload, unsigned int length) {\n' +
        '  String data = "";\n' +
        '  for (int i = 0; i < length; i++) {\n' +
        '    data = String(data) + String((char) payload[i]);\n' +
        '  }\n' +
        '  mqtt_topic = String(topic);\n' +
        '  mqtt_data = data;\n' +
        '  mqtt_status = true;\n' +
        '}\n';
    
    Blockly.Arduino.setups_['setup_mqtt'] = 
        'client.setServer(mqtt_broker, mqtt_port);\n' +
        'client.setCallback(callback);\n' +
        'String client_id = "esp-client-";\n' +
        'client_id += String(WiFi.macAddress());\n' +
        'Serial.printf("客户端 %s 连接到MQTT服务器\\n", client_id.c_str());\n' +
        'if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {\n' +
        '  Serial.println("MQTT已连接");\n' +
        '  client.subscribe(String(String(mqtt_username) + "/#").c_str());\n' +
        '}';
    var code = 
        'if (WiFi.status() == WL_CONNECTED) {\n' +
        '  if (!client.connected()) {\n' +
        '    String client_id = "esp-client-";\n' +
        '    client_id += String(WiFi.macAddress());\n' +
        '    if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {\n' +
        '      Serial.println("MQTT已重新连接");\n' +
        '      client.subscribe(String(String(mqtt_username) + "/#").c_str());\n' +
        '      client.publish(String(String(mqtt_username) +"/"+ String(project) +"/"+ String("b640a0ce465fa2a4150c36b305c1c11b")).c_str(),String(client_id).c_str());\n' +
        '    }\n' +
        '  }\n' +
        '  client.loop();\n' +
        '}\n';

    return code;
};

    Blockly.Arduino.forBlock['make_arduino_homeassistant_mqtt_discovery'] = function() {
        var component = this.getFieldValue('COMPONENT');
        var deviceId = this.getFieldValue('DEVICE_ID');
        var name = this.getFieldValue('NAME');
        var stateTopic = this.getFieldValue('STATE_TOPIC') || 'home/' + deviceId + '/state';
        var commandTopic = this.getFieldValue('COMMAND_TOPIC') || 'home/' + deviceId + '/command';
        var availabilityTopic = this.getFieldValue('AVAILABILITY_TOPIC') || 'home/' + deviceId + '/availability';
        var payloadAvailable = this.getFieldValue('PAYLOAD_AVAILABLE') || 'online';
        var payloadNotAvailable = this.getFieldValue('PAYLOAD_NOT_AVAILABLE') || 'offline';
        var deviceClass = this.getFieldValue('DEVICE_CLASS');
        var unit = this.getFieldValue('UNIT');
        var minVal = this.getFieldValue('MIN');
        var maxVal = this.getFieldValue('MAX');
        var options = this.getFieldValue('OPTIONS');

        var discoveryTopic = 'homeassistant/' + component + '/' + deviceId + '/config';
        var baseTopic = 'home/' + deviceId;
        
        var configStr = '{"name":"' + name + '","~":"' + baseTopic + '"';

        var hasStateTopic = ['sensor', 'binary_sensor', 'switch', 'light', 'cover', 'fan', 'humidifier', 'lock', 'siren', 'vacuum', 'valve', 'water_heater', 'update', 'tag_scanner', 'event', 'device_tracker', 'image', 'alarm_control_panel', 'lawn_mower'].indexOf(component) !== -1;
        var hasCommandTopic = ['switch', 'light', 'cover', 'fan', 'humidifier', 'lock', 'button', 'number', 'text', 'select', 'siren', 'vacuum', 'valve', 'water_heater', 'update', 'notify', 'scene', 'lawn_mower', 'alarm_control_panel'].indexOf(component) !== -1;

        if (component !== 'climate' && hasStateTopic) {
            configStr += ',"state_topic":"' + stateTopic + '"';
        }
        
        if (component !== 'climate' && hasCommandTopic) {
            configStr += ',"command_topic":"' + commandTopic + '"';
        }
        
        configStr += ',"availability_topic":"' + availabilityTopic + '"';
        configStr += ',"payload_available":"' + payloadAvailable + '"';
        configStr += ',"payload_not_available":"' + payloadNotAvailable + '"';
        configStr += ',"unique_id":"' + deviceId + '"';

        if (component === 'sensor' || component === 'binary_sensor') {
            if (deviceClass) {
                configStr += ',"device_class":"' + deviceClass + '"';
            }
            if (unit) {
                configStr += ',"unit_of_measurement":"' + unit + '"';
            }
        }
        
        if (component === 'lock') {
            configStr += ',"payload_lock":"LOCK"';
            configStr += ',"payload_unlock":"UNLOCK"';
            configStr += ',"payload_pause":"PAUSE"';
        }
        
        if (component === 'button') {
            configStr += ',"payload_press":"PRESS"';
        }
        
        if (component === 'climate') {
            // 获取 Climate (温控器/空调) 专用配置
            var climateModeTopic = this.getFieldValue('CLIMATE_MODE_TOPIC') || baseTopic + '/mode/set';
            var climateModeStateTopic = this.getFieldValue('CLIMATE_MODE_STATE_TOPIC') || baseTopic + '/mode/state';
            var climateTempTopic = this.getFieldValue('CLIMATE_TEMP_TOPIC') || baseTopic + '/temperature/set';
            var climateCurrentTempTopic = this.getFieldValue('CLIMATE_CURRENT_TEMP_TOPIC') || baseTopic + '/temperature/current';
            var climateMinTemp = this.getFieldValue('CLIMATE_MIN_TEMP') || 16;
            var climateMaxTemp = this.getFieldValue('CLIMATE_MAX_TEMP') || 30;
            var climateTempStep = this.getFieldValue('CLIMATE_TEMP_STEP') || 0.5;
            var climateModes = this.getFieldValue('CLIMATE_MODES') || 'off,auto,heat,cool,dry,fan_only';
            
            // 构建 Climate 配置
            configStr += ',"mode_command_topic":"' + climateModeTopic + '"';
            configStr += ',"mode_state_topic":"' + climateModeStateTopic + '"';
            configStr += ',"temperature_command_topic":"' + climateTempTopic + '"';
            configStr += ',"current_temperature_topic":"' + climateCurrentTempTopic + '"';
            configStr += ',"min_temp":' + climateMinTemp;
            configStr += ',"max_temp":' + climateMaxTemp;
            configStr += ',"temp_step":' + climateTempStep;
            configStr += ',"temperature_unit":"C"';
            
            // 处理模式列表
            if (climateModes) {
                var modesList = climateModes.split(',').map(function(mode) { return '"' + mode.trim() + '"'; });
                configStr += ',"modes":[' + modesList.join(',') + ']';
            }
            
            // 扫风模式配置
            var swingModeTopic = this.getFieldValue('SWING_MODE_TOPIC') || baseTopic + '/swing/set';
            var swingModeStateTopic = this.getFieldValue('SWING_MODE_STATE_TOPIC') || baseTopic + '/swing/state';
            var swingModes = this.getFieldValue('SWING_MODES') || 'off,vertical,horizontal,both';
            configStr += ',"swing_mode_command_topic":"' + swingModeTopic + '"';
            configStr += ',"swing_mode_state_topic":"' + swingModeStateTopic + '"';
            if (swingModes) {
                var swingList = swingModes.split(',').map(function(mode) { return '"' + mode.trim() + '"'; });
                configStr += ',"swing_modes":[' + swingList.join(',') + ']';
            }
        }
        
        if (component === 'vacuum') {
            configStr += ',"schema":"state"';
        }
        
        if (component === 'water_heater') {
            configStr += ',"current_temperature_topic":"' + baseTopic + '/temperature"';
            configStr += ',"min_temp":"35"';
            configStr += ',"max_temp":"85"';
            configStr += ',"temperature_unit":"C"';
            configStr += ',"modes":["off","eco","electric","performance","high"]';
        }
        
        if (component === 'number' || component === 'text') {
            if (minVal) configStr += ',"min":' + minVal;
            if (maxVal) configStr += ',"max":' + maxVal;
        }
        
        if (component === 'select') {
            if (options) {
                var optionsList = options.split(',').map(function(opt) { return '"' + opt.trim() + '"'; });
                configStr += ',"options":[' + optionsList.join(',') + ']';
            }
        }
        
        if (component === 'alarm_control_panel') {
            configStr += ',"code_format":"number"';
            configStr += ',"payload_arm_home":"armed_home"';
            configStr += ',"payload_arm_away":"armed_away"';
            configStr += ',"payload_disarm":"disarm"';
        }
        
        if (component === 'device_tracker') {
            configStr += ',"source_type":"gps"';
            configStr += ',"payload_home":"home"';
            configStr += ',"payload_not_home":"not_home"';
        }
        
        if (component === 'scene') {
            configStr += ',"payload":"trigger"';
        }
        
        if (component === 'notify') {
            configStr += ',"payload":"trigger"';
        }
        
        if (component === 'event') {
            configStr += ',"event_types":[]';
        }
        
        if (component === 'camera' || component === 'image') {
            configStr += ',"topic":"' + baseTopic + '/image"';
        }
        
        if (component === 'device_trigger') {
            configStr += ',"topic":"' + baseTopic + '/trigger"';
            configStr += ',"type":"button_short_press"';
            configStr += ',"subtype":"button_1"';
        }
        
        if (['binary_sensor', 'switch', 'light', 'cover'].indexOf(component) !== -1) {
            configStr += ',"payload_on":"ON"';
            configStr += ',"payload_off":"OFF"';
        }
        
        if (component === 'light') {
            configStr += ',"brightness":true';
        }
        
        if (component === 'cover') {
            configStr += ',"position_template":"' + baseTopic + '/position"';
        }
        
        configStr += '}';

        var uniqueId = deviceId + '_' + component;
        Blockly.Arduino.definitions_['var_declare_ha_discovery_' + uniqueId] = 'const char* HA_DISCOVERY_TOPIC_' + uniqueId + ' = "' + discoveryTopic + '";';
        Blockly.Arduino.definitions_['var_declare_ha_payload_' + uniqueId] = 'const char* HA_DISCOVERY_PAYLOAD_' + uniqueId + ' = R"rawliteral(' + configStr + ')rawliteral";';

        Blockly.Arduino.definitions_['var_declare_ha_online_timer'] = 'unsigned long ha_online_timer = 0;';
        Blockly.Arduino.definitions_['var_declare_ha_online_sent'] = 'bool ha_online_sent = false;';
        Blockly.Arduino.definitions_['func_ha_check_online'] = 'void haCheckOnline() {\n' +
            '  if (!ha_online_sent && millis() - ha_online_timer >= 8000) {\n' +
            '    mqtt_client.publish("' + availabilityTopic + '", "' + payloadAvailable + '", true);\n' +
            '    ha_online_sent = true;\n' +
            '  }\n' +
            '}';

        Blockly.Arduino.setups_['mqtt_discovery_' + uniqueId] =
            'mqtt_client.setBufferSize(512);\n' +
            'if (mqtt_client.connected()) {\n' +
            '  mqtt_client.publish(HA_DISCOVERY_TOPIC_' + uniqueId + ', HA_DISCOVERY_PAYLOAD_' + uniqueId + ', true);\n' +
            '  ha_online_timer = millis();\n' +
            '}\n';

        return 'haCheckOnline();\n';
    };

    // 定义 JSON 多键值对发布块的代码生成逻辑
    Blockly.Arduino.forBlock['MQTT_publish_json_multi'] = function () {
        var topic = Blockly.Arduino.valueToCode(this, 'topic', Blockly.Arduino.ORDER_ATOMIC);
        var itemCount = this.itemCount_ || 1;
        
        var code = 'String json_data = "{";\n';
        
        for (var i = 0; i < itemCount; i++) {
            var key = Blockly.Arduino.valueToCode(this, 'KEY' + i, Blockly.Arduino.ORDER_ATOMIC);
            var value = Blockly.Arduino.valueToCode(this, 'VALUE' + i, Blockly.Arduino.ORDER_ATOMIC);
            
            var keyIsString = (key.charAt(0) === '"' && key.charAt(key.length - 1) === '"');
            var valueIsString = (value.charAt(0) === '"' && value.charAt(value.length - 1) === '"');
            
            var keyStr = keyIsString ? key.substring(1, key.length - 1) : key;
            var valueStr = valueIsString ? value.substring(1, value.length - 1) : value;
            
            if (keyIsString && valueIsString) {
                code += 'json_data += "\\"' + keyStr + '\\":\\"' + valueStr + '\\"";';
            } else if (keyIsString && !valueIsString) {
                code += 'json_data += "\\"' + keyStr + '\\":\\"" + String(' + valueStr + ');';
            } else if (!keyIsString && valueIsString) {
                code += 'json_data += "\\"" + String(' + keyStr + ') + "\\":\\"' + valueStr + '\\"";';
            } else {
                code += 'json_data += "\\"" + String(' + keyStr + ') + "\\":\\"" + String(' + valueStr + ');';
            }
            
            if (i < itemCount - 1) {
                code += '\njson_data += ",";';
            }
            code += '\n';
        }
        
        code += 'json_data += "}";\n';
        code += 'mqtt_client.publish(String(' + topic + ').c_str(), json_data.c_str());\n';

        return code;
    };

    // 定义 JSON 对象积木的代码生成逻辑（用于嵌套）
    Blockly.Arduino.forBlock['mqtt_json_object'] = function () {
        var itemCount = this.itemCount_ || 1;

        var code = 'String("{")';

        for (var i = 0; i < itemCount; i++) {
            var key = Blockly.Arduino.valueToCode(this, 'KEY' + i, Blockly.Arduino.ORDER_ATOMIC);
            var value = Blockly.Arduino.valueToCode(this, 'VALUE' + i, Blockly.Arduino.ORDER_ATOMIC);

            var keyIsString = (key.charAt(0) === '"' && key.charAt(key.length - 1) === '"');
            var valueIsString = (value.charAt(0) === '"' && value.charAt(value.length - 1) === '"');

            var keyStr = keyIsString ? key.substring(1, key.length - 1) : key;
            var valueStr = valueIsString ? value.substring(1, value.length - 1) : value;

            if (i > 0) {
                code += ' + ","';
            }

            if (keyIsString && valueIsString) {
                code += ' + "\\"' + keyStr + '\\":\\"' + valueStr + '\\""';
            } else if (keyIsString && !valueIsString) {
                code += ' + "\\"' + keyStr + '\\":\\"" + String(' + valueStr + ') + "\\""';
            } else if (!keyIsString && valueIsString) {
                code += ' + "\\"" + String(' + keyStr + ') + "\\":\\"' + valueStr + '\\""';
            } else {
                code += ' + "\\"" + String(' + keyStr + ') + "\\":\\"" + String(' + valueStr + ') + "\\""';
            }
        }

        code += ' + "}"';

        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };


Blockly.Arduino.forBlock['make_arduino_describe'] = function(block) {

  return  ' //作  者 ： \n' +
  ' //回到  未来\n' +
  ' //QQ : 375091377\n';
};
    Blockly.Arduino.forBlock = Blockly.Arduino.forBlock || {};

    Blockly.Arduino.forBlock['http_get_json_timeout_esp32'] = function(block) {
        const url = Blockly.Arduino.valueToCode(block, 'URL', Blockly.Arduino.ORDER_ATOMIC) || '""';
        const timeout = Blockly.Arduino.valueToCode(block, 'TIMEOUT', Blockly.Arduino.ORDER_ATOMIC) || '5000';

        Blockly.Arduino.definitions_['include_arduinojson'] = '#include <ArduinoJson.h>';
        Blockly.Arduino.definitions_['include_httpclient'] = '#include <HTTPClient.h>';

        Blockly.Arduino.definitions_['function_http_get_json'] = `
String httpGetJson(const char* url, int timeout) {
  String response = "";
  HTTPClient http;
  http.begin(url);
  http.setTimeout(timeout);
  http.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);

  int httpCode = http.GET();

  if (httpCode == HTTP_CODE_OK) {
    response = http.getString();
  } else {
    response = String("{\\"error\\":\\"HTTP ") + String(httpCode) + String("\\"}");
  }

  http.end();
  return response;
}
`;

        const code = `httpGetJson(${url}, ${timeout})`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    Blockly.Arduino.forBlock['http_get_json_timeout_esp8266'] = function(block) {
        const url = Blockly.Arduino.valueToCode(block, 'URL', Blockly.Arduino.ORDER_ATOMIC) || '""';
        const timeout = Blockly.Arduino.valueToCode(block, 'TIMEOUT', Blockly.Arduino.ORDER_ATOMIC) || '5000';

        Blockly.Arduino.definitions_['include_arduinojson'] = '#include <ArduinoJson.h>';
        Blockly.Arduino.definitions_['include_httpclient'] = '#include <ESP8266HTTPClient.h>';
        Blockly.Arduino.definitions_['include_wificlient'] = '#include <WiFiClient.h>';

        Blockly.Arduino.definitions_['function_http_get_json'] = `
String httpGetJson(const char* url, int timeout) {
  String response = "";
  WiFiClientSecure client;
  HTTPClient http;
  client.setInsecure();
  http.begin(client, url);
  http.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
  http.setTimeout(timeout);

  int httpCode = http.GET();

  if (httpCode == HTTP_CODE_OK) {
    response = http.getString();
  } else {
    response = String("{\\"error\\":\\"HTTP ") + String(httpCode) + String("\\"}");
  }

  http.end();
  return response;
}
`;

        const code = `httpGetJson(${url}, ${timeout})`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // ESP32 专用 JSON 检索
    Blockly.Arduino.forBlock['json_retrieve_esp32'] = function(block) {
        let jsonString = Blockly.Arduino.valueToCode(block, 'JSON_STRING', Blockly.Arduino.ORDER_ATOMIC) || '""';
        let key = Blockly.Arduino.valueToCode(block, 'KEY', Blockly.Arduino.ORDER_ATOMIC) || '""';

        let jsonParam, keyParam;
        
        if (jsonString.startsWith('"')) {
            const content = jsonString.slice(1, -1);
            const varName = 'json_str_esp32_' + block.id.replace(/[^a-zA-Z0-9]/g, '_');
            Blockly.Arduino.definitions_['var_declare_' + varName] = `String ${varName} = R"JSONRAW(${content})JSONRAW";`;
            jsonParam = `${varName}.c_str()`;
        } else {
            jsonParam = `String(${jsonString}).c_str()`;
        }
        
        if (key.startsWith('"')) {
            const keyContent = key.slice(1, -1);
            const keyVarName = 'json_key_esp32_' + block.id.replace(/[^a-zA-Z0-9]/g, '_');
            Blockly.Arduino.definitions_['var_declare_' + keyVarName] = `String ${keyVarName} = "${keyContent}";`;
            keyParam = `${keyVarName}.c_str()`;
        } else {
            keyParam = `String(${key}).c_str()`;
        }

        Blockly.Arduino.definitions_['include_arduinojson'] = '#include <ArduinoJson.h>';

        Blockly.Arduino.definitions_['function_json_search_esp32'] = `
String jsonSearchESP32(const char* jsonString, const char* key) {
  StaticJsonDocument<4096> doc;
  DeserializationError error = deserializeJson(doc, jsonString);

  if (error) {
    Serial.print("JSON解析错误: ");
    Serial.println(error.c_str());
    return "ERROR:" + String(error.c_str());
  }
  Serial.println("JSON解析成功");

  std::function<String(JsonVariant, const char*)> searchKey;
  searchKey = [&searchKey](JsonVariant obj, const char* targetKey) -> String {
    if (obj.is<JsonObject>()) {
      JsonObject object = obj.as<JsonObject>();
      for (JsonPair kv : object) {
        if (strcmp(kv.key().c_str(), targetKey) == 0) {
          JsonVariant value = kv.value();
          if (value.is<const char*>()) {
            return String(value.as<const char*>());
          } else if (value.is<int>()) {
            return String(value.as<int>());
          } else if (value.is<float>() || value.is<double>()) {
            return String(value.as<float>(), 6);
          } else if (value.is<bool>()) {
            return value.as<bool>() ? "true" : "false";
          }
        }
        if (kv.value().is<JsonObject>() || kv.value().is<JsonArray>()) {
          String result = searchKey(kv.value(), targetKey);
          if (result.length() > 0 && result.indexOf("ERROR:") != 0) {
            return result;
          }
        }
      }
    } else if (obj.is<JsonArray>()) {
      JsonArray array = obj.as<JsonArray>();
      for (JsonVariant item : array) {
        if (item.is<JsonObject>() || item.is<JsonArray>()) {
          String result = searchKey(item, targetKey);
          if (result.length() > 0 && result.indexOf("ERROR:") != 0) {
            return result;
          }
        }
      }
    }
    return "";
  };

  return searchKey(doc.as<JsonVariant>(), key);
}
`;

        const code = `jsonSearchESP32(${jsonParam}, ${keyParam})`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // ESP8266 专用 JSON 检索
    Blockly.Arduino.forBlock['json_retrieve_esp8266'] = function(block) {
        let jsonString = Blockly.Arduino.valueToCode(block, 'JSON_STRING', Blockly.Arduino.ORDER_ATOMIC) || '""';
        let key = Blockly.Arduino.valueToCode(block, 'KEY', Blockly.Arduino.ORDER_ATOMIC) || '""';

        let jsonParam, keyParam;
        
        if (jsonString.startsWith('"')) {
            const content = jsonString.slice(1, -1);
            const varName = 'json_str_esp8266_' + block.id.replace(/[^a-zA-Z0-9]/g, '_');
            Blockly.Arduino.definitions_['var_declare_' + varName] = `String ${varName} = R"JSONRAW(${content})JSONRAW";`;
            jsonParam = `${varName}.c_str()`;
        } else {
            jsonParam = `String(${jsonString}).c_str()`;
        }
        
        if (key.startsWith('"')) {
            const keyContent = key.slice(1, -1);
            const keyVarName = 'json_key_esp8266_' + block.id.replace(/[^a-zA-Z0-9]/g, '_');
            Blockly.Arduino.definitions_['var_declare_' + keyVarName] = `String ${keyVarName} = "${keyContent}";`;
            keyParam = `${keyVarName}.c_str()`;
        } else {
            keyParam = `String(${key}).c_str()`;
        }

        Blockly.Arduino.definitions_['include_arduinojson'] = '#include <ArduinoJson.h>';

        Blockly.Arduino.definitions_['function_json_search_esp8266'] = `
String jsonSearchESP8266(const char* jsonString, const char* key) {
  DynamicJsonDocument doc(4096);
  DeserializationError error = deserializeJson(doc, jsonString);

  if (error) {
    Serial.print("JSON解析错误: ");
    Serial.println(error.c_str());
    return "ERROR:" + String(error.c_str());
  }
  Serial.println("JSON解析成功");

  std::function<String(JsonVariant, const char*)> searchKey;
  searchKey = [&searchKey](JsonVariant obj, const char* targetKey) -> String {
    if (obj.is<JsonObject>()) {
      JsonObject object = obj.as<JsonObject>();
      for (JsonPair kv : object) {
        if (strcmp(kv.key().c_str(), targetKey) == 0) {
          JsonVariant value = kv.value();
          if (value.is<const char*>()) {
            return String(value.as<const char*>());
          } else if (value.is<int>()) {
            return String(value.as<int>());
          } else if (value.is<float>() || value.is<double>()) {
            return String(value.as<float>(), 6);
          } else if (value.is<bool>()) {
            return value.as<bool>() ? "true" : "false";
          }
        }
        if (kv.value().is<JsonObject>() || kv.value().is<JsonArray>()) {
          String result = searchKey(kv.value(), targetKey);
          if (result.length() > 0 && result.indexOf("ERROR:") != 0) {
            return result;
          }
        }
      }
    } else if (obj.is<JsonArray>()) {
      JsonArray array = obj.as<JsonArray>();
      for (JsonVariant item : array) {
        if (item.is<JsonObject>() || item.is<JsonArray>()) {
          String result = searchKey(item, targetKey);
          if (result.length() > 0 && result.indexOf("ERROR:") != 0) {
            return result;
          }
        }
      }
    }
    return "";
  };

  return searchKey(doc.as<JsonVariant>(), key);
}
`;

        const code = `jsonSearchESP8266(${jsonParam}, ${keyParam})`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // ESP32 专用数组长度
    Blockly.Arduino.forBlock['json_array_length_esp32'] = function(block) {
        let jsonString = Blockly.Arduino.valueToCode(block, 'JSON_STRING', Blockly.Arduino.ORDER_ATOMIC) || '""';
        let key = Blockly.Arduino.valueToCode(block, 'KEY', Blockly.Arduino.ORDER_ATOMIC) || '""';

        let jsonParam, keyParam;
        
        if (jsonString.startsWith('"')) {
            const content = jsonString.slice(1, -1);
            const varName = 'json_str_esp32_' + block.id.replace(/[^a-zA-Z0-9]/g, '_');
            Blockly.Arduino.definitions_['var_declare_' + varName] = `String ${varName} = R"JSONRAW(${content})JSONRAW";`;
            jsonParam = `${varName}.c_str()`;
        } else {
            jsonParam = `String(${jsonString}).c_str()`;
        }

        if (key.startsWith('"')) {
            const keyContent = key.slice(1, -1);
            const keyVarName = 'json_key_esp32_' + block.id.replace(/[^a-zA-Z0-9]/g, '_');
            Blockly.Arduino.definitions_['var_declare_' + keyVarName] = `String ${keyVarName} = "${keyContent}";`;
            keyParam = `${keyVarName}.c_str()`;
        } else {
            keyParam = `String(${key}).c_str()`;
        }

        Blockly.Arduino.definitions_['include_arduinojson'] = '#include <ArduinoJson.h>';

        Blockly.Arduino.definitions_['function_json_array_length_esp32'] = `
int jsonArrayLengthESP32(const char* jsonString, const char* keyPath) {
  StaticJsonDocument<4096> doc;
  DeserializationError error = deserializeJson(doc, jsonString);

  if (error) {
    return -1;
  }

  JsonVariant current = doc.as<JsonVariant>();
  char* path = strdup(keyPath);
  char* token = strtok(path, ".");

  while (token != NULL && !current.isNull()) {
    if (current.is<JsonObject>()) {
      current = current[token];
    } else {
      free(path);
      return -1;
    }
    token = strtok(NULL, ".");
  }

  free(path);

  if (current.is<JsonArray>()) {
    return current.size();
  }

  return -1;
}
`;

        const code = `jsonArrayLengthESP32(${jsonParam}, ${keyParam})`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // ESP8266 专用数组长度
    Blockly.Arduino.forBlock['json_array_length_esp8266'] = function(block) {
        let jsonString = Blockly.Arduino.valueToCode(block, 'JSON_STRING', Blockly.Arduino.ORDER_ATOMIC) || '""';
        let key = Blockly.Arduino.valueToCode(block, 'KEY', Blockly.Arduino.ORDER_ATOMIC) || '""';

        let jsonParam, keyParam;
        
        if (jsonString.startsWith('"')) {
            const content = jsonString.slice(1, -1);
            const varName = 'json_str_esp8266_' + block.id.replace(/[^a-zA-Z0-9]/g, '_');
            Blockly.Arduino.definitions_['var_declare_' + varName] = `String ${varName} = R"JSONRAW(${content})JSONRAW";`;
            jsonParam = `${varName}.c_str()`;
        } else {
            jsonParam = `String(${jsonString}).c_str()`;
        }

        if (key.startsWith('"')) {
            const keyContent = key.slice(1, -1);
            const keyVarName = 'json_key_esp8266_' + block.id.replace(/[^a-zA-Z0-9]/g, '_');
            Blockly.Arduino.definitions_['var_declare_' + keyVarName] = `String ${keyVarName} = "${keyContent}";`;
            keyParam = `${keyVarName}.c_str()`;
        } else {
            keyParam = `String(${key}).c_str()`;
        }

        Blockly.Arduino.definitions_['include_arduinojson'] = '#include <ArduinoJson.h>';

        Blockly.Arduino.definitions_['function_json_array_length_esp8266'] = `
int jsonArrayLengthESP8266(const char* jsonString, const char* keyPath) {
  DynamicJsonDocument doc(4096);
  DeserializationError error = deserializeJson(doc, jsonString);

  if (error) {
    return -1;
  }

  JsonVariant current = doc.as<JsonVariant>();
  char* path = strdup(keyPath);
  char* token = strtok(path, ".");

  while (token != NULL && !current.isNull()) {
    if (current.is<JsonObject>()) {
      current = current[token];
    } else {
      free(path);
      return -1;
    }
    token = strtok(NULL, ".");
  }

  free(path);

  if (current.is<JsonArray>()) {
    return current.size();
  }

  return -1;
}
`;

        const code = `jsonArrayLengthESP8266(${jsonParam}, ${keyParam})`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // ESP32 专用检查键
    Blockly.Arduino.forBlock['json_has_key_esp32'] = function(block) {
        let jsonString = Blockly.Arduino.valueToCode(block, 'JSON_STRING', Blockly.Arduino.ORDER_ATOMIC) || '""';
        let key = Blockly.Arduino.valueToCode(block, 'KEY', Blockly.Arduino.ORDER_ATOMIC) || '""';

        let jsonParam, keyParam;

        if (jsonString.startsWith('"')) {
            const content = jsonString.slice(1, -1);
            const varName = 'json_str_esp32_' + block.id.replace(/[^a-zA-Z0-9]/g, '_');
            Blockly.Arduino.definitions_['var_declare_' + varName] = `String ${varName} = R"JSONRAW(${content})JSONRAW";`;
            jsonParam = `${varName}.c_str()`;
        } else {
            jsonParam = `String(${jsonString}).c_str()`;
        }

        if (key.startsWith('"')) {
            const keyContent = key.slice(1, -1);
            const keyVarName = 'json_key_esp32_' + block.id.replace(/[^a-zA-Z0-9]/g, '_');
            Blockly.Arduino.definitions_['var_declare_' + keyVarName] = `String ${keyVarName} = "${keyContent}";`;
            keyParam = `${keyVarName}.c_str()`;
        } else {
            keyParam = `String(${key}).c_str()`;
        }

        Blockly.Arduino.definitions_['include_arduinojson'] = '#include <ArduinoJson.h>';

        Blockly.Arduino.definitions_['function_json_has_key_esp32'] = `
bool jsonHasKeyESP32(const char* jsonString, const char* key) {
  StaticJsonDocument<4096> doc;
  DeserializationError error = deserializeJson(doc, jsonString);

  if (error) {
    return false;
  }

  std::function<bool(JsonVariant, const char*)> searchKey;
  searchKey = [&searchKey](JsonVariant obj, const char* targetKey) -> bool {
    if (obj.is<JsonObject>()) {
      JsonObject object = obj.as<JsonObject>();
      for (JsonPair kv : object) {
        if (strcmp(kv.key().c_str(), targetKey) == 0) {
          return true;
        }
        if (kv.value().is<JsonObject>() || kv.value().is<JsonArray>()) {
          if (searchKey(kv.value(), targetKey)) {
            return true;
          }
        }
      }
    } else if (obj.is<JsonArray>()) {
      JsonArray array = obj.as<JsonArray>();
      for (JsonVariant item : array) {
        if (item.is<JsonObject>() || item.is<JsonArray>()) {
          if (searchKey(item, targetKey)) {
            return true;
          }
        }
      }
    }
    return false;
  };

  return searchKey(doc.as<JsonVariant>(), key);
}
`;

        const code = `jsonHasKeyESP32(${jsonParam}, ${keyParam})`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // ESP8266 专用检查键
    Blockly.Arduino.forBlock['json_has_key_esp8266'] = function(block) {
        let jsonString = Blockly.Arduino.valueToCode(block, 'JSON_STRING', Blockly.Arduino.ORDER_ATOMIC) || '""';
        let key = Blockly.Arduino.valueToCode(block, 'KEY', Blockly.Arduino.ORDER_ATOMIC) || '""';

        let jsonParam, keyParam;

        if (jsonString.startsWith('"')) {
            const content = jsonString.slice(1, -1);
            const varName = 'json_str_esp8266_' + block.id.replace(/[^a-zA-Z0-9]/g, '_');
            Blockly.Arduino.definitions_['var_declare_' + varName] = `String ${varName} = R"JSONRAW(${content})JSONRAW";`;
            jsonParam = `${varName}.c_str()`;
        } else {
            jsonParam = `String(${jsonString}).c_str()`;
        }

        if (key.startsWith('"')) {
            const keyContent = key.slice(1, -1);
            const keyVarName = 'json_key_esp8266_' + block.id.replace(/[^a-zA-Z0-9]/g, '_');
            Blockly.Arduino.definitions_['var_declare_' + keyVarName] = `String ${keyVarName} = "${keyContent}";`;
            keyParam = `${keyVarName}.c_str()`;
        } else {
            keyParam = `String(${key}).c_str()`;
        }

        Blockly.Arduino.definitions_['include_arduinojson'] = '#include <ArduinoJson.h>';

        Blockly.Arduino.definitions_['function_json_has_key_esp8266'] = `
bool jsonHasKeyESP8266(const char* jsonString, const char* key) {
  DynamicJsonDocument doc(4096);
  DeserializationError error = deserializeJson(doc, jsonString);

  if (error) {
    return false;
  }

  std::function<bool(JsonVariant, const char*)> searchKey;
  searchKey = [&searchKey](JsonVariant obj, const char* targetKey) -> bool {
    if (obj.is<JsonObject>()) {
      JsonObject object = obj.as<JsonObject>();
      for (JsonPair kv : object) {
        if (strcmp(kv.key().c_str(), targetKey) == 0) {
          return true;
        }
        if (kv.value().is<JsonObject>() || kv.value().is<JsonArray>()) {
          if (searchKey(kv.value(), targetKey)) {
            return true;
          }
        }
      }
    } else if (obj.is<JsonArray>()) {
      JsonArray array = obj.as<JsonArray>();
      for (JsonVariant item : array) {
        if (item.is<JsonObject>() || item.is<JsonArray>()) {
          if (searchKey(item, targetKey)) {
            return true;
          }
        }
      }
    }
    return false;
  };

  return searchKey(doc.as<JsonVariant>(), key);
}
`;

        const code = `jsonHasKeyESP8266(${jsonParam}, ${keyParam})`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

//初始化74HC595的控制管脚
Blockly.Arduino.forBlock['arduino_74hc595_start'] = function () {
    var text_ic_74hc595_name = this.getFieldValue('ic_74hc595_name');
    var value_ic_74hc595_num = Blockly.Arduino.valueToCode(this, 'ic_74hc595_num', Blockly.Arduino.ORDER_ATOMIC);
    var value_ic_74hc595_data = Blockly.Arduino.valueToCode(this, 'ic_74hc595_data', Blockly.Arduino.ORDER_ATOMIC) || '1';
    var value_ic_74hc595_clock = Blockly.Arduino.valueToCode(this, 'ic_74hc595_clock', Blockly.Arduino.ORDER_ATOMIC);
    var value_ic_74hc595_latch = Blockly.Arduino.valueToCode(this, 'ic_74hc595_latch', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_ShiftRegister74HC595'] = '#include <ShiftRegister74HC595.h>';
    Blockly.Arduino.definitions_['var_declare_74hc595' + text_ic_74hc595_name] = 'ShiftRegister74HC595<' + value_ic_74hc595_num + '> ' + text_ic_74hc595_name + '(' + value_ic_74hc595_data + ', ' + value_ic_74hc595_clock + ', ' + value_ic_74hc595_latch + ');';

    var code = '';
    return code;
};

//设置74HC595芯片中全部管脚的电平高低
Blockly.Arduino.forBlock['arduino_74hc595_set_all'] = function () {
    var text_ic_74hc595_name = this.getFieldValue('ic_74hc595_name');
    var dropdown_ic_74hc595_all_pin = this.getFieldValue('ic_74hc595_all_pin');

    var code = text_ic_74hc595_name + '.' + dropdown_ic_74hc595_all_pin + '();\n';
    return code;
};

//设置74HC595芯片中其中一个管脚的电平高低
Blockly.Arduino.forBlock['arduino_74hc595_set_one'] = function () {
    var text_ic_74hc595_name = this.getFieldValue('ic_74hc595_name');
    var value_ic_74hc595_one_pin = Blockly.Arduino.valueToCode(this, 'ic_74hc595_one_pin', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_ic_74hc595_one_pin_status = this.getFieldValue('ic_74hc595_one_pin_status');

    var code = text_ic_74hc595_name + '.set(' + value_ic_74hc595_one_pin + ', ' + dropdown_ic_74hc595_one_pin_status + ');\n';
    return code;
};

//设置74HC595芯片中其中一个管脚的电平高低
Blockly.Arduino.forBlock['arduino_74hc595_set_one_change'] = function () {
    var text_ic_74hc595_name = this.getFieldValue('ic_74hc595_name');
    var value_ic_74hc595_one_pin = Blockly.Arduino.valueToCode(this, 'ic_74hc595_one_pin', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_ic_74hc595_one_pin_status = Blockly.Arduino.valueToCode(this, 'ic_74hc595_one_pin_status', Blockly.Arduino.ORDER_ATOMIC);

    var code = text_ic_74hc595_name + '.set(' + value_ic_74hc595_one_pin + ', ' + dropdown_ic_74hc595_one_pin_status + ');\n';
    return code;
};

//设置74HC595芯片中各个管脚的电平高低（1个74HC595）
Blockly.Arduino.forBlock['arduino_74hc595_1_set'] = function () {
    var text_ic_74hc595_name = this.getFieldValue('ic_74hc595_name');
    var value_ic_74hc595_1_set_data = Blockly.Arduino.valueToCode(this, 'ic_74hc595_1_set_data', Blockly.Arduino.ORDER_ATOMIC);

    var code = 'uint8_t pinValues[] = {' + value_ic_74hc595_1_set_data + '};' +
        '\n' + text_ic_74hc595_name + '.setAll(pinValues);\n';
    return code;
};

//设置74HC595芯片中各个管脚的电平高低（2个74HC595相连）
Blockly.Arduino.forBlock['arduino_74hc595_2_set'] = function () {
    var text_ic_74hc595_name = this.getFieldValue('ic_74hc595_name');
    var value_ic_74hc595_1_set_data = Blockly.Arduino.valueToCode(this, 'ic_74hc595_1_set_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_ic_74hc595_2_set_data = Blockly.Arduino.valueToCode(this, 'ic_74hc595_2_set_data', Blockly.Arduino.ORDER_ATOMIC);

    var code = 'uint8_t pinValues[] = {' + value_ic_74hc595_1_set_data + ',' + value_ic_74hc595_2_set_data + '};' +
        '\n' + text_ic_74hc595_name + '.setAll(pinValues);\n';
    return code;
};

//设置74HC595芯片中各个管脚的电平高低（3个74HC595相连）
Blockly.Arduino.forBlock['arduino_74hc595_3_set'] = function () {
    var text_ic_74hc595_name = this.getFieldValue('ic_74hc595_name');
    var value_ic_74hc595_1_set_data = Blockly.Arduino.valueToCode(this, 'ic_74hc595_1_set_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_ic_74hc595_2_set_data = Blockly.Arduino.valueToCode(this, 'ic_74hc595_2_set_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_ic_74hc595_3_set_data = Blockly.Arduino.valueToCode(this, 'ic_74hc595_3_set_data', Blockly.Arduino.ORDER_ATOMIC);

    var code = 'uint8_t pinValues[] = {' + value_ic_74hc595_1_set_data + ',' + value_ic_74hc595_2_set_data + ',' + value_ic_74hc595_3_set_data + '};' +
        '\n' + text_ic_74hc595_name + '.setAll(pinValues);\n';
    return code;
};

//设置74HC595芯片中各个管脚的电平高低
Blockly.Arduino.forBlock['arduino_74hc595_pin'] = function () {
    var checkbox_ic_set_every_1 = this.getFieldValue('ic_set_every_1') == 'TRUE';
    var checkbox_ic_set_every_2 = this.getFieldValue('ic_set_every_2') == 'TRUE';
    var checkbox_ic_set_every_3 = this.getFieldValue('ic_set_every_3') == 'TRUE';
    var checkbox_ic_set_every_4 = this.getFieldValue('ic_set_every_4') == 'TRUE';
    var checkbox_ic_set_every_5 = this.getFieldValue('ic_set_every_5') == 'TRUE';
    var checkbox_ic_set_every_6 = this.getFieldValue('ic_set_every_6') == 'TRUE';
    var checkbox_ic_set_every_7 = this.getFieldValue('ic_set_every_7') == 'TRUE';
    var checkbox_ic_set_every_8 = this.getFieldValue('ic_set_every_8') == 'TRUE';
    var checkbox_ic_set_all = '';

    if (checkbox_ic_set_every_1) {
        checkbox_ic_set_every_1 = '1';
    }
    else {
        checkbox_ic_set_every_1 = '0';
    }

    if (checkbox_ic_set_every_2) {
        checkbox_ic_set_every_2 = '1';
    }
    else {
        checkbox_ic_set_every_2 = '0';
    }

    if (checkbox_ic_set_every_3) {
        checkbox_ic_set_every_3 = '1';
    }
    else {
        checkbox_ic_set_every_3 = '0';
    }

    if (checkbox_ic_set_every_4) {
        checkbox_ic_set_every_4 = '1';
    }
    else {
        checkbox_ic_set_every_4 = '0';
    }

    if (checkbox_ic_set_every_5) {
        checkbox_ic_set_every_5 = '1';
    }
    else {
        checkbox_ic_set_every_5 = '0';
    }

    if (checkbox_ic_set_every_6) {
        checkbox_ic_set_every_6 = '1';
    }
    else {
        checkbox_ic_set_every_6 = '0';
    }

    if (checkbox_ic_set_every_7) {
        checkbox_ic_set_every_7 = '1';
    }
    else {
        checkbox_ic_set_every_7 = '0';
    }

    if (checkbox_ic_set_every_8) {
        checkbox_ic_set_every_8 = '1';
    }
    else {
        checkbox_ic_set_every_8 = '0';
    }

    checkbox_ic_set_all = 'B' + checkbox_ic_set_every_1 + checkbox_ic_set_every_2 + checkbox_ic_set_every_3 + checkbox_ic_set_every_4 + checkbox_ic_set_every_5 + checkbox_ic_set_every_6 + checkbox_ic_set_every_7 + checkbox_ic_set_every_8;

    var code = checkbox_ic_set_all;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//使用数组来设置74HC595芯片中全部管脚的电平高低
Blockly.Arduino.forBlock['arduino_74hc595_set'] = function () {
    var text_ic_74hc595_name = this.getFieldValue('ic_74hc595_name');
    var text_ic_74hc595_everypin = this.getFieldValue('ic_74hc595_everypin');

    var code = text_ic_74hc595_name + '.setAll(' + text_ic_74hc595_everypin + ');\n';
    return code;
};

//获取74HC595芯片中某个管脚的状态
Blockly.Arduino.forBlock['arduino_74hc595_get'] = function () {
    var text_ic_74hc595_name = this.getFieldValue('ic_74hc595_name');
    var value_ic_74hc595_get_data = Blockly.Arduino.valueToCode(this, 'ic_74hc595_get_data', Blockly.Arduino.ORDER_ATOMIC);

    var code = '' + text_ic_74hc595_name + '.get(' + value_ic_74hc595_get_data + ')';

    return [code, Blockly.Arduino.ORDER_ATOMIC];
};


Blockly.Arduino.forBlock['make_arduino_boot_time_begin'] = function() {
  return 'resetTime = millis();\n';
};

Blockly.Arduino.forBlock['make_arduino_boot_time_duration'] = function(block) {
  var unit = block.getFieldValue('TIME_UNIT');
  var digits = block.getFieldValue('DIGITS');
  var formatStr = "%0" + digits + "d";
  // 添加字符串格式化所需的变量声明和头文件
  Blockly.Arduino.definitions_['var_declare_time_str'] = 'char timeStr[3];\n';
  Blockly.Arduino.definitions_['include_stdio'] = '#include <stdio.h>\n';
  var code;
    // 确保返回值为字符串类型
    Blockly.Arduino.setups_['boot_time_setup'] = 'resetTime = millis();\n';
    switch(unit) {
    case 'hours':
      code = `(sprintf(timeStr, "${formatStr}", (millis() - resetTime) / 3600000), timeStr)`;
      break;
    case 'minutes':
        code = '(sprintf(timeStr, "%02d", ((millis() - resetTime) % 3600000) / 60000), timeStr)';
        break;
      case 'seconds':
        code = '(sprintf(timeStr, "%02d", ((millis() - resetTime) % 60000) / 1000), timeStr)';
      break;
  }
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

// 已合并原小时/分钟/秒三个独立积木生成器，此处删除原定义

Blockly.Arduino.forBlock['make_arduino_boot_time_format'] = function() {
  Blockly.Arduino.definitions_['var_declare_time_str'] = 'char timeStr[9] = "";\n';
  Blockly.Arduino.definitions_['var_declare_boot_time'] = 'unsigned long resetTime = 0;\n';
  // 检查是否已设置串口波特率，如果没有则自动添加
  var hasSerialBegin = false;
  for (var key in Blockly.Arduino.setups_) {
      if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
          hasSerialBegin = true;
          break;
      }
  }
  if (!hasSerialBegin) {
      Blockly.Arduino.setups_['setup_boot_time'] = 'Serial.begin(9600);\n';
  }
  var code = 'unsigned long currentMillis = millis() - resetTime;\n' +
             'unsigned long totalSec = currentMillis / 1000;\n';
  return code;
};

//初始化DS1307，默认时间为系统此时的时间
Blockly.Arduino.forBlock['make_ds1307_begin'] = function () {
    var text_ds1307_name = this.getFieldValue('ds1307_name');
    var checkbox_ds1307_get_time_date = this.getFieldValue('ds1307_get_time_date') == 'TRUE';
    var value_ds1307_begin_year = Blockly.Arduino.valueToCode(this, 'ds1307_begin_year', Blockly.Arduino.ORDER_ATOMIC);
    var value_ds1307_begin_month = Blockly.Arduino.valueToCode(this, 'ds1307_begin_month', Blockly.Arduino.ORDER_ATOMIC);
    var value_ds1307_begin_day = Blockly.Arduino.valueToCode(this, 'ds1307_begin_day', Blockly.Arduino.ORDER_ATOMIC);
    var value_ds1307_begin_hour = Blockly.Arduino.valueToCode(this, 'ds1307_begin_hour', Blockly.Arduino.ORDER_ATOMIC);
    var value_ds1307_begin_minute = Blockly.Arduino.valueToCode(this, 'ds1307_begin_minute', Blockly.Arduino.ORDER_ATOMIC);
    var value_ds1307_begin_second = Blockly.Arduino.valueToCode(this, 'ds1307_begin_second', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_RTClib'] = '#include <RTClib.h>';
    Blockly.Arduino.definitions_['var_declare_start_ds1307' + text_ds1307_name] = 'RTC_DS1307 ' + text_ds1307_name + ';';

    // 检查是否已设置串口波特率，如果没有则自动添加
    var hasSerialBegin = false;
    for (var key in Blockly.Arduino.setups_) {
        if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
            hasSerialBegin = true;
            break;
        }
    }
    if (!hasSerialBegin) {
        Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
    }
    Blockly.Arduino.setups_['setup_wire_ds1307' + text_ds1307_name] = 'Wire.begin(); \n  ' + text_ds1307_name + '.begin();';
    if (!checkbox_ds1307_get_time_date) {
        Blockly.Arduino.setups_['setup_wire_ds1307_adjust' + text_ds1307_name] = text_ds1307_name + '.adjust(DateTime(' + value_ds1307_begin_year + ', ' + value_ds1307_begin_month + ', ' + value_ds1307_begin_day + ', ' + value_ds1307_begin_hour + ' ,' + value_ds1307_begin_minute + ', ' + value_ds1307_begin_second + '));';
    }
    var code = '';
    return code;
};

//获取DS1307中的时间与日期
Blockly.Arduino.forBlock['make_ds1307_get_time_date'] = function () {
    var text_get_time_date_name = this.getFieldValue('get_time_date_name');
    var value_get_time_date_data = Blockly.Arduino.valueToCode(this, 'get_time_date_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'DateTime ' + text_get_time_date_name + ' = ' + value_get_time_date_data + '.now();\n';
    return code;
};

//返回DS1307中的时间与日期
Blockly.Arduino.forBlock['make_ds1307_get_time_date_data'] = function () {
    var text_ds1307_name = this.getFieldValue('ds1307_name');
    var code = text_ds1307_name + '.now()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//返回 时间&日期 中的年、月、日、时、分、秒
Blockly.Arduino.forBlock['make_ds1307_get_time_date_1'] = function () {
    var text_timedate_name = this.getFieldValue('timedate_name');
    var dropdown_get_time_date_data = this.getFieldValue('get_time_date_data');
    var code = '' + text_timedate_name + '.' + dropdown_get_time_date_data + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//设置DS1302中的年、月、日、时、分、秒
Blockly.Arduino.forBlock['make_ds1307_set_time_date'] = function () {
    var value_set_time_date_data = Blockly.Arduino.valueToCode(this, 'set_time_date_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_ds1307_name = this.getFieldValue('ds1307_name');
    var dropdown_set_time_date_type = this.getFieldValue('set_time_date_type');
    var code = '' + text_ds1307_name + '.set(' + dropdown_set_time_date_type + ', ' + value_set_time_date_data + ');\n';
    return code;
};

//初始化AT24C32
Blockly.Arduino.forBlock['make_at24c32_begin'] = function () {
    var value_at24c32_begin_data = Blockly.Arduino.valueToCode(this, 'at24c32_begin_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_at24c32_name = this.getFieldValue('at24c32_name');

    Blockly.Arduino.definitions_['include_AT24Cxx'] = '#include <AT24Cxx.h>';
    Blockly.Arduino.definitions_['var_declare_start_at24c32' + text_at24c32_name] = 'AT24Cxx ' + text_at24c32_name + '(' + value_at24c32_begin_data + ');';
    var code = '';
    return code;
};

//AT24C32指定地址写入数据，地址的范围是0-4096,数据的大小是一字节
Blockly.Arduino.forBlock['make_at24c32_writemem'] = function () {
    var text_at24c32_name = this.getFieldValue('at24c32_name');
    var value_at24c32_writemem_area = Blockly.Arduino.valueToCode(this, 'at24c32_writemem_area', Blockly.Arduino.ORDER_ATOMIC);
    var value_at24c32_writemem_data = Blockly.Arduino.valueToCode(this, 'at24c32_writemem_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_at24c32_name + '.WriteMem(' + value_at24c32_writemem_area + ', ' + value_at24c32_writemem_data + ');\n';
    return code;
};

//AT24C32指定地址写入数据，地址的范围是0-4096，数据为一字节，字节数必须要小于等于数组的大小
Blockly.Arduino.forBlock['make_at24c32_writemem_1'] = function () {
    var text_at24c32_name = this.getFieldValue('at24c32_name');
    var value_at24c32_writemem_area = Blockly.Arduino.valueToCode(this, 'at24c32_writemem_area', Blockly.Arduino.ORDER_ATOMIC);
    var value_at24c32_writemem_data = Blockly.Arduino.valueToCode(this, 'at24c32_writemem_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_at24c32_writemem_num = Blockly.Arduino.valueToCode(this, 'at24c32_writemem_num', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_at24c32_name + '.WriteMem(' + value_at24c32_writemem_area + ', ' + value_at24c32_writemem_data + ', ' + value_at24c32_writemem_num + ');\n';
    return code;
};

//AT24C32指定地址读取数据，地址的范围是0-4096
Blockly.Arduino.forBlock['make_at24c32_readmem'] = function () {
    var text_at24c32_name = this.getFieldValue('at24c32_name');
    var value_at24c32_readmem_area = Blockly.Arduino.valueToCode(this, 'at24c32_readmem_area', Blockly.Arduino.ORDER_ATOMIC);
    var value_at24c32_readmem_data = Blockly.Arduino.valueToCode(this, 'at24c32_readmem_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_at24c32_name + '.ReadMem(' + value_at24c32_readmem_area + ', ' + value_at24c32_readmem_data + ');\n';
    return code;
};

//AT24C32指定地址读取数据，地址的范围是0-4096，数据为一字节，字节数必须要小于等于数组的大小
Blockly.Arduino.forBlock['make_at24c32_readmem_1'] = function () {
    var text_at24c32_name = this.getFieldValue('at24c32_name');
    var value_at24c32_readmem_area = Blockly.Arduino.valueToCode(this, 'at24c32_readmem_area', Blockly.Arduino.ORDER_ATOMIC);
    var value_at24c32_readmem_data = Blockly.Arduino.valueToCode(this, 'at24c32_readmem_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_at24c32_readmem_num = Blockly.Arduino.valueToCode(this, 'at24c32_readmem_num', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_at24c32_name + '.ReadMem(' + value_at24c32_readmem_area + ', ' + value_at24c32_readmem_data + ', ' + value_at24c32_readmem_num + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_rtc_begin'] = function () {
    var dropdown_rtc_type = this.getFieldValue('rtc_type');
    var text_rtc_name = this.getFieldValue('rtc_name');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_RTClib'] = '#include <RTClib.h>';
    Blockly.Arduino.definitions_['var_declare_start_ds1307' + text_rtc_name] = 'RTC_' + dropdown_rtc_type + ' ' + text_rtc_name + ';';

    Blockly.Arduino.setups_['setup_rtc_' + text_rtc_name] = text_rtc_name + '.begin();';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_rtc_adjust_1'] = function () {
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_adjust_date = Blockly.Arduino.valueToCode(this, 'adjust_date', Blockly.Arduino.ORDER_ATOMIC);
    var value_adjust_time = Blockly.Arduino.valueToCode(this, 'adjust_time', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.adjust(DateTime(' + value_adjust_date + ', ' + value_adjust_time + '));\n';
    return code;
};

Blockly.Arduino.forBlock['make_get_system_date_time'] = function () {
    var dropdown_get_system_data = this.getFieldValue('get_system_data');
    var code = '__' + dropdown_get_system_data + '__';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_rtc_adjust_2'] = function () {
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_adjust_year = Blockly.Arduino.valueToCode(this, 'adjust_year', Blockly.Arduino.ORDER_ATOMIC);
    var value_adjust_month = Blockly.Arduino.valueToCode(this, 'adjust_month', Blockly.Arduino.ORDER_ATOMIC);
    var value_adjust_day = Blockly.Arduino.valueToCode(this, 'adjust_day', Blockly.Arduino.ORDER_ATOMIC);
    var value_adjust_hour = Blockly.Arduino.valueToCode(this, 'adjust_hour', Blockly.Arduino.ORDER_ATOMIC);
    var value_adjust_minute = Blockly.Arduino.valueToCode(this, 'adjust_minute', Blockly.Arduino.ORDER_ATOMIC);
    var value_adjust_second = Blockly.Arduino.valueToCode(this, 'adjust_second', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_rtc_name + '.adjust(DateTime(' + value_adjust_year + ', ' + value_adjust_month + ', ' + value_adjust_day + ', ' + value_adjust_hour + ', ' + value_adjust_minute + ', ' + value_adjust_second + '));\n';
    return code;
};

Blockly.Arduino.forBlock['make_rtc_adjust_3'] = function () {
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_adjust_data = Blockly.Arduino.valueToCode(this, 'adjust_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_adjust_type = this.getFieldValue('adjust_type');

    Blockly.Arduino.definitions_['function_' + text_rtc_name + '_adjust'] = '//RTC时钟调整时间'
        + '\nint ' + text_rtc_name + '_adjust(int select_data, int data)'
        + '\n{'
        + '\n  DateTime now = ' + text_rtc_name + '.now();'
        + '\n  int date_data[6];'
        + '\n  date_data[0] = now.year();'
        + '\n  date_data[1] = now.month();'
        + '\n  date_data[2] = now.day();'
        + '\n  date_data[3] = now.hour();'
        + '\n  date_data[4] = now.minute();'
        + '\n  date_data[5] = now.second();'
        + '\n  if(select_data <= 5 && select_data >=0)'
        + '\n  {'
        + '\n    date_data[select_data] = data;'
        + '\n    ' + text_rtc_name + '.adjust(DateTime(date_data[0], date_data[1], date_data[2], date_data[3], date_data[4], date_data[5]));'
        + '\n    return 1;'
        + '\n  }'
        + '\n  else'
        + '\n    return 0;'
        + '\n}\n';
    var code = text_rtc_name + '_adjust(' + dropdown_adjust_type + ', ' + value_adjust_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_rtc_get_time_date_1'] = function () {
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_get_time_date_data = this.getFieldValue('get_time_date_data');
    var code = text_rtc_name + '.now().' + dropdown_get_time_date_data + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//获取DS1307中的时间与日期
Blockly.Arduino.forBlock['make_rtc_get_time_date'] = function () {
    var text_get_time_date_name = this.getFieldValue('get_time_date_name');
    var value_get_time_date_data = Blockly.Arduino.valueToCode(this, 'get_time_date_data', Blockly.Arduino.ORDER_ATOMIC);

    var code = '';
    if (value_get_time_date_data)
        code = 'DateTime ' + text_get_time_date_name + ' = ' + value_get_time_date_data + ';\n';
    else
        code = 'DateTime now = RTC.now();\n'
    return code;
};

Blockly.Arduino.forBlock['make_calculate_date_time'] = function () {
    var value_future_day = Blockly.Arduino.valueToCode(this, 'future_day', Blockly.Arduino.ORDER_ATOMIC);
    var value_future_hour = Blockly.Arduino.valueToCode(this, 'future_hour', Blockly.Arduino.ORDER_ATOMIC);
    var value_future_minute = Blockly.Arduino.valueToCode(this, 'future_minute', Blockly.Arduino.ORDER_ATOMIC);
    var value_future_second = Blockly.Arduino.valueToCode(this, 'future_second', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'TimeSpan(' + value_future_day + ',' + value_future_hour + ',' + value_future_minute + ',' + value_future_second + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_calculate_date_time_1'] = function () {
    var value_future_second = Blockly.Arduino.valueToCode(this, 'future_second', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'TimeSpan(' + value_future_second + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_rtc_get_temperature'] = function () {
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = '' + text_rtc_name + '.getTemperature()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/********** RTC时钟模块 **********/
/*
* 通用
*/

/*
//设置RTC时钟的时间与日期
Blockly.Arduino.forBlock['make_rtc_SetDateTime'] = function() {
  var text_rtc_name = this.getFieldValue('rtc_name');
  var value_date = Blockly.Arduino.valueToCode(this, 'date', Blockly.Arduino.ORDER_ATOMIC);
  var value_time = Blockly.Arduino.valueToCode(this, 'time', Blockly.Arduino.ORDER_ATOMIC);
  var code = text_rtc_name+'.SetDateTime(RtcDateTime('+value_date+', '+value_time+'));\n';
  return code;
};
*/

/*
//设置RTC时钟的时间与日期-1
Blockly.Arduino.forBlock['make_rtc_SetDateTime_1'] = function() {
  var text_rtc_name = this.getFieldValue('rtc_name');
  var value_year = Blockly.Arduino.valueToCode(this, 'year', Blockly.Arduino.ORDER_ATOMIC);
  var value_month = Blockly.Arduino.valueToCode(this, 'month', Blockly.Arduino.ORDER_ATOMIC);
  var value_day = Blockly.Arduino.valueToCode(this, 'day', Blockly.Arduino.ORDER_ATOMIC);
  var value_hour = Blockly.Arduino.valueToCode(this, 'hour', Blockly.Arduino.ORDER_ATOMIC);
  var value_minute = Blockly.Arduino.valueToCode(this, 'minute', Blockly.Arduino.ORDER_ATOMIC);
  var value_second = Blockly.Arduino.valueToCode(this, 'second', Blockly.Arduino.ORDER_ATOMIC);
  var code = text_rtc_name+'.SetDateTime(RtcDateTime('+value_year+', '+value_month+', '+value_day+', '+value_hour+', '+value_minute+', '+value_second+'));\n';
  return code;
};
*/

/*
//设置RTC时钟的时间与日期-3
Blockly.Arduino.forBlock['make_rtc_SetDateTime_3'] = function() {
  var text_rtc_name = this.getFieldValue('rtc_name');
  var text_rtcdatetime_name = this.getFieldValue('rtcdatetime_name');
  
  var code = text_rtc_name+'.SetDateTime('+text_rtcdatetime_name+');\n';
  return code;
};
*/

/*
//时间&日期赋值
Blockly.Arduino.forBlock['make_RtcDateTime_get_time_date_1'] = function() {
  var text_rtcdatetime_name = this.getFieldValue('rtcdatetime_name');
  var text_rtc_name = this.getFieldValue('rtc_name');
  
  var code = 'RtcDateTime '+text_rtcdatetime_name+' = '+text_rtc_name+'.GetDateTime();\n';
  return code;
};
*/

/*
//设置时间&日期的时间与日期
Blockly.Arduino.forBlock['make_RtcDateTime_SetDateTime'] = function() {
  var text_rtc_name = this.getFieldValue('rtc_name');
  var value_date = Blockly.Arduino.valueToCode(this, 'date', Blockly.Arduino.ORDER_ATOMIC);
  var value_time = Blockly.Arduino.valueToCode(this, 'time', Blockly.Arduino.ORDER_ATOMIC);
  var code = 'RtcDateTime '+text_rtc_name+' = RtcDateTime('+value_date+', '+value_time+');\n';
  return code;
};
*/

/*
//设置时间&日期的时间与日期-1
Blockly.Arduino.forBlock['make_RtcDateTime_SetDateTime_1'] = function() {
  var text_rtc_name = this.getFieldValue('rtc_name');
  var value_year = Blockly.Arduino.valueToCode(this, 'year', Blockly.Arduino.ORDER_ATOMIC);
  var value_month = Blockly.Arduino.valueToCode(this, 'month', Blockly.Arduino.ORDER_ATOMIC);
  var value_day = Blockly.Arduino.valueToCode(this, 'day', Blockly.Arduino.ORDER_ATOMIC);
  var value_hour = Blockly.Arduino.valueToCode(this, 'hour', Blockly.Arduino.ORDER_ATOMIC);
  var value_minute = Blockly.Arduino.valueToCode(this, 'minute', Blockly.Arduino.ORDER_ATOMIC);
  var value_second = Blockly.Arduino.valueToCode(this, 'second', Blockly.Arduino.ORDER_ATOMIC);
  var code = 'RtcDateTime '+text_rtc_name+' = RtcDateTime('+value_year+', '+value_month+', '+value_day+', '+value_hour+', '+value_minute+', '+value_second+');\n';
  return code;
};
*/

/*
* RTC时钟
*/
//RTC时间日期可读？ | RTC正在运行？
Blockly.Arduino.forBlock['make_rtc_IsDateTimeValid_GetIsRunning'] = function () {
    this.setTooltip("RTC时间日期可读？ | RTC正在运行？");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS1302时钟模块 设置运行状态
Blockly.Arduino.forBlock['make_rtc_ds1302_SetIsRunning'] = function () {
    this.setTooltip("RTC时钟 设置运行状态");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    //var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.SetIsRunning(' + value_data + ');\n';
    return code;
};

//RTC时钟设置时间与日期
Blockly.Arduino.forBlock['make_RTC_SetDateTime'] = function () {
    this.setTooltip("RTC时钟 设置时间与日期");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.SetDateTime(' + value_data + ');\n';
    return code;
};

//调整RTC时钟的时间与日期
Blockly.Arduino.forBlock['make_rtc_SetDateTime_2'] = function () {
    this.setTooltip("RTC时钟 调整时间与日期");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_type = this.getFieldValue('type');

    Blockly.Arduino.definitions_['function_' + text_rtc_name + '_SetDateTime'] = '//RTC时钟调整时间'
        + '\nbool ' + text_rtc_name + '_SetDateTime(int select_data, int data)'
        + '\n{'
        + '\n  RtcDateTime now = ' + text_rtc_name + '.GetDateTime();'
        + '\n  int date_data[6];'
        + '\n  date_data[0] = now.Year();'
        + '\n  date_data[1] = now.Month();'
        + '\n  date_data[2] = now.Day();'
        + '\n  date_data[3] = now.Hour();'
        + '\n  date_data[4] = now.Minute();'
        + '\n  date_data[5] = now.Second();'
        + '\n  if(select_data <= 5 && select_data >=0)'
        + '\n  {'
        + '\n    date_data[select_data] = data;'
        + '\n    ' + text_rtc_name + '.SetDateTime(RtcDateTime(date_data[0], date_data[1], date_data[2], date_data[3], date_data[4], date_data[5]));'
        + '\n    return 1;'
        + '\n  }'
        + '\n  else'
        + '\n    return 0;'
        + '\n}\n';
    var code = text_rtc_name + '_SetDateTime(' + dropdown_type + ', ' + value_data + ');\n';
    return code;
};

//获取RTC时钟的时间和日期
Blockly.Arduino.forBlock['make_rtc_get_now_data'] = function () {
    this.setTooltip("RTC时钟 获取当前时间和日期");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.GetDateTime()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//获取RTC时钟的年、月、日、时、分、秒、周
Blockly.Arduino.forBlock['make_RtcDateTime_get_time_date'] = function () {
    this.setTooltip("RTC时钟 获取年、月、日、时、分、秒、周，返回数据的类型为uint16_t(年)、uint16_t(月、日、时、分、秒、周)");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');

    var code = text_rtc_name + '.GetDateTime().' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
* 时间&日期
*/
//初始化时间&日期
Blockly.Arduino.forBlock['make_DateTime_declare'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_DateTime_name = this.getFieldValue('DateTime_name');
    var code = 'RtcDateTime ' + text_DateTime_name + ' = ' + value_data + ';\n';
    return code;
};

//时间&日期赋值
Blockly.Arduino.forBlock['make_DateTime_set_data'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_DateTime_name = this.getFieldValue('DateTime_name');
    var code = text_DateTime_name + ' = ' + value_data + ';\n';
    return code;
};

//获取时间&日期
Blockly.Arduino.forBlock['make_DateTime_get_data'] = function () {
    var text_DateTime_name = this.getFieldValue('DateTime_name');
    var code = text_DateTime_name;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//RtcDateTime时间与日期可读？
Blockly.Arduino.forBlock['make_DateTime_IsValid'] = function () {
    this.setTooltip("RtcDateTime 时间与日期可读？，返回数据的类型为boolean");
    var text_DateTime_name = this.getFieldValue('DateTime_name');
    var code = text_DateTime_name + '.IsValid()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//获取RtcDateTime的时间与日期-1
Blockly.Arduino.forBlock['make_DateTime_get_1'] = function () {
    this.setTooltip("RtcDateTime 获取的时间与日期，返回数据的类型为RtcDateTime");
    var value_date = Blockly.Arduino.valueToCode(this, 'date', Blockly.Arduino.ORDER_ATOMIC);
    var value_time = Blockly.Arduino.valueToCode(this, 'time', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'RtcDateTime(' + value_date + ', ' + value_time + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//获取RtcDateTime的时间与日期-2
Blockly.Arduino.forBlock['make_DateTime_get_2'] = function () {
    this.setTooltip("RtcDateTime 获取的时间与日期，返回数据的类型为RtcDateTime");
    var value_year = Blockly.Arduino.valueToCode(this, 'year', Blockly.Arduino.ORDER_ATOMIC);
    var value_month = Blockly.Arduino.valueToCode(this, 'month', Blockly.Arduino.ORDER_ATOMIC);
    var value_day = Blockly.Arduino.valueToCode(this, 'day', Blockly.Arduino.ORDER_ATOMIC);
    var value_hour = Blockly.Arduino.valueToCode(this, 'hour', Blockly.Arduino.ORDER_ATOMIC);
    var value_minute = Blockly.Arduino.valueToCode(this, 'minute', Blockly.Arduino.ORDER_ATOMIC);
    var value_second = Blockly.Arduino.valueToCode(this, 'second', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'RtcDateTime(' + value_year + ', ' + value_month + ', ' + value_day + ', ' + value_hour + ', ' + value_minute + ', ' + value_second + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//RtcDateTime增加或减少时间
Blockly.Arduino.forBlock['make_DateTime_add_remove'] = function () {
    this.setTooltip("RtcDateTime 增加或减少时间");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_type = this.getFieldValue('type');
    var value_day = Blockly.Arduino.valueToCode(this, 'day', Blockly.Arduino.ORDER_ATOMIC);
    var value_hour = Blockly.Arduino.valueToCode(this, 'hour', Blockly.Arduino.ORDER_ATOMIC);
    var value_minute = Blockly.Arduino.valueToCode(this, 'minute', Blockly.Arduino.ORDER_ATOMIC);
    var value_second = Blockly.Arduino.valueToCode(this, 'second', Blockly.Arduino.ORDER_ATOMIC);
    var code = value_data + ' ' + dropdown_type + ' (uint32_t)((uint32_t)' + value_day + '*24*60*60 + (uint32_t)' + value_hour + '*60*60 + (uint32_t)' + value_minute + '*60 + (uint32_t)' + value_second + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//获取时间&日期的年、月、日、时、分、秒、周
Blockly.Arduino.forBlock['make_RtcDateTime_get_time_date_2'] = function () {
    this.setTooltip("RtcDateTime 获取年、月、日、时、分、秒、周，返回数据的类型为uint16_t(年)、uint16_t(月、日、时、分、秒、周)");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
* AT24C32
*/
//初始化AT24C32(使用硬件I2C)
Blockly.Arduino.forBlock['make_rtc_at24c32_begin'] = function () {
    this.setTooltip("初始化AT24C32存储器");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_eeprom_name = this.getFieldValue('eeprom_name');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_EepromAT24C32'] = '#include <EepromAT24C32.h>';
    Blockly.Arduino.definitions_['var_declare_at24c32_' + text_eeprom_name] = 'EepromAt24c32<TwoWire> ' + text_eeprom_name + '(Wire, ' + value_address + ');';

    Blockly.Arduino.setups_['setup_at24c32_' + text_eeprom_name] = text_eeprom_name + '.Begin();';
    var code = '';
    return code;
};

//初始化AT24C32(使用软件模拟I2C)
Blockly.Arduino.forBlock['make_rtc_at24c32_begin_1'] = function () {
    this.setTooltip("初始化AT24C32存储器");
    var text_eeprom_name = this.getFieldValue('eeprom_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_EepromAT24C32'] = '#include <EepromAT24C32.h>';

    // 使用默认的 Wire 对象初始化 EepromAt24c32
    Blockly.Arduino.definitions_['var_declare_at24c32_' + text_eeprom_name] = 
        'EepromAt24c32<TwoWire> ' + text_eeprom_name + '(Wire, ' + value_address + ');';

    // 在 setup 中重新配置 Wire 对象的引脚
    Blockly.Arduino.setups_['setup_custom_wire'] = 
        'Wire.begin(' + value_sda + ', ' + value_scl + ');';

    // 初始化 AT24C32 存储器
    Blockly.Arduino.setups_['setup_at24c32_' + text_eeprom_name] = text_eeprom_name + '.Begin();';
    
    var code = '';
    return code;
};




//AT24C32 地址
Blockly.Arduino.forBlock['make_rtc_at24c32_address'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//AT24C32 返回上次连接的错误码
Blockly.Arduino.forBlock['make_rtc_at24c32_LastError'] = function () {
    this.setTooltip("AT24C32 返回上次连接的错误码，返回数据的类型为uint8_t");
    var text_eeprom_name = this.getFieldValue('eeprom_name');
    var code = text_eeprom_name + '.LastError()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//AT24C32 写入字节
Blockly.Arduino.forBlock['make_rtc_at24c32_SetMemory_byte'] = function () {
    this.setTooltip("AT24C32 写入字节");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_eeprom_name = this.getFieldValue('eeprom_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_eeprom_name + '.SetMemory(' + value_address + ', ' + value_data + ');\n';
    return code;
};

//AT24C32 读取字节
Blockly.Arduino.forBlock['make_rtc_at24c32_GetMemory_byte'] = function () {
    this.setTooltip("AT24C32 读取字节，返回数据的类型为uint8_t");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_eeprom_name = this.getFieldValue('eeprom_name');
    var code = text_eeprom_name + '.GetMemory(' + value_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//AT24C32 写入字节数组
Blockly.Arduino.forBlock['make_rtc_at24c32_SetMemory_list'] = function () {
    this.setTooltip("AT24C32 写入字节数组，返回数据的类型为uint8_t");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_eeprom_name = this.getFieldValue('eeprom_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_eeprom_name + '.SetMemory(' + value_address + ', (const uint8_t*)' + value_data + ', ' + value_length + ');\n';
    return code;
};

//AT24C32 读取字节数组
Blockly.Arduino.forBlock['make_rtc_at24c32_GetMemory_list'] = function () {
    this.setTooltip("AT24C32 读取字节数组，返回数据的类型为uint8_t");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_eeprom_name = this.getFieldValue('eeprom_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_eeprom_name + '.GetMemory(' + value_address + ', ' + value_data + ', ' + value_length + ');\n';
    return code;
};

//AT24C32时钟模块 读取字节数组，返回读取结果
Blockly.Arduino.forBlock['make_rtc_at24c32_GetMemory_list_return'] = function () {
    this.setTooltip("AT24C32 读取字节数组，返回数据的类型为uint8_t");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_eeprom_name = this.getFieldValue('eeprom_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_eeprom_name + '.GetMemory(' + value_address + ', ' + value_data + ', ' + value_length + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
* DS1302
*/
//初始化DS1302
Blockly.Arduino.forBlock['make_rtc_ds1302_begin'] = function () {
    this.setTooltip("初始化DS1302时钟模块");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_rst = Blockly.Arduino.valueToCode(this, 'rst', Blockly.Arduino.ORDER_ATOMIC);
    var value_dat = Blockly.Arduino.valueToCode(this, 'dat', Blockly.Arduino.ORDER_ATOMIC);
    var value_clk = Blockly.Arduino.valueToCode(this, 'clk', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_AThreeWire'] = '#include <ThreeWire.h>  ';
    Blockly.Arduino.definitions_['include_RtcDS1302'] = '#include <RtcDS1302.h>';
    Blockly.Arduino.definitions_['var_declare_rtc_' + text_rtc_name] = 'ThreeWire Wire_' + value_dat + '_' + value_clk + '_' + value_rst + '(' + value_dat + ', ' + value_clk + ', ' + value_rst + ');\n'
        + 'RtcDS1302<ThreeWire> ' + text_rtc_name + '(Wire_' + value_dat + '_' + value_clk + '_' + value_rst + ');';

    Blockly.Arduino.setups_['setup_rtc_' + text_rtc_name] = text_rtc_name + '.Begin();';
    var code = '';
    return code;
};

//DS1302时钟模块 写保护？
Blockly.Arduino.forBlock['make_rtc_ds1302_GetIsWriteProtected'] = function () {
    this.setTooltip("DS1302时钟模块 写保护？，返回数据的类型为boolean");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.GetIsWriteProtected()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS1302时钟模块 设置写保护
Blockly.Arduino.forBlock['make_rtc_ds1302_SetIsWriteProtected'] = function () {
    this.setTooltip("DS1302时钟模块 设置写保护");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    //var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.SetIsWriteProtected(' + value_data + ');\n';
    return code;
};

//DS1302时钟模块 设置涓流充电功能
Blockly.Arduino.forBlock['make_rtc_ds1302_SetTrickleChargeSettings'] = function () {
    this.setTooltip("DS1302时钟模块 设置涓流充电功能");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type1 = this.getFieldValue('type1');
    var dropdown_type2 = this.getFieldValue('type2');
    var dropdown_type3 = this.getFieldValue('type3');
    var code = text_rtc_name + '.SetTrickleChargeSettings(B' + dropdown_type1 + dropdown_type2 + dropdown_type3 + ');\n';
    return code;
};

//DS1302时钟模块 获取涓流充电设置
Blockly.Arduino.forBlock['make_rtc_ds1302_GetTrickleChargeSettings'] = function () {
    this.setTooltip("DS1302时钟模块 获取涓流充电设置，返回数据的类型为uint8_t");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.GetTrickleChargeSettings()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS1302时钟模块 写入字节
Blockly.Arduino.forBlock['make_rtc_ds1302_SetMemory_byte'] = function () {
    this.setTooltip("DS1302时钟模块 写入字节");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.SetMemory((uint8_t)' + value_address + ', ' + value_data + ');\n';
    return code;
};

//DS1302时钟模块 读取字节
Blockly.Arduino.forBlock['make_rtc_ds1302_GetMemory_byte'] = function () {
    this.setTooltip("DS1302时钟模块 读取字节，返回数据的类型为uint8_t");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.GetMemory(' + value_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS1302时钟模块 写入字节数组
Blockly.Arduino.forBlock['make_rtc_ds1302_SetMemory_list'] = function () {
    this.setTooltip("DS1302时钟模块 写入字节数组，返回数据的类型为uint8_t");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.SetMemory((const uint8_t*)' + value_data + ', ' + value_length + ');\n';
    return code;
};

//DS1302时钟模块 读取字节数组
Blockly.Arduino.forBlock['make_rtc_ds1302_GetMemory_list'] = function () {
    this.setTooltip("DS1302时钟模块 读取字节数组，返回数据的类型为uint8_t");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.GetMemory(' + value_data + ', ' + value_length + ');\n';
    return code;
};

//DS1302时钟模块 读取字节数组，返回读取结果
Blockly.Arduino.forBlock['make_rtc_ds1302_GetMemory_list_return'] = function () {
    this.setTooltip("DS1302时钟模块 读取字节数组，返回数据的类型为uint8_t");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.GetMemory(' + value_data + ', ' + value_length + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
* DS1307
*/
//初始化DS1307、DS3231时钟模块(I2C)
Blockly.Arduino.forBlock['make_rtc_ds1307_3231_begin'] = function () {
    this.setTooltip("初始化DS1307、DS3231时钟模块");
    var dropdown_rtc_type = this.getFieldValue('rtc_type');
    var text_rtc_name = this.getFieldValue('rtc_name');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_' + dropdown_rtc_type] = '#include <' + dropdown_rtc_type + '.h>';
    Blockly.Arduino.definitions_['var_declare_rtc_' + text_rtc_name] = '' + dropdown_rtc_type + '<TwoWire> ' + text_rtc_name + '(Wire);';

    Blockly.Arduino.setups_['setup_rtc_' + text_rtc_name] = text_rtc_name + '.Begin();';
    var code = '';
    return code;
};

//初始化DS1307、DS3231时钟模块(I2C)-可以定义管脚
Blockly.Arduino.forBlock['make_rtc_ds1307_3231_begin_1'] = function () {
    this.setTooltip("初始化DS1307、DS3231时钟模块");
    var dropdown_rtc_type = this.getFieldValue('rtc_type');
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_SoftwareWire'] = '#include <SoftwareWire.h>';
    Blockly.Arduino.definitions_['include_' + dropdown_rtc_type] = '#include <' + dropdown_rtc_type + '.h>';
    Blockly.Arduino.definitions_['var_declare_SoftwareWire' + value_sda + '_' + value_scl] = 'SoftwareWire Wire_' + value_sda + '_' + value_scl + '(' + value_sda + ', ' + value_scl + ');';
    Blockly.Arduino.definitions_['var_declare_rtc_' + text_rtc_name] = dropdown_rtc_type + '<SoftwareWire> ' + text_rtc_name + '(Wire_' + value_sda + '_' + value_scl + ');';

    Blockly.Arduino.setups_['setup_rtc_' + text_rtc_name] = text_rtc_name + '.Begin();';
    var code = '';
    return code;
};

//DS1307时钟模块 返回上次连接的错误码
Blockly.Arduino.forBlock['make_rtc_ds1307_LastError'] = function () {
    this.setTooltip("DS1307时钟模块 返回上次连接的错误码，返回数据的类型为uint8_t");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.LastError()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS1307时钟模块 写入字节
Blockly.Arduino.forBlock['make_rtc_ds1307_SetMemory_byte'] = function () {
    this.setTooltip("DS1307时钟模块 写入字节");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.SetMemory(' + value_address + ', ' + value_data + ');\n';
    return code;
};

//DS1307时钟模块 读取字节
Blockly.Arduino.forBlock['make_rtc_ds1307_GetMemory_byte'] = function () {
    this.setTooltip("DS1307时钟模块 读取字节，返回数据的类型为uint8_t");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.GetMemory(' + value_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS1307时钟模块 写入字节数组
Blockly.Arduino.forBlock['make_rtc_ds1307_SetMemory_list'] = function () {
    this.setTooltip("DS1307时钟模块 写入字节数组，返回数据的类型为uint8_t");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.SetMemory(' + value_address + ', (const uint8_t*)' + value_data + ', ' + value_length + ');\n';
    return code;
};

//DS1307时钟模块 读取字节数组
Blockly.Arduino.forBlock['make_rtc_ds1307_GetMemory_list'] = function () {
    this.setTooltip("DS1307时钟模块 读取字节数组，返回数据的类型为uint8_t");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.GetMemory(' + value_address + ', ' + value_data + ', ' + value_length + ');\n';
    return code;
};

//DS1307时钟模块 读取字节数组，返回读取结果
Blockly.Arduino.forBlock['make_rtc_ds1307_GetMemory_list_return'] = function () {
    this.setTooltip("DS1307时钟模块 读取字节数组，返回数据的类型为uint8_t");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.GetMemory(' + value_address + ', ' + value_data + ', ' + value_length + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS1307时钟模块 SQW管脚输出方波
Blockly.Arduino.forBlock['make_rtc_ds1307_SetSquareWavePin'] = function () {
    this.setTooltip("DS1307时钟模块 SQW管脚输出方波");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.SetSquareWavePin(' + dropdown_type + ');\n';
    return code;
};

/*
* DS3231
*/
//DS3231时钟模块 返回上次连接的错误码
Blockly.Arduino.forBlock['make_rtc_ds3231_LastError'] = function () {
    this.setTooltip("DS3231时钟模块 返回上次连接的错误码，返回数据的类型为uint8_t");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.LastError()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3231时钟模块 打开或关闭32KHZ管脚
Blockly.Arduino.forBlock['make_rtc_ds3231_Enable32kHzPin'] = function () {
    this.setTooltip("DS3231时钟模块 打开或关闭32KHZ管脚");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.Enable32kHzPin(' + value_data + ');\n';
    return code;
};

//开-关
Blockly.Arduino.forBlock['make_pin_on_off'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3231时钟模块 设置SQW管脚的输出模式
Blockly.Arduino.forBlock['make_rtc_ds3231_SetSquareWavePin'] = function () {
    this.setTooltip("DS3231时钟模块 设置SQW管脚的输出模式");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.SetSquareWavePin(' + dropdown_type + ', ' + value_data + ');\n';
    return code;
};

//DS3231时钟模块 设置SQW管脚的输出方波的频率
Blockly.Arduino.forBlock['make_rtc_ds3231_SetSquareWavePinClockFrequency'] = function () {
    this.setTooltip("DS3231时钟模块 设置SQW管脚输出方波的频率");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.SetSquareWavePinClockFrequency(' + dropdown_type + ');\n';
    return code;
};

//DS3231时钟模块 设置闹钟1和闹钟2
Blockly.Arduino.forBlock['make_rtc_ds3231_SetAlarm'] = function () {
    this.setTooltip("DS3231时钟模块 设置闹钟1和闹钟2");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.' + dropdown_type + '(' + value_data + ');\n';
    return code;
};

//DS3231时钟模块 获取闹钟1的日、时、分、秒、工作模式
Blockly.Arduino.forBlock['make_DS3231_getAlarm1data'] = function () {
    this.setTooltip("DS3231时钟模块 获取闹钟1的日、时、分、秒、工作模式，返回数据类型为uint8_t(日、时、分、秒)，DS3231AlarmOneControl(工作模式)");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.GetAlarmOne().' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3231时钟模块 获取闹钟1的日、时、分、工作模式
Blockly.Arduino.forBlock['make_DS3231_getAlarm2data'] = function () {
    this.setTooltip("DS3231时钟模块 获取闹钟2的日、时、分、工作模式，返回数据类型为uint8_t(日、时、分)，DS3231AlarmOneControl(工作模式)");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.GetAlarmTwo().' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3231时钟模块 获取闹钟1、闹钟2的时间和工作模式
Blockly.Arduino.forBlock['make_DS3231_getAlarm'] = function () {
    this.setTooltip("DS3231时钟模块 获取闹钟1、闹钟2的时间和工作模式，返回数据的类型为DS3231AlarmOne(闹钟1)，DS3231AlarmTwo(闹钟2)");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3231时钟模块 允许其他闹钟再次告警
Blockly.Arduino.forBlock['make_rtc_ds3231_LatchAlarmsTriggeredFlags'] = function () {
    this.setTooltip("DS3231时钟模块 允许闹钟告警");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.LatchAlarmsTriggeredFlags();\n';
    return code;
};

//DS3231时钟模块 返回上次告警信息，允许其他闹钟再次告警
Blockly.Arduino.forBlock['make_rtc_ds3231_LatchAlarmsTriggeredFlags_return'] = function () {
    this.setTooltip("DS3231时钟模块 允许闹钟告警，返回数据的类型为DS3231AlarmFlag");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.LatchAlarmsTriggeredFlags()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3231时钟模块 获取温度
Blockly.Arduino.forBlock['make_DS3231_getFloatDeg'] = function () {
    this.setTooltip("DS3231时钟模块 获取温度，返回数据的类型为float");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.GetTemperature().' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
* DS3231闹钟1
*/
//DS3231闹钟1 声明
Blockly.Arduino.forBlock['make_DS3231AlarmOne_declare'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_alarm_name = this.getFieldValue('alarm_name');
    var code = 'DS3231AlarmOne ' + text_alarm_name + ' = ' + value_data + ';\n';
    return code;
};

//DS3231闹钟1 赋值
Blockly.Arduino.forBlock['make_DS3231AlarmOne_set'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_alarm_name = this.getFieldValue('alarm_name');
    var code = text_alarm_name + ' = ' + value_data + ';\n';
    return code;
};

//DS3231闹钟1 取值
Blockly.Arduino.forBlock['make_DS3231AlarmOne_get'] = function () {
    var text_alarm_name = this.getFieldValue('alarm_name');
    var code = text_alarm_name;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3231闹钟1 设置时间和工作模式
Blockly.Arduino.forBlock['make_DS3231AlarmOne_set_time'] = function () {
    var value_day = Blockly.Arduino.valueToCode(this, 'day', Blockly.Arduino.ORDER_ATOMIC);
    var value_hour = Blockly.Arduino.valueToCode(this, 'hour', Blockly.Arduino.ORDER_ATOMIC);
    var value_minute = Blockly.Arduino.valueToCode(this, 'minute', Blockly.Arduino.ORDER_ATOMIC);
    var value_second = Blockly.Arduino.valueToCode(this, 'second', Blockly.Arduino.ORDER_ATOMIC);
    var value_flag = Blockly.Arduino.valueToCode(this, 'flag', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'DS3231AlarmOne(' + value_day + ', ' + value_hour + ', ' + value_minute + ', ' + value_second + ', ' + value_flag + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3231闹钟1 工作模式的类型
Blockly.Arduino.forBlock['make_DS3231AlarmOne_flag_type'] = function () {
    var dropdown_flag_type = this.getFieldValue('flag_type');
    var code = dropdown_flag_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3231闹钟1 获取日、时、分、秒、工作模式
Blockly.Arduino.forBlock['make_DS3231AlarmOne_getAlarmdata'] = function () {
    var text_alarm_name = this.getFieldValue('alarm_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_alarm_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
* DS3231闹钟2
*/
//DS3231闹钟2 声明
Blockly.Arduino.forBlock['make_DS3231AlarmTwo_declare'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_alarm_name = this.getFieldValue('alarm_name');
    var code = 'DS3231AlarmTwo ' + text_alarm_name + ' = ' + value_data + ';\n';
    return code;
};

//DS3231闹钟2 赋值
Blockly.Arduino.forBlock['make_DS3231AlarmTwo_set'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_alarm_name = this.getFieldValue('alarm_name');
    var code = text_alarm_name + ' = ' + value_data + ';';
    return code;
};

//DS3231闹钟2 取值
Blockly.Arduino.forBlock['make_DS3231AlarmTwo_get'] = function () {
    var text_alarm_name = this.getFieldValue('alarm_name');
    var code = text_alarm_name;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3231闹钟2 设置时间和工作模式
Blockly.Arduino.forBlock['make_DS3231AlarmTwo_set_time'] = function () {
    var value_day = Blockly.Arduino.valueToCode(this, 'day', Blockly.Arduino.ORDER_ATOMIC);
    var value_hour = Blockly.Arduino.valueToCode(this, 'hour', Blockly.Arduino.ORDER_ATOMIC);
    var value_minute = Blockly.Arduino.valueToCode(this, 'minute', Blockly.Arduino.ORDER_ATOMIC);
    var value_flag = Blockly.Arduino.valueToCode(this, 'flag', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'DS3231AlarmTwo(' + value_day + ', ' + value_hour + ', ' + value_minute + ', ' + value_flag + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3231闹钟2 工作模式的类型
Blockly.Arduino.forBlock['make_DS3231AlarmTwo_flag_type'] = function () {
    var dropdown_flag_type = this.getFieldValue('flag_type');
    var code = dropdown_flag_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3231闹钟2 获取日、时、分、工作模式
Blockly.Arduino.forBlock['make_DS3231AlarmTwo_getAlarmdata'] = function () {
    var text_alarm_name = this.getFieldValue('alarm_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_alarm_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
* DS3234
*/
//初始化DS3234时钟模块(SPI)
Blockly.Arduino.forBlock['make_rtc_ds3234_begin'] = function () {
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_cs = Blockly.Arduino.valueToCode(this, 'cs', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['include_RtcDS3234'] = '#include <RtcDS3234.h>';
    Blockly.Arduino.definitions_['var_declare_rtc_' + text_rtc_name] = 'RtcDS3234<SPIClass> ' + text_rtc_name + '(SPI, ' + value_cs + ');';

    Blockly.Arduino.setups_['setup_rtc_' + text_rtc_name] = text_rtc_name + '.Begin();';
    var code = '';
    return code;
};

/*
* DS3234_test
*/
//DS3234时钟模块 打开或关闭32KHZ管脚
Blockly.Arduino.forBlock['make_rtc_ds3234_Enable32kHzPin'] = function () {
    this.setTooltip("DS3234时钟模块 打开或关闭32KHZ管脚");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.Enable32kHzPin(' + value_data + ');\n';
    return code;
};

//DS3234时钟模块 设置SQW管脚的输出模式
Blockly.Arduino.forBlock['make_rtc_ds3234_SetSquareWavePin'] = function () {
    this.setTooltip("DS3234时钟模块 设置SQW管脚的输出模式");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.SetSquareWavePin(' + dropdown_type + ');\n';
    return code;
};

//DS3234时钟模块 设置SQW管脚的输出方波的频率
Blockly.Arduino.forBlock['make_rtc_ds3234_SetSquareWavePinClockFrequency'] = function () {
    this.setTooltip("DS3234时钟模块 设置SQW管脚输出方波的频率");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.SetSquareWavePinClockFrequency(' + dropdown_type + ');\n';
    return code;
};

//DS3234时钟模块 设置闹钟1和闹钟2
Blockly.Arduino.forBlock['make_rtc_ds3234_SetAlarm'] = function () {
    this.setTooltip("DS3234时钟模块 设置闹钟1和闹钟2");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.' + dropdown_type + '(' + value_data + ');\n';
    return code;
};

//DS3234时钟模块 获取闹钟1的日、时、分、秒、工作模式
Blockly.Arduino.forBlock['make_DS3234_getAlarm1data'] = function () {
    this.setTooltip("DS3234时钟模块 获取闹钟1的日、时、分、秒、工作模式，返回数据类型为uint8_t(日、时、分、秒)，DS3234AlarmOneControl(工作模式)");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.GetAlarmOne().' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3234时钟模块 获取闹钟2的日、时、分、工作模式
Blockly.Arduino.forBlock['make_DS3234_getAlarm2data'] = function () {
    this.setTooltip("DS3234时钟模块 获取闹钟2的日、时、分、工作模式，返回数据类型为uint8_t(日、时、分)，DS3234AlarmOneControl(工作模式)");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.GetAlarmTwo().' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3234时钟模块 获取闹钟1、闹钟2的时间和工作模式
Blockly.Arduino.forBlock['make_DS3234_getAlarm'] = function () {
    this.setTooltip("DS3234时钟模块 获取闹钟1、闹钟2的时间和工作模式，返回数据的类型为DS3234AlarmOne(闹钟1)，DS3234AlarmTwo(闹钟2)");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3234时钟模块 允许其他闹钟再次告警
Blockly.Arduino.forBlock['make_rtc_ds3234_LatchAlarmsTriggeredFlags'] = function () {
    this.setTooltip("DS3234时钟模块 允许闹钟告警");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.LatchAlarmsTriggeredFlags();\n';
    return code;
};

//DS3234时钟模块 返回上次告警信息，允许其他闹钟再次告警
Blockly.Arduino.forBlock['make_rtc_ds3234_LatchAlarmsTriggeredFlags_return'] = function () {
    this.setTooltip("DS3234时钟模块 允许闹钟告警，返回数据的类型为DS3234AlarmFlag");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.LatchAlarmsTriggeredFlags()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3234时钟模块 获取温度
Blockly.Arduino.forBlock['make_DS3234_getFloatDeg'] = function () {
    this.setTooltip("DS3234时钟模块 获取温度，返回数据的类型为float");
    var text_rtc_name = this.getFieldValue('rtc_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_rtc_name + '.GetTemperature().' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
* DS3234闹钟1
*/
//DS3234闹钟1 声明
Blockly.Arduino.forBlock['make_DS3234AlarmOne_declare'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_alarm_name = this.getFieldValue('alarm_name');
    var code = 'DS3234AlarmOne ' + text_alarm_name + ' = ' + value_data + ';\n';
    return code;
};

//DS3234闹钟1 赋值
Blockly.Arduino.forBlock['make_DS3234AlarmOne_set'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_alarm_name = this.getFieldValue('alarm_name');
    var code = text_alarm_name + ' = ' + value_data + ';\n';
    return code;
};

//DS3234闹钟1 取值
Blockly.Arduino.forBlock['make_DS3234AlarmOne_get'] = function () {
    var text_alarm_name = this.getFieldValue('alarm_name');
    var code = text_alarm_name;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3234闹钟1 设置时间和工作模式
Blockly.Arduino.forBlock['make_DS3234AlarmOne_set_time'] = function () {
    var value_day = Blockly.Arduino.valueToCode(this, 'day', Blockly.Arduino.ORDER_ATOMIC);
    var value_hour = Blockly.Arduino.valueToCode(this, 'hour', Blockly.Arduino.ORDER_ATOMIC);
    var value_minute = Blockly.Arduino.valueToCode(this, 'minute', Blockly.Arduino.ORDER_ATOMIC);
    var value_second = Blockly.Arduino.valueToCode(this, 'second', Blockly.Arduino.ORDER_ATOMIC);
    var value_flag = Blockly.Arduino.valueToCode(this, 'flag', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'DS3234AlarmOne(' + value_day + ', ' + value_hour + ', ' + value_minute + ', ' + value_second + ', ' + value_flag + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3234闹钟1 工作模式的类型
Blockly.Arduino.forBlock['make_DS3234AlarmOne_flag_type'] = function () {
    var dropdown_flag_type = this.getFieldValue('flag_type');
    var code = dropdown_flag_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3234闹钟1 获取日、时、分、秒、工作模式
Blockly.Arduino.forBlock['make_DS3234AlarmOne_getAlarmdata'] = function () {
    var text_alarm_name = this.getFieldValue('alarm_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_alarm_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
* DS3234闹钟2
*/
//DS3234闹钟2 声明
Blockly.Arduino.forBlock['make_DS3234AlarmTwo_declare'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_alarm_name = this.getFieldValue('alarm_name');
    var code = 'DS3234AlarmTwo ' + text_alarm_name + ' = ' + value_data + ';\n';
    return code;
};

//DS3234闹钟2 赋值
Blockly.Arduino.forBlock['make_DS3234AlarmTwo_set'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_alarm_name = this.getFieldValue('alarm_name');
    var code = text_alarm_name + ' = ' + value_data + ';';
    return code;
};

//DS3234闹钟2 取值
Blockly.Arduino.forBlock['make_DS3234AlarmTwo_get'] = function () {
    var text_alarm_name = this.getFieldValue('alarm_name');
    var code = text_alarm_name;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3234闹钟2 设置时间和工作模式
Blockly.Arduino.forBlock['make_DS3234AlarmTwo_set_time'] = function () {
    var value_day = Blockly.Arduino.valueToCode(this, 'day', Blockly.Arduino.ORDER_ATOMIC);
    var value_hour = Blockly.Arduino.valueToCode(this, 'hour', Blockly.Arduino.ORDER_ATOMIC);
    var value_minute = Blockly.Arduino.valueToCode(this, 'minute', Blockly.Arduino.ORDER_ATOMIC);
    var value_flag = Blockly.Arduino.valueToCode(this, 'flag', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'DS3234AlarmTwo(' + value_day + ', ' + value_hour + ', ' + value_minute + ', ' + value_flag + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3234闹钟2 工作模式的类型
Blockly.Arduino.forBlock['make_DS3234AlarmTwo_flag_type'] = function () {
    var dropdown_flag_type = this.getFieldValue('flag_type');
    var code = dropdown_flag_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3234闹钟2 获取日、时、分、工作模式
Blockly.Arduino.forBlock['make_DS3234AlarmTwo_getAlarmdata'] = function () {
    var text_alarm_name = this.getFieldValue('alarm_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_alarm_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
* DS3234RAM
*/
//DS3234时钟模块 写入字节
Blockly.Arduino.forBlock['make_rtc_ds3234_SetMemory_byte'] = function () {
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.SetMemory(' + value_address + ', ' + value_data + ');\n';
    return code;
};

//DS3234时钟模块 读取字节
Blockly.Arduino.forBlock['make_rtc_ds3234_GetMemory_byte'] = function () {
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var code = text_rtc_name + '.GetMemory(' + value_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DS3234时钟模块 写入字节数组
Blockly.Arduino.forBlock['make_rtc_ds3234_SetMemory_list'] = function () {
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.SetMemory(' + value_address + ', (const uint8_t*)' + value_data + ', ' + value_length + ');\n';
    return code;
};

//DS3234时钟模块 读取字节数组
Blockly.Arduino.forBlock['make_rtc_ds3234_GetMemory_list'] = function () {
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.GetMemory(' + value_address + ', ' + value_data + ', ' + value_length + ');\n';
    return code;
};

//DS3234时钟模块 读取字节数组，返回读取结果
Blockly.Arduino.forBlock['make_rtc_ds3234_GetMemory_list_return'] = function () {
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_rtc_name = this.getFieldValue('rtc_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_rtc_name + '.GetMemory(' + value_address + ', ' + value_data + ', ' + value_length + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化PCF8574 IO扩展模块
Blockly.Arduino.forBlock['make_arduino_pcf8574_begin'] = function () {
    var text_pcf8574_name = this.getFieldValue('pcf8574_name');
    var value_pcf8574_address = Blockly.Arduino.valueToCode(this, 'pcf8574_address', Blockly.Arduino.ORDER_ATOMIC);
    var statements_pcf8574_pin_type = Blockly.Arduino.statementToCode(this, 'pcf8574_pin_type');

    var statements_pcf8574_pin_type_1 = '';
    if (statements_pcf8574_pin_type != '') {
        for (var i of statements_pcf8574_pin_type) {
            if (i == '.')
                statements_pcf8574_pin_type_1 = statements_pcf8574_pin_type_1 + text_pcf8574_name + '.';
            else
                statements_pcf8574_pin_type_1 += i;
        }
        statements_pcf8574_pin_type_1 = statements_pcf8574_pin_type_1.substring(0, statements_pcf8574_pin_type_1.length - 1);
    }

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_PCF8574'] = '#include "PCF8574.h"';
    Blockly.Arduino.definitions_['var_declare_' + text_pcf8574_name] = 'PCF8574 ' + text_pcf8574_name + ';';
    if (statements_pcf8574_pin_type != '')
        Blockly.Arduino.setups_['setup_pcf8574_' + text_pcf8574_name] = '' + text_pcf8574_name + '.begin(' + value_pcf8574_address + ');'
            + '\n' + statements_pcf8574_pin_type_1;
    else
        Blockly.Arduino.setups_['setup_pcf8574_' + text_pcf8574_name] = '' + text_pcf8574_name + '.begin(' + value_pcf8574_address + ');';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_pcf8574_begin_soft'] = function () {
    // 获取PCF8574对象的名称
    var text_pcf8574_name = this.getFieldValue('pcf8574_name');
    // 获取SDA引脚值
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    // 获取SCL引脚值
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    // 获取PCF8574设备地址
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    // 获取设置引脚模式的语句
    var statements_pcf8574_pin_type = Blockly.Arduino.statementToCode(this, 'pin');

    // 处理引脚模式语句，确保每个语句都以正确的前缀开头
    var statements_pcf8574_pin_type_1 = '';
    if (statements_pcf8574_pin_type != '') {
        for (var i of statements_pcf8574_pin_type) {
            if (i == '.')
                statements_pcf8574_pin_type_1 = statements_pcf8574_pin_type_1 + text_pcf8574_name + '.';
            else
                statements_pcf8574_pin_type_1 += i;
        }
        statements_pcf8574_pin_type_1 = statements_pcf8574_pin_type_1.substring(0, statements_pcf8574_pin_type_1.length - 1);
    }

    // 包含必要的库文件
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>'; // 引入Wire库
    Blockly.Arduino.definitions_['include_PCF8574'] = '#include "PCF8574.h"'; // 引入PCF8574库

    // 声明PCF8574对象，并传入Wire指针
    Blockly.Arduino.definitions_['var_declare_' + text_pcf8574_name] = 
        'PCF8574 ' + text_pcf8574_name + '(&Wire);'; // 使用Wire对象初始化PCF8574

    // 在setup函数中初始化Wire
    Blockly.Arduino.setups_['setup_wire'] = 
        '';  // Wire不需要显式初始化，只需包含库即可

    // 开始初始化PCF8574传感器，在setup函数中执行
    if (statements_pcf8574_pin_type != '')
        Blockly.Arduino.setups_['setup_pcf8574_' + text_pcf8574_name] = '' + text_pcf8574_name + '.begin(' + value_address + ');'
            + '\n' + statements_pcf8574_pin_type_1;
    else
        Blockly.Arduino.setups_['setup_pcf8574_' + text_pcf8574_name] = '' + text_pcf8574_name + '.begin(' + value_address + ');';

    // 返回生成的代码（这里为空）
    var code = '';
    return code;
};




Blockly.Arduino.forBlock['make_arduino_pcf8574_pin_type'] = function () {
    // 获取PCF8574管脚编号
    var value_pcf8574_pin = Blockly.Arduino.valueToCode(this, 'pcf8574_pin', Blockly.Arduino.ORDER_ATOMIC);
    // 获取PCF8574管脚类型（INPUT 或 OUTPUT）
    var dropdown_pcf8574_pin_type = this.getFieldValue('pcf8574_pin_type');
    var code = '';
    // 检查父块是否为硬件I2C初始化块
    var surround_parent = this.getSurroundParent();
    if (surround_parent && surround_parent.type == 'make_arduino_pcf8574_begin')
        code = '.pinMode(' + value_pcf8574_pin + ', ' + dropdown_pcf8574_pin_type + ');\n';
    // 检查父块是否为软件I2C初始化块
    if (surround_parent && surround_parent.type == 'make_arduino_pcf8574_begin_soft')
        code = '.pinMode(' + value_pcf8574_pin + ', ' + dropdown_pcf8574_pin_type + ');\n';
    return code;
};



Blockly.Arduino.forBlock['make_arduino_pcf8574_digital_pin'] = function () {
    // 获取数字输出管脚编号
    var dropdown_pin_data = this.getFieldValue('pin_data');
    var code = dropdown_pin_data;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};



Blockly.Arduino.forBlock['make_arduino_pcf8574_digital_out_type'] = function () {
    // 获取数字输出管脚状态（HIGH 或 LOW）
    var dropdown_output_data = this.getFieldValue('output_data');
    var code = dropdown_output_data;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};



Blockly.Arduino.forBlock['make_arduino_pcf8574_digitalWrite'] = function () {
    // 获取PCF8574对象名称
    var text_pcf8574_name = this.getFieldValue('pcf8574_name');
    // 获取数字输出管脚编号
    var value_pcf8574_pin = Blockly.Arduino.valueToCode(this, 'pcf8574_pin', Blockly.Arduino.ORDER_ATOMIC);
    // 获取数字输出管脚状态
    var value_pcf8574_out_data = Blockly.Arduino.valueToCode(this, 'pcf8574_out_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_pcf8574_name + '.digitalWrite(' + value_pcf8574_pin + ', ' + value_pcf8574_out_data + ');\n';
    return code;
};



Blockly.Arduino.forBlock['make_arduino_pcf8574_digitalRead'] = function () {
    // 获取PCF8574对象名称
    var text_pcf8574_name = this.getFieldValue('pcf8574_name');
    // 获取数字输入管脚编号
    var value_pcf8574_pin = Blockly.Arduino.valueToCode(this, 'pcf8574_pin', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_pcf8574_name + '.digitalRead(' + value_pcf8574_pin + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};



Blockly.Arduino.forBlock['make_arduino_pcf8574_toggle'] = function () {
    // 获取PCF8574对象名称
    var text_pcf8574_name = this.getFieldValue('pcf8574_name');
    // 获取翻转管脚编号
    var value_pcf8574_pin = Blockly.Arduino.valueToCode(this, 'pcf8574_pin', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_pcf8574_name + '.toggle(' + value_pcf8574_pin + ');\n';
    return code;
};



Blockly.Arduino.forBlock['make_arduino_pcf8574_write'] = function () {
    // 获取PCF8574对象名称
    var text_pcf8574_name = this.getFieldValue('pcf8574_name');
    // 获取要设置的电平值
    var value_pcf8574_pin = Blockly.Arduino.valueToCode(this, 'pcf8574_pin', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_pcf8574_name + '.write(' + value_pcf8574_pin + ');\n';
    return code;
};





//初始化MCP23017 IO扩展模块
Blockly.Arduino.forBlock['make_arduino_mcp23017_begin'] = function () {
    var text_mcp23017_name = this.getFieldValue('mcp23017_name');
    var value_mcp23017_address = Blockly.Arduino.valueToCode(this, 'mcp23017_address', Blockly.Arduino.ORDER_ATOMIC);
    var statements_mcp23017_pin_type = Blockly.Arduino.statementToCode(this, 'mcp23017_pin_type');
    var statements_mcp23017_pin_type_1 = '';
    if (statements_mcp23017_pin_type != '') {
        for (var i of statements_mcp23017_pin_type) {
            if (i == '.')
                statements_mcp23017_pin_type_1 = statements_mcp23017_pin_type_1 + text_mcp23017_name + '.';
            else
                statements_mcp23017_pin_type_1 += i;
        }
        statements_mcp23017_pin_type_1 = statements_mcp23017_pin_type_1.substring(0, statements_mcp23017_pin_type_1.length - 1);
    }

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_MCP23017'] = '#include "Adafruit_MCP23017.h"';
    Blockly.Arduino.definitions_['var_declare_' + text_mcp23017_name] = 'Adafruit_MCP23017 ' + text_mcp23017_name + ';';
    if (statements_mcp23017_pin_type != '')
        Blockly.Arduino.setups_['setup_mcp23017_' + text_mcp23017_name] = '' + text_mcp23017_name + '.begin(' + value_mcp23017_address + ');'
            + '\n' + statements_mcp23017_pin_type_1;
    else
        Blockly.Arduino.setups_['setup_mcp23017_' + text_mcp23017_name] = '' + text_mcp23017_name + '.begin(' + value_mcp23017_address + ');';
    var code = '';
    return code;
};

//初始化MCP23017 使用软件模拟I2C
Blockly.Arduino.forBlock['make_arduino_mcp23017_begin_soft'] = function () {
    var text_mcp23017_name = this.getFieldValue('mcp23017_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
    var value_mcp23017_address = Blockly.Arduino.valueToCode(this, 'mcp23017_address', Blockly.Arduino.ORDER_ATOMIC);
    var statements_mcp23017_pin_type = Blockly.Arduino.statementToCode(this, 'mcp23017_pin_type');
    var statements_mcp23017_pin_type_1 = '';
    if (statements_mcp23017_pin_type != '') {
        for (var i of statements_mcp23017_pin_type) {
            if (i == '.')
                statements_mcp23017_pin_type_1 = statements_mcp23017_pin_type_1 + text_mcp23017_name + '.';
            else
                statements_mcp23017_pin_type_1 += i;
        }
        statements_mcp23017_pin_type_1 = statements_mcp23017_pin_type_1.substring(0, statements_mcp23017_pin_type_1.length - 1);
    }

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_MCP23017'] = '#include "Adafruit_MCP23017.h"';
    Blockly.Arduino.definitions_['var_declare_' + text_mcp23017_name] = 'Adafruit_MCP23017 ' + text_mcp23017_name + ';';
    if (statements_mcp23017_pin_type != '')
        Blockly.Arduino.setups_['setup_mcp23017_' + text_mcp23017_name] = '' + text_mcp23017_name + '.begin(' + value_mcp23017_address + ');'
            + '\n' + statements_mcp23017_pin_type_1;
    else
        Blockly.Arduino.setups_['setup_mcp23017_' + text_mcp23017_name] = '' + text_mcp23017_name + '.begin(' + value_mcp23017_address + ');';

    // 初始化Wire对象，指定SDA和SCL引脚
    Blockly.Arduino.setups_['setup_wire'] = 
        'Wire.begin(' + value_sda.replace(/"/g, '') + ', ' + value_scl.replace(/"/g, '') + ');';  

    var code = '';
    return code;
};




//MCP23017 IO扩展模块 设置管脚模式
Blockly.Arduino.forBlock['make_arduino_mcp23017_pin_type'] = function () {
    var value_mcp23017_pin = Blockly.Arduino.valueToCode(this, 'mcp23017_pin', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_mcp23017_pin_type = this.getFieldValue('mcp23017_pin_type');
    var code = '';
    var surround_parent = this.getSurroundParent();
    if (surround_parent && (surround_parent.type == 'make_arduino_mcp23017_begin' || surround_parent.type == 'make_arduino_mcp23017_begin_soft'))
        if (dropdown_mcp23017_pin_type == 'INPUT_PULLUP')
            code = '.pinMode(' + value_mcp23017_pin + ', INPUT);\n.pullUp(' + value_mcp23017_pin + ', HIGH);\n';
        else
            code = '.pinMode(' + value_mcp23017_pin + ', ' + dropdown_mcp23017_pin_type + ');\n';
    return code;
};

//MCP23017 IO扩展模块 数字管脚定义
Blockly.Arduino.forBlock['make_arduino_mcp23017_digital_pin'] = function () {
    var dropdown_pin_data = this.getFieldValue('pin_data');
    var code = dropdown_pin_data;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//MCP23017 IO扩展模块 输出状态定义
Blockly.Arduino.forBlock['make_arduino_mcp23017_digital_out_type'] = function () {
    var dropdown_output_data = this.getFieldValue('output_data');
    var code = dropdown_output_data;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//MCP23017 IO扩展模块 管脚输出状态定义
Blockly.Arduino.forBlock['make_arduino_mcp23017_digitalWrite'] = function () {
    var text_mcp23017_name = this.getFieldValue('mcp23017_name');
    var value_mcp23017_pin = Blockly.Arduino.valueToCode(this, 'mcp23017_pin', Blockly.Arduino.ORDER_ATOMIC);
    var value_mcp23017_out_data = Blockly.Arduino.valueToCode(this, 'mcp23017_out_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_mcp23017_name + '.digitalWrite(' + value_mcp23017_pin + ', ' + value_mcp23017_out_data + ');\n';
    return code;
};

//MCP23017 IO扩展模块 管脚输入定义
Blockly.Arduino.forBlock['make_arduino_mcp23017_digitalRead'] = function () {
    var text_mcp23017_name = this.getFieldValue('mcp23017_name');
    var value_mcp23017_pin = Blockly.Arduino.valueToCode(this, 'mcp23017_pin', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_mcp23017_name + '.digitalRead(' + value_mcp23017_pin + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//MCP23017 IO扩展模块 设置各管脚的电平
Blockly.Arduino.forBlock['make_arduino_mcp23017_write'] = function () {
    var text_mcp23017_name = this.getFieldValue('mcp23017_name');
    var value_mcp23017_pinA = Blockly.Arduino.valueToCode(this, 'mcp23017_pinA', Blockly.Arduino.ORDER_ATOMIC);
    var value_mcp23017_pinB = Blockly.Arduino.valueToCode(this, 'mcp23017_pinB', Blockly.Arduino.ORDER_ATOMIC);

    var code = '';
    if (value_mcp23017_pinA == '' || value_mcp23017_pinB == '')
        code = '' + text_mcp23017_name + '.writeGPIOAB(0xffff);\n';
    else {
        value_mcp23017_pinA = value_mcp23017_pinA.substring(1);
        value_mcp23017_pinB = value_mcp23017_pinB.substring(1);
        value_mcp23017_pinA = parseInt(value_mcp23017_pinA, 2).toString(16);
        value_mcp23017_pinB = parseInt(value_mcp23017_pinB, 2).toString(16);
        if (value_mcp23017_pinA.length == 1)
            value_mcp23017_pinA = '0' + value_mcp23017_pinA;
        if (value_mcp23017_pinB.length == 1)
            value_mcp23017_pinB = '0' + value_mcp23017_pinB;
        code = '' + text_mcp23017_name + '.writeGPIOAB(0x' + value_mcp23017_pinB + value_mcp23017_pinA + ');\n';
    }
    return code;
};

//MCP23017 IO扩展模块 启用中断
Blockly.Arduino.forBlock['make_arduino_mcp23017_setupInterrupts'] = function () {
    var text_mcp23017_name = this.getFieldValue('mcp23017_name');
    var value_mcp23017_mirroring = Blockly.Arduino.valueToCode(this, 'mcp23017_mirroring', Blockly.Arduino.ORDER_ATOMIC);
    var value_mcp23017_openDrain = Blockly.Arduino.valueToCode(this, 'mcp23017_openDrain', Blockly.Arduino.ORDER_ATOMIC);
    var code = '';
    if (value_mcp23017_openDrain == 'open')
        code = '' + text_mcp23017_name + '.setupInterrupts(' + value_mcp23017_mirroring + ', true);\n';
    else
        code = '' + text_mcp23017_name + '.setupInterrupts(' + value_mcp23017_mirroring + ', false, ' + value_mcp23017_openDrain + ');\n';
    return code;
};

//MCP23017 IO扩展模块 设置中断模式
Blockly.Arduino.forBlock['make_arduino_mcp23017_setupInterrupts_mode'] = function () {
    var dropdown_mode = this.getFieldValue('mode');
    var code = dropdown_mode;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//MCP23017 IO扩展模块 设置中断管脚
Blockly.Arduino.forBlock['make_arduino_mcp23017_attachInterrupt'] = function () {
    var text_mcp23017_name = this.getFieldValue('mcp23017_name');
    var value_mcp23017_int_pin = Blockly.Arduino.valueToCode(this, 'mcp23017_int_pin', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_mcp23017_int_type = this.getFieldValue('mcp23017_int_type');
    var code = '' + text_mcp23017_name + '.setupInterruptPin(' + value_mcp23017_int_pin + ',' + dropdown_mcp23017_int_type + ');\n';
    return code;
};

//MCP23017 IO扩展模块 获取最近一次的中断管脚和其数据
Blockly.Arduino.forBlock['make_arduino_mcp23017_getLastInterrupt'] = function () {
    var text_mcp23017_name = this.getFieldValue('mcp23017_name');
    var dropdown_data = this.getFieldValue('data');
    var code = text_mcp23017_name + '.getLastInterrupt' + dropdown_data + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化PCF8591 AD转换模块
Blockly.Arduino.forBlock['make_arduino_pcf8591_begin'] = function () {
    this.setTooltip("初始化PCF8591 AD转换模块");
    var text_pcf8591_name = this.getFieldValue('pcf8591_name');
    var value_pcf8591_address = Blockly.Arduino.valueToCode(this, 'pcf8591_address', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['include_' + 'Arduino'] = '#include "Arduino.h"';
    Blockly.Arduino.definitions_['include_' + 'PCF8591'] = '#include "PCF8591.h"';
    Blockly.Arduino.definitions_['var_declare_' + text_pcf8591_name] = 'PCF8591 ' + text_pcf8591_name + '(' + value_pcf8591_address + ');';
    Blockly.Arduino.setups_['pcf8591_begin'] = text_pcf8591_name + '.begin();';
    var code = '';
    return code;
};

//初始化PCF8591 AD转换模块 可设置SDA & SCL
Blockly.Arduino.forBlock['make_arduino_pcf8591_begin_sda_scl'] = function () {
    this.setTooltip("初始化PCF8591 AD转换模块");
    var text_pcf8591_name = this.getFieldValue('pcf8591_name');
    var value_pcf8591_sda = Blockly.Arduino.valueToCode(this, 'pcf8591_sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_pcf8591_scl = Blockly.Arduino.valueToCode(this, 'pcf8591_scl', Blockly.Arduino.ORDER_ATOMIC);
    var value_pcf8591_address = Blockly.Arduino.valueToCode(this, 'pcf8591_address', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['include_' + 'Arduino'] = '#include "Arduino.h"';
    Blockly.Arduino.definitions_['include_' + 'PCF8591'] = '#include "PCF8591.h"';
    Blockly.Arduino.definitions_['var_declare_' + text_pcf8591_name] = 'PCF8591 ' + text_pcf8591_name + '(' + value_pcf8591_address + ', ' + value_pcf8591_sda + ', ' + value_pcf8591_scl + ');';
    Blockly.Arduino.setups_['pcf8591_begin'] = text_pcf8591_name + '.begin();';
    var code = '';
    return code;
};

//PCF8591 获取模拟输入管脚的值
Blockly.Arduino.forBlock['make_arduino_pcf8591_analogRead'] = function () {
    this.setTooltip("PCF8591 AD转换模块 获取模拟输入管脚的值");
    var text_pcf8591_name = this.getFieldValue('pcf8591_name');
    var value_pin = Blockly.Arduino.valueToCode(this, 'pin', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_pcf8591_name + '.analogRead(' + value_pin + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//PCF8591 输入管脚定义
Blockly.Arduino.forBlock['make_arduino_pcf8591_read_pin'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//PCF8591 设置模拟输出管脚的值
Blockly.Arduino.forBlock['make_arduino_pcf8591_analogWrite'] = function () {
    this.setTooltip("PCF8591 AD转换模块 设置模拟输出管脚的值");
    var text_pcf8591_name = this.getFieldValue('pcf8591_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_pcf8591_name + '.analogWrite(' + value_data + ');\n';
    return code;
};

//PCF8591 获取输入管脚的电压值
Blockly.Arduino.forBlock['make_arduino_pcf8591_voltageRead'] = function () {
    this.setTooltip("PCF8591 AD转换模块 获取输入管脚的电压值");
    var text_pcf8591_name = this.getFieldValue('pcf8591_name');
    var value_pin = Blockly.Arduino.valueToCode(this, 'pin', Blockly.Arduino.ORDER_ATOMIC);
    var value_microcontrollerReferenceVoltage = Blockly.Arduino.valueToCode(this, 'microcontrollerReferenceVoltage', Blockly.Arduino.ORDER_ATOMIC);
    var value_referenceVoltage = Blockly.Arduino.valueToCode(this, 'referenceVoltage', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_pcf8591_name + '.voltageRead(' + value_pin + ', ' + value_microcontrollerReferenceVoltage + ', ' + value_referenceVoltage + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//PCF8591 设置输出管脚的电压值
Blockly.Arduino.forBlock['make_arduino_pcf8591_voltageWrite'] = function () {
    this.setTooltip("PCF8591 AD转换模块 设置输出管脚的电压值");
    var text_pcf8591_name = this.getFieldValue('pcf8591_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_microcontrollerReferenceVoltage = Blockly.Arduino.valueToCode(this, 'microcontrollerReferenceVoltage', Blockly.Arduino.ORDER_ATOMIC);
    var value_referenceVoltage = Blockly.Arduino.valueToCode(this, 'referenceVoltage', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_pcf8591_name + '.voltageWrite(' + value_data + ', ' + value_microcontrollerReferenceVoltage + ', ' + value_referenceVoltage + ');\n';
    return code;
};

//PCF8591 获取输入管脚的电压值-无参考电压
Blockly.Arduino.forBlock['make_arduino_pcf8591_voltageRead_1'] = function () {
    this.setTooltip("PCF8591 AD转换模块 获取输入管脚的电压值");
    var text_pcf8591_name = this.getFieldValue('pcf8591_name');
    var value_pin = Blockly.Arduino.valueToCode(this, 'pin', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_pcf8591_name + '.voltageRead(' + value_pin + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//PCF8591 设置输出管脚的电压值-无参考电压
Blockly.Arduino.forBlock['make_arduino_pcf8591_voltageWrite_1'] = function () {
    this.setTooltip("PCF8591 AD转换模块 设置输出管脚的电压值");
    var text_pcf8591_name = this.getFieldValue('pcf8591_name');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_pcf8591_name + '.voltageWrite(' + value_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['xl9555_info'] = function(block) {
  return '';
};

Blockly.Arduino.forBlock['xl9555_init'] = function(block) {
  var sda = Blockly.Arduino.valueToCode(block, 'SDA', Blockly.Arduino.ORDER_ATOMIC) || '17';
  var scl = Blockly.Arduino.valueToCode(block, 'SCL', Blockly.Arduino.ORDER_ATOMIC) || '18';
  var addr = block.getFieldValue('ADDR') || '0x20';
  
  Blockly.Arduino.definitions_['include_arduino_h'] = '#include <Arduino.h>';
  Blockly.Arduino.definitions_['include_wire'] = '#include <Wire.h>';
  Blockly.Arduino.definitions_['include_xl9555'] = '#include "xl9555.h"';
  
  // 直接生成带引脚的IIC初始化代码，适用于ESP系列平台
  var wireBeginCode = 'Wire.begin(' + sda + ', ' + scl + ');';
  
  // 避免覆盖已存在的I2C初始化配置
  if (!Blockly.Arduino.setups_['setup_i2c']) {
    Blockly.Arduino.setups_['setup_i2c'] = wireBeginCode;
  }
  
  // 直接生成地址配置和初始化代码，不使用条件判断
  Blockly.Arduino.setups_['setup_xl9555'] = 'xl9555_set_addr(' + addr + '); xl9555_init();';
  
  return '';
};

Blockly.Arduino.forBlock['xl9555_init_hardware_i2c'] = function(block) {
  var addr = block.getFieldValue('ADDR') || '0x20';
  var i2c_port = block.getFieldValue('I2C_PORT') || '1';
  
  Blockly.Arduino.definitions_['include_arduino_h'] = '#include <Arduino.h>';
  Blockly.Arduino.definitions_['include_wire'] = '#include <Wire.h>';
  Blockly.Arduino.definitions_['include_xl9555'] = '#include "xl9555.h"';
  
  // 根据选择的I2C端口进行初始化
  var wireBeginCode = '';
  if (i2c_port === '1') {
    wireBeginCode = 'Wire.begin();';
  } else if (i2c_port === '2') {
    wireBeginCode = 'Wire1.begin();';
  }
  
  // 避免覆盖已存在的I2C初始化配置
  if (!Blockly.Arduino.setups_['setup_i2c_' + i2c_port]) {
    Blockly.Arduino.setups_['setup_i2c_' + i2c_port] = wireBeginCode;
  }
  
  // 直接生成地址配置和初始化代码，不使用条件判断
  Blockly.Arduino.setups_['setup_xl9555'] = 'xl9555_set_addr(' + addr + '); xl9555_init();';
  
  return '';
};

Blockly.Arduino.forBlock['xl9555_digital_write'] = function(block) {
  var addr = block.getFieldValue('ADDR') || '0x20';
  var pin = block.getFieldValue('PIN') || '0';
  var value = Blockly.Arduino.valueToCode(block, 'VALUE', Blockly.Arduino.ORDER_ATOMIC) || '1';
  
  var code = 'xl9555_set_addr(' + addr + '); xl9555_pin_set(1 << ' + pin + ', ' + (value === '1' ? 'IO_SET_HIGH' : 'IO_SET_LOW') + ');\n';
  return code;
};

Blockly.Arduino.forBlock['xl9555_digital_read'] = function(block) {
  var addr = block.getFieldValue('ADDR') || '0x20';
  var pin = block.getFieldValue('PIN') || '0';
  
  var code = 'xl9555_set_addr(' + addr + '), xl9555_get_pin(1 << ' + pin + ')';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['xl9555_port_write'] = function(block) {
  var addr = block.getFieldValue('ADDR') || '0x20';
  var value = Blockly.Arduino.valueToCode(block, 'VALUE', Blockly.Arduino.ORDER_ATOMIC) || '1';
  
  var code = 'xl9555_set_addr(' + addr + '); xl9555_write_port(0, ' + value + ');\n';
  return code;
};

Blockly.Arduino.forBlock['xl9555_port_read'] = function(block) {
  var addr = block.getFieldValue('ADDR') || '0x20';
  var port = block.getFieldValue('PORT') || '0';
  
  var code = 'xl9555_set_addr(' + addr + '), xl9555_read_port(' + port + ')';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['xl9555_pin_mode'] = function(block) {
  var addr = block.getFieldValue('ADDR') || '0x20';
  var pin = block.getFieldValue('PIN') || '0';
  var mode = block.getFieldValue('MODE') || 'INPUT';
  
  var code = 'xl9555_set_addr(' + addr + '); xl9555_io_config(1 << ' + pin + ', ' + (mode === 'INPUT' ? 'IO_SET_INPUT' : 'IO_SET_OUTPUT') + ');\n';
  return code;
};

Blockly.Arduino.forBlock['xl9555_interrupt'] = function(block) {
  var addr = block.getFieldValue('ADDR') || '0x20';
  var pin = block.getFieldValue('PIN') || '0';
  var enable = block.getFieldValue('ENABLE') || 'false';
  
  var code = 'xl9555_set_addr(' + addr + '); xl9555_interrupt_enable(1 << ' + pin + ', ' + (enable === 'true' ? 'true' : 'false') + ');\n';
  return code;
};

Blockly.Arduino.forBlock['xl9555_multifunction_key'] = function(block) {
  var addr = block.getFieldValue('ADDR') || '0x20';
  var pin = block.getFieldValue('PIN') || '0';
  var type = block.getFieldValue('TYPE') || 'CLICK';
  var trigger = block.getFieldValue('TRIGGER') || 'LOW';
  var do_statements = Blockly.Arduino.statementToCode(block, 'DO');
  
  var code = '// 多功能按键检测（带去抖）\n';
  code += 'xl9555_set_addr(' + addr + ');\n';
  code += 'static unsigned long lastDebounceTime' + pin + ' = 0;\n';
  code += 'static unsigned long lastClickTime' + pin + ' = 0;\n';
  code += 'static unsigned long debounceDelay = 200;\n';
  code += 'int reading' + pin + ' = xl9555_get_pin(1 << ' + pin + ');\n';
  code += 'if (reading' + pin + ' == ' + trigger + ') {\n';
  code += '  if (millis() - lastDebounceTime' + pin + ' > debounceDelay) {\n';
  code += '    lastDebounceTime' + pin + ' = millis();\n';
  code += '    if ("' + type + '" == "CLICK") {\n';
  code += '      ' + do_statements + '\n';
  code += '    } else if ("' + type + '" == "DOUBLE_CLICK") {\n';
  code += '      if (millis() - lastClickTime' + pin + ' < 500) {\n';
  code += '        ' + do_statements + '\n';
  code += '      }\n';
  code += '      lastClickTime' + pin + ' = millis();\n';
  code += '    }\n';
  code += '  }\n';
  code += '}\n';
  return code;
};
//初始化PAJ7620手势传感器
Blockly.Arduino.forBlock['make_arduino_paj7620_begin'] = function () {
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_paj7620'] = '#include "paj7620.h"';
    Blockly.Arduino.setups_['setup_paj7620'] = 'paj7620Init();';
    var code = '';
    return code;
};

//初始化PAJ7620手势传感器-1
Blockly.Arduino.forBlock['make_arduino_paj7620_begin_1'] = function () {
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_paj7620'] = '#include "paj7620.h"';
    var code = 'paj7620Init()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//PAJ7620手势传感器 获取数据
Blockly.Arduino.forBlock['make_arduino_paj7620_ReadReg'] = function () {
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var value_qty = Blockly.Arduino.valueToCode(this, 'qty', Blockly.Arduino.ORDER_ATOMIC);
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'paj7620ReadReg(' + value_address + ', ' + value_qty + ', &' + value_data + ');\n';
    return code;
};

//PAJ7620手势传感器 获取数据-返回请求结果
Blockly.Arduino.forBlock['make_arduino_paj7620_ReadReg_1'] = function () {
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var value_qty = Blockly.Arduino.valueToCode(this, 'qty', Blockly.Arduino.ORDER_ATOMIC);
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'paj7620ReadReg(' + value_address + ', ' + value_qty + ', &' + value_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//PAJ7620手势传感器 手势数据
Blockly.Arduino.forBlock['make_arduino_paj7620_data'] = function () {
    var dropdown_data = this.getFieldValue('data');
    var code = dropdown_data;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化TCA9548A I2C扩展模块
Blockly.Arduino.forBlock['make_arduino_tca9548a_begin'] = function () {
    var text_tca9548a_name = this.getFieldValue('tca9548a_name');
    var value_tca9548a_address = Blockly.Arduino.valueToCode(this, 'tca9548a_address', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_TCA9548A'] = '#include "TCA9548A.h"';
    Blockly.Arduino.definitions_['var_declare_' + text_tca9548a_name] = 'TCA9548A ' + text_tca9548a_name + '(' + value_tca9548a_address + ');';
    Blockly.Arduino.setups_['setup_tca9548a_' + text_tca9548a_name] = '' + text_tca9548a_name + '.init();';
    var code = '';
    return code;
};

//初始化TCA9548A I2C扩展模块 使用软件模拟I2C
Blockly.Arduino.forBlock['make_arduino_tca9548a_begin_soft'] = function () {
    var text_tca9548a_name = this.getFieldValue('tca9548a_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);

    // 包含必要的库文件
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_TCA9548A'] = '#include "TCA9548A.h"';

    // 初始化Wire对象，指定SDA和SCL引脚
    Blockly.Arduino.setups_['setup_wire'] = 
        'Wire.begin(' + value_sda.replace(/"/g, '') + ', ' + value_scl.replace(/"/g, '') + ');';  

    // 声明并初始化TCA9548A对象
    Blockly.Arduino.definitions_['var_declare_' + text_tca9548a_name] = 'TCA9548A ' + text_tca9548a_name + '(' + value_address.replace(/"/g, '') + ');';

    var code = '';
    return code;
};




//TCA9548A I2C扩展模块 关闭所有端口
Blockly.Arduino.forBlock['make_arduino_tca9548a_disable'] = function () {
    var text_tca9548a_name = this.getFieldValue('tca9548a_name');
    var code = '' + text_tca9548a_name + '.disable();\n';
    return code;
};

//TCA9548A I2C扩展模块 设置当前要使用的端口
Blockly.Arduino.forBlock['make_arduino_tca9548a_set_port'] = function () {
    var text_tca9548a_name = this.getFieldValue('tca9548a_name');
    var value_port_data = Blockly.Arduino.valueToCode(this, 'port_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_tca9548a_name + '.set_port(' + value_port_data + ');\n';
    return code;
};

//端口号
Blockly.Arduino.forBlock['make_arduino_tca9548a_set_port_data'] = function () {
    var dropdown_data = this.getFieldValue('data');
    var code = dropdown_data;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//TCA9548A I2C扩展模块 获取当前正在使用的端口对应的端口号
Blockly.Arduino.forBlock['make_arduino_tca9548a_get_port'] = function () {
    var text_tca9548a_name = this.getFieldValue('tca9548a_name');
    var code = '' + text_tca9548a_name + '.get_port()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化AS608光学指纹传感器
Blockly.Arduino.forBlock['make_arduino_as608_begin'] = function () {
    var text_as608_name = this.getFieldValue('as608_name');
    var value_softwire = Blockly.Arduino.valueToCode(this, 'softwire', Blockly.Arduino.ORDER_ATOMIC);
    var value_password = Blockly.Arduino.valueToCode(this, 'password', Blockly.Arduino.ORDER_ATOMIC);
    var value_rate = Blockly.Arduino.valueToCode(this, 'rate', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Adafruit_Fingerprint'] = '#include <Adafruit_Fingerprint.h>';
    Blockly.Arduino.definitions_['var_declare_zas608_begin_' + text_as608_name] = 'Adafruit_Fingerprint ' + text_as608_name + ' = Adafruit_Fingerprint(&' + value_softwire + ', ' + value_password + ');';
    Blockly.Arduino.setups_['setup_as608_begin_' + text_as608_name] = text_as608_name + '.begin(' + value_rate + ');';
    var code = '';
    return code;
};

//AS608光学指纹传感器 串口传输波特率定义
Blockly.Arduino.forBlock['make_arduino_as608_rate'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//AS608光学指纹传感器 获取数据
Blockly.Arduino.forBlock['make_arduino_as608_get'] = function () {
    var text_as608_name = this.getFieldValue('as608_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_as608_name + '.' + dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//AS608光学指纹传感器 执行某些函数
Blockly.Arduino.forBlock['make_arduino_as608_do'] = function () {
    var text_as608_name = this.getFieldValue('as608_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_as608_name + '.' + dropdown_type + ';\n';
    return code;
};

//AS608光学指纹传感器 指纹图像转为特征模板 返回结果
Blockly.Arduino.forBlock['make_arduino_as608_image2Tz_return'] = function () {
    var text_as608_name = this.getFieldValue('as608_name');
    var value_slot = Blockly.Arduino.valueToCode(this, 'slot', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_as608_name + '.image2Tz(' + value_slot + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//AS608光学指纹传感器 指纹图像转为特征模板
Blockly.Arduino.forBlock['make_arduino_as608_image2Tz'] = function () {
    var text_as608_name = this.getFieldValue('as608_name');
    var value_slot = Blockly.Arduino.valueToCode(this, 'slot', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_as608_name + '.image2Tz(' + value_slot + ');\n';
    return code;
};

//AS608光学指纹传感器 槽位类型
Blockly.Arduino.forBlock['make_arduino_as608_image2Tz_slot'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//AS608光学指纹传感器 操作模型 返回结果
Blockly.Arduino.forBlock['make_arduino_as608_operate_model_return'] = function () {
    var text_as608_name = this.getFieldValue('as608_name');
    var dropdown_type = this.getFieldValue('type');
    var value_location = Blockly.Arduino.valueToCode(this, 'location', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_as608_name + '.' + dropdown_type + '(' + value_location + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//AS608光学指纹传感器 操作模型
Blockly.Arduino.forBlock['make_arduino_as608_operate_model'] = function () {
    var text_as608_name = this.getFieldValue('as608_name');
    var dropdown_type = this.getFieldValue('type');
    var value_location = Blockly.Arduino.valueToCode(this, 'location', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_as608_name + '.' + dropdown_type + '(' + value_location + ');\n';
    return code;
};

//AS608光学指纹传感器 设置访问密码 返回结果
Blockly.Arduino.forBlock['make_arduino_as608_setPassword_return'] = function () {
    var text_as608_name = this.getFieldValue('as608_name');
    var value_password = Blockly.Arduino.valueToCode(this, 'password', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_as608_name + '.setPassword(' + value_password + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//AS608光学指纹传感器 设置访问密码
Blockly.Arduino.forBlock['make_arduino_as608_setPassword'] = function () {
    var text_as608_name = this.getFieldValue('as608_name');
    var value_password = Blockly.Arduino.valueToCode(this, 'password', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_as608_name + '.setPassword(' + value_password + ');\n';
    return code;
};

//AS608光学指纹传感器 返回值类型
Blockly.Arduino.forBlock['make_arduino_as608_get_data'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};


// 工具函数：处理引脚值，去掉多余的括号
function getPinValue(block, inputName, defaultValue) {
    const code = Blockly.Arduino.valueToCode(block, inputName, Blockly.Arduino.ORDER_ATOMIC) || defaultValue;
    // 如果代码被括号包围且内容是单个数字，则去掉括号
    if (code.startsWith('(') && code.endsWith(')') && code.length <= 6) {
        return code.slice(1, -1);
    }
    return code;
}

// 初始化积木代码生成器（合并版）
Blockly.Arduino.forBlock['LovyanGFX_INIT_ESP8266'] = function(block) {
    // 获取设备名称
    const deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';

    // 获取连接方式
    var connectionType = block.getFieldValue('CONNECTION_TYPE') || 'SPI';

    // 获取通用配置参数
    const screen_width = block.getFieldValue('SCREEN_WIDTH');
    const screen_height = block.getFieldValue('SCREEN_HEIGHT');
    let offset_x = block.getFieldValue('OFFSET_X') || 0;
    let offset_y = block.getFieldValue('OFFSET_Y') || 0;
    const rotation = block.getFieldValue('ROTATION');

    // 获取面板类型和修复花边选项
    const panel_type = block.getFieldValue('PANEL_TYPE');
    const fix_edge = block.getFieldValue('FIX_EDGE') || 'BLACKTAB';

    // 检查是否已设置串口波特率，如果没有则自动添加
    var hasSerialBegin = false;
    for (var key in Blockly.Arduino.setups_) {
        if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
            hasSerialBegin = true;
            break;
        }
    }
    if (!hasSerialBegin) {
        Blockly.Arduino.setups_['setup_serial_auto'] = 'Serial.begin(115200);';
    }
    
    // 处理ST7735/ST7735S的修复花边预设
    // 参考TFT_eSPI的ST7735配置
    if ((panel_type === 'Panel_ST7735' || panel_type === 'Panel_ST7735S') && fix_edge !== 'CUSTOM') {
        switch(fix_edge) {
            case 'BLACKTAB':
                offset_x = 0;
                offset_y = 0;
                break;
            case 'GREENTAB2':
                offset_x = 2;
                offset_y = 1;
                break;
            case 'GREENTAB3':
                offset_x = 2;
                offset_y = 3;
                break;
            case 'GREENTAB128':
                offset_x = 0;
                offset_y = 32;
                break;
            case 'GREENTAB160x80':
                offset_x = 26;
                offset_y = 1;
                break;
            case 'REDTAB160x80':
                offset_x = 24;
                offset_y = 0;
                break;
        }
    }
    
    // 根据LovyanGFX库的实际逻辑计算尺寸

    const memory_width = screen_width + Math.abs(offset_x);
    const memory_height = screen_height + Math.abs(offset_y);
    const panel_width = screen_width;
    const panel_height = screen_height;
    
    // 添加必要的宏定义和头文件
    // Wire库必须在其他库之前包含，确保TwoWire类定义可用
    Blockly.Arduino.definitions_['include_wire_first'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['define_lgfx_v1'] = '#define LGFX_USE_V1';
    // 确保Arduino.h在LovyanGFX之前包含，提供基本定义
    Blockly.Arduino.definitions_['include_arduino'] = '#include <Arduino.h>';
    Blockly.Arduino.definitions_['include_lovyan'] = '#include <LovyanGFX.hpp>';
    
    // 🔧 根据连接类型包含相应的库
    if (connectionType === 'SPI') {
        // SPI连接需要包含SPI库
        Blockly.Arduino.definitions_['include_spi'] = '#include <SPI.h>';
    }
    
    // 🔧 确保Wire对象被实例化（关键修复）
    // 对于ESP8266平台，确保使用正确的引脚配置
    if (connectionType === 'I2C') {
        const sda_pin = (Blockly.Arduino.valueToCode(block, 'SDA', Blockly.Arduino.ORDER_ATOMIC) || '14').replace(/[()]/g, '');
        const scl_pin = (Blockly.Arduino.valueToCode(block, 'SCL', Blockly.Arduino.ORDER_ATOMIC) || '12').replace(/[()]/g, '');
        Blockly.Arduino.setups_['wire_begin'] = `Wire.begin(${sda_pin}, ${scl_pin});`;
    } else {
        Blockly.Arduino.setups_['wire_begin'] = 'Wire.begin();';
    }
    
    if (connectionType === 'SPI') {
        // SPI连接配置
        const panel_type = block.getFieldValue('PANEL_TYPE');
        const spi_freq = block.getFieldValue('SPI_FREQ');
        
        // 获取显示设置
        const rgb_order = block.getFieldValue('RGB_ORDER') === 'true';
        const invert_display = block.getFieldValue('INVERT_DISPLAY') === 'true';
        
        // 获取SPI引脚配置并清理数值（去除Blockly添加的多余括号）
        const cs = (Blockly.Arduino.valueToCode(block, 'CS', Blockly.Arduino.ORDER_ATOMIC) || '5').replace(/[()]/g, '');
        const rst = (Blockly.Arduino.valueToCode(block, 'RST', Blockly.Arduino.ORDER_ATOMIC) || '-1').replace(/[()]/g, '');
        const dc = (Blockly.Arduino.valueToCode(block, 'DC', Blockly.Arduino.ORDER_ATOMIC) || '4').replace(/[()]/g, '');
        const mosi = (Blockly.Arduino.valueToCode(block, 'MOSI', Blockly.Arduino.ORDER_ATOMIC) || '23').replace(/[()]/g, '');
        const miso = (Blockly.Arduino.valueToCode(block, 'MISO', Blockly.Arduino.ORDER_ATOMIC) || '19').replace(/[()]/g, '');
        const sclk = (Blockly.Arduino.valueToCode(block, 'SCLK', Blockly.Arduino.ORDER_ATOMIC) || '18').replace(/[()]/g, '');
        const mosi_enable = block.getFieldValue('MOSI_ENABLE') || 'ENABLED';
        
        // 创建自定义LGFX类定义（SPI）
        // 根据面板类型确定类名
        let panelClassName;
        switch(panel_type) {
            case 'Panel_ILI9341':
                panelClassName = 'ILI9341';
                break;
            case 'Panel_ILI9163':
                panelClassName = 'ILI9163';
                break;
            case 'Panel_ILI9342':
                panelClassName = 'ILI9342';
                break;
            case 'Panel_ILI9481':
                panelClassName = 'ILI9481';
                break;
            case 'Panel_ILI9486':
                panelClassName = 'ILI9486';
                break;
            case 'Panel_ILI9488':
                panelClassName = 'ILI9488';
                break;
            case 'Panel_ST7735':
                panelClassName = 'ST7735';
                break;
            case 'Panel_ST7735S':
                panelClassName = 'ST7735S';
                break;
            case 'Panel_ST7789':
                panelClassName = 'ST7789';
                break;
            case 'Panel_ST7796':
                panelClassName = 'ST7796';
                break;
            case 'Panel_HX8357B':
                panelClassName = 'HX8357B';
                break;
            case 'Panel_HX8357D':
                panelClassName = 'HX8357D';
                break;
            case 'Panel_GC9A01':
                panelClassName = 'GC9A01';
                break;
            case 'Panel_RA8875':
                panelClassName = 'RA8875';
                break;
            case 'Panel_SSD1331':
                panelClassName = 'SSD1331';
                break;
            case 'Panel_SSD1351':
                panelClassName = 'SSD1351';
                break;
            case 'Panel_SSD1963':
                panelClassName = 'SSD1963';
                break;
            case 'Panel_GDEW0154M09':
                panelClassName = 'GDEW0154M09';
                break;
            case 'Panel_IT8951':
                panelClassName = 'IT8951';
                break;
            default:
                panelClassName = 'ILI9341'; // 默认使用ILI9341
        }
        
        Blockly.Arduino.definitions_['lgfx_class_' + deviceName] = `
class LGFX_${deviceName} : public lgfx::LGFX_Device
{
public:
  lgfx::Panel_${panelClassName} _panel_instance;
  lgfx::Bus_SPI _bus_instance;

  LGFX_${deviceName}(void)
  {
    { // 配置总线
      auto cfg = _bus_instance.config();
      cfg.spi_mode = 0;
      cfg.spi_3wire  = ${mosi_enable === 'DISABLED' ? 'true' : 'false'};
      cfg.freq_write = ${spi_freq * 1000000};
      cfg.freq_read  = 16000000;
      cfg.pin_sclk = ${sclk};
      ${mosi_enable === 'ENABLED' ? `cfg.pin_mosi = ${mosi};\n      ` : ''}cfg.pin_miso = ${miso};
      cfg.pin_dc   = ${dc};
      _bus_instance.config(cfg);
      _panel_instance.setBus(&_bus_instance);
    }

    { // 配置面板
      auto cfg = _panel_instance.config();
      cfg.pin_cs           = ${cs};
      cfg.pin_rst          = ${rst};
      cfg.pin_busy         = -1;
      cfg.panel_width      = ${panel_width};
      cfg.panel_height     = ${panel_height};
      cfg.offset_x         = ${offset_x};
      cfg.offset_y         = ${offset_y};
      cfg.offset_rotation  = 2;
      cfg.dummy_read_pixel = 8;
      cfg.dummy_read_bits  = 1;
      cfg.readable         = true;
      cfg.invert           = ${invert_display};
      cfg.rgb_order        = ${rgb_order};
      cfg.dlen_16bit       = false;
      cfg.bus_shared       = true;
      _panel_instance.config(cfg);
    }

    setPanel(&_panel_instance);
  }
};
`;
    } else {
        // I2C连接配置
        const panel_type = block.getFieldValue('PANEL_TYPE');
        const i2c_freq = block.getFieldValue('I2C_FREQ');
        const i2c_addr = block.getFieldValue('I2C_ADDR');
        
        // 获取I2C引脚配置
        const sda = Blockly.Arduino.valueToCode(block, 'SDA', Blockly.Arduino.ORDER_ATOMIC) || '21';
        const scl = Blockly.Arduino.valueToCode(block, 'SCL', Blockly.Arduino.ORDER_ATOMIC) || '22';
        
        // 创建自定义LGFX类定义（I2C）
        // 根据面板类型确定类名
        let panelClassName;
        switch(panel_type) {
            case 'Panel_SSD1306':
                panelClassName = 'SSD1306';
                break;
            case 'Panel_SH110x':
                panelClassName = 'SH110x';
                break;
            case 'Panel_SSD1327':
                panelClassName = 'SSD1327';
                break;
            case 'Panel_SSD1331':
                panelClassName = 'SSD1331';
                break;
            case 'Panel_SSD1351':
                panelClassName = 'SSD1351';
                break;
            default:
                panelClassName = 'SSD1306'; // 默认使用SSD1306
        }
        
        Blockly.Arduino.definitions_['lgfx_class_' + deviceName] = `
class LGFX_${deviceName} : public lgfx::LGFX_Device
{
public:
  lgfx::Panel_${panelClassName} _panel_instance;
  lgfx::Bus_I2C _bus_instance;

  LGFX_${deviceName}(void)
  {
    { // 配置总线
      auto cfg = _bus_instance.config();
      cfg.i2c_addr = ${i2c_addr}; // I2C地址
      cfg.freq_write = ${i2c_freq}; // I2C频率
      cfg.freq_read = ${i2c_freq}; // I2C频率
      cfg.pin_sda = ${sda}; // SDA引脚
      cfg.pin_scl = ${scl}; // SCL引脚
      cfg.prefix_cmd = 0x00; // 命令前缀
      cfg.prefix_data = 0x40; // 数据前缀
      _bus_instance.config(cfg);
      _panel_instance.setBus(&_bus_instance);
    }

    { // 配置面板
      auto cfg = _panel_instance.config();
      cfg.memory_width  = ${memory_width};
      cfg.memory_height = ${memory_height};
      cfg.panel_width  = ${panel_width};
      cfg.panel_height = ${panel_height};
      cfg.offset_x = ${offset_x};
      cfg.offset_y = ${offset_y};
      cfg.offset_rotation = ${rotation + 2}; // 修改默认旋转为180度，与TFT_eSPI保持一致
      cfg.dummy_read_pixel = 8;
      cfg.dummy_read_bits  = 1;
      cfg.readable = true;
      cfg.invert = false;
      cfg.rgb_order = false;
      cfg.dlen_16bit = false;
      cfg.bus_shared = true;
      _panel_instance.config(cfg);
    }

    setPanel(&_panel_instance);
  }
};
`;
    }

    // 定义全局tft实例
    Blockly.Arduino.definitions_['lgfx_tft_' + deviceName] = 'LGFX_' + deviceName + ' ' + deviceName + ';';
    
    // 生成初始化代码
    const setupCode = `
  ${deviceName}.begin();
  ${deviceName}.setRotation(${rotation});
`;
    
    Blockly.Arduino.setups_['lgfx_init_' + deviceName] = setupCode;
    
    return '';
};

Blockly.Arduino.forBlock['LovyanGFX_INIT_ESP32'] = function(block) {
    // 获取设备名称
    const deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
    
    // 获取连接方式
    var connectionType = block.getFieldValue('CONNECTION_TYPE') || 'SPI';
    
    // 获取通用配置参数
    const screen_width = block.getFieldValue('SCREEN_WIDTH');
    const screen_height = block.getFieldValue('SCREEN_HEIGHT');
    const offset_x = block.getFieldValue('OFFSET_X') || 0;
    const offset_y = block.getFieldValue('OFFSET_Y') || 0;
    const rotation = block.getFieldValue('ROTATION');
    
    // 计算面板尺寸
    const panel_width = screen_width;
    const panel_height = screen_height;
    
    // 添加必要的宏定义和头文件
    // Wire库必须在其他库之前包含，确保TwoWire类定义可用
    Blockly.Arduino.definitions_['include_wire_first'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['define_lgfx_v1'] = '#define LGFX_USE_V1';
    // 确保Arduino.h在LovyanGFX之前包含，提供基本定义
    Blockly.Arduino.definitions_['include_arduino'] = '#include <Arduino.h>';
    Blockly.Arduino.definitions_['include_lovyan'] = '#include <LovyanGFX.hpp>';
    
    // 🔧 根据连接类型包含相应的库
    if (connectionType === 'SPI') {
        // SPI连接需要包含SPI库
        Blockly.Arduino.definitions_['include_spi'] = '#include <SPI.h>';
    }
    
    // 🔧 确保Wire对象被实例化（关键修复）
    // 对于ESP32平台，确保使用正确的引脚配置
    if (connectionType === 'I2C') {
        const sda_pin = (Blockly.Arduino.valueToCode(block, 'SDA', Blockly.Arduino.ORDER_ATOMIC) || '21').replace(/[()]/g, '');
        const scl_pin = (Blockly.Arduino.valueToCode(block, 'SCL', Blockly.Arduino.ORDER_ATOMIC) || '22').replace(/[()]/g, '');
        Blockly.Arduino.setups_['wire_begin'] = `Wire.begin(${sda_pin}, ${scl_pin});`;
    } else {
        Blockly.Arduino.setups_['wire_begin'] = 'Wire.begin();';
    }
    
    if (connectionType === 'SPI') {
        // SPI连接配置
        const panel_type = block.getFieldValue('PANEL_TYPE');
        const spi_freq = block.getFieldValue('SPI_FREQ');
        const spi_host = block.getFieldValue('SPI_HOST') || 'SPI3_HOST';
        
        // 获取显示设置
        const rgb_order = block.getFieldValue('RGB_ORDER') === 'true';
        const invert_display = block.getFieldValue('INVERT_DISPLAY') === 'true';
        
        // 获取SPI引脚配置并清理数值（去除Blockly添加的多余括号）
        const cs = (Blockly.Arduino.valueToCode(block, 'CS', Blockly.Arduino.ORDER_ATOMIC) || '5').replace(/[()]/g, '');
        const rst = (Blockly.Arduino.valueToCode(block, 'RST', Blockly.Arduino.ORDER_ATOMIC) || '-1').replace(/[()]/g, '');
        const dc = (Blockly.Arduino.valueToCode(block, 'DC', Blockly.Arduino.ORDER_ATOMIC) || '4').replace(/[()]/g, '');
        const mosi = (Blockly.Arduino.valueToCode(block, 'MOSI', Blockly.Arduino.ORDER_ATOMIC) || '23').replace(/[()]/g, '');
        const miso = (Blockly.Arduino.valueToCode(block, 'MISO', Blockly.Arduino.ORDER_ATOMIC) || '19').replace(/[()]/g, '');
        const sclk = (Blockly.Arduino.valueToCode(block, 'SCLK', Blockly.Arduino.ORDER_ATOMIC) || '18').replace(/[()]/g, '');
        const mosi_enable = block.getFieldValue('MOSI_ENABLE') || 'ENABLED';
        
        // 创建自定义LGFX类定义（SPI）
        // 根据面板类型确定类名
        let panelClassName;
        switch(panel_type) {
            case 'Panel_ILI9341':
                panelClassName = 'ILI9341';
                break;
            case 'Panel_ILI9163':
                panelClassName = 'ILI9163';
                break;
            case 'Panel_ILI9342':
                panelClassName = 'ILI9342';
                break;
            case 'Panel_ILI9481':
                panelClassName = 'ILI9481';
                break;
            case 'Panel_ILI9486':
                panelClassName = 'ILI9486';
                break;
            case 'Panel_ILI9488':
                panelClassName = 'ILI9488';
                break;
            case 'Panel_ST7735':
                panelClassName = 'ST7735';
                break;
            case 'Panel_ST7735S':
                panelClassName = 'ST7735S';
                break;
            case 'Panel_ST7789':
                panelClassName = 'ST7789';
                break;
            case 'Panel_ST7796':
                panelClassName = 'ST7796';
                break;
            case 'Panel_HX8357B':
                panelClassName = 'HX8357B';
                break;
            case 'Panel_HX8357D':
                panelClassName = 'HX8357D';
                break;
            case 'Panel_GC9A01':
                panelClassName = 'GC9A01';
                break;
            case 'Panel_RA8875':
                panelClassName = 'RA8875';
                break;
            case 'Panel_SSD1331':
                panelClassName = 'SSD1331';
                break;
            case 'Panel_SSD1351':
                panelClassName = 'SSD1351';
                break;
            case 'Panel_SSD1963':
                panelClassName = 'SSD1963';
                break;
            case 'Panel_GDEW0154M09':
                panelClassName = 'GDEW0154M09';
                break;
            case 'Panel_IT8951':
                panelClassName = 'IT8951';
                break;
            default:
                panelClassName = 'ILI9341'; // 默认使用ILI9341
        }
        
        Blockly.Arduino.definitions_['lgfx_class_' + deviceName] = `
class LGFX_${deviceName} : public lgfx::LGFX_Device
{
public:
  lgfx::Panel_${panelClassName} _panel_instance;
  lgfx::Bus_SPI _bus_instance;
  lgfx::Light_PWM _light_instance;

  LGFX_${deviceName}(void)
  {
    { // 配置总线
      auto cfg = _bus_instance.config();
      cfg.spi_host = ${spi_host};
      cfg.spi_mode = 0;
      cfg.freq_write = ${spi_freq * 1000000};
      cfg.freq_read  = 16000000;
      cfg.spi_3wire  = ${mosi_enable === 'DISABLED' ? 'true' : 'false'};
      cfg.use_lock   = true;
      cfg.dma_channel = SPI_DMA_CH_AUTO;
      cfg.pin_sclk = ${sclk};
      ${mosi_enable === 'ENABLED' ? `cfg.pin_mosi = ${mosi};\n      ` : ''}cfg.pin_miso = ${miso};
      cfg.pin_dc   = ${dc};
      _bus_instance.config(cfg);
      _panel_instance.setBus(&_bus_instance);
    }

    { // 配置面板
      auto cfg = _panel_instance.config();
      cfg.pin_cs           = ${cs};
      cfg.pin_rst          = ${rst};
      cfg.pin_busy         = -1;
      cfg.panel_width      = ${panel_width};
      cfg.panel_height     = ${panel_height};
      cfg.offset_x         = ${offset_x};
      cfg.offset_y         = ${offset_y};
      cfg.offset_rotation  = 2;
      cfg.dummy_read_pixel = 8;
      cfg.dummy_read_bits  = 1;
      cfg.readable         = true;
      cfg.invert           = ${invert_display};
      cfg.rgb_order        = ${rgb_order};
      cfg.dlen_16bit       = false;
      cfg.bus_shared       = true;
      _panel_instance.config(cfg);
    }
    setPanel(&_panel_instance);
  }
};
`;
    } else {
        // I2C连接配置
        const panel_type = block.getFieldValue('PANEL_TYPE');
        const i2c_freq = block.getFieldValue('I2C_FREQ');
        const i2c_addr = block.getFieldValue('I2C_ADDR');
        
        // 获取I2C引脚配置
        const sda = Blockly.Arduino.valueToCode(block, 'SDA', Blockly.Arduino.ORDER_ATOMIC) || '21';
        const scl = Blockly.Arduino.valueToCode(block, 'SCL', Blockly.Arduino.ORDER_ATOMIC) || '22';
        
        // 创建自定义LGFX类定义（I2C）
        // 根据面板类型确定类名
        let panelClassName;
        switch(panel_type) {
            case 'Panel_SSD1306':
                panelClassName = 'SSD1306';
                break;
            case 'Panel_SH110x':
                panelClassName = 'SH110x';
                break;
            case 'Panel_SSD1327':
                panelClassName = 'SSD1327';
                break;
            case 'Panel_SSD1331':
                panelClassName = 'SSD1331';
                break;
            case 'Panel_SSD1351':
                panelClassName = 'SSD1351';
                break;
            default:
                panelClassName = 'SSD1306'; // 默认使用SSD1306
        }
        
        Blockly.Arduino.definitions_['lgfx_class_' + deviceName] = `
class LGFX_${deviceName} : public lgfx::LGFX_Device
{
public:
  lgfx::Panel_${panelClassName} _panel_instance;
  lgfx::Bus_I2C _bus_instance;

  LGFX_${deviceName}(void)
  {
    { // 配置总线
      auto cfg = _bus_instance.config();
      cfg.i2c_addr = ${i2c_addr}; // I2C地址
      cfg.freq_write = ${i2c_freq}; // I2C频率
      cfg.freq_read = ${i2c_freq}; // I2C频率
      cfg.pin_sda = ${sda}; // SDA引脚
      cfg.pin_scl = ${scl}; // SCL引脚
      cfg.prefix_cmd = 0x00; // 命令前缀
      cfg.prefix_data = 0x40; // 数据前缀
      _bus_instance.config(cfg);
      _panel_instance.setBus(&_bus_instance);
    }

    { // 配置面板
      auto cfg = _panel_instance.config();
      cfg.memory_width  = ${memory_width};
      cfg.memory_height = ${memory_height};
      cfg.panel_width  = ${panel_width};
      cfg.panel_height = ${panel_height};
      cfg.offset_x = ${offset_x};
      cfg.offset_y = ${offset_y};
      cfg.offset_rotation = ${rotation + 2}; // 修改默认旋转为180度，与TFT_eSPI保持一致
      cfg.dummy_read_pixel = 8;
      cfg.dummy_read_bits  = 1;
      cfg.readable = true;
      cfg.invert = false;
      cfg.rgb_order = false;
      cfg.dlen_16bit = false;
      cfg.bus_shared = true;
      _panel_instance.config(cfg);
    }

    setPanel(&_panel_instance);
  }
};
`;
    }

    // 定义全局tft实例
    Blockly.Arduino.definitions_['lgfx_tft_' + deviceName] = 'LGFX_' + deviceName + ' ' + deviceName + ';';
    
    // 生成初始化代码
    const setupCode = `
  ${deviceName}.begin();
  ${deviceName}.setRotation(${rotation});
`;
    
    Blockly.Arduino.setups_['lgfx_init_' + deviceName] = setupCode;
    
    return '';
};


// 触摸屏配置积木
Blockly.Arduino.forBlock['LovyanGFX_CONFIG_TOUCH'] = function(block) {
    // 获取设备名称
    const deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
    
    // 根据触摸屏类型自动确定连接方式
    var touchType = block.getFieldValue('TOUCH_TYPE');
    var connectionType = (touchType === 'Touch_XPT2046') ? 'SPI' : 'I2C';
    
    // 根据触摸屏类型获取默认I2C地址和频率
    const getTouchDefaults = (touchType) => {
        switch (touchType) {
            case 'Touch_GT911':
                return { addr: '0x5D', freq: '400000' };
            case 'Touch_FT5x06':
            case 'Touch_FT5206':
            case 'Touch_FT5306':
            case 'Touch_FT5406':
            case 'Touch_FT6206':
            case 'Touch_FT6306':
            case 'Touch_FT6436':
            case 'Touch_FT6336':
            case 'Touch_FT6336U':
                return { addr: '0x38', freq: '400000' };
            case 'Touch_CST816S':
                return { addr: '0x15', freq: '400000' };
            case 'Touch_GSL1680E':
            case 'Touch_GSL1680F':
            case 'Touch_GSL1680':
            case 'Touch_GSL1680_800x480':
                return { addr: '0x40', freq: '400000' };
            case 'Touch_STMPE610':
                return { addr: '0x41', freq: '400000' };
            case 'Touch_TT21100':
                return { addr: '0x24', freq: '400000' };
            case 'Touch_XPT2046':
                return { addr: '0x00', freq: '1000000' }; // SPI模式，地址无效
            default:
                return { addr: '0x38', freq: '400000' };
        }
    };
    
    // 获取频率 - 根据连接方式获取对应的频率字段
    let frequency;
    if (connectionType === 'SPI') {
        frequency = block.getFieldValue('SPI_FREQUENCY');
    } else {
        // I2C模式使用默认值
        frequency = getTouchDefaults(touchType).freq;
    }
    
    // 获取坐标范围
    const x_min = Blockly.Arduino.valueToCode(block, 'TOUCH_X_MIN', Blockly.Arduino.ORDER_ATOMIC) || '0';
    const x_max = Blockly.Arduino.valueToCode(block, 'TOUCH_X_MAX', Blockly.Arduino.ORDER_ATOMIC) || '320';
    const y_min = Blockly.Arduino.valueToCode(block, 'TOUCH_Y_MIN', Blockly.Arduino.ORDER_ATOMIC) || '0';
    const y_max = Blockly.Arduino.valueToCode(block, 'TOUCH_Y_MAX', Blockly.Arduino.ORDER_ATOMIC) || '240';
    const touch_rotation = block.getFieldValue('TOUCH_ROTATION') || '0';
    
    // 创建触摸屏配置代码
    let touchConfig = '';
    
    if (connectionType === 'SPI') {
        // SPI连接配置
        // 注意：XPT2046使用软SPI模式(spi_host = -1)，避免与显示屏SPI冲突
        const cs = Blockly.Arduino.valueToCode(block, 'TOUCH_CS', Blockly.Arduino.ORDER_ATOMIC) || '5';
        const irq = Blockly.Arduino.valueToCode(block, 'TOUCH_IRQ', Blockly.Arduino.ORDER_ATOMIC) || '38';
        const sclk = Blockly.Arduino.valueToCode(block, 'TOUCH_SCLK', Blockly.Arduino.ORDER_ATOMIC) || '18';
        const mosi = Blockly.Arduino.valueToCode(block, 'TOUCH_MOSI', Blockly.Arduino.ORDER_ATOMIC) || '23';
        const miso = Blockly.Arduino.valueToCode(block, 'TOUCH_MISO', Blockly.Arduino.ORDER_ATOMIC) || '19';
        
        touchConfig = `
    { // 配置触摸屏 (XPT2046 SPI - 软SPI模式)
      auto cfg = _touch_instance.config();
      cfg.x_min = ${x_min};
      cfg.x_max = ${x_max};
      cfg.y_min = ${y_min};
      cfg.y_max = ${y_max};
      cfg.pin_int = ${irq};
      cfg.bus_shared = true;
      cfg.offset_rotation = ${touch_rotation};
      cfg.spi_host = -1; 
      cfg.freq = ${frequency};
      cfg.pin_sclk = ${sclk};
      cfg.pin_mosi = ${mosi};
      cfg.pin_miso = ${miso};
      cfg.pin_cs = ${cs};
      _touch_instance.config(cfg);
      _panel_instance.setTouch(&_touch_instance);
    }`;
    } else {
        // I2C连接配置
        const sda = Blockly.Arduino.valueToCode(block, 'TOUCH_SDA', Blockly.Arduino.ORDER_ATOMIC) || '23';
        const scl = Blockly.Arduino.valueToCode(block, 'TOUCH_SCL', Blockly.Arduino.ORDER_ATOMIC) || '32';
        
        // I2C模式使用默认值
        const defaults = getTouchDefaults(touchType);
        const addrValue = defaults.addr;
        const i2cFreq = defaults.freq;
        
        touchConfig = `
    { // 配置触摸屏 (${touchType} I2C)
      auto cfg = _touch_instance.config();
      cfg.x_min = ${x_min};
      cfg.x_max = ${x_max};
      cfg.y_min = ${y_min};
      cfg.y_max = ${y_max};
      cfg.pin_int = -1;
      cfg.bus_shared = true;
      cfg.offset_rotation = ${touch_rotation};
      cfg.i2c_port = 1;
      cfg.i2c_addr = ${addrValue};
      cfg.pin_sda = ${sda};
      cfg.pin_scl = ${scl};
      cfg.freq = ${i2cFreq};
      _touch_instance.config(cfg);
      _panel_instance.setTouch(&_touch_instance);
    }`;
    }
    
    // 获取现有的LGFX类定义
    let existingClassDef = Blockly.Arduino.definitions_['lgfx_class_' + deviceName] || '';
    
    // 检查是否已经包含触摸屏实例定义
    if (!existingClassDef.includes('lgfx::' + touchType + ' _touch_instance;')) {
        // 在类定义中添加触摸屏实例
        existingClassDef = existingClassDef.replace(
            'public:',
            'public:\n  lgfx::' + touchType + ' _touch_instance;'
        );
    }
    
    // 在构造函数末尾添加触摸屏配置
    if (!existingClassDef.includes('配置触摸屏')) {
        existingClassDef = existingClassDef.replace(
            'setPanel(&_panel_instance);',
            'setPanel(&_panel_instance);\n    // 配置触摸屏' + touchConfig
        );
    }
    
    // 更新类定义
    Blockly.Arduino.definitions_['lgfx_class_' + deviceName] = existingClassDef;
    // 检查是否启用LVGL注册
    var register_lvgl = block.getFieldValue('REGISTER_LVGL') || 'FALSE';
    
    if (register_lvgl === 'TRUE') {
        // 生成完整的LVGL触摸设备注册代码
        
        // 添加LVGL头文件
        Blockly.Arduino.definitions_['include_lvgl'] = '#include <lvgl.h>';
        
        // 生成LVGL触摸读取回调函数
        const touchCallback = `
// LVGL触摸读取回调函数
void my_touchpad_read(lv_indev_t *indev, lv_indev_data_t *data) {
    uint16_t touchX, touchY;
    // 默认设置为释放状态
    data->state = LV_INDEV_STATE_RELEASED;
    if (${deviceName}.getTouch(&touchX, &touchY)) {
        // 如果检测到触摸，设置为按下状态
        data->state = LV_INDEV_STATE_PRESSED;
        data->point.x = touchX;
        data->point.y = touchY;
    }
}`;
        
        // 添加触摸回调函数定义
        Blockly.Arduino.definitions_['lvgl_touch_callback'] = touchCallback;
        
        // 在setup函数中添加LVGL触摸设备注册代码
        const setupCode = `
    // 初始化LVGL触摸设备
    lv_indev_t *indev = lv_indev_create();
    lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
    lv_indev_set_read_cb(indev, my_touchpad_read);
`;
        
        // 添加到setup函数
        if (!Blockly.Arduino.setups_['lvgl_touch_setup']) {
            Blockly.Arduino.setups_['lvgl_touch_setup'] = setupCode;
        }
    }
    
    return '';
};





// LVGL初始化积木代码生成器
Blockly.Arduino.forBlock['LovyanGFX_LVGL_INIT'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  
  // 添加LVGL头文件
  Blockly.Arduino.definitions_['include_lvgl'] = '#include <lvgl.h>';
  
  // 添加LVGL配置
  Blockly.Arduino.definitions_['lvgl_config_' + deviceName] = `
// LVGL配置
#define LVGL_BUFFER_HEIGHT 40
static lv_disp_draw_buf_t draw_buf_${deviceName};
static lv_color_t buf_${deviceName}[LVGL_BUFFER_HEIGHT * 320];
static lv_disp_drv_t disp_drv_${deviceName};
`;

  // 添加LVGL显示驱动初始化函数
  Blockly.Arduino.definitions_['lvgl_disp_init_' + deviceName] = `
// LVGL显示驱动初始化函数
void my_disp_flush_${deviceName}(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
    uint32_t w = (area->x2 - area->x1 + 1);
    uint32_t h = (area->y2 - area->y1 + 1);

    ${deviceName}.startWrite();
    ${deviceName}.setAddrWindow(area->x1, area->y1, w, h);
    ${deviceName}.writePixels((lgfx::rgb565_t*)color_p, w * h);
    ${deviceName}.endWrite();

    lv_disp_flush_ready(disp);
}

void lvgl_display_init_${deviceName}() {
    lv_init();
    
    lv_disp_draw_buf_init(&draw_buf_${deviceName}, buf_${deviceName}, NULL, LVGL_BUFFER_HEIGHT * 320);
    
    lv_disp_drv_init(&disp_drv_${deviceName});
    disp_drv_${deviceName}.hor_res = ${deviceName}.width();
    disp_drv_${deviceName}.ver_res = ${deviceName}.height();
    disp_drv_${deviceName}.flush_cb = my_disp_flush_${deviceName};
    disp_drv_${deviceName}.draw_buf = &draw_buf_${deviceName};
    lv_disp_drv_register(&disp_drv_${deviceName});
}
`;

  // 在setup中调用LVGL初始化函数
  Blockly.Arduino.setups_['lvgl_init_' + deviceName] = 'lvgl_display_init_' + deviceName + '();';
  
  return '';
};

// 绘制数字代码生成器
Blockly.Arduino.forBlock['LovyanGFX_TFT_DRAW_NUMBER'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  var number = Blockly.Arduino.valueToCode(block, 'NUMBER', Blockly.Arduino.ORDER_ATOMIC) || '0';
  var xPos = Blockly.Arduino.valueToCode(block, 'X_POS', Blockly.Arduino.ORDER_ATOMIC) || '0';
  var yPos = Blockly.Arduino.valueToCode(block, 'Y_POS', Blockly.Arduino.ORDER_ATOMIC) || '0';
  var fontSize = Blockly.Arduino.valueToCode(block, 'FONT_SIZE', Blockly.Arduino.ORDER_ATOMIC) || '1';
  
  // 使用 setTextSize 设置放大倍数，绘制数字后恢复默认大小
  return deviceName + '.setTextSize(' + fontSize + ');\n  ' + deviceName + '.drawNumber(' + number + ', ' + xPos + ', ' + yPos + ');\n  ' + deviceName + '.setTextSize(1);\n';
};

// 英文字体设置积木代码生成器
Blockly.Arduino.forBlock['LovyanGFX_TFT_YING'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  var fontFamily = block.getFieldValue('FONT_FAMILY') || 'FreeSans';
  var fontSize = block.getFieldValue('FONT_SIZE') || '12pt';
  
  var fontName;
  
  // 根据字体类型构建字体名称
  if (fontFamily && fontFamily.startsWith('Free')) {
    // FreeFonts: FreeMono9pt7b, FreeSansBold12pt7b 等
    // 如果字号是default（内置字体的情况），使用默认12pt
    var size = (fontSize === 'default') ? '12pt' : fontSize;
    fontName = fontFamily + size + '7b';
  } else if (fontFamily === 'DejaVu') {
    // DejaVu: DejaVu9, DejaVu12, DejaVu72 等
    var size = (fontSize === 'default') ? '12' : fontSize;
    fontName = 'DejaVu' + size;
  } else {
    // 内置字体: Font0, Font2, Font4 等，直接使用字体名，不拼接字号
    fontName = fontFamily;
  }
  
  // 根据选择的字体设置字体
  var setupCode = deviceName + '.setFont(&fonts::' + fontName + ');\n';
  
  // 将设置代码添加到setup函数中
  Blockly.Arduino.setups_['english_font_setup_' + deviceName] = setupCode;
  
  // 设置类积木不需要返回代码
  return '';
};

// 中文字体设置积木代码生成器
Blockly.Arduino.forBlock['LovyanGFX_TFT_ZW'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  var dropdown_xl_zwzt = block.getFieldValue('XL_ZWZT');
  var dropdown_xl_zwzh = block.getFieldValue('XL_ZWZH');
  
  // 根据字体类型和字号生成相应的字体设置代码
  var fontCode = '';
  
  // 使用switch语句根据字体类型和字号动态生成代码
  switch(dropdown_xl_zwzt) {
    case 'gb2312a':
      // 中文GB2312A字体 - 常规字体
      fontCode = `${deviceName}.setFont(&lgfx::fonts::efontCN_${dropdown_xl_zwzh});  // 中文GB2312A常规字体`;
      break;
    case 'gb2312b':
      // 中文GB2312B字体 - 粗体
      fontCode = `${deviceName}.setFont(&lgfx::fonts::efontCN_${dropdown_xl_zwzh}_b);  // 中文GB2312B粗体字体`;
      break;
    default:
      // 默认使用GB2312A字体
      fontCode = `${deviceName}.setFont(&lgfx::fonts::efontCN_${dropdown_xl_zwzh});  // 默认中文GB2312A字体`;
      break;
  }
  
  // 将设置代码添加到loop函数中，而不是setup函数中
  var code = fontCode + ';\n';
  return code;
};


// 获取触摸X坐标
Blockly.Arduino.forBlock['LovyanGFX_getTouchX'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  // 检查是否启用了独立触摸系统（通过触摸屏配置积木的LVGL注册）
  if (Blockly.Arduino.definitions_['lvgl_touch_standalone']) {
    // 🎯 LVGL独立模式：使用独立触摸系统的函数
    var code = 'get_touch_x()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
  } else {
    // 🔗 原有模式：使用原有机制
    if (!Blockly.Arduino.definitions_['touch_xy_vars_' + deviceName]) {
      Blockly.Arduino.definitions_['touch_xy_vars_' + deviceName] = 'uint16_t touch_x_' + deviceName + ', touch_y_' + deviceName + ';';
    }
    var code = '(' + deviceName + '.getTouch(&touch_x_' + deviceName + ', &touch_y_' + deviceName + ') ? touch_x_' + deviceName + ' : 0)';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
  }
};

// 获取触摸Y坐标
Blockly.Arduino.forBlock['LovyanGFX_getTouchY'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  // 检查是否启用了独立触摸系统（通过触摸屏配置积木的LVGL注册）
  if (Blockly.Arduino.definitions_['lvgl_touch_standalone']) {
    // 🎯 LVGL独立模式：使用独立触摸系统的函数
    var code = 'get_touch_y()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
  } else {
    // 🔗 原有模式：使用原有机制
    var code = '(' + deviceName + '.getTouch(&touch_x_' + deviceName + ', &touch_y_' + deviceName + ') ? touch_y_' + deviceName + ' : 0)';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
  }
};

// 检测是否被触摸
Blockly.Arduino.forBlock['LovyanGFX_touched'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  // 检查是否启用了独立触摸系统（通过触摸屏配置积木的LVGL注册）
  if (Blockly.Arduino.definitions_['lvgl_touch_standalone']) {
    // 🎯 LVGL独立模式：使用独立触摸系统的函数
    var code = 'is_touch_pressed()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
  } else {
    // 🔗 原有模式：使用原有机制
    var code = deviceName + '.getTouch(&touch_x_' + deviceName + ', &touch_y_' + deviceName + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
  }
};


//屏宽/屏高代码生成器
Blockly.Arduino.forBlock['LovyanGFX_s_h19'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  var dropdown_h_e71 = block.getFieldValue('h_e71');
  var code = deviceName + '.' + dropdown_h_e71 + '()';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

// 设置旋转方向代码生成器
Blockly.Arduino.forBlock['LovyanGFX_set_rotation'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  var dropdown_rotation = block.getFieldValue('LovyanGFX_set_rotation_data');
  var code = deviceName + '.setRotation(' + dropdown_rotation + ');\n';
  return code;
};


// 颜色选择积木代码生成器
Blockly.Arduino.forBlock['LovyanGFX_COLOR'] = function(block) {
  var color = block.getFieldValue('my_color');
  // 将十六进制颜色值转换为0xFCCC格式
  var r = parseInt(color.substr(1,2), 16);
  var g = parseInt(color.substr(3,2), 16);
  var b = parseInt(color.substr(5,2), 16);
  
  // 转换为565格式 (RGB565)
  var r5 = (r >> 3) & 0x1F;  // 取高5位
  var g6 = (g >> 2) & 0x3F;  // 取高6位
  var b5 = (b >> 3) & 0x1F;  // 取高5位
  
  // 组合为16位颜色值
  var rgb565 = (r5 << 11) | (g6 << 5) | b5;
  var code = '0x' + rgb565.toString(16).padStart(4, '0');
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

// 文字滚动积木代码生成器（支持四种滚动方向）
Blockly.Arduino.forBlock['LovyanGFX_TEXT_SCROLL'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  var text = Blockly.Arduino.valueToCode(block, 'TEXT', Blockly.Arduino.ORDER_ATOMIC) || '"Hello"';
  var fontSize = Blockly.Arduino.valueToCode(block, 'FONT_SIZE', Blockly.Arduino.ORDER_ATOMIC) || '16';
  var fontColor = Blockly.Arduino.valueToCode(block, 'FONT_COLOR', Blockly.Arduino.ORDER_ATOMIC) || '0xFFFF';

  var scrollSpeed = Blockly.Arduino.valueToCode(block, 'SCROLL_SPEED', Blockly.Arduino.ORDER_ATOMIC) || '1';
  var scrollDirection = block.getFieldValue('SCROLL_DIRECTION');
  
  // 获取滚动区域变量名
  var scrollRectXVarName = 'scrollRectX_' + deviceName;
  var scrollRectYVarName = 'scrollRectY_' + deviceName;
  var scrollRectWidthVarName = 'scrollRectWidth_' + deviceName;
  var scrollRectHeightVarName = 'scrollRectHeight_' + deviceName;
  
  if (scrollDirection === 'left_to_right' || scrollDirection === 'right_to_left') {
    // 水平滚动实现（从左到右或从右到左）
    // 创建唯一的变量名
    var spriteName = 'scrollSprite_' + deviceName;
    var textVarName = 'scrollText_' + deviceName;
    var textPosVarName = 'scrollPos_' + deviceName;
    var textLenVarName = 'scrollLen_' + deviceName;
    var scrollActiveVarName = 'scrollActive_' + deviceName;
    var loopFlagVarName = 'horizontalScrollInitialized_' + deviceName;
    var scrollSpriteHeightVarName = 'scrollSpriteHeight_' + deviceName;
    
    // 定义全局变量
    Blockly.Arduino.definitions_[spriteName] = 'LGFX_Sprite ' + spriteName + ';\n';
    Blockly.Arduino.definitions_[textVarName] = 'String ' + textVarName + ' = ' + text + ';\n';
    Blockly.Arduino.definitions_[textPosVarName] = 'size_t ' + textPosVarName + ' = 0;\n';
    Blockly.Arduino.definitions_[textLenVarName] = 'size_t ' + textLenVarName + ' = 0;\n';
    Blockly.Arduino.definitions_[scrollActiveVarName] = 'bool ' + scrollActiveVarName + ' = true;\n';
    Blockly.Arduino.definitions_[loopFlagVarName] = 'bool ' + loopFlagVarName + ' = false;\n';
    Blockly.Arduino.definitions_[scrollSpriteHeightVarName] = 'int ' + scrollSpriteHeightVarName + ';\n';
    
    // 用户输入的值直接作为放大倍数，与垂直滚动保持一致
    // 降低最小字体大小限制，允许更小的字体显示
    var actualFontSize = '(' + fontSize + ' < 1 ? 1 : ' + fontSize + ')';
    // 字体高度基于AsciiFont24x48是24像素，放大倍数
    var spriteHeight = '(' + actualFontSize + ' * 48)';
    
    // 在setup中初始化Sprite
    // ESP8266内存有限，减小Sprite高度以节省内存（只创建文字区域，不创建整个滚动区域）
    var setupCode = spriteName + '.setColorDepth(8);\n';
    setupCode += spriteName + '.setTextWrap(false);\n';
    setupCode += '    ' + scrollSpriteHeightVarName + ' = ' + actualFontSize + ' * 48;\n';
    setupCode += '    if (' + scrollSpriteHeightVarName + ' > ' + scrollRectHeightVarName + ') {\n';
    setupCode += '      ' + scrollSpriteHeightVarName + ' = ' + scrollRectHeightVarName + ';\n';
    setupCode += '    }\n';
    setupCode += '    ' + spriteName + '.createSprite(' + scrollRectWidthVarName + ', ' + scrollSpriteHeightVarName + ');\n';
    // 为Sprite设置中文字体，与主设备相同
    // 使用与主显示屏相同的中文字体，避免重复加载不同字体
    setupCode += spriteName + '.setFont(' + deviceName + '.getFont());\n';
    // 中文字体大小设置：使用用户设置的字体大小，与垂直滚动保持一致
    setupCode += spriteName + '.setTextSize(' + actualFontSize + ');\n';
    setupCode += spriteName + '.setTextColor(' + fontColor + ');\n';
    // 不再填充整个Sprite背景，让滚动区域的背景色显示出来
    // setupCode += spriteName + '.fillScreen(' + bgColor + ');\n';
    setupCode += textLenVarName + ' = ' + textVarName + '.length();\n';
    setupCode += loopFlagVarName + ' = true;\n';
    
    Blockly.Arduino.setups_['horizontal_scroll_setup_' + deviceName] = setupCode;
    
    // 返回loop函数中的代码，添加时间控制机制，与垂直滚动保持一致
    var loopCode = 'if (' + scrollActiveVarName + ' && ' + loopFlagVarName + ') {\n';
    loopCode += '  static unsigned long lastScrollTime = 0;\n';
    loopCode += '  static int32_t textX = ' + scrollRectWidthVarName + ' + 32;\n'; // 初始位置在右侧边缘外
    loopCode += '  if (millis() - lastScrollTime > (1000 / ' + scrollSpeed + ')) {\n';
    loopCode += '    lastScrollTime = millis();\n';
    // 清除文字区域，避免拖影（使用滚动区域的背景色）
    loopCode += '    ' + spriteName + '.fillRect(0, 0, ' + scrollRectWidthVarName + ', ' + scrollSpriteHeightVarName + ', scrollRectBgColor_' + deviceName + ');\n';
    
    if (scrollDirection === 'right_to_left') {
      // 从右到左滚动
      loopCode += '    // 更新文字位置\n';
      loopCode += '    textX -= ' + actualFontSize + ';\n'; // 每次移动像素等于放大倍数
      // 文字宽度计算：每个字符宽度12像素（AsciiFont24x48是24x48）
      loopCode += '    int textWidth = ' + textLenVarName + ' * ' + actualFontSize + ' * 12;\n';
      loopCode += '    if (textX < -textWidth) {\n';
      loopCode += '      textX = ' + scrollRectWidthVarName + ';\n';
      loopCode += '    }\n';
    } else {
      // 从左到右滚动
      loopCode += '    textX += ' + actualFontSize + ';\n'; // 每次移动像素等于放大倍数
      // 文字宽度计算：每个字符宽度12像素（AsciiFont24x48是24x48）
      loopCode += '    int textWidth = ' + textLenVarName + ' * ' + actualFontSize + ' * 12;\n';
      loopCode += '    if (textX > ' + scrollRectWidthVarName + ') {\n';
      loopCode += '      textX = -textWidth;\n';
      loopCode += '    }\n';
    }
    
    loopCode += '    \n';
    // Y坐标设置为0，确保文字从Sprite顶部开始显示
    // 这样可以显示完整的文字高度
    loopCode += '    ' + spriteName + '.setCursor(textX, 0);\n';
    // 一次性打印整个字符串，而不是逐个字符打印
    loopCode += '    ' + spriteName + '.println(' + textVarName + ');\n';
    loopCode += '    \n';
    loopCode += '    ' + spriteName + '.pushSprite(&' + deviceName + ', ' + scrollRectXVarName + ', ' + scrollRectYVarName + ');\n';
    loopCode += '  }\n';
    loopCode += '}\n';
    
    return loopCode;
  } else {
    // 垂直滚动实现（从上到下或从下到上）
    // 创建唯一的变量名
    var spriteName = 'verticalScrollSprite_' + deviceName;
    var textVarName = 'verticalScrollText_' + deviceName;
    var scrollActiveVarName = 'verticalScrollActive_' + deviceName;
    var loopFlagVarName = 'verticalScrollInitialized_' + deviceName;
    var scrollPosVarName = 'verticalScrollPos_' + deviceName;
    var verticalScrollSpriteHeightVarName = 'verticalScrollSpriteHeight_' + deviceName;
    
    // 定义全局变量
    Blockly.Arduino.definitions_[spriteName] = 'LGFX_Sprite ' + spriteName + ';\n';
    Blockly.Arduino.definitions_[textVarName] = 'String ' + textVarName + ' = ' + text + ';\n';
    Blockly.Arduino.definitions_[scrollActiveVarName] = 'bool ' + scrollActiveVarName + ' = true;\n';
    Blockly.Arduino.definitions_[loopFlagVarName] = 'bool ' + loopFlagVarName + ' = false;\n';
    Blockly.Arduino.definitions_[scrollPosVarName] = 'int32_t ' + scrollPosVarName + ' = 0;\n';
    Blockly.Arduino.definitions_[verticalScrollSpriteHeightVarName] = 'int ' + verticalScrollSpriteHeightVarName + ';\n';
    
 
    var actualFontSize = '(' + fontSize + ' < 1 ? 1 : ' + fontSize + ')';
    
    var setupCode = '';
    setupCode += '    ' + verticalScrollSpriteHeightVarName + ' = ' + scrollRectHeightVarName + ';\n';
    setupCode += '    if (' + verticalScrollSpriteHeightVarName + ' > 80) {\n';
    setupCode += '      ' + verticalScrollSpriteHeightVarName + ' = 80;\n';
    setupCode += '    }\n';
    setupCode += '    ' + spriteName + '.setColorDepth(8);\n';
    setupCode += '    ' + spriteName + '.setTextWrap(false);\n';
    setupCode += '    ' + spriteName + '.createSprite(' + scrollRectWidthVarName + ', ' + verticalScrollSpriteHeightVarName + ');\n';
    setupCode += spriteName + '.setFont(' + deviceName + '.getFont());\n';
    setupCode += spriteName + '.setTextSize(' + actualFontSize + ');\n';
    setupCode += spriteName + '.setTextColor(' + fontColor + ');\n';
    setupCode += loopFlagVarName + ' = true;\n';
    Blockly.Arduino.setups_['vertical_scroll_setup_' + deviceName] = setupCode;
    
    var loopCode = 'if (' + scrollActiveVarName + ' && ' + loopFlagVarName + ') {\n';
    loopCode += '  static unsigned long lastScrollTime = 0;\n';
    loopCode += '  if (millis() - lastScrollTime > (1000 / ' + scrollSpeed + ')) {\n';
    loopCode += '    lastScrollTime = millis();\n';
    loopCode += '    int oldPos = ' + scrollPosVarName + ';\n';
    
    if (scrollDirection === 'top_to_bottom') {
      // 从上到下滚动（参考测试好的代码逻辑）
      loopCode += '    int oldAbsoluteY = ' + scrollRectYVarName + ' + oldPos;\n';
      loopCode += '    if (oldAbsoluteY >= ' + scrollRectYVarName + ' && oldAbsoluteY < (' + scrollRectYVarName + ' + ' + scrollRectHeightVarName + ')) {\n';
      loopCode += '      ' + deviceName + '.drawFastHLine(' + scrollRectXVarName + ', oldAbsoluteY, ' + scrollRectWidthVarName + ', scrollRectBgColor_' + deviceName + ');\n';
      loopCode += '    }\n';
      loopCode += '    ' + scrollPosVarName + '++;\n';
      loopCode += '    if (' + scrollPosVarName + ' > ' + scrollRectHeightVarName + ') {\n';
      loopCode += '      ' + scrollPosVarName + ' = -' + verticalScrollSpriteHeightVarName + ';\n';
      loopCode += '      ' + deviceName + '.fillRect(' + scrollRectXVarName + ', ' + scrollRectYVarName + ', ' + scrollRectWidthVarName + ', ' + scrollRectHeightVarName + ', scrollRectBgColor_' + deviceName + ');\n';
      loopCode += '    }\n';
    } else {
      // 从下到上滚动
      loopCode += '    int oldAbsoluteY = ' + scrollRectYVarName + ' + oldPos + ' + verticalScrollSpriteHeightVarName + ' - 1;\n';
      loopCode += '    if (oldAbsoluteY >= ' + scrollRectYVarName + ' && oldAbsoluteY < (' + scrollRectYVarName + ' + ' + scrollRectHeightVarName + ')) {\n';
      loopCode += '      ' + deviceName + '.drawFastHLine(' + scrollRectXVarName + ', oldAbsoluteY, ' + scrollRectWidthVarName + ', scrollRectBgColor_' + deviceName + ');\n';
      loopCode += '    }\n';
      loopCode += '    ' + scrollPosVarName + '--;\n';
      loopCode += '    if (' + scrollPosVarName + ' < -' + verticalScrollSpriteHeightVarName + ') {\n';
      loopCode += '      ' + scrollPosVarName + ' = ' + scrollRectHeightVarName + ';\n';
      loopCode += '      ' + deviceName + '.fillRect(' + scrollRectXVarName + ', ' + scrollRectYVarName + ', ' + scrollRectWidthVarName + ', ' + scrollRectHeightVarName + ', scrollRectBgColor_' + deviceName + ');\n';
      loopCode += '    }\n';
    }
    
    loopCode += '    int pushY = ' + scrollRectYVarName + ' + ' + scrollPosVarName + ';\n';
    
    // 在 Sprite 中绘制文字
    loopCode += '    ' + spriteName + '.fillSprite(scrollRectBgColor_' + deviceName + ');\n';
    loopCode += '    ' + spriteName + '.setCursor(0, 0);\n';
    loopCode += '    ' + spriteName + '.print(' + textVarName + ');\n';
    // 设置剪裁区域，确保Sprite只在滚动区域内显示
    loopCode += '    ' + deviceName + '.setClipRect(' + scrollRectXVarName + ', ' + scrollRectYVarName + ', ' + scrollRectWidthVarName + ', ' + scrollRectHeightVarName + ');\n';
    loopCode += '    ' + spriteName + '.pushSprite(&' + deviceName + ', ' + scrollRectXVarName + ', pushY);\n';
    loopCode += '    ' + deviceName + '.clearClipRect();\n';
    loopCode += '  }\n';
    loopCode += '}\n';
    
    return loopCode;
  }
};

// 滚动区域设置积木代码生成器（添加背景色功能）
Blockly.Arduino.forBlock['LovyanGFX_SCROLL_RECT'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  var value_x = Blockly.Arduino.valueToCode(block, 'X', Blockly.Arduino.ORDER_ATOMIC) || '0';
  var value_y = Blockly.Arduino.valueToCode(block, 'Y', Blockly.Arduino.ORDER_ATOMIC) || '0';
  var value_width = Blockly.Arduino.valueToCode(block, 'WIDTH', Blockly.Arduino.ORDER_ATOMIC) || '100';
  var value_height = Blockly.Arduino.valueToCode(block, 'HEIGHT', Blockly.Arduino.ORDER_ATOMIC) || '100';
  var value_bg_color = Blockly.Arduino.valueToCode(block, 'BG_COLOR', Blockly.Arduino.ORDER_ATOMIC) || '0x0000';
  
  // 将设置代码添加到setup函数中
  var setupCode = deviceName + '.setScrollRect(' + value_x + ', ' + value_y + ', ' + value_width + ', ' + value_height + ');\n';
  
  // 添加背景色填充代码
  setupCode += deviceName + '.fillRect(' + value_x + ', ' + value_y + ', ' + value_width + ', ' + value_height + ', ' + value_bg_color + ');\n';
  
  // 添加全局变量来存储滚动区域的位置，供文字滚动积木使用
  var scrollRectXVarName = 'scrollRectX_' + deviceName;
  var scrollRectYVarName = 'scrollRectY_' + deviceName;
  var scrollRectWidthVarName = 'scrollRectWidth_' + deviceName;
  var scrollRectHeightVarName = 'scrollRectHeight_' + deviceName;
  var scrollRectBgColorVarName = 'scrollRectBgColor_' + deviceName;
  
  Blockly.Arduino.definitions_[scrollRectXVarName] = 'int ' + scrollRectXVarName + ' = ' + value_x + ';\n';
  Blockly.Arduino.definitions_[scrollRectYVarName] = 'int ' + scrollRectYVarName + ' = ' + value_y + ';\n';
  Blockly.Arduino.definitions_[scrollRectWidthVarName] = 'int ' + scrollRectWidthVarName + ' = ' + value_width + ';\n';
  Blockly.Arduino.definitions_[scrollRectHeightVarName] = 'int ' + scrollRectHeightVarName + ' = ' + value_height + ';\n';
  Blockly.Arduino.definitions_[scrollRectBgColorVarName] = 'uint16_t ' + scrollRectBgColorVarName + ' = ' + value_bg_color + ';\n';
  
  Blockly.Arduino.setups_['scroll_rect_setup_' + deviceName] = setupCode;
  
  // 设置类积木不需要返回代码
  return '';
};

// 清除滚动区域积木代码生成器
Blockly.Arduino.forBlock['LovyanGFX_CLEAR_SCROLL_RECT'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  
  // 将设置代码添加到loop函数中，而不是setup函数中
  var code = deviceName + '.clearScrollRect();\n';
  return code;
};

// 停止文字滚动积木代码生成器（支持所有方向）
Blockly.Arduino.forBlock['LovyanGFX_STOP_SCROLL'] = function(block) {
  var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
  
  // 获取所有滚动相关的变量名（支持水平、垂直、四个方向）
  var horizontalScrollActiveVarName = 'scrollActive_' + deviceName;
  var verticalScrollActiveVarName = 'verticalScrollActive_' + deviceName;
  var horizontalScrollSpriteName = 'scrollSprite_' + deviceName;
  var verticalScrollSpriteName = 'verticalScrollSprite_' + deviceName;
  
  // 将停止滚动代码添加到loop函数中，而不是setup函数中
  var code = horizontalScrollActiveVarName + ' = false;\n';
  code += verticalScrollActiveVarName + ' = false;\n';
  code += deviceName + '.clearScrollRect();\n'; // 清除滚动区域，防止拖影
  
  return code;
};

function string_Bin_to_Hex(outstr_select) {
    switch (outstr_select) {
        case '0000':
            {
                outstr_select = '0';
                break;
            }
        case '0001':
            {
                outstr_select = '1';
                break;
            }
        case '0010':
            {
                outstr_select = '2';
                break;
            }
        case '0011':
            {
                outstr_select = '3';
                break;
            }
        case '0100':
            {
                outstr_select = '4';
                break;
            }
        case '0101':
            {
                outstr_select = '5';
                break;
            }
        case '0110':
            {
                outstr_select = '6';
                break;
            }
        case '0111':
            {
                outstr_select = '7';
                break;
            }
        case '1000':
            {
                outstr_select = '8';
                break;
            }
        case '1001':
            {
                outstr_select = '9';
                break;
            }
        case '1010':
            {
                outstr_select = 'A';
                break;
            }
        case '1011':
            {
                outstr_select = 'B';
                break;
            }
        case '1100':
            {
                outstr_select = 'C';
                break;
            }
        case '1101':
            {
                outstr_select = 'D';
                break;
            }
        case '1110':
            {
                outstr_select = 'E';
                break;
            }
        case '1111':
            {
                outstr_select = 'F';
                break;
            }
    }
    return outstr_select;
};

function string_Hex_to_Bin(outstr_select) {
    switch (outstr_select) {
        case '0':
            {
                outstr_select = '0000';
                break;
            }
        case '1':
            {
                outstr_select = '0001';
                break;
            }
        case '2':
            {
                outstr_select = '0010';
                break;
            }
        case '3':
            {
                outstr_select = '0011';
                break;
            }
        case '4':
            {
                outstr_select = '0100';
                break;
            }
        case '5':
            {
                outstr_select = '0101';
                break;
            }
        case '6':
            {
                outstr_select = '0110';
                break;
            }
        case '7':
            {
                outstr_select = '0111';
                break;
            }
        case '8':
            {
                outstr_select = '1000';
                break;
            }
        case '9':
            {
                outstr_select = '1001';
                break;
            }
        case 'a':
            {
                outstr_select = '1010';
                break;
            }
        case 'b':
            {
                outstr_select = '1011';
                break;
            }
        case 'c':
            {
                outstr_select = '1100';
                break;
            }
        case 'd':
            {
                outstr_select = '1101';
                break;
            }
        case 'e':
            {
                outstr_select = '1110';
                break;
            }
        case 'f':
            {
                outstr_select = '1111';
                break;
            }
    }
    return outstr_select;
};

//屏幕背光初始化引脚
Blockly.Arduino.forBlock['make_arduino_st7735_backlight_20200703'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_st7735_backlight_pin = Blockly.Arduino.valueToCode(this, 'st7735_backlight_pin', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_backlight_brightness = Blockly.Arduino.valueToCode(this, 'st7735_backlight_brightness', Blockly.Arduino.ORDER_ATOMIC);
    var code = 'analogWrite(' + value_st7735_backlight_pin + ', ' + value_st7735_backlight_brightness + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_set_rotation'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var dropdown_set_rotation_data = this.getFieldValue('set_rotation_data');
    var code = '' + text_st7735_name + '.setRotation(' + dropdown_set_rotation_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_setRotation'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_angle = Blockly.Arduino.valueToCode(this, 'angle', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var code = text_st7735_name + '.setRotation(' + value_angle + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_set_cursor'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_set_cursor_x = Blockly.Arduino.valueToCode(this, 'set_cursor_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_set_cursor_y = Blockly.Arduino.valueToCode(this, 'set_cursor_y', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_st7735_name + '.setCursor(' + value_set_cursor_x + ', ' + value_set_cursor_y + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_set_text_size'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var dropdown_set_text_size_data = this.getFieldValue('set_text_size_data');
    var code = '' + text_st7735_name + '.setTextSize(' + dropdown_set_text_size_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_setTextSize'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_size = Blockly.Arduino.valueToCode(this, 'size', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var code = text_st7735_name + '.setTextSize(' + value_size + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_oled_TextSize'] = function () {
    var dropdown_size = this.getFieldValue('size');
    return [dropdown_size, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_oled_Rotation'] = function () {
    var dropdown_angle = this.getFieldValue('angle');
    return [dropdown_angle, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_st7735_set_text_color'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_set_text_color_data = Blockly.Arduino.valueToCode(this, 'set_text_color_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_st7735_name + '.setTextColor(' + value_set_text_color_data + ');\n';
    return code;
};

//RGB颜色
Blockly.Arduino.forBlock['make_arduino_st7735_color'] = function () {
    var colour_st7735_color_type = this.getFieldValue('st7735_color_type');
    var str_1 = colour_st7735_color_type.charAt(1);
    var str_2 = colour_st7735_color_type.charAt(2);
    var str_3 = colour_st7735_color_type.charAt(3);
    var str_4 = colour_st7735_color_type.charAt(4);
    var str_5 = colour_st7735_color_type.charAt(5);
    var str_6 = colour_st7735_color_type.charAt(6);

    str_1 = string_Hex_to_Bin(str_1);
    str_2 = string_Hex_to_Bin(str_2);
    str_3 = string_Hex_to_Bin(str_3);
    str_4 = string_Hex_to_Bin(str_4);
    str_5 = string_Hex_to_Bin(str_5);
    str_6 = string_Hex_to_Bin(str_6);

    str_2 = str_2.charAt(0);
    str_4 = str_4.substring(0, 2);
    str_6 = str_6.charAt(0);

    var str = str_1 + str_2 + str_3 + str_4 + str_5 + str_6;
    var str1 = '';
    str1 = '0x' + string_Bin_to_Hex(str.substring(0, 4)) + string_Bin_to_Hex(str.substring(4, 8)) + string_Bin_to_Hex(str.substring(8, 12)) + string_Bin_to_Hex(str.substring(12, 16));
    var code = str1;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//BGR颜色
Blockly.Arduino.forBlock['make_arduino_st7735_color_2020_07_20'] = function () {
    var colour_st7735_color_type = this.getFieldValue('st7735_color_type');
    var str_5 = colour_st7735_color_type.charAt(1);
    var str_6 = colour_st7735_color_type.charAt(2);
    var str_3 = colour_st7735_color_type.charAt(3);
    var str_4 = colour_st7735_color_type.charAt(4);
    var str_1 = colour_st7735_color_type.charAt(5);
    var str_2 = colour_st7735_color_type.charAt(6);

    str_1 = string_Hex_to_Bin(str_1);
    str_2 = string_Hex_to_Bin(str_2);
    str_3 = string_Hex_to_Bin(str_3);
    str_4 = string_Hex_to_Bin(str_4);
    str_5 = string_Hex_to_Bin(str_5);
    str_6 = string_Hex_to_Bin(str_6);

    str_2 = str_2.charAt(0);
    str_4 = str_4.substring(0, 2);
    str_6 = str_6.charAt(0);

    var str = str_1 + str_2 + str_3 + str_4 + str_5 + str_6;
    var str1 = '';
    str1 = string_Bin_to_Hex(str.substring(0, 4)) + string_Bin_to_Hex(str.substring(4, 8)) + string_Bin_to_Hex(str.substring(8, 12)) + string_Bin_to_Hex(str.substring(12, 16));
    str1 = parseInt(str1, 16);
    var code = str1;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};


Blockly.Arduino.forBlock['make_arduino_st7735_fill_screen'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_fill_screen_type = Blockly.Arduino.valueToCode(this, 'fill_screen_type', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_st7735_name + '.fillScreen(' + value_fill_screen_type + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_set_text_screen_color_2019_10_18'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var dropdown_choose_type = this.getFieldValue('choose_type');
    var value_set_text_color_data = Blockly.Arduino.valueToCode(this, 'set_text_color_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_st7735_name + '.' + dropdown_choose_type + '(' + value_set_text_color_data + ');\n';
    return code;
};

//设置字体和字体背景颜色
Blockly.Arduino.forBlock['arduino_st7735_set_text_background_color_2020_07_01'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_set_text_color_data = Blockly.Arduino.valueToCode(this, 'set_text_color_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_set_text_color_background = Blockly.Arduino.valueToCode(this, 'set_text_color_background', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_st7735_name + '.setTextColor(' + value_set_text_color_data + ', ' + value_set_text_color_background + ');\n';
    return code;
};

//设置文本综合
Blockly.Arduino.forBlock['arduino_st7735_set_text_2020_07_02'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_set_text_x = Blockly.Arduino.valueToCode(this, 'set_text_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_set_text_y = Blockly.Arduino.valueToCode(this, 'set_text_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_set_text_color = Blockly.Arduino.valueToCode(this, 'set_text_color', Blockly.Arduino.ORDER_ATOMIC);
    var value_set_background_color = Blockly.Arduino.valueToCode(this, 'set_background_color', Blockly.Arduino.ORDER_ATOMIC);
    var value_set_text_data = Blockly.Arduino.valueToCode(this, 'set_text_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_size = Blockly.Arduino.valueToCode(this, 'size', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var checkbox_set_text_linebreak = this.getFieldValue('set_text_linebreak') == 'TRUE';
    if (checkbox_set_text_linebreak) {
        checkbox_set_text_linebreak = 'println';
    }
    else {
        checkbox_set_text_linebreak = 'print';
    }
    var code = '' + text_st7735_name + '.setCursor(' + value_set_text_x + ', ' + value_set_text_y + ');\n'
        + '' + text_st7735_name + '.setTextColor(' + value_set_text_color + ', ' + value_set_background_color + ');\n'
        + '' + text_st7735_name + '.setTextSize(' + value_size + ');\n'
        + '' + text_st7735_name + '.' + checkbox_set_text_linebreak + '(' + value_set_text_data + ');\n';
    return code;
};

//显示汉字（使用位图显示）
Blockly.Arduino.forBlock['make_arduino_st7735_show_hz'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var checkbox_st7735_show_hz = this.getFieldValue('st7735_show_hz') == 'TRUE';
    var checkbox_st7735_show_hz_message = this.getFieldValue('st7735_show_hz_message') == 'TRUE';
    var checkbox_st7735_show_hz_save = this.getFieldValue('st7735_show_hz_save') == 'TRUE';
    var dropdown_st7735_hz_sharp = this.getFieldValue('st7735_hz_sharp');
    var text_st7735_hz_line_height = this.getFieldValue('st7735_hz_line_height');
    var dropdown_hz_up_down = this.getFieldValue('hz_up_down');
    var text_hz_up_down_data = this.getFieldValue('hz_up_down_data');
    var dropdown_hz_left_right = this.getFieldValue('hz_left_right');
    var text_hz_left_right_data = this.getFieldValue('hz_left_right_data');
    var value_st7735_hz_data = Blockly.Arduino.valueToCode(this, 'st7735_hz_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_hz_x = Blockly.Arduino.valueToCode(this, 'st7735_hz_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_hz_y = Blockly.Arduino.valueToCode(this, 'st7735_hz_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_hz_height = Blockly.Arduino.valueToCode(this, 'st7735_hz_height', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_hz_width = Blockly.Arduino.valueToCode(this, 'st7735_hz_width', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_hz_color = Blockly.Arduino.valueToCode(this, 'st7735_hz_color', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_st7735_hz_variant = 'normal';
    var dropdown_st7735_hz_style = 'normal';
    var dropdown_st7735_hz_thickness = 'normal';
    var fontSize_width = myAtoi(value_st7735_hz_width);
    var fontSize_height = myAtoi(value_st7735_hz_height);
    var bs = Math.ceil(fontSize_width / 8);//每行占字节数

    var move_x = 0;
    var move_y = 0;
    if (dropdown_hz_up_down == "hz_down") {
        move_y = myAtoi(text_hz_up_down_data);
    }
    else {
        move_y = myAtoi("-" + text_hz_up_down_data);
    }

    if (dropdown_hz_left_right == "hz_right") {
        move_x = myAtoi(text_hz_left_right_data);
    }
    else {
        move_x = myAtoi("-" + text_hz_left_right_data);
    }
    canvas.width = fontSize_width;
    canvas.height = fontSize_height;
    ctx.font = dropdown_st7735_hz_style + ' ' + dropdown_st7735_hz_variant + ' ' + dropdown_st7735_hz_thickness + ' ' + text_st7735_hz_line_height + 'px ' + dropdown_st7735_hz_sharp;
    ctx.textAlign = "left";
    ctx.textBaseline = "top";

    var c = value_st7735_hz_data;
    ctx.fillStyle = "#000000";
    ctx.fillRect(0, 0, fontSize_width, fontSize_height);//涂背景
    ctx.fillStyle = "#ffffff";
    ctx.fillText(c, move_x, move_y);//写字
    var data = ctx.getImageData(0, 0, fontSize_width, fontSize_height).data;//获取图像
    var zm = new Array(bs * fontSize_height);
    for (var i = 0; i < zm.length; i++)zm[i] = 0;//初始化字模数组
    for (var i = 0; i < fontSize_height; i++)//读像素值组成字模数组
        for (var j = 0; j < fontSize_width; j++)
            if (data[i * fontSize_width * 4 + j * 4]) zm[parseInt(j / 8) + i * bs] += bitArr[j % 8];
    var outStr = "";//将字模数组转化为十六进制形式
    for (var i = 0; i < zm.length - 1; i++)outStr += toHex(zm[i]) + ",";
    outStr += toHex(zm[i]);

    var zm1 = new Array(bs * fontSize_height);
    var outstr1 = "";
    for (var i in zm) zm1[i] = zm[i].toString(2);
    for (var i in zm1) {
        var str = "";
        for (var j = 0; j < 8 - zm1[i].length; j++)str += "0";
        zm1[i] = str + zm1[i];
    }
    for (var i in zm1) outstr1 += zm1[i];

    var HZ_image = "";
    var num_hz = 0;
    for (var i = 0; i < fontSize_width; i++) {
        HZ_image += "--";
        if (i == (fontSize_width - 1)) HZ_image += "\n|";
    }

    for (var data_hz of outstr1) {
        num_hz++;
        if (num_hz == outstr1.length) {
            HZ_image += "|\n";
        }
        else if (num_hz % (bs * 8) < fontSize_width && num_hz % (bs * 8) > 0) {
            if (data_hz == "0") HZ_image += "  ";
            else if (data_hz == "1") HZ_image += "0 ";
        }
        else if (num_hz % (bs * 8) == 0) {
            HZ_image += "|\n|";
        }
    }
    for (var i = 0; i < fontSize_width; i++) {
        HZ_image += "--";
    }
    HZ_image = "/*" + "\n" + HZ_image + "\n" + "*/";

    var hz_sharp = "";
    switch (dropdown_st7735_hz_sharp) {
        case "STHeiti":
            hz_sharp = "华文黑体";
            break;
        case "STKaiti":
            hz_sharp = "华文楷体";
            break;
        case "STXihei":
            hz_sharp = "华文细黑";
            break;
        case "STSong":
            hz_sharp = "华文宋体";
            break;
        case "STZhongsong":
            hz_sharp = "华文中宋";
            break;
        case "STFangsong":
            hz_sharp = "华文仿宋";
            break;
        case "STCaiyun":
            hz_sharp = "华文彩云";
            break;
        case "STHupo":
            hz_sharp = "华文琥珀";
            break;
        case "STLiti":
            hz_sharp = "华文隶书";
            break;
        case "STXingkai":
            hz_sharp = "华文行楷";
            break;
        case "STXinwei":
            hz_sharp = "华文新魏";
            break;
        case "simHei":
            hz_sharp = "黑体";
            break;
        case "simSun":
            hz_sharp = "宋体";
            break;
        case "NSimSun":
            hz_sharp = "新宋体";
            break;
        case "FangSong":
            hz_sharp = "仿宋";
            break;
        case "KaiTi":
            hz_sharp = "楷体";
            break;
        case "FangSong_GB2312":
            hz_sharp = "仿宋_GB2312";
            break;
        case "KaiTi_GB2312":
            hz_sharp = "楷体_GB2312";
            break;
        case "LiSu":
            hz_sharp = "隶书";
            break;
        case "YouYuan":
            hz_sharp = "幼圆";
            break;
        case "PMingLiU":
            hz_sharp = "新细明体";
            break;
        case "MingLiU":
            hz_sharp = "细明体";
            break;
        case "DFKai-SB":
            hz_sharp = "标楷体";
            break;
        case "Microsoft JhengHei":
            hz_sharp = "微软正黑体";
            break;
        case "Microsoft YaHei":
            hz_sharp = "微软雅黑体";
            break;
        default:
            hz_sharp = dropdown_st7735_hz_sharp;
            break;
    }
    hz_sharp = "字体：" + hz_sharp + "  字号：" + text_st7735_hz_line_height + "px" + "  显示文字：" + value_st7735_hz_data;

    if (checkbox_st7735_show_hz) {
        if (checkbox_st7735_show_hz_save) {
            Blockly.Arduino.definitions_['var_declare_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = HZ_image + "\n//" + hz_sharp + "\nstatic const unsigned char PROGMEM oled_st7735_" + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + "[" + (bs * fontSize_height) + "]={" + outStr + "};";
        }
        else {
            Blockly.Arduino.definitions_['var_declare_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = HZ_image + "\n//" + hz_sharp + "\nunsigned char oled_st7735_" + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + "[" + (bs * fontSize_height) + "]={" + outStr + "};";
        }
    }
    else {
        if (checkbox_st7735_show_hz_message) {
            if (checkbox_st7735_show_hz_save) {
                Blockly.Arduino.definitions_['var_declare_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = "//" + hz_sharp + "\nstatic const unsigned char PROGMEM oled_st7735_" + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + "[" + (bs * fontSize_height) + "]={" + outStr + "};";
            }
            else {
                Blockly.Arduino.definitions_['var_declare_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = "//" + hz_sharp + "\nunsigned char oled_st7735_" + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + "[" + (bs * fontSize_height) + "]={" + outStr + "};";
            }
        }
        else {
            if (checkbox_st7735_show_hz_save) {
                Blockly.Arduino.definitions_['var_declare_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = "static const unsigned char PROGMEM oled_st7735_" + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + "[" + (bs * fontSize_height) + "]={" + outStr + "};";
            }
            else {
                Blockly.Arduino.definitions_['var_declare_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = "unsigned char oled_st7735_" + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + "[" + (bs * fontSize_height) + "]={" + outStr + "};";
            }
        }
    }
    if (checkbox_st7735_show_hz_message) {
        var code = '//绘制位图 ' + hz_sharp + '  X坐标：' + value_st7735_hz_x + '  Y坐标：' + value_st7735_hz_y + '  位图宽度：' + value_st7735_hz_width + '  位图高度：' + value_st7735_hz_height + '\n' + text_st7735_name + '.drawBitmap(' + value_st7735_hz_x + ', ' + value_st7735_hz_y + ', oled_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + ', ' + value_st7735_hz_width + ', ' + value_st7735_hz_height + ', ' + value_st7735_hz_color + ');\n';
    }
    else {
        var code = text_st7735_name + '.drawBitmap(' + value_st7735_hz_x + ', ' + value_st7735_hz_y + ', oled_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + ', ' + value_st7735_hz_width + ', ' + value_st7735_hz_height + ', ' + value_st7735_hz_color + ');\n';
    }
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_print'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_st7735_print_data = Blockly.Arduino.valueToCode(this, 'st7735_print_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_st7735_name + '.print(' + value_st7735_print_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_println'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_st7735_print_data = Blockly.Arduino.valueToCode(this, 'st7735_print_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_st7735_name + '.println(' + value_st7735_print_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_print1'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_st7735_print1_data = Blockly.Arduino.valueToCode(this, 'st7735_print1_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_st7735_print1_type = this.getFieldValue('st7735_print1_type');
    var code = '' + text_st7735_name + '.print(' + value_st7735_print1_data + ', ' + dropdown_st7735_print1_type + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_println1'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_st7735_println1_data = Blockly.Arduino.valueToCode(this, 'st7735_println1_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_st7735_println1_type = this.getFieldValue('st7735_println1_type');
    var code = '' + text_st7735_name + '.println(' + value_st7735_println1_data + ', ' + dropdown_st7735_println1_type + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_show_text_2019_10_18'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var dropdown_show_text_type = this.getFieldValue('show_text_type');
    var value_st7735_print_data = Blockly.Arduino.valueToCode(this, 'st7735_print_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_st7735_name + '.' + dropdown_show_text_type + '(' + value_st7735_print_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_show_num_2019_10_18'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var dropdown_show_num_type = this.getFieldValue('show_num_type');
    var value_st7735_print_data = Blockly.Arduino.valueToCode(this, 'st7735_print_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_st7735_print_type = this.getFieldValue('st7735_print_type');
    var code = '' + text_st7735_name + '.' + dropdown_show_num_type + '(' + value_st7735_print_data + ', ' + dropdown_st7735_print_type + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_draw_pixel'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_st7735_draw_pixel_x = Blockly.Arduino.valueToCode(this, 'st7735_draw_pixel_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_pixel_y = Blockly.Arduino.valueToCode(this, 'st7735_draw_pixel_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_pixel_color = Blockly.Arduino.valueToCode(this, 'st7735_draw_pixel_color', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_st7735_name + '.drawPixel(' + value_st7735_draw_pixel_x + ', ' + value_st7735_draw_pixel_y + ', ' + value_st7735_draw_pixel_color + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_draw_line'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_st7735_draw_pixel_start_x = Blockly.Arduino.valueToCode(this, 'st7735_draw_pixel_start_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_pixel_start_y = Blockly.Arduino.valueToCode(this, 'st7735_draw_pixel_start_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_pixel_end_x = Blockly.Arduino.valueToCode(this, 'st7735_draw_pixel_end_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_pixel_end_y = Blockly.Arduino.valueToCode(this, 'st7735_draw_pixel_end_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_pixel_color = Blockly.Arduino.valueToCode(this, 'st7735_draw_pixel_color', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_st7735_name + '.drawLine(' + value_st7735_draw_pixel_start_x + ', ' + value_st7735_draw_pixel_start_y + ', ' + value_st7735_draw_pixel_end_x + ', ' + value_st7735_draw_pixel_end_y + ', ' + value_st7735_draw_pixel_color + ');\n';
    return code;
};

//TFT长度&角度画线20200810
Blockly.Arduino.forBlock['make_arduino_st7735_draw_angle_line_2020_08_10'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_st7735_draw_angle_line_x1 = Blockly.Arduino.valueToCode(this, 'st7735_draw_angle_line_x1', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_angle_line_y1 = Blockly.Arduino.valueToCode(this, 'st7735_draw_angle_line_y1', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_angle_line_length = Blockly.Arduino.valueToCode(this, 'st7735_draw_angle_line_length', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_angle_line_angle = Blockly.Arduino.valueToCode(this, 'st7735_draw_angle_line_angle', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_angle_line_color = Blockly.Arduino.valueToCode(this, 'st7735_draw_angle_line_color', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['st7735_draw_angle_line'] = 'int line_x1,line_y1,line_x2,line_y2,line_Angle,line_length;';
    var code = 'line_x1 = ' + value_st7735_draw_angle_line_x1 + ';\n'
        + 'line_y1 = ' + value_st7735_draw_angle_line_y1 + ';\n'
        + 'line_x2 = 0;\n'
        + 'line_y2 = 0;\n'
        + 'line_Angle = ' + value_st7735_draw_angle_line_angle + ' + 90;\n'
        + 'line_length = ' + value_st7735_draw_angle_line_length + ';\n'
        + 'line_x2 = line_x1 + line_length * sin(line_Angle / 180.0 * 3.14159);\n'
        + 'line_y2 = line_y1 + line_length * cos(line_Angle / 180.0 * 3.14159);\n'
        + 'tft.drawLine(line_x1, line_y1, line_x2, line_y2, ' + value_st7735_draw_angle_line_color + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_draw_line1'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var dropdown_st7735_draw_line1_type = this.getFieldValue('st7735_draw_line1_type');
    var value_st7735_draw_pixel_start_x = Blockly.Arduino.valueToCode(this, 'st7735_draw_pixel_start_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_pixel_start_y = Blockly.Arduino.valueToCode(this, 'st7735_draw_pixel_start_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_pixel_length = Blockly.Arduino.valueToCode(this, 'st7735_draw_pixel_length', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_pixel_color = Blockly.Arduino.valueToCode(this, 'st7735_draw_pixel_color', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_st7735_name + '.' + dropdown_st7735_draw_line1_type + '(' + value_st7735_draw_pixel_start_x + ', ' + value_st7735_draw_pixel_start_y + ', ' + value_st7735_draw_pixel_length + ', ' + value_st7735_draw_pixel_color + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_draw_rect'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var dropdown_st7735_draw_rect_type = this.getFieldValue('st7735_draw_rect_type');
    var dropdown_st7735_draw_rect_type_1 = this.getFieldValue('st7735_draw_rect_type_1');
    var value_st7735_draw_rect_x = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_y = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_width = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_width', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_hight = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_hight', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_color = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_color', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_st7735_name + '.' + dropdown_st7735_draw_rect_type_1 + dropdown_st7735_draw_rect_type + '(' + value_st7735_draw_rect_x + ', ' + value_st7735_draw_rect_y + ', ' + value_st7735_draw_rect_width + ', ' + value_st7735_draw_rect_hight + ', ' + value_st7735_draw_rect_color + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_draw_rect_change_2019_10_18'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var dropdown_st7735_draw_rect_type_1 = this.getFieldValue('st7735_draw_rect_type_1');
    var value_st7735_draw_rect_x = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_y = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_width = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_width', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_hight = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_hight', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_color = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_color', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_st7735_name + '.' + dropdown_st7735_draw_rect_type_1 + 'Rect(' + value_st7735_draw_rect_x + ', ' + value_st7735_draw_rect_y + ', ' + value_st7735_draw_rect_width + ', ' + value_st7735_draw_rect_hight + ', ' + value_st7735_draw_rect_color + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_draw_Roundrect_change_2019_10_18'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var dropdown_st7735_draw_rect_type_1 = this.getFieldValue('st7735_draw_rect_type_1');
    var value_st7735_draw_rect_x = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_y = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_width = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_width', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_hight = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_hight', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_radius = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_radius', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_rect_color = Blockly.Arduino.valueToCode(this, 'st7735_draw_rect_color', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_st7735_name + '.' + dropdown_st7735_draw_rect_type_1 + 'RoundRect(' + value_st7735_draw_rect_x + ', ' + value_st7735_draw_rect_y + ', ' + value_st7735_draw_rect_width + ', ' + value_st7735_draw_rect_hight + ', ' + value_st7735_draw_rect_radius + ', ' + value_st7735_draw_rect_color + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_draw_circle'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var dropdown_oled_draw_circle_type = this.getFieldValue('oled_draw_circle_type');
    var value_st7735_draw_circle_x = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_circle_y = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_circle_radius = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_radius', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_circle_color = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_color', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_st7735_name + '.' + dropdown_oled_draw_circle_type + 'Circle(' + value_st7735_draw_circle_x + ', ' + value_st7735_draw_circle_y + ', ' + value_st7735_draw_circle_radius + ', ' + value_st7735_draw_circle_color + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_draw_CircleHelper'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_st7735_draw_circle_x = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_circle_y = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_circle_radius = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_radius', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_circle_cornername = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_cornername', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_circle_color = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_color', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_st7735_name + '.startWrite(' + ');\n'
        + text_st7735_name + '.drawCircleHelper(' + value_st7735_draw_circle_x + ', ' + value_st7735_draw_circle_y + ', ' + value_st7735_draw_circle_radius + ', ' + value_st7735_draw_circle_cornername + ', ' + value_st7735_draw_circle_color + ');\n'
        + text_st7735_name + '.endWrite(' + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_fill_CircleHelper'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var value_st7735_draw_circle_x = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_circle_y = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_circle_radius = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_radius', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_circle_cornername = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_cornername', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_circle_delta = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_delta', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_circle_color = Blockly.Arduino.valueToCode(this, 'st7735_draw_circle_color', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_st7735_name + '.startWrite(' + ');\n'
        + text_st7735_name + '.fillCircleHelper(' + value_st7735_draw_circle_x + ', ' + value_st7735_draw_circle_y + ', ' + value_st7735_draw_circle_radius + ', ' + value_st7735_draw_circle_cornername + ', ' + value_st7735_draw_circle_delta + ', ' + value_st7735_draw_circle_color + ');\n'
        + text_st7735_name + '.endWrite(' + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_draw_ellipse'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var dropdown_st7735_draw_ellipse_type = this.getFieldValue('st7735_draw_ellipse_type');
    var value_st7735_draw_ellipse_x = Blockly.Arduino.valueToCode(this, 'st7735_draw_ellipse_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_ellipse_y = Blockly.Arduino.valueToCode(this, 'st7735_draw_ellipse_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_ellipse_x_radius = Blockly.Arduino.valueToCode(this, 'st7735_draw_ellipse_x_radius', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_ellipse_y_radius = Blockly.Arduino.valueToCode(this, 'st7735_draw_ellipse_y_radius', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_ellipse_cornername = Blockly.Arduino.valueToCode(this, 'st7735_draw_ellipse_cornername', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_ellipse_color = Blockly.Arduino.valueToCode(this, 'st7735_draw_ellipse_color', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['function_draw_ellipse_section'] = 'void draw_ellipse_section(Adafruit_GFX *screen, int16_t x, int16_t y, int16_t x0, int16_t y0, uint8_t option, boolean fill, uint16_t color){\n'
        + '  /* upper left */\n'
        + '  if (option & 0x01){\n'
        + '    if(fill)\n'
        + '      screen->drawFastVLine(x0-x, y0-y, y+1, color);\n'
        + '    else\n'
        + '      screen->drawPixel(x0 - x, y0 - y, color);\n'
        + '  }\n'
        + '\n'
        + '  /* upper right */\n'
        + '  if (option & 0x02){\n'
        + '    if(fill)\n'
        + '      screen->drawFastVLine(x0+x, y0-y, y+1, color);\n'
        + '    else\n'
        + '      screen->drawPixel(x0 + x, y0 - y, color);\n'
        + '  }\n'
        + '\n'
        + '  /* lower right */\n'
        + '  if (option & 0x04){\n'
        + '    if(fill)\n'
        + '      screen->drawFastVLine(x0+x, y0, y+1, color);\n'
        + '    else\n'
        + '      screen->drawPixel(x0 + x, y0 + y, color);\n'
        + '  }\n'
        + '\n'
        + '  /* lower left */\n'
        + '  if (option & 0x08){\n'
        + '    if(fill)\n'
        + '      screen->drawFastVLine(x0-x, y0, y+1, color);\n'
        + '    else\n'
        + '      screen->drawPixel(x0 - x, y0 + y, color);\n'
        + '  }\n'
        + '}\n';
    Blockly.Arduino.definitions_['function_draw_ellipse'] = 'void draw_ellipse(Adafruit_GFX *screen, int16_t x0, int16_t y0, int16_t rx, int16_t ry, uint8_t option, boolean fill, uint16_t color){\n'
        + '  uint16_t x, y;\n'
        + '  int32_t xchg, ychg;\n'
        + '  int32_t err;\n'
        + '  int32_t rxrx2;\n'
        + '  int32_t ryry2;\n'
        + '  int32_t stopx, stopy;\n'
        + '\n'
        + '  rxrx2 = rx;\n'
        + '  rxrx2 *= rx;\n'
        + '  rxrx2 *= 2;\n'
        + '\n'
        + '  ryry2 = ry;\n'
        + '  ryry2 *= ry;\n'
        + '  ryry2 *= 2;\n'
        + '\n'
        + '  x = rx;\n'
        + '  y = 0;\n'
        + '\n'
        + '  xchg = 1;\n'
        + '  xchg -= rx;\n'
        + '  xchg -= rx;\n'
        + '  xchg *= ry;\n'
        + '  xchg *= ry;\n'
        + '\n'
        + '  ychg = rx;\n'
        + '  ychg *= rx;\n'
        + '\n'
        + '  err = 0;\n'
        + '\n'
        + '  stopx = ryry2;\n'
        + '  stopx *= rx;\n'
        + '  stopy = 0;\n'
        + '\n'
        + '  while( stopx >= stopy ){\n'
        + '    draw_ellipse_section(screen, x, y, x0, y0, option, fill, color);\n'
        + '    y++;\n'
        + '    stopy += rxrx2;\n'
        + '    err += ychg;\n'
        + '    ychg += rxrx2;\n'
        + '    if ( 2*err+xchg > 0 ){\n'
        + '      x--;\n'
        + '      stopx -= ryry2;\n'
        + '      err += xchg;\n'
        + '      xchg += ryry2;\n'
        + '    }\n'
        + '  }\n'
        + '\n'
        + '  x = 0;\n'
        + '  y = ry;\n'
        + '\n'
        + '  xchg = ry;\n'
        + '  xchg *= ry;\n'
        + '\n'
        + '  ychg = 1;\n'
        + '  ychg -= ry;\n'
        + '  ychg -= ry;\n'
        + '  ychg *= rx;\n'
        + '  ychg *= rx;\n'
        + '\n'
        + '  err = 0;\n'
        + '\n'
        + '  stopx = 0;\n'
        + '\n\n'
        + '  stopy = rxrx2;\n'
        + '  stopy *= ry;\n'
        + '\n'
        + '  while( stopx <= stopy ){\n'
        + '    draw_ellipse_section(screen, x, y, x0, y0, option, fill, color);\n'
        + '    x++;\n'
        + '    stopx += ryry2;\n'
        + '    err += xchg;\n'
        + '    xchg += ryry2;\n'
        + '    if ( 2*err+ychg > 0 ){\n'
        + '      y--;\n'
        + '      stopy -= rxrx2;\n'
        + '      err += ychg;\n'
        + '      ychg += rxrx2;\n'
        + '    }\n'
        + '  }\n'
        + '}\n';
    var code = 'draw_ellipse(&' + text_st7735_name + ', ' + value_st7735_draw_ellipse_x + ', ' + value_st7735_draw_ellipse_y + ', ' + value_st7735_draw_ellipse_x_radius + ', ' + value_st7735_draw_ellipse_y_radius + ', ' + value_st7735_draw_ellipse_cornername + ', ' + dropdown_st7735_draw_ellipse_type + ', ' + value_st7735_draw_ellipse_color + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_st7735_draw_triangle'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var dropdown_st7735_draw_triangle_type = this.getFieldValue('st7735_draw_triangle_type');
    var value_st7735_draw_triangle_x1 = Blockly.Arduino.valueToCode(this, 'st7735_draw_triangle_x1', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_triangle_y1 = Blockly.Arduino.valueToCode(this, 'st7735_draw_triangle_y1', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_triangle_x2 = Blockly.Arduino.valueToCode(this, 'st7735_draw_triangle_x2', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_triangle_y2 = Blockly.Arduino.valueToCode(this, 'st7735_draw_triangle_y2', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_triangle_x3 = Blockly.Arduino.valueToCode(this, 'st7735_draw_triangle_x3', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_triangle_y3 = Blockly.Arduino.valueToCode(this, 'st7735_draw_triangle_y3', Blockly.Arduino.ORDER_ATOMIC);
    var value_st7735_draw_triangle_color = Blockly.Arduino.valueToCode(this, 'st7735_draw_triangle_color', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_st7735_name + '.' + dropdown_st7735_draw_triangle_type + 'Triangle(' + value_st7735_draw_triangle_x1 + ', ' + value_st7735_draw_triangle_y1 + ', ' + value_st7735_draw_triangle_x2 + ', ' + value_st7735_draw_triangle_y2 + ', ' + value_st7735_draw_triangle_x3 + ', ' + value_st7735_draw_triangle_y3 + ', ' + value_st7735_draw_triangle_color + ');\n';
    return code;
};

//初始化LCD12864
Blockly.Arduino.forBlock['make_arduino_lcd12864_begin'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var dropdown_display_rotation = this.getFieldValue('display_rotation');
    var value_clock = Blockly.Arduino.valueToCode(this, 'clock', Blockly.Arduino.ORDER_ATOMIC);
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var value_cs = Blockly.Arduino.valueToCode(this, 'cs', Blockly.Arduino.ORDER_ATOMIC);
    var value_reset = Blockly.Arduino.valueToCode(this, 'reset', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_U8g2lib'] = '#include <U8g2lib.h>';
    Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['var_declare_U8G2_' + text_lcd12864_name] = 'U8G2_ST7920_128X64_1_SW_SPI ' + text_lcd12864_name + '(' + dropdown_display_rotation + ', ' + value_clock + ', ' + value_data + ', ' + value_cs + ', ' + value_reset + ');';
    Blockly.Arduino.setups_["setup_u8g2_" + text_lcd12864_name] = ' ' + text_lcd12864_name + '.begin();';
    var code = '';
    return code;
};

//LCD12864更新屏幕数据
Blockly.Arduino.forBlock['make_arduino_lcd12864_update'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var statements_update_data = Blockly.Arduino.statementToCode(this, 'update_data');
    var code = '' + text_lcd12864_name + '.firstPage();'
        + '\ndo'
        + '\n{'
        + '\n  ' + statements_update_data
        + '\n}'
        + '\nwhile(' + text_lcd12864_name + '.nextPage());\n';
    return code;
};

//显示汉字（使用位图显示）
Blockly.Arduino.forBlock['make_arduino_lcd12864_show_hz'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var checkbox_lcd12864_show_hz = this.getFieldValue('lcd12864_show_hz') == 'TRUE';
    var checkbox_lcd12864_show_hz_message = this.getFieldValue('lcd12864_show_hz_message') == 'TRUE';
    var checkbox_lcd12864_show_hz_save = this.getFieldValue('lcd12864_show_hz_save') == 'TRUE';
    var dropdown_lcd12864_hz_sharp = this.getFieldValue('lcd12864_hz_sharp');
    var text_lcd12864_hz_line_height = this.getFieldValue('lcd12864_hz_line_height');
    var dropdown_hz_up_down = this.getFieldValue('hz_up_down');
    var text_hz_up_down_data = this.getFieldValue('hz_up_down_data');
    var dropdown_hz_left_right = this.getFieldValue('hz_left_right');
    var text_hz_left_right_data = this.getFieldValue('hz_left_right_data');
    var value_lcd12864_hz_data = Blockly.Arduino.valueToCode(this, 'lcd12864_hz_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_lcd12864_hz_x = Blockly.Arduino.valueToCode(this, 'lcd12864_hz_x', Blockly.Arduino.ORDER_ATOMIC);
    var value_lcd12864_hz_y = Blockly.Arduino.valueToCode(this, 'lcd12864_hz_y', Blockly.Arduino.ORDER_ATOMIC);
    var value_lcd12864_hz_height = Blockly.Arduino.valueToCode(this, 'lcd12864_hz_height', Blockly.Arduino.ORDER_ATOMIC);
    var value_lcd12864_hz_width = Blockly.Arduino.valueToCode(this, 'lcd12864_hz_width', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_lcd12864_hz_variant = 'normal';
    var dropdown_lcd12864_hz_style = 'normal';
    var dropdown_lcd12864_hz_thickness = 'normal';
    var fontSize_width = myAtoi(value_lcd12864_hz_width);
    var fontSize_height = myAtoi(value_lcd12864_hz_height);
    var bs = Math.ceil(fontSize_width / 8);//每行占字节数

    var move_x = 0;
    var move_y = 0;
    if (dropdown_hz_up_down == "hz_down") {
        move_y = myAtoi(text_hz_up_down_data);
    }
    else {
        move_y = myAtoi("-" + text_hz_up_down_data);
    }

    if (dropdown_hz_left_right == "hz_right") {
        move_x = myAtoi(text_hz_left_right_data);
    }
    else {
        move_x = myAtoi("-" + text_hz_left_right_data);
    }
    canvas.width = fontSize_width;
    canvas.height = fontSize_height;
    ctx.font = dropdown_lcd12864_hz_style + ' ' + dropdown_lcd12864_hz_variant + ' ' + dropdown_lcd12864_hz_thickness + ' ' + text_lcd12864_hz_line_height + 'px ' + dropdown_lcd12864_hz_sharp;
    ctx.textAlign = "left";
    ctx.textBaseline = "top";

    var c = value_lcd12864_hz_data;
    ctx.fillStyle = "#000000";
    ctx.fillRect(0, 0, fontSize_width, fontSize_height);//涂背景
    ctx.fillStyle = "#ffffff";
    ctx.fillText(c, move_x, move_y);//写字
    var data = ctx.getImageData(0, 0, fontSize_width, fontSize_height).data;//获取图像
    var zm = new Array(bs * fontSize_height);
    for (var i = 0; i < zm.length; i++)zm[i] = 0;//初始化字模数组
    for (var i = 0; i < fontSize_height; i++)//读像素值组成字模数组
        for (var j = 0; j < fontSize_width; j++)
            if (data[i * fontSize_width * 4 + j * 4]) zm[parseInt(j / 8) + i * bs] += bitArr[j % 8];
    var outStr = "";//将字模数组转化为十六进制形式
    for (var i = 0; i < zm.length - 1; i++)outStr += toHex(zm[i]) + ",";
    outStr += toHex(zm[i]);

    var zm1 = new Array(bs * fontSize_height);
    var outstr1 = "";
    for (var i in zm) zm1[i] = zm[i].toString(2);
    for (var i in zm1) {
        var str = "";
        for (var j = 0; j < 8 - zm1[i].length; j++)str += "0";
        zm1[i] = str + zm1[i];
    }
    for (var i in zm1) outstr1 += zm1[i];

    var HZ_image = "";
    var num_hz = 0;
    for (var i = 0; i < fontSize_width; i++) {
        HZ_image += "--";
        if (i == (fontSize_width - 1)) HZ_image += "\n|";
    }

    for (var data_hz of outstr1) {
        num_hz++;
        if (num_hz == outstr1.length) {
            HZ_image += "|\n";
        }
        else if (num_hz % (bs * 8) < fontSize_width && num_hz % (bs * 8) > 0) {
            if (data_hz == "0") HZ_image += "  ";
            else if (data_hz == "1") HZ_image += "0 ";
        }
        else if (num_hz % (bs * 8) == 0) {
            HZ_image += "|\n|";
        }
    }
    for (var i = 0; i < fontSize_width; i++) {
        HZ_image += "--";
    }
    HZ_image = "/*" + "\n" + HZ_image + "\n" + "*/";

    var hz_sharp = "";
    switch (dropdown_lcd12864_hz_sharp) {
        case "STHeiti":
            hz_sharp = "华文黑体";
            break;
        case "STKaiti":
            hz_sharp = "华文楷体";
            break;
        case "STXihei":
            hz_sharp = "华文细黑";
            break;
        case "STSong":
            hz_sharp = "华文宋体";
            break;
        case "STZhongsong":
            hz_sharp = "华文中宋";
            break;
        case "STFangsong":
            hz_sharp = "华文仿宋";
            break;
        case "STCaiyun":
            hz_sharp = "华文彩云";
            break;
        case "STHupo":
            hz_sharp = "华文琥珀";
            break;
        case "STLiti":
            hz_sharp = "华文隶书";
            break;
        case "STXingkai":
            hz_sharp = "华文行楷";
            break;
        case "STXinwei":
            hz_sharp = "华文新魏";
            break;
        case "simHei":
            hz_sharp = "黑体";
            break;
        case "simSun":
            hz_sharp = "宋体";
            break;
        case "NSimSun":
            hz_sharp = "新宋体";
            break;
        case "FangSong":
            hz_sharp = "仿宋";
            break;
        case "KaiTi":
            hz_sharp = "楷体";
            break;
        case "FangSong_GB2312":
            hz_sharp = "仿宋_GB2312";
            break;
        case "KaiTi_GB2312":
            hz_sharp = "楷体_GB2312";
            break;
        case "LiSu":
            hz_sharp = "隶书";
            break;
        case "YouYuan":
            hz_sharp = "幼圆";
            break;
        case "PMingLiU":
            hz_sharp = "新细明体";
            break;
        case "MingLiU":
            hz_sharp = "细明体";
            break;
        case "DFKai-SB":
            hz_sharp = "标楷体";
            break;
        case "Microsoft JhengHei":
            hz_sharp = "微软正黑体";
            break;
        case "Microsoft YaHei":
            hz_sharp = "微软雅黑体";
            break;
        default:
            hz_sharp = dropdown_lcd12864_hz_sharp;
            break;
    }
    hz_sharp = "字体：" + hz_sharp + "  字号：" + text_lcd12864_hz_line_height + "px" + "  显示文字：" + value_lcd12864_hz_data;


    var modulus_array = new Array();
    for (var i = 0; i < fontSize_height; i++) {
        modulus_array[i] = new Array();
        for (var j = 0; j < bs * 8; j++) {
            modulus_array[i][j] = "";
        }
    }

    for (var i = 1; i <= fontSize_height; i++) {
        for (var j = 1; j <= bs * 8; j++) {
            modulus_array[i - 1][j - 1] = outstr1.charAt((i - 1) * bs * 8 + j - 1);
        }
    }

    var bit_num = fontSize_height * bs;
    var modulus_data = "";
    var array_x = 0;
    var array_y = 0;
    var modulus_y = Math.ceil(fontSize_height / 8);
    var modulus_x = Math.ceil(fontSize_width / 8);

    bit_num = modulus_x * fontSize_height;
    for (var j = 1; j <= bit_num; j++) {
        for (var i = 1; i <= 8; i++) {
            if (j % modulus_x == 0)
                array_x = (modulus_x - 1) * 8 + i - 1;
            else
                array_x = (j % modulus_x - 1) * 8 + i - 1;
            array_y = Math.ceil(j / modulus_x) - 1;
            modulus_data += modulus_array[array_y][array_x];
        }
        modulus_data += ",";
    }

    var now_data = "";
    var end_data = "";

    for (var i of modulus_data) {
        if (i == ",") {
            end_data += now_data;
            end_data += ",";
            now_data = "";
        }
        else
            now_data = i + now_data;
    }
    modulus_data = end_data;

    now_data = "";
    end_data = "0x";
    for (var i of modulus_data) {
        if (i == ",") {
            end_data += ",0x";
            continue;
        }
        now_data += i;
        if (now_data.length == 4) {
            end_data += string_Bin_to_Hex(now_data);
            now_data = "";
        }
    }
    modulus_data = end_data;
    modulus_data = modulus_data.substring(0, modulus_data.length - 3);

    if (checkbox_lcd12864_show_hz) {
        if (checkbox_lcd12864_show_hz_save) {
            Blockly.Arduino.definitions_['var_declare_lcd12864_' + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data)] = HZ_image + "\n//" + hz_sharp + "\nstatic const unsigned char PROGMEM lcd12864_" + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data) + "[" + (bs * fontSize_height) + "]={" + modulus_data + "};";
        }
        else {
            Blockly.Arduino.definitions_['var_declare_lcd12864_' + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data)] = HZ_image + "\n//" + hz_sharp + "\nunsigned char lcd12864_" + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data) + "[" + (bs * fontSize_height) + "]={" + modulus_data + "};";
        }
    }
    else {
        if (checkbox_lcd12864_show_hz_message) {
            if (checkbox_lcd12864_show_hz_save) {
                Blockly.Arduino.definitions_['var_declare_lcd12864_' + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data)] = "//" + hz_sharp + "\nstatic const unsigned char PROGMEM lcd12864_" + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data) + "[" + (bs * fontSize_height) + "]={" + modulus_data + "};";
            }
            else {
                Blockly.Arduino.definitions_['var_declare_lcd12864_' + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data)] = "//" + hz_sharp + "\nunsigned char lcd12864_" + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data) + "[" + (bs * fontSize_height) + "]={" + modulus_data + "};";
            }
        }
        else {
            if (checkbox_lcd12864_show_hz_save) {
                Blockly.Arduino.definitions_['var_declare_lcd12864_' + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data)] = "static const unsigned char PROGMEM lcd12864_" + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data) + "[" + (bs * fontSize_height) + "]={" + modulus_data + "};";
            }
            else {
                Blockly.Arduino.definitions_['var_declare_lcd12864_' + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data)] = "unsigned char lcd12864_" + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data) + "[" + (bs * fontSize_height) + "]={" + modulus_data + "};";
            }
        }
    }
    if (checkbox_lcd12864_show_hz_message) {
        var code = '//绘制位图 ' + hz_sharp + '  X坐标：' + value_lcd12864_hz_x + '  Y坐标：' + value_lcd12864_hz_y + '  位图宽度：' + value_lcd12864_hz_width + '  位图高度：' + value_lcd12864_hz_height + '\n' + text_lcd12864_name + '.drawXBMP(' + value_lcd12864_hz_x + ', ' + value_lcd12864_hz_y + ', ' + value_lcd12864_hz_width + ', ' + value_lcd12864_hz_height + ', lcd12864_' + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data) + ');\n';
    }
    else {
        var code = text_lcd12864_name + '.drawXBMP(' + value_lcd12864_hz_x + ', ' + value_lcd12864_hz_y + ', ' + value_lcd12864_hz_width + ', ' + value_lcd12864_hz_height + ', lcd12864_' + dropdown_lcd12864_hz_sharp + '_' + text_lcd12864_hz_line_height + 'px' + encodeUnicode(value_lcd12864_hz_data) + ');\n';
    }
    return code;
};

//LCD12864设置字体
Blockly.Arduino.forBlock['make_arduino_lcd12864_setFont'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var dropdown_font_type = this.getFieldValue('font_type');
    var dropdown_font_size = this.getFieldValue('font_size');
    var dropdown_font_type1 = this.getFieldValue('font_type1');
    var code = '' + text_lcd12864_name + '.setFont(u8g2_font_' + dropdown_font_type + dropdown_font_type1 + dropdown_font_size + '_tf);\n'
        + '' + text_lcd12864_name + '.setFontPosTop();\n';
    return code;
};

//LCD12864设置光标位置
Blockly.Arduino.forBlock['make_arduino_lcd12864_setCursor'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var value_x = Blockly.Arduino.valueToCode(this, 'x', Blockly.Arduino.ORDER_ATOMIC);
    var value_y = Blockly.Arduino.valueToCode(this, 'y', Blockly.Arduino.ORDER_ATOMIC);

    var code = '' + text_lcd12864_name + '.setCursor(' + value_x + ', ' + value_y + ');\n';
    return code;
};

//LCD12864显示文本
Blockly.Arduino.forBlock['make_arduino_lcd12864_print'] = function () {
    var value_print_data = Blockly.Arduino.valueToCode(this, 'print_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var code = '' + text_lcd12864_name + '.print(' + value_print_data + ');\n';
    return code;
};

//LCD12864清屏
Blockly.Arduino.forBlock['make_arduino_lcd12864_clearDisplay'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var code = '' + text_lcd12864_name + '.clearDisplay();\n';
    return code;
};

//LCD12864设置背光亮度
Blockly.Arduino.forBlock['make_arduino_lcd12864_setContrast'] = function () {
    var value_set_data = Blockly.Arduino.valueToCode(this, 'set_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var code = '' + text_lcd12864_name + '.setContrast(' + value_set_data + ');\n';
    return code;
};

//LCD12864绘制位图
Blockly.Arduino.forBlock['make_arduino_lcd12864_drawXBMP'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var value_x = Blockly.Arduino.valueToCode(this, 'x', Blockly.Arduino.ORDER_ATOMIC);
    var value_y = Blockly.Arduino.valueToCode(this, 'y', Blockly.Arduino.ORDER_ATOMIC);
    var value_width = Blockly.Arduino.valueToCode(this, 'width', Blockly.Arduino.ORDER_ATOMIC);
    var value_height = Blockly.Arduino.valueToCode(this, 'height', Blockly.Arduino.ORDER_ATOMIC);
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_lcd12864_name + '.drawXBMP(' + value_x + ', ' + value_y + ', ' + value_width + ', ' + value_height + ', ' + value_data + ');\n';
    return code;
};

//LCD12864画点
Blockly.Arduino.forBlock['make_arduino_lcd12864_drawPixel'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var value_x = Blockly.Arduino.valueToCode(this, 'x', Blockly.Arduino.ORDER_ATOMIC);
    var value_y = Blockly.Arduino.valueToCode(this, 'y', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_lcd12864_name + '.drawPixel(' + value_x + ', ' + value_y + ');\n';
    return code;
};

//LCD12864画线
Blockly.Arduino.forBlock['make_arduino_lcd12864_drawLine'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var value_x1 = Blockly.Arduino.valueToCode(this, 'x1', Blockly.Arduino.ORDER_ATOMIC);
    var value_y1 = Blockly.Arduino.valueToCode(this, 'y1', Blockly.Arduino.ORDER_ATOMIC);
    var value_x2 = Blockly.Arduino.valueToCode(this, 'x2', Blockly.Arduino.ORDER_ATOMIC);
    var value_y2 = Blockly.Arduino.valueToCode(this, 'y2', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_lcd12864_name + '.drawLine(' + value_x1 + ', ' + value_y1 + ', ' + value_x2 + ', ' + value_y2 + ');\n';
    return code;
};

//LCD12864画水平线和垂直线
Blockly.Arduino.forBlock['make_arduino_lcd12864_drawLine1'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var dropdown_draw_type = this.getFieldValue('draw_type');
    var value_x = Blockly.Arduino.valueToCode(this, 'x', Blockly.Arduino.ORDER_ATOMIC);
    var value_y = Blockly.Arduino.valueToCode(this, 'y', Blockly.Arduino.ORDER_ATOMIC);
    var value_length = Blockly.Arduino.valueToCode(this, 'length', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_lcd12864_name + '.' + dropdown_draw_type + '(' + value_x + ', ' + value_y + ', ' + value_length + ');\n';
    return code;
};

//LCD12864画矩形
Blockly.Arduino.forBlock['make_arduino_lcd12864_drawBox'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var dropdown_draw_type = this.getFieldValue('draw_type');
    var value_x = Blockly.Arduino.valueToCode(this, 'x', Blockly.Arduino.ORDER_ATOMIC);
    var value_y = Blockly.Arduino.valueToCode(this, 'y', Blockly.Arduino.ORDER_ATOMIC);
    var value_width = Blockly.Arduino.valueToCode(this, 'width', Blockly.Arduino.ORDER_ATOMIC);
    var value_height = Blockly.Arduino.valueToCode(this, 'height', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_lcd12864_name + '.' + dropdown_draw_type + '(' + value_x + ', ' + value_y + ', ' + value_width + ', ' + value_height + ');\n';
    return code;
};

//LCD12864画圆角矩形
Blockly.Arduino.forBlock['make_arduino_lcd12864_drawRBox'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var dropdown_draw_type = this.getFieldValue('draw_type');
    var value_x = Blockly.Arduino.valueToCode(this, 'x', Blockly.Arduino.ORDER_ATOMIC);
    var value_y = Blockly.Arduino.valueToCode(this, 'y', Blockly.Arduino.ORDER_ATOMIC);
    var value_width = Blockly.Arduino.valueToCode(this, 'width', Blockly.Arduino.ORDER_ATOMIC);
    var value_height = Blockly.Arduino.valueToCode(this, 'height', Blockly.Arduino.ORDER_ATOMIC);
    var value_r = Blockly.Arduino.valueToCode(this, 'r', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_lcd12864_name + '.' + dropdown_draw_type + '(' + value_x + ', ' + value_y + ', ' + value_width + ', ' + value_height + ', ' + value_r + ');\n';
    return code;
};

//LCD12864画圆
Blockly.Arduino.forBlock['make_arduino_lcd12864_drawCircle'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var dropdown_draw_type = this.getFieldValue('draw_type');
    var value_x = Blockly.Arduino.valueToCode(this, 'x', Blockly.Arduino.ORDER_ATOMIC);
    var value_y = Blockly.Arduino.valueToCode(this, 'y', Blockly.Arduino.ORDER_ATOMIC);
    var value_r = Blockly.Arduino.valueToCode(this, 'r', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_draw_type1 = this.getFieldValue('draw_type1');
    var code = '' + text_lcd12864_name + '.' + dropdown_draw_type + '(' + value_x + ', ' + value_y + ', ' + value_r + ', ' + dropdown_draw_type1 + ');\n';
    return code;
};

//LCD12864画椭圆
Blockly.Arduino.forBlock['make_arduino_lcd12864_drawEllipse'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var dropdown_draw_type = this.getFieldValue('draw_type');
    var value_x = Blockly.Arduino.valueToCode(this, 'x', Blockly.Arduino.ORDER_ATOMIC);
    var value_y = Blockly.Arduino.valueToCode(this, 'y', Blockly.Arduino.ORDER_ATOMIC);
    var value_x_r = Blockly.Arduino.valueToCode(this, 'x_r', Blockly.Arduino.ORDER_ATOMIC);
    var value_y_r = Blockly.Arduino.valueToCode(this, 'y_r', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_draw_type1 = this.getFieldValue('draw_type1');
    var code = '' + text_lcd12864_name + '.' + dropdown_draw_type + '(' + value_x + ', ' + value_y + ', ' + value_x_r + ', ' + value_y_r + ', ' + dropdown_draw_type1 + ');\n';
    return code;
};

//LCD12864画三角形
Blockly.Arduino.forBlock['make_arduino_lcd12864_drawTriangle'] = function () {
    var text_lcd12864_name = this.getFieldValue('lcd12864_name');
    var value_x1 = Blockly.Arduino.valueToCode(this, 'x1', Blockly.Arduino.ORDER_ATOMIC);
    var value_y1 = Blockly.Arduino.valueToCode(this, 'y1', Blockly.Arduino.ORDER_ATOMIC);
    var value_x2 = Blockly.Arduino.valueToCode(this, 'x2', Blockly.Arduino.ORDER_ATOMIC);
    var value_y2 = Blockly.Arduino.valueToCode(this, 'y2', Blockly.Arduino.ORDER_ATOMIC);
    var value_x3 = Blockly.Arduino.valueToCode(this, 'x3', Blockly.Arduino.ORDER_ATOMIC);
    var value_y3 = Blockly.Arduino.valueToCode(this, 'y3', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_lcd12864_name + '.drawTriangle(' + value_x1 + ', ' + value_y1 + ', ' + value_x2 + ', ' + value_y2 + ', ' + value_x3 + ', ' + value_y3 + ');\n';
    return code;
};
//初始化MAX7219八位数码管
Blockly.Arduino.forBlock['make_arduino_max7219_led_begin'] = function () {
    var text_max7219_name = this.getFieldValue('max7219_name');
    var value_din = Blockly.Arduino.valueToCode(this, 'din', Blockly.Arduino.ORDER_ATOMIC);
    var value_clk = Blockly.Arduino.valueToCode(this, 'clk', Blockly.Arduino.ORDER_ATOMIC);
    var value_cs = Blockly.Arduino.valueToCode(this, 'cs', Blockly.Arduino.ORDER_ATOMIC);
    var value_number = Blockly.Arduino.valueToCode(this, 'number', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_LedControl'] = '#include "LedControl.h"';
    Blockly.Arduino.definitions_['var_declare_max7219_led_' + text_max7219_name] = 'LedControl ' + text_max7219_name + '=LedControl(' + value_din + ', ' + value_clk + ', ' + value_cs + ', ' + value_number + ');';
    var code = '';
    return code;
};

//MAX7219八位数码管 获取连接的设备的数目
Blockly.Arduino.forBlock['make_arduino_max7219_led_getDeviceCount'] = function () {
    var text_max7219_name = this.getFieldValue('max7219_name');
    var code = text_max7219_name + '.getDeviceCount()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//MAX7219八位数码管 打开或关闭某个设备
Blockly.Arduino.forBlock['make_arduino_max7219_led_shutdown'] = function () {
    var text_max7219_name = this.getFieldValue('max7219_name');
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var value_status = Blockly.Arduino.valueToCode(this, 'status', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_max7219_name + '.shutdown(' + value_address + ', ' + value_status + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_max7219_led_shutdown_data'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//MAX7219八位数码管 调整一个设备的亮度和最大显示位数
Blockly.Arduino.forBlock['make_arduino_max7219_led_setScanLimit'] = function () {
    var text_max7219_name = this.getFieldValue('max7219_name');
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var value_limit = Blockly.Arduino.valueToCode(this, 'limit', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_limit_type = this.getFieldValue('limit_type');
    var code = text_max7219_name + '.' + dropdown_limit_type + '(' + value_address + ', ' + value_limit + ');\n';
    return code;
};

//MAX7219八位数码管 清除一个设备上所有显示数据
Blockly.Arduino.forBlock['make_arduino_max7219_led_clearDisplay'] = function () {
    var text_max7219_name = this.getFieldValue('max7219_name');
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_max7219_name + '.clearDisplay(' + value_address + ');\n';
    return code;
};

//MAX7219八位数码管 设置某个设备上一个点处LED的亮与灭
Blockly.Arduino.forBlock['make_arduino_max7219_led_setLed'] = function () {
    var text_max7219_name = this.getFieldValue('max7219_name');
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var value_row = Blockly.Arduino.valueToCode(this, 'row', Blockly.Arduino.ORDER_ATOMIC);
    var value_col = Blockly.Arduino.valueToCode(this, 'col', Blockly.Arduino.ORDER_ATOMIC);
    var value_state = Blockly.Arduino.valueToCode(this, 'state', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_max7219_name + '.setLed(' + value_address + ', ' + value_row + ', ' + value_col + ', ' + value_state + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_max7219_led_setLed_data'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_max7219_led_setRow_Column'] = function () {
    var text_max7219_name = this.getFieldValue('max7219_name');
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var value_x_y = Blockly.Arduino.valueToCode(this, 'x_y', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_x_y_type = this.getFieldValue('x_y_type');
    var value_x_y_state = Blockly.Arduino.valueToCode(this, 'state', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_max7219_name + '.' + dropdown_x_y_type + '(' + value_address + ', ' + value_x_y + ', ' + value_x_y_state + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_max7219_led'] = function () {
    var checkbox_led_no_0 = this.getFieldValue('led_no_0') == 'TRUE';
    var checkbox_led_1 = this.getFieldValue('led_1') == 'TRUE';
    var checkbox_led_1_1 = this.getFieldValue('led_1_1') == 'TRUE';
    var checkbox_led_6 = this.getFieldValue('led_6') == 'TRUE';
    var checkbox_led_no_1 = this.getFieldValue('led_no_1') == 'TRUE';
    var checkbox_led_no_2 = this.getFieldValue('led_no_2') == 'TRUE';
    var checkbox_led_2 = this.getFieldValue('led_2') == 'TRUE';
    var checkbox_led_6_1 = this.getFieldValue('led_6_1') == 'TRUE';
    var checkbox_led_no_3 = this.getFieldValue('led_no_3') == 'TRUE';
    var checkbox_led_no_4 = this.getFieldValue('led_no_4') == 'TRUE';
    var checkbox_led_2_1 = this.getFieldValue('led_2_1') == 'TRUE';
    var checkbox_led_no_10 = this.getFieldValue('led_no_10') == 'TRUE';
    var checkbox_led_7 = this.getFieldValue('led_7') == 'TRUE';
    var checkbox_led_7_1 = this.getFieldValue('led_7_1') == 'TRUE';
    var checkbox_led_5 = this.getFieldValue('led_5') == 'TRUE';
    var checkbox_led_no_5 = this.getFieldValue('led_no_5') == 'TRUE';
    var checkbox_led_no_6 = this.getFieldValue('led_no_6') == 'TRUE';
    var checkbox_led_3 = this.getFieldValue('led_3') == 'TRUE';
    var checkbox_led_5_1 = this.getFieldValue('led_5_1') == 'TRUE';
    var checkbox_led_no_7 = this.getFieldValue('led_no_7') == 'TRUE';
    var checkbox_led_no_8 = this.getFieldValue('led_no_8') == 'TRUE';
    var checkbox_led_3_1 = this.getFieldValue('led_3_1') == 'TRUE';
    var checkbox_led_no_9 = this.getFieldValue('led_no_9') == 'TRUE';
    var checkbox_led_4 = this.getFieldValue('led_4') == 'TRUE';
    var checkbox_led_4_1 = this.getFieldValue('led_4_1') == 'TRUE';
    var checkbox_led_0 = this.getFieldValue('led_0') == 'TRUE';

    this.setFieldValue("false", "led_no_0");
    this.setFieldValue("false", "led_no_1");
    this.setFieldValue("false", "led_no_2");
    this.setFieldValue("false", "led_no_3");
    this.setFieldValue("false", "led_no_4");
    this.setFieldValue("false", "led_no_5");
    this.setFieldValue("false", "led_no_6");
    this.setFieldValue("false", "led_no_7");
    this.setFieldValue("false", "led_no_8");
    this.setFieldValue("false", "led_no_9");
    this.setFieldValue("false", "led_no_10");

    var code = 'B';
    if (checkbox_led_0) {
        code += '1';
    }
    else {
        code += '0';
    }
    if (checkbox_led_1) {
        code += '1';
        this.setFieldValue("true", "led_1_1");
    }
    else {
        code += '0';
        this.setFieldValue("false", "led_1_1");
    }
    if (checkbox_led_2) {
        code += '1';
        this.setFieldValue("true", "led_2_1");
    }
    else {
        code += '0';
        this.setFieldValue("false", "led_2_1");
    }
    if (checkbox_led_3) {
        code += '1';
        this.setFieldValue("true", "led_3_1");
    }
    else {
        code += '0';
        this.setFieldValue("false", "led_3_1");
    }
    if (checkbox_led_4) {
        code += '1';
        this.setFieldValue("true", "led_4_1");
    }
    else {
        code += '0';
        this.setFieldValue("false", "led_4_1");
    }
    if (checkbox_led_5) {
        code += '1';
        this.setFieldValue("true", "led_5_1");
    }
    else {
        code += '0';
        this.setFieldValue("false", "led_5_1");
    }
    if (checkbox_led_6) {
        code += '1';
        this.setFieldValue("true", "led_6_1");
    }
    else {
        code += '0';
        this.setFieldValue("false", "led_6_1");
    }
    if (checkbox_led_7) {
        code += '1';
        this.setFieldValue("true", "led_7_1");
    }
    else {
        code += '0';
        this.setFieldValue("false", "led_7_1");
    }

    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//MAX7219八位数码管 让某个设备的某个数码管显示字节
Blockly.Arduino.forBlock['make_arduino_max7219_led_setDigit'] = function () {
    var text_max7219_name = this.getFieldValue('max7219_name');
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var value_digit = Blockly.Arduino.valueToCode(this, 'digit', Blockly.Arduino.ORDER_ATOMIC);
    var value_value = Blockly.Arduino.valueToCode(this, 'value', Blockly.Arduino.ORDER_ATOMIC);
    var value_dp = Blockly.Arduino.valueToCode(this, 'dp', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_max7219_name + '.setDigit(' + value_address + ', ' + value_digit + ', ' + value_value + ', ' + value_dp + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_max7219_led_byte'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//MAX7219八位数码管 让某个设备的某个数码管显示字符
Blockly.Arduino.forBlock['make_arduino_max7219_led_setChar'] = function () {
    var text_max7219_name = this.getFieldValue('max7219_name');
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var value_digit = Blockly.Arduino.valueToCode(this, 'digit', Blockly.Arduino.ORDER_ATOMIC);
    var value_value = Blockly.Arduino.valueToCode(this, 'value', Blockly.Arduino.ORDER_ATOMIC);
    var value_dp = Blockly.Arduino.valueToCode(this, 'dp', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_max7219_name + '.setChar(' + value_address + ', ' + value_digit + ', ' + value_value + ', ' + value_dp + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_max7219_led_char'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = '\'' + dropdown_type + '\'';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};
// TM16xx数码管显示库 - 代码生成器

// 全局变量用于存储模块名称（支持多个模块）
var tm16xxModules = {};
// 辅助函数：获取模块名称（支持多个模块）
function getTm16xxObjectName(block) {
  var moduleName = block.getFieldValue('MODULE_NAME');
  if (moduleName) {
    return moduleName;
  }
  return 'tm16xx_module';
}

// 辅助函数：获取芯片类型
function getTm16xxChipType(block) {
  var moduleName = block.getFieldValue('MODULE_NAME');
  if (moduleName && tm16xxModules[moduleName]) {
    return tm16xxModules[moduleName];
  }
  return null;
}

// 确保代码生成器函数被正确注册
function registerTm16xxGenerators() {
  if (typeof Blockly === 'undefined' || !Blockly.Arduino) {
    setTimeout(registerTm16xxGenerators, 100);
    return;
  }

  // 初始化TM16xx模块（完整版）
  Blockly.Arduino.forBlock['tm16xx_init'] = function(block) {
    var chipType = block.getFieldValue('CHIP_TYPE');
    var dioPin = block.getFieldValue('DIO_PIN');
    var clkPin = block.getFieldValue('CLK_PIN');
    var stbPin = block.getFieldValue('STB_PIN');
    var digits = block.getFieldValue('DIGITS');
    var moduleName = block.getFieldValue('MODULE_NAME') || 'tm16xx_module';
    
    // 添加必要的头文件
    Blockly.Arduino.definitions_['include_arduino'] = '#include <Arduino.h>';
    Blockly.Arduino.definitions_['include_' + chipType] = '#include <' + chipType + '.h>';
    
    // 根据芯片类型生成不同的对象声明
    var objectDeclaration;
    if (chipType === 'TM1650') {
      // TM1650只需要位数参数
      objectDeclaration = chipType + ' ' + moduleName + '(' + digits + ');';
    } else if (chipType === 'TM1637' || chipType === 'TM1640') {
      objectDeclaration = chipType + ' ' + moduleName + '(' + dioPin + ', ' + clkPin + ', ' + digits + ');';
    } else {
      objectDeclaration = chipType + ' ' + moduleName + '(' + dioPin + ', ' + clkPin + ', ' + stbPin + ', ' + digits + ');';
    }
    
    // 将对象声明添加到definitions中
    Blockly.Arduino.definitions_['tm16xx_object_' + moduleName] = objectDeclaration;
    
    // 添加初始化代码到setup
    if (chipType === 'TM1650') {
      // TM1650使用init()方法进行初始化
      Blockly.Arduino.setups_['setup_tm16xx_' + moduleName] = moduleName + '.init();';
    } else {
      Blockly.Arduino.setups_['setup_tm16xx_' + moduleName] = moduleName + '.setupDisplay(true, 7);';
    }
    
    // 存储模块名称
    tm16xxModules[moduleName] = chipType;
    
    return '';
  };



  // 显示文本
  Blockly.Arduino.forBlock['tm16xx_display_string'] = function(block) {
    var text = Blockly.Arduino.valueToCode(block, 'TEXT', Blockly.Arduino.ORDER_ATOMIC) || '""';
    
    // 使用辅助函数获取模块名称
    var objectName = getTm16xxObjectName(block);
    var chipType = getTm16xxChipType(block);
    
    // 根据芯片类型生成不同的代码
    var code = '';
    if (chipType === 'TM1650') {
      code += objectName + '.displayString(' + text + ');\n';
    } else {
      code += objectName + '.setDisplayToString(' + text + ');\n';
    }
    
    return code;
  };

  // 显示数字
  Blockly.Arduino.forBlock['tm16xx_display_number'] = function(block) {
    var number = Blockly.Arduino.valueToCode(block, 'NUMBER', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var dotPosition = block.getFieldValue('DOT_POSITION');
    
    // 使用辅助函数获取模块名称
    var objectName = getTm16xxObjectName(block);
    var chipType = getTm16xxChipType(block);
    
    // 根据芯片类型生成不同的代码
    var code = '';
    if (chipType === 'TM1650') {
      if (dotPosition === '0') {
        code += objectName + '.displayNumber(' + number + ');\n';
      } else {
        code += 'String numStr = String(' + number + ');\n';
        code += 'if (numStr.length() <= ' + dotPosition + ') {\n';
        code += '  numStr = "0" + numStr;\n';
        code += '}\n';
        code += objectName + '.displayString(numStr.substring(0, ' + dotPosition + ') + "." + numStr.substring(' + dotPosition + '));\n';
      }
    } else {
      if (dotPosition === '0') {
        code += objectName + '.setDisplayToDecNumber(' + number + ');\n';
      } else {
        code += objectName + '.setDisplayToDecNumber(' + number + ', _BV(' + dotPosition + '));\n';
      }
    }
    
    return code;
  };

  // 清空显示
  Blockly.Arduino.forBlock['tm16xx_clear_display'] = function(block) {
    // 使用辅助函数获取模块名称
    var objectName = getTm16xxObjectName(block);
    var chipType = getTm16xxChipType(block);
    
    // 根据芯片类型生成不同的代码
    var code = '';
    if (chipType === 'TM1650') {
      code += objectName + '.displayString("    ");\n';
    } else {
      code += objectName + '.clearDisplay();\n';
    }
    
    return code;
  };

  // 设置亮度
  Blockly.Arduino.forBlock['tm16xx_set_brightness'] = function(block) {
    var brightness = block.getFieldValue('BRIGHTNESS');
    
    // 使用辅助函数获取模块名称
    var objectName = getTm16xxObjectName(block);
    var chipType = getTm16xxChipType(block);
    
    // 根据芯片类型生成不同的代码
    var code = '';
    if (chipType === 'TM1650') {
      code += objectName + '.setBrightness(' + brightness + ');\n';
    } else {
      code += objectName + '.setupDisplay(true, ' + brightness + ');\n';
    }
    
    return code;
  };

  // 设置段码
  Blockly.Arduino.forBlock['tm16xx_set_segment'] = function(block) {
    var position = block.getFieldValue('POSITION');
    var segments = Blockly.Arduino.valueToCode(block, 'SEGMENTS', Blockly.Arduino.ORDER_ATOMIC) || '0';
    
    // 使用辅助函数获取模块名称
    var objectName = getTm16xxObjectName(block);
    
    return objectName + '.setSegments(' + segments + ', ' + position + ');\n';
  };

  // 获取按键状态
  Blockly.Arduino.forBlock['tm16xx_get_buttons'] = function(block) {
    // 使用辅助函数获取模块名称
    var objectName = getTm16xxObjectName(block);
    
    return [objectName + '.getButtons()', Blockly.Arduino.ORDER_ATOMIC];
  };

  // 判断某个按键是否被按下
  Blockly.Arduino.forBlock['tm16xx_is_button_pressed'] = function(block) {
    var button = block.getFieldValue('BUTTON');
    var buttonMask = Math.pow(2, button - 1);
    
    // 使用辅助函数获取模块名称
    var objectName = getTm16xxObjectName(block);
    
    return ['(' + objectName + '.getButtons() & ' + buttonMask + ') != 0', Blockly.Arduino.ORDER_EQUALITY];
  };

  // 显示时间
  Blockly.Arduino.forBlock['tm16xx_display_time'] = function(block) {
    var hour = Blockly.Arduino.valueToCode(block, 'HOUR', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var minute = Blockly.Arduino.valueToCode(block, 'MINUTE', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var showColon = block.getFieldValue('SHOW_COLON') === 'TRUE';
    
    // 使用辅助函数获取模块名称
    var objectName = getTm16xxObjectName(block);
    
    var code = '';
    code += 'int tm16xx_time = (' + hour + ') * 100 + (' + minute + ');\n';
    
    if (showColon) {
      code += objectName + '.setDisplayToDecNumber(tm16xx_time, _BV(4));\n';
    } else {
      code += objectName + '.setDisplayToDecNumber(tm16xx_time);\n';
    }
    
    return code;
  };
}

// 尝试立即注册代码生成器
registerTm16xxGenerators();

// 也尝试在窗口加载完成后注册
if (typeof window !== 'undefined') {
  window.addEventListener('load', registerTm16xxGenerators);
}


    // ==================== 初始化类积木 ====================
    
    // 初始化 SD 卡（自定义引脚）
    Blockly.Arduino.forBlock['sd_card_init_custom_pins'] = function() {
        var sdCs = Blockly.Arduino.valueToCode(this, 'CS', Blockly.Arduino.ORDER_ATOMIC) || '4';
        var sdMosi = Blockly.Arduino.valueToCode(this, 'MOSI', Blockly.Arduino.ORDER_ATOMIC) || '6';
        var sdMiso = Blockly.Arduino.valueToCode(this, 'MISO', Blockly.Arduino.ORDER_ATOMIC) || '7';
        var sdSck = Blockly.Arduino.valueToCode(this, 'SCK', Blockly.Arduino.ORDER_ATOMIC) || '5';
        // 检查是否已设置串口波特率，如果没有则自动添加
        var hasSerialBegin = false;
        for (var key in Blockly.Arduino.setups_) {
            if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
                hasSerialBegin = true;
                break;
            }
        }
        if (!hasSerialBegin) {
            Blockly.Arduino.setups_['setup_serial_auto'] = 'Serial.begin(115200);';
        }
        Blockly.Arduino.definitions_['include_sd'] = '#include <SD.h>';
        Blockly.Arduino.definitions_['include_spi'] = '#include <SPI.h>';

        Blockly.Arduino.definitions_['var_declare_sd_cspin'] = `const int SD_CS_PIN = ${sdCs};`;
        Blockly.Arduino.definitions_['var_declare_sd_pins'] = `const int SD_MOSI_PIN = ${sdMosi};\nconst int SD_MISO_PIN = ${sdMiso};\nconst int SD_SCK_PIN = ${sdSck};`;
        Blockly.Arduino.definitions_['var_declare_spi'] = 'SPIClass *spi = nullptr;';
        
        var spiHost = this.getFieldValue('SPI_HOST') || 'FSPI';

        Blockly.Arduino.setups_['setup_spi'] = `spi = new SPIClass(${spiHost});
  spi->begin(SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN, SD_CS_PIN);
  if (!SD.begin(SD_CS_PIN, *spi)) {
    Serial.println("SD卡初始化失败");
  }`;

        return '';
    };

    // 初始化 SD 卡（自定义引脚）- ESP8266专用
    Blockly.Arduino.forBlock['sd_card_init_custom_pins_esp8266'] = function() {
        var sdCs = Blockly.Arduino.valueToCode(this, 'CS', Blockly.Arduino.ORDER_ATOMIC) || '4';
        var sdMosi = Blockly.Arduino.valueToCode(this, 'MOSI', Blockly.Arduino.ORDER_ATOMIC) || '6';
        var sdMiso = Blockly.Arduino.valueToCode(this, 'MISO', Blockly.Arduino.ORDER_ATOMIC) || '7';
        var sdSck = Blockly.Arduino.valueToCode(this, 'SCK', Blockly.Arduino.ORDER_ATOMIC) || '5';
        // 检查是否已设置串口波特率，如果没有则自动添加
        var hasSerialBegin = false;
        for (var key in Blockly.Arduino.setups_) {
            if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
                hasSerialBegin = true;
                break;
            }
        }
        if (!hasSerialBegin) {
            Blockly.Arduino.setups_['setup_serial_auto'] = 'Serial.begin(115200);';
        }
        Blockly.Arduino.definitions_['include_sd'] = '#include <SD.h>';
        Blockly.Arduino.definitions_['include_spi'] = '#include <SPI.h>';

        Blockly.Arduino.definitions_['var_declare_sd_cspin'] = `const int SD_CS_PIN = ${sdCs};`;
        Blockly.Arduino.definitions_['var_declare_sd_pins'] = `const int SD_MOSI_PIN = ${sdMosi};\nconst int SD_MISO_PIN = ${sdMiso};\nconst int SD_SCK_PIN = ${sdSck};`;

        Blockly.Arduino.setups_['setup_sd_esp8266'] = `SPI.begin(SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN, SD_CS_PIN);
  if (!SD.begin(SD_CS_PIN)) {
    Serial.println("SD卡初始化失败");
  }`;

        return '';
    };

    // ==================== 文件操作类积木 ====================
    
    // 文件操作（打开并读取/写入）
    Blockly.Arduino.forBlock['sd_file_operation'] = function() {
        var operation = this.getFieldValue('OPERATION');
        var filename = Blockly.Arduino.valueToCode(this, 'FILENAME', Blockly.Arduino.ORDER_ATOMIC) || '"/test.txt"';
        
        Blockly.Arduino.definitions_['include_sd'] = '#include <SD.h>';
        Blockly.Arduino.definitions_['include_spi'] = '#include <SPI.h>';
        
        if (operation === 'READ') {
            // 读取模式：定义读取函数并返回文件内容
            var funcName = 'readSdFileContent';
            Blockly.Arduino.definitions_['function_' + funcName] = 
                'String ' + funcName + '(const char* filepath) {\n' +
                '  File f = SD.open(filepath, FILE_READ);\n' +
                '  if (!f) {\n' +
                '    Serial.println("打开文件失败：" + String(filepath));\n' +
                '    return "";\n' +
                '  }\n' +
                '  String content = "";\n' +
                '  while (f.available()) {\n' +
                '    content += (char)f.read();\n' +
                '  }\n' +
                '  f.close();\n' +
                '  return content;\n' +
                '}';
            
            var code = funcName + '(' + filename + ')';
            return [code, Blockly.Arduino.ORDER_ATOMIC];
        } else {
            // 写入模式：打开文件并写入数据
            var data = Blockly.Arduino.valueToCode(this, 'DATA', Blockly.Arduino.ORDER_ATOMIC) || '""';
            
            var funcName = 'writeSdFileContent';
            Blockly.Arduino.definitions_['function_' + funcName] = 
                'bool ' + funcName + '(const char* filepath, String data) {\n' +
                '  File f = SD.open(filepath, FILE_WRITE);\n' +
                '  if (!f) {\n' +
                '    Serial.println("打开文件失败：" + String(filepath));\n' +
                '    return false;\n' +
                '  }\n' +
                '  f.print(data);\n' +
                '  f.close();\n' +
                '  return true;\n' +
                '}';
            
            return funcName + '(' + filename + ', ' + data + ');';
        }
    };
    
    // 关闭文件
    Blockly.Arduino.forBlock['sd_file_close'] = function() {
        var file = Blockly.Arduino.valueToCode(this, 'FILE', Blockly.Arduino.ORDER_ATOMIC) || 'file';
        
        return file + '.close();';
    };
    
    // ==================== 文件信息类积木 ====================
    
    // 检查文件是否存在
    Blockly.Arduino.forBlock['sd_file_exists'] = function() {
        var filename = Blockly.Arduino.valueToCode(this, 'FILENAME', Blockly.Arduino.ORDER_ATOMIC) || '"/test.txt"';
        
        var code = 'SD.exists(' + filename + ')';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };
    
    // 获取文件大小
    Blockly.Arduino.forBlock['sd_file_size'] = function() {
        var filename = Blockly.Arduino.valueToCode(this, 'FILENAME', Blockly.Arduino.ORDER_ATOMIC) || '"/test.txt"';
        
        var funcName = 'getSdFileSize';
        Blockly.Arduino.definitions_['function_' + funcName] = 
            'int ' + funcName + '(const char* filepath) {\n' +
            '  File f = SD.open(filepath, FILE_READ);\n' +
            '  if (!f) return -1;\n' +
            '  int size = f.size();\n' +
            '  f.close();\n' +
            '  return size;\n' +
            '}';
        
        var code = funcName + '(' + filename + ')';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };
    
    // ==================== 目录操作类积木 ====================
    
    // 创建目录
    Blockly.Arduino.forBlock['sd_mkdir'] = function() {
        var path = Blockly.Arduino.valueToCode(this, 'PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/mydir"';
        
        var code = 'if (!SD.mkdir(' + path + ')) {\n';
        code += '  Serial.println("创建目录失败：" + String(' + path + '));\n';
        code += '} else {\n';
        code += '  Serial.println("目录创建成功：" + String(' + path + '));\n';
        code += '}';
        
        return code;
    };
    
    // 删除文件
    Blockly.Arduino.forBlock['sd_remove'] = function() {
        var filename = Blockly.Arduino.valueToCode(this, 'FILENAME', Blockly.Arduino.ORDER_ATOMIC) || '"/test.txt"';
        
        var code = 'if (SD.remove(' + filename + ')) {\n';
        code += '  Serial.println("文件删除成功：" + String(' + filename + '));\n';
        code += '} else {\n';
        code += '  Serial.println("文件删除失败：" + String(' + filename + '));\n';
        code += '}';
        
        return code;
    };
    
    // 列出目录文件
    Blockly.Arduino.forBlock['sd_list_files'] = function() {
        var path = Blockly.Arduino.valueToCode(this, 'PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/"';
        
 
        
        var funcName = 'listDir';
        Blockly.Arduino.definitions_['function_' + funcName] = 
            'void ' + funcName + '(const char* dirname) {\n' +
            '  Serial.println(String("目录：") + dirname);\n' +
            '  File root = SD.open(dirname);\n' +
            '  if (!root || !root.isDirectory()) {\n' +
            '    Serial.println("无法打开目录");\n' +
            '    return;\n' +
            '  }\n' +
            '  File file = root.openNextFile();\n' +
            '  while (file) {\n' +
            '    if (file.isDirectory()) {\n' +
            '      Serial.print("  [目录] ");\n' +
            '    } else {\n' +
            '      Serial.print("  [文件] ");\n' +
            '    }\n' +
            '    Serial.println(file.name());\n' +
            '    file = root.openNextFile();\n' +
            '  }\n' +
            '  root.close();\n' +
            '  Serial.println("--- 列表结束 ---");\n' +
            '}';
        
        return funcName + '(' + path + ');';
    };
    
    // ==================== SD卡信息类积木 ====================
    
    // 获取SD卡信息
    Blockly.Arduino.forBlock['sd_card_info'] = function() {
        var infoType = this.getFieldValue('info_type');
        
        Blockly.Arduino.definitions_['include_sd'] = '#include <SD.h>';
        Blockly.Arduino.definitions_['include_spi'] = '#include <SPI.h>';
        Blockly.Arduino.definitions_['include_fs'] = '#include <FS.h>';
        
        var funcName = 'getSDCardInfo';
        Blockly.Arduino.definitions_['function_' + funcName] = 
            'float ' + funcName + '(String type) {\n' +
            '  if (type == "totalMB") {\n' +
            '    return SD.totalBytes() / (1024.0 * 1024.0);\n' +
            '  } else if (type == "usedMB") {\n' +
            '    return SD.usedBytes() / (1024.0 * 1024.0);\n' +
            '  } else if (type == "freeMB") {\n' +
            '    return (SD.totalBytes() - SD.usedBytes()) / (1024.0 * 1024.0);\n' +
            '  } else if (type == "totalGB") {\n' +
            '    return SD.totalBytes() / (1024.0 * 1024.0 * 1024.0);\n' +
            '  } else if (type == "usedGB") {\n' +
            '    return SD.usedBytes() / (1024.0 * 1024.0 * 1024.0);\n' +
            '  } else if (type == "freeGB") {\n' +
            '    return (SD.totalBytes() - SD.usedBytes()) / (1024.0 * 1024.0 * 1024.0);\n' +
            '  } else if (type == "rootFiles") {\n' +
            '    return countRootItems("files");\n' +
            '  } else if (type == "rootDirs") {\n' +
            '    return countRootItems("dirs");\n' +
            '  }\n' +
            '  return 0;\n' +
            '}';
        
        Blockly.Arduino.definitions_['function_countRootItems'] = 
            'int countRootItems(String type) {\n' +
            '  int count = 0;\n' +
            '  File root = SD.open("/");\n' +
            '  if (!root || !root.isDirectory()) {\n' +
            '    return -1;\n' +
            '  }\n' +
            '  File file = root.openNextFile();\n' +
            '  while (file) {\n' +
            '    if (type == "files" && !file.isDirectory()) {\n' +
            '      count++;\n' +
            '    } else if (type == "dirs" && file.isDirectory()) {\n' +
            '      count++;\n' +
            '    }\n' +
            '    file = root.openNextFile();\n' +
            '  }\n' +
            '  root.close();\n' +
            '  return count;\n' +
            '}';
        
        var code;
        if (infoType === 'cardType') {
            Blockly.Arduino.definitions_['function_getSDCardType'] = 
                'String getSDCardType() {\n' +
                '  uint8_t cardType = SD.cardType();\n' +
                '  if (cardType == CARD_NONE) return "未插入";\n' +
                '  if (cardType == CARD_MMC) return "MMC";\n' +
                '  if (cardType == CARD_SD) return "SDSC";\n' +
                '  if (cardType == CARD_SDHC) return "SDHC";\n' +
                '  return "未知";\n' +
                '}';
            code = 'getSDCardType()';
        } else if (infoType === 'mounted') {
            code = '(SD.cardType() != CARD_NONE)';
        } else {
            code = funcName + '("' + infoType + '")';
        }
        
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };




//初始化AT24Cxx储存器
Blockly.Arduino.forBlock['make_arduino_at24cxx_begin'] = function () {
    var value_at24cxx_begin_data = Blockly.Arduino.valueToCode(this, 'at24cxx_begin_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_at24cxx_begin_type = this.getFieldValue('at24cxx_begin_type');
    var text_at24cxx_name = this.getFieldValue('at24cxx_name');

    Blockly.Arduino.definitions_['include_AH_24Cxx'] = '#include <AH_24Cxx.h>';
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';

    if (dropdown_at24cxx_begin_type == "AT24C01") {
        Blockly.Arduino.definitions_['var_declare_AH_24Cxx_' + text_at24cxx_name] = '#define AT24C01  0\n' + 'AH_24Cxx ' + text_at24cxx_name + ' = AH_24Cxx(' + dropdown_at24cxx_begin_type + ', ' + value_at24cxx_begin_data + ');';
    }
    else if (dropdown_at24cxx_begin_type == "AT24C02") {
        Blockly.Arduino.definitions_['var_declare_AH_24Cxx_' + text_at24cxx_name] = '#define AT24C02  1\n' + 'AH_24Cxx ' + text_at24cxx_name + ' = AH_24Cxx(' + dropdown_at24cxx_begin_type + ', ' + value_at24cxx_begin_data + ');';
    }
    else if (dropdown_at24cxx_begin_type == "AT24C04") {
        Blockly.Arduino.definitions_['var_declare_AH_24Cxx_' + text_at24cxx_name] = '#define AT24C04  3\n' + 'AH_24Cxx ' + text_at24cxx_name + ' = AH_24Cxx(' + dropdown_at24cxx_begin_type + ', ' + value_at24cxx_begin_data + ');';
    }
    else if (dropdown_at24cxx_begin_type == "AT24C08") {
        Blockly.Arduino.definitions_['var_declare_AH_24Cxx_' + text_at24cxx_name] = '#define AT24C08  4\n' + 'AH_24Cxx ' + text_at24cxx_name + ' = AH_24Cxx(' + dropdown_at24cxx_begin_type + ', ' + value_at24cxx_begin_data + ');';
    }
    else if (dropdown_at24cxx_begin_type == "AT24C16") {
        Blockly.Arduino.definitions_['var_declare_AH_24Cxx_' + text_at24cxx_name] = '#define AT24C16  5\n' + 'AH_24Cxx ' + text_at24cxx_name + ' = AH_24Cxx(' + dropdown_at24cxx_begin_type + ', ' + value_at24cxx_begin_data + ');';
    }
    else if (dropdown_at24cxx_begin_type == "AT24C32") {
        Blockly.Arduino.definitions_['var_declare_AH_24Cxx_' + text_at24cxx_name] = '#define AT24C32  6\n' + 'AH_24Cxx ' + text_at24cxx_name + ' = AH_24Cxx(' + dropdown_at24cxx_begin_type + ', ' + value_at24cxx_begin_data + ');';
    }
    else if (dropdown_at24cxx_begin_type == "AT24C64") {
        Blockly.Arduino.definitions_['var_declare_AH_24Cxx_' + text_at24cxx_name] = '#define AT24C64  7\n' + 'AH_24Cxx ' + text_at24cxx_name + ' = AH_24Cxx(' + dropdown_at24cxx_begin_type + ', ' + value_at24cxx_begin_data + ');';
    }
    else if (dropdown_at24cxx_begin_type == "AT24C128") {
        Blockly.Arduino.definitions_['var_declare_AH_24Cxx_' + text_at24cxx_name] = '#define AT24C128  8\n' + 'AH_24Cxx ' + text_at24cxx_name + ' = AH_24Cxx(' + dropdown_at24cxx_begin_type + ', ' + value_at24cxx_begin_data + ');';
    }
    else if (dropdown_at24cxx_begin_type == "AT24C256") {
        Blockly.Arduino.definitions_['var_declare_AH_24Cxx_' + text_at24cxx_name] = '#define AT24C256  9\n' + 'AH_24Cxx ' + text_at24cxx_name + ' = AH_24Cxx(' + dropdown_at24cxx_begin_type + ', ' + value_at24cxx_begin_data + ');';
    }
    Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin();';
    var code = '';
    return code;
};

//AT24Cxx储存器写入数据
Blockly.Arduino.forBlock['make_arduino_at24cxx_write_byte'] = function () {
    var value_at24cxx_write_byte_data = Blockly.Arduino.valueToCode(this, 'at24cxx_write_byte_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_at24cxx_name = this.getFieldValue('at24cxx_name');
    var value_at24cxx_write_byte_address = Blockly.Arduino.valueToCode(this, 'at24cxx_write_byte_address', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_at24cxx_name + '.write_byte(' + value_at24cxx_write_byte_address + ', ' + value_at24cxx_write_byte_data + ');\n';
    return code;
};

//AT24Cxx储存器读取数据
Blockly.Arduino.forBlock['make_arduino_at24cxx_read_byte'] = function () {
    var value_at24cxx_read_byte_address = Blockly.Arduino.valueToCode(this, 'at24cxx_read_byte_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_at24cxx_name = this.getFieldValue('at24cxx_name');
    var code = text_at24cxx_name + '.read_byte(' + value_at24cxx_read_byte_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//AT24Cxx储存器写入数据(使用一个字节数组)
Blockly.Arduino.forBlock['make_arduino_at24cxx_write_page'] = function () {
    var value_at24cxx_write_page_data = Blockly.Arduino.valueToCode(this, 'at24cxx_write_page_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_at24cxx_name = this.getFieldValue('at24cxx_name');
    var value_at24cxx_write_page_address = Blockly.Arduino.valueToCode(this, 'at24cxx_write_page_address', Blockly.Arduino.ORDER_ATOMIC);
    var value_at24cxx_write_page_length = Blockly.Arduino.valueToCode(this, 'at24cxx_write_page_length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_at24cxx_name + '.write_page(' + value_at24cxx_write_page_address + ', ' + value_at24cxx_write_page_data + ', ' + value_at24cxx_write_page_length + ');\n';
    return code;
};

//AT24Cxx储存器读取数据，保存数据到一个数组
Blockly.Arduino.forBlock['make_arduino_at24cxx_read_buffer'] = function () {
    var value_at24cxx_read_buffer_address = Blockly.Arduino.valueToCode(this, 'at24cxx_read_buffer_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_at24cxx_name = this.getFieldValue('at24cxx_name');
    var value_at24cxx_read_buffer_length = Blockly.Arduino.valueToCode(this, 'at24cxx_read_buffer_length', Blockly.Arduino.ORDER_ATOMIC);
    var value_at24cxx_read_buffer_data = Blockly.Arduino.valueToCode(this, 'at24cxx_read_buffer_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_at24cxx_name + '.read_buffer(' + value_at24cxx_read_buffer_address + ', ' + value_at24cxx_read_buffer_data + ', ' + value_at24cxx_read_buffer_length + ');\n';
    return code;
};

//初始化AT24CXX存储器-1
Blockly.Arduino.forBlock['make_arduino_at24cx_begin_1'] = function () {
    this.setTooltip("初始化AT24CXX存储器");

    var value_at24cx_begin_address = Blockly.Arduino.valueToCode(this, 'at24cx_begin_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_at24cx_name = this.getFieldValue('at24cx_name');
    var value_at24cx_begin_pagesize = Blockly.Arduino.valueToCode(this, 'at24cx_begin_pagesize', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_AT24CX'] = '#include <AT24CX.h>';
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['var_declare_AH_24Cx_' + text_at24cx_name] = 'AT24CX ' + text_at24cx_name + '(' + value_at24cx_begin_address + ', ' + value_at24cx_begin_pagesize + ');';
    var code = '';
    return code;
};

//初始化AT24CXX存储器-1 使用软件模拟I2C
Blockly.Arduino.forBlock['make_arduino_at24cx_begin_1_Soft'] = function () {
    this.setTooltip("初始化AT24CXX存储器");

    var text_at24cx_name = this.getFieldValue('at24cxx_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var value_pagesize = Blockly.Arduino.valueToCode(this, 'pagesize', Blockly.Arduino.ORDER_ATOMIC);

    // 包含必要的库文件
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_AT24CX'] = '#include <AT24CX.h>';

    // 初始化Wire对象，指定SDA和SCL引脚
    Blockly.Arduino.setups_['setup_wire'] = 
        'Wire.begin(' + value_sda.replace(/"/g, '') + ', ' + value_scl.replace(/"/g, '') + ');';  

    // 声明并初始化AT24CX对象
    Blockly.Arduino.definitions_['var_declare_AH_24Cx_' + text_at24cx_name] = 'AT24CX ' + text_at24cx_name + '(' + value_address.replace(/"/g, '') + ', ' + value_pagesize.replace(/"/g, '') + ');';

    var code = '';
    return code;
};





//初始化AT24CXX存储器
Blockly.Arduino.forBlock['make_arduino_at24cx_begin'] = function () {
    this.setTooltip("初始化AT24CXX存储器");

    var value_at24cx_begin_data = Blockly.Arduino.valueToCode(this, 'at24cx_begin_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_at24cx_begin_type = this.getFieldValue('at24cx_begin_type');
    var text_at24cx_name = this.getFieldValue('at24cx_name');

    Blockly.Arduino.definitions_['include_AT24CX'] = '#include <AT24CX.h>';
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['var_declare_AH_24Cx_' + text_at24cx_name] = dropdown_at24cx_begin_type + ' ' + text_at24cx_name + '(' + value_at24cx_begin_data + ');';
    var code = '';
    return code;
};

//初始化AT24CXX存储器 使用软件模拟I2C
Blockly.Arduino.forBlock['make_arduino_at24cx_begin_soft'] = function () {
    this.setTooltip("初始化AT24CXX存储器");

    var dropdown_at24cx_begin_type = this.getFieldValue('at24cxx_begin_type');
    var text_at24cx_name = this.getFieldValue('at24cxx_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);

    if (dropdown_at24cx_begin_type == '1' || dropdown_at24cx_begin_type == '2')
        dropdown_at24cx_begin_type = '8';
    else if (dropdown_at24cx_begin_type == '4' || dropdown_at24cx_begin_type == '8' || dropdown_at24cx_begin_type == '16')
        dropdown_at24cx_begin_type = '16';
    else if (dropdown_at24cx_begin_type == '32' || dropdown_at24cx_begin_type == '64')
        dropdown_at24cx_begin_type = '32';
    else if (dropdown_at24cx_begin_type == '128' || dropdown_at24cx_begin_type == '256')
        dropdown_at24cx_begin_type = '64';
    else
        dropdown_at24cx_begin_type = '128';

    // 包含必要的库文件
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_AT24CX'] = '#include <AT24CX.h>';

    // 初始化Wire对象，指定SDA和SCL引脚
    Blockly.Arduino.setups_['setup_wire'] = 
        'Wire.begin(' + value_sda.replace(/"/g, '') + ', ' + value_scl.replace(/"/g, '') + ');';  

    // 声明并初始化AT24CX对象
    Blockly.Arduino.definitions_['var_declare_AH_24Cx_' + text_at24cx_name] = 'AT24CX ' + text_at24cx_name + '(' + value_address.replace(/"/g, '') + ', ' + dropdown_at24cx_begin_type + ');';

    var code = '';
    return code;
};




//AT24CXX存储器 地址
Blockly.Arduino.forBlock['make_arduino_at24cx_address'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//AT24CXX存储器 写入数值
Blockly.Arduino.forBlock['make_arduino_at24cx_write_data'] = function () {
    this.setTooltip("AT24CXX存储器 写入数值(字节、整数、长整数、单精度浮点数、双精度浮点数)");

    var value_at24cx_write_address = Blockly.Arduino.valueToCode(this, 'at24cx_write_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_at24cx_name = this.getFieldValue('at24cx_name');
    var dropdown_write_type = this.getFieldValue('write_type');
    var value_at24cx_write_data = Blockly.Arduino.valueToCode(this, 'at24cx_write_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_at24cx_name + '.' + dropdown_write_type + '(' + value_at24cx_write_address + ', ' + value_at24cx_write_data + ');\n';
    return code;
};

//AT24CXX存储器 写入数组
Blockly.Arduino.forBlock['make_arduino_at24cx_write_list'] = function () {
    this.setTooltip("AT24CXX存储器 写入数组(字节数组、字符数组)");

    var value_at24cx_write_address = Blockly.Arduino.valueToCode(this, 'at24cx_write_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_at24cx_name = this.getFieldValue('at24cx_name');
    var dropdown_write_type = this.getFieldValue('write_type');
    var value_at24cx_write_data = Blockly.Arduino.valueToCode(this, 'at24cx_write_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_at24cx_data_length = Blockly.Arduino.valueToCode(this, 'at24cx_data_length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_at24cx_name + '.' + dropdown_write_type + '(' + value_at24cx_write_address + ', ' + value_at24cx_write_data + ', ' + value_at24cx_data_length + ');\n';
    return code;
};

//AT24CXX存储器 读取数据
Blockly.Arduino.forBlock['make_arduino_at24cx_read_data'] = function () {
    this.setTooltip("AT24CXX存储器 读取数值(字节、整数、长整数、单精度浮点数、双精度浮点数)");
    var value_at24cx_read_address = Blockly.Arduino.valueToCode(this, 'at24cx_read_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_at24cx_name = this.getFieldValue('at24cx_name');
    var dropdown_read_type = this.getFieldValue('read_type');
    var code = text_at24cx_name + '.' + dropdown_read_type + '(' + value_at24cx_read_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//AT24CXX存储器 读取数组
Blockly.Arduino.forBlock['make_arduino_at24cx_read_list'] = function () {
    this.setTooltip("AT24CXX存储器 读取数组(字节数组、字符数组)");

    var value_at24cx_read_address = Blockly.Arduino.valueToCode(this, 'at24cx_read_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_at24cx_name = this.getFieldValue('at24cx_name');
    var dropdown_read_type = this.getFieldValue('read_type');
    var value_at24cx_read_data = Blockly.Arduino.valueToCode(this, 'at24cx_read_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_at24cx_data_length = Blockly.Arduino.valueToCode(this, 'at24cx_data_length', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_at24cx_name + '.' + dropdown_read_type + '(' + value_at24cx_read_address + ', ' + value_at24cx_read_data + ', ' + value_at24cx_data_length + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_bmp180_begin_i2c'] = function () {
    var value_bmp180_oversampling = Blockly.Arduino.valueToCode(this, 'bmp180_oversampling', Blockly.Arduino.ORDER_ATOMIC);
    var text_bmp180_name = this.getFieldValue('bmp180_name');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_BMP085'] = '#include <Adafruit_BMP085.h>';

    Blockly.Arduino.definitions_['var_declare_bmp180_' + text_bmp180_name] = 'Adafruit_BMP085 ' + text_bmp180_name + ';';

    Blockly.Arduino.setups_['setup_BMP180_' + text_bmp180_name] = text_bmp180_name + '.begin(' + value_bmp180_oversampling + ');';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_bmp180_begin_i2c_return_status'] = function () {
    var value_bmp180_oversampling = Blockly.Arduino.valueToCode(this, 'bmp180_oversampling', Blockly.Arduino.ORDER_ATOMIC);
    var text_bmp180_name = this.getFieldValue('bmp180_name');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_BMP085'] = '#include <Adafruit_BMP085.h>';

    Blockly.Arduino.definitions_['var_declare_bmp180_' + text_bmp180_name] = 'Adafruit_BMP085 ' + text_bmp180_name + ';';

    var code = text_bmp180_name + '.begin(' + value_bmp180_oversampling + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化BMP180大气压强传感器 使用软件模拟I2C
Blockly.Arduino.forBlock['make_arduino_bmp180_begin_i2c_soft'] = function () {
    var text_bmp180_name = this.getFieldValue('bmp180_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
    var value_oversampling = this.getFieldValue('oversampling'); // Assuming oversampling is a dropdown field

    // Include necessary libraries
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_BMP085'] = '#include <Adafruit_BMP085.h>';

    // Declare BMP180 object
    Blockly.Arduino.definitions_['var_declare_' + text_bmp180_name] = 'Adafruit_BMP085 ' + text_bmp180_name + ';';

    // Initialize Wire with specified SDA and SCL pins in setup
    var setup_code =
        'Wire.begin(' + value_sda + ', ' + value_scl + ');\n'

    Blockly.Arduino.setups_['setup_BMP180_' + text_bmp180_name] = setup_code;

    // Return the initialization status
    var code = text_bmp180_name + '.begin()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};


//BMP180大气压强传感器(I2C) 采样频率类型
Blockly.Arduino.forBlock['make_arduino_bmp180_oversampling'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_bmp180_get_temperature_pressure'] = function () {
    var text_bmp180_name = this.getFieldValue('bmp180_name');
    var dropdown_bmp180_get_temperature_pressure_data = this.getFieldValue('bmp180_get_temperature_pressure_data');
    var code = text_bmp180_name + '.read' + dropdown_bmp180_get_temperature_pressure_data + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_bmp180_get_altitude'] = function () {
    var text_bmp180_name = this.getFieldValue('bmp180_name');
    var value_bmp180_get_altitude_data = Blockly.Arduino.valueToCode(this, 'bmp180_get_altitude_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_bmp180_name + '.readAltitude(' + value_bmp180_get_altitude_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
Blockly.Arduino.forBlock['make_arduino_bmp280_begin_i2c'] = function() {
  var text_bmp280_name = this.getFieldValue('bmp280_name');

  Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
  Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
  Blockly.Arduino.definitions_['include_Adafruit_BMP280'] = '#include <Adafruit_BMP280.h>';

  Blockly.Arduino.definitions_['var_declare_bmp280_' + text_bmp280_name] = 'Adafruit_BMP280 '+text_bmp280_name+';';

  // 检查是否已设置串口波特率，如果没有则自动添加
  var hasSerialBegin = false;
  for (var key in Blockly.Arduino.setups_) {
      if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
          hasSerialBegin = true;
          break;
      }
  }
  if (!hasSerialBegin) {
      Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
  }
  Blockly.Arduino.setups_['setup_BMP280_' + text_bmp280_name] = 'if (!'+text_bmp280_name+'.begin()) {\n'
                                                             +'    Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));\n'
                                                             +'    while (1);\n'
                                                             +'  }\n'
                                                             +'\n'
                                                             +'  '+text_bmp280_name+'.setSampling(Adafruit_BMP280::MODE_NORMAL,\n'
                                                             +'                  Adafruit_BMP280::SAMPLING_X2,\n'
                                                             +'                  Adafruit_BMP280::SAMPLING_X16,\n'
                                                             +'                  Adafruit_BMP280::FILTER_X16,\n'
                                                             +'                  Adafruit_BMP280::STANDBY_MS_500);';
  
  var code = '';
  return code;
};
*/

Blockly.Arduino.forBlock['make_arduino_bmp280_begin_i2c'] = function () {
    var text_bmp280_name = this.getFieldValue('bmp280_name');
    var value_bmp280_address = Blockly.Arduino.valueToCode(this, 'bmp280_address', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    //Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['include_Adafruit_BMP280'] = '#include <Adafruit_BMP280.h>';

    Blockly.Arduino.definitions_['var_declare_bmp280_' + text_bmp280_name] = 'Adafruit_BMP280 ' + text_bmp280_name + ';';

    Blockly.Arduino.setups_['setup_BMP280_' + text_bmp280_name] = text_bmp280_name + '.begin(' + value_bmp280_address + ');\n'
        + '  ' + text_bmp280_name + '.setSampling(Adafruit_BMP280::MODE_NORMAL,\n'
        + '                  Adafruit_BMP280::SAMPLING_X2,\n'
        + '                  Adafruit_BMP280::SAMPLING_X16,\n'
        + '                  Adafruit_BMP280::FILTER_X16,\n'
        + '                  Adafruit_BMP280::STANDBY_MS_500);';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_bmp280_begin_i2c_return_status'] = function () {
    var text_bmp280_name = this.getFieldValue('bmp280_name');
    var value_bmp280_address = Blockly.Arduino.valueToCode(this, 'bmp280_address', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    //Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['include_Adafruit_BMP280'] = '#include <Adafruit_BMP280.h>';

    Blockly.Arduino.definitions_['var_declare_bmp280_' + text_bmp280_name] = 'Adafruit_BMP280 ' + text_bmp280_name + ';';

    Blockly.Arduino.setups_['setup_BMP280_' + text_bmp280_name] = text_bmp280_name + '.setSampling(Adafruit_BMP280::MODE_NORMAL,\n'
        + '                  Adafruit_BMP280::SAMPLING_X2,\n'
        + '                  Adafruit_BMP280::SAMPLING_X16,\n'
        + '                  Adafruit_BMP280::FILTER_X16,\n'
        + '                  Adafruit_BMP280::STANDBY_MS_500);';
    var code = text_bmp280_name + '.begin(' + value_bmp280_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_bmp280_begin_i2c_return_status'] = function () {
    var text_bmp280_name = this.getFieldValue('bmp280_name');
    var value_bmp280_address = Blockly.Arduino.valueToCode(this, 'bmp280_address', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    //Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['include_Adafruit_BMP280'] = '#include <Adafruit_BMP280.h>';

    Blockly.Arduino.definitions_['var_declare_bmp280_' + text_bmp280_name] = 'Adafruit_BMP280 ' + text_bmp280_name + ';';

    Blockly.Arduino.setups_['setup_BMP280_' + text_bmp280_name] = text_bmp280_name + '.setSampling(Adafruit_BMP280::MODE_NORMAL,\n'
        + '                  Adafruit_BMP280::SAMPLING_X2,\n'
        + '                  Adafruit_BMP280::SAMPLING_X16,\n'
        + '                  Adafruit_BMP280::FILTER_X16,\n'
        + '                  Adafruit_BMP280::STANDBY_MS_500);';
    var code = text_bmp280_name + '.begin(' + value_bmp280_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_bmp280_begin_i2c_soft'] = function () {
    var text_bmp280_name = this.getFieldValue('bmp280_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);

    // Include necessary libraries
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_BMP280'] = '#include <Adafruit_BMP280.h>';

    // Declare BMP280 object
    Blockly.Arduino.definitions_['var_declare_' + text_bmp280_name] = 'Adafruit_BMP280 ' + text_bmp280_name + ';';

    // Initialize Wire with SDA and SCL pins
    Blockly.Arduino.setups_['setup_wire_' + value_sda + '_' + value_scl] = 'Wire.begin(' + value_sda + ', ' + value_scl + ');';

    // Setup BMP280 sampling configuration
    Blockly.Arduino.setups_['setup_BMP280_sampling_' + text_bmp280_name] = text_bmp280_name + '.setSampling(Adafruit_BMP280::MODE_NORMAL,\n'
        + '                  Adafruit_BMP280::SAMPLING_X2,\n'
        + '                  Adafruit_BMP280::SAMPLING_X16,\n'
        + '                  Adafruit_BMP280::FILTER_X16,\n'
        + '                  Adafruit_BMP280::STANDBY_MS_500);';

    // Return the initialization status
    var code = text_bmp280_name + '.begin(' + value_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};





/*
Blockly.Arduino.forBlock['make_arduino_bmp280_begin_spi_1'] = function() {
  var text_bmp280_name = this.getFieldValue('bmp280_name');
  var value_bmp280_begin_spi_cs = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_cs', Blockly.Arduino.ORDER_ATOMIC);

  Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
  Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
  Blockly.Arduino.definitions_['include_Adafruit_BMP280'] = '#include <Adafruit_BMP280.h>';

  Blockly.Arduino.definitions_['var_declare_bmp280_' + text_bmp280_name] = 'Adafruit_BMP280 '+text_bmp280_name+'('+value_bmp280_begin_spi_cs+');';

  // 检查是否已设置串口波特率，如果没有则自动添加
  var hasSerialBegin = false;
  for (var key in Blockly.Arduino.setups_) {
      if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
          hasSerialBegin = true;
          break;
      }
  }
  if (!hasSerialBegin) {
      Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
  }
  Blockly.Arduino.setups_['setup_BMP280_' + text_bmp280_name] = 'if (!'+text_bmp280_name+'.begin()) {\n'
                                                             +'    Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));\n'
                                                             +'    while (1);\n'
                                                             +'  }\n'
                                                             +'\n'
                                                             +'  '+text_bmp280_name+'.setSampling(Adafruit_BMP280::MODE_NORMAL,\n'
                                                             +'                  Adafruit_BMP280::SAMPLING_X2,\n'
                                                             +'                  Adafruit_BMP280::SAMPLING_X16,\n'
                                                             +'                  Adafruit_BMP280::FILTER_X16,\n'
                                                             +'                  Adafruit_BMP280::STANDBY_MS_500);';
  
  var code = '';
  return code;
};
*/

Blockly.Arduino.forBlock['make_arduino_bmp280_begin_spi_1'] = function () {
    var text_bmp280_name = this.getFieldValue('bmp280_name');
    var value_bmp280_begin_spi_cs = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_cs', Blockly.Arduino.ORDER_ATOMIC);

    //Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['include_Adafruit_BMP280'] = '#include <Adafruit_BMP280.h>';

    Blockly.Arduino.definitions_['var_declare_bmp280_' + text_bmp280_name] = 'Adafruit_BMP280 ' + text_bmp280_name + '(' + value_bmp280_begin_spi_cs + ');';

    Blockly.Arduino.setups_['setup_BMP280_' + text_bmp280_name] = text_bmp280_name + '.begin();\n'
        + '  ' + text_bmp280_name + '.setSampling(Adafruit_BMP280::MODE_NORMAL,\n'
        + '                  Adafruit_BMP280::SAMPLING_X2,\n'
        + '                  Adafruit_BMP280::SAMPLING_X16,\n'
        + '                  Adafruit_BMP280::FILTER_X16,\n'
        + '                  Adafruit_BMP280::STANDBY_MS_500);';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_bmp280_begin_spi_1_return_status'] = function () {
    var text_bmp280_name = this.getFieldValue('bmp280_name');
    var value_bmp280_begin_spi_cs = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_cs', Blockly.Arduino.ORDER_ATOMIC);

    //Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['include_Adafruit_BMP280'] = '#include <Adafruit_BMP280.h>';

    Blockly.Arduino.definitions_['var_declare_bmp280_' + text_bmp280_name] = 'Adafruit_BMP280 ' + text_bmp280_name + '(' + value_bmp280_begin_spi_cs + ');';

    Blockly.Arduino.setups_['setup_BMP280_' + text_bmp280_name] = text_bmp280_name + '.setSampling(Adafruit_BMP280::MODE_NORMAL,\n'
        + '                Adafruit_BMP280::SAMPLING_X2,\n'
        + '                Adafruit_BMP280::SAMPLING_X16,\n'
        + '                Adafruit_BMP280::FILTER_X16,\n'
        + '                Adafruit_BMP280::STANDBY_MS_500);';

    var code = text_bmp280_name + '.begin()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
Blockly.Arduino.forBlock['make_arduino_bmp280_begin_spi_2'] = function() {
  var text_bmp280_name = this.getFieldValue('bmp280_name');
  var value_bmp280_begin_spi_cs = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_cs', Blockly.Arduino.ORDER_ATOMIC);
  var value_bmp280_begin_spi_mosi = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_mosi', Blockly.Arduino.ORDER_ATOMIC);
  var value_bmp280_begin_spi_miso = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_miso', Blockly.Arduino.ORDER_ATOMIC);
  var value_bmp280_begin_spi_sck = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_sck', Blockly.Arduino.ORDER_ATOMIC);

  Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
  Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
  Blockly.Arduino.definitions_['include_Adafruit_BMP280'] = '#include <Adafruit_BMP280.h>';

  Blockly.Arduino.definitions_['var_declare_bmp280_' + text_bmp280_name] = 'Adafruit_BMP280 '+text_bmp280_name+'('+value_bmp280_begin_spi_cs+', '+value_bmp280_begin_spi_mosi+', '+value_bmp280_begin_spi_miso+', '+value_bmp280_begin_spi_sck+');';

  // 检查是否已设置串口波特率，如果没有则自动添加
  var hasSerialBegin = false;
  for (var key in Blockly.Arduino.setups_) {
      if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
          hasSerialBegin = true;
          break;
      }
  }
  if (!hasSerialBegin) {
      Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
  }
  Blockly.Arduino.setups_['setup_BMP280_' + text_bmp280_name] = 'if (!'+text_bmp280_name+'.begin()) {\n'
                                                             +'    Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));\n'
                                                             +'    while (1);\n'
                                                             +'  }\n'
                                                             +'\n'
                                                             +'  '+text_bmp280_name+'.setSampling(Adafruit_BMP280::MODE_NORMAL,\n'
                                                             +'                  Adafruit_BMP280::SAMPLING_X2,\n'
                                                             +'                  Adafruit_BMP280::SAMPLING_X16,\n'
                                                             +'                  Adafruit_BMP280::FILTER_X16,\n'
                                                             +'                  Adafruit_BMP280::STANDBY_MS_500);';
  
  var code = '';
  return code;
};
*/

Blockly.Arduino.forBlock['make_arduino_bmp280_begin_spi_2'] = function () {
    var text_bmp280_name = this.getFieldValue('bmp280_name');
    var value_bmp280_begin_spi_cs = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_cs', Blockly.Arduino.ORDER_ATOMIC);
    var value_bmp280_begin_spi_mosi = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_mosi', Blockly.Arduino.ORDER_ATOMIC);
    var value_bmp280_begin_spi_miso = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_miso', Blockly.Arduino.ORDER_ATOMIC);
    var value_bmp280_begin_spi_sck = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_sck', Blockly.Arduino.ORDER_ATOMIC);

    //Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['include_Adafruit_BMP280'] = '#include <Adafruit_BMP280.h>';

    Blockly.Arduino.definitions_['var_declare_bmp280_' + text_bmp280_name] = 'Adafruit_BMP280 ' + text_bmp280_name + '(' + value_bmp280_begin_spi_cs + ', ' + value_bmp280_begin_spi_mosi + ', ' + value_bmp280_begin_spi_miso + ', ' + value_bmp280_begin_spi_sck + ');';

    Blockly.Arduino.setups_['setup_BMP280_' + text_bmp280_name] = text_bmp280_name + '.begin();\n'
        + '  ' + text_bmp280_name + '.setSampling(Adafruit_BMP280::MODE_NORMAL,\n'
        + '                  Adafruit_BMP280::SAMPLING_X2,\n'
        + '                  Adafruit_BMP280::SAMPLING_X16,\n'
        + '                  Adafruit_BMP280::FILTER_X16,\n'
        + '                  Adafruit_BMP280::STANDBY_MS_500);';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_bmp280_begin_spi_2_return_status'] = function () {
    var text_bmp280_name = this.getFieldValue('bmp280_name');
    var value_bmp280_begin_spi_cs = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_cs', Blockly.Arduino.ORDER_ATOMIC);
    var value_bmp280_begin_spi_mosi = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_mosi', Blockly.Arduino.ORDER_ATOMIC);
    var value_bmp280_begin_spi_miso = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_miso', Blockly.Arduino.ORDER_ATOMIC);
    var value_bmp280_begin_spi_sck = Blockly.Arduino.valueToCode(this, 'bmp280_begin_spi_sck', Blockly.Arduino.ORDER_ATOMIC);

    //Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['include_Adafruit_BMP280'] = '#include <Adafruit_BMP280.h>';

    Blockly.Arduino.definitions_['var_declare_bmp280_' + text_bmp280_name] = 'Adafruit_BMP280 ' + text_bmp280_name + '(' + value_bmp280_begin_spi_cs + ', ' + value_bmp280_begin_spi_mosi + ', ' + value_bmp280_begin_spi_miso + ', ' + value_bmp280_begin_spi_sck + ');';

    Blockly.Arduino.setups_['setup_BMP280_' + text_bmp280_name] = text_bmp280_name + '.setSampling(Adafruit_BMP280::MODE_NORMAL,\n'
        + '                  Adafruit_BMP280::SAMPLING_X2,\n'
        + '                  Adafruit_BMP280::SAMPLING_X16,\n'
        + '                  Adafruit_BMP280::FILTER_X16,\n'
        + '                  Adafruit_BMP280::STANDBY_MS_500);';

    var code = text_bmp280_name + '.begin()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_bmp280_get_temperature_pressure'] = function () {
    var text_bmp280_name = this.getFieldValue('bmp280_name');
    var dropdown_bmp280_get_temperature_pressure_data = this.getFieldValue('bmp280_get_temperature_pressure_data');
    var code = '' + text_bmp280_name + '.read' + dropdown_bmp280_get_temperature_pressure_data + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_bmp280_get_altitude'] = function () {
    var text_bmp280_name = this.getFieldValue('bmp280_name');
    var value_bmp280_get_altitude_data = Blockly.Arduino.valueToCode(this, 'bmp280_get_altitude_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_bmp280_name + '.readAltitude(' + value_bmp280_get_altitude_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_tcs230_begin_1'] = function () {
    var text_tcs230_name = this.getFieldValue('tcs230_name');
    var value_tcs230_s0 = Blockly.Arduino.valueToCode(this, 'tcs230_s0', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs230_s1 = Blockly.Arduino.valueToCode(this, 'tcs230_s1', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs230_s2 = Blockly.Arduino.valueToCode(this, 'tcs230_s2', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs230_s3 = Blockly.Arduino.valueToCode(this, 'tcs230_s3', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs230_led = Blockly.Arduino.valueToCode(this, 'tcs230_led', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs230_out = Blockly.Arduino.valueToCode(this, 'tcs230_out', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Color'] = '#include <Color.h>';

    Blockly.Arduino.definitions_['var_declare_tcs230_' + text_tcs230_name] = 'Color ' + text_tcs230_name + '((unsigned int[]) {' + value_tcs230_s0 + ', ' + value_tcs230_s1 + ', ' + value_tcs230_s2 + ', ' + value_tcs230_s3 + ', ' + value_tcs230_led + '}, ' + value_tcs230_out + ');';

    var code = '';
    return code;
};

//2019.10.5修改，保留原图形块
Blockly.Arduino.forBlock['make_arduino_tcs230_new_begin_1'] = function () {
    var value_tcs230_s0 = Blockly.Arduino.valueToCode(this, 'tcs230_s0', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs230_s1 = Blockly.Arduino.valueToCode(this, 'tcs230_s1', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs230_s2 = Blockly.Arduino.valueToCode(this, 'tcs230_s2', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs230_s3 = Blockly.Arduino.valueToCode(this, 'tcs230_s3', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs230_led = Blockly.Arduino.valueToCode(this, 'tcs230_led', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs230_out = Blockly.Arduino.valueToCode(this, 'tcs230_out', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['var_declare_tcs230_pin'] = '#define tcs230_S0 ' + value_tcs230_s0 + ''
        + '\n#define tcs230_S1 ' + value_tcs230_s1 + ''
        + '\n#define tcs230_S2 ' + value_tcs230_s2 + ''
        + '\n#define tcs230_S3 ' + value_tcs230_s3 + ''
        + '\n#define tcs230_sensorOut ' + value_tcs230_out + ''
        + '\n#define tcs230_LED ' + value_tcs230_led + '';

    Blockly.Arduino.definitions_['function_tcs230_Getcolor'] = '//TCS230颜色传感器获取RGB值'
        + '\nint tcs230_Getcolor(char data)'
        + '\n{'
        + '\n  int frequency = 0;'
        + '\n  switch(data)'
        + '\n  {'
        + '\n    case \'R\':'
        + '\n    {'
        + '\n      digitalWrite(tcs230_S2,LOW);'
        + '\n      digitalWrite(tcs230_S3,LOW);'
        + '\n      frequency = pulseIn(tcs230_sensorOut, LOW);'
        + '\n      frequency = map(frequency, 25, 72, 255, 0);'
        + '\n      break;'
        + '\n    }'
        + '\n    case \'G\':'
        + '\n    {'
        + '\n      digitalWrite(tcs230_S2,HIGH);'
        + '\n      digitalWrite(tcs230_S3,HIGH);'
        + '\n      frequency = pulseIn(tcs230_sensorOut, LOW);'
        + '\n      frequency = map(frequency, 30, 90, 255, 0);'
        + '\n      break;'
        + '\n    }'
        + '\n    case \'B\':'
        + '\n    {'
        + '\n      digitalWrite(tcs230_S2,LOW);'
        + '\n      digitalWrite(tcs230_S3,HIGH);'
        + '\n      frequency = pulseIn(tcs230_sensorOut, LOW);'
        + '\n      frequency = map(frequency, 25, 70, 255, 0);'
        + '\n      break;'
        + '\n    }'
        + '\n    default:'
        + '\n      return -1;'
        + '\n  }'
        + '\n  if (frequency < 0)'
        + '\n    frequency = 0;'
        + '\n  if (frequency > 255)'
        + '\n    frequency = 255;'
        + '\n  return frequency;'
        + '\n}\n';

    Blockly.Arduino.setups_['setup_tcs230_pin'] = 'pinMode(tcs230_S0, OUTPUT);'
        + '\n  pinMode(tcs230_S1, OUTPUT);'
        + '\n  pinMode(tcs230_S2, OUTPUT);'
        + '\n  pinMode(tcs230_S3, OUTPUT);'
        + '\n  pinMode(tcs230_LED, OUTPUT);'
        + '\n  pinMode(tcs230_sensorOut, INPUT);'
        + '\n  digitalWrite(tcs230_S0,HIGH);'
        + '\n  digitalWrite(tcs230_S1,LOW);'
        + '\n  digitalWrite(tcs230_LED,HIGH);';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_tcs230_get_color'] = function () {
    var text_tcs230_name = this.getFieldValue('tcs230_name');
    var dropdown_tcs230_color = this.getFieldValue('tcs230_color');
    var code = '' + text_tcs230_name + '.' + dropdown_tcs230_color + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_new_tcs230_get_color'] = function () {
    var dropdown_tcs230_color = this.getFieldValue('tcs230_color');
    var code = 'tcs230_Getcolor(\'' + dropdown_tcs230_color + '\')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

/*
Blockly.Arduino.forBlock['make_arduino_tcs34725_begin'] = function() {
  var text_tcs34725_name = this.getFieldValue('tcs34725_name');

  Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
  Blockly.Arduino.definitions_['include_Adafruit_TCS34725'] = '#include "Adafruit_TCS34725.h"';

  Blockly.Arduino.definitions_['var_declare_tcs34725_' + text_tcs34725_name] = 'Adafruit_TCS34725 '+text_tcs34725_name+' = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_2_4MS, TCS34725_GAIN_1X);';

  // 检查是否已设置串口波特率，如果没有则自动添加
  var hasSerialBegin = false;
  for (var key in Blockly.Arduino.setups_) {
      if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
          hasSerialBegin = true;
          break;
      }
  }
  if (!hasSerialBegin) {
      Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
  }
  Blockly.Arduino.setups_['setup_tcs34725_' + text_tcs34725_name] = 'if ('+text_tcs34725_name+'.begin()) {'
                                                                + '\n    Serial.println("发现TCS34725传感器");'
                                                                + '\n  } else {'
                                                                + '\n    Serial.println("未找到TCS34725，请检查连接");'
                                                                + '\n    while (1);'
                                                                + '\n  }';
  var code = '';
  return code;
};
*/

/*
Blockly.Arduino.forBlock['make_arduino_tcs34725_begin'] = function() {
  var text_tcs34725_name = this.getFieldValue('tcs34725_name');

  Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
  Blockly.Arduino.definitions_['include_Adafruit_TCS34725'] = '#include "Adafruit_TCS34725.h"';

  Blockly.Arduino.definitions_['var_declare_tcs34725_' + text_tcs34725_name] = 'Adafruit_TCS34725 '+text_tcs34725_name+' = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_2_4MS, TCS34725_GAIN_1X);';

  Blockly.Arduino.setups_['setup_tcs34725_' + text_tcs34725_name] = text_tcs34725_name+'.begin();';
  
  var code = '';
  return code;
};
*/

Blockly.Arduino.forBlock['make_arduino_tcs34725_begin'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var value_tcs34725_address = Blockly.Arduino.valueToCode(this, 'tcs34725_address', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_TCS34725'] = '#include "Adafruit_TCS34725.h"';

    Blockly.Arduino.definitions_['var_declare_tcs34725_' + text_tcs34725_name] = 'Adafruit_TCS34725 ' + text_tcs34725_name + ' = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_2_4MS, TCS34725_GAIN_1X);';

    Blockly.Arduino.setups_['setup_tcs34725_' + text_tcs34725_name] = text_tcs34725_name + '.begin(' + value_tcs34725_address + ');';

    var code = '';
    return code;
};

/*
Blockly.Arduino.forBlock['make_arduino_tcs34725_begin_1'] = function() {
  var text_tcs34725_name = this.getFieldValue('tcs34725_name');
  var dropdown_tcs34725_enable_delay = this.getFieldValue('tcs34725_enable_delay');
  var dropdown_tcs34725_gain = this.getFieldValue('tcs34725_gain');

  Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
  Blockly.Arduino.definitions_['include_Adafruit_TCS34725'] = '#include "Adafruit_TCS34725.h"';

  Blockly.Arduino.definitions_['var_declare_tcs34725_' + text_tcs34725_name] = 'Adafruit_TCS34725 '+text_tcs34725_name+' = Adafruit_TCS34725('+dropdown_tcs34725_enable_delay+', '+dropdown_tcs34725_gain+');';

  // 检查是否已设置串口波特率，如果没有则自动添加
  var hasSerialBegin = false;
  for (var key in Blockly.Arduino.setups_) {
      if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
          hasSerialBegin = true;
          break;
      }
  }
  if (!hasSerialBegin) {
      Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
  }
  Blockly.Arduino.setups_['setup_tcs34725_' + text_tcs34725_name] = 'if ('+text_tcs34725_name+'.begin()) {'
                                                                + '\n    Serial.println("Found sensor");'
                                                                + '\n  } else {'
                                                                + '\n    Serial.println("No TCS34725 found ... check your connections");'
                                                                + '\n    while (1);'
                                                                + '\n  }';
  var code = '';
  return code;
};
*/

Blockly.Arduino.forBlock['make_arduino_tcs34725_begin_1'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var dropdown_tcs34725_enable_delay = this.getFieldValue('tcs34725_enable_delay');
    var dropdown_tcs34725_gain = this.getFieldValue('tcs34725_gain');
    var value_tcs34725_address = Blockly.Arduino.valueToCode(this, 'tcs34725_address', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_TCS34725'] = '#include "Adafruit_TCS34725.h"';

    Blockly.Arduino.definitions_['var_declare_tcs34725_' + text_tcs34725_name] = 'Adafruit_TCS34725 ' + text_tcs34725_name + ' = Adafruit_TCS34725(' + dropdown_tcs34725_enable_delay + ', ' + dropdown_tcs34725_gain + ');';

    Blockly.Arduino.setups_['setup_tcs34725_' + text_tcs34725_name] = text_tcs34725_name + '.begin(' + value_tcs34725_address + ');';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_begin_2'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var dropdown_tcs34725_enable_delay = this.getFieldValue('tcs34725_enable_delay');
    var dropdown_tcs34725_gain = this.getFieldValue('tcs34725_gain');
    var value_tcs34725_address = Blockly.Arduino.valueToCode(this, 'tcs34725_address', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_TCS34725'] = '#include "Adafruit_TCS34725.h"';

    Blockly.Arduino.definitions_['var_declare_tcs34725_' + text_tcs34725_name] = 'Adafruit_TCS34725 ' + text_tcs34725_name + ' = Adafruit_TCS34725(' + dropdown_tcs34725_enable_delay + ', ' + dropdown_tcs34725_gain + ');';
    var code = text_tcs34725_name + '.begin(' + value_tcs34725_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化TCS34725颜色传感器 使用软件模拟I2C
Blockly.Arduino.forBlock['make_arduino_tcs34725_begin_Soft'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var dropdown_tcs34725_integration_time = this.getFieldValue('tcs34725_enable_delay'); // 注意这里使用 'tcs34725_enable_delay'
    var dropdown_tcs34725_gain = this.getFieldValue('tcs34725_gain');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');

    // Include necessary libraries
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_TCS34725'] = '#include "Adafruit_TCS34725.h"';

    // Map integration time dropdown to actual values
    var integrationTimeMap = {
        'TCS34725_INTEGRATIONTIME_2_4MS': 'TCS34725_INTEGRATIONTIME_2_4MS',
        'TCS34725_INTEGRATIONTIME_24MS': 'TCS34725_INTEGRATIONTIME_24MS',
        'TCS34725_INTEGRATIONTIME_50MS': 'TCS34725_INTEGRATIONTIME_50MS',
        'TCS34725_INTEGRATIONTIME_101MS': 'TCS34725_INTEGRATIONTIME_101MS',
        'TCS34725_INTEGRATIONTIME_154MS': 'TCS34725_INTEGRATIONTIME_154MS',
        'TCS34725_INTEGRATIONTIME_700MS': 'TCS34725_INTEGRATIONTIME_700MS'
    };

    var selectedIntegrationTime = integrationTimeMap[dropdown_tcs34725_integration_time];

    // Declare TCS34725 object with I2C address
    Blockly.Arduino.definitions_['var_declare_' + text_tcs34725_name] = 
        'Adafruit_TCS34725 ' + text_tcs34725_name + '(' + selectedIntegrationTime + ', ' + dropdown_tcs34725_gain + ');';

    // Initialize Wire with specified SDA and SCL pins in setup
    var setup_code =
        'Wire.begin(' + value_sda + ', ' + value_scl + ');' +
        '\n' + text_tcs34725_name + '.begin(' + value_address + ');';

    Blockly.Arduino.setups_['setup_TCS34725_' + text_tcs34725_name] = setup_code;

    // Return the initialization status
    var code = '';
    return code;
};




Blockly.Arduino.forBlock['make_arduino_tcs34725_set_integrationtime'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var dropdown_tcs34725_enable_delay = this.getFieldValue('tcs34725_enable_delay');
    var code = '' + text_tcs34725_name + '.setIntegrationTime(' + dropdown_tcs34725_enable_delay + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_set_gain'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var dropdown_tcs34725_gain = this.getFieldValue('tcs34725_gain');
    var code = '' + text_tcs34725_name + 'setGain(' + dropdown_tcs34725_gain + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_get_rawdata'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var value_tcs34725_get_r = Blockly.Arduino.valueToCode(this, 'tcs34725_get_r', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_get_g = Blockly.Arduino.valueToCode(this, 'tcs34725_get_g', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_get_b = Blockly.Arduino.valueToCode(this, 'tcs34725_get_b', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_get_c = Blockly.Arduino.valueToCode(this, 'tcs34725_get_c', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_tcs34725_name + '.getRawData(&' + value_tcs34725_get_r + ', &' + value_tcs34725_get_g + ', &' + value_tcs34725_get_b + ', &' + value_tcs34725_get_c + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_get_rgb'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var value_tcs34725_get_r = Blockly.Arduino.valueToCode(this, 'tcs34725_get_r', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_get_g = Blockly.Arduino.valueToCode(this, 'tcs34725_get_g', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_get_b = Blockly.Arduino.valueToCode(this, 'tcs34725_get_b', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_tcs34725_name + '.getRGB(&' + value_tcs34725_get_r + ', &' + value_tcs34725_get_g + ', &' + value_tcs34725_get_b + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_calculate_colortemperature'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var value_tcs34725_input_r = Blockly.Arduino.valueToCode(this, 'tcs34725_input_r', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_input_g = Blockly.Arduino.valueToCode(this, 'tcs34725_input_g', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_input_b = Blockly.Arduino.valueToCode(this, 'tcs34725_input_b', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_tcs34725_name + '.calculateColorTemperature(' + value_tcs34725_input_r + ', ' + value_tcs34725_input_g + ', ' + value_tcs34725_input_b + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_calculate_colortemperature_dn40'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var value_tcs34725_input_r = Blockly.Arduino.valueToCode(this, 'tcs34725_input_r', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_input_g = Blockly.Arduino.valueToCode(this, 'tcs34725_input_g', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_input_b = Blockly.Arduino.valueToCode(this, 'tcs34725_input_b', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_input_c = Blockly.Arduino.valueToCode(this, 'tcs34725_input_c', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_tcs34725_name + '.calculateColorTemperature_dn40(' + value_tcs34725_input_r + ', ' + value_tcs34725_input_g + ', ' + value_tcs34725_input_b + ', ' + value_tcs34725_input_c + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_calculate_lux'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var value_tcs34725_input_r = Blockly.Arduino.valueToCode(this, 'tcs34725_input_r', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_input_g = Blockly.Arduino.valueToCode(this, 'tcs34725_input_g', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_input_b = Blockly.Arduino.valueToCode(this, 'tcs34725_input_b', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_tcs34725_name + '.calculateLux(' + value_tcs34725_input_r + ', ' + value_tcs34725_input_g + ', ' + value_tcs34725_input_b + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_read8'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var dropdown_tcs34725_read8_data = this.getFieldValue('tcs34725_read8_data');
    var code = text_tcs34725_name + '.read8(' + dropdown_tcs34725_read8_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_read16'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var dropdown_tcs34725_read16_data = this.getFieldValue('tcs34725_read16_data');
    var code = '' + text_tcs34725_name + '.read16(' + dropdown_tcs34725_read16_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_set_interrupt'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var dropdown_tcs34725_set_interrupt_data = this.getFieldValue('tcs34725_set_interrupt_data');
    var code = '' + text_tcs34725_name + '.setInterrupt(' + dropdown_tcs34725_set_interrupt_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_clear_interrupt'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var code = '' + text_tcs34725_name + '.clearInterrupt();\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_set_intlimits_time'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var dropdown_tcs34725_set_intlimits_time_data = this.getFieldValue('tcs34725_set_intlimits_time_data');
    var code = text_tcs34725_name + '.write8(TCS34725_PERS, ' + dropdown_tcs34725_set_intlimits_time_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_set_intlimits'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var value_tcs34725_set_low_limit = Blockly.Arduino.valueToCode(this, 'tcs34725_set_low_limit', Blockly.Arduino.ORDER_ATOMIC);
    var value_tcs34725_set_high_limit = Blockly.Arduino.valueToCode(this, 'tcs34725_set_high_limit', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_tcs34725_name + '.setIntLimits(' + value_tcs34725_set_low_limit + ', ' + value_tcs34725_set_high_limit + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_tcs34725_enable_disable'] = function () {
    var text_tcs34725_name = this.getFieldValue('tcs34725_name');
    var dropdown_tcs34725_enable_disable_data = this.getFieldValue('tcs34725_enable_disable_data');
    var code = text_tcs34725_name + '.' + dropdown_tcs34725_enable_disable_data + '();\n';
    return code;
};

/*
Blockly.Arduino.forBlock['make_arduino_aht10_begin'] = function() {
  var value_aht10_begin_address = Blockly.Arduino.valueToCode(this, 'aht10_begin_address', Blockly.Arduino.ORDER_ATOMIC);
  var text_aht10_name = this.getFieldValue('aht10_name');

  Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
  Blockly.Arduino.definitions_['include_Thinary_AHT10'] = '#include <Thinary_AHT10.h>';

  Blockly.Arduino.definitions_['var_declare_aht10_' + text_aht10_name] = 'AHT10Class '+text_aht10_name+';';

  // 检查是否已设置串口波特率，如果没有则自动添加
  var hasSerialBegin = false;
  for (var key in Blockly.Arduino.setups_) {
      if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
          hasSerialBegin = true;
          break;
      }
  }
  if (!hasSerialBegin) {
      Blockly.Arduino.setups_['setup_serial_Serial9600'] = 'Serial.begin(9600);';
  }
  Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin();';
  Blockly.Arduino.setups_['setup_aht10_begin_' + text_aht10_name] = 'if('+text_aht10_name+'.begin('+value_aht10_begin_address+'))'
                                                                +'\n    Serial.println("AHT10初始化成功");'
                                                                +'\n  else'
                                                                +'\n    Serial.println("AHT10初始化失败");';

  var code = '';
  return code;
};
*/

Blockly.Arduino.forBlock['make_arduino_aht10_begin'] = function () {
    var value_aht10_begin_address = Blockly.Arduino.valueToCode(this, 'aht10_begin_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_aht10_name = this.getFieldValue('aht10_name');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Thinary_AHT10'] = '#include <Thinary_AHT10.h>';

    Blockly.Arduino.definitions_['var_declare_aht10_' + text_aht10_name] = 'AHT10Class ' + text_aht10_name + ';';

    Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin();';
    Blockly.Arduino.setups_['setup_aht10_begin_' + text_aht10_name] = text_aht10_name + '.begin(' + value_aht10_begin_address + ');';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_aht10_begin_1'] = function () {
    var value_aht10_begin_address = Blockly.Arduino.valueToCode(this, 'aht10_begin_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_aht10_name = this.getFieldValue('aht10_name');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Thinary_AHT10'] = '#include <Thinary_AHT10.h>';

    Blockly.Arduino.definitions_['var_declare_' + text_aht10_name] = 'AHT10Class ' + text_aht10_name + ';';

    //Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin();';

    var code = text_aht10_name + '.begin(' + value_aht10_begin_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化AHT10温湿度传感器 使用软件模拟I2C
Blockly.Arduino.forBlock['make_arduino_aht10_begin_Soft'] = function () {
    var text_name = this.getFieldValue('aht10_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);

    // Include necessary libraries
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Thinary_AHT10'] = '#include <Thinary_AHT10.h>';

    // Declare Wire and AHT10 objects
    Blockly.Arduino.setups_['setup_wire_' + value_sda + '_' + value_scl] = 'Wire.begin(' + value_sda + ', ' + value_scl + ');';
    Blockly.Arduino.definitions_['var_declare_' + text_name] = 'AHT10Class ' + text_name + ';';

    // Initialize AHT10 sensor with software I2C
    var setup_code = 
        text_name + '.begin(' + value_address + ');';
    Blockly.Arduino.setups_['setup_AHT10_' + text_name] = setup_code;

    // Return the initialization status
    var code = text_name + '.begin(' + value_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};




Blockly.Arduino.forBlock['make_arduino_aht10_get'] = function () {
    var text_aht10_name = this.getFieldValue('aht10_name');
    var dropdown_aht10_get_data = this.getFieldValue('aht10_get_data');
    var code = text_aht10_name + '.Get' + dropdown_aht10_get_data + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_aht10_read_status'] = function () {
    var text_aht10_name = this.getFieldValue('aht10_name');
    var code = text_aht10_name + '.readStatus()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};
// 合并后的AHT20模块
Blockly.Arduino.forBlock['make_arduino_aht20'] = function() {
    const name = this.getFieldValue('NAME');
    const value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    const value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    const value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);

    // 添加库引用和变量声明
    Blockly.Arduino.definitions_['include_wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_aht20'] = '#include <AHT20.h>';
    Blockly.Arduino.definitions_[`var_${name}`] = `AHT20 ${name}(${value_address || '0x38'});`;
    
    // 添加初始化代码
    Blockly.Arduino.setups_[`setup_${name}`] = `Wire.begin(${value_sda}, ${value_scl});`;
    Blockly.Arduino.setups_[`begin_${name}`] = `${name}.begin();`;
    return '';
};

Blockly.Arduino.forBlock['make_arduino_aht20_get_data'] = function(block) {
  const name = block.getFieldValue('NAME');
  const data_type = block.getFieldValue('data_type');
  let code;
  if (data_type === 'temperature') {
    code = `${name}.getTemperature()`;
  } else {
    code = `${name}.getHumidity()`;
  }
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_lm75_begin'] = function () {
    var text_lm75_name = this.getFieldValue('lm75_name');
    var value_lm75_i2c_A0 = Blockly.Arduino.valueToCode(this, 'lm75_i2c_A0', Blockly.Arduino.ORDER_ATOMIC);
    var value_lm75_i2c_A1 = Blockly.Arduino.valueToCode(this, 'lm75_i2c_A1', Blockly.Arduino.ORDER_ATOMIC);
    var value_lm75_i2c_A2 = Blockly.Arduino.valueToCode(this, 'lm75_i2c_A2', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_LM75A'] = '#include <LM75A.h>';
    Blockly.Arduino.definitions_['var_declare_LM75A_' + text_lm75_name] = 'LM75A ' + text_lm75_name + '(' + value_lm75_i2c_A0 + ', ' + value_lm75_i2c_A1 + ', ' + value_lm75_i2c_A2 + ');';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_lm75_begin_1'] = function () {
    var value_lm75_i2c_address = Blockly.Arduino.valueToCode(this, 'lm75_i2c_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_lm75_name = this.getFieldValue('lm75_name');

    Blockly.Arduino.definitions_['include_LM75A'] = '#include <LM75A.h>';
    /*
    if(value_lm75_i2c_address == '0x49')
      Blockly.Arduino.definitions_['var_declare_LM75A_' + text_lm75_name] = 'LM75A '+text_lm75_name+'(true, false, false);';
    else if(value_lm75_i2c_address == '0x4A')
      Blockly.Arduino.definitions_['var_declare_LM75A_' + text_lm75_name] = 'LM75A '+text_lm75_name+'(false, true, false);';
    else if(value_lm75_i2c_address == '0x4B')
      Blockly.Arduino.definitions_['var_declare_LM75A_' + text_lm75_name] = 'LM75A '+text_lm75_name+'(true, true, false);';
    else if(value_lm75_i2c_address == '0x4C')
      Blockly.Arduino.definitions_['var_declare_LM75A_' + text_lm75_name] = 'LM75A '+text_lm75_name+'(false, false, true);';
    else if(value_lm75_i2c_address == '0x4D')
      Blockly.Arduino.definitions_['var_declare_LM75A_' + text_lm75_name] = 'LM75A '+text_lm75_name+'(true, false, true);';
    else if(value_lm75_i2c_address == '0x4E')
      Blockly.Arduino.definitions_['var_declare_LM75A_' + text_lm75_name] = 'LM75A '+text_lm75_name+'(false, true, true);';
    else if(value_lm75_i2c_address == '0x4F')
      Blockly.Arduino.definitions_['var_declare_LM75A_' + text_lm75_name] = 'LM75A '+text_lm75_name+'(true, true, true);';
    else
      Blockly.Arduino.definitions_['var_declare_LM75A_' + text_lm75_name] = 'LM75A '+text_lm75_name+'(false, false, false);';
    */
    Blockly.Arduino.definitions_['var_declare_LM75A_' + text_lm75_name] = 'LM75A ' + text_lm75_name + '(' + value_lm75_i2c_address + ');';

    var code = '';
    return code;
};

//初始化LM75温度传感器 使用软件模拟I2C
Blockly.Arduino.forBlock['make_arduino_lm75_begin_soft'] = function () {
    var text_lm75_name = this.getFieldValue('lm75_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);

    // Include necessary libraries
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_LM75A'] = '#include <LM75A.h>';

    // Declare LM75 object
    Blockly.Arduino.definitions_['var_declare_' + text_lm75_name] = 'LM75A ' + text_lm75_name + '(' + value_address + ');';

    // Initialize Wire with specified SDA and SCL pins in setup
    var setup_code =
        'Wire.begin(' + value_sda + ', ' + value_scl + ');\n';
    Blockly.Arduino.setups_['setup_wire'] = setup_code;

    // Return the initialization status
    var code = '';
    return code;
};






Blockly.Arduino.forBlock['make_arduino_lm75_get_temp'] = function () {
    var text_lm75_name = this.getFieldValue('lm75_name');
    var dropdown_lm75_get_temp_type = this.getFieldValue('lm75_get_temp_type');
    var code = '' + text_lm75_name + '.' + dropdown_lm75_get_temp_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_lm75_get_temp_1'] = function () {
    var value_lm75_input_temp_data = Blockly.Arduino.valueToCode(this, 'lm75_input_temp_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_lm75_get_temp_type = this.getFieldValue('lm75_get_temp_type');

    Blockly.Arduino.definitions_['include_LM75A'] = '#include <LM75A.h>';

    var code = 'LM75A::' + dropdown_lm75_get_temp_type + '(' + value_lm75_input_temp_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化MCP9808温度传感器
Blockly.Arduino.forBlock['make_arduino_mcp9808_begin'] = function () {
    this.setTooltip("初始化MCP9808温度传感器，返回数据的类型为boolean");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    Blockly.Arduino.definitions_['include_' + 'Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_' + 'Adafruit_MCP9808'] = '#include "Adafruit_MCP9808.h"';
    Blockly.Arduino.definitions_['var_declare_' + text_name] = 'Adafruit_MCP9808 ' + text_name + ' = Adafruit_MCP9808();';
    var code = text_name + '.begin(' + value_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化MCP9808温度传感器(使用软件模拟I2C)
Blockly.Arduino.forBlock['make_arduino_mcp9808_begin_1'] = function () {
    this.setTooltip("初始化MCP9808温度传感器, 返回数据的类型为boolean");
    var text_name = this.getFieldValue('name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');

    // Include necessary libraries
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_MCP9808'] = '#include "Adafruit_MCP9808.h"';

    // Initialize Wire with specified SDA and SCL pins in setup
    Blockly.Arduino.setups_['setup_wire_' + value_sda + '_' + value_scl] = 
        'Wire.begin(' + value_sda + ', ' + value_scl + ');';

    // Declare MCP9808 object
    Blockly.Arduino.definitions_['var_declare_' + text_name] = 
        'Adafruit_MCP9808 ' + text_name + ';';

    // Begin initialization of MCP9808 sensor
    var code = text_name + '.begin(' + value_address + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};




//MCP9808温度传感器 设置测量分辨率
Blockly.Arduino.forBlock['make_arduino_mcp9808_setResolution'] = function () {
    this.setTooltip("MCP9808温度传感器 设置测量分辨率");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    var code = text_name + '.setResolution(' + value_data + ');\n';
    return code;
};

//MCP9808温度传感器 分辨率定义
Blockly.Arduino.forBlock['make_arduino_mcp9808_setResolution_data'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//MCP9808温度传感器 唤醒或休眠设备
Blockly.Arduino.forBlock['make_arduino_mcp9808_wake_shutdown'] = function () {
    this.setTooltip("MCP9808温度传感器 唤醒或休眠设备");
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_name + '.' + dropdown_type + '();\n';
    return code;
};

//MCP9808温度传感器 获取温度(℃或℉)和测量分辨率
Blockly.Arduino.forBlock['make_arduino_mcp9808_get_data'] = function () {
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    if (dropdown_type == 'readTempC')
        this.setTooltip("MCP9808温度传感器 获取温度(℃)，返回数据的类型为float");
    else if (dropdown_type == 'readTempF')
        this.setTooltip("MCP9808温度传感器 获取温度(℉)，返回数据的类型为float");
    else
        this.setTooltip("MCP9808温度传感器 获取测量分辨率，返回数据的类型为uint8_t");
    var code = text_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_sht30_begin'] = function () {
    var value_sht30_begin_address = Blockly.Arduino.valueToCode(this, 'sht30_begin_address', Blockly.Arduino.ORDER_ATOMIC);
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
    var name = this.getFieldValue('sht30_name') || 'sht30';

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';

    if (value_sda && value_scl) {
        var sda_pin = value_sda.replace(/"/g, '');
        var scl_pin = value_scl.replace(/"/g, '');
        Blockly.Arduino.setups_['setup_i2c_' + name] = 'Wire.begin(' + sda_pin + ', ' + scl_pin + ');';
    } else {
        Blockly.Arduino.setups_['setup_i2c_' + name] = 'Wire.begin();';
    }

    Blockly.Arduino.definitions_[`var_declare_${name}`] = `uint8_t ${name}_address = ${value_sht30_begin_address};`;

    Blockly.Arduino.definitions_[`function_${name}_get_data`] = `float ${name}_get_data(int data_type)`
        + '\n{'
        + '\n  unsigned int data[6];'
        + `\n  Wire.beginTransmission(${name}_address);`
        + '\n  Wire.write(0x2C);'
        + '\n  Wire.write(0x06);'
        + '\n  Wire.endTransmission();'
        + `\n  Wire.requestFrom((uint8_t)${name}_address, (uint8_t)6);`
        + '\n  if (Wire.available() == 6)'
        + '\n  {'
        + '\n    data[0] = Wire.read();'
        + '\n    data[1] = Wire.read();'
        + '\n    data[2] = Wire.read();'
        + '\n    data[3] = Wire.read();'
        + '\n    data[4] = Wire.read();'
        + '\n    data[5] = Wire.read();'
        + '\n  }'
        + '\n  switch (data_type)'
        + '\n  {'
        + '\n    case 0:'
        + '\n      return ((((data[0] * 256.0) + data[1]) * 175) / 65535.0) - 45;'
        + '\n    case 1:'
        + '\n      return ((((((data[0] * 256.0) + data[1]) * 175) / 65535.0) - 45) * 1.8) + 32;'
        + '\n    case 2:'
        + '\n      return ((((data[3] * 256.0) + data[4]) * 100) / 65535.0);'
        + '\n    default:'
        + '\n      return -1;'
        + '\n  }'
        + '\n}'
    ;
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_sht30_get_data'] = function () {
    var dropdown_sht30_get_data_type = this.getFieldValue('sht30_get_data_type');
    var name = this.getFieldValue('sht30_name');
    var code = `${name}_get_data(` + dropdown_sht30_get_data_type + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_mlx90614_begin'] = function () {
    var value_mlx90614_address = Blockly.Arduino.valueToCode(this, 'mlx90614_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_mlx90614_name = this.getFieldValue('mlx90614_name');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_MLX90614'] = '#include <Adafruit_MLX90614.h>';

    Blockly.Arduino.definitions_['var_declare_' + text_mlx90614_name] = 'Adafruit_MLX90614 ' + text_mlx90614_name + ' = Adafruit_MLX90614(' + value_mlx90614_address + ');';

    Blockly.Arduino.setups_['setup_MLX90614_' + text_mlx90614_name] = '' + text_mlx90614_name + '.begin();';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_mlx90614_begin_1'] = function () {
    var value_mlx90614_address = Blockly.Arduino.valueToCode(this, 'mlx90614_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_mlx90614_name = this.getFieldValue('mlx90614_name');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_MLX90614'] = '#include <Adafruit_MLX90614.h>';

    Blockly.Arduino.definitions_['var_declare_' + text_mlx90614_name] = 'Adafruit_MLX90614 ' + text_mlx90614_name + ' = Adafruit_MLX90614(' + value_mlx90614_address + ');';

    var code = '' + text_mlx90614_name + '.begin()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_mlx90614_begin_soft'] = function () {
    var text_mlx90614_name = this.getFieldValue('mlx90614_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_mlx90614_address = Blockly.Arduino.valueToCode(this, 'mlx90614_address', Blockly.Arduino.ORDER_ATOMIC);
    // Include necessary libraries
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_MLX90614'] = '#include <Adafruit_MLX90614.h>';

    // Initialize Wire with specified SDA and SCL pins in setup
    Blockly.Arduino.setups_['setup_wire_' + value_sda + '_' + value_scl] = 
        'Wire.begin(' + value_sda + ', ' + value_scl + ');';

    // Declare MLX90614 object
    Blockly.Arduino.definitions_['var_declare_' + text_mlx90614_name] = 
        'Adafruit_MLX90614 ' + text_mlx90614_name + '= Adafruit_MLX90614(' + value_mlx90614_address + ');';

    // Begin initialization of MLX90614 sensor
    var code = text_mlx90614_name + '.begin()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};




Blockly.Arduino.forBlock['make_arduino_mlx90614_get_data'] = function () {
    var text_mlx90614_name = this.getFieldValue('mlx90614_name');
    var dropdown_mlx90614_data = this.getFieldValue('mlx90614_data');
    var code = '' + text_mlx90614_name + '.' + dropdown_mlx90614_data + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_htu21d_begin'] = function () {
    var text_htu21d_name = this.getFieldValue('htu21d_name');

    Blockly.Arduino.definitions_['include_Adafruit_HTU21DF'] = '#include "Adafruit_HTU21DF.h"';

    Blockly.Arduino.definitions_['var_declare_' + text_htu21d_name] = 'Adafruit_HTU21DF ' + text_htu21d_name + ' = Adafruit_HTU21DF();';

    Blockly.Arduino.setups_['setup_HTU21DF_' + text_htu21d_name] = '' + text_htu21d_name + '.begin();';

    // 添加返回读取温湿度的代码
    var code = text_htu21d_name + '.readTemperature();\n' + 
               text_htu21d_name + '.readHumidity();\n';
    return code;
};

//初始化HTU21D温湿度传感器 使用软件模拟I2C
Blockly.Arduino.forBlock['make_arduino_htu21d_begin_soft'] = function () {
    var text_htu21d_name = this.getFieldValue('htu21d_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);

    // Include necessary libraries
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_HTU21DF'] = '#include "Adafruit_HTU21DF.h"';

    // Declare Wire and HTU21D objects
    Blockly.Arduino.setups_['setup_wire_' + value_sda + '_' + value_scl] = 'Wire.begin(' + value_sda + ', ' + value_scl + ');';
    Blockly.Arduino.definitions_['var_declare_' + text_htu21d_name] = 'Adafruit_HTU21DF ' + text_htu21d_name + ';';

    // Initialize HTU21D sensor with software I2C
    var setup_code =
        text_htu21d_name + '.begin();';
    Blockly.Arduino.setups_['setup_HTU21D_' + text_htu21d_name] = setup_code;

    // Return the initialization status
    var code = text_htu21d_name + '.begin()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_htu21d_get_data'] = function () {
    var text_htu21d_name = this.getFieldValue('htu21d_name');
    var dropdown_htu21d_get_data_type = this.getFieldValue('htu21d_get_data_type');
    var code = '' + text_htu21d_name + '.' + dropdown_htu21d_get_data_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};



Blockly.Arduino.forBlock['make_arduino_max6675_begin'] = function () {
    var text_max6675_name = this.getFieldValue('max6675_name');
    var value_max6675_clk = Blockly.Arduino.valueToCode(this, 'max6675_clk', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_max6675_cs = Blockly.Arduino.valueToCode(this, 'max6675_cs', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_max6675_so = Blockly.Arduino.valueToCode(this, 'max6675_so', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');

    // Include necessary libraries
    Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
    Blockly.Arduino.definitions_['include_max6675'] = '#include "max6675.h"';

    // Declare MAX6675 object
    Blockly.Arduino.definitions_['var_declare_' + text_max6675_name] = 
        'MAX6675 ' + text_max6675_name + '(' + value_max6675_clk + ', ' + value_max6675_cs + ', ' + value_max6675_so + ');';

    // Setup code to initialize SPI in setup function
    Blockly.Arduino.setups_['setup_spi'] = 'SPI.begin();';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_max6675_get_temperature'] = function () {
    var text_max6675_name = this.getFieldValue('max6675_name');
    var dropdown_max6675_get_type = this.getFieldValue('max6675_get_type');
    var code = '' + text_max6675_name + '.' + dropdown_max6675_get_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};


Blockly.Arduino.forBlock['make_arduino_describe'] = function(block) {

  return  ' //作  者 ： \n' +
  ' //回到  未来\n' +
  ' //QQ : 375091377\n';
};

    Blockly.Arduino.forBlock['make_arduino_dht20'] = function() {
        const name = this.getFieldValue('NAME');
        const value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
        const value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
        const value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);

        Blockly.Arduino.definitions_['include_wire'] = '#include <Wire.h>';
        Blockly.Arduino.definitions_['include_dht20'] = '#include <DFRobot_DHT20.h>';
        Blockly.Arduino.definitions_['var_declare_' + name] = 'DFRobot_DHT20 ' + name + '(&Wire, ' + (value_address || '0x38') + ');';
        
        Blockly.Arduino.setups_['setup_wire_' + name] = 'Wire.begin();';
        Blockly.Arduino.setups_['begin_' + name] = name + '.begin();';
        
        return '';
    };

    Blockly.Arduino.forBlock['make_arduino_dht20_get_data'] = function(block) {
        const name = block.getFieldValue('NAME');
        const data_type = block.getFieldValue('data_type');
        let code;
        if (data_type === 'temperature') {
            code = name + '.getTemperature()';
        } else {
            code = name + '.getHumidity()';
        }
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };


Blockly.Arduino.forBlock['make_arduino_bh1750_begin'] = function () {
    var value_bh1750_address = Blockly.Arduino.valueToCode(this, 'bh1750_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_bh1750_name = this.getFieldValue('bh1750_name');
    var dropdown_bh1750_mode = this.getFieldValue('bh1750_mode');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_BH1750'] = '#include <BH1750.h>';

    Blockly.Arduino.definitions_['var_declare_' + text_bh1750_name] = 'BH1750 ' + text_bh1750_name + '(' + value_bh1750_address + ');';

    Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin();';
    Blockly.Arduino.setups_['setup_bh1750_' + text_bh1750_name] = '' + text_bh1750_name + '.begin(BH1750::' + dropdown_bh1750_mode + ');';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_bh1750_begin_return_status'] = function () {
    var value_bh1750_address = Blockly.Arduino.valueToCode(this, 'bh1750_address', Blockly.Arduino.ORDER_ATOMIC);
    var text_bh1750_name = this.getFieldValue('bh1750_name');
    var dropdown_bh1750_mode = this.getFieldValue('bh1750_mode');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_BH1750'] = '#include <BH1750.h>';

    Blockly.Arduino.definitions_['var_declare_' + text_bh1750_name] = 'BH1750 ' + text_bh1750_name + '(' + value_bh1750_address + ');';

    Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin();';
    var code = text_bh1750_name + '.begin(BH1750::' + dropdown_bh1750_mode + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化BH1750光照度传感器 使用软件模拟I2C
Blockly.Arduino.forBlock['make_arduino_bh1750_begin_soft'] = function () {
    var text_name = this.getFieldValue('name');
    var dropdown_bh1750_mode = this.getFieldValue('bh1750_mode');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');

    // Include necessary libraries
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_BH1750'] = '#include <BH1750.h>';

    // Declare BH1750 object with address
    Blockly.Arduino.definitions_['var_declare_' + text_name] = 
        'BH1750 ' + text_name + '(' + value_address + ');';

    // Initialize Wire with specified SDA and SCL pins in setup
    Blockly.Arduino.setups_['setup_wire_' + value_sda + '_' + value_scl] = 
        'Wire.begin(' + value_sda + ', ' + value_scl + ');';

    // Return the begin() call so user can check return value
    var code = text_name + '.begin(BH1750::' + dropdown_bh1750_mode + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};





Blockly.Arduino.forBlock['make_arduino_bh1750_set_mtreg'] = function () {
    var value_bh1750_set_mtreg_data = Blockly.Arduino.valueToCode(this, 'bh1750_set_mtreg_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_bh1750_name = this.getFieldValue('bh1750_name');
    var code = '' + text_bh1750_name + '.setMTreg(' + value_bh1750_set_mtreg_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_bh1750_set_mtreg_return_status'] = function () {
    var value_bh1750_set_mtreg_data = Blockly.Arduino.valueToCode(this, 'bh1750_set_mtreg_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_bh1750_name = this.getFieldValue('bh1750_name');
    var code = text_bh1750_name + '.setMTreg(' + value_bh1750_set_mtreg_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_bh1750_configure'] = function () {
    var text_bh1750_name = this.getFieldValue('bh1750_name');
    var dropdown_bh1750_mode = this.getFieldValue('bh1750_mode');
    var code = text_bh1750_name + '.configure(BH1750::' + dropdown_bh1750_mode + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_bh1750_configure_return_status'] = function () {
    var text_bh1750_name = this.getFieldValue('bh1750_name');
    var dropdown_bh1750_mode = this.getFieldValue('bh1750_mode');
    var code = text_bh1750_name + '.configure(BH1750::' + dropdown_bh1750_mode + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_bh1750_read_lightLevel'] = function () {
    var text_bh1750_name = this.getFieldValue('bh1750_name');
    var code = text_bh1750_name + '.readLightLevel()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化初始化MAX44009光照度传感器
Blockly.Arduino.forBlock['make_arduino_max44009_begin'] = function () {
    var text_max44009_name = this.getFieldValue('max44009_name');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_MAX44009'] = '#include <MAX44009.h>';

    Blockly.Arduino.definitions_['var_declare_' + text_max44009_name] = 'MAX44009 ' + text_max44009_name + ';';

    Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin();';
    Blockly.Arduino.setups_['setup_max44009_' + text_max44009_name] = '' + text_max44009_name + '.begin();';

    var code = '';
    return code;
};

//初始化MAX44009光照度传感器,返回连接状态
Blockly.Arduino.forBlock['make_arduino_max44009_begin_1'] = function () {
    var text_max44009_name = this.getFieldValue('max44009_name');

    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_MAX44009'] = '#include <MAX44009.h>';

    Blockly.Arduino.definitions_['var_declare_' + text_max44009_name] = 'MAX44009 ' + text_max44009_name + ';';

    Blockly.Arduino.setups_['setup_i2c'] = 'Wire.begin();';
    var code = '' + text_max44009_name + '.begin()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化MAX44009光照度传感器 使用软件模拟I2C
Blockly.Arduino.forBlock['make_arduino_max44009_begin_soft'] = function () {
    var text_max44009_name = this.getFieldValue('max44009_name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC).replace(/"/g, '');

    // Include necessary libraries
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_MAX44009'] = '#include <MAX44009.h>';

    // Declare MAX44009 object without address (assuming default address)
    Blockly.Arduino.definitions_['var_declare_' + text_max44009_name] = 
        'MAX44009 ' + text_max44009_name + ';';

    // Initialize Wire with specified SDA and SCL pins in setup
    Blockly.Arduino.setups_['setup_wire_' + value_sda + '_' + value_scl] = 
        'Wire.begin(' + value_sda + ', ' + value_scl + ');';

    // Begin initialization of MAX44009 sensor in setup without error handling
    var setup_code = 
        text_max44009_name + '.begin();';
    Blockly.Arduino.setups_['setup_' + text_max44009_name] = setup_code;

    var code = '';
    return code;
};




//MAX44009光照度传感器 获取光照度
Blockly.Arduino.forBlock['make_arduino_max44009_get_lux'] = function () {
    var text_max44009_name = this.getFieldValue('max44009_name');
    var code = '' + text_max44009_name + '.get_lux()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化ML8511紫外线传感器
Blockly.Arduino.forBlock['make_arduino_ml8511_begin'] = function () {
    this.setTooltip("初始化ML8511紫外线传感器，返回数据的类型为boolean");
    var text_name = this.getFieldValue('name');
    var value_out = Blockly.Arduino.valueToCode(this, 'out', Blockly.Arduino.ORDER_ATOMIC);
    var value_en = Blockly.Arduino.valueToCode(this, 'en', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['include_' + 'ML8511'] = '#include <ML8511.h>';
    Blockly.Arduino.definitions_['var_declare_' + 'ML8511'] = 'ML8511 ' + text_name + '(' + value_out + ', ' + value_en + ');';
    var code = text_name + '.begin()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//ML8511紫外线传感器 获取紫外线强度和输出电压
Blockly.Arduino.forBlock['make_arduino_ml8511_getuvIntensity_getoutputVoltage'] = function () {
    this.setTooltip("ML8511紫外线传感器，获取紫外线强度和输出电压,返回数据的类型为double");
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_pulsesensor_begin'] = function () {
    var text_pulseSensor_name = this.getFieldValue('pulseSensor_name');
    var value_pulseSensor_pin1 = Blockly.Arduino.valueToCode(this, 'pulseSensor_pin1', Blockly.Arduino.ORDER_ATOMIC);
    var statements_pulseSensor_data = Blockly.Arduino.statementToCode(this, 'pulseSensor_data');

    var statements_pulseSensor_data_1 = '';
    for (var i of statements_pulseSensor_data) {
        if (i == '@') {
            statements_pulseSensor_data_1 = statements_pulseSensor_data_1 + text_pulseSensor_name;
        }
        else {
            statements_pulseSensor_data_1 = statements_pulseSensor_data_1 + i;
        }
    }

    Blockly.Arduino.definitions_['var_declare_PulseSensorPlayground_a'] = '#define USE_ARDUINO_INTERRUPTS true\n#include <PulseSensorPlayground.h>';
    //Blockly.Arduino.definitions_['include_PulseSensorPlayground'] = '#define USE_ARDUINO_INTERRUPTS true\n#include <PulseSensorPlayground.h>';

    Blockly.Arduino.definitions_['var_declare_PulseSensorPlayground_b_' + text_pulseSensor_name] = 'PulseSensorPlayground ' + text_pulseSensor_name + ';';

    Blockly.Arduino.setups_['setup_pulsesensor_begin_' + text_pulseSensor_name] = '' + text_pulseSensor_name + '.analogInput(' + value_pulseSensor_pin1 + ');\n'
        + statements_pulseSensor_data_1
        + '  ' + text_pulseSensor_name + '.begin();';

    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_pulsesensor_blinkonpulse'] = function () {
    var value_pulsesensor_pin1 = Blockly.Arduino.valueToCode(this, 'pulsesensor_pin1', Blockly.Arduino.ORDER_ATOMIC);

    var surround_parent = this.getSurroundParent();
    var code = '';
    if (surround_parent && surround_parent.type == 'make_arduino_pulsesensor_begin') {
        code = '@.blinkOnPulse(' + value_pulsesensor_pin1 + ');\n';
    }
    else {
        code = '';
    }
    return code;
};

Blockly.Arduino.forBlock['make_arduino_pulsesensor_fadeonpulse'] = function () {
    var value_pulsesensor_pin1 = Blockly.Arduino.valueToCode(this, 'pulsesensor_pin1', Blockly.Arduino.ORDER_ATOMIC);

    var surround_parent = this.getSurroundParent();
    var code = '';
    if (surround_parent && surround_parent.type == 'make_arduino_pulsesensor_begin') {
        code = '@.fadeOnPulse(' + value_pulsesensor_pin1 + ');\n';
    }
    else {
        code = '';
    }
    return code;
};

Blockly.Arduino.forBlock['make_arduino_pulsesensor_setthreshold'] = function () {
    var value_pulsesensor_data = Blockly.Arduino.valueToCode(this, 'pulsesensor_data', Blockly.Arduino.ORDER_ATOMIC);

    var surround_parent = this.getSurroundParent();
    var code = '';
    if (surround_parent && surround_parent.type == 'make_arduino_pulsesensor_begin') {
        code = '@.setThreshold(' + value_pulsesensor_data + ');\n';
    }
    else {
        code = '';
    }
    return code;
};

Blockly.Arduino.forBlock['make_arduino_pulsesensor_getlatestsample'] = function () {
    var text_pulsesensor_name = this.getFieldValue('pulsesensor_name');
    var code = text_pulsesensor_name + 'getLatestSample()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_pulsesensor_getbeatsperminute'] = function () {
    var text_pulsesensor_name = this.getFieldValue('pulsesensor_name');
    var code = text_pulsesensor_name + '.getBeatsPerMinute()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_pulsesensor_sawstartofbeat'] = function () {
    var text_pulsesensor_name = this.getFieldValue('pulsesensor_name');
    var code = text_pulsesensor_name + '.sawStartOfBeat()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_pulsesensor_isinsidebeat'] = function () {
    var text_pulsesensor_name = this.getFieldValue('pulsesensor_name');
    var code = text_pulsesensor_name + '.isInsideBeat()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化INA219双向电流/电源监控传感器
Blockly.Arduino.forBlock['make_arduino_ina219_begin'] = function () {
    this.setTooltip("初始化INA219双向电流/电源监控传感器(使用硬件I2C)");
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    Blockly.Arduino.definitions_['include_' + 'Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_' + 'Adafruit_INA219'] = '#include <Adafruit_INA219.h>';
    Blockly.Arduino.definitions_['var_declare_' + text_name] = 'Adafruit_INA219 ' + text_name + '(' + value_address + ');';
    Blockly.Arduino.setups_['ina219_' + text_name] = text_name + '.begin();';
    var code = '';
    return code;
};

//初始化INA219双向电流/电源监控传感器 - 使用软件模拟的I2C
Blockly.Arduino.forBlock['make_arduino_ina219_begin_1'] = function () {
    this.setTooltip("初始化INA219双向电流/电源监控传感器(使用硬件I2C)");
    var text_name = this.getFieldValue('name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);

    // 包含必要的库文件
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_Adafruit_INA219'] = '#include <Adafruit_INA219.h>';

    // 声明INA219对象
    Blockly.Arduino.definitions_['var_declare_' + text_name] = 'Adafruit_INA219 ' + text_name + '(' + value_address.replace(/"/g, '') + ');';

    // 初始化Wire对象，指定SDA和SCL引脚
    Blockly.Arduino.setups_['setup_wire'] = 
        'Wire.begin(' + value_sda.replace(/"/g, '') + ', ' + value_scl.replace(/"/g, '') + ');';  

    // 初始化INA219传感器，在setup函数中执行
    Blockly.Arduino.setups_['ina219_' + text_name] = text_name + '.begin();';

    var code = '';
    return code;
};




//INA219双向电流/电源监控传感器 设置测量上限
Blockly.Arduino.forBlock['make_arduino_ina219_setCalibration'] = function () {
    this.setTooltip("INA219双向电流/电源监控传感器 设置测量的上限");
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_name + '.' + dropdown_type + '();\n';
    return code;
};

//INA219双向电流/电源监控传感器 获取一些数据
Blockly.Arduino.forBlock['make_arduino_ina219_get_data'] = function () {
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    if (dropdown_type == 'getShuntVoltage_mV')
        this.setTooltip("INA219双向电流/电源监控传感器 获取分流电阻电压(mV)，返回数据的类型为float");
    else if (dropdown_type == 'getBusVoltage_V')
        this.setTooltip("INA219双向电流/电源监控传感器 获取总线电压(V)，返回数据的类型为float");
    else if (dropdown_type == 'getCurrent_mA')
        this.setTooltip("INA219双向电流/电源监控传感器 获取电流(mA)，返回数据的类型为float");
    else
        this.setTooltip("INA219双向电流/电源监控传感器 获取功率(mW)，返回数据的类型为float");

    var code = text_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//INA219双向电流/电源监控传感器 开启或关闭节电模式
Blockly.Arduino.forBlock['make_arduino_ina219_powerSave'] = function () {
    this.setTooltip("INA219双向电流/电源监控传感器 开启或关闭节电模式");
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    var code = text_name + '.powerSave(' + value_data + ');\n';
    return code;
};Blockly.Arduino.forBlock['make_arduino_ina226_begin'] = function () {
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
    
    // 添加头文件包含
    Blockly.Arduino.definitions_['include_' + 'INA226'] = '#include <INA226.h>';
    Blockly.Arduino.definitions_['include_' + 'Wire'] = '#include <Wire.h>';    

    // 声明INA226对象（使用模板字符串）
    Blockly.Arduino.definitions_['var_declare_' + text_name] = `INA226 ${text_name}(${value_address || '0x40'});`;

    // I2C初始化（兼容 ESP32 2.0.7 和 ESP8266）
    Blockly.Arduino.setups_['setup_i2c_' + text_name] = `Wire.begin(${value_sda}, ${value_scl});`;
    const shuntResistance = parseFloat(this.getFieldValue('shuntResistance'));
    const maxCurrentInput = parseFloat(this.getFieldValue('maxCurrent'));
    const samples = this.getFieldValue('samples');
    const conversionTime = this.getFieldValue('CONVERSION_TIME');
    var text_name = this.getFieldValue('name');
    
    // 使用用户输入的最大电流值，该值已经在block中根据分流电阻自动计算
    const finalMaxCurrent = maxCurrentInput;
    const normalize = true;
    
    // 在宏定义部分添加功率报警宏定义
Blockly.Arduino.definitions_['var_declare_ina226_alerts'] = `
#define INA226_VOLTAGE_OVER_LIMIT 0x0002
#define INA226_CURRENT_OVER_LIMIT 0x0001 
#define INA226_VOLTAGE_UNDER_LIMIT 0x0004`;

    Blockly.Arduino.setups_['ina226setCalibration'] = 
        `${text_name}.setMaxCurrentShunt(${finalMaxCurrent.toFixed(1)}, ${shuntResistance}, ${normalize});\n` +
        `  ${text_name}.setAverage(${samples});\n` +
        `  ${text_name}.setBusVoltageConversionTime(${conversionTime});`;
    
    return '';  // 该块不直接生成代码
};


Blockly.Arduino.forBlock['make_arduino_ina226_setAlert'] = function () {
    const alertTypeSelect = this.getFieldValue('alertTypeSelect');
    const limitValue = Blockly.Arduino.valueToCode(this, 'limit', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var text_name = this.getFieldValue('name');

    let alertFunction = '';
    switch(alertTypeSelect) {
        case "voltage_over":
            alertFunction = `float voltageLimit = ${limitValue};  // 单位：伏特\n` +
                           `  uint16_t alertLimit = voltageLimit / 0.00125;\n` +
                           `  ${text_name}.setAlertLimit(alertLimit);\n` +
                           `  ${text_name}.setAlertRegister(${text_name}_VOLTAGE_OVER_LIMIT);`;
            break;
        case "power":
            alertFunction = `float powerLimit = ${limitValue};  // 单位：毫瓦\n` +
                           `  uint16_t alertLimit = powerLimit / 25;\n` +
                           `  ${text_name}.setAlertLimit(alertLimit);\n` +
                           `  ${text_name}.setAlertRegister(${text_name}_POWER_OVER_LIMIT);`;
            break;
        case "overcurrent":
            alertFunction = `float currentLimit = ${limitValue};  // 单位：毫安\n` +
                           `  uint16_t alertLimit = currentLimit * 1000;\n` +
                           `  ${text_name}.setAlertLimit(alertLimit);\n` +
                           `  ${text_name}.setAlertRegister(${text_name}_CURRENT_OVER_LIMIT);`;
            break;
        case "undervoltage":
            alertFunction = `float voltageLimit = ${limitValue};  // 单位：伏特\n` +
                           `  uint16_t alertLimit = voltageLimit / 0.00125;\n` +
                           `  ${text_name}.setAlertLimit(alertLimit);\n` +
                           `  ${text_name}.setAlertRegister(${text_name}_VOLTAGE_UNDER_LIMIT);`;
            break;
    }

    if (alertFunction) {
        Blockly.Arduino.setups_['ina226setAlert'] = alertFunction;
    }
    
    return '';
};

    // 修改报警检测模块
    Blockly.Arduino.forBlock['ina226_print_alert'] = function() {
        var text_name = this.getFieldValue('NAME');
        var alert_type = this.getFieldValue('ALERT_TYPE');
        
        // 设置工具提示
        if (alert_type == "voltage_over")
            this.setTooltip("检测电压超限报警");
        else if (alert_type == "overcurrent")
            this.setTooltip("检测电流超限报警");
        else if (alert_type == "undervoltage")
            this.setTooltip("检测电压欠压报警");
        else if (alert_type == "power")
            this.setTooltip("检测功率超限报警");

        // 根据报警类型设置对应的标志位
        var alertFlag = '';
        if (alert_type == "voltage_over") {
            alertFlag = 'INA226_VOLTAGE_OVER_LIMIT';
        } else if (alert_type == "overcurrent") {
            alertFlag = 'INA226_CURRENT_OVER_LIMIT';
        } else if (alert_type == "undervoltage") {
            alertFlag = 'INA226_VOLTAGE_UNDER_LIMIT';
        } else if (alert_type == "power") {
            alertFlag = 'INA226_POWER_OVER_LIMIT';
        }
        
        var code = `(${text_name}.getAlertFlag() & ${alertFlag}) ? 1 : 0`;
        return [code, Blockly.Arduino.ORDER_CONDITIONAL];
    };

//INA226双向电流/电源监控传感器 获取一些数据
Blockly.Arduino.forBlock['ina226_get_data'] = function() {
    var text_name = this.getFieldValue('NAME');
    var dropdown_type = this.getFieldValue('TYPE');

    // 设置工具提示
    if (dropdown_type == 'getShuntVoltage_mV')
        this.setTooltip("分流电阻两端的压降(mV)");
    else if (dropdown_type == 'getBusVoltage_mV')
        this.setTooltip("总线供电电压(mV)");
    else if (dropdown_type == 'getCurrent_mA')
        this.setTooltip("实时电流测量值(mA)");
    else if (dropdown_type == 'getPower_mW')
        this.setTooltip("实时功率消耗(mW)");

    var code = `${text_name}.${dropdown_type}()`;
    
    return [code, Blockly.Arduino.ORDER_NONE];
};

Blockly.Arduino.forBlock['make_arduino_MPU6500_begin'] = function () {
    var value_address = Blockly.Arduino.valueToCode(this, 'address', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('NAME');
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
    var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);

    // 添加头文件包含
    Blockly.Arduino.definitions_['include_' + 'MPU6500'] = '#include <MPU6500_WE.h>';
    Blockly.Arduino.definitions_['include_' + 'Wire'] = '#include <Wire.h>';    
    
    // 声明对象（动态地址）
    Blockly.Arduino.definitions_['var_declare_' + text_name] = 
        `MPU6500_WE ${text_name} = MPU6500_WE(${value_address});`;
        
        Blockly.Arduino.setups_[`setup_${text_name}_`] = [
            'Wire.begin(' + value_sda.replace(/"/g, '') + ', ' + value_scl.replace(/"/g, '') + ');',
            `  ${text_name}.autoOffsets();`
        ].join('\n');

    return '';
};
 Blockly.Arduino.forBlock['ina226_wiring_diagram'] = function(block) {

  return  '//接线图';
};
Blockly.Arduino.forBlock['mpu6500_config'] = function() {
    const text_name = this.getFieldValue('NAME');
    const dlpfOption = this.getFieldValue('DLPF_OPTION');
    const sampleRateDivider = Blockly.Arduino.valueToCode(this, 'SAMPLE_RATE_DIVIDER', Blockly.Arduino.ORDER_ATOMIC) || '5';
    const gyroRange = this.getFieldValue('GYRO_RANGE_OPTION');
    const accRange = this.getFieldValue('ACC_RANGE_OPTION');
    const accDlpfEnabled = this.getFieldValue('ACC_DLPF_ENABLED_OPTION') === 'true';
    const accDlpfLevel = this.getFieldValue('ACC_DLPF_LEVEL_OPTION');

    let setupCode = '';

    // DLPF设置
    switch(dlpfOption) {
        case 'MPU6500_DLPF_0':
            setupCode += `${text_name}.enableGyrDLPF();\n  ${text_name}.setGyrDLPF(MPU6500_DLPF_0);\n`;
            break;
        case 'MPU6500_DLPF_1':
            setupCode += `${text_name}.enableGyrDLPF();\n  ${text_name}.setGyrDLPF(MPU6500_DLPF_1);\n`;
            break;
        case 'MPU6500_DLPF_2':
            setupCode += `${text_name}.enableGyrDLPF();\n  ${text_name}.setGyrDLPF(MPU6500_DLPF_2);\n`;
            break;
        case 'MPU6500_DLPF_3':
            setupCode += `${text_name}.enableGyrDLPF();\n  ${text_name}.setGyrDLPF(MPU6500_DLPF_3);\n`;
            break;
        case 'MPU6500_DLPF_4':
            setupCode += `${text_name}.enableGyrDLPF();\n  ${text_name}.setGyrDLPF(MPU6500_DLPF_4);\n`;
            break;
        case 'MPU6500_DLPF_5':
            setupCode += `${text_name}.enableGyrDLPF();\n  ${text_name}.setGyrDLPF(MPU6500_DLPF_5);\n`;
            break;
        case 'MPU6500_DLPF_6':
            setupCode += `${text_name}.enableGyrDLPF();\n  ${text_name}.setGyrDLPF(MPU6500_DLPF_6);\n`;
            break;
        case 'MPU6500_BW_WO_DLPF_3600':
            setupCode += `${text_name}.disableGyrDLPF();\n  ${text_name}.setGyrBandwidth(3600);\n`;
            break;
        case 'MPU6500_BW_WO_DLPF_8800':
            setupCode += `${text_name}.disableGyrDLPF();\n  ${text_name}.setGyrBandwidth(8800);\n`;
            break;
    }

    // 采样率除数设置
    setupCode += `  ${text_name}.setSampleRateDivider(${sampleRateDivider});\n`;

    // 陀螺仪量程设置
    setupCode += `  ${text_name}.setGyrRange(${gyroRange});\n`;

    // 加速度计量程设置
    setupCode += `  ${text_name}.setAccRange(${accRange});\n`;

    // 加速度计DLPF启用/禁用设置
    setupCode += `  ${text_name}.enableAccDLPF(${accDlpfEnabled});\n`;

    // 加速度计DLPF级别设置
    if (accDlpfEnabled) {
        setupCode += `  ${text_name}.setAccDLPF(${accDlpfLevel});
`;
    }
    
    // 将配置代码添加到设备的setup中
    const existingSetup = Blockly.Arduino.setups_[`setup_${text_name}_`] || '';
    Blockly.Arduino.setups_[`setup_${text_name}_`] = existingSetup + setupCode;
    return '';

};


Blockly.Arduino.forBlock['mpu6500_get_data'] = function() {
    var dropdown_type = this.getFieldValue('TYPE');
    var text_name = this.getFieldValue('NAME');
    var code = '';

    // 直接访问传感器对象的实时数据（无需中间变量）
    switch(dropdown_type) {
        case 'gValue.x':
            code += `${text_name}.getGValues().x`; // 直接调用函数获取实时值
            break;
        case 'gValue.y':
            code += `${text_name}.getGValues().y`;
            break;
        case 'gValue.z':
            code += `${text_name}.getGValues().z`;
            break;
        case 'gyr.x':
            code += `${text_name}.getGyrValues().x`;
            break;
        case 'gyr.y':
            code += `${text_name}.getGyrValues().y`;
            break;
        case 'gyr.z':
            code += `${text_name}.getGyrValues().z`;
            break;
        case 'temp':
            code += `${text_name}.getTemperature()`;
            break;
        case 'resultantG':
            // 假设getResultantG需要实时加速度数据作为参数
            code += `${text_name}.getResultantG(${text_name}.getGValues())`;
            break;
        case 'angle.x':
            code += `${text_name}.getAngles().x`; // 新增角度X值获取
            break;
        case 'angle.y':
            code += `${text_name}.getAngles().y`; // 新增角度Y值获取
            break;
        case 'angle.z':
            code += `${text_name}.getAngles().z`; // 新增角度Z值获取
            break;
        default:
            code += '0.0f'; // 默认返回浮点数0
    }

    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化GP2Y1010AU0F粉尘传感器
Blockly.Arduino.forBlock['make_arduino_gp2y1010au0f_begin'] = function () {
    this.setTooltip("初始化GP2Y1010AU0F粉尘传感器");
    var text_name = this.getFieldValue('name');
    var value_led = Blockly.Arduino.valueToCode(this, 'led', Blockly.Arduino.ORDER_ATOMIC);
    var value_vo = Blockly.Arduino.valueToCode(this, 'vo', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['include_' + 'GP2Y1010AU0F'] = '#include "GP2Y1010AU0F.h"';
    Blockly.Arduino.definitions_['var_declare_' + text_name] = 'GP2Y1010AU0F ' + text_name + '(' + value_led + ', ' + value_vo + ');';
    var code = '';
    return code;
};

//GP2Y1010AU0F粉尘传感器 获取输出电压
Blockly.Arduino.forBlock['make_arduino_gp2y1010au0f_getOutputV'] = function () {
    this.setTooltip("GP2Y1010AU0F粉尘传感器 对空气采样并获取输出电压(V)，返回数据的类型为double");
    var text_name = this.getFieldValue('name');
    var code = text_name + '.getOutputV()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//GP2Y1010AU0F粉尘传感器 根据输入电压计算灰尘浓度(ug/m3)
Blockly.Arduino.forBlock['make_arduino_gp2y1010au0f_getDustDensity'] = function () {
    this.setTooltip("GP2Y1010AU0F粉尘传感器 根据输入电压计算灰尘浓度(ug/m³)，返回数据的类型为double");
    var text_name = this.getFieldValue('name');
    var value_input = Blockly.Arduino.valueToCode(this, 'input', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.getDustDensity(' + value_input + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//GP2Y1010AU0F粉尘传感器 根据灰尘浓度计算空气质量指数aqi(是将所有粒度的灰尘都按照PM2.5的指标计算的, 并不准确)
Blockly.Arduino.forBlock['make_arduino_gp2y1010au0f_getAQI'] = function () {
    this.setTooltip("GP2Y1010AU0F粉尘传感器 根据灰尘浓度计算空气质量指数(AQI)，返回数据的类型为double");
    var text_name = this.getFieldValue('name');
    var value_input = Blockly.Arduino.valueToCode(this, 'input', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.getAQI(' + value_input + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//GP2Y1010AU0F粉尘传感器 根据空气质量指数计算空气质量级别
Blockly.Arduino.forBlock['make_arduino_gp2y1010au0f_getGradeInfo'] = function () {
    this.setTooltip("GP2Y1010AU0F粉尘传感器 根据空气质量指数计算空气质量级别，返回数据的类型为int");
    var text_name = this.getFieldValue('name');
    var value_input = Blockly.Arduino.valueToCode(this, 'input', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.getGradeInfo(' + value_input + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['vl53l0x_init'] = function() {
    
  var name = this.getFieldValue('name');
  var measureMode = this.getFieldValue('MEASURE_MODE');
  var i2cAddr = Blockly.Arduino.valueToCode(this, 'I2C_ADDR', Blockly.Arduino.ORDER_ATOMIC) || '0x29';
  
  // 添加头文件包含
  Blockly.Arduino.definitions_['include_VL53L0X'] = '#include <VL53L0X.h>';
  Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
  
  // 声明VL53L0X对象
  Blockly.Arduino.definitions_['var_declare_' + name] = `VL53L0X ${name};`;
  
  // 声明测量模式标记变量
  Blockly.Arduino.definitions_['var_declare_mode_flag_' + name] = `bool ${name}_continuous = ${measureMode === 'CONTINUOUS' ? 'true' : 'false'};`;
  
  // 生成VL53L0X初始化代码
  Blockly.Arduino.setups_['setup_wire'] = 'Wire.begin();';
  
  // 设置I2C地址
  Blockly.Arduino.setups_['setup_addr_' + name] = `  ${name}.setAddress(${i2cAddr});`;
  
  // 添加精度模式条件编译
  var mode = this.getFieldValue('MODE');
  Blockly.Arduino.definitions_['define_mode_' + mode] = '#define ' + mode;
  
  // 添加模式相关配置代码
  if(mode === 'LONG_RANGE') {
    // 长距离模式使用默认值
    Blockly.Arduino.setups_['setup_mode_' + name] = 
      '  ' + name + '.setSignalRateLimit(0.1);\n' +
      '  ' + name + '.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);\n' +
      '  ' + name + '.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);\n';
  } else {
    var timingBudgetMs = Blockly.Arduino.valueToCode(this, 'TIMING_BUDGET', Blockly.Arduino.ORDER_ATOMIC) || 
      (mode === 'HIGH_SPEED' ? '20' : '200');
    var timingBudgetUs = timingBudgetMs + ' * 1000';
    
    Blockly.Arduino.setups_['setup_mode_' + name] = 
      '  ' + name + '.setMeasurementTimingBudget(' + timingBudgetUs + ');\n';
  }
  
  // 连续测量模式需要启动连续测量
  if(measureMode === 'CONTINUOUS') {
    Blockly.Arduino.setups_['setup_continuous_' + name] = `  ${name}.startContinuous();`;
  }
  
  return '';
};

Blockly.Arduino.forBlock['vl53l0x_read_range'] = function() {
  var name = this.getFieldValue('name');
  
  // 根据初始化时设置的标记变量自动判断测量模式
  var code = `${name}_continuous ? ${name}.readRangeContinuousMillimeters() : ${name}.readRangeSingleMillimeters()`;
  
  return [code, Blockly.Arduino.ORDER_NONE];
};
  Blockly.Arduino.forBlock['make_arduino_max30105_begin'] = function() {
    var text_name = this.getFieldValue('name');
    
    Blockly.Arduino.definitions_['include_MAX30105'] = '#include "MAX30105.h"';
    Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
    Blockly.Arduino.definitions_['include_heartRate'] = '#include "heartRate.h"';
    Blockly.Arduino.definitions_['include_spo2'] = '#include "spo2_algorithm.h"';
    
    Blockly.Arduino.definitions_['var_declare_' + text_name] = `MAX30105 ${text_name};`;
    
    // 血氧检测相关变量
    Blockly.Arduino.definitions_['define_BUFFER_SIZE'] = '#define BUFFER_SIZE 100 // 缓冲区大小';
    Blockly.Arduino.definitions_['var_declare_irBuffer'] = 'uint32_t irBuffer[BUFFER_SIZE]; // 红外数据缓冲区';
    Blockly.Arduino.definitions_['var_declare_redBuffer'] = 'uint32_t redBuffer[BUFFER_SIZE]; // 红光数据缓冲区';
    Blockly.Arduino.definitions_['var_declare_spo2'] = 'int32_t spo2; // 血氧饱和度值';
    Blockly.Arduino.definitions_['var_declare_validSPO2'] = 'int8_t validSPO2; // 血氧有效性标志';
    Blockly.Arduino.definitions_['var_declare_heartRate'] = 'int32_t heartRate; // 心率值(来自血氧算法)';
    Blockly.Arduino.definitions_['var_declare_validHeartRate'] = 'int8_t validHeartRate; // 心率有效性标志(来自血氧算法)';
    
    // 心率检测(PBA算法)相关变量
    Blockly.Arduino.definitions_['var_declare_rates'] = 'const byte RATE_SIZE = 4; // 平均心率数组大小\nbyte rates[RATE_SIZE]; // 存储心率的数组\nbyte rateSpot = 0; // 数组中当前存储位置的索引\nlong lastBeat = 0; // 上一次检测到心跳的时间戳';
    Blockly.Arduino.definitions_['var_declare_beatsPerMinute'] = 'float beatsPerMinute; // 实时心率';
    Blockly.Arduino.definitions_['var_declare_beatAvg'] = 'int beatAvg; // 平均心率';
    Blockly.Arduino.definitions_['var_declare_bufferIndex'] = 'uint32_t bufferIndex = 0; // 缓冲区索引';
    
    var value_sda = Blockly.Arduino.valueToCode(this, 'sda', Blockly.Arduino.ORDER_ATOMIC);
  var value_scl = Blockly.Arduino.valueToCode(this, 'scl', Blockly.Arduino.ORDER_ATOMIC);
  
  Blockly.Arduino.setups_['setup_max30105_' + text_name] = 
      'Wire.begin(' + value_sda + ', ' + value_scl + ');\n'
      + `if (!${text_name}.begin(Wire, I2C_SPEED_FAST)) {\n`
      + '  Serial.println("MAX30105 未找到。请检查连接和电源。");\n'
      + '  while(1);\n'
      + '}\n'
      + `${text_name}.setup();\n`
      + `${text_name}.setPulseAmplitudeRed(0x0A);\n`
      + `${text_name}.setPulseAmplitudeGreen(0);\n`
      + `${text_name}.enableDIETEMPRDY();\n\n`
  
    var code = '';
    // 处理心率检测
    code += 'long irValue = ' + text_name + '.getIR();\n';
    code += 'if (checkForBeat(irValue)) {\n';
    code += '  long delta = millis() - lastBeat;\n';
    code += '  lastBeat = millis();\n';
    code += '  beatsPerMinute = 60 / (delta / 1000.0);\n';
    code += '  if (beatsPerMinute < 255 && beatsPerMinute > 20) {\n';
    code += '    rates[rateSpot++] = (byte)beatsPerMinute;\n';
    code += '    rateSpot %= RATE_SIZE;\n';
    code += '    beatAvg = 0;\n';
    code += '    for (byte x = 0; x < RATE_SIZE; x++)\n';
    code += '      beatAvg += rates[x];\n';
    code += '    beatAvg /= RATE_SIZE;\n';
    code += '  }\n';
    code += '}\n';
  
    // 更新缓冲区
    code += 'redBuffer[bufferIndex] = ' + text_name + '.getRed();\n';
    code += 'irBuffer[bufferIndex] = ' + text_name + '.getIR();\n';
    code += 'bufferIndex = (bufferIndex + 1) % BUFFER_SIZE;\n';
  
    // 每100个样本计算一次血氧
    code += 'static uint32_t lastSampleTime = 0;\n';
    code += 'if (millis() - lastSampleTime >= 4000) {\n';
    code += '  maxim_heart_rate_and_oxygen_saturation(irBuffer, BUFFER_SIZE, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);\n';
    code += '  lastSampleTime = millis();\n';
    code += '}\n';
  
    return code;
    };
    
  Blockly.Arduino.forBlock['max30105_read_data'] = function() {
    var text_name = this.getFieldValue('name');
    var dropdown_data_type = this.getFieldValue('data_type');
    
    var code = '';
    switch(dropdown_data_type) {
      case 'temperature':
        code = `${text_name}.readTemperature()`;
        break;
      case 'current_hr':
        code = 'beatsPerMinute';
        break;
      case 'avg_hr':
        code = 'beatAvg';
        break;
      case 'spo2':
        code = 'spo2';
        break;
      case 'heart_rate':
        code = 'heartRate';
        break;
    }
    
    return [code, Blockly.Arduino.ORDER_ATOMIC];
  };
  

    // ==================== 引脚设置类积木 ====================

    // 设置音频引脚（统一配置）
    Blockly.Arduino.forBlock['audio_set_pins'] = function() {
        var bclk = Blockly.Arduino.valueToCode(this, 'BCLK', Blockly.Arduino.ORDER_ATOMIC) || '27';
        var lrc = Blockly.Arduino.valueToCode(this, 'LRC', Blockly.Arduino.ORDER_ATOMIC) || '26';
        var din = Blockly.Arduino.valueToCode(this, 'DIN', Blockly.Arduino.ORDER_ATOMIC) || '25';
        
        Blockly.Arduino.definitions_['var_declare_audio_pins'] = 
            `// 统一音频引脚配置
int _audio_bclk = ${bclk};
int _audio_lrc = ${lrc};
int _audio_din = ${din};`;
        
        Blockly.Arduino.definitions_['include_driver_i2s'] = '#include <driver/i2s.h>';
        Blockly.Arduino.definitions_['var_declare_i2s_initialized'] = 'bool _i2s_initialized = false;';
        
        Blockly.Arduino.definitions_['function_init_i2s'] = 
`bool initI2S(int _bclk, int _lrclk, int _din) {
  if (_i2s_initialized) {
    i2s_driver_uninstall(I2S_NUM_0);
  }
  
  static const i2s_config_t i2s_config = {
    .mode = static_cast<i2s_mode_t>(I2S_MODE_MASTER | I2S_MODE_TX),
    .sample_rate = 44100,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
    .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 4,
    .dma_buf_len = 400,
    .use_apll = false,
    .tx_desc_auto_clear = true
  };

  static const i2s_pin_config_t pin_config = {
    .bck_io_num = _bclk,
    .ws_io_num = _lrclk,
    .data_out_num = _din,
    .data_in_num = I2S_PIN_NO_CHANGE
  };

  if (i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL)) {
    Serial.println("安装并启动I2S驱动失败！");
    return false;
  }
  if (i2s_set_pin(I2S_NUM_0, &pin_config)) {
    Serial.println("设置I2S引脚号失败！");
    return false;
  }

  _i2s_initialized = true;
  return true;
}`;
        
        Blockly.Arduino.setups_['setup_audio_pins'] = 
            `// 初始化I2S
  initI2S(_audio_bclk, _audio_lrc, _audio_din);`;
        
        return '';
    };

    // ==================== 音频播放类积木 ====================
    
    // 初始化本地音乐播放器
    Blockly.Arduino.forBlock['audio_init_player'] = function() {
        // 检查是否已设置串口波特率，如果没有则自动添加
        var hasSerialBegin = false;
        for (var key in Blockly.Arduino.setups_) {
            if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
                hasSerialBegin = true;
                break;
            }
        }
        if (!hasSerialBegin) {
            Blockly.Arduino.setups_['setup_serial_auto'] = 'Serial.begin(115200);';
        }
        
        Blockly.Arduino.definitions_['include_audio'] = '#include <Audio.h>';
        Blockly.Arduino.definitions_['var_declare_audio'] = 'Audio audio;';
        
        Blockly.Arduino.setups_['setup_audio_init'] = 
            `audio.setPinout(_audio_bclk, _audio_lrc, _audio_din);`;
        
        return 'audio.loop();';
    };
    
    // 播放本地音频文件
    Blockly.Arduino.forBlock['audio_play_file'] = function() {
        var filename = Blockly.Arduino.valueToCode(this, 'FILENAME', Blockly.Arduino.ORDER_ATOMIC) || '"/music.mp3"';
        
        return 'if (audio.connecttoFS(SD, ' + filename + ')) {\n' +
               '  Serial.printf("开始播放: %s\\n", ' + filename + ');\n' +
               '} else {\n' +
               '  Serial.println("文件打开失败");\n' +
               '}';
    };
    
    // 播放文件夹
    Blockly.Arduino.forBlock['audio_play_folder'] = function() {
        var folder = Blockly.Arduino.valueToCode(this, 'FOLDER', Blockly.Arduino.ORDER_ATOMIC) || '"/music"';
        
        Blockly.Arduino.definitions_['include_vector'] = '#include <vector>';
        
        Blockly.Arduino.definitions_['var_declare_playlist'] = 
            `// 播放列表相关
std::vector<String> playList;
int playListIndex = -1;`;
        
        Blockly.Arduino.definitions_['function_scan_folder'] = 
`void scanFolder(String folder) {
  playList.clear();
  File root = SD.open(folder);
  if (!root || !root.isDirectory()) {
    Serial.println("文件夹不存在或无法打开");
    return;
  }
  
  File file = root.openNextFile();
  while (file) {
    if (!file.isDirectory()) {
      String filename = String(file.name());
      filename.toLowerCase();
      if (filename.endsWith(".mp3") || filename.endsWith(".wav") || 
          filename.endsWith(".aac") || filename.endsWith(".flac") || 
          filename.endsWith(".m4a") || filename.endsWith(".ogg")) {
        playList.push_back(folder + "/" + file.name());
      }
    }
    file = root.openNextFile();
  }
  root.close();
  Serial.printf("找到 %d 个音频文件\\n", playList.size());
}`;
        
        Blockly.Arduino.definitions_['function_audio_eof_playlist'] = 
`// 音频播放结束回调（支持播放列表）
void audio_eof_mp3(const char *info) {
  Serial.print("播放结束: ");
  Serial.println(info);
  
  // 自动播放下一首
  if (playList.size() > 0 && playListIndex >= 0) {
    playListIndex = (playListIndex + 1) % playList.size();
    Serial.printf("切换到下一首: %s\\n", playList[playListIndex].c_str());
    audio.connecttoFS(SD, playList[playListIndex].c_str());
  }
}`;
        
        return 'scanFolder(' + folder + ');\n' +
               'if (playList.size() > 0) {\n' +
               '  playListIndex = 0;\n' +
               '  audio.connecttoFS(SD, playList[0].c_str());\n' +
               '  Serial.printf("开始播放文件夹: %s\\n", ' + folder + ');\n' +
               '} else {\n' +
               '  Serial.println("文件夹中没有找到音频文件");\n' +
               '}';
    };
    
    // 初始化网络音频播放器
    Blockly.Arduino.forBlock['audio_init_http_player'] = function() {
        // 检查是否已设置串口波特率，如果没有则自动添加
        var hasSerialBegin = false;
        for (var key in Blockly.Arduino.setups_) {
            if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
                hasSerialBegin = true;
                break;
            }
        }
        if (!hasSerialBegin) {
            Blockly.Arduino.setups_['setup_serial_auto'] = 'Serial.begin(115200);';
        }
        
        Blockly.Arduino.definitions_['include_audio'] = '#include <Audio.h>';
        Blockly.Arduino.definitions_['var_declare_audio'] = 'Audio audio;';
        
        Blockly.Arduino.setups_['setup_audio_init'] = 
            `audio.setPinout(_audio_bclk, _audio_lrc, _audio_din);
  audio.setVolume(12);`;
        
        return 'audio.loop();';
    };
    
    // 播放网络音频
    Blockly.Arduino.forBlock['audio_play_http'] = function() {
        var url = Blockly.Arduino.valueToCode(this, 'URL', Blockly.Arduino.ORDER_ATOMIC) || '"http://lhttp.qingting.fm/live/1754/64k.mp3"';
        
        return '// 检查WiFi连接\n' +
               'if (WiFi.status() != WL_CONNECTED) {\n' +
               '  Serial.println("错误：WiFi未连接");\n' +
               '} else {\n' +
               '  if (audio.connecttohost(' + url + ')) {\n' +
               '    Serial.println("网络音频播放成功");\n' +
               '  } else {\n' +
               '    Serial.println("网络音频连接失败");\n' +
               '  }\n' +
               '}';
    };
    
    // 播放控制
    Blockly.Arduino.forBlock['audio_control'] = function() {
        var action = this.getFieldValue('ACTION');
        var code = '';
        
        switch(action) {
            case 'stop':
                code = 'audio.stopSong();\n' +
                       'Serial.println("播放已停止");';
                break;
            case 'pause':
                code = 'if (audio.isRunning()) {\n' +
                       '  audio.pauseResume();\n' +
                       '  Serial.println("已暂停");\n' +
                       '}';
                break;
            case 'resume':
                code = 'if (!audio.isRunning()) {\n' +
                       '  audio.pauseResume();\n' +
                       '  Serial.println("继续播放");\n' +
                       '}';
                break;
            case 'next':
                code = 'if (playList.size() > 0) {\n' +
                       '  playListIndex = (playListIndex + 1) % playList.size();\n' +
                       '  audio.connecttoFS(SD, playList[playListIndex].c_str());\n' +
                       '  Serial.printf("下一首: %s\\n", playList[playListIndex].c_str());\n' +
                       '} else {\n' +
                       '  Serial.println("播放列表为空");\n' +
                       '}';
                break;
            case 'previous':
                code = 'if (playList.size() > 0) {\n' +
                       '  playListIndex--;\n' +
                       '  if (playListIndex < 0) playListIndex = playList.size() - 1;\n' +
                       '  audio.connecttoFS(SD, playList[playListIndex].c_str());\n' +
                       '  Serial.printf("上一首: %s\\n", playList[playListIndex].c_str());\n' +
                       '} else {\n' +
                       '  Serial.println("播放列表为空");\n' +
                       '}';
                break;
        }
        
        return code;
    };
    
    // 是否正在播放
    Blockly.Arduino.forBlock['audio_is_playing'] = function() {
        return ['audio.isRunning()', Blockly.Arduino.ORDER_ATOMIC];
    };
    
    // ==================== 音量控制类积木 ====================
    
    // 设置音量
    Blockly.Arduino.forBlock['audio_set_volume'] = function() {
        var volume = Blockly.Arduino.valueToCode(this, 'VOLUME', Blockly.Arduino.ORDER_ATOMIC) || '12';
        
        return 'audio.setVolume(' + volume + ');';
    };
    
    // 获取当前音量
    Blockly.Arduino.forBlock['audio_get_volume'] = function() {
        return ['audio.getVolume()', Blockly.Arduino.ORDER_ATOMIC];
    };

    // ==================== 蓝牙音箱类积木（仅ESP32） ====================
    
    // 初始化蓝牙音箱
    Blockly.Arduino.forBlock['audio_bt_init'] = function() {
        var btName = this.getFieldValue('BT_NAME') || 'ESP32_Speaker';
        
        // 检查是否已设置串口波特率，如果没有则自动添加
        var hasSerialBegin = false;
        for (var key in Blockly.Arduino.setups_) {
            if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
                hasSerialBegin = true;
                break;
            }
        }
        if (!hasSerialBegin) {
            Blockly.Arduino.setups_['setup_serial_auto'] = 'Serial.begin(115200);';
        }
        
        Blockly.Arduino.definitions_['include_esp_bt_main'] = '#include <esp_bt_main.h>';
        Blockly.Arduino.definitions_['include_esp_bt_device'] = '#include <esp_bt_device.h>';
        Blockly.Arduino.definitions_['include_esp_gap_bt_api'] = '#include <esp_gap_bt_api.h>';
        Blockly.Arduino.definitions_['include_esp_a2dp_api'] = '#include <esp_a2dp_api.h>';
        Blockly.Arduino.definitions_['include_esp_avrc_api'] = '#include <esp_avrc_api.h>';
        
        Blockly.Arduino.definitions_['var_declare_bt_remote_address'] = 'uint8_t remoteAddress[6];';
        Blockly.Arduino.definitions_['var_declare_bt_volume'] = 'float _bt_volume = 1.0;';
        Blockly.Arduino.definitions_['var_declare_bt_avrc_connected'] = 'bool _bt_avrcConnected = false;';
        Blockly.Arduino.definitions_['var_declare_bt_metadata'] = 'String _bt_metadata = "";';
        Blockly.Arduino.definitions_['var_declare_bt_meta_flag'] = 'uint8_t _bt_metaFlag = 0;';
        
        Blockly.Arduino.definitions_['function_audio_data_callback'] = 
`void audioDataProcessCallback(const uint8_t *data, uint32_t len) {
  int16_t* data16 = (int16_t*)data;
  int16_t processedData;
  int count = len / 2;
  size_t i2s_bytes_write = 0;

  for (int i = 0; i < count; i++) {
    processedData = (int16_t)((*data16) * _bt_volume);
    data16++;
    i2s_write(I2S_NUM_0, &processedData, 2, &i2s_bytes_write, 10);
  }
}`;

        Blockly.Arduino.definitions_['function_avrc_callback'] = 
`void avrcCallback(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) {
  esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(param);

  switch (event) {
    case ESP_AVRC_CT_METADATA_RSP_EVT: {
        char *attr_text = (char *) malloc (rc->meta_rsp.attr_length + 1);
        memcpy(attr_text, rc->meta_rsp.attr_text, rc->meta_rsp.attr_length);
        attr_text[rc->meta_rsp.attr_length] = 0;
        _bt_metadata = String(attr_text);
        _bt_metaFlag = rc->meta_rsp.attr_id;
        free(attr_text);
        break;
      }
    case ESP_AVRC_CT_CONNECTION_STATE_EVT:{
        _bt_avrcConnected = rc->conn_stat.connected;
        if (_bt_avrcConnected) {
          uint8_t * p = rc->conn_stat.remote_bda;
          for (uint8_t i = 0; i < 6; i++) {
            remoteAddress[i] = *(p + i);
          }
        } else {
          memset(remoteAddress, 0, 6);
        }
        break;
      }
    default:
      break;
  }
}`;

        Blockly.Arduino.definitions_['function_a2dp_callback'] = 
`void a2dpCallback(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) {
  switch (event) {
    case ESP_A2D_AUDIO_CFG_EVT:
    case ESP_A2D_CONNECTION_STATE_EVT:
    case ESP_A2D_AUDIO_STATE_EVT:
    case ESP_A2D_MEDIA_CTRL_ACK_EVT:
    case ESP_A2D_PROF_STATE_EVT:
      break;
    default:
      break;
  }
}`;

        Blockly.Arduino.definitions_['function_init_bluetooth'] = 
`bool initBluetooth(const char * _btName) {
  if (!btStarted() && !btStart()) {
    Serial.println("初始化控制器失败");
    return false;
  }
  esp_bluedroid_status_t bt_state = esp_bluedroid_get_status();
  if (bt_state == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
    if (esp_bluedroid_init()) {
      Serial.println("初始化bluedroid失败！");
      return false;
    }
  }
  if (bt_state != ESP_BLUEDROID_STATUS_ENABLED) {
    if (esp_bluedroid_enable()) {
      Serial.println("启用bluedroid失败！");
      return false;
    }
  }
  if (esp_bt_dev_set_device_name(_btName)) {
    Serial.println("设置设备名称失败！");
    return false;
  }

  if (esp_avrc_ct_init()) {
    Serial.println("初始化蓝牙AVRCP控制器模块失败！");
    return false;
  }
  if (esp_avrc_ct_register_callback(avrcCallback)) {
    Serial.println("向AVRCP模块注册应用回调失败！");
    return false;
  }

  if (esp_a2d_sink_init()) {
    Serial.println("初始化蓝牙A2DP接收模块失败！");
    return false;
  }
  if (esp_a2d_register_callback(a2dpCallback)) {
    Serial.println("向A2DP模块注册应用回调失败！");
    return false;
  }
  if (esp_a2d_sink_register_data_callback(audioDataProcessCallback)) {
    Serial.println("注册A2DP接收数据输出函数失败！");
    return false;
  }

  if (esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE)) {
    Serial.println("设置传统蓝牙的可发现性和可连接性模式失败！");
    return false;
  }

  return true;
}`;

        Blockly.Arduino.setups_['setup_bt_audio'] = 
            `// 初始化蓝牙音箱
  if (!initBluetooth("${btName}")) {
    Serial.println("初始化蓝牙失败！");
  }
  Serial.println("蓝牙音箱初始化成功！");`;
        
        return '';
    };
    
    // 获取蓝牙音乐元数据
    Blockly.Arduino.forBlock['audio_bt_metadata'] = function() {
        var metaType = this.getFieldValue('META_TYPE');
        
        var typeCode = '';
        if (metaType === 'TITLE') {
            typeCode = 'ESP_AVRC_MD_ATTR_TITLE';
        } else if (metaType === 'ARTIST') {
            typeCode = 'ESP_AVRC_MD_ATTR_ARTIST';
        } else if (metaType === 'ALBUM') {
            typeCode = 'ESP_AVRC_MD_ATTR_ALBUM';
        }
        
        Blockly.Arduino.definitions_['function_get_bt_metadata'] = 
`String getBtMetadata(uint8_t type) {
  _bt_metadata = "";
  if (_bt_avrcConnected) {
    esp_avrc_ct_send_metadata_cmd(type, type);
    for (uint8_t i = 0; i < 20; i++) {
      if (0 != _bt_metaFlag) {
        break;
      }
      delay(100);
    }
    _bt_metaFlag = 0;
  }
  return _bt_metadata;
}`;
        
        return ['getBtMetadata(' + typeCode + ')', Blockly.Arduino.ORDER_ATOMIC];
    };
    
    // ==================== 网络音频类积木（兼容旧代码） ====================
    
    // 停止网络音频（兼容旧代码）
    Blockly.Arduino.forBlock['audio_stop_http'] = function() {
        return 'audio.stopSong();\n' +
               'Serial.println("网络音频已停止");';
    };


Blockly.Arduino.forBlock['make_arduino_inmp441_begin'] = function(block) {
  const bclk = Blockly.Arduino.valueToCode(block, 'BCLK', Blockly.Arduino.ORDER_ATOMIC) || '14';
  const lrclk = Blockly.Arduino.valueToCode(block, 'LRCLK', Blockly.Arduino.ORDER_ATOMIC) || '15';
  const data = Blockly.Arduino.valueToCode(block, 'DATA', Blockly.Arduino.ORDER_ATOMIC) || '32';
  const sampleRate = Blockly.Arduino.valueToCode(block, 'SAMPLE_RATE', Blockly.Arduino.ORDER_ATOMIC) || '16000';
  const gain = Blockly.Arduino.valueToCode(block, 'GAIN', Blockly.Arduino.ORDER_ATOMIC) || '1.0';

  // 检查是否已设置串口波特率，如果没有则自动添加
  var hasSerialBegin = false;
  for (var key in Blockly.Arduino.setups_) {
    if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
      hasSerialBegin = true;
      break;
    }
  }
  if (!hasSerialBegin) {
    Blockly.Arduino.setups_['setup_serial_auto'] = 'Serial.begin(115200);';
  }

  Blockly.Arduino.definitions_['include_inmp441'] = '#include <driver/i2s.h>';
  Blockly.Arduino.definitions_['var_declare_inmp441_port'] = 'const i2s_port_t I2S_PORT = I2S_NUM_0;';
  Blockly.Arduino.definitions_['var_declare_inmp441_blocksize'] = 'const int INMP441_BLOCK_SIZE = 512;';
  Blockly.Arduino.definitions_['var_declare_inmp441_gain'] = `float inmp441_gain = ${gain};`;

  Blockly.Arduino.setups_['inmp441_setup'] = `esp_err_t err;\n` +
    `const i2s_config_t i2s_config = {\n` +
    `  .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),\n` +
    `  .sample_rate = ${sampleRate},\n` +
    `  .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,\n` +
    `  .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,\n` +
    `  .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),\n` +
    `  .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,\n` +
    `  .dma_buf_count = 8,\n` +
    `  .dma_buf_len = INMP441_BLOCK_SIZE,\n` +
    `  .use_apll = false,\n` +
    `  .tx_desc_auto_clear = false,\n` +
    `  .fixed_mclk = 0\n` +
    `};\n` +
    `const i2s_pin_config_t pin_config = {\n` +
    `  .bck_io_num = ${bclk},\n` +
    `  .ws_io_num = ${lrclk},\n` +
    `  .data_out_num = I2S_PIN_NO_CHANGE,\n` +
    `  .data_in_num = ${data}\n` +
    `};\n` +
    `err = i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);\n` +
    `if (err != ESP_OK) {\n` +
    `  Serial.printf("INMP441 driver install failed: %d\\n", err);\n` +
    `}\n` +
    `err = i2s_set_pin(I2S_PORT, &pin_config);\n` +
    `if (err != ESP_OK) {\n` +
    `  Serial.printf("INMP441 pin config failed: %d\\n", err);\n` +
    `}\n` +
    `i2s_start(I2S_PORT);`;

  return '';
};

Blockly.Arduino.forBlock['make_arduino_inmp441_get_rms'] = function(block) {
  Blockly.Arduino.definitions_['var_declare_inmp441_rms_vars'] = 'float inmp441_rms = 0.0;';
  Blockly.Arduino.definitions_['var_declare_inmp441_rms_buffer'] = 'int32_t inmp441_samples[INMP441_BLOCK_SIZE];';

  const code = `([] => {
  size_t bytes_read = 0;
  i2s_read(I2S_PORT, inmp441_samples, INMP441_BLOCK_SIZE * 4, &bytes_read, portMAX_DELAY);
  int samples_read = bytes_read / 4;
  if (samples_read > 0) {
    float sum_squares = 0.0;
    for (int i = 0; i < samples_read; i++) {
      int32_t sample_24bit = inmp441_samples[i] >> 8;
      float normalized = (sample_24bit / 8388608.0) * inmp441_gain;
      sum_squares += normalized * normalized;
    }
    inmp441_rms = sqrt(sum_squares / samples_read);
  }
  return inmp441_rms;
})()`;

  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_inmp441_get_db'] = function(block) {
  Blockly.Arduino.definitions_['var_declare_inmp441_db_vars'] = 'float inmp441_db = 0.0;';
  Blockly.Arduino.definitions_['var_declare_inmp441_db_buffer'] = 'int32_t inmp441_db_samples[INMP441_BLOCK_SIZE];';

  const code = `([]() {
  size_t bytes_read = 0;
  i2s_read(I2S_PORT, inmp441_db_samples, INMP441_BLOCK_SIZE * 4, &bytes_read, portMAX_DELAY);
  int samples_read = bytes_read / 4;
  if (samples_read > 0) {
    float sum_squares = 0.0;
    for (int i = 0; i < samples_read; i++) {
      int32_t sample_24bit = inmp441_db_samples[i] >> 8;
      float normalized = (sample_24bit / 8388608.0) * inmp441_gain;
      sum_squares += normalized * normalized;
    }
    float rms = sqrt(sum_squares / samples_read);
    inmp441_db = (rms > 0) ? (20.0 * log10(rms)) : -120.0;
  }
  return inmp441_db;
})()`;

  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_inmp441_get_samples'] = function(block) {
  const size = block.getFieldValue('SIZE_SELECT') || '512';
  const format = block.getFieldValue('FORMAT');

  if (format === 'pcm') {
    Blockly.Arduino.definitions_['var_declare_inmp441_samples_buffer'] = `int32_t *inmp441_pcm_buffer = NULL;\nint inmp441_pcm_size = 0;`;

    const code = `([]() {
  if (inmp441_pcm_buffer) free(inmp441_pcm_buffer);
  inmp441_pcm_size = ${size};
  inmp441_pcm_buffer = (int32_t *)malloc(${size} * 4);
  if (!inmp441_pcm_buffer) return (int32_t *)NULL;
  size_t bytes_read = 0;
  i2s_read(I2S_PORT, inmp441_pcm_buffer, ${size} * 4, &bytes_read, portMAX_DELAY);
  int actual_samples = bytes_read / 4;
  for (int i = 0; i < actual_samples; i++) {
    int32_t sample_24bit = inmp441_pcm_buffer[i] >> 8;
    float normalized = (sample_24bit / 8388608.0) * inmp441_gain;
    inmp441_pcm_buffer[i] = (int32_t)(normalized * 2147483647.0);
  }
  return inmp441_pcm_buffer;
})()`;

    return [code, Blockly.Arduino.ORDER_ATOMIC];
  }

  if (format === 'wav') {
    Blockly.Arduino.definitions_['var_declare_inmp441_wav_buffer'] = `uint8_t *inmp441_wav_buffer = NULL;\nint inmp441_wav_size = 0;`;

    const code = `([]() {
  int wav_header_size = 44;
  int pcm_size = ${size} * 4;
  int total_size = wav_header_size + pcm_size;
  if (inmp441_wav_buffer) free(inmp441_wav_buffer);
  inmp441_wav_buffer = (uint8_t *)malloc(total_size);
  if (!inmp441_wav_buffer) return (uint8_t *)NULL;
  int32_t *pcm_data = (int32_t *)(inmp441_wav_buffer + wav_header_size);
  size_t bytes_read = 0;
  i2s_read(I2S_PORT, pcm_data, pcm_size, &bytes_read, portMAX_DELAY);
  int actual_samples = bytes_read / 4;
  for (int i = 0; i < actual_samples; i++) {
    int32_t sample_24bit = pcm_data[i] >> 8;
    float normalized = (sample_24bit / 8388608.0) * inmp441_gain;
    pcm_data[i] = (int32_t)(normalized * 2147483647.0);
  }
  int data_size = actual_samples * 4;
  memcpy(inmp441_wav_buffer, "RIFF", 4);
  *(uint32_t *)(inmp441_wav_buffer + 4) = total_size - 8;
  memcpy(inmp441_wav_buffer + 8, "WAVE", 4);
  memcpy(inmp441_wav_buffer + 12, "fmt ", 4);
  *(uint32_t *)(inmp441_wav_buffer + 16) = 16;
  *(uint16_t *)(inmp441_wav_buffer + 20) = 1;
  *(uint16_t *)(inmp441_wav_buffer + 22) = 1;
  *(uint32_t *)(inmp441_wav_buffer + 24) = 16000;
  *(uint32_t *)(inmp441_wav_buffer + 28) = 16000 * 2;
  *(uint16_t *)(inmp441_wav_buffer + 32) = 2;
  *(uint16_t *)(inmp441_wav_buffer + 34) = 16;
  memcpy(inmp441_wav_buffer + 36, "data", 4);
  *(uint32_t *)(inmp441_wav_buffer + 40) = data_size;
  inmp441_wav_size = wav_header_size + data_size;
  return inmp441_wav_buffer;
})()`;

    return [code, Blockly.Arduino.ORDER_ATOMIC];
  }

  if (format === 'base64') {
    Blockly.Arduino.definitions_['var_declare_inmp441_base64_buffer'] = `char *inmp441_base64_buffer = NULL;\nint inmp441_base64_size = 0;`;
    Blockly.Arduino.definitions_['func_inmp441_base64_encode'] = `static const char *base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\n` +
      `static void inmp441_base64_encode_chunk(const uint8_t *input, int len, char *output, int *out_len) {\n` +
      `  int j = 0;\n` +
      `  for (int i = 0; i < len; i += 3) {\n` +
      `    int a = input[i];\n` +
      `    int b = (i + 1 < len) ? input[i + 1] : 0;\n` +
      `    int c = (i + 2 < len) ? input[i + 2] : 0;\n` +
      `    output[j++] = base64_chars[(a >> 2) & 0x3F];\n` +
      `    output[j++] = base64_chars[((a << 4) | (b >> 4)) & 0x3F];\n` +
      `    output[j++] = (i + 1 < len) ? base64_chars[((b << 2) | (c >> 6)) & 0x3F] : '=';\n` +
      `    output[j++] = (i + 2 < len) ? base64_chars[c & 0x3F] : '=';\n` +
      `  }\n` +
      `  *out_len = j;\n` +
      `}`;

    const code = `([]() {
  int pcm_size = ${size} * 4;
  int wav_header_size = 44;
  int total_size = wav_header_size + pcm_size;
  uint8_t *wav_data = (uint8_t *)malloc(total_size);
  if (!wav_data) return (char *)"";
  int32_t *pcm_data = (int32_t *)(wav_data + wav_header_size);
  size_t bytes_read = 0;
  i2s_read(I2S_PORT, pcm_data, pcm_size, &bytes_read, portMAX_DELAY);
  int actual_samples = bytes_read / 4;
  for (int i = 0; i < actual_samples; i++) {
    int32_t sample_24bit = pcm_data[i] >> 8;
    float normalized = (sample_24bit / 8388608.0) * inmp441_gain;
    pcm_data[i] = (int32_t)(normalized * 2147483647.0);
  }
  *(uint32_t *)(wav_data + 4) = total_size - 8;
  memcpy(wav_data, "RIFF", 4);
  memcpy(wav_data + 8, "WAVE", 4);
  memcpy(wav_data + 12, "fmt ", 4);
  *(uint32_t *)(wav_data + 16) = 16;
  *(uint16_t *)(wav_data + 20) = 1;
  *(uint16_t *)(wav_data + 22) = 1;
  *(uint32_t *)(wav_data + 24) = 16000;
  *(uint32_t *)(wav_data + 28) = 16000 * 2;
  *(uint16_t *)(wav_data + 32) = 2;
  *(uint16_t *)(wav_data + 34) = 16;
  memcpy(wav_data + 36, "data", 4);
  *(uint32_t *)(wav_data + 40) = actual_samples * 4;
  int b64_len = ((total_size + 2) / 3) * 4 + 1;
  if (inmp441_base64_buffer) free(inmp441_base64_buffer);
  inmp441_base64_buffer = (char *)malloc(b64_len);
  if (!inmp441_base64_buffer) { free(wav_data); return (char *)""; }
  int out_len = 0;
  inmp441_base64_encode_chunk(wav_data, total_size, inmp441_base64_buffer, &out_len);
  inmp441_base64_buffer[out_len] = '\\0';
  inmp441_base64_size = out_len;
  free(wav_data);
  return inmp441_base64_buffer;
})()`;

    return [code, Blockly.Arduino.ORDER_ATOMIC];
  }

  return ['NULL', Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_inmp441_recording'] = function(block) {
  const action = block.getFieldValue('ACTION');
  let filename = Blockly.Arduino.valueToCode(block, 'FILENAME', Blockly.Arduino.ORDER_ATOMIC) || '"/recording.wav"';
  const format = block.getFieldValue('FORMAT') || 'pcm';
  const size = Blockly.Arduino.valueToCode(block, 'SIZE', Blockly.Arduino.ORDER_ATOMIC) || '512';

  if (filename.startsWith('"/sd/')) {
    filename = filename.replace('"/sd/', '"/');
  }

  if (action === 'start') {
    Blockly.Arduino.definitions_['include_sd'] = '#include <SD.h>';
    Blockly.Arduino.definitions_['var_declare_sd_file'] = 'File inmp441_audio_file;';
    Blockly.Arduino.definitions_['var_declare_sd_state'] = 'bool inmp441_is_recording = false;\nuint32_t inmp441_data_bytes = 0;';
    Blockly.Arduino.definitions_['var_declare_inmp441_sd_buffer'] = `int32_t inmp441_i2s_buffer[${size}];\nint16_t inmp441_pcm_buffer[${size}];`;
    Blockly.Arduino.definitions_['var_declare_inmp441_file_index'] = 'int inmp441_file_index = 0;';
    Blockly.Arduino.definitions_['var_declare_inmp441_filename'] = 'char inmp441_current_filename[64];';

    if (!Blockly.Arduino.definitions_['var_declare_inmp441_port']) {
      Blockly.Arduino.definitions_['include_inmp441'] = '#include <driver/i2s.h>';
      Blockly.Arduino.definitions_['var_declare_inmp441_port'] = 'const i2s_port_t I2S_PORT = I2S_NUM_0;';
      Blockly.Arduino.definitions_['var_declare_inmp441_blocksize'] = 'const int INMP441_BLOCK_SIZE = 512;';
      Blockly.Arduino.definitions_['var_declare_inmp441_gain'] = 'float inmp441_gain = 1.0;';

      Blockly.Arduino.setups_['inmp441_setup'] = `esp_err_t err;\n` +
        `const i2s_config_t i2s_config = {\n` +
        `  .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),\n` +
        `  .sample_rate = 16000,\n` +
        `  .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,\n` +
        `  .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,\n` +
        `  .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),\n` +
        `  .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,\n` +
        `  .dma_buf_count = 8,\n` +
        `  .dma_buf_len = INMP441_BLOCK_SIZE,\n` +
        `  .use_apll = false,\n` +
        `  .tx_desc_auto_clear = false,\n` +
        `  .fixed_mclk = 0\n` +
        `};\n` +
        `const i2s_pin_config_t pin_config = {\n` +
        `  .bck_io_num = 14,\n` +
        `  .ws_io_num = 15,\n` +
        `  .data_out_num = I2S_PIN_NO_CHANGE,\n` +
        `  .data_in_num = 32\n` +
        `};\n` +
        `err = i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);\n` +
        `if (err != ESP_OK) {\n` +
        `  Serial.printf("INMP441 driver install failed: %d\\n", err);\n` +
        `}\n` +
        `err = i2s_set_pin(I2S_PORT, &pin_config);\n` +
        `if (err != ESP_OK) {\n` +
        `  Serial.printf("INMP441 pin config failed: %d\\n", err);\n` +
        `}\n` +
        `i2s_start(I2S_PORT);`;
    }

    let initCode = `if (!inmp441_is_recording) {\n` +
      `  do {\n` +
      `    sprintf(inmp441_current_filename, "/recording_%03d.wav", inmp441_file_index);\n` +
      `    inmp441_file_index++;\n` +
      `  } while (SD.exists(inmp441_current_filename) && inmp441_file_index < 1000);\n` +
      `  inmp441_audio_file = SD.open(inmp441_current_filename, FILE_WRITE);\n` +
      `  if (inmp441_audio_file) {\n` +
      `    Serial.printf("Recording to: %s\\n", inmp441_current_filename);\n` +
      `    uint8_t wav_header[44] = {0};\n` +
      `    memcpy(wav_header, "RIFF", 4);\n` +
      `    *(uint32_t *)(wav_header + 4) = 0;\n` +
      `    memcpy(wav_header + 8, "WAVE", 4);\n` +
      `    memcpy(wav_header + 12, "fmt ", 4);\n` +
      `    *(uint32_t *)(wav_header + 16) = 16;\n` +
      `    *(uint16_t *)(wav_header + 20) = 1;\n` +
      `    *(uint16_t *)(wav_header + 22) = 1;\n` +
      `    *(uint32_t *)(wav_header + 24) = 16000;\n` +
      `    *(uint32_t *)(wav_header + 28) = 16000 * 2;\n` +
      `    *(uint16_t *)(wav_header + 32) = 2;\n` +
      `    *(uint16_t *)(wav_header + 34) = 16;\n` +
      `    memcpy(wav_header + 36, "data", 4);\n` +
      `    *(uint32_t *)(wav_header + 40) = 0;\n` +
      `    inmp441_audio_file.write(wav_header, 44);\n` +
      `    inmp441_is_recording = true;\n` +
      `    inmp441_data_bytes = 0;\n` +
      `  } else {\n` +
      `    Serial.printf("Failed to open file: %s\\n", inmp441_current_filename);\n` +
      `  }\n` +
      `}\n`;

    let writeCode = `if (inmp441_is_recording && inmp441_audio_file) {\n` +
      `  size_t bytes_read = 0;\n` +
      `  i2s_read(I2S_PORT, inmp441_i2s_buffer, ${size} * 4, &bytes_read, 100 / portTICK_PERIOD_MS);\n` +
      `  int actual_samples = bytes_read / 4;\n` +
      `  if (actual_samples > 0) {\n` +
      `    for (int i = 0; i < actual_samples; i++) {\n` +
      `      int32_t sample = inmp441_i2s_buffer[i] >> 16;\n` +
      `      sample = (int32_t)(sample * inmp441_gain);\n` +
      `      if (sample > 32767) sample = 32767;\n` +
      `      if (sample < -32768) sample = -32768;\n` +
      `      inmp441_pcm_buffer[i] = (int16_t)sample;\n` +
      `    }\n` +
      `    inmp441_audio_file.write((uint8_t *)inmp441_pcm_buffer, actual_samples * 2);\n` +
      `    inmp441_data_bytes += actual_samples * 2;\n` +
      `  }\n` +
      `}`;

    return initCode + writeCode;
  } else {
    let code = `if (inmp441_is_recording && inmp441_audio_file) {\n` +
      `  inmp441_is_recording = false;\n` +
      `  uint32_t file_size = inmp441_audio_file.size();\n` +
      `  inmp441_audio_file.seek(4);\n` +
      `  uint32_t riff_size = file_size - 8;\n` +
      `  inmp441_audio_file.write((uint8_t *)&riff_size, 4);\n` +
      `  inmp441_audio_file.seek(40);\n` +
      `  uint32_t data_size = inmp441_data_bytes;\n` +
      `  inmp441_audio_file.write((uint8_t *)&data_size, 4);\n` +
      `  inmp441_audio_file.close();\n` +
      `  Serial.printf("Recording saved: %lu bytes\\n", file_size);\n` +
      `}`;
    return code;
  }
};

Blockly.Arduino.forBlock['make_arduino_inmp441_sample_size'] = function(block) {
  const size = block.getFieldValue('SIZE_SELECT') || '512';
  return [size, Blockly.Arduino.ORDER_ATOMIC];
};




Blockly.Arduino.forBlock['make_arduino_stepper_begin'] = function () {
    var text_stepper_name = this.getFieldValue('stepper_name');
    var value_stepper_in1 = Blockly.Arduino.valueToCode(this, 'stepper_in1', Blockly.Arduino.ORDER_ATOMIC);
    var value_stepper_in2 = Blockly.Arduino.valueToCode(this, 'stepper_in2', Blockly.Arduino.ORDER_ATOMIC);
    var value_stepper_in3 = Blockly.Arduino.valueToCode(this, 'stepper_in3', Blockly.Arduino.ORDER_ATOMIC);
    var value_stepper_in4 = Blockly.Arduino.valueToCode(this, 'stepper_in4', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_AccelStepper'] = '#include <AccelStepper.h>';

    Blockly.Arduino.definitions_['var_declare_' + text_stepper_name] = 'AccelStepper ' + text_stepper_name + '(AccelStepper::FULL4WIRE, ' + value_stepper_in1 + ', ' + value_stepper_in2 + ', ' + value_stepper_in3 + ', ' + value_stepper_in4 + ', true);';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_stepper_begin_mode'] = function () {
    var dropdown_stepper_begin_mode = this.getFieldValue('stepper_begin_mode');
    var statements_stepper_begin_mode_data = Blockly.Arduino.statementToCode(this, 'stepper_begin_mode_data');

    statements_stepper_begin_mode_data = statements_stepper_begin_mode_data.substring(2, statements_stepper_begin_mode_data.length - 1);
    Blockly.Arduino.setups_['setup_Stepper_' + statements_stepper_begin_mode_data + '_' + dropdown_stepper_begin_mode] = statements_stepper_begin_mode_data;
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_stepper_set_speed_acceleration'] = function () {
    var value_set_speed_acceleration_data = Blockly.Arduino.valueToCode(this, 'set_speed_acceleration_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_stepper_name = this.getFieldValue('stepper_name');
    var dropdown_set_type = this.getFieldValue('set_type');
    var code = text_stepper_name + '.' + dropdown_set_type + '(' + value_set_speed_acceleration_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_stepper_setPinsInverted'] = function () {
    var text_stepper_name = this.getFieldValue('stepper_name');
    var dropdown_setPinsInverted_mode = this.getFieldValue('setPinsInverted_mode');
    var code = '';
    if (dropdown_setPinsInverted_mode == 'A_false' || dropdown_setPinsInverted_mode == 'A_true')
        code = text_stepper_name + '.setPinsInverted(' + dropdown_setPinsInverted_mode.substring(2) + ', false, false);\n';
    else
        code = text_stepper_name + '.setPinsInverted(false, ' + dropdown_setPinsInverted_mode.substring(2) + ', false);\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_stepper_get_position_speed'] = function () {
    var text_stepper_name = this.getFieldValue('stepper_name');
    var dropdown_get_position_speed_type = this.getFieldValue('get_position_speed_type');
    var code = text_stepper_name + '.' + dropdown_get_position_speed_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_stepper_runToNewPosition'] = function () {
    var value_stepper_runToNewPosition_data = Blockly.Arduino.valueToCode(this, 'stepper_runToNewPosition_data', Blockly.Arduino.ORDER_ATOMIC);
    var text_stepper_name = this.getFieldValue('stepper_name');
    var code = text_stepper_name + '.runToNewPosition(' + value_stepper_runToNewPosition_data + ');\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_stepper_run'] = function () {
    var text_stepper_name = this.getFieldValue('stepper_name');
    var dropdown_run_mode = this.getFieldValue('run_mode');
    var code = text_stepper_name + '.' + dropdown_run_mode + '();\n';
    return code;
};

//初始化步进电机
Blockly.Arduino.forBlock['make_arduino_accelstepper_begin'] = function () {
    this.setTooltip("初始化步进电机，使用单片机上的IO");
    var dropdown_type = this.getFieldValue('type');
    var text_name = this.getFieldValue('name');
    var value_pin1 = Blockly.Arduino.valueToCode(this, 'pin1', Blockly.Arduino.ORDER_ATOMIC);
    var value_pin2 = Blockly.Arduino.valueToCode(this, 'pin2', Blockly.Arduino.ORDER_ATOMIC);
    var value_pin3 = Blockly.Arduino.valueToCode(this, 'pin3', Blockly.Arduino.ORDER_ATOMIC);
    var value_pin4 = Blockly.Arduino.valueToCode(this, 'pin4', Blockly.Arduino.ORDER_ATOMIC);
    var value_enable = Blockly.Arduino.valueToCode(this, 'enable', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['include_AccelStepper'] = '#include <AccelStepper.h>';

    Blockly.Arduino.definitions_['var_declare_' + text_name] = 'AccelStepper ' + text_name + '(' + dropdown_type + ', ' + value_pin1 + ', ' + value_pin2 + ', ' + value_pin3 + ', ' + value_pin4 + ', ' + value_enable + ');';
    var code = '';
    return code;
};

//初始化步进电机 使用74HC595/PCF8574/MCP23017上的IO口
Blockly.Arduino.forBlock['make_arduino_accelstepper_begin_1'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var text_name = this.getFieldValue('name');
    var dropdown_io_type = this.getFieldValue('io_type');
    var text_io_name = this.getFieldValue('io_name');
    var value_pin1 = Blockly.Arduino.valueToCode(this, 'pin1', Blockly.Arduino.ORDER_ATOMIC);
    var value_pin2 = Blockly.Arduino.valueToCode(this, 'pin2', Blockly.Arduino.ORDER_ATOMIC);
    var value_pin3 = Blockly.Arduino.valueToCode(this, 'pin3', Blockly.Arduino.ORDER_ATOMIC);
    var value_pin4 = Blockly.Arduino.valueToCode(this, 'pin4', Blockly.Arduino.ORDER_ATOMIC);
    var value_enable = Blockly.Arduino.valueToCode(this, 'enable', Blockly.Arduino.ORDER_ATOMIC);

    if (dropdown_io_type == '74HC595') {
        Blockly.Arduino.definitions_['include_ShiftRegister74HC595'] = '#include <ShiftRegister74HC595.h>';
        Blockly.Arduino.definitions_['include_AccelStepper_74HC595'] = '#include <AccelStepper_74HC595.h>';
        Blockly.Arduino.definitions_['var_declare_' + text_name] = 'AccelStepper_74HC595 ' + text_name + '(&' + text_io_name + ', ' + dropdown_type + ', ' + value_pin1 + ', ' + value_pin2 + ', ' + value_pin3 + ', ' + value_pin4 + ', ' + value_enable + ');';
    }
    else if (dropdown_io_type == 'PCF8574(硬I2C)') {
        Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
        Blockly.Arduino.definitions_['include_PCF8574'] = '#include "PCF8574.h"';
        Blockly.Arduino.definitions_['include_AccelStepper_PCF8574'] = '#include <AccelStepper_PCF8574.h>';
        Blockly.Arduino.definitions_['var_declare_' + text_name] = 'AccelStepper_PCF8574 ' + text_name + '(&' + text_io_name + ', ' + dropdown_type + ', ' + value_pin1 + ', ' + value_pin2 + ', ' + value_pin3 + ', ' + value_pin4 + ', ' + value_enable + ');';
    }
    else if (dropdown_io_type == 'PCF8574(软I2C)') {
        Blockly.Arduino.definitions_['nclude_Wire'] = '#include <Wire.h>';
        Blockly.Arduino.definitions_['nclude_PCF8574'] = '#include "PCF8574.h"';
        Blockly.Arduino.definitions_['include_AccelStepper_PCF8574'] = '#include <AccelStepper_PCF8574.h>';
        Blockly.Arduino.definitions_['var_declare_' + text_name] = 'AccelStepper_PCF8574 ' + text_name + '(&' + text_io_name + ', ' + dropdown_type + ', ' + value_pin1 + ', ' + value_pin2 + ', ' + value_pin3 + ', ' + value_pin4 + ', ' + value_enable + ');';
    }
    else if (dropdown_io_type == 'MCP23017(硬I2C)') {
        Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
        Blockly.Arduino.definitions_['include_Adafruit_MCP23017'] = '#include "Adafruit_MCP23017.h"';
        Blockly.Arduino.definitions_['include_AccelStepper_MCP23017'] = '#include <AccelStepper_MCP23017.h>';
        Blockly.Arduino.definitions_['var_declare_' + text_name] = 'AccelStepper_MCP23017 ' + text_name + '(&' + text_io_name + ', ' + dropdown_type + ', ' + value_pin1 + ', ' + value_pin2 + ', ' + value_pin3 + ', ' + value_pin4 + ', ' + value_enable + ');';
    }
    else if (dropdown_io_type == 'MCP23017(软I2C)') {
        Blockly.Arduino.definitions_['include_SoftwareWire'] = '#include <SoftwareWire.h>';
        Blockly.Arduino.definitions_['include_Adafruit_MCP23017_Soft'] = '#include "Adafruit_MCP23017_Soft.h"';
        Blockly.Arduino.definitions_['include_AccelStepper_MCP23017_Soft'] = '#include <AccelStepper_MCP23017_Soft.h>';
        Blockly.Arduino.definitions_['var_declare_' + text_name] = 'AccelStepper_MCP23017_Soft ' + text_name + '(&' + text_io_name + ', ' + dropdown_type + ', ' + value_pin1 + ', ' + value_pin2 + ', ' + value_pin3 + ', ' + value_pin4 + ', ' + value_enable + ');';
    }
    var code = '';
    return code;
};

//步进电机 有返回值函数
Blockly.Arduino.forBlock['make_arduino_accelstepper_get_data'] = function () {
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    if (dropdown_type == 'isRunning')
        this.setTooltip("检查电机是否正在向目标运行，如果速度不是零或者不在目标位置，则为true，返回数据的类型为boolean");
    else if (dropdown_type == 'run')
        this.setTooltip("每次调用此函数最多只会执行一个步进，返回数据的类型为boolean");
    else if (dropdown_type == 'runSpeed')
        this.setTooltip("每次调用此函数最多只会执行一个步进，返回数据的类型为boolean");
    else if (dropdown_type == 'runSpeedToPosition')
        this.setTooltip("以当前选定的速度运行，直到到达目标位置，不实现加速，返回数据的类型为boolean");
    else if (dropdown_type == 'speed')
        this.setTooltip("获取当前的瞬时速度，返回数据的类型为float");
    else if (dropdown_type == 'maxSpeed')
        this.setTooltip("获取最大速度，返回数据的类型为float");
    else if (dropdown_type == 'targetPosition')
        this.setTooltip("获取目标位置，返回数据的类型为long");
    else if (dropdown_type == 'currentPosition')
        this.setTooltip("获取当前位置，返回数据的类型为long");
    else
        this.setTooltip("获取从当前位置到目标位置的距离，返回数据的类型为long");
    var code = text_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//步进电机 启用输出/禁用输出/停止运动/以加减速方式运行到目标位置
Blockly.Arduino.forBlock['make_arduino_accelstepper_set'] = function () {
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    if (dropdown_type == 'stop')
        this.setTooltip("停止步进电机的运动");
    else if (dropdown_type == 'runToPosition')
        this.setTooltip("将电机(带加/减速)移动到目标位置，并阻塞，直到到达目标位置。不要在事件循环中使用它，因为它会阻塞");
    else if (dropdown_type == 'enableOutputs')
        this.setTooltip("启用输出");
    else
        this.setTooltip("禁用输出，可以关闭电机线圈的电源，节约电能");
    var code = text_name + '.' + dropdown_type + '();';
    return code;
};
//步进电机 设置 最大速度/加速度/当前速度/当前位置/最小脉冲宽度
Blockly.Arduino.forBlock['make_arduino_accelstepper_set_data'] = function () {
    this.setTooltip("设置最大速度/加速度/当前速度/当前位置/最小脉冲宽度/输出管脚");
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.' + dropdown_type + '(' + value_data + ');\n';
    return code;
};

//步进电机 移动
Blockly.Arduino.forBlock['make_arduino_accelstepper_move'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    if (dropdown_type == 'moveTo')
        this.setTooltip("使用此函数后，必须要调用 带加减速运行 函数来运行步进电机，如果想使用恒速移动，在调用此函数之后需设置速度");
    else if (dropdown_type == 'move')
        this.setTooltip("设置相对于当前位置的目标位置");
    else if (dropdown_type == 'runToNewPosition')
        this.setTooltip("将电机(带加速/减速)移动到新的目标位置，并阻塞，直到到达新目标位置。不要在事件循环中使用它，因为它会阻塞");
    var code = text_name + '.' + dropdown_type + '(' + value_data + ');\n';
    return code;
};

//步进电机 翻转管脚
Blockly.Arduino.forBlock['make_arduino_accelstepper_setPinsInverted_3'] = function () {
    this.setTooltip("设置步进驱动器引脚的反转");
    var text_name = this.getFieldValue('name');
    var value_directionInvert = Blockly.Arduino.valueToCode(this, 'directionInvert', Blockly.Arduino.ORDER_ATOMIC);
    var value_stepInvert = Blockly.Arduino.valueToCode(this, 'stepInvert', Blockly.Arduino.ORDER_ATOMIC);
    var value_enableInvert = Blockly.Arduino.valueToCode(this, 'enableInvert', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.setPinsInverted(' + value_directionInvert + ', ' + value_stepInvert + ', ' + value_enableInvert + ');\n';
    return code;
};

//步进电机 翻转管脚 - 1
Blockly.Arduino.forBlock['make_arduino_accelstepper_setPinsInverted_5'] = function () {
    this.setTooltip("设置步进驱动器引脚的反转");
    var text_name = this.getFieldValue('name');
    var value_pin1 = Blockly.Arduino.valueToCode(this, 'pin1', Blockly.Arduino.ORDER_ATOMIC);
    var value_pin2 = Blockly.Arduino.valueToCode(this, 'pin2', Blockly.Arduino.ORDER_ATOMIC);
    var value_pin3 = Blockly.Arduino.valueToCode(this, 'pin3', Blockly.Arduino.ORDER_ATOMIC);
    var value_pin4 = Blockly.Arduino.valueToCode(this, 'pin4', Blockly.Arduino.ORDER_ATOMIC);
    var value_enable = Blockly.Arduino.valueToCode(this, 'enable', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.setPinsInverted(' + value_pin1 + ', ' + value_pin2 + ', ' + value_pin3 + ', ' + value_pin4 + ', ' + value_enable + ');\n';
    return code;
};

//初始化舵机
Blockly.Arduino.forBlock['make_arduino_servo_begin'] = function () {
    this.setTooltip("初始化舵机，返回数据的类型为boolean，成功返回通道号，失败则返回0");
    var text_name = this.getFieldValue('name');
    var value_pin = Blockly.Arduino.valueToCode(this, 'pin', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['include_' + 'VarSpeedServo'] = '#include <VarSpeedServo.h>';
    Blockly.Arduino.definitions_['var_declare_' + text_name] = 'VarSpeedServo ' + text_name + ';';
    //Blockly.Arduino.setups_['varspeedservo_'+text_name] = text_name+'.attach('+value_pin+');';
    var code = text_name + '.attach(' + value_pin + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化舵机 可设置最小角度和最大角度
Blockly.Arduino.forBlock['make_arduino_servo_begin_1'] = function () {
    this.setTooltip("初始化舵机，返回数据的类型为boolean，成功返回通道号，失败则返回0");
    var text_name = this.getFieldValue('name');
    var value_pin = Blockly.Arduino.valueToCode(this, 'pin', Blockly.Arduino.ORDER_ATOMIC);
    var value_min = Blockly.Arduino.valueToCode(this, 'min', Blockly.Arduino.ORDER_ATOMIC);
    var value_max = Blockly.Arduino.valueToCode(this, 'max', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['include_' + 'VarSpeedServo'] = '#include <VarSpeedServo.h>';
    Blockly.Arduino.definitions_['var_declare_' + text_name] = 'VarSpeedServo ' + text_name + ';';
    //Blockly.Arduino.setups_['varspeedservo_'+text_name] = text_name+'.attach('+value_pin+', '+value_min+', '+value_max+');';
    var code = text_name + '.attach(' + value_pin + ', ' + value_min + ', ' + value_max + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//舵机 设置角度
Blockly.Arduino.forBlock['make_arduino_servo_write'] = function () {
    this.setTooltip("舵机 设置当前的角度(0~180°)，输入值超出544视为脉冲宽度，小于则视为角度，不阻塞程序运行");
    var text_name = this.getFieldValue('name');
    var value_value = Blockly.Arduino.valueToCode(this, 'value', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.write(' + value_value + ');\n';
    return code;
};

//舵机 设置角度和速度
Blockly.Arduino.forBlock['make_arduino_servo_write_1'] = function () {
    this.setTooltip("舵机 设置当前的角度(0~180°)，输入值超出544视为脉冲宽度，小于则视为角度，不阻塞程序运行");
    var text_name = this.getFieldValue('name');
    var value_value = Blockly.Arduino.valueToCode(this, 'value', Blockly.Arduino.ORDER_ATOMIC);
    var value_speed = Blockly.Arduino.valueToCode(this, 'speed', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.write(' + value_value + ', ' + value_speed + ');\n';
    return code;
};

//舵机 设置角度和速度以及选择是否阻塞
Blockly.Arduino.forBlock['make_arduino_servo_write_2'] = function () {
    this.setTooltip("舵机 设置当前的角度(0~180°)，输入值超出544视为脉冲宽度，小于则视为角度");
    var text_name = this.getFieldValue('name');
    var value_value = Blockly.Arduino.valueToCode(this, 'value', Blockly.Arduino.ORDER_ATOMIC);
    var value_speed = Blockly.Arduino.valueToCode(this, 'speed', Blockly.Arduino.ORDER_ATOMIC);
    var value_wait = Blockly.Arduino.valueToCode(this, 'wait', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.write(' + value_value + ', ' + value_speed + ', ' + value_wait + ');\n';
    return code;
};

//舵机 设置脉冲宽度
Blockly.Arduino.forBlock['make_arduino_servo_writeMicroseconds'] = function () {
    this.setTooltip("舵机 设置脉冲宽度，默认的最小脉宽为544微秒，最大脉宽为2400微秒");
    var value_value = Blockly.Arduino.valueToCode(this, 'value', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
    var code = text_name + '.writeMicroseconds(' + value_value + ');\n';
    return code;
};

//舵机 获取数据
Blockly.Arduino.forBlock['make_arduino_servo_read'] = function () {
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    if (dropdown_type == 'read')
        this.setTooltip("舵机 获取当前角度，返回数据的类型为int");
    else if (dropdown_type == 'readMicroseconds')
        this.setTooltip("舵机 获取当前脉宽，返回数据的类型为int");
    else if (dropdown_type == 'isMoving')
        this.setTooltip("舵机 正在移动?，返回数据的类型为boolean");
    else
        this.setTooltip("舵机 舵机连上控制管脚?，返回数据的类型为boolean");
    var code = text_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//舵机 执行某些函数
Blockly.Arduino.forBlock['make_arduino_servo_set'] = function () {
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
    if (dropdown_type == 'stop')
        this.setTooltip("舵机 停止移动");
    else if (dropdown_type == 'wait')
        this.setTooltip("舵机 等待移动完成");
    else if (dropdown_type == 'sequenceStop')
        this.setTooltip("舵机 停止执行动作组");
    else
        this.setTooltip("舵机 释放管脚");
    var code = text_name + '.' + dropdown_type + '();\n';
    return code;
};

//舵机 建立一个动作组
Blockly.Arduino.forBlock['make_arduino_servo_action_group'] = function () {
    var text_name = this.getFieldValue('name');
    var statements_data = Blockly.Arduino.statementToCode(this, 'data');
    if (statements_data)
        statements_data = statements_data.substring(2, statements_data.length - 1);
    Blockly.Arduino.definitions_['include_' + 'VarSpeedServo'] = '#include <VarSpeedServo.h>';
    Blockly.Arduino.definitions_['var_declare_' + text_name] = 'servoSequencePoint ' + text_name + '[] = {' + statements_data + '};';
    var code = '';
    return code;
};

//舵机 动作组里数据定义
Blockly.Arduino.forBlock['make_arduino_servo_action_group_data'] = function () {
    var text_angle = this.getFieldValue('angle');
    var text_speed = this.getFieldValue('speed');
    var surround_parent = this.getSurroundParent();
    var code = '';
    if (surround_parent && surround_parent.type == 'make_arduino_servo_action_group') {
        this.setWarningText(null);
        code = '{' + text_angle + ',' + text_speed + '},';
    }
    else {
        this.setWarningText("此块需放到创建动作组块下");
    }
    return code;
};

//舵机 循环执行某一动作组
Blockly.Arduino.forBlock['make_arduino_servo_sequencePlay'] = function () {
    this.setTooltip("舵机 从索引为0的动作开始，循环执行某一动作组里的动作，返回数据的类型为uint8_t");
    var text_name = this.getFieldValue('name');
    var value_sequencein = Blockly.Arduino.valueToCode(this, 'sequencein', Blockly.Arduino.ORDER_ATOMIC);
    var value_numpositions = Blockly.Arduino.valueToCode(this, 'numpositions', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.sequencePlay(' + value_sequencein + ', ' + value_numpositions + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//舵机 执行某一动作组，可设置是否循环
Blockly.Arduino.forBlock['make_arduino_servo_sequencePlay_1'] = function () {
    this.setTooltip("舵机 从某个索引的动作开始，执行某一动作组里的动作，返回数据的类型为uint8_t");
    var text_name = this.getFieldValue('name');
    var value_sequencein = Blockly.Arduino.valueToCode(this, 'sequencein', Blockly.Arduino.ORDER_ATOMIC);
    var value_numpositions = Blockly.Arduino.valueToCode(this, 'numpositions', Blockly.Arduino.ORDER_ATOMIC);
    var value_loop = Blockly.Arduino.valueToCode(this, 'loop', Blockly.Arduino.ORDER_ATOMIC);
    var value_startPos = Blockly.Arduino.valueToCode(this, 'startPos', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_name + '.sequencePlay(' + value_sequencein + ', ' + value_numpositions + ', ' + value_loop + ', ' + value_startPos + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化DFPlayer Mini
Blockly.Arduino.forBlock['make_arduino_dfplayer_mini_begin'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var value_dfplayer_pin = Blockly.Arduino.valueToCode(this, 'dfplayer_pin', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['include_Arduino'] = '#include "Arduino.h"';
    Blockly.Arduino.definitions_['include_DFRobotDFPlayerMini'] = '#include "DFRobotDFPlayerMini.h"';
    Blockly.Arduino.definitions_['var_declare_DFPlayerMini_' + text_dfplayer_name] = 'DFRobotDFPlayerMini ' + text_dfplayer_name + ';';
    Blockly.Arduino.setups_['setup_DFPlayerMini_' + text_dfplayer_name] = '' + text_dfplayer_name + '.begin(' + value_dfplayer_pin + ');';
    var code = '';
    return code;
};

//定义DFPlayer Mini 所使用的串口类型
Blockly.Arduino.forBlock['make_arduino_dfplayer_mini_pin'] = function () {
    var dropdown_pin_type = this.getFieldValue('pin_type');
    Blockly.Arduino.definitions_['include_SoftwareSerial'] = '#include "SoftwareSerial.h"';
    var code = dropdown_pin_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DFPlayer Mini 所使用的串口类型（ESP32初始化）2020_09_10
Blockly.Arduino.forBlock['make_arduino_dfplayer_mini_esp32_begin'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var dropdown_dfplayer_serial = this.getFieldValue('dfplayer_serial');
    Blockly.Arduino.definitions_['include_Arduino'] = '#include "Arduino.h"';
    Blockly.Arduino.definitions_['include_DFRobotDFPlayerMini'] = '#include "DFRobotDFPlayerMini.h"';
    Blockly.Arduino.definitions_['var_declare_DFPlayerMini_' + text_dfplayer_name] = 'DFRobotDFPlayerMini ' + text_dfplayer_name + ';';
    Blockly.Arduino.setups_['setup_DFPlayerMini_' + text_dfplayer_name] = '' + text_dfplayer_name + '.begin(' + dropdown_dfplayer_serial + ');';
    var code = '';
    return code;
};

//DFPlayer Mini 设置串口通信的超时时间
Blockly.Arduino.forBlock['make_arduino_dfplayer_mini_setTimeOut'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var value_timeout_data = Blockly.Arduino.valueToCode(this, 'timeout_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_dfplayer_name + '.setTimeOut(' + value_timeout_data + ');\n';
    return code;
};

//DFPlayer Mini 设置音量
Blockly.Arduino.forBlock['make_arduino_dfplayer_mini_volume'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var value_volume_data = Blockly.Arduino.valueToCode(this, 'volume_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_dfplayer_name + '.volume(' + value_volume_data + ');\n';
    return code;
};

//DFPlayer Mini 音量+|-
Blockly.Arduino.forBlock['make_arduino_dfplayer_mini_volume_up_down'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var dropdown_volume_type = this.getFieldValue('volume_type');
    var code = '' + text_dfplayer_name + '.' + dropdown_volume_type + '();\n';
    return code;
};

//DFPlayer Mini 设置音效
Blockly.Arduino.forBlock['make_arduino_dfplayer_mini_EQ'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var value_eq_data = Blockly.Arduino.valueToCode(this, 'eq_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_dfplayer_name + '.EQ(' + value_eq_data + ');\n';
    return code;
};

//DFPlayer Mini 定义音效类型
Blockly.Arduino.forBlock['make_arduino_dfplayer_mini_EQ_type'] = function () {
    var dropdown_eq_type = this.getFieldValue('eq_type');
    var code = dropdown_eq_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DFPlayer Mini 指定播放设备
Blockly.Arduino.forBlock['make_arduino_dfplayer_mini_outputDevice'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var value_outputdevice_data = Blockly.Arduino.valueToCode(this, 'outputdevice_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_dfplayer_name + '.outputDevice(' + value_outputdevice_data + ');\n';
    return code;
};

//DFPlayer Mini 定义播放设备类型
Blockly.Arduino.forBlock['make_arduino_dfplayer_mini_outputDevice_type'] = function () {
    var dropdown_outputdevice_type = this.getFieldValue('outputdevice_type');
    var code = dropdown_outputdevice_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DFPlayer Mini 设置-1
Blockly.Arduino.forBlock['make_arduino_dfplayer_set_1'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var dropdown_set_data = this.getFieldValue('set_data');
    var code = '' + text_dfplayer_name + '.' + dropdown_set_data + '();\n';
    return code;
};

//DFPlayer Mini 播放和循环指定曲目
Blockly.Arduino.forBlock['make_arduino_dfplayer_play_loop'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var value_play_data = Blockly.Arduino.valueToCode(this, 'play_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_play_type = this.getFieldValue('play_type');
    var code = '' + text_dfplayer_name + '.' + dropdown_play_type + '(' + value_play_data + ');\n';
    return code;
};

//DFPlayer Mini 播放指定文件夹下的曲目
Blockly.Arduino.forBlock['make_arduino_dfplayer_playFolder'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var value_fold_data = Blockly.Arduino.valueToCode(this, 'fold_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_fold_type = this.getFieldValue('fold_type');
    var value_play_data = Blockly.Arduino.valueToCode(this, 'play_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_dfplayer_name + '.' + dropdown_fold_type + '(' + value_fold_data + ', ' + value_play_data + ');\n';
    return code;
};

//DFPlayer Mini 循环播放指定文件夹下的曲目
Blockly.Arduino.forBlock['make_arduino_dfplayer_loopFolder'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var value_fold_data = Blockly.Arduino.valueToCode(this, 'fold_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_dfplayer_name + '.loopFolder(' + value_fold_data + ');\n';
    return code;
};

//DFPlayer Mini 获取当前信息
Blockly.Arduino.forBlock['make_arduino_dfplayer_read_now'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var dropdown_read_type = this.getFieldValue('read_type');
    var code = '' + text_dfplayer_name + '.' + dropdown_read_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DFPlayer Mini 获取U盘|SD卡|FLASH的总文件数
Blockly.Arduino.forBlock['make_arduino_dfplayer_readFileCounts'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var value_device_type = Blockly.Arduino.valueToCode(this, 'device_type', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_play_data = this.getFieldValue('play_data');
    var code = '' + text_dfplayer_name + '.' + dropdown_play_data + '(' + value_device_type + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//DFPlayer Mini 获取指定文件夹下的文件数
Blockly.Arduino.forBlock['make_arduino_dfplayer_readFileCountsInFolder'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var value_folder_data = Blockly.Arduino.valueToCode(this, 'folder_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_dfplayer_name + '.readFileCountsInFolder(' + value_folder_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_dfplayer_available'] = function () {
    var text_dfplayer_name = this.getFieldValue('dfplayer_name');
    var dropdown_type = this.getFieldValue('type');
    var code = '' + text_dfplayer_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化数字电位器
Blockly.Arduino.forBlock['make_arduino_x9cxxx_begin'] = function () {
    this.setTooltip("初始化数字电位器");
    var dropdown_type = this.getFieldValue('type');
    var text_x9cxxx_name = this.getFieldValue('x9cxxx_name');
    var value_cs = Blockly.Arduino.valueToCode(this, 'cs', Blockly.Arduino.ORDER_ATOMIC);
    var value_ud = Blockly.Arduino.valueToCode(this, 'ud', Blockly.Arduino.ORDER_ATOMIC);
    var value_inc = Blockly.Arduino.valueToCode(this, 'inc', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['include_' + 'FastX9CXXX'] = '#include <FastX9CXXX.h>';
    Blockly.Arduino.definitions_['var_declare_' + text_x9cxxx_name] = dropdown_type + ' ' + text_x9cxxx_name + ';';
    Blockly.Arduino.setups_['x9cxxx_' + text_x9cxxx_name] = text_x9cxxx_name + '.Setup(' + value_cs + ', ' + value_ud + ', ' + value_inc + ');';
    var code = '';
    return code;
};

//数字电位器 设置阶数
Blockly.Arduino.forBlock['make_arduino_x9cxxx_JumpToStep'] = function () {
    this.setTooltip("数字电位器 设置阶数");
    var text_x9cxxx_name = this.getFieldValue('x9cxxx_name');
    var value_step = Blockly.Arduino.valueToCode(this, 'step', Blockly.Arduino.ORDER_ATOMIC);
    var value_store = Blockly.Arduino.valueToCode(this, 'store', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_x9cxxx_name + '.JumpToStep(' + value_step + ', ' + value_store + ');\n';
    return code;
};

//数字电位器 阶数自增或自减
Blockly.Arduino.forBlock['make_arduino_x9cxxx_Down_Up'] = function () {
    this.setTooltip("数字电位器 阶数自增或自减");
    var text_x9cxxx_name = this.getFieldValue('x9cxxx_name');
    var dropdown_type = this.getFieldValue('type');
    var value_store = Blockly.Arduino.valueToCode(this, 'store', Blockly.Arduino.ORDER_ATOMIC);
    var code = text_x9cxxx_name + '.' + dropdown_type + '(' + value_store + ');\n';
    return code;
};

//数字电位器 获取当前电阻估计值和当前阶数
Blockly.Arduino.forBlock['make_arduino_x9cxxx_GetEstimatedResistance_GetStep'] = function () {
    var text_x9cxxx_name = this.getFieldValue('x9cxxx_name');
    var dropdown_type = this.getFieldValue('type');
    if (dropdown_type == 'GetEstimatedResistance')
        this.setTooltip("数字电位器 获取当前电阻估计值，返回数据的类型为uint32_t");
    else
        this.setTooltip("数字电位器 获取当前阶数，返回数据的类型为uint8_t");
    var code = text_x9cxxx_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//数字电位器 储存当前阶数和复位
Blockly.Arduino.forBlock['make_arduino_x9cxxx_Reset_Store'] = function () {
    this.setTooltip("数字电位器 储存当前阶数或复位");
    var text_x9cxxx_name = this.getFieldValue('x9cxxx_name');
    var dropdown_type = this.getFieldValue('type');
    var code = text_x9cxxx_name + '.' + dropdown_type + '();\n';
    return code;
};

Blockly.Arduino.forBlock['make_reverseCipher'] = function () {
    var value_Cipher_data = Blockly.Arduino.valueToCode(this, 'Cipher_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_Cipher_type = this.getFieldValue('Cipher_type');

    Blockly.Arduino.definitions_['function_reverseCipher'] = '//反转加密法'
        + '\nString reverseCipher(String message_data)'
        + '\n{'
        + '\n  String translated = "";'
        + '\n  for (int i = (String(message_data).length() - 1); i >= 0;i--)'
        + '\n    translated = String(translated) + String(String(message_data).charAt(i));'
        + '\n  return translated;'
        + '\n}\n';
    var code = 'reverseCipher(' + value_Cipher_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_caesarCipher'] = function () {
    var value_Cipher_data = Blockly.Arduino.valueToCode(this, 'Cipher_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_Cipher_type = this.getFieldValue('Cipher_type');
    var value_Cipher_key = Blockly.Arduino.valueToCode(this, 'Cipher_key', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['function_caesarCipher'] = '//凯撒加密法'
        + '\nString caesarCipher(String message_data,boolean select_data,int key)'
        + '\n{'
        + '\n  String cipher_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";'
        + '\n  String translated = "";'
        + '\n  int cipher_num = 0;'
        + '\n  message_data.toUpperCase();'
        + '\n  for(int i = 0; i < String(message_data).length();i++)'
        + '\n  {'
        + '\n    cipher_num = String(cipher_letters).indexOf(String(message_data).charAt(i));'
        + '\n    if(cipher_num != -1)'
        + '\n    {'
        + '\n      if(select_data)'
        + '\n        cipher_num += key;'
        + '\n      else'
        + '\n        cipher_num -= key;'
        + '\n      if(cipher_num > 0 && cipher_num >= String(cipher_letters).length())'
        + '\n        cipher_num -= String(cipher_letters).length();'
        + '\n      else if(cipher_num < 0)'
        + '\n        cipher_num += String(cipher_letters).length();'
        + '\n      translated = String(translated) + String(String(cipher_letters).charAt(cipher_num));'
        + '\n    }'
        + '\n    else'
        + '\n      translated = String(translated) + String(String(message_data).charAt(i));'
        + '\n  }'
        + '\n  return translated;'
        + '\n}\n';
    var code = 'caesarCipher(' + value_Cipher_data + ', ' + dropdown_Cipher_type + ', ' + value_Cipher_key + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_transpositionCipher'] = function () {
    var value_Cipher_data = Blockly.Arduino.valueToCode(this, 'Cipher_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_Cipher_type = this.getFieldValue('Cipher_type');
    var value_Cipher_key = Blockly.Arduino.valueToCode(this, 'Cipher_key', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['function_transpositionCipher'] = '//换位加密法'
        + '\nString transpositionCipher(String message_data,boolean select_data,int key)'
        + '\n{'
        + '\n  int len = String(message_data).length();'
        + '\n  String translated = "";'
        + '\n  if(select_data)'
        + '\n  {'
        + '\n    for(int i = 0;i < key;i++)'
        + '\n    {'
        + '\n      for(int j = 0;j <= len/key;j++)'
        + '\n      {'
        + '\n        if(i + j*key < len)'
        + '\n        {'
        + '\n          translated = String(translated) + String(message_data).charAt(i + j*key);'
        + '\n        }'
        + '\n      }'
        + '\n    }'
        + '\n  }'
        + '\n  else'
        + '\n  {'
        + '\n    String message_data1 = String(message_data).substring(0,len%key*(len/key+1));'
        + '\n    message_data = String(message_data).substring(len%key*(len/key+1));'
        + '\n    for(int i = String(message_data).length()/(len/key);i >= 1;i--)'
        + '\n    {'
        + '\n      message_data = String(message_data).substring(0,len/key*i) + String(\'*\') + String(message_data).substring(len/key*i);'
        + '\n    }'
        + '\n    message_data1 = String(message_data1) + String(message_data);'
        + '\n    for(int i = 0;i <= len/key;i++)'
        + '\n    {'
        + '\n      for(int j = 0;j < key;j++)'
        + '\n      {'
        + '\n        if(i != len/key || j < len%key)'
        + '\n        {'
        + '\n          translated = String(translated) + String(message_data1).charAt(j*(len/key+1)+i);'
        + '\n        }'
        + '\n      }'
        + '\n    }'
        + '\n  }'
        + '\n  return translated;'
        + '\n}\n';
    var code = 'transpositionCipher(' + value_Cipher_data + ', ' + dropdown_Cipher_type + ', ' + value_Cipher_key + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_multiplierCipher'] = function () {
    var value_Cipher_data = Blockly.Arduino.valueToCode(this, 'Cipher_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_Cipher_type = this.getFieldValue('Cipher_type');
    var value_Cipher_key = Blockly.Arduino.valueToCode(this, 'Cipher_key', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['function_gcdJC'] = '//检测两个数是否互素,互素返回辗转相除的次数，不互素返回-1'
        + '\nint gcdJC(long a,long b)'
        + '\n{'
        + '\n  long r;'
        + '\n  int i = 0;'
        + '\n  while(b != 0)'
        + '\n  {'
        + '\n    r = a % b;'
        + '\n    i++;'
        + '\n    if(r != 0)'
        + '\n    {'
        + '\n      a = b;'
        + '\n      b = r;'
        + '\n    }'
        + '\n    else'
        + '\n    {'
        + '\n      if(b == 1)'
        + '\n        return i;'
        + '\n      else'
        + '\n        return -1;'
        + '\n    }'
        + '\n  }'
        + '\n  return 0;'
        + '\n}\n';

    Blockly.Arduino.definitions_['function_inversion'] = '//求模逆 a*b=1 mod n 结果返回b 即 a的逆元'
        + '\nlong inversion(long a,long n)'
        + '\n{'
        + '\n  long n1 = n;'
        + '\n  int length = gcdJC(a,n);'
        + '\n  if(length == -1)'
        + '\n    return -1;'
        + '\n  if(a > n)'
        + '\n    length += 2;'
        + '\n  long t[length];'
        + '\n  t[0] = 0;'
        + '\n  t[1] = 1;'
        + '\n  int i =0;'
        + '\n  long temp1 = 0, temp2 = 0;'
        + '\n  while(true)'
        + '\n  {'
        + '\n    temp1 = n/a;'
        + '\n    temp2 = n%a;'
        + '\n    i++;'
        + '\n    t[i + 1] = t[i - 1] - temp1*t[i];'
        + '\n    if(temp2 != 1)'
        + '\n    {'
        + '\n      n = a;'
        + '\n      a = temp2;'
        + '\n    }'
        + '\n    else'
        + '\n    {'
        + '\n      if(t[length - 1] < 0)'
        + '\n        return t[length - 1] + n1;'
        + '\n      else'
        + '\n        return t[length - 1];'
        + '\n    }'
        + '\n  }'
        + '\n}\n';

    Blockly.Arduino.definitions_['function_multiplierCipher'] = '//乘数加密法'
        + '\nString multiplierCipher(String message_data,boolean select_data,int key)'
        + '\n{'
        + '\n  String cipher_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";'
        + '\n  String translated = "";'
        + '\n  int cipher_num = 0;'
        + '\n  message_data.toUpperCase();'
        + '\n  for(int i = 0; i < String(message_data).length();i++)'
        + '\n  {'
        + '\n    cipher_num = String(cipher_letters).indexOf(String(message_data).charAt(i));'
        + '\n    if(cipher_num != -1)'
        + '\n    {'
        + '\n      if(select_data)'
        + '\n        cipher_num = (cipher_num*key)%String(cipher_letters).length();'
        + '\n      else'
        + '\n        cipher_num = cipher_num*(inversion(key,String(cipher_letters).length()))%String(cipher_letters).length();'
        + '\n      translated = String(translated) + String(String(cipher_letters).charAt(cipher_num));'
        + '\n    }'
        + '\n    else'
        + '\n      translated = String(translated) + String(String(message_data).charAt(i));'
        + '\n  }'
        + '\n  return translated;'
        + '\n}\n';
    var code = 'multiplierCipher(' + value_Cipher_data + ', ' + dropdown_Cipher_type + ', ' + value_Cipher_key + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_affineCipher'] = function () {
    var value_Cipher_data = Blockly.Arduino.valueToCode(this, 'Cipher_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_Cipher_type = this.getFieldValue('Cipher_type');
    var value_Cipher_key1 = Blockly.Arduino.valueToCode(this, 'Cipher_key1', Blockly.Arduino.ORDER_ATOMIC);
    var value_Cipher_key2 = Blockly.Arduino.valueToCode(this, 'Cipher_key2', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['function_gcdJC'] = '//检测两个数是否互素,互素返回辗转相除的次数，不互素返回-1'
        + '\nint gcdJC(long a,long b)'
        + '\n{'
        + '\n  long r;'
        + '\n  int i = 0;'
        + '\n  while(b != 0)'
        + '\n  {'
        + '\n    r = a % b;'
        + '\n    i++;'
        + '\n    if(r != 0)'
        + '\n    {'
        + '\n      a = b;'
        + '\n      b = r;'
        + '\n    }'
        + '\n    else'
        + '\n    {'
        + '\n      if(b == 1)'
        + '\n        return i;'
        + '\n      else'
        + '\n        return -1;'
        + '\n    }'
        + '\n  }'
        + '\n  return 0;'
        + '\n}\n';

    Blockly.Arduino.definitions_['function_inversion'] = '//求模逆 a*b=1 mod n 结果返回b 即 a的逆元'
        + '\nlong inversion(long a,long n)'
        + '\n{'
        + '\n  long n1 = n;'
        + '\n  int length = gcdJC(a,n);'
        + '\n  if(length == -1)'
        + '\n    return -1;'
        + '\n  if(a > n)'
        + '\n    length += 2;'
        + '\n  long t[length];'
        + '\n  t[0] = 0;'
        + '\n  t[1] = 1;'
        + '\n  int i =0;'
        + '\n  long temp1 = 0, temp2 = 0;'
        + '\n  while(true)'
        + '\n  {'
        + '\n    temp1 = n/a;'
        + '\n    temp2 = n%a;'
        + '\n    i++;'
        + '\n    t[i + 1] = t[i - 1] - temp1*t[i];'
        + '\n    if(temp2 != 1)'
        + '\n    {'
        + '\n      n = a;'
        + '\n      a = temp2;'
        + '\n    }'
        + '\n    else'
        + '\n    {'
        + '\n      if(t[length - 1] < 0)'
        + '\n        return t[length - 1] + n1;'
        + '\n      else'
        + '\n        return t[length - 1];'
        + '\n    }'
        + '\n  }'
        + '\n}\n';

    Blockly.Arduino.definitions_['function_affineCipher'] = '//仿射加密法'
        + '\nString affineCipher(String message_data,boolean select_data,int key1,int key2)'
        + '\n{'
        + '\n  String cipher_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";'
        + '\n  String translated = "";'
        + '\n  int cipher_num = 0;'
        + '\n  message_data.toUpperCase();'
        + '\n  for(int i = 0; i < String(message_data).length();i++)'
        + '\n  {'
        + '\n    cipher_num = String(cipher_letters).indexOf(String(message_data).charAt(i));'
        + '\n    if(cipher_num != -1)'
        + '\n    {'
        + '\n      if(select_data)'
        + '\n        cipher_num = (cipher_num*key1+key2)%String(cipher_letters).length();'
        + '\n      else'
        + '\n      {'
        + '\n        cipher_num = (cipher_num-key2)*(inversion(key1,String(cipher_letters).length()))%String(cipher_letters).length();'
        + '\n        while(cipher_num < 0)'
        + '\n          cipher_num += String(cipher_letters).length();'
        + '\n      }'
        + '\n      translated = String(translated) + String(String(cipher_letters).charAt(cipher_num));'
        + '\n    }'
        + '\n    else'
        + '\n      translated = String(translated) + String(String(message_data).charAt(i));'
        + '\n  }'
        + '\n  return translated;'
        + '\n}\n';

    var code = 'affineCipher(' + value_Cipher_data + ', ' + dropdown_Cipher_type + ', ' + value_Cipher_key1 + ', ' + value_Cipher_key2 + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_simpleSubCipher'] = function () {
    var value_Cipher_data = Blockly.Arduino.valueToCode(this, 'Cipher_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_Cipher_type = this.getFieldValue('Cipher_type');
    var value_Cipher_key = Blockly.Arduino.valueToCode(this, 'Cipher_key', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['function_simpleSubCipher'] = '//简单替代加密法'
        + '\nString simpleSubCipher(String message_data,String key)'
        + '\n{'
        + '\n  String cipher_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";'
        + '\n  String translated = "";'
        + '\n  int cipher_num = 0;'
        + '\n  message_data.toUpperCase();'
        + '\n  for(int i = 0; i < String(message_data).length();i++)'
        + '\n  {'
        + '\n    cipher_num = String(cipher_letters).indexOf(String(message_data).charAt(i));'
        + '\n    if(cipher_num != -1)'
        + '\n      translated = String(translated) + String(String(key).charAt(cipher_num));'
        + '\n    else'
        + '\n      translated = String(translated) + String(String(message_data).charAt(i));'
        + '\n  }'
        + '\n  return translated;'
        + '\n}\n';
    var code = 'simpleSubCipher(' + value_Cipher_data + ', ' + value_Cipher_key + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_simpleSubGetkey'] = function () {
    var value_Cipher_key = Blockly.Arduino.valueToCode(this, 'Cipher_key', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['function_simpleSubGetkey'] = '//获取解密密匙(简单替代加密法)'
        + '\nString simpleSubGetkey(String key)'
        + '\n{'
        + '\n  String cipher_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";'
        + '\n  String translated = "";'
        + '\n  for(int i = 0;i < String(cipher_letters).length();i++)'
        + '\n    for(int j = 0;j < String(cipher_letters).length();j++)'
        + '\n      if(String(key).charAt(j) == String(cipher_letters).charAt(i))'
        + '\n      {'
        + '\n        translated = String(translated) + String(String(cipher_letters).charAt(j));'
        + '\n        break;'
        + '\n      }'
        + '\n  return translated;'
        + '\n}\n';

    var code = 'simpleSubGetkey(' + value_Cipher_key + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_simpleSubRandomkey'] = function () {

    Blockly.Arduino.definitions_['function_simpleSubRandomkey'] = '//获取随机密匙(简单替代加密法)'
        + '\nString simpleSubRandomkey()'
        + '\n{'
        + '\n  String cipher_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";'
        + '\n  String output_key = "";'
        + '\n  int key_data;'
        + '\n  int j = 0;'
        + '\n  int key = 0;'
        + '\n  boolean data_ok = false;'
        + '\n  for(int i = 0;i < 25;i++)'
        + '\n  {'
        + '\n    key = random(0,25 - i);'
        + '\n    output_key = String(output_key) + String(cipher_letters).charAt(key);'
        + '\n    cipher_letters = String(cipher_letters).substring(0,key) + String(cipher_letters).substring(key + 1,25 - i);'
        + '\n  }'
        + '\n  output_key = String(output_key) + String(cipher_letters);'
        + '\n  return output_key;'
        + '\n}\n';

    var code = 'simpleSubRandomkey()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_vigenereCipher'] = function () {
    var value_Cipher_data = Blockly.Arduino.valueToCode(this, 'Cipher_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_Cipher_type = this.getFieldValue('Cipher_type');
    var value_Cipher_key = Blockly.Arduino.valueToCode(this, 'Cipher_key', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['function_caesarCipher'] = '//凯撒加密法'
        + '\nString caesarCipher(String message_data,boolean select_data,int key)'
        + '\n{'
        + '\n  String cipher_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";'
        + '\n  String translated = "";'
        + '\n  int cipher_num = 0;'
        + '\n  message_data.toUpperCase();'
        + '\n  for(int i = 0; i < String(message_data).length();i++)'
        + '\n  {'
        + '\n    cipher_num = String(cipher_letters).indexOf(String(message_data).charAt(i));'
        + '\n    if(cipher_num != -1)'
        + '\n    {'
        + '\n      if(select_data)'
        + '\n        cipher_num += key;'
        + '\n      else'
        + '\n        cipher_num -= key;'
        + '\n      if(cipher_num > 0 && cipher_num >= String(cipher_letters).length())'
        + '\n        cipher_num -= String(cipher_letters).length();'
        + '\n      else if(cipher_num < 0)'
        + '\n        cipher_num += String(cipher_letters).length();'
        + '\n      translated = String(translated) + String(String(cipher_letters).charAt(cipher_num));'
        + '\n    }'
        + '\n    else'
        + '\n      translated = String(translated) + String(String(message_data).charAt(i));'
        + '\n  }'
        + '\n  return translated;'
        + '\n}\n';

    Blockly.Arduino.definitions_['function_vigenereCipher'] = '//维吉尼亚加密法'
        + '\nString vigenereCipher(String message_data,boolean select_data,String key)'
        + '\n{'
        + '\n  String cipher_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";'
        + '\n  int key_type;'
        + '\n  String translated = "";'
        + '\n  int cipher_num = 0,j=0;'
        + '\n  message_data.toUpperCase();'
        + '\n  key.toUpperCase();'
        + '\n  for(int i = 0;i < String(message_data).length();i++)'
        + '\n  {'
        + '\n    key_type = (j)%String(key).length();'
        + '\n    cipher_num = String(cipher_letters).indexOf(String(message_data).charAt(i));'
        + '\n    if(cipher_num == -1)'
        + '\n      translated = String(translated) + String(message_data).charAt(i);'
        + '\n    else'
        + '\n    {'
        + '\n      key_type = String(cipher_letters).indexOf(String(key).charAt(key_type));'
        + '\n      if(select_data)'
        + '\n        translated = String(translated) + caesarCipher(String(String(message_data).charAt(i)),true,key_type);'
        + '\n      else'
        + '\n        translated = String(translated) + caesarCipher(String(String(message_data).charAt(i)),false,key_type);'
        + '\n      j++;'
        + '\n    }'
        + '\n  }'
        + '\n  return translated;'
        + '\n}\n';

    var code = 'vigenereCipher(' + value_Cipher_data + ', ' + dropdown_Cipher_type + ', ' + value_Cipher_key + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//获取某个版本对应二维码存储所需的字节数
Blockly.Arduino.forBlock['make_arduino_qrcode_getBufferSize'] = function () {
    var value_qrcode_version = Blockly.Arduino.valueToCode(this, 'qrcode_version', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_qrcode'] = '#include "qrcode.h"';
    Blockly.Arduino.definitions_['var_declare_qrcode'] = 'QRCode qrcode;';

    var code = 'qrcode_getBufferSize(' + value_qrcode_version + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//使用某个文本，通过设置二维码版本、容错率来生成二维码
Blockly.Arduino.forBlock['make_arduino_qrcode_initText'] = function () {
    var value_qrcode_text = Blockly.Arduino.valueToCode(this, 'qrcode_text', Blockly.Arduino.ORDER_ATOMIC);
    var value_qrcode_version = Blockly.Arduino.valueToCode(this, 'qrcode_version', Blockly.Arduino.ORDER_ATOMIC);
    var value_qrcode_ecc = Blockly.Arduino.valueToCode(this, 'qrcode_ecc', Blockly.Arduino.ORDER_ATOMIC);
    var value_qrcode_data = Blockly.Arduino.valueToCode(this, 'qrcode_data', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_qrcode'] = '#include "qrcode.h"';
    Blockly.Arduino.definitions_['var_declare_qrcode'] = 'QRCode qrcode;';
    Blockly.Arduino.definitions_['var_declare_qrcode_data'] = 'uint8_t *qrcodeData; // 声明一个指向uint8_t类型的指针，用于存储二维码数据';
    
    var code = 'int bufferSize = qrcode_getBufferSize(3);  // 计算所需缓冲区大小\n'
             + 'qrcode_initText(&qrcode, ' + value_qrcode_data + ', ' + value_qrcode_version + ', ' + value_qrcode_ecc + ', ' + value_qrcode_text + ');\n';
    return code;
};
//获取二维码的尺寸
Blockly.Arduino.forBlock['make_arduino_qrcode_size'] = function () {
    var dropdown_data = this.getFieldValue('data');
    Blockly.Arduino.definitions_['include_qrcode'] = '#include "qrcode.h"';
    Blockly.Arduino.definitions_['var_declare_qrcode'] = 'QRCode qrcode;';
    var code = 'qrcode.' + dropdown_data + '';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//获取二维码上某个坐标点处的方块值
Blockly.Arduino.forBlock['make_arduino_qrcode_getModule'] = function () {
    var value_x_data = Blockly.Arduino.valueToCode(this, 'x_data', Blockly.Arduino.ORDER_ATOMIC);
    var value_y_data = Blockly.Arduino.valueToCode(this, 'y_data', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_['include_qrcode'] = '#include "qrcode.h"';
    Blockly.Arduino.definitions_['var_declare_qrcode'] = 'QRCode qrcode;';
    var code = 'qrcode_getModule(&qrcode, ' + value_x_data + ', ' + value_y_data + ')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化PID
Blockly.Arduino.forBlock['make_arduino_pid_begin'] = function () {
    var text_pid_name = this.getFieldValue('pid_name');
    var value_pid_input = Blockly.Arduino.valueToCode(this, 'pid_input', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_output = Blockly.Arduino.valueToCode(this, 'pid_output', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_setpoint = Blockly.Arduino.valueToCode(this, 'pid_setpoint', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_kp = Blockly.Arduino.valueToCode(this, 'pid_kp', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_ki = Blockly.Arduino.valueToCode(this, 'pid_ki', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_kd = Blockly.Arduino.valueToCode(this, 'pid_kd', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_direction = Blockly.Arduino.valueToCode(this, 'pid_direction', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_PID_v1'] = '#include <PID_v1.h>';
    Blockly.Arduino.definitions_['var_declare' + value_pid_input] = 'double ' + value_pid_input + ' = 0;';
    Blockly.Arduino.definitions_['var_declare' + value_pid_output] = 'double ' + value_pid_output + ' = 0;';
    Blockly.Arduino.definitions_['var_declare' + value_pid_setpoint] = 'double ' + value_pid_setpoint + ' = 0;';
    Blockly.Arduino.definitions_['var_declare_pid' + text_pid_name] = 'PID ' + text_pid_name + '(&' + value_pid_input + ', &' + value_pid_output + ', &' + value_pid_setpoint + ', ' + value_pid_kp + ', ' + value_pid_ki + ', ' + value_pid_kd + ', ' + value_pid_direction + ');';
    var code = '';
    return code;
};

//初始化PID-1
Blockly.Arduino.forBlock['make_arduino_pid_begin_1'] = function () {
    var text_pid_name = this.getFieldValue('pid_name');
    var value_pid_input = Blockly.Arduino.valueToCode(this, 'pid_input', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_output = Blockly.Arduino.valueToCode(this, 'pid_output', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_setpoint = Blockly.Arduino.valueToCode(this, 'pid_setpoint', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_kp = Blockly.Arduino.valueToCode(this, 'pid_kp', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_ki = Blockly.Arduino.valueToCode(this, 'pid_ki', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_kd = Blockly.Arduino.valueToCode(this, 'pid_kd', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_direction = Blockly.Arduino.valueToCode(this, 'pid_direction', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_pon = Blockly.Arduino.valueToCode(this, 'pid_pon', Blockly.Arduino.ORDER_ATOMIC);

    Blockly.Arduino.definitions_['include_PID_v1'] = '#include <PID_v1.h>';
    Blockly.Arduino.definitions_['var_declare' + value_pid_input] = 'double ' + value_pid_input + ' = 0;';
    Blockly.Arduino.definitions_['var_declare' + value_pid_output] = 'double ' + value_pid_output + ' = 0;';
    Blockly.Arduino.definitions_['var_declare' + value_pid_setpoint] = 'double ' + value_pid_setpoint + ' = 0;';
    Blockly.Arduino.definitions_['var_declare_pid' + text_pid_name] = 'PID ' + text_pid_name + '(&' + value_pid_input + ', &' + value_pid_output + ', &' + value_pid_setpoint + ', ' + value_pid_kp + ', ' + value_pid_ki + ', ' + value_pid_kd + ', ' + value_pid_direction + ', ' + value_pid_pon + ');';
    var code = '';
    return code;
};

//设置PID方向
Blockly.Arduino.forBlock['make_arduino_pid_direction'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//指定PID算法的计算过程是自动还是手动
Blockly.Arduino.forBlock['make_arduino_pid_SetMode'] = function () {
    var text_pid_name = this.getFieldValue('pid_name');
    var value_pid_mode = Blockly.Arduino.valueToCode(this, 'pid_mode', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_pid_name + '.SetMode(' + value_pid_mode + ');\n';
    return code;
};

//自动|手动
Blockly.Arduino.forBlock['make_arduino_pid_Mode'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//PID算法 运行计算过程
Blockly.Arduino.forBlock['make_arduino_pid_Compute'] = function () {
    var text_pid_name = this.getFieldValue('pid_name');
    var code = '' + text_pid_name + '.Compute();\n';
    return code;
};

//PID算法 运行计算过程-1
Blockly.Arduino.forBlock['make_arduino_pid_Compute_1'] = function () {
    var text_pid_name = this.getFieldValue('pid_name');
    var code = '' + text_pid_name + '.Compute()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//PID算法 设置输出的上下限
Blockly.Arduino.forBlock['make_arduino_pid_SetOutputLimits'] = function () {
    var text_pid_name = this.getFieldValue('pid_name');
    var value_min = Blockly.Arduino.valueToCode(this, 'min', Blockly.Arduino.ORDER_ATOMIC);
    var value_max = Blockly.Arduino.valueToCode(this, 'max', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_pid_name + '.SetOutputLimits(' + value_min + ', ' + value_max + ');\n';
    return code;
};

//PID算法 调整参数
Blockly.Arduino.forBlock['make_arduino_pid_SetTunings'] = function () {
    var text_pid_name = this.getFieldValue('pid_name');
    var value_pid_kp = Blockly.Arduino.valueToCode(this, 'pid_kp', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_ki = Blockly.Arduino.valueToCode(this, 'pid_ki', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_kd = Blockly.Arduino.valueToCode(this, 'pid_kd', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_pon = Blockly.Arduino.valueToCode(this, 'pid_pon', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_pid_name + '.SetTunings(' + value_pid_kp + ', ' + value_pid_ki + ', ' + value_pid_kd + ', ' + value_pid_pon + ');\n';
    return code;
};

//PID算法 工作模式
Blockly.Arduino.forBlock['make_arduino_pid_pon'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var code = dropdown_type;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//PID算法 调整参数
Blockly.Arduino.forBlock['make_arduino_pid_SetTunings_1'] = function () {
    var text_pid_name = this.getFieldValue('pid_name');
    var value_pid_kp = Blockly.Arduino.valueToCode(this, 'pid_kp', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_ki = Blockly.Arduino.valueToCode(this, 'pid_ki', Blockly.Arduino.ORDER_ATOMIC);
    var value_pid_kd = Blockly.Arduino.valueToCode(this, 'pid_kd', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_pid_name + '.SetTunings(' + value_pid_kp + ', ' + value_pid_ki + ', ' + value_pid_kd + ');\n';
    return code;
};

//PID算法 调整控制方向
Blockly.Arduino.forBlock['make_arduino_pid_SetControllerDirection'] = function () {
    var text_pid_name = this.getFieldValue('pid_name');
    var value_pid_direction = Blockly.Arduino.valueToCode(this, 'pid_direction', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_pid_name + '.SetControllerDirection(' + value_pid_direction + ');\n';
    return code;
};

//PID算法 调整采样时间
Blockly.Arduino.forBlock['make_arduino_pid_SetSampleTime'] = function () {
    var text_pid_name = this.getFieldValue('pid_name');
    var value_pid_time = Blockly.Arduino.valueToCode(this, 'pid_time', Blockly.Arduino.ORDER_ATOMIC);
    var code = '' + text_pid_name + '.SetSampleTime(' + value_pid_time + ');\n';
    return code;
};

//PID算法 获取Kp、Ki、Kd、控制方向、工作方向
Blockly.Arduino.forBlock['make_arduino_pid_get'] = function () {
    var text_pid_name = this.getFieldValue('pid_name');
    var dropdown_type = this.getFieldValue('type');
    var code = '' + text_pid_name + '.' + dropdown_type + '()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino.forBlock['make_arduino_battery_begin'] = function() {

  const capacity = this.getFieldValue('BATTERY_CAPACITY');
  const minVoltage = this.getFieldValue('VOLTAGE_MIN');
  const maxVoltage = this.getFieldValue('VOLTAGE_MAX');
  const name = this.getFieldValue('name');
  const voltageInput = Blockly.Arduino.valueToCode(this, 'VOLTAGE_INPUT', Blockly.Arduino.ORDER_ATOMIC);
  const currentInput = Blockly.Arduino.valueToCode(this, 'CURRENT_INPUT', Blockly.Arduino.ORDER_ATOMIC);


  Blockly.Arduino.definitions_[`var_capacity_${name}`] = `#define BATTERY_CAPACITY ${capacity}.0f `;
  Blockly.Arduino.definitions_[`var_voltage_min_${name}`] = `#define VOLTAGE_MIN ${minVoltage}   `;
  Blockly.Arduino.definitions_[`var_voltage_max_${name}`] = `#define VOLTAGE_MAX ${maxVoltage}   `;
    // 添加更新间隔定义
    Blockly.Arduino.definitions_[`define_update_interval_${name}`] = `#define UPDATE_INTERVAL 1000`; // 默认1秒更新一次
  Blockly.Arduino.definitions_[`var_current_voltage_${name}`] = 
  `float initialVoltage = 0.0;       // 初始化时的电池电压
float remainingCapacity = 0.0;    // 剩余容量（mAh）
unsigned long lastUpdateTime = 0;       // 上次更新时间（ms）
float filteredCapacity = 0.0;     // 平滑后的剩余容量
float voltage = 0.0;              // 当前电压
float current = 0.0;              // 当前电流
float remainingPercentage = 0.0;  // 剩余百分比`

  // 初始化逻辑
  Blockly.Arduino.setups_[`setup_${name}_init`] = `initialVoltage = ${voltageInput};


  float initialPercentage = mapVoltageToPercentage(initialVoltage);
  remainingCapacity = BATTERY_CAPACITY * (initialPercentage / 100.0);
  filteredCapacity = remainingCapacity;`;

  // 电压映射函数定义
  Blockly.Arduino.definitions_[`func_map_voltage_${name}`] = `float mapVoltageToPercentage(float voltage) { 
    voltage = constrain(voltage, VOLTAGE_MIN, VOLTAGE_MAX); 
    return ((voltage - VOLTAGE_MIN) / (VOLTAGE_MAX - VOLTAGE_MIN)) * 100.0; 
  }`;
  
  // 生成loop代码片段（仅返回需要循环执行的代码）
  return `unsigned long currentTime = millis(); 
  if (currentTime - lastUpdateTime >= UPDATE_INTERVAL) { 
    voltage = ${voltageInput}; 
      delay(400);
      current = ${currentInput}; 
      delay(400);
      float deltaTime = (currentTime - lastUpdateTime) / 3600000.0; 
    float capacityDelta = current * deltaTime; 
    
    if (current > 0) {  
      remainingCapacity = max(remainingCapacity - abs(capacityDelta), 0.0f);
    } else if (current < 0) {  
      remainingCapacity = min(remainingCapacity + abs(capacityDelta), BATTERY_CAPACITY);
    }
    
    filteredCapacity = filteredCapacity * 0.8 + remainingCapacity * 0.2; 
    remainingPercentage = (filteredCapacity / BATTERY_CAPACITY) * 100.0; 
    remainingPercentage = constrain(remainingPercentage, 0.0, 100.0); 
    lastUpdateTime = currentTime; // 更新时间戳
  }`;
  

};

// 电池数据输出模块代码生成
Blockly.Arduino.forBlock['make_arduino_battery_data'] = function() {
  const dataType = this.getFieldValue('DATA_TYPE');
  let variable;
  switch(dataType) {
    case 'voltage':
      variable = 'voltage';
      break;
    case 'current':
      variable = 'current';
      break;
    case 'filteredCapacity':
      variable = 'filteredCapacity';
      break;
    case 'remainingPercentage':
      variable = 'remainingPercentage';
      break;
    default:
      variable = '0'; // 默认值，防止错误
  }
  return [variable, Blockly.Arduino.ORDER_ATOMIC];
};

// 合并的滤波配置代码生成器
Blockly.Arduino.forBlock['make_arduino_filter_config'] = function(block) {
  var filterName = block.getFieldValue('filterName');
  var filterType = block.getFieldValue('filterType') || 'SLI';
  var new_value = Blockly.Arduino.valueToCode(block, 'new_value', Blockly.Arduino.ORDER_ATOMIC) || '0';
  
  var code = '';
  
  if (filterType === 'SLI') {
    // 滑动平均滤波 - 适用于模拟信号、传感器数据
    var filterWindowSize = Blockly.Arduino.valueToCode(block, 'filterWindowSize', Blockly.Arduino.ORDER_ATOMIC) || '5';
    
    Blockly.Arduino.definitions_['var_sli_filter_' + filterName] = `volatile float ${filterName}_sli_result;\nvolatile int ${filterName}_sli_window_size = ${filterWindowSize};\nfloat ${filterName}_sli_buffer[${filterWindowSize}];\nvolatile int ${filterName}_sli_currentIndex = 0;\nvolatile float ${filterName}_sli_adc_sum = 0.0;`;

    Blockly.Arduino.definitions_['func_sliding_' + filterName] = `float ${filterName}_slidingAverage(float new_value) {\n  ${filterName}_sli_adc_sum -= ${filterName}_sli_buffer[${filterName}_sli_currentIndex];\n  ${filterName}_sli_buffer[${filterName}_sli_currentIndex] = new_value;\n  ${filterName}_sli_adc_sum += new_value;\n  ${filterName}_sli_result = (float)${filterName}_sli_adc_sum / ${filterName}_sli_window_size;\n  ${filterName}_sli_currentIndex = (${filterName}_sli_currentIndex + 1) % ${filterName}_sli_window_size;\n  return ${filterName}_sli_result;\n}`;

    Blockly.Arduino.setups_['setup_sli_filter_' + filterName] = `for (int i = 0; i < ${filterName}_sli_window_size; i++) {\n  ${filterName}_sli_buffer[i] = 0;\n}`;

    code = `${filterName}_sli_result = ${filterName}_slidingAverage(${new_value});\n`;
    
  } else if (filterType === 'KAL') {
    // 卡尔曼滤波
    var q = Blockly.Arduino.valueToCode(block, 'filterWindowSize', Blockly.Arduino.ORDER_ATOMIC) || '0.1';
    var r = Blockly.Arduino.valueToCode(block, 'rX', Blockly.Arduino.ORDER_ATOMIC) || '0.1';
    var x = Blockly.Arduino.valueToCode(block, 'xX', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var p = Blockly.Arduino.valueToCode(block, 'pX', Blockly.Arduino.ORDER_ATOMIC) || '1.0';
    var k = Blockly.Arduino.valueToCode(block, 'kX', Blockly.Arduino.ORDER_ATOMIC) || '0.0';

    Blockly.Arduino.definitions_['var_kal_filter_' + filterName] = `float ${filterName}_kal_result;\nfloat ${filterName}_kal_q = ${q};\nfloat ${filterName}_kal_r = ${r};\nfloat ${filterName}_kal_x = ${x};\nfloat ${filterName}_kal_p = ${p};\nfloat ${filterName}_kal_k = ${k};`;

    Blockly.Arduino.definitions_['func_kalman_' + filterName] = `float ${filterName}_kalmanFilter(float new_value) {\n  ${filterName}_kal_p = ${filterName}_kal_p + ${filterName}_kal_q;\n  ${filterName}_kal_k = ${filterName}_kal_p / (${filterName}_kal_p + ${filterName}_kal_r);\n  ${filterName}_kal_result = ${filterName}_kal_result + ${filterName}_kal_k * (new_value - ${filterName}_kal_result);\n  ${filterName}_kal_p = (1 - ${filterName}_kal_k) * ${filterName}_kal_p;\n  return ${filterName}_kal_result;\n}`;

    code = `${filterName}_kal_result = ${filterName}_kalmanFilter(${new_value});\n`;
    
  } else if (filterType === 'COMP') {
    // 互补滤波
    var alpha = Blockly.Arduino.valueToCode(block, 'filterWindowSize', Blockly.Arduino.ORDER_ATOMIC) || '0.9';
    
    const resultVar = filterName + '_comp_result';
    const alphaVar = filterName + '_comp_alpha';
    const previousVar = filterName + '_previous';
    const funcName = filterName + '_complementaryFilter';

    Blockly.Arduino.definitions_['var_' + resultVar] = `volatile float ${resultVar};`;
    Blockly.Arduino.definitions_['var_' + alphaVar] = `volatile float ${alphaVar} = ${alpha};`;
    Blockly.Arduino.definitions_['var_' + previousVar] = `volatile float ${previousVar} = 0;`;

    Blockly.Arduino.definitions_['func_' + funcName] = `float ${funcName}(float new_value) {\n  ${resultVar} = ${alphaVar} * new_value + (1 - ${alphaVar}) * ${previousVar};\n  ${previousVar} = ${resultVar};\n  return ${resultVar};\n}`;

    code = `${resultVar} = ${funcName}(${new_value});\n`;
    
  } else if (filterType === 'MEDIAN') {
    // 中位值滤波
    var samples = Blockly.Arduino.valueToCode(block, 'filterWindowSize', Blockly.Arduino.ORDER_ATOMIC) || '5';
    
    Blockly.Arduino.definitions_['var_median_filter_' + filterName] = `int ${filterName}_median_buffer[${samples}];\nint ${filterName}_median_index = 0;\nint ${filterName}_median_result = 0;`;
    
    Blockly.Arduino.definitions_['func_median_' + filterName] = `int ${filterName}_medianFilter(int value) {\n  static int sorted[${samples}];\n  ${filterName}_median_buffer[${filterName}_median_index] = value;\n  ${filterName}_median_index = (${filterName}_median_index + 1) % ${samples};\n  for (int i = 0; i < ${samples}; i++) {\n    sorted[i] = ${filterName}_median_buffer[i];\n  }\n  for (int i = 0; i < ${samples} - 1; i++) {\n    for (int j = 0; j < ${samples} - i - 1; j++) {\n      if (sorted[j] > sorted[j + 1]) {\n        int temp = sorted[j];\n        sorted[j] = sorted[j + 1];\n        sorted[j + 1] = temp;\n      }\n    }\n  }\n  ${filterName}_median_result = sorted[${samples} / 2];\n  return ${filterName}_median_result;\n}`;

    code = `${filterName}_median_result = ${filterName}_medianFilter(${new_value});\n`;
    
  } else if (filterType === 'AVERAGE') {
    // 算术平均滤波
    var samples = Blockly.Arduino.valueToCode(block, 'filterWindowSize', Blockly.Arduino.ORDER_ATOMIC) || '5';
    
    Blockly.Arduino.definitions_['var_avg_filter_' + filterName] = `int ${filterName}_avg_buffer[${samples}];\nint ${filterName}_avg_index = 0;\nint ${filterName}_avg_sum = 0;\nint ${filterName}_avg_result = 0;`;
    
    Blockly.Arduino.definitions_['func_average_' + filterName] = `int ${filterName}_averageFilter(int value) {\n  ${filterName}_avg_sum -= ${filterName}_avg_buffer[${filterName}_avg_index];\n  ${filterName}_avg_sum += value;\n  ${filterName}_avg_buffer[${filterName}_avg_index] = value;\n  ${filterName}_avg_index = (${filterName}_avg_index + 1) % ${samples};\n  ${filterName}_avg_result = ${filterName}_avg_sum / ${samples};\n  return ${filterName}_avg_result;\n}`;

    code = `${filterName}_avg_result = ${filterName}_averageFilter(${new_value});\n`;
    
  } else if (filterType === 'MEDIAN_AVERAGE') {
    // 中位值平均滤波
    var samples = Blockly.Arduino.valueToCode(block, 'filterWindowSize', Blockly.Arduino.ORDER_ATOMIC) || '5';
    
    Blockly.Arduino.definitions_['var_medavg_filter_' + filterName] = `int ${filterName}_medavg_buffer[${samples}];\nint ${filterName}_medavg_index = 0;\nint ${filterName}_medavg_result = 0;`;
    
    Blockly.Arduino.definitions_['func_medavg_' + filterName] = `int ${filterName}_medianAverageFilter(int value) {\n  static int sorted[${samples}];\n  ${filterName}_medavg_buffer[${filterName}_medavg_index] = value;\n  ${filterName}_medavg_index = (${filterName}_medavg_index + 1) % ${samples};\n  int sum = 0;\n  for (int i = 0; i < ${samples}; i++) {\n    sorted[i] = ${filterName}_medavg_buffer[i];\n  }\n  for (int i = 0; i < ${samples} - 1; i++) {\n    for (int j = 0; j < ${samples} - i - 1; j++) {\n      if (sorted[j] > sorted[j + 1]) {\n        int temp = sorted[j];\n        sorted[j] = sorted[j + 1];\n        sorted[j + 1] = temp;\n      }\n    }\n  }\n  for (int i = 1; i < ${samples} - 1; i++) {\n    sum += sorted[i];\n  }\n  ${filterName}_medavg_result = sum / (${samples} - 2);\n  return ${filterName}_medavg_result;\n}`;

    code = `${filterName}_medavg_result = ${filterName}_medianAverageFilter(${new_value});\n`;
    
  } else if (filterType === 'LIMITED_AVERAGE') {
    // 限幅平均滤波
    var samples = Blockly.Arduino.valueToCode(block, 'filterWindowSize', Blockly.Arduino.ORDER_ATOMIC) || '5';
    var limit = Blockly.Arduino.valueToCode(block, 'limit', Blockly.Arduino.ORDER_ATOMIC) || '5';
    
    Blockly.Arduino.definitions_['var_limavg_filter_' + filterName] = `int ${filterName}_limavg_buffer[${samples}];\nint ${filterName}_limavg_index = 0;\nint ${filterName}_limavg_sum = 0;\nint ${filterName}_limavg_result = 0;\nint ${filterName}_limavg_last = 0;`;
    
    Blockly.Arduino.definitions_['func_limavg_' + filterName] = `int ${filterName}_limitedAverageFilter(int value) {\n  if (abs(value - ${filterName}_limavg_last) > ${limit}) {\n    value = ${filterName}_limavg_last;\n  }\n  ${filterName}_limavg_last = value;\n  ${filterName}_limavg_sum -= ${filterName}_limavg_buffer[${filterName}_limavg_index];\n  ${filterName}_limavg_sum += value;\n  ${filterName}_limavg_buffer[${filterName}_limavg_index] = value;\n  ${filterName}_limavg_index = (${filterName}_limavg_index + 1) % ${samples};\n  ${filterName}_limavg_result = ${filterName}_limavg_sum / ${samples};\n  return ${filterName}_limavg_result;\n}`;

    code = `${filterName}_limavg_result = ${filterName}_limitedAverageFilter(${new_value});\n`;
    
  } else if (filterType === 'LOWPASS') {
    // 一阶滞后滤波
    var alpha = Blockly.Arduino.valueToCode(block, 'filterWindowSize', Blockly.Arduino.ORDER_ATOMIC) || '0.1';
    
    Blockly.Arduino.definitions_['var_lp_filter_' + filterName] = `int ${filterName}_lp_last = 0;\nint ${filterName}_lp_result = 0;`;
    
    Blockly.Arduino.definitions_['func_lowpass_' + filterName] = `int ${filterName}_lowpassFilter(int value) {\n  ${filterName}_lp_result = ${alpha} * value + (1 - ${alpha}) * ${filterName}_lp_last;\n  ${filterName}_lp_last = ${filterName}_lp_result;\n  return ${filterName}_lp_result;\n}`;

    code = `${filterName}_lp_result = ${filterName}_lowpassFilter(${new_value});\n`;
    
  } else if (filterType === 'WEIGHTED_AVERAGE') {
    // 加权滑动平均滤波
    var samples = Blockly.Arduino.valueToCode(block, 'filterWindowSize', Blockly.Arduino.ORDER_ATOMIC) || '5';
    
    Blockly.Arduino.definitions_['var_wtavg_filter_' + filterName] = `int ${filterName}_wtavg_buffer[${samples}];\nint ${filterName}_wtavg_index = 0;\nint ${filterName}_wtavg_result = 0;`;
    
    Blockly.Arduino.definitions_['func_wtavg_' + filterName] = `int ${filterName}_weightedAverageFilter(int value) {\n  static int weights[${samples}] = {`;
    
    // 生成权重数组
    var weights = [];
    var totalWeight = 0;
    for (var i = 0; i < parseInt(samples); i++) {
      var w = i + 1;
      weights.push(w);
      totalWeight += w;
    }
    Blockly.Arduino.definitions_['func_wtavg_' + filterName] += weights.join(',') + `};\n  static int sum = 0;\n  ${filterName}_wtavg_buffer[${filterName}_wtavg_index] = value;\n  sum = 0;\n  for (int i = 0; i < ${samples}; i++) {\n    int idx = (${filterName}_wtavg_index - ${samples} + i + ${samples}) % ${samples};\n    sum += weights[i] * ${filterName}_wtavg_buffer[idx];\n  }\n  ${filterName}_wtavg_index = (${filterName}_wtavg_index + 1) % ${samples};\n  ${filterName}_wtavg_result = sum / ${totalWeight};\n  return ${filterName}_wtavg_result;\n}`;

    code = `${filterName}_wtavg_result = ${filterName}_weightedAverageFilter(${new_value});\n`;
    
  } else if (filterType === 'ITERATIVE') {
    // 消抖滤波
    Blockly.Arduino.definitions_['var_iter_filter_' + filterName] = `int ${filterName}_iter_last = 0;\nint ${filterName}_iter_result = 0;`;
    
    Blockly.Arduino.definitions_['func_iter_' + filterName] = `int ${filterName}_iterativeFilter(int value) {\n  ${filterName}_iter_last = value;\n  ${filterName}_iter_result = value;\n  return ${filterName}_iter_result;\n}`;

    code = `${filterName}_iter_result = ${filterName}_iterativeFilter(${new_value});\n`;
    
  } else if (filterType === 'LIMITED_ITERATIVE') {
    // 限幅消抖滤波
    var limit = Blockly.Arduino.valueToCode(block, 'limit', Blockly.Arduino.ORDER_ATOMIC) || '5';
    
    Blockly.Arduino.definitions_['var_limiter_filter_' + filterName] = `int ${filterName}_limiter_last = 0;\nint ${filterName}_limiter_result = 0;`;
    
    Blockly.Arduino.definitions_['func_limiter_' + filterName] = `int ${filterName}_limitedIterativeFilter(int value) {\n  if (abs(value - ${filterName}_limiter_last) > ${limit}) {\n    value = ${filterName}_limiter_last;\n  }\n  ${filterName}_limiter_last = value;\n  ${filterName}_limiter_result = value;\n  return ${filterName}_limiter_result;\n}`;

    code = `${filterName}_limiter_result = ${filterName}_limitedIterativeFilter(${new_value});\n`;
  }
  
  return code;
};

// 动态滤波结果积木代码生成器
Blockly.Arduino.forBlock['dynamic_filter_result'] = function(block) {
  var filterName = block.getFieldValue('filterName') || 'filter';
  // 从 mutation 获取 filterType，如果没有则默认为 SLI
  var filterType = block.filterType_ || 'SLI';
  
  var resultVar = '';
  if (filterType === 'SLI') {
    resultVar = filterName + '_sli_result';
  } else if (filterType === 'KAL') {
    resultVar = filterName + '_kal_result';
  } else if (filterType === 'COMP') {
    resultVar = filterName + '_comp_result';
  } else if (filterType === 'MEDIAN') {
    resultVar = filterName + '_median_result';
  } else if (filterType === 'AVERAGE') {
    resultVar = filterName + '_avg_result';
  } else if (filterType === 'MOVING_AVERAGE') {
    resultVar = filterName + '_mov_result';
  } else if (filterType === 'MEDIAN_AVERAGE') {
    resultVar = filterName + '_medavg_result';
  } else if (filterType === 'LIMITED_AVERAGE') {
    resultVar = filterName + '_limavg_result';
  } else if (filterType === 'LOWPASS') {
    resultVar = filterName + '_lp_result';
  } else if (filterType === 'WEIGHTED_AVERAGE') {
    resultVar = filterName + '_wtavg_result';
  } else if (filterType === 'ITERATIVE') {
    resultVar = filterName + '_iter_result';
  } else if (filterType === 'LIMITED_ITERATIVE') {
    resultVar = filterName + '_limiter_result';
  }
  
  return [resultVar, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_tool_normal'] = function () {
    var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
    var code = value_data + ';\n';
    return code;
};

Blockly.Arduino.forBlock['make_tool'] = function () {
    var statements_make_tool_data = Blockly.Arduino.valueToCode(this, 'make_tool_data');
    //var text_make_tool_result = this.getFieldValue('make_tool_result');
    var code1 = '';
    var code = '0.00';
    if (statements_make_tool_data != '') {
    }
    Blockly.Arduino.make_tool_calculate_result_data = code;
    return code1;
};

Blockly.Arduino.forBlock['make_tool_1'] = function () {
    var text_make_tool_1_data = this.getFieldValue('make_tool_1_data');
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_tool_2'] = function () {
    var text_screen_1 = this.getFieldValue('screen_1');
    var text_screen_2 = this.getFieldValue('screen_2');
    var text_screen_3 = this.getFieldValue('screen_3');
    var dropdown_convert_type = this.getFieldValue('convert_type');
    var statements_calculate_data = Blockly.Arduino.statementToCode(this, 'calculate_data');
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_tool_result'] = function () {
    var value_make_tool_result_data = Blockly.Arduino.valueToCode(this, 'make_tool_result_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '';

    var surround_parent = this.getSurroundParent();
    if (surround_parent) {
        code = value_make_tool_result_data;
    }
    else {
        code = '';
    }
    return code;
};

Blockly.Arduino.forBlock['make_tool_result_1'] = function () {
    var code = '';

    var surround_parent = this.getSurroundParent();
    if ((surround_parent && surround_parent.type == 'make_tool_result') || (surround_parent && surround_parent.type == 'make_tool_calculate_1') || (surround_parent && surround_parent.type == 'make_tool_calculate')) {
        code = 'code';
    }
    else {
        code = '';
    }
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_tool_calculate_1'] = function () {
    var value_make_tool_input_data1 = Blockly.Arduino.valueToCode(this, 'make_tool_input_data1', Blockly.Arduino.ORDER_ATOMIC);
    var value_make_tool_input_data2 = Blockly.Arduino.valueToCode(this, 'make_tool_input_data2', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_make_tool_calculate_type = this.getFieldValue('make_tool_calculate_type');
    var code = '';
    var code1 = '';
    var surround_parent = this.getSurroundParent();
    if (surround_parent) {
        if (value_make_tool_input_data1.charAt(0) == '(' && value_make_tool_input_data1.charAt(value_make_tool_input_data1.length - 1) == ')')
            value_make_tool_input_data1 = value_make_tool_input_data1.substring(1, value_make_tool_input_data1.length - 1);
        if (value_make_tool_input_data2.charAt(0) == '(' && value_make_tool_input_data2.charAt(value_make_tool_input_data2.length - 1) == ')')
            value_make_tool_input_data2 = value_make_tool_input_data2.substring(1, value_make_tool_input_data2.length - 1);
        if (Number(value_make_tool_input_data1) != NaN && Number(value_make_tool_input_data2) != NaN) {
            switch (dropdown_make_tool_calculate_type) {
                case '+':
                    {
                        code1 = String(Number(value_make_tool_input_data1) + Number(value_make_tool_input_data2));
                        break;
                    }
                case '-':
                    {
                        code1 = String(Number(value_make_tool_input_data1) - Number(value_make_tool_input_data2));
                        break;
                    }
                case '×':
                    {
                        code1 = String(Number(value_make_tool_input_data1) * Number(value_make_tool_input_data2));
                        break;
                    }
                case '÷':
                    {
                        code1 = String(Number(value_make_tool_input_data1) / Number(value_make_tool_input_data2));
                        break;
                    }
                case '%':
                    {
                        code1 = String(Number(value_make_tool_input_data1) % Number(value_make_tool_input_data2));
                        break;
                    }
                case '^':
                    {
                        code1 = String(Math.pow(Number(value_make_tool_input_data1), Number(value_make_tool_input_data2)));
                        break;
                    }
                default:
                    {
                        code1 = 'NaN';
                    }
            }
        }
        else {
            code1 = 'NaN';
        }
    }
    else {
        code1 = '';
    }

    return [code1, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_tool_calculate'] = function () {
    var value_make_tool_calculate_data = Blockly.Arduino.valueToCode(this, 'make_tool_calculate_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_make_tool_calculate_type = this.getFieldValue('make_tool_calculate_type');
    var code = '';
    var code1 = '';
    var surround_parent = this.getSurroundParent();
    if (surround_parent) {
        if (value_make_tool_calculate_data.charAt(0) == '(' && value_make_tool_calculate_data.charAt(value_make_tool_calculate_data.length - 1) == ')')
            value_make_tool_calculate_data = value_make_tool_calculate_data.substring(1, value_make_tool_calculate_data.length - 1);
        if (Number(value_make_tool_calculate_data) != NaN) {
            switch (dropdown_make_tool_calculate_type) {
                case 'sin':
                    {
                        code1 = String(Math.sin(Number(value_make_tool_calculate_data)));
                        break;
                    }
                case 'cos':
                    {
                        code1 = String(Math.cos(Number(value_make_tool_calculate_data)));
                        break;
                    }
                case 'tan':
                    {
                        code1 = String(Math.tan(Number(value_make_tool_calculate_data)));
                        break;
                    }
                case 'asin':
                    {
                        code1 = String(Math.asin(Number(value_make_tool_calculate_data)));
                        break;
                    }
                case 'acos':
                    {
                        code1 = String(Math.acos(Number(value_make_tool_calculate_data)));
                        break;
                    }
                case 'atan':
                    {
                        code1 = String(Math.atan(Number(value_make_tool_calculate_data)));
                        break;
                    }
                case 'ln':
                    {
                        code1 = String(Math.log(Number(value_make_tool_calculate_data)));
                        break;
                    }
                case 'log10':
                    {
                        code1 = String(Math.log(Number(value_make_tool_calculate_data)) / Math.LN2);
                        break;
                    }
                case 'e^':
                    {
                        code1 = String(Math.exp(Number(value_make_tool_calculate_data)));
                        break;
                    }
                case '10^':
                    {
                        code1 = String(Math.pow(10, Number(value_make_tool_calculate_data)));
                        break;
                    }
                default:
                    code1 = 'NaN';
            }
        }
        else {
            code1 = 'NaN';
        }
    }
    else {
        code1 = '';
    }
    return [code1, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_tool_bit_operation'] = function () {
    var value_bit_operation_1 = Blockly.Arduino.valueToCode(this, 'bit_operation_1', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_bit_operation_type = this.getFieldValue('bit_operation_type');
    var value_bit_operation_2 = Blockly.Arduino.valueToCode(this, 'bit_operation_2', Blockly.Arduino.ORDER_ATOMIC);
    var code = '';

    var surround_parent = this.getSurroundParent();
    if (surround_parent) {
        if (value_bit_operation_1.charAt(0) == '(' && value_bit_operation_1.charAt(value_bit_operation_1.length - 1) == ')')
            value_bit_operation_1 = value_bit_operation_1.substring(1, value_bit_operation_1.length - 1);

        if (value_bit_operation_2.charAt(0) == '(' && value_bit_operation_2.charAt(value_bit_operation_2.length - 1) == ')')
            value_bit_operation_2 = value_bit_operation_2.substring(1, value_bit_operation_2.length - 1);

        if (Number(value_bit_operation_1) != NaN && Number(value_bit_operation_2) != NaN) {
            switch (dropdown_bit_operation_type) {
                case '&':
                    {
                        code = String(Number(value_bit_operation_1) & Number(value_bit_operation_2));
                        break;
                    }
                case '|':
                    {
                        code = String(Number(value_bit_operation_1) | Number(value_bit_operation_2));
                        break;
                    }
                case '^':
                    {
                        code = String(Number(value_bit_operation_1) ^ Number(value_bit_operation_2));
                        break;
                    }
                case '>>':
                    {
                        code = String(Number(value_bit_operation_1) >> Number(value_bit_operation_2));
                        break;
                    }
                case '<<':
                    {
                        code = String(Number(value_bit_operation_1) << Number(value_bit_operation_2));
                        break;
                    }
                default:
                    code = 'NaN';
            }
        }
        else {
            code = 'NaN';
        }
    }
    else {
        code = '';
    }
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_tool_not_operation'] = function () {
    var value_not_operation_data = Blockly.Arduino.valueToCode(this, 'not_operation_data', Blockly.Arduino.ORDER_ATOMIC);
    var code = '';

    var surround_parent = this.getSurroundParent();
    if (surround_parent) {
        if (value_not_operation_data.charAt(0) == '(' && value_not_operation_data.charAt(value_not_operation_data.length - 1) == ')')
            value_not_operation_data = value_not_operation_data.substring(1, value_not_operation_data.length - 1);
        if (Number(value_not_operation_data) != NaN) {
            code = String(~Number(value_not_operation_data));
        }
        else {
            code = 'NaN';
        }

    }
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_tool_convert_data'] = function () {
    var value_convert_data = Blockly.Arduino.valueToCode(this, 'convert_data', Blockly.Arduino.ORDER_ATOMIC);
    var dropdown_convert_type = this.getFieldValue('convert_type');
    var code = '';

    var surround_parent = this.getSurroundParent();
    if (surround_parent) {
        if (value_convert_data.charAt(0) == '(' && value_convert_data.charAt(value_convert_data.length - 1) == ')')
            value_convert_data = value_convert_data.substring(1, value_convert_data.length - 1);
        if (Number(value_convert_data) != NaN) {
            if (dropdown_convert_type == 'BIN')
                code = String(parseInt(Number(value_convert_data), 2));
            else if (dropdown_convert_type == 'OCT')
                code = String(parseInt(Number(value_convert_data), 8));
            else if (dropdown_convert_type == 'HEX') {
                if (value_convert_data.substring(0, 2) != '0x' && value_convert_data.substring(0, 2) != '0X')
                    value_convert_data = '0x' + value_convert_data;
                code = value_convert_data;
            }
            else
                code = value_convert_data;
        }
        else {
            code = 'NaN';
        }
    }
    else {
        code = '';
    }
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_tool_convert_bin'] = function () {
    var checkbox_ic_set_every_1 = this.getFieldValue('ic_set_every_1') == 'TRUE';
    var checkbox_ic_set_every_2 = this.getFieldValue('ic_set_every_2') == 'TRUE';
    var checkbox_ic_set_every_3 = this.getFieldValue('ic_set_every_3') == 'TRUE';
    var checkbox_ic_set_every_4 = this.getFieldValue('ic_set_every_4') == 'TRUE';
    var checkbox_ic_set_every_5 = this.getFieldValue('ic_set_every_5') == 'TRUE';
    var checkbox_ic_set_every_6 = this.getFieldValue('ic_set_every_6') == 'TRUE';
    var checkbox_ic_set_every_7 = this.getFieldValue('ic_set_every_7') == 'TRUE';
    var checkbox_ic_set_every_8 = this.getFieldValue('ic_set_every_8') == 'TRUE';
    var checkbox_ic_set_all = '';

    if (checkbox_ic_set_every_1) {
        checkbox_ic_set_every_1 = '1';
    }
    else {
        checkbox_ic_set_every_1 = '0';
    }

    if (checkbox_ic_set_every_2) {
        checkbox_ic_set_every_2 = '1';
    }
    else {
        checkbox_ic_set_every_2 = '0';
    }

    if (checkbox_ic_set_every_3) {
        checkbox_ic_set_every_3 = '1';
    }
    else {
        checkbox_ic_set_every_3 = '0';
    }

    if (checkbox_ic_set_every_4) {
        checkbox_ic_set_every_4 = '1';
    }
    else {
        checkbox_ic_set_every_4 = '0';
    }

    if (checkbox_ic_set_every_5) {
        checkbox_ic_set_every_5 = '1';
    }
    else {
        checkbox_ic_set_every_5 = '0';
    }

    if (checkbox_ic_set_every_6) {
        checkbox_ic_set_every_6 = '1';
    }
    else {
        checkbox_ic_set_every_6 = '0';
    }

    if (checkbox_ic_set_every_7) {
        checkbox_ic_set_every_7 = '1';
    }
    else {
        checkbox_ic_set_every_7 = '0';
    }

    if (checkbox_ic_set_every_8) {
        checkbox_ic_set_every_8 = '1';
    }
    else {
        checkbox_ic_set_every_8 = '0';
    }
    var code = '';
    var surround_parent = this.getSurroundParent();
    if (surround_parent) {
        checkbox_ic_set_all = checkbox_ic_set_every_1 + checkbox_ic_set_every_2 + checkbox_ic_set_every_3 + checkbox_ic_set_every_4 + checkbox_ic_set_every_5 + checkbox_ic_set_every_6 + checkbox_ic_set_every_7 + checkbox_ic_set_every_8;
        code = checkbox_ic_set_all;
    }

    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_tool_convert_bin_add'] = function () {
    // Create a list with any number of elements of any type.
    var dropdown_math_add_type = this.getFieldValue('math_add_type');
    var code = new Array(this.itemCount_);
    for (var n = 0; n < this.itemCount_; n++) {
        code[n] = Blockly.Arduino.valueToCode(this, 'ADD' + n,
            Blockly.Arduino.ORDER_NONE) || '1';
    }

    var code1 = '';

    for (var n = 0; n < this.itemCount_; n++)
        code1 = code1 + code[n];
    return [code1, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_tool_convert_bin_add_1'] = function () {
    var bin_add_data1 = Blockly.Arduino.valueToCode(this, 'bin_add_data1', Blockly.Arduino.ORDER_ATOMIC);
    var bin_add_data2 = Blockly.Arduino.valueToCode(this, 'bin_add_data2', Blockly.Arduino.ORDER_ATOMIC);
    var code = '';

    var surround_parent = this.getSurroundParent();
    if (surround_parent) {
        code = bin_add_data1 + bin_add_data2;
    }
    else {
        code = '';
    }
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//取模工具
Blockly.Arduino.forBlock['make_tool_modulus'] = function () {
    var dropdown_bitmap_formats = this.getFieldValue('bitmap_formats');
    var dropdown_modulus_way = this.getFieldValue('modulus_way');
    var dropdown_modulus_direction = this.getFieldValue('modulus_direction');
    var dropdown_hz_sharp = this.getFieldValue('hz_sharp');
    var text_hz_line_height = this.getFieldValue('hz_line_height');
    var dropdown_hz_up_down = this.getFieldValue('hz_up_down');
    var text_hz_up_down_data = this.getFieldValue('hz_up_down_data');
    var dropdown_hz_left_right = this.getFieldValue('hz_left_right');
    var text_hz_left_right_data = this.getFieldValue('hz_left_right_data');
    var text_bitmap_width = this.getFieldValue('bitmap_width');
    var text_bitmap_height = this.getFieldValue('bitmap_height');
    var angle_bitmap_rotate = this.getFieldValue('bitmap_rotate');
    var checkbox_show_hz = this.getFieldValue('show_hz') == 'TRUE';
    var text_input_data = this.getFieldValue('input_data');

    var dropdown_hz_variant = 'normal';
    var dropdown_hz_style = 'normal';
    var dropdown_hz_thickness = 'normal';
    var fontSize_width = myAtoi(text_bitmap_width);
    var fontSize_height = myAtoi(text_bitmap_height);
    var bs = Math.ceil(fontSize_width / 8);//每行占字节数

    var move_x = 0;
    var move_y = 0;
    if (dropdown_hz_up_down == "hz_down") {
        move_y = myAtoi(text_hz_up_down_data);
    }
    else {
        move_y = myAtoi("-" + text_hz_up_down_data);
    }

    if (dropdown_hz_left_right == "hz_right") {
        move_x = myAtoi(text_hz_left_right_data);
    }
    else {
        move_x = myAtoi("-" + text_hz_left_right_data);
    }
    canvas.width = fontSize_width;
    canvas.height = fontSize_height;
    ctx.font = dropdown_hz_style + ' ' + dropdown_hz_variant + ' ' + dropdown_hz_thickness + ' ' + text_hz_line_height + 'px ' + dropdown_hz_sharp;
    ctx.textAlign = "left";
    ctx.textBaseline = "top";

    var c = text_input_data;
    ctx.fillStyle = "#000000";
    ctx.fillRect(0, 0, fontSize_width, fontSize_height);//涂背景
    ctx.fillStyle = "#ffffff";
    ctx.translate(fontSize_width / 2, fontSize_height / 2);
    ctx.rotate(Math.PI / 180 * (angle_bitmap_rotate - 0));
    ctx.fillText(c, move_x - fontSize_width / 2, move_y - fontSize_height / 2);//写字
    var data = ctx.getImageData(0, 0, fontSize_width, fontSize_height).data;//获取图像
    var zm = new Array(bs * fontSize_height);
    for (var i = 0; i < zm.length; i++)zm[i] = 0;//初始化字模数组
    for (var i = 0; i < fontSize_height; i++)//读像素值组成字模数组
        for (var j = 0; j < fontSize_width; j++)
            if (data[i * fontSize_width * 4 + j * 4]) zm[parseInt(j / 8) + i * bs] += bitArr[j % 8];
    var outStr = "";//将字模数组转化为十六进制形式
    for (var i = 0; i < zm.length - 1; i++)outStr += toHex(zm[i]) + ",";
    outStr += toHex(zm[i]);

    var zm1 = new Array(bs * fontSize_height);
    var outstr1 = "";
    for (var i in zm) zm1[i] = zm[i].toString(2);
    for (var i in zm1) {
        var str = "";
        for (var j = 0; j < 8 - zm1[i].length; j++)str += "0";
        zm1[i] = str + zm1[i];
    }
    for (var i in zm1) outstr1 += zm1[i];

    var HZ_image = "";
    var num_hz = 0;
    for (var i = 0; i < fontSize_width; i++) {
        HZ_image += "--";
        if (i == (fontSize_width - 1)) HZ_image += "\n|";
    }

    for (var data_hz of outstr1) {
        num_hz++;
        if (num_hz == outstr1.length) {
            HZ_image += "|\n";
        }
        else if (num_hz % (bs * 8) < fontSize_width && num_hz % (bs * 8) > 0) {
            if (data_hz == "0") HZ_image += "  ";
            else if (data_hz == "1") HZ_image += "0 ";
        }
        else if (num_hz % (bs * 8) == 0) {
            HZ_image += "|\n|";
        }
    }
    for (var i = 0; i < fontSize_width; i++) {
        HZ_image += "--";
    }
    HZ_image = "/*" + "\n" + HZ_image + "\n" + "*/";

    var hz_sharp = "";
    switch (dropdown_hz_sharp) {
        case "STHeiti":
            hz_sharp = "华文黑体";
            break;
        case "STKaiti":
            hz_sharp = "华文楷体";
            break;
        case "STXihei":
            hz_sharp = "华文细黑";
            break;
        case "STSong":
            hz_sharp = "华文宋体";
            break;
        case "STZhongsong":
            hz_sharp = "华文中宋";
            break;
        case "STFangsong":
            hz_sharp = "华文仿宋";
            break;
        case "STCaiyun":
            hz_sharp = "华文彩云";
            break;
        case "STHupo":
            hz_sharp = "华文琥珀";
            break;
        case "STLiti":
            hz_sharp = "华文隶书";
            break;
        case "STXingkai":
            hz_sharp = "华文行楷";
            break;
        case "STXinwei":
            hz_sharp = "华文新魏";
            break;
        case "simHei":
            hz_sharp = "黑体";
            break;
        case "simSun":
            hz_sharp = "宋体";
            break;
        case "NSimSun":
            hz_sharp = "新宋体";
            break;
        case "FangSong":
            hz_sharp = "仿宋";
            break;
        case "KaiTi":
            hz_sharp = "楷体";
            break;
        case "FangSong_GB2312":
            hz_sharp = "仿宋_GB2312";
            break;
        case "KaiTi_GB2312":
            hz_sharp = "楷体_GB2312";
            break;
        case "LiSu":
            hz_sharp = "隶书";
            break;
        case "YouYuan":
            hz_sharp = "幼圆";
            break;
        case "PMingLiU":
            hz_sharp = "新细明体";
            break;
        case "MingLiU":
            hz_sharp = "细明体";
            break;
        case "DFKai-SB":
            hz_sharp = "标楷体";
            break;
        case "Microsoft JhengHei":
            hz_sharp = "微软正黑体";
            break;
        case "Microsoft YaHei":
            hz_sharp = "微软雅黑体";
            break;
        default:
            hz_sharp = dropdown_hz_sharp;
            break;
    }
    hz_sharp = "字体：" + hz_sharp + "  字号：" + text_hz_line_height + "px" + "  显示文字：" + text_input_data + '\n' + HZ_image;

    var modulus_array = new Array();
    for (var i = 0; i < fontSize_height; i++) {
        modulus_array[i] = new Array();
        for (var j = 0; j < bs * 8; j++) {
            modulus_array[i][j] = "";
        }
    }

    for (var i = 1; i <= fontSize_height; i++) {
        for (var j = 1; j <= bs * 8; j++) {
            modulus_array[i - 1][j - 1] = outstr1.charAt((i - 1) * bs * 8 + j - 1);
        }
    }
    //取模方式
    //逐列式 - 1,逐行式 - 2,列行式 - 3,行列式 - 4

    //取模走向
    //顺向(高位在前) - 1,逆向(低位在前) - 2
    var bit_num = fontSize_height * bs;
    var modulus_data = "";
    var array_x = 0;
    var array_y = 0;
    var modulus_y = Math.ceil(fontSize_height / 8);
    var modulus_x = Math.ceil(fontSize_width / 8);

    //if(dropdown_modulus_direction == '1')
    //{
    //逐列式 - 1
    if (dropdown_modulus_way == '1') {
        bit_num = modulus_y * fontSize_width;
        for (var j = 1; j <= bit_num; j++) {
            for (var i = 1; i <= 8; i++) {
                if (j % modulus_y == 0)
                    array_y = (modulus_y - 1) * 8 + i - 1;
                else
                    array_y = (j % modulus_y - 1) * 8 + i - 1;

                array_x = Math.ceil(j / modulus_y) - 1;
                if (array_x > (fontSize_width - 1))
                    break;
                if (array_y > (fontSize_height - 1)) {
                    if (dropdown_bitmap_formats == '1')
                        modulus_data += "0";
                    else
                        modulus_data += "1";
                    continue;
                }

                //modulus_data+=modulus_array[array_y][array_x];
                if (dropdown_bitmap_formats == '1')
                    modulus_data += modulus_array[array_y][array_x];
                else {
                    if (modulus_array[array_y][array_x] == "0")
                        modulus_data += "1";
                    else
                        modulus_data += "0";
                }
            }
            modulus_data += ",";
        }
    }
    //逐行式 - 2
    else if (dropdown_modulus_way == '2') {
        bit_num = modulus_x * fontSize_height;
        for (var j = 1; j <= bit_num; j++) {
            for (var i = 1; i <= 8; i++) {
                if (j % modulus_x == 0)
                    array_x = (modulus_x - 1) * 8 + i - 1;
                else
                    array_x = (j % modulus_x - 1) * 8 + i - 1;
                array_y = Math.ceil(j / modulus_x) - 1;

                //modulus_data+=modulus_array[array_y][array_x];
                if (dropdown_bitmap_formats == '1')
                    modulus_data += modulus_array[array_y][array_x];
                else {
                    if (modulus_array[array_y][array_x] == "0")
                        modulus_data += "1";
                    else
                        modulus_data += "0";
                }
            }
            modulus_data += ",";
        }
    }
    //列行式 - 3
    else if (dropdown_modulus_way == '3') {
        bit_num = modulus_y * fontSize_width;
        for (var j = 1; j <= bit_num; j++) {
            for (var i = 1; i <= 8; i++) {
                if (j % (modulus_x * 8) == 0)
                    array_x = modulus_x * 8 - 1;
                else
                    array_x = j % (modulus_x * 8) - 1;
                array_y = (Math.ceil(j / (modulus_x * 8)) - 1) * 8 + i - 1;
                if (array_x > (fontSize_width - 1))
                    break;
                if (array_y > (fontSize_height - 1)) {
                    if (dropdown_bitmap_formats == '1')
                        modulus_data += "0";
                    else
                        modulus_data += "1";
                    continue;
                }

                //modulus_data+=modulus_array[array_y][array_x];
                if (dropdown_bitmap_formats == '1')
                    modulus_data += modulus_array[array_y][array_x];
                else {
                    if (modulus_array[array_y][array_x] == "0")
                        modulus_data += "1";
                    else
                        modulus_data += "0";
                }
            }
            modulus_data += ",";
        }
    }
    //行列式 - 4
    else if (dropdown_modulus_way == '4') {
        bit_num = modulus_x * fontSize_height;
        for (var j = 1; j <= bit_num; j++) {
            for (var i = 1; i <= 8; i++) {
                if (j % fontSize_height == 0)
                    array_y = fontSize_height - 1;
                else
                    array_y = j % fontSize_height - 1;
                array_x = (Math.ceil(j / fontSize_height) - 1) * 8 + i - 1;

                //modulus_data+=modulus_array[array_y][array_x];
                if (dropdown_bitmap_formats == '1')
                    modulus_data += modulus_array[array_y][array_x];
                else {
                    if (modulus_array[array_y][array_x] == "0")
                        modulus_data += "1";
                    else
                        modulus_data += "0";
                }
            }
            modulus_data += ",";
        }
    }
    //}
    var now_data = "";
    var end_data = "";
    if (dropdown_modulus_direction == 2) {
        for (var i of modulus_data) {
            if (i == ",") {
                end_data += now_data;
                end_data += ",";
                now_data = "";
            }
            else
                now_data = i + now_data;
        }
        modulus_data = end_data;
    }

    now_data = "";
    end_data = "0x";
    for (var i of modulus_data) {
        if (i == ",") {
            end_data += ",0x";
            continue;
        }
        now_data += i;
        if (now_data.length == 4) {
            end_data += string_Bin_to_Hex(now_data);
            now_data = "";
        }
    }
    modulus_data = end_data;
    modulus_data = modulus_data.substring(0, modulus_data.length - 3);

    if (checkbox_show_hz)
        Blockly.Arduino.definitions_['var_declare_tool_modulus_data_' + dropdown_hz_sharp + '_' + text_hz_line_height + 'px' + encodeUnicode(text_input_data)] = '//' + hz_sharp;

    var code = modulus_data;
    return code;
};

Blockly.Arduino.forBlock['make_tool_modulus_1'] = function () {
    var statements_modulus_data = Blockly.Arduino.statementToCode(this, 'modulus_data');
    var text_output_data = this.getFieldValue('output_data');
    var code = '';
    return code;
};

var img = new Image();
Blockly.Arduino.forBlock['make_tool_modulus_2'] = function () {
    var dropdown_bitmap_formats = this.getFieldValue('bitmap_formats');
    var dropdown_modulus_way = this.getFieldValue('modulus_way');
    var dropdown_modulus_direction = this.getFieldValue('modulus_direction');
    var dropdown_hz_sharp = this.getFieldValue('hz_sharp');
    var text_hz_line_height = this.getFieldValue('hz_line_height');
    var dropdown_hz_up_down = this.getFieldValue('hz_up_down');
    var text_hz_up_down_data = this.getFieldValue('hz_up_down_data');
    var dropdown_hz_left_right = this.getFieldValue('hz_left_right');
    var text_hz_left_right_data = this.getFieldValue('hz_left_right_data');
    var text_bitmap_width = this.getFieldValue('bitmap_width');
    var text_bitmap_height = this.getFieldValue('bitmap_height');
    var angle_bitmap_rotate = this.getFieldValue('bitmap_rotate');
    var checkbox_show_hz = this.getFieldValue('show_hz') == 'TRUE';
    var text_input_data = this.getFieldValue('input_data');

    var dropdown_hz_variant = 'normal';
    var dropdown_hz_style = 'normal';
    var dropdown_hz_thickness = 'normal';
    var fontSize_width = myAtoi(text_bitmap_width);
    var fontSize_height = myAtoi(text_bitmap_height);
    var bs = Math.ceil(fontSize_width / 8);//每行占字节数

    var move_x = 0;
    var move_y = 0;
    if (dropdown_hz_up_down == "hz_down") {
        move_y = myAtoi(text_hz_up_down_data);
    }
    else {
        move_y = myAtoi("-" + text_hz_up_down_data);
    }

    if (dropdown_hz_left_right == "hz_right") {
        move_x = myAtoi(text_hz_left_right_data);
    }
    else {
        move_x = myAtoi("-" + text_hz_left_right_data);
    }
    canvas.width = fontSize_width;
    canvas.height = fontSize_height;
    ctx.font = dropdown_hz_style + ' ' + dropdown_hz_variant + ' ' + dropdown_hz_thickness + ' ' + text_hz_line_height + 'px ' + dropdown_hz_sharp;
    ctx.textAlign = "left";
    ctx.textBaseline = "top";


    //img.src = "/pcb.png";

    var c = text_input_data;

    ctx.fillStyle = "#000000";
    ctx.fillRect(0, 0, fontSize_width, fontSize_height);//涂背景
    ctx.fillStyle = "#ffffff";
    ctx.translate(fontSize_width / 2, fontSize_height / 2);
    ctx.rotate(Math.PI / 180 * (angle_bitmap_rotate - 0));
    ctx.fillText(c, move_x - fontSize_width / 2, move_y - fontSize_height / 2);//写字
    //ctx.drawImage(img,0,0,100,100);//写字

    var data = ctx.getImageData(0, 0, fontSize_width, fontSize_height).data;//获取图像
    var zm = new Array(bs * fontSize_height);
    for (var i = 0; i < zm.length; i++)zm[i] = 0;//初始化字模数组
    for (var i = 0; i < fontSize_height; i++)//读像素值组成字模数组
        for (var j = 0; j < fontSize_width; j++)
            if (data[i * fontSize_width * 4 + j * 4]) zm[parseInt(j / 8) + i * bs] += bitArr[j % 8];
    var outStr = "";//将字模数组转化为十六进制形式
    for (var i = 0; i < zm.length - 1; i++)outStr += toHex(zm[i]) + ",";
    outStr += toHex(zm[i]);

    var zm1 = new Array(bs * fontSize_height);
    var outstr1 = "";
    for (var i in zm) zm1[i] = zm[i].toString(2);
    for (var i in zm1) {
        var str = "";
        for (var j = 0; j < 8 - zm1[i].length; j++)str += "0";
        zm1[i] = str + zm1[i];
    }
    for (var i in zm1) outstr1 += zm1[i];

    var HZ_image = "";
    var num_hz = 0;
    for (var i = 0; i < fontSize_width; i++) {
        HZ_image += "--";
        if (i == (fontSize_width - 1)) HZ_image += "\n|";
    }

    for (var data_hz of outstr1) {
        num_hz++;
        if (num_hz == outstr1.length) {
            HZ_image += "|\n";
        }
        else if (num_hz % (bs * 8) < fontSize_width && num_hz % (bs * 8) > 0) {
            if (data_hz == "0") HZ_image += "  ";
            else if (data_hz == "1") HZ_image += "0 ";
        }
        else if (num_hz % (bs * 8) == 0) {
            HZ_image += "|\n|";
        }
    }
    for (var i = 0; i < fontSize_width; i++) {
        HZ_image += "--";
    }
    HZ_image = "/*" + "\n" + HZ_image + "\n" + "*/";

    var hz_sharp = "";
    switch (dropdown_hz_sharp) {
        case "STHeiti":
            hz_sharp = "华文黑体";
            break;
        case "STKaiti":
            hz_sharp = "华文楷体";
            break;
        case "STXihei":
            hz_sharp = "华文细黑";
            break;
        case "STSong":
            hz_sharp = "华文宋体";
            break;
        case "STZhongsong":
            hz_sharp = "华文中宋";
            break;
        case "STFangsong":
            hz_sharp = "华文仿宋";
            break;
        case "STCaiyun":
            hz_sharp = "华文彩云";
            break;
        case "STHupo":
            hz_sharp = "华文琥珀";
            break;
        case "STLiti":
            hz_sharp = "华文隶书";
            break;
        case "STXingkai":
            hz_sharp = "华文行楷";
            break;
        case "STXinwei":
            hz_sharp = "华文新魏";
            break;
        case "simHei":
            hz_sharp = "黑体";
            break;
        case "simSun":
            hz_sharp = "宋体";
            break;
        case "NSimSun":
            hz_sharp = "新宋体";
            break;
        case "FangSong":
            hz_sharp = "仿宋";
            break;
        case "KaiTi":
            hz_sharp = "楷体";
            break;
        case "FangSong_GB2312":
            hz_sharp = "仿宋_GB2312";
            break;
        case "KaiTi_GB2312":
            hz_sharp = "楷体_GB2312";
            break;
        case "LiSu":
            hz_sharp = "隶书";
            break;
        case "YouYuan":
            hz_sharp = "幼圆";
            break;
        case "PMingLiU":
            hz_sharp = "新细明体";
            break;
        case "MingLiU":
            hz_sharp = "细明体";
            break;
        case "DFKai-SB":
            hz_sharp = "标楷体";
            break;
        case "Microsoft JhengHei":
            hz_sharp = "微软正黑体";
            break;
        case "Microsoft YaHei":
            hz_sharp = "微软雅黑体";
            break;
        default:
            hz_sharp = dropdown_hz_sharp;
            break;
    }
    hz_sharp = "字体：" + hz_sharp + "  字号：" + text_hz_line_height + "px" + "  显示文字：" + text_input_data + '\n' + HZ_image;

    var modulus_array = new Array();
    for (var i = 0; i < fontSize_height; i++) {
        modulus_array[i] = new Array();
        for (var j = 0; j < bs * 8; j++) {
            modulus_array[i][j] = "";
        }
    }

    for (var i = 1; i <= fontSize_height; i++) {
        for (var j = 1; j <= bs * 8; j++) {
            modulus_array[i - 1][j - 1] = outstr1.charAt((i - 1) * bs * 8 + j - 1);
        }
    }
    //取模方式
    //逐列式 - 1,逐行式 - 2,列行式 - 3,行列式 - 4

    //取模走向
    //顺向(高位在前) - 1,逆向(低位在前) - 2
    var bit_num = fontSize_height * bs;
    var modulus_data = "";
    var array_x = 0;
    var array_y = 0;
    var modulus_y = Math.ceil(fontSize_height / 8);
    var modulus_x = Math.ceil(fontSize_width / 8);

    //if(dropdown_modulus_direction == '1')
    //{
    //逐列式 - 1
    if (dropdown_modulus_way == '1') {
        bit_num = modulus_y * fontSize_width;
        for (var j = 1; j <= bit_num; j++) {
            for (var i = 1; i <= 8; i++) {
                if (j % modulus_y == 0)
                    array_y = (modulus_y - 1) * 8 + i - 1;
                else
                    array_y = (j % modulus_y - 1) * 8 + i - 1;

                array_x = Math.ceil(j / modulus_y) - 1;
                if (array_x > (fontSize_width - 1))
                    break;
                if (array_y > (fontSize_height - 1)) {
                    if (dropdown_bitmap_formats == '1')
                        modulus_data += "0";
                    else
                        modulus_data += "1";
                    continue;
                }

                //modulus_data+=modulus_array[array_y][array_x];
                if (dropdown_bitmap_formats == '1')
                    modulus_data += modulus_array[array_y][array_x];
                else {
                    if (modulus_array[array_y][array_x] == "0")
                        modulus_data += "1";
                    else
                        modulus_data += "0";
                }
            }
            modulus_data += ",";
        }
    }
    //逐行式 - 2
    else if (dropdown_modulus_way == '2') {
        bit_num = modulus_x * fontSize_height;
        for (var j = 1; j <= bit_num; j++) {
            for (var i = 1; i <= 8; i++) {
                if (j % modulus_x == 0)
                    array_x = (modulus_x - 1) * 8 + i - 1;
                else
                    array_x = (j % modulus_x - 1) * 8 + i - 1;
                array_y = Math.ceil(j / modulus_x) - 1;

                //modulus_data+=modulus_array[array_y][array_x];
                if (dropdown_bitmap_formats == '1')
                    modulus_data += modulus_array[array_y][array_x];
                else {
                    if (modulus_array[array_y][array_x] == "0")
                        modulus_data += "1";
                    else
                        modulus_data += "0";
                }
            }
            modulus_data += ",";
        }
    }
    //列行式 - 3
    else if (dropdown_modulus_way == '3') {
        bit_num = modulus_y * fontSize_width;
        for (var j = 1; j <= bit_num; j++) {
            for (var i = 1; i <= 8; i++) {
                if (j % (modulus_x * 8) == 0)
                    array_x = modulus_x * 8 - 1;
                else
                    array_x = j % (modulus_x * 8) - 1;
                array_y = (Math.ceil(j / (modulus_x * 8)) - 1) * 8 + i - 1;
                if (array_x > (fontSize_width - 1))
                    break;
                if (array_y > (fontSize_height - 1)) {
                    if (dropdown_bitmap_formats == '1')
                        modulus_data += "0";
                    else
                        modulus_data += "1";
                    continue;
                }

                //modulus_data+=modulus_array[array_y][array_x];
                if (dropdown_bitmap_formats == '1')
                    modulus_data += modulus_array[array_y][array_x];
                else {
                    if (modulus_array[array_y][array_x] == "0")
                        modulus_data += "1";
                    else
                        modulus_data += "0";
                }
            }
            modulus_data += ",";
        }
    }
    //行列式 - 4
    else if (dropdown_modulus_way == '4') {
        bit_num = modulus_x * fontSize_height;
        for (var j = 1; j <= bit_num; j++) {
            for (var i = 1; i <= 8; i++) {
                if (j % fontSize_height == 0)
                    array_y = fontSize_height - 1;
                else
                    array_y = j % fontSize_height - 1;
                array_x = (Math.ceil(j / fontSize_height) - 1) * 8 + i - 1;

                //modulus_data+=modulus_array[array_y][array_x];
                if (dropdown_bitmap_formats == '1')
                    modulus_data += modulus_array[array_y][array_x];
                else {
                    if (modulus_array[array_y][array_x] == "0")
                        modulus_data += "1";
                    else
                        modulus_data += "0";
                }
            }
            modulus_data += ",";
        }
    }
    //}
    var now_data = "";
    var end_data = "";
    if (dropdown_modulus_direction == 2) {
        for (var i of modulus_data) {
            if (i == ",") {
                end_data += now_data;
                end_data += ",";
                now_data = "";
            }
            else
                now_data = i + now_data;
        }
        modulus_data = end_data;
    }

    now_data = "";
    end_data = "0x";
    for (var i of modulus_data) {
        if (i == ",") {
            end_data += ",0x";
            continue;
        }
        now_data += i;
        if (now_data.length == 4) {
            end_data += string_Bin_to_Hex(now_data);
            now_data = "";
        }
    }
    modulus_data = end_data;
    modulus_data = modulus_data.substring(0, modulus_data.length - 3);

    if (checkbox_show_hz)
        Blockly.Arduino.definitions_['var_declare_tool_modulus_data_' + dropdown_hz_sharp + '_' + text_hz_line_height + 'px' + encodeUnicode(text_input_data)] = '//' + hz_sharp;

    var code = modulus_data;
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['lists_create_with_hz'] = function () {
    // Create a list with any number of elements of any type.
    this.setFieldValue(this.itemCount_, "y");
    var varName = Blockly.Arduino.variableDB_.getName(this.getFieldValue('VAR'),
        Blockly.Variables.NAME_TYPE);
    var X = this.getFieldValue('x');
    var Y = this.getFieldValue('y');
    var checkbox_save_hz = this.getFieldValue('save_hz') == 'TRUE';
    var code = new Array(this.itemCount_);
    for (var n = 0; n < this.itemCount_; n++) {
        code[n] = '{' + Blockly.Arduino.valueToCode(this, 'ADD' + n,
            Blockly.Arduino.ORDER_NONE) + '}';
    }

    var lists_data = code.join(',\n  ');
    var X_1 = 0;
    var X_1_old = 0;
    for (var i of lists_data) {
        if (i == '{') {
            X_1 = 0;
            continue;
        }
        else if (i == '}') {
            if (X_1_old < X_1)
                X_1_old = X_1;
        }
        else if (i == ',')
            X_1++;
    }
    X_1 = X_1_old + 1;

    this.setFieldValue(X_1, "x");

    if (checkbox_save_hz)
        Blockly.Arduino.definitions_['var_declare' + varName] = 'static const unsigned char PROGMEM ' + varName + '[' + Y + ']' + '[' + X_1 + '] = ' + '{\n  ' + lists_data + '\n};';
    else
        Blockly.Arduino.definitions_['var_declare' + varName] = 'unsigned char ' + varName + '[' + Y + ']' + '[' + X_1 + '] = ' + '{\n  ' + lists_data + '\n};';
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['lists_create_with_hz_1'] = function () {
    var varName = Blockly.Arduino.variableDB_.getName(this.getFieldValue('VAR'),
        Blockly.Variables.NAME_TYPE);
    var X = this.getFieldValue('x');
    var checkbox_save_hz = this.getFieldValue('save_hz') == 'TRUE';
    var value_input = Blockly.Arduino.valueToCode(this, 'input_data', Blockly.Arduino.ORDER_ATOMIC);

    var X_1 = 0;
    for (var i of value_input) {
        if (i == ',')
            X_1++;
    }
    X_1++;

    this.setFieldValue(X_1, "x");

    if (checkbox_save_hz)
        Blockly.Arduino.definitions_['var_declare' + varName] = 'static const unsigned char PROGMEM ' + varName + '[' + X_1 + '] = ' + '{' + value_input + '};';
    else
        Blockly.Arduino.definitions_['var_declare' + varName] = 'unsigned char ' + varName + '[' + X_1 + '] = ' + '{' + value_input + '};';
    var code = '';
    return code;
};

//将文本或符号编码
function encodeUnicode1(str) {
    let res = [];
    for (let i = 0; i < str.length; i++) {
        res[i] = ("00" + str.charCodeAt(i).toString(16)).slice(-4);
        res[i] = res[i].toUpperCase();
    }
    return "" + res.join(" ");
};

//将文本或符号编码
function encodeUnicode2(str) {
    let res = [];
    for (let i = 0; i < str.length; i++) {
        res[i] = ("00" + str.charCodeAt(i).toString(16)).slice(-4);
        res[i] = res[i].toUpperCase();
    }
    return "\\u" + res.join("\\u");
};


var json = {
    "00A4": "A1E8",
    "00A7": "A1EC",
    "00A8": "A1A7",
    "00B0": "A1E3",
    "00B1": "A1C0",
    "00B7": "A1A4",
    "00D7": "A1C1",
    "00E0": "A8A4",
    "00E1": "A8A2",
    "00E8": "A8A8",
    "00E9": "A8A6",
    "00EA": "A8BA",
    "00EC": "A8AC",
    "00ED": "A8AA",
    "00F2": "A8B0",
    "00F3": "A8AE",
    "00F7": "A1C2",
    "00F9": "A8B4",
    "00FA": "A8B2",
    "00FC": "A8B9",
    "0101": "A8A1",
    "0113": "A8A5",
    "011B": "A8A7",
    "012B": "A8A9",
    "014D": "A8AD",
    "016B": "A8B1",
    "01CE": "A8A3",
    "01D0": "A8AB",
    "01D2": "A8AF",
    "01D4": "A8B3",
    "01D6": "A8B5",
    "01D8": "A8B6",
    "01DA": "A8B7",
    "01DC": "A8B8",
    "02C7": "A1A6",
    "02C9": "A1A5",
    "0391": "A6A1",
    "0392": "A6A2",
    "0393": "A6A3",
    "0394": "A6A4",
    "0395": "A6A5",
    "0396": "A6A6",
    "0397": "A6A7",
    "0398": "A6A8",
    "0399": "A6A9",
    "039A": "A6AA",
    "039B": "A6AB",
    "039C": "A6AC",
    "039D": "A6AD",
    "039E": "A6AE",
    "039F": "A6AF",
    "03A0": "A6B0",
    "03A1": "A6B1",
    "03A3": "A6B2",
    "03A4": "A6B3",
    "03A5": "A6B4",
    "03A6": "A6B5",
    "03A7": "A6B6",
    "03A8": "A6B7",
    "03A9": "A6B8",
    "03B1": "A6C1",
    "03B2": "A6C2",
    "03B3": "A6C3",
    "03B4": "A6C4",
    "03B5": "A6C5",
    "03B6": "A6C6",
    "03B7": "A6C7",
    "03B8": "A6C8",
    "03B9": "A6C9",
    "03BA": "A6CA",
    "03BB": "A6CB",
    "03BC": "A6CC",
    "03BD": "A6CD",
    "03BE": "A6CE",
    "03BF": "A6CF",
    "03C0": "A6D0",
    "03C1": "A6D1",
    "03C3": "A6D2",
    "03C4": "A6D3",
    "03C5": "A6D4",
    "03C6": "A6D5",
    "03C7": "A6D6",
    "03C8": "A6D7",
    "03C9": "A6D8",
    "0401": "A7A7",
    "0410": "A7A1",
    "0411": "A7A2",
    "0412": "A7A3",
    "0413": "A7A4",
    "0414": "A7A5",
    "0415": "A7A6",
    "0416": "A7A8",
    "0417": "A7A9",
    "0418": "A7AA",
    "0419": "A7AB",
    "041A": "A7AC",
    "041B": "A7AD",
    "041C": "A7AE",
    "041D": "A7AF",
    "041E": "A7B0",
    "041F": "A7B1",
    "0420": "A7B2",
    "0421": "A7B3",
    "0422": "A7B4",
    "0423": "A7B5",
    "0424": "A7B6",
    "0425": "A7B7",
    "0426": "A7B8",
    "0427": "A7B9",
    "0428": "A7BA",
    "0429": "A7BB",
    "042A": "A7BC",
    "042B": "A7BD",
    "042C": "A7BE",
    "042D": "A7BF",
    "042E": "A7C0",
    "042F": "A7C1",
    "0430": "A7D1",
    "0431": "A7D2",
    "0432": "A7D3",
    "0433": "A7D4",
    "0434": "A7D5",
    "0435": "A7D6",
    "0436": "A7D8",
    "0437": "A7D9",
    "0438": "A7DA",
    "0439": "A7DB",
    "043A": "A7DC",
    "043B": "A7DD",
    "043C": "A7DE",
    "043D": "A7DF",
    "043E": "A7E0",
    "043F": "A7E1",
    "0440": "A7E2",
    "0441": "A7E3",
    "0442": "A7E4",
    "0443": "A7E5",
    "0444": "A7E6",
    "0445": "A7E7",
    "0446": "A7E8",
    "0447": "A7E9",
    "0448": "A7EA",
    "0449": "A7EB",
    "044A": "A7EC",
    "044B": "A7ED",
    "044C": "A7EE",
    "044D": "A7EF",
    "044E": "A7F0",
    "044F": "A7F1",
    "0451": "A7D7",
    "2014": "A1AA",
    "2016": "A1AC",
    "2018": "A1AE",
    "2019": "A1AF",
    "201C": "A1B0",
    "201D": "A1B1",
    "2026": "A1AD",
    "2030": "A1EB",
    "2032": "A1E4",
    "2033": "A1E5",
    "203B": "A1F9",
    "2103": "A1E6",
    "2116": "A1ED",
    "2160": "A2F1",
    "2161": "A2F2",
    "2162": "A2F3",
    "2163": "A2F4",
    "2164": "A2F5",
    "2165": "A2F6",
    "2166": "A2F7",
    "2167": "A2F8",
    "2168": "A2F9",
    "2169": "A2FA",
    "216A": "A2FB",
    "216B": "A2FC",
    "2190": "A1FB",
    "2191": "A1FC",
    "2192": "A1FA",
    "2193": "A1FD",
    "2208": "A1CA",
    "220F": "A1C7",
    "2211": "A1C6",
    "221A": "A1CC",
    "221D": "A1D8",
    "221E": "A1DE",
    "2220": "A1CF",
    "2225": "A1CE",
    "2227": "A1C4",
    "2228": "A1C5",
    "2229": "A1C9",
    "222A": "A1C8",
    "222B": "A1D2",
    "222E": "A1D3",
    "2234": "A1E0",
    "2235": "A1DF",
    "2236": "A1C3",
    "2237": "A1CB",
    "223D": "A1D7",
    "2248": "A1D6",
    "224C": "A1D5",
    "2260": "A1D9",
    "2261": "A1D4",
    "2264": "A1DC",
    "2265": "A1DD",
    "226E": "A1DA",
    "226F": "A1DB",
    "2299": "A1D1",
    "22A5": "A1CD",
    "2312": "A1D0",
    "2460": "A2D9",
    "2461": "A2DA",
    "2462": "A2DB",
    "2463": "A2DC",
    "2464": "A2DD",
    "2465": "A2DE",
    "2466": "A2DF",
    "2467": "A2E0",
    "2468": "A2E1",
    "2469": "A2E2",
    "2474": "A2C5",
    "2475": "A2C6",
    "2476": "A2C7",
    "2477": "A2C8",
    "2478": "A2C9",
    "2479": "A2CA",
    "247A": "A2CB",
    "247B": "A2CC",
    "247C": "A2CD",
    "247D": "A2CE",
    "247E": "A2CF",
    "247F": "A2D0",
    "2480": "A2D1",
    "2481": "A2D2",
    "2482": "A2D3",
    "2483": "A2D4",
    "2484": "A2D5",
    "2485": "A2D6",
    "2486": "A2D7",
    "2487": "A2D8",
    "2488": "A2B1",
    "2489": "A2B2",
    "248A": "A2B3",
    "248B": "A2B4",
    "248C": "A2B5",
    "248D": "A2B6",
    "248E": "A2B7",
    "248F": "A2B8",
    "2490": "A2B9",
    "2491": "A2BA",
    "2492": "A2BB",
    "2493": "A2BC",
    "2494": "A2BD",
    "2495": "A2BE",
    "2496": "A2BF",
    "2497": "A2C0",
    "2498": "A2C1",
    "2499": "A2C2",
    "249A": "A2C3",
    "249B": "A2C4",
    "2500": "A9A4",
    "2501": "A9A5",
    "2502": "A9A6",
    "2503": "A9A7",
    "2504": "A9A8",
    "2505": "A9A9",
    "2506": "A9AA",
    "2507": "A9AB",
    "2508": "A9AC",
    "2509": "A9AD",
    "250A": "A9AE",
    "250B": "A9AF",
    "250C": "A9B0",
    "250D": "A9B1",
    "250E": "A9B2",
    "250F": "A9B3",
    "2510": "A9B4",
    "2511": "A9B5",
    "2512": "A9B6",
    "2513": "A9B7",
    "2514": "A9B8",
    "2515": "A9B9",
    "2516": "A9BA",
    "2517": "A9BB",
    "2518": "A9BC",
    "2519": "A9BD",
    "251A": "A9BE",
    "251B": "A9BF",
    "251C": "A9C0",
    "251D": "A9C1",
    "251E": "A9C2",
    "251F": "A9C3",
    "2520": "A9C4",
    "2521": "A9C5",
    "2522": "A9C6",
    "2523": "A9C7",
    "2524": "A9C8",
    "2525": "A9C9",
    "2526": "A9CA",
    "2527": "A9CB",
    "2528": "A9CC",
    "2529": "A9CD",
    "252A": "A9CE",
    "252B": "A9CF",
    "252C": "A9D0",
    "252D": "A9D1",
    "252E": "A9D2",
    "252F": "A9D3",
    "2530": "A9D4",
    "2531": "A9D5",
    "2532": "A9D6",
    "2533": "A9D7",
    "2534": "A9D8",
    "2535": "A9D9",
    "2536": "A9DA",
    "2537": "A9DB",
    "2538": "A9DC",
    "2539": "A9DD",
    "253A": "A9DE",
    "253B": "A9DF",
    "253C": "A9E0",
    "253D": "A9E1",
    "253E": "A9E2",
    "253F": "A9E3",
    "2540": "A9E4",
    "2541": "A9E5",
    "2542": "A9E6",
    "2543": "A9E7",
    "2544": "A9E8",
    "2545": "A9E9",
    "2546": "A9EA",
    "2547": "A9EB",
    "2548": "A9EC",
    "2549": "A9ED",
    "254A": "A9EE",
    "254B": "A9EF",
    "25A0": "A1F6",
    "25A1": "A1F5",
    "25B2": "A1F8",
    "25B3": "A1F7",
    "25C6": "A1F4",
    "25C7": "A1F3",
    "25CB": "A1F0",
    "25CE": "A1F2",
    "25CF": "A1F1",
    "2605": "A1EF",
    "2606": "A1EE",
    "2640": "A1E2",
    "2642": "A1E1",
    "3000": "A1A1",
    "3001": "A1A2",
    "3002": "A1A3",
    "3003": "A1A8",
    "3005": "A1A9",
    "3008": "A1B4",
    "3009": "A1B5",
    "300A": "A1B6",
    "300B": "A1B7",
    "300C": "A1B8",
    "300D": "A1B9",
    "300E": "A1BA",
    "300F": "A1BB",
    "3010": "A1BE",
    "3011": "A1BF",
    "3013": "A1FE",
    "3014": "A1B2",
    "3015": "A1B3",
    "3016": "A1BC",
    "3017": "A1BD",
    "3041": "A4A1",
    "3042": "A4A2",
    "3043": "A4A3",
    "3044": "A4A4",
    "3045": "A4A5",
    "3046": "A4A6",
    "3047": "A4A7",
    "3048": "A4A8",
    "3049": "A4A9",
    "304A": "A4AA",
    "304B": "A4AB",
    "304C": "A4AC",
    "304D": "A4AD",
    "304E": "A4AE",
    "304F": "A4AF",
    "3050": "A4B0",
    "3051": "A4B1",
    "3052": "A4B2",
    "3053": "A4B3",
    "3054": "A4B4",
    "3055": "A4B5",
    "3056": "A4B6",
    "3057": "A4B7",
    "3058": "A4B8",
    "3059": "A4B9",
    "305A": "A4BA",
    "305B": "A4BB",
    "305C": "A4BC",
    "305D": "A4BD",
    "305E": "A4BE",
    "305F": "A4BF",
    "3060": "A4C0",
    "3061": "A4C1",
    "3062": "A4C2",
    "3063": "A4C3",
    "3064": "A4C4",
    "3065": "A4C5",
    "3066": "A4C6",
    "3067": "A4C7",
    "3068": "A4C8",
    "3069": "A4C9",
    "306A": "A4CA",
    "306B": "A4CB",
    "306C": "A4CC",
    "306D": "A4CD",
    "306E": "A4CE",
    "306F": "A4CF",
    "3070": "A4D0",
    "3071": "A4D1",
    "3072": "A4D2",
    "3073": "A4D3",
    "3074": "A4D4",
    "3075": "A4D5",
    "3076": "A4D6",
    "3077": "A4D7",
    "3078": "A4D8",
    "3079": "A4D9",
    "307A": "A4DA",
    "307B": "A4DB",
    "307C": "A4DC",
    "307D": "A4DD",
    "307E": "A4DE",
    "307F": "A4DF",
    "3080": "A4E0",
    "3081": "A4E1",
    "3082": "A4E2",
    "3083": "A4E3",
    "3084": "A4E4",
    "3085": "A4E5",
    "3086": "A4E6",
    "3087": "A4E7",
    "3088": "A4E8",
    "3089": "A4E9",
    "308A": "A4EA",
    "308B": "A4EB",
    "308C": "A4EC",
    "308D": "A4ED",
    "308E": "A4EE",
    "308F": "A4EF",
    "3090": "A4F0",
    "3091": "A4F1",
    "3092": "A4F2",
    "3093": "A4F3",
    "30A1": "A5A1",
    "30A2": "A5A2",
    "30A3": "A5A3",
    "30A4": "A5A4",
    "30A5": "A5A5",
    "30A6": "A5A6",
    "30A7": "A5A7",
    "30A8": "A5A8",
    "30A9": "A5A9",
    "30AA": "A5AA",
    "30AB": "A5AB",
    "30AC": "A5AC",
    "30AD": "A5AD",
    "30AE": "A5AE",
    "30AF": "A5AF",
    "30B0": "A5B0",
    "30B1": "A5B1",
    "30B2": "A5B2",
    "30B3": "A5B3",
    "30B4": "A5B4",
    "30B5": "A5B5",
    "30B6": "A5B6",
    "30B7": "A5B7",
    "30B8": "A5B8",
    "30B9": "A5B9",
    "30BA": "A5BA",
    "30BB": "A5BB",
    "30BC": "A5BC",
    "30BD": "A5BD",
    "30BE": "A5BE",
    "30BF": "A5BF",
    "30C0": "A5C0",
    "30C1": "A5C1",
    "30C2": "A5C2",
    "30C3": "A5C3",
    "30C4": "A5C4",
    "30C5": "A5C5",
    "30C6": "A5C6",
    "30C7": "A5C7",
    "30C8": "A5C8",
    "30C9": "A5C9",
    "30CA": "A5CA",
    "30CB": "A5CB",
    "30CC": "A5CC",
    "30CD": "A5CD",
    "30CE": "A5CE",
    "30CF": "A5CF",
    "30D0": "A5D0",
    "30D1": "A5D1",
    "30D2": "A5D2",
    "30D3": "A5D3",
    "30D4": "A5D4",
    "30D5": "A5D5",
    "30D6": "A5D6",
    "30D7": "A5D7",
    "30D8": "A5D8",
    "30D9": "A5D9",
    "30DA": "A5DA",
    "30DB": "A5DB",
    "30DC": "A5DC",
    "30DD": "A5DD",
    "30DE": "A5DE",
    "30DF": "A5DF",
    "30E0": "A5E0",
    "30E1": "A5E1",
    "30E2": "A5E2",
    "30E3": "A5E3",
    "30E4": "A5E4",
    "30E5": "A5E5",
    "30E6": "A5E6",
    "30E7": "A5E7",
    "30E8": "A5E8",
    "30E9": "A5E9",
    "30EA": "A5EA",
    "30EB": "A5EB",
    "30EC": "A5EC",
    "30ED": "A5ED",
    "30EE": "A5EE",
    "30EF": "A5EF",
    "30F0": "A5F0",
    "30F1": "A5F1",
    "30F2": "A5F2",
    "30F3": "A5F3",
    "30F4": "A5F4",
    "30F5": "A5F5",
    "30F6": "A5F6",
    "3105": "A8C5",
    "3106": "A8C6",
    "3107": "A8C7",
    "3108": "A8C8",
    "3109": "A8C9",
    "310A": "A8CA",
    "310B": "A8CB",
    "310C": "A8CC",
    "310D": "A8CD",
    "310E": "A8CE",
    "310F": "A8CF",
    "3110": "A8D0",
    "3111": "A8D1",
    "3112": "A8D2",
    "3113": "A8D3",
    "3114": "A8D4",
    "3115": "A8D5",
    "3116": "A8D6",
    "3117": "A8D7",
    "3118": "A8D8",
    "3119": "A8D9",
    "311A": "A8DA",
    "311B": "A8DB",
    "311C": "A8DC",
    "311D": "A8DD",
    "311E": "A8DE",
    "311F": "A8DF",
    "3120": "A8E0",
    "3121": "A8E1",
    "3122": "A8E2",
    "3123": "A8E3",
    "3124": "A8E4",
    "3125": "A8E5",
    "3126": "A8E6",
    "3127": "A8E7",
    "3128": "A8E8",
    "3129": "A8E9",
    "3220": "A2E5",
    "3221": "A2E6",
    "3222": "A2E7",
    "3223": "A2E8",
    "3224": "A2E9",
    "3225": "A2EA",
    "3226": "A2EB",
    "3227": "A2EC",
    "3228": "A2ED",
    "3229": "A2EE",
    "4E00": "D2BB",
    "4E01": "B6A1",
    "4E03": "C6DF",
    "4E07": "CDF2",
    "4E08": "D5C9",
    "4E09": "C8FD",
    "4E0A": "C9CF",
    "4E0B": "CFC2",
    "4E0C": "D8A2",
    "4E0D": "B2BB",
    "4E0E": "D3EB",
    "4E10": "D8A4",
    "4E11": "B3F3",
    "4E13": "D7A8",
    "4E14": "C7D2",
    "4E15": "D8A7",
    "4E16": "CAC0",
    "4E18": "C7F0",
    "4E19": "B1FB",
    "4E1A": "D2B5",
    "4E1B": "B4D4",
    "4E1C": "B6AB",
    "4E1D": "CBBF",
    "4E1E": "D8A9",
    "4E22": "B6AA",
    "4E24": "C1BD",
    "4E25": "D1CF",
    "4E27": "C9A5",
    "4E28": "D8AD",
    "4E2A": "B8F6",
    "4E2B": "D1BE",
    "4E2C": "E3DC",
    "4E2D": "D6D0",
    "4E30": "B7E1",
    "4E32": "B4AE",
    "4E34": "C1D9",
    "4E36": "D8BC",
    "4E38": "CDE8",
    "4E39": "B5A4",
    "4E3A": "CEAA",
    "4E3B": "D6F7",
    "4E3D": "C0F6",
    "4E3E": "BED9",
    "4E3F": "D8AF",
    "4E43": "C4CB",
    "4E45": "BEC3",
    "4E47": "D8B1",
    "4E48": "C3B4",
    "4E49": "D2E5",
    "4E4B": "D6AE",
    "4E4C": "CEDA",
    "4E4D": "D5A7",
    "4E4E": "BAF5",
    "4E4F": "B7A6",
    "4E50": "C0D6",
    "4E52": "C6B9",
    "4E53": "C5D2",
    "4E54": "C7C7",
    "4E56": "B9D4",
    "4E58": "B3CB",
    "4E59": "D2D2",
    "4E5C": "D8BF",
    "4E5D": "BEC5",
    "4E5E": "C6F2",
    "4E5F": "D2B2",
    "4E60": "CFB0",
    "4E61": "CFE7",
    "4E66": "CAE9",
    "4E69": "D8C0",
    "4E70": "C2F2",
    "4E71": "C2D2",
    "4E73": "C8E9",
    "4E7E": "C7AC",
    "4E86": "C1CB",
    "4E88": "D3E8",
    "4E89": "D5F9",
    "4E8B": "CAC2",
    "4E8C": "B6FE",
    "4E8D": "D8A1",
    "4E8E": "D3DA",
    "4E8F": "BFF7",
    "4E91": "D4C6",
    "4E92": "BBA5",
    "4E93": "D8C1",
    "4E94": "CEE5",
    "4E95": "BEAE",
    "4E98": "D8A8",
    "4E9A": "D1C7",
    "4E9B": "D0A9",
    "4E9F": "D8BD",
    "4EA0": "D9EF",
    "4EA1": "CDF6",
    "4EA2": "BFBA",
    "4EA4": "BDBB",
    "4EA5": "BAA5",
    "4EA6": "D2E0",
    "4EA7": "B2FA",
    "4EA8": "BAE0",
    "4EA9": "C4B6",
    "4EAB": "CFED",
    "4EAC": "BEA9",
    "4EAD": "CDA4",
    "4EAE": "C1C1",
    "4EB2": "C7D7",
    "4EB3": "D9F1",
    "4EB5": "D9F4",
    "4EBA": "C8CB",
    "4EBB": "D8E9",
    "4EBF": "D2DA",
    "4EC0": "CAB2",
    "4EC1": "C8CA",
    "4EC2": "D8EC",
    "4EC3": "D8EA",
    "4EC4": "D8C6",
    "4EC5": "BDF6",
    "4EC6": "C6CD",
    "4EC7": "B3F0",
    "4EC9": "D8EB",
    "4ECA": "BDF1",
    "4ECB": "BDE9",
    "4ECD": "C8D4",
    "4ECE": "B4D3",
    "4ED1": "C2D8",
    "4ED3": "B2D6",
    "4ED4": "D7D0",
    "4ED5": "CACB",
    "4ED6": "CBFB",
    "4ED7": "D5CC",
    "4ED8": "B8B6",
    "4ED9": "CFC9",
    "4EDD": "D9DA",
    "4EDE": "D8F0",
    "4EDF": "C7AA",
    "4EE1": "D8EE",
    "4EE3": "B4FA",
    "4EE4": "C1EE",
    "4EE5": "D2D4",
    "4EE8": "D8ED",
    "4EEA": "D2C7",
    "4EEB": "D8EF",
    "4EEC": "C3C7",
    "4EF0": "D1F6",
    "4EF2": "D6D9",
    "4EF3": "D8F2",
    "4EF5": "D8F5",
    "4EF6": "BCFE",
    "4EF7": "BCDB",
    "4EFB": "C8CE",
    "4EFD": "B7DD",
    "4EFF": "B7C2",
    "4F01": "C6F3",
    "4F09": "D8F8",
    "4F0A": "D2C1",
    "4F0D": "CEE9",
    "4F0E": "BCBF",
    "4F0F": "B7FC",
    "4F10": "B7A5",
    "4F11": "D0DD",
    "4F17": "D6DA",
    "4F18": "D3C5",
    "4F19": "BBEF",
    "4F1A": "BBE1",
    "4F1B": "D8F1",
    "4F1E": "C9A1",
    "4F1F": "CEB0",
    "4F20": "B4AB",
    "4F22": "D8F3",
    "4F24": "C9CB",
    "4F25": "D8F6",
    "4F26": "C2D7",
    "4F27": "D8F7",
    "4F2A": "CEB1",
    "4F2B": "D8F9",
    "4F2F": "B2AE",
    "4F30": "B9C0",
    "4F32": "D9A3",
    "4F34": "B0E9",
    "4F36": "C1E6",
    "4F38": "C9EC",
    "4F3A": "CBC5",
    "4F3C": "CBC6",
    "4F3D": "D9A4",
    "4F43": "B5E8",
    "4F46": "B5AB",
    "4F4D": "CEBB",
    "4F4E": "B5CD",
    "4F4F": "D7A1",
    "4F50": "D7F4",
    "4F51": "D3D3",
    "4F53": "CCE5",
    "4F55": "BACE",
    "4F57": "D9A2",
    "4F58": "D9DC",
    "4F59": "D3E0",
    "4F5A": "D8FD",
    "4F5B": "B7F0",
    "4F5C": "D7F7",
    "4F5D": "D8FE",
    "4F5E": "D8FA",
    "4F5F": "D9A1",
    "4F60": "C4E3",
    "4F63": "D3B6",
    "4F64": "D8F4",
    "4F65": "D9DD",
    "4F67": "D8FB",
    "4F69": "C5E5",
    "4F6C": "C0D0",
    "4F6F": "D1F0",
    "4F70": "B0DB",
    "4F73": "BCD1",
    "4F74": "D9A6",
    "4F76": "D9A5",
    "4F7B": "D9AC",
    "4F7C": "D9AE",
    "4F7E": "D9AB",
    "4F7F": "CAB9",
    "4F83": "D9A9",
    "4F84": "D6B6",
    "4F88": "B3DE",
    "4F89": "D9A8",
    "4F8B": "C0FD",
    "4F8D": "CACC",
    "4F8F": "D9AA",
    "4F91": "D9A7",
    "4F94": "D9B0",
    "4F97": "B6B1",
    "4F9B": "B9A9",
    "4F9D": "D2C0",
    "4FA0": "CFC0",
    "4FA3": "C2C2",
    "4FA5": "BDC4",
    "4FA6": "D5EC",
    "4FA7": "B2E0",
    "4FA8": "C7C8",
    "4FA9": "BFEB",
    "4FAA": "D9AD",
    "4FAC": "D9AF",
    "4FAE": "CEEA",
    "4FAF": "BAEE",
    "4FB5": "C7D6",
    "4FBF": "B1E3",
    "4FC3": "B4D9",
    "4FC4": "B6ED",
    "4FC5": "D9B4",
    "4FCA": "BFA1",
    "4FCE": "D9DE",
    "4FCF": "C7CE",
    "4FD0": "C0FE",
    "4FD1": "D9B8",
    "4FD7": "CBD7",
    "4FD8": "B7FD",
    "4FDA": "D9B5",
    "4FDC": "D9B7",
    "4FDD": "B1A3",
    "4FDE": "D3E1",
    "4FDF": "D9B9",
    "4FE1": "D0C5",
    "4FE3": "D9B6",
    "4FE6": "D9B1",
    "4FE8": "D9B2",
    "4FE9": "C1A9",
    "4FEA": "D9B3",
    "4FED": "BCF3",
    "4FEE": "D0DE",
    "4FEF": "B8A9",
    "4FF1": "BEE3",
    "4FF3": "D9BD",
    "4FF8": "D9BA",
    "4FFA": "B0B3",
    "4FFE": "D9C2",
    "500C": "D9C4",
    "500D": "B1B6",
    "500F": "D9BF",
    "5012": "B5B9",
    "5014": "BEF3",
    "5018": "CCC8",
    "5019": "BAF2",
    "501A": "D2D0",
    "501C": "D9C3",
    "501F": "BDE8",
    "5021": "B3AB",
    "5025": "D9C5",
    "5026": "BEEB",
    "5028": "D9C6",
    "5029": "D9BB",
    "502A": "C4DF",
    "502C": "D9BE",
    "502D": "D9C1",
    "502E": "D9C0",
    "503A": "D5AE",
    "503C": "D6B5",
    "503E": "C7E3",
    "5043": "D9C8",
    "5047": "BCD9",
    "5048": "D9CA",
    "504C": "D9BC",
    "504E": "D9CB",
    "504F": "C6AB",
    "5055": "D9C9",
    "505A": "D7F6",
    "505C": "CDA3",
    "5065": "BDA1",
    "506C": "D9CC",
    "5076": "C5BC",
    "5077": "CDB5",
    "507B": "D9CD",
    "507E": "D9C7",
    "507F": "B3A5",
    "5080": "BFFE",
    "5085": "B8B5",
    "5088": "C0FC",
    "508D": "B0F8",
    "50A3": "B4F6",
    "50A5": "D9CE",
    "50A7": "D9CF",
    "50A8": "B4A2",
    "50A9": "D9D0",
    "50AC": "B4DF",
    "50B2": "B0C1",
    "50BA": "D9D1",
    "50BB": "C9B5",
    "50CF": "CFF1",
    "50D6": "D9D2",
    "50DA": "C1C5",
    "50E6": "D9D6",
    "50E7": "C9AE",
    "50EC": "D9D5",
    "50ED": "D9D4",
    "50EE": "D9D7",
    "50F3": "CBDB",
    "50F5": "BDA9",
    "50FB": "C6A7",
    "5106": "D9D3",
    "5107": "D9D8",
    "510B": "D9D9",
    "5112": "C8E5",
    "5121": "C0DC",
    "513F": "B6F9",
    "5140": "D8A3",
    "5141": "D4CA",
    "5143": "D4AA",
    "5144": "D0D6",
    "5145": "B3E4",
    "5146": "D5D7",
    "5148": "CFC8",
    "5149": "B9E2",
    "514B": "BFCB",
    "514D": "C3E2",
    "5151": "B6D2",
    "5154": "CDC3",
    "5155": "D9EE",
    "5156": "D9F0",
    "515A": "B5B3",
    "515C": "B6B5",
    "5162": "BEA4",
    "5165": "C8EB",
    "5168": "C8AB",
    "516B": "B0CB",
    "516C": "B9AB",
    "516D": "C1F9",
    "516E": "D9E2",
    "5170": "C0BC",
    "5171": "B9B2",
    "5173": "B9D8",
    "5174": "D0CB",
    "5175": "B1F8",
    "5176": "C6E4",
    "5177": "BEDF",
    "5178": "B5E4",
    "5179": "D7C8",
    "517B": "D1F8",
    "517C": "BCE6",
    "517D": "CADE",
    "5180": "BCBD",
    "5181": "D9E6",
    "5182": "D8E7",
    "5185": "C4DA",
    "5188": "B8D4",
    "5189": "C8BD",
    "518C": "B2E1",
    "518D": "D4D9",
    "5192": "C3B0",
    "5195": "C3E1",
    "5196": "DAA2",
    "5197": "C8DF",
    "5199": "D0B4",
    "519B": "BEFC",
    "519C": "C5A9",
    "51A0": "B9DA",
    "51A2": "DAA3",
    "51A4": "D4A9",
    "51A5": "DAA4",
    "51AB": "D9FB",
    "51AC": "B6AC",
    "51AF": "B7EB",
    "51B0": "B1F9",
    "51B1": "D9FC",
    "51B2": "B3E5",
    "51B3": "BEF6",
    "51B5": "BFF6",
    "51B6": "D2B1",
    "51B7": "C0E4",
    "51BB": "B6B3",
    "51BC": "D9FE",
    "51BD": "D9FD",
    "51C0": "BEBB",
    "51C4": "C6E0",
    "51C6": "D7BC",
    "51C7": "DAA1",
    "51C9": "C1B9",
    "51CB": "B5F2",
    "51CC": "C1E8",
    "51CF": "BCF5",
    "51D1": "B4D5",
    "51DB": "C1DD",
    "51DD": "C4FD",
    "51E0": "BCB8",
    "51E1": "B7B2",
    "51E4": "B7EF",
    "51EB": "D9EC",
    "51ED": "C6BE",
    "51EF": "BFAD",
    "51F0": "BBCB",
    "51F3": "B5CA",
    "51F5": "DBC9",
    "51F6": "D0D7",
    "51F8": "CDB9",
    "51F9": "B0BC",
    "51FA": "B3F6",
    "51FB": "BBF7",
    "51FC": "DBCA",
    "51FD": "BAAF",
    "51FF": "D4E4",
    "5200": "B5B6",
    "5201": "B5F3",
    "5202": "D8D6",
    "5203": "C8D0",
    "5206": "B7D6",
    "5207": "C7D0",
    "5208": "D8D7",
    "520A": "BFAF",
    "520D": "DBBB",
    "520E": "D8D8",
    "5211": "D0CC",
    "5212": "BBAE",
    "5216": "EBBE",
    "5217": "C1D0",
    "5218": "C1F5",
    "5219": "D4F2",
    "521A": "B8D5",
    "521B": "B4B4",
    "521D": "B3F5",
    "5220": "C9BE",
    "5224": "C5D0",
    "5228": "C5D9",
    "5229": "C0FB",
    "522B": "B1F0",
    "522D": "D8D9",
    "522E": "B9CE",
    "5230": "B5BD",
    "5233": "D8DA",
    "5236": "D6C6",
    "5237": "CBA2",
    "5238": "C8AF",
    "5239": "C9B2",
    "523A": "B4CC",
    "523B": "BFCC",
    "523D": "B9F4",
    "523F": "D8DB",
    "5240": "D8DC",
    "5241": "B6E7",
    "5242": "BCC1",
    "5243": "CCEA",
    "524A": "CFF7",
    "524C": "D8DD",
    "524D": "C7B0",
    "5250": "B9D0",
    "5251": "BDA3",
    "5254": "CCDE",
    "5256": "C6CA",
    "525C": "D8E0",
    "525E": "D8DE",
    "5261": "D8DF",
    "5265": "B0FE",
    "5267": "BEE7",
    "5269": "CAA3",
    "526A": "BCF4",
    "526F": "B8B1",
    "5272": "B8EE",
    "527D": "D8E2",
    "527F": "BDCB",
    "5281": "D8E4",
    "5282": "D8E3",
    "5288": "C5FC",
    "5290": "D8E5",
    "5293": "D8E6",
    "529B": "C1A6",
    "529D": "C8B0",
    "529E": "B0EC",
    "529F": "B9A6",
    "52A0": "BCD3",
    "52A1": "CEF1",
    "52A2": "DBBD",
    "52A3": "C1D3",
    "52A8": "B6AF",
    "52A9": "D6FA",
    "52AA": "C5AC",
    "52AB": "BDD9",
    "52AC": "DBBE",
    "52AD": "DBBF",
    "52B1": "C0F8",
    "52B2": "BEA2",
    "52B3": "C0CD",
    "52BE": "DBC0",
    "52BF": "CAC6",
    "52C3": "B2AA",
    "52C7": "D3C2",
    "52C9": "C3E3",
    "52CB": "D1AB",
    "52D0": "DBC2",
    "52D2": "C0D5",
    "52D6": "DBC3",
    "52D8": "BFB1",
    "52DF": "C4BC",
    "52E4": "C7DA",
    "52F0": "DBC4",
    "52F9": "D9E8",
    "52FA": "C9D7",
    "52FE": "B9B4",
    "52FF": "CEF0",
    "5300": "D4C8",
    "5305": "B0FC",
    "5306": "B4D2",
    "5308": "D0D9",
    "530D": "D9E9",
    "530F": "DECB",
    "5310": "D9EB",
    "5315": "D8B0",
    "5316": "BBAF",
    "5317": "B1B1",
    "5319": "B3D7",
    "531A": "D8CE",
    "531D": "D4D1",
    "5320": "BDB3",
    "5321": "BFEF",
    "5323": "CFBB",
    "5326": "D8D0",
    "532A": "B7CB",
    "532E": "D8D1",
    "5339": "C6A5",
    "533A": "C7F8",
    "533B": "D2BD",
    "533E": "D8D2",
    "533F": "C4E4",
    "5341": "CAAE",
    "5343": "C7A7",
    "5345": "D8A6",
    "5347": "C9FD",
    "5348": "CEE7",
    "5349": "BBDC",
    "534A": "B0EB",
    "534E": "BBAA",
    "534F": "D0AD",
    "5351": "B1B0",
    "5352": "D7E4",
    "5353": "D7BF",
    "5355": "B5A5",
    "5356": "C2F4",
    "5357": "C4CF",
    "535A": "B2A9",
    "535C": "B2B7",
    "535E": "B1E5",
    "535F": "DFB2",
    "5360": "D5BC",
    "5361": "BFA8",
    "5362": "C2AC",
    "5363": "D8D5",
    "5364": "C2B1",
    "5366": "D8D4",
    "5367": "CED4",
    "5369": "DAE0",
    "536B": "CEC0",
    "536E": "D8B4",
    "536F": "C3AE",
    "5370": "D3A1",
    "5371": "CEA3",
    "5373": "BCB4",
    "5374": "C8B4",
    "5375": "C2D1",
    "5377": "BEED",
    "5378": "D0B6",
    "537A": "DAE1",
    "537F": "C7E4",
    "5382": "B3A7",
    "5384": "B6F2",
    "5385": "CCFC",
    "5386": "C0FA",
    "5389": "C0F7",
    "538B": "D1B9",
    "538C": "D1E1",
    "538D": "D8C7",
    "5395": "B2DE",
    "5398": "C0E5",
    "539A": "BAF1",
    "539D": "D8C8",
    "539F": "D4AD",
    "53A2": "CFE1",
    "53A3": "D8C9",
    "53A5": "D8CA",
    "53A6": "CFC3",
    "53A8": "B3F8",
    "53A9": "BEC7",
    "53AE": "D8CB",
    "53B6": "DBCC",
    "53BB": "C8A5",
    "53BF": "CFD8",
    "53C1": "C8FE",
    "53C2": "B2CE",
    "53C8": "D3D6",
    "53C9": "B2E6",
    "53CA": "BCB0",
    "53CB": "D3D1",
    "53CC": "CBAB",
    "53CD": "B7B4",
    "53D1": "B7A2",
    "53D4": "CAE5",
    "53D6": "C8A1",
    "53D7": "CADC",
    "53D8": "B1E4",
    "53D9": "D0F0",
    "53DB": "C5D1",
    "53DF": "DBC5",
    "53E0": "B5FE",
    "53E3": "BFDA",
    "53E4": "B9C5",
    "53E5": "BEE4",
    "53E6": "C1ED",
    "53E8": "DFB6",
    "53E9": "DFB5",
    "53EA": "D6BB",
    "53EB": "BDD0",
    "53EC": "D5D9",
    "53ED": "B0C8",
    "53EE": "B6A3",
    "53EF": "BFC9",
    "53F0": "CCA8",
    "53F1": "DFB3",
    "53F2": "CAB7",
    "53F3": "D3D2",
    "53F5": "D8CF",
    "53F6": "D2B6",
    "53F7": "BAC5",
    "53F8": "CBBE",
    "53F9": "CCBE",
    "53FB": "DFB7",
    "53FC": "B5F0",
    "53FD": "DFB4",
    "5401": "D3F5",
    "5403": "B3D4",
    "5404": "B8F7",
    "5406": "DFBA",
    "5408": "BACF",
    "5409": "BCAA",
    "540A": "B5F5",
    "540C": "CDAC",
    "540D": "C3FB",
    "540E": "BAF3",
    "540F": "C0F4",
    "5410": "CDC2",
    "5411": "CFF2",
    "5412": "DFB8",
    "5413": "CFC5",
    "5415": "C2C0",
    "5416": "DFB9",
    "5417": "C2F0",
    "541B": "BEFD",
    "541D": "C1DF",
    "541E": "CDCC",
    "541F": "D2F7",
    "5420": "B7CD",
    "5421": "DFC1",
    "5423": "DFC4",
    "5426": "B7F1",
    "5427": "B0C9",
    "5428": "B6D6",
    "5429": "B7D4",
    "542B": "BAAC",
    "542C": "CCFD",
    "542D": "BFD4",
    "542E": "CBB1",
    "542F": "C6F4",
    "5431": "D6A8",
    "5432": "DFC5",
    "5434": "CEE2",
    "5435": "B3B3",
    "5438": "CEFC",
    "5439": "B4B5",
    "543B": "CEC7",
    "543C": "BAF0",
    "543E": "CEE1",
    "5440": "D1BD",
    "5443": "DFC0",
    "5446": "B4F4",
    "5448": "B3CA",
    "544A": "B8E6",
    "544B": "DFBB",
    "5450": "C4C5",
    "5452": "DFBC",
    "5453": "DFBD",
    "5454": "DFBE",
    "5455": "C5BB",
    "5456": "DFBF",
    "5457": "DFC2",
    "5458": "D4B1",
    "5459": "DFC3",
    "545B": "C7BA",
    "545C": "CED8",
    "5462": "C4D8",
    "5464": "DFCA",
    "5466": "DFCF",
    "5468": "D6DC",
    "5471": "DFC9",
    "5472": "DFDA",
    "5473": "CEB6",
    "5475": "BAC7",
    "5476": "DFCE",
    "5477": "DFC8",
    "5478": "C5DE",
    "547B": "C9EB",
    "547C": "BAF4",
    "547D": "C3FC",
    "5480": "BED7",
    "5482": "DFC6",
    "5484": "DFCD",
    "5486": "C5D8",
    "548B": "D5A6",
    "548C": "BACD",
    "548E": "BECC",
    "548F": "D3BD",
    "5490": "B8C0",
    "5492": "D6E4",
    "5494": "DFC7",
    "5495": "B9BE",
    "5496": "BFA7",
    "5499": "C1FC",
    "549A": "DFCB",
    "549B": "DFCC",
    "549D": "DFD0",
    "54A3": "DFDB",
    "54A4": "DFE5",
    "54A6": "DFD7",
    "54A7": "DFD6",
    "54A8": "D7C9",
    "54A9": "DFE3",
    "54AA": "DFE4",
    "54AB": "E5EB",
    "54AC": "D2A7",
    "54AD": "DFD2",
    "54AF": "BFA9",
    "54B1": "D4DB",
    "54B3": "BFC8",
    "54B4": "DFD4",
    "54B8": "CFCC",
    "54BB": "DFDD",
    "54BD": "D1CA",
    "54BF": "DFDE",
    "54C0": "B0A7",
    "54C1": "C6B7",
    "54C2": "DFD3",
    "54C4": "BAE5",
    "54C6": "B6DF",
    "54C7": "CDDB",
    "54C8": "B9FE",
    "54C9": "D4D5",
    "54CC": "DFDF",
    "54CD": "CFEC",
    "54CE": "B0A5",
    "54CF": "DFE7",
    "54D0": "DFD1",
    "54D1": "D1C6",
    "54D2": "DFD5",
    "54D3": "DFD8",
    "54D4": "DFD9",
    "54D5": "DFDC",
    "54D7": "BBA9",
    "54D9": "DFE0",
    "54DA": "DFE1",
    "54DC": "DFE2",
    "54DD": "DFE6",
    "54DE": "DFE8",
    "54DF": "D3B4",
    "54E5": "B8E7",
    "54E6": "C5B6",
    "54E7": "DFEA",
    "54E8": "C9DA",
    "54E9": "C1A8",
    "54EA": "C4C4",
    "54ED": "BFDE",
    "54EE": "CFF8",
    "54F2": "D5DC",
    "54F3": "DFEE",
    "54FA": "B2B8",
    "54FC": "BADF",
    "54FD": "DFEC",
    "54FF": "DBC1",
    "5501": "D1E4",
    "5506": "CBF4",
    "5507": "B4BD",
    "5509": "B0A6",
    "550F": "DFF1",
    "5510": "CCC6",
    "5511": "DFF2",
    "5514": "DFED",
    "551B": "DFE9",
    "5520": "DFEB",
    "5522": "DFEF",
    "5523": "DFF0",
    "5524": "BBBD",
    "5527": "DFF3",
    "552A": "DFF4",
    "552C": "BBA3",
    "552E": "CADB",
    "552F": "CEA8",
    "5530": "E0A7",
    "5531": "B3AA",
    "5533": "E0A6",
    "5537": "E0A1",
    "553C": "DFFE",
    "553E": "CDD9",
    "553F": "DFFC",
    "5541": "DFFA",
    "5543": "BFD0",
    "5544": "D7C4",
    "5546": "C9CC",
    "5549": "DFF8",
    "554A": "B0A1",
    "5550": "DFFD",
    "5555": "DFFB",
    "5556": "E0A2",
    "555C": "E0A8",
    "5561": "B7C8",
    "5564": "C6A1",
    "5565": "C9B6",
    "5566": "C0B2",
    "5567": "DFF5",
    "556A": "C5BE",
    "556C": "D8C4",
    "556D": "DFF9",
    "556E": "C4F6",
    "5575": "E0A3",
    "5576": "E0A4",
    "5577": "E0A5",
    "5578": "D0A5",
    "557B": "E0B4",
    "557C": "CCE4",
    "557E": "E0B1",
    "5580": "BFA6",
    "5581": "E0AF",
    "5582": "CEB9",
    "5583": "E0AB",
    "5584": "C9C6",
    "5587": "C0AE",
    "5588": "E0AE",
    "5589": "BAED",
    "558A": "BAB0",
    "558B": "E0A9",
    "558F": "DFF6",
    "5591": "E0B3",
    "5594": "E0B8",
    "5598": "B4AD",
    "5599": "E0B9",
    "559C": "CFB2",
    "559D": "BAC8",
    "559F": "E0B0",
    "55A7": "D0FA",
    "55B1": "E0AC",
    "55B3": "D4FB",
    "55B5": "DFF7",
    "55B7": "C5E7",
    "55B9": "E0AD",
    "55BB": "D3F7",
    "55BD": "E0B6",
    "55BE": "E0B7",
    "55C4": "E0C4",
    "55C5": "D0E1",
    "55C9": "E0BC",
    "55CC": "E0C9",
    "55CD": "E0CA",
    "55D1": "E0BE",
    "55D2": "E0AA",
    "55D3": "C9A4",
    "55D4": "E0C1",
    "55D6": "E0B2",
    "55DC": "CAC8",
    "55DD": "E0C3",
    "55DF": "E0B5",
    "55E1": "CECB",
    "55E3": "CBC3",
    "55E4": "E0CD",
    "55E5": "E0C6",
    "55E6": "E0C2",
    "55E8": "E0CB",
    "55EA": "E0BA",
    "55EB": "E0BF",
    "55EC": "E0C0",
    "55EF": "E0C5",
    "55F2": "E0C7",
    "55F3": "E0C8",
    "55F5": "E0CC",
    "55F7": "E0BB",
    "55FD": "CBD4",
    "55FE": "E0D5",
    "5600": "E0D6",
    "5601": "E0D2",
    "5608": "E0D0",
    "5609": "BCCE",
    "560C": "E0D1",
    "560E": "B8C2",
    "560F": "D8C5",
    "5618": "D0EA",
    "561B": "C2EF",
    "561E": "E0CF",
    "561F": "E0BD",
    "5623": "E0D4",
    "5624": "E0D3",
    "5627": "E0D7",
    "562C": "E0DC",
    "562D": "E0D8",
    "5631": "D6F6",
    "5632": "B3B0",
    "5634": "D7EC",
    "5636": "CBBB",
    "5639": "E0DA",
    "563B": "CEFB",
    "563F": "BAD9",
    "564C": "E0E1",
    "564D": "E0DD",
    "564E": "D2AD",
    "5654": "E0E2",
    "5657": "E0DB",
    "5658": "E0D9",
    "5659": "E0DF",
    "565C": "E0E0",
    "5662": "E0DE",
    "5664": "E0E4",
    "5668": "C6F7",
    "5669": "D8AC",
    "566A": "D4EB",
    "566B": "E0E6",
    "566C": "CAC9",
    "5671": "E0E5",
    "5676": "B8C1",
    "567B": "E0E7",
    "567C": "E0E8",
    "5685": "E0E9",
    "5686": "E0E3",
    "568E": "BABF",
    "568F": "CCE7",
    "5693": "E0EA",
    "56A3": "CFF9",
    "56AF": "E0EB",
    "56B7": "C8C2",
    "56BC": "BDC0",
    "56CA": "C4D2",
    "56D4": "E0EC",
    "56D7": "E0ED",
    "56DA": "C7F4",
    "56DB": "CBC4",
    "56DD": "E0EE",
    "56DE": "BBD8",
    "56DF": "D8B6",
    "56E0": "D2F2",
    "56E1": "E0EF",
    "56E2": "CDC5",
    "56E4": "B6DA",
    "56EB": "E0F1",
    "56ED": "D4B0",
    "56F0": "C0A7",
    "56F1": "B4D1",
    "56F4": "CEA7",
    "56F5": "E0F0",
    "56F9": "E0F2",
    "56FA": "B9CC",
    "56FD": "B9FA",
    "56FE": "CDBC",
    "56FF": "E0F3",
    "5703": "C6D4",
    "5704": "E0F4",
    "5706": "D4B2",
    "5708": "C8A6",
    "5709": "E0F6",
    "570A": "E0F5",
    "571C": "E0F7",
    "571F": "CDC1",
    "5723": "CAA5",
    "5728": "D4DA",
    "5729": "DBD7",
    "572A": "DBD9",
    "572C": "DBD8",
    "572D": "B9E7",
    "572E": "DBDC",
    "572F": "DBDD",
    "5730": "B5D8",
    "5733": "DBDA",
    "5739": "DBDB",
    "573A": "B3A1",
    "573B": "DBDF",
    "573E": "BBF8",
    "5740": "D6B7",
    "5742": "DBE0",
    "5747": "BEF9",
    "574A": "B7BB",
    "574C": "DBD0",
    "574D": "CCAE",
    "574E": "BFB2",
    "574F": "BBB5",
    "5750": "D7F8",
    "5751": "BFD3",
    "5757": "BFE9",
    "575A": "BCE1",
    "575B": "CCB3",
    "575C": "DBDE",
    "575D": "B0D3",
    "575E": "CEEB",
    "575F": "B7D8",
    "5760": "D7B9",
    "5761": "C6C2",
    "5764": "C0A4",
    "5766": "CCB9",
    "5768": "DBE7",
    "5769": "DBE1",
    "576A": "C6BA",
    "576B": "DBE3",
    "576D": "DBE8",
    "576F": "C5F7",
    "5773": "DBEA",
    "5776": "DBE9",
    "5777": "BFC0",
    "577B": "DBE6",
    "577C": "DBE5",
    "5782": "B4B9",
    "5783": "C0AC",
    "5784": "C2A2",
    "5785": "DBE2",
    "5786": "DBE4",
    "578B": "D0CD",
    "578C": "DBED",
    "5792": "C0DD",
    "5793": "DBF2",
    "579B": "B6E2",
    "57A0": "DBF3",
    "57A1": "DBD2",
    "57A2": "B9B8",
    "57A3": "D4AB",
    "57A4": "DBEC",
    "57A6": "BFD1",
    "57A7": "DBF0",
    "57A9": "DBD1",
    "57AB": "B5E6",
    "57AD": "DBEB",
    "57AE": "BFE5",
    "57B2": "DBEE",
    "57B4": "DBF1",
    "57B8": "DBF9",
    "57C2": "B9A1",
    "57C3": "B0A3",
    "57CB": "C2F1",
    "57CE": "B3C7",
    "57CF": "DBEF",
    "57D2": "DBF8",
    "57D4": "C6D2",
    "57D5": "DBF4",
    "57D8": "DBF5",
    "57D9": "DBF7",
    "57DA": "DBF6",
    "57DD": "DBFE",
    "57DF": "D3F2",
    "57E0": "B2BA",
    "57E4": "DBFD",
    "57ED": "DCA4",
    "57EF": "DBFB",
    "57F4": "DBFA",
    "57F8": "DBFC",
    "57F9": "C5E0",
    "57FA": "BBF9",
    "57FD": "DCA3",
    "5800": "DCA5",
    "5802": "CCC3",
    "5806": "B6D1",
    "5807": "DDC0",
    "580B": "DCA1",
    "580D": "DCA2",
    "5811": "C7B5",
    "5815": "B6E9",
    "5819": "DCA7",
    "581E": "DCA6",
    "5820": "DCA9",
    "5821": "B1A4",
    "5824": "B5CC",
    "582A": "BFB0",
    "5830": "D1DF",
    "5835": "B6C2",
    "5844": "DCA8",
    "584C": "CBFA",
    "584D": "EBF3",
    "5851": "CBDC",
    "5854": "CBFE",
    "5858": "CCC1",
    "585E": "C8FB",
    "5865": "DCAA",
    "586B": "CCEE",
    "586C": "DCAB",
    "587E": "DBD3",
    "5880": "DCAF",
    "5881": "DCAC",
    "5883": "BEB3",
    "5885": "CAFB",
    "5889": "DCAD",
    "5892": "C9CA",
    "5893": "C4B9",
    "5899": "C7BD",
    "589A": "DCAE",
    "589E": "D4F6",
    "589F": "D0E6",
    "58A8": "C4AB",
    "58A9": "B6D5",
    "58BC": "DBD4",
    "58C1": "B1DA",
    "58C5": "DBD5",
    "58D1": "DBD6",
    "58D5": "BABE",
    "58E4": "C8C0",
    "58EB": "CABF",
    "58EC": "C8C9",
    "58EE": "D7B3",
    "58F0": "C9F9",
    "58F3": "BFC7",
    "58F6": "BAF8",
    "58F9": "D2BC",
    "5902": "E2BA",
    "5904": "B4A6",
    "5907": "B1B8",
    "590D": "B8B4",
    "590F": "CFC4",
    "5914": "D9E7",
    "5915": "CFA6",
    "5916": "CDE2",
    "5919": "D9ED",
    "591A": "B6E0",
    "591C": "D2B9",
    "591F": "B9BB",
    "5924": "E2B9",
    "5925": "E2B7",
    "5927": "B4F3",
    "5929": "CCEC",
    "592A": "CCAB",
    "592B": "B7F2",
    "592D": "D8B2",
    "592E": "D1EB",
    "592F": "BABB",
    "5931": "CAA7",
    "5934": "CDB7",
    "5937": "D2C4",
    "5938": "BFE4",
    "5939": "BCD0",
    "593A": "B6E1",
    "593C": "DEC5",
    "5941": "DEC6",
    "5942": "DBBC",
    "5944": "D1D9",
    "5947": "C6E6",
    "5948": "C4CE",
    "5949": "B7EE",
    "594B": "B7DC",
    "594E": "BFFC",
    "594F": "D7E0",
    "5951": "C6F5",
    "5954": "B1BC",
    "5955": "DEC8",
    "5956": "BDB1",
    "5957": "CCD7",
    "5958": "DECA",
    "595A": "DEC9",
    "5960": "B5EC",
    "5962": "C9DD",
    "5965": "B0C2",
    "5973": "C5AE",
    "5974": "C5AB",
    "5976": "C4CC",
    "5978": "BCE9",
    "5979": "CBFD",
    "597D": "BAC3",
    "5981": "E5F9",
    "5982": "C8E7",
    "5983": "E5FA",
    "5984": "CDFD",
    "5986": "D7B1",
    "5987": "B8BE",
    "5988": "C2E8",
    "598A": "C8D1",
    "598D": "E5FB",
    "5992": "B6CA",
    "5993": "BCCB",
    "5996": "D1FD",
    "5997": "E6A1",
    "5999": "C3EE",
    "599E": "E6A4",
    "59A3": "E5FE",
    "59A4": "E6A5",
    "59A5": "CDD7",
    "59A8": "B7C1",
    "59A9": "E5FC",
    "59AA": "E5FD",
    "59AB": "E6A3",
    "59AE": "C4DD",
    "59AF": "E6A8",
    "59B2": "E6A7",
    "59B9": "C3C3",
    "59BB": "C6DE",
    "59BE": "E6AA",
    "59C6": "C4B7",
    "59CA": "E6A2",
    "59CB": "CABC",
    "59D0": "BDE3",
    "59D1": "B9C3",
    "59D2": "E6A6",
    "59D3": "D0D5",
    "59D4": "CEAF",
    "59D7": "E6A9",
    "59D8": "E6B0",
    "59DA": "D2A6",
    "59DC": "BDAA",
    "59DD": "E6AD",
    "59E3": "E6AF",
    "59E5": "C0D1",
    "59E8": "D2CC",
    "59EC": "BCA7",
    "59F9": "E6B1",
    "59FB": "D2F6",
    "59FF": "D7CB",
    "5A01": "CDFE",
    "5A03": "CDDE",
    "5A04": "C2A6",
    "5A05": "E6AB",
    "5A06": "E6AC",
    "5A07": "BDBF",
    "5A08": "E6AE",
    "5A09": "E6B3",
    "5A0C": "E6B2",
    "5A11": "E6B6",
    "5A13": "E6B8",
    "5A18": "C4EF",
    "5A1C": "C4C8",
    "5A1F": "BEEA",
    "5A20": "C9EF",
    "5A23": "E6B7",
    "5A25": "B6F0",
    "5A29": "C3E4",
    "5A31": "D3E9",
    "5A32": "E6B4",
    "5A34": "E6B5",
    "5A36": "C8A2",
    "5A3C": "E6BD",
    "5A40": "E6B9",
    "5A46": "C6C5",
    "5A49": "CDF1",
    "5A4A": "E6BB",
    "5A55": "E6BC",
    "5A5A": "BBE9",
    "5A62": "E6BE",
    "5A67": "E6BA",
    "5A6A": "C0B7",
    "5A74": "D3A4",
    "5A75": "E6BF",
    "5A76": "C9F4",
    "5A77": "E6C3",
    "5A7A": "E6C4",
    "5A7F": "D0F6",
    "5A92": "C3BD",
    "5A9A": "C3C4",
    "5A9B": "E6C2",
    "5AAA": "E6C1",
    "5AB2": "E6C7",
    "5AB3": "CFB1",
    "5AB5": "EBF4",
    "5AB8": "E6CA",
    "5ABE": "E6C5",
    "5AC1": "BCDE",
    "5AC2": "C9A9",
    "5AC9": "BCB5",
    "5ACC": "CFD3",
    "5AD2": "E6C8",
    "5AD4": "E6C9",
    "5AD6": "E6CE",
    "5AD8": "E6D0",
    "5ADC": "E6D1",
    "5AE0": "E6CB",
    "5AE1": "B5D5",
    "5AE3": "E6CC",
    "5AE6": "E6CF",
    "5AE9": "C4DB",
    "5AEB": "E6C6",
    "5AF1": "E6CD",
    "5B09": "E6D2",
    "5B16": "E6D4",
    "5B17": "E6D3",
    "5B32": "E6D5",
    "5B34": "D9F8",
    "5B37": "E6D6",
    "5B40": "E6D7",
    "5B50": "D7D3",
    "5B51": "E6DD",
    "5B53": "E6DE",
    "5B54": "BFD7",
    "5B55": "D4D0",
    "5B57": "D7D6",
    "5B58": "B4E6",
    "5B59": "CBEF",
    "5B5A": "E6DA",
    "5B5B": "D8C3",
    "5B5C": "D7CE",
    "5B5D": "D0A2",
    "5B5F": "C3CF",
    "5B62": "E6DF",
    "5B63": "BCBE",
    "5B64": "B9C2",
    "5B65": "E6DB",
    "5B66": "D1A7",
    "5B69": "BAA2",
    "5B6A": "C2CF",
    "5B6C": "D8AB",
    "5B70": "CAEB",
    "5B71": "E5EE",
    "5B73": "E6DC",
    "5B75": "B7F5",
    "5B7A": "C8E6",
    "5B7D": "C4F5",
    "5B80": "E5B2",
    "5B81": "C4FE",
    "5B83": "CBFC",
    "5B84": "E5B3",
    "5B85": "D5AC",
    "5B87": "D3EE",
    "5B88": "CAD8",
    "5B89": "B0B2",
    "5B8B": "CBCE",
    "5B8C": "CDEA",
    "5B8F": "BAEA",
    "5B93": "E5B5",
    "5B95": "E5B4",
    "5B97": "D7DA",
    "5B98": "B9D9",
    "5B99": "D6E6",
    "5B9A": "B6A8",
    "5B9B": "CDF0",
    "5B9C": "D2CB",
    "5B9D": "B1A6",
    "5B9E": "CAB5",
    "5BA0": "B3E8",
    "5BA1": "C9F3",
    "5BA2": "BFCD",
    "5BA3": "D0FB",
    "5BA4": "CAD2",
    "5BA5": "E5B6",
    "5BA6": "BBC2",
    "5BAA": "CFDC",
    "5BAB": "B9AC",
    "5BB0": "D4D7",
    "5BB3": "BAA6",
    "5BB4": "D1E7",
    "5BB5": "CFFC",
    "5BB6": "BCD2",
    "5BB8": "E5B7",
    "5BB9": "C8DD",
    "5BBD": "BFED",
    "5BBE": "B1F6",
    "5BBF": "CBDE",
    "5BC2": "BCC5",
    "5BC4": "BCC4",
    "5BC5": "D2FA",
    "5BC6": "C3DC",
    "5BC7": "BFDC",
    "5BCC": "B8BB",
    "5BD0": "C3C2",
    "5BD2": "BAAE",
    "5BD3": "D4A2",
    "5BDD": "C7DE",
    "5BDE": "C4AF",
    "5BDF": "B2EC",
    "5BE1": "B9D1",
    "5BE4": "E5BB",
    "5BE5": "C1C8",
    "5BE8": "D5AF",
    "5BEE": "E5BC",
    "5BF0": "E5BE",
    "5BF8": "B4E7",
    "5BF9": "B6D4",
    "5BFA": "CBC2",
    "5BFB": "D1B0",
    "5BFC": "B5BC",
    "5BFF": "CAD9",
    "5C01": "B7E2",
    "5C04": "C9E4",
    "5C06": "BDAB",
    "5C09": "CEBE",
    "5C0A": "D7F0",
    "5C0F": "D0A1",
    "5C11": "C9D9",
    "5C14": "B6FB",
    "5C15": "E6D8",
    "5C16": "BCE2",
    "5C18": "B3BE",
    "5C1A": "C9D0",
    "5C1C": "E6D9",
    "5C1D": "B3A2",
    "5C22": "DECC",
    "5C24": "D3C8",
    "5C25": "DECD",
    "5C27": "D2A2",
    "5C2C": "DECE",
    "5C31": "BECD",
    "5C34": "DECF",
    "5C38": "CAAC",
    "5C39": "D2FC",
    "5C3A": "B3DF",
    "5C3B": "E5EA",
    "5C3C": "C4E1",
    "5C3D": "BEA1",
    "5C3E": "CEB2",
    "5C3F": "C4F2",
    "5C40": "BED6",
    "5C41": "C6A8",
    "5C42": "B2E3",
    "5C45": "BED3",
    "5C48": "C7FC",
    "5C49": "CCEB",
    "5C4A": "BDEC",
    "5C4B": "CEDD",
    "5C4E": "CABA",
    "5C4F": "C6C1",
    "5C50": "E5EC",
    "5C51": "D0BC",
    "5C55": "D5B9",
    "5C59": "E5ED",
    "5C5E": "CAF4",
    "5C60": "CDC0",
    "5C61": "C2C5",
    "5C63": "E5EF",
    "5C65": "C2C4",
    "5C66": "E5F0",
    "5C6E": "E5F8",
    "5C6F": "CDCD",
    "5C71": "C9BD",
    "5C79": "D2D9",
    "5C7A": "E1A8",
    "5C7F": "D3EC",
    "5C81": "CBEA",
    "5C82": "C6F1",
    "5C88": "E1AC",
    "5C8C": "E1A7",
    "5C8D": "E1A9",
    "5C90": "E1AA",
    "5C91": "E1AF",
    "5C94": "B2ED",
    "5C96": "E1AB",
    "5C97": "B8DA",
    "5C98": "E1AD",
    "5C99": "E1AE",
    "5C9A": "E1B0",
    "5C9B": "B5BA",
    "5C9C": "E1B1",
    "5CA2": "E1B3",
    "5CA3": "E1B8",
    "5CA9": "D1D2",
    "5CAB": "E1B6",
    "5CAC": "E1B5",
    "5CAD": "C1EB",
    "5CB1": "E1B7",
    "5CB3": "D4C0",
    "5CB5": "E1B2",
    "5CB7": "E1BA",
    "5CB8": "B0B6",
    "5CBD": "E1B4",
    "5CBF": "BFF9",
    "5CC1": "E1B9",
    "5CC4": "E1BB",
    "5CCB": "E1BE",
    "5CD2": "E1BC",
    "5CD9": "D6C5",
    "5CE1": "CFBF",
    "5CE4": "E1BD",
    "5CE5": "E1BF",
    "5CE6": "C2CD",
    "5CE8": "B6EB",
    "5CEA": "D3F8",
    "5CED": "C7CD",
    "5CF0": "B7E5",
    "5CFB": "BEFE",
    "5D02": "E1C0",
    "5D03": "E1C1",
    "5D06": "E1C7",
    "5D07": "B3E7",
    "5D0E": "C6E9",
    "5D14": "B4DE",
    "5D16": "D1C2",
    "5D1B": "E1C8",
    "5D1E": "E1C6",
    "5D24": "E1C5",
    "5D26": "E1C3",
    "5D27": "E1C2",
    "5D29": "B1C0",
    "5D2D": "D5B8",
    "5D2E": "E1C4",
    "5D34": "E1CB",
    "5D3D": "E1CC",
    "5D3E": "E1CA",
    "5D47": "EFFA",
    "5D4A": "E1D3",
    "5D4B": "E1D2",
    "5D4C": "C7B6",
    "5D58": "E1C9",
    "5D5B": "E1CE",
    "5D5D": "E1D0",
    "5D69": "E1D4",
    "5D6B": "E1D1",
    "5D6C": "E1CD",
    "5D6F": "E1CF",
    "5D74": "E1D5",
    "5D82": "E1D6",
    "5D99": "E1D7",
    "5D9D": "E1D8",
    "5DB7": "E1DA",
    "5DC5": "E1DB",
    "5DCD": "CEA1",
    "5DDB": "E7DD",
    "5DDD": "B4A8",
    "5DDE": "D6DD",
    "5DE1": "D1B2",
    "5DE2": "B3B2",
    "5DE5": "B9A4",
    "5DE6": "D7F3",
    "5DE7": "C7C9",
    "5DE8": "BEDE",
    "5DE9": "B9AE",
    "5DEB": "CED7",
    "5DEE": "B2EE",
    "5DEF": "DBCF",
    "5DF1": "BCBA",
    "5DF2": "D2D1",
    "5DF3": "CBC8",
    "5DF4": "B0CD",
    "5DF7": "CFEF",
    "5DFD": "D9E3",
    "5DFE": "BDED",
    "5E01": "B1D2",
    "5E02": "CAD0",
    "5E03": "B2BC",
    "5E05": "CBA7",
    "5E06": "B7AB",
    "5E08": "CAA6",
    "5E0C": "CFA3",
    "5E0F": "E0F8",
    "5E10": "D5CA",
    "5E11": "E0FB",
    "5E14": "E0FA",
    "5E15": "C5C1",
    "5E16": "CCFB",
    "5E18": "C1B1",
    "5E19": "E0F9",
    "5E1A": "D6E3",
    "5E1B": "B2AF",
    "5E1C": "D6C4",
    "5E1D": "B5DB",
    "5E26": "B4F8",
    "5E27": "D6A1",
    "5E2D": "CFAF",
    "5E2E": "B0EF",
    "5E31": "E0FC",
    "5E37": "E1A1",
    "5E38": "B3A3",
    "5E3B": "E0FD",
    "5E3C": "E0FE",
    "5E3D": "C3B1",
    "5E42": "C3DD",
    "5E44": "E1A2",
    "5E45": "B7F9",
    "5E4C": "BBCF",
    "5E54": "E1A3",
    "5E55": "C4BB",
    "5E5B": "E1A4",
    "5E5E": "E1A5",
    "5E61": "E1A6",
    "5E62": "B4B1",
    "5E72": "B8C9",
    "5E73": "C6BD",
    "5E74": "C4EA",
    "5E76": "B2A2",
    "5E78": "D0D2",
    "5E7A": "E7DB",
    "5E7B": "BBC3",
    "5E7C": "D3D7",
    "5E7D": "D3C4",
    "5E7F": "B9E3",
    "5E80": "E2CF",
    "5E84": "D7AF",
    "5E86": "C7EC",
    "5E87": "B1D3",
    "5E8A": "B4B2",
    "5E8B": "E2D1",
    "5E8F": "D0F2",
    "5E90": "C2AE",
    "5E91": "E2D0",
    "5E93": "BFE2",
    "5E94": "D3A6",
    "5E95": "B5D7",
    "5E96": "E2D2",
    "5E97": "B5EA",
    "5E99": "C3ED",
    "5E9A": "B8FD",
    "5E9C": "B8AE",
    "5E9E": "C5D3",
    "5E9F": "B7CF",
    "5EA0": "E2D4",
    "5EA5": "E2D3",
    "5EA6": "B6C8",
    "5EA7": "D7F9",
    "5EAD": "CDA5",
    "5EB3": "E2D8",
    "5EB5": "E2D6",
    "5EB6": "CAFC",
    "5EB7": "BFB5",
    "5EB8": "D3B9",
    "5EB9": "E2D5",
    "5EBE": "E2D7",
    "5EC9": "C1AE",
    "5ECA": "C0C8",
    "5ED1": "E2DB",
    "5ED2": "E2DA",
    "5ED3": "C0AA",
    "5ED6": "C1CE",
    "5EDB": "E2DC",
    "5EE8": "E2DD",
    "5EEA": "E2DE",
    "5EF4": "DBC8",
    "5EF6": "D1D3",
    "5EF7": "CDA2",
    "5EFA": "BDA8",
    "5EFE": "DEC3",
    "5EFF": "D8A5",
    "5F00": "BFAA",
    "5F01": "DBCD",
    "5F02": "D2EC",
    "5F03": "C6FA",
    "5F04": "C5AA",
    "5F08": "DEC4",
    "5F0A": "B1D7",
    "5F0B": "DFAE",
    "5F0F": "CABD",
    "5F11": "DFB1",
    "5F13": "B9AD",
    "5F15": "D2FD",
    "5F17": "B8A5",
    "5F18": "BAEB",
    "5F1B": "B3DA",
    "5F1F": "B5DC",
    "5F20": "D5C5",
    "5F25": "C3D6",
    "5F26": "CFD2",
    "5F27": "BBA1",
    "5F29": "E5F3",
    "5F2A": "E5F2",
    "5F2D": "E5F4",
    "5F2F": "CDE4",
    "5F31": "C8F5",
    "5F39": "B5AF",
    "5F3A": "C7BF",
    "5F3C": "E5F6",
    "5F40": "ECB0",
    "5F50": "E5E6",
    "5F52": "B9E9",
    "5F53": "B5B1",
    "5F55": "C2BC",
    "5F56": "E5E8",
    "5F57": "E5E7",
    "5F58": "E5E9",
    "5F5D": "D2CD",
    "5F61": "E1EA",
    "5F62": "D0CE",
    "5F64": "CDAE",
    "5F66": "D1E5",
    "5F69": "B2CA",
    "5F6A": "B1EB",
    "5F6C": "B1F2",
    "5F6D": "C5ED",
    "5F70": "D5C3",
    "5F71": "D3B0",
    "5F73": "E1DC",
    "5F77": "E1DD",
    "5F79": "D2DB",
    "5F7B": "B3B9",
    "5F7C": "B1CB",
    "5F80": "CDF9",
    "5F81": "D5F7",
    "5F82": "E1DE",
    "5F84": "BEB6",
    "5F85": "B4FD",
    "5F87": "E1DF",
    "5F88": "BADC",
    "5F89": "E1E0",
    "5F8A": "BBB2",
    "5F8B": "C2C9",
    "5F8C": "E1E1",
    "5F90": "D0EC",
    "5F92": "CDBD",
    "5F95": "E1E2",
    "5F97": "B5C3",
    "5F98": "C5C7",
    "5F99": "E1E3",
    "5F9C": "E1E4",
    "5FA1": "D3F9",
    "5FA8": "E1E5",
    "5FAA": "D1AD",
    "5FAD": "E1E6",
    "5FAE": "CEA2",
    "5FB5": "E1E7",
    "5FB7": "B5C2",
    "5FBC": "E1E8",
    "5FBD": "BBD5",
    "5FC3": "D0C4",
    "5FC4": "E2E0",
    "5FC5": "B1D8",
    "5FC6": "D2E4",
    "5FC9": "E2E1",
    "5FCC": "BCC9",
    "5FCD": "C8CC",
    "5FCF": "E2E3",
    "5FD0": "ECFE",
    "5FD1": "ECFD",
    "5FD2": "DFAF",
    "5FD6": "E2E2",
    "5FD7": "D6BE",
    "5FD8": "CDFC",
    "5FD9": "C3A6",
    "5FDD": "E3C3",
    "5FE0": "D6D2",
    "5FE1": "E2E7",
    "5FE4": "E2E8",
    "5FE7": "D3C7",
    "5FEA": "E2EC",
    "5FEB": "BFEC",
    "5FED": "E2ED",
    "5FEE": "E2E5",
    "5FF1": "B3C0",
    "5FF5": "C4EE",
    "5FF8": "E2EE",
    "5FFB": "D0C3",
    "5FFD": "BAF6",
    "5FFE": "E2E9",
    "5FFF": "B7DE",
    "6000": "BBB3",
    "6001": "CCAC",
    "6002": "CBCB",
    "6003": "E2E4",
    "6004": "E2E6",
    "6005": "E2EA",
    "6006": "E2EB",
    "600A": "E2F7",
    "600D": "E2F4",
    "600E": "D4F5",
    "600F": "E2F3",
    "6012": "C5AD",
    "6014": "D5FA",
    "6015": "C5C2",
    "6016": "B2C0",
    "6019": "E2EF",
    "601B": "E2F2",
    "601C": "C1AF",
    "601D": "CBBC",
    "6020": "B5A1",
    "6021": "E2F9",
    "6025": "BCB1",
    "6026": "E2F1",
    "6027": "D0D4",
    "6028": "D4B9",
    "6029": "E2F5",
    "602A": "B9D6",
    "602B": "E2F6",
    "602F": "C7D3",
    "6035": "E2F0",
    "603B": "D7DC",
    "603C": "EDA1",
    "603F": "E2F8",
    "6041": "EDA5",
    "6042": "E2FE",
    "6043": "CAD1",
    "604B": "C1B5",
    "604D": "BBD0",
    "6050": "BFD6",
    "6052": "BAE3",
    "6055": "CBA1",
    "6059": "EDA6",
    "605A": "EDA3",
    "605D": "EDA2",
    "6062": "BBD6",
    "6063": "EDA7",
    "6064": "D0F4",
    "6067": "EDA4",
    "6068": "BADE",
    "6069": "B6F7",
    "606A": "E3A1",
    "606B": "B6B2",
    "606C": "CCF1",
    "606D": "B9A7",
    "606F": "CFA2",
    "6070": "C7A1",
    "6073": "BFD2",
    "6076": "B6F1",
    "6078": "E2FA",
    "6079": "E2FB",
    "607A": "E2FD",
    "607B": "E2FC",
    "607C": "C4D5",
    "607D": "E3A2",
    "607F": "D3C1",
    "6083": "E3A7",
    "6084": "C7C4",
    "6089": "CFA4",
    "608C": "E3A9",
    "608D": "BAB7",
    "6092": "E3A8",
    "6094": "BBDA",
    "6096": "E3A3",
    "609A": "E3A4",
    "609B": "E3AA",
    "609D": "E3A6",
    "609F": "CEF2",
    "60A0": "D3C6",
    "60A3": "BBBC",
    "60A6": "D4C3",
    "60A8": "C4FA",
    "60AB": "EDA8",
    "60AC": "D0FC",
    "60AD": "E3A5",
    "60AF": "C3F5",
    "60B1": "E3AD",
    "60B2": "B1AF",
    "60B4": "E3B2",
    "60B8": "BCC2",
    "60BB": "E3AC",
    "60BC": "B5BF",
    "60C5": "C7E9",
    "60C6": "E3B0",
    "60CA": "BEAA",
    "60CB": "CDEF",
    "60D1": "BBF3",
    "60D5": "CCE8",
    "60D8": "E3AF",
    "60DA": "E3B1",
    "60DC": "CFA7",
    "60DD": "E3AE",
    "60DF": "CEA9",
    "60E0": "BBDD",
    "60E6": "B5EB",
    "60E7": "BEE5",
    "60E8": "B2D2",
    "60E9": "B3CD",
    "60EB": "B1B9",
    "60EC": "E3AB",
    "60ED": "B2D1",
    "60EE": "B5AC",
    "60EF": "B9DF",
    "60F0": "B6E8",
    "60F3": "CFEB",
    "60F4": "E3B7",
    "60F6": "BBCC",
    "60F9": "C8C7",
    "60FA": "D0CA",
    "6100": "E3B8",
    "6101": "B3EE",
    "6106": "EDA9",
    "6108": "D3FA",
    "6109": "D3E4",
    "610D": "EDAA",
    "610E": "E3B9",
    "610F": "D2E2",
    "6115": "E3B5",
    "611A": "D3DE",
    "611F": "B8D0",
    "6120": "E3B3",
    "6123": "E3B6",
    "6124": "B7DF",
    "6126": "E3B4",
    "6127": "C0A2",
    "612B": "E3BA",
    "613F": "D4B8",
    "6148": "B4C8",
    "614A": "E3BB",
    "614C": "BBC5",
    "614E": "C9F7",
    "6151": "C9E5",
    "6155": "C4BD",
    "615D": "EDAB",
    "6162": "C2FD",
    "6167": "BBDB",
    "6168": "BFAE",
    "6170": "CEBF",
    "6175": "E3BC",
    "6177": "BFB6",
    "618B": "B1EF",
    "618E": "D4F7",
    "6194": "E3BE",
    "619D": "EDAD",
    "61A7": "E3BF",
    "61A8": "BAA9",
    "61A9": "EDAC",
    "61AC": "E3BD",
    "61B7": "E3C0",
    "61BE": "BAB6",
    "61C2": "B6AE",
    "61C8": "D0B8",
    "61CA": "B0C3",
    "61CB": "EDAE",
    "61D1": "EDAF",
    "61D2": "C0C1",
    "61D4": "E3C1",
    "61E6": "C5B3",
    "61F5": "E3C2",
    "61FF": "DCB2",
    "6206": "EDB0",
    "6208": "B8EA",
    "620A": "CEEC",
    "620B": "EAA7",
    "620C": "D0E7",
    "620D": "CAF9",
    "620E": "C8D6",
    "620F": "CFB7",
    "6210": "B3C9",
    "6211": "CED2",
    "6212": "BDE4",
    "6215": "E3DE",
    "6216": "BBF2",
    "6217": "EAA8",
    "6218": "D5BD",
    "621A": "C6DD",
    "621B": "EAA9",
    "621F": "EAAA",
    "6221": "EAAC",
    "6222": "EAAB",
    "6224": "EAAE",
    "6225": "EAAD",
    "622A": "BDD8",
    "622C": "EAAF",
    "622E": "C2BE",
    "6233": "B4C1",
    "6234": "B4F7",
    "6237": "BBA7",
    "623D": "ECE6",
    "623E": "ECE5",
    "623F": "B7BF",
    "6240": "CBF9",
    "6241": "B1E2",
    "6243": "ECE7",
    "6247": "C9C8",
    "6248": "ECE8",
    "6249": "ECE9",
    "624B": "CAD6",
    "624C": "DED0",
    "624D": "B2C5",
    "624E": "D4FA",
    "6251": "C6CB",
    "6252": "B0C7",
    "6253": "B4F2",
    "6254": "C8D3",
    "6258": "CDD0",
    "625B": "BFB8",
    "6263": "BFDB",
    "6266": "C7A4",
    "6267": "D6B4",
    "6269": "C0A9",
    "626A": "DED1",
    "626B": "C9A8",
    "626C": "D1EF",
    "626D": "C5A4",
    "626E": "B0E7",
    "626F": "B3B6",
    "6270": "C8C5",
    "6273": "B0E2",
    "6276": "B7F6",
    "6279": "C5FA",
    "627C": "B6F3",
    "627E": "D5D2",
    "627F": "B3D0",
    "6280": "BCBC",
    "6284": "B3AD",
    "6289": "BEF1",
    "628A": "B0D1",
    "6291": "D2D6",
    "6292": "CAE3",
    "6293": "D7A5",
    "6295": "CDB6",
    "6296": "B6B6",
    "6297": "BFB9",
    "6298": "D5DB",
    "629A": "B8A7",
    "629B": "C5D7",
    "629F": "DED2",
    "62A0": "BFD9",
    "62A1": "C2D5",
    "62A2": "C7C0",
    "62A4": "BBA4",
    "62A5": "B1A8",
    "62A8": "C5EA",
    "62AB": "C5FB",
    "62AC": "CCA7",
    "62B1": "B1A7",
    "62B5": "B5D6",
    "62B9": "C4A8",
    "62BB": "DED3",
    "62BC": "D1BA",
    "62BD": "B3E9",
    "62BF": "C3F2",
    "62C2": "B7F7",
    "62C4": "D6F4",
    "62C5": "B5A3",
    "62C6": "B2F0",
    "62C7": "C4B4",
    "62C8": "C4E9",
    "62C9": "C0AD",
    "62CA": "DED4",
    "62CC": "B0E8",
    "62CD": "C5C4",
    "62CE": "C1E0",
    "62D0": "B9D5",
    "62D2": "BEDC",
    "62D3": "CDD8",
    "62D4": "B0CE",
    "62D6": "CDCF",
    "62D7": "DED6",
    "62D8": "BED0",
    "62D9": "D7BE",
    "62DA": "DED5",
    "62DB": "D5D0",
    "62DC": "B0DD",
    "62DF": "C4E2",
    "62E2": "C2A3",
    "62E3": "BCF0",
    "62E5": "D3B5",
    "62E6": "C0B9",
    "62E7": "C5A1",
    "62E8": "B2A6",
    "62E9": "D4F1",
    "62EC": "C0A8",
    "62ED": "CAC3",
    "62EE": "DED7",
    "62EF": "D5FC",
    "62F1": "B9B0",
    "62F3": "C8AD",
    "62F4": "CBA9",
    "62F6": "DED9",
    "62F7": "BFBD",
    "62FC": "C6B4",
    "62FD": "D7A7",
    "62FE": "CAB0",
    "62FF": "C4C3",
    "6301": "B3D6",
    "6302": "B9D2",
    "6307": "D6B8",
    "6308": "EAFC",
    "6309": "B0B4",
    "630E": "BFE6",
    "6311": "CCF4",
    "6316": "CDDA",
    "631A": "D6BF",
    "631B": "C2CE",
    "631D": "CECE",
    "631E": "CCA2",
    "631F": "D0AE",
    "6320": "C4D3",
    "6321": "B5B2",
    "6322": "DED8",
    "6323": "D5F5",
    "6324": "BCB7",
    "6325": "BBD3",
    "6328": "B0A4",
    "632A": "C5B2",
    "632B": "B4EC",
    "632F": "D5F1",
    "6332": "EAFD",
    "6339": "DEDA",
    "633A": "CDA6",
    "633D": "CDEC",
    "6342": "CEE6",
    "6343": "DEDC",
    "6345": "CDB1",
    "6346": "C0A6",
    "6349": "D7BD",
    "634B": "DEDB",
    "634C": "B0C6",
    "634D": "BAB4",
    "634E": "C9D3",
    "634F": "C4F3",
    "6350": "BEE8",
    "6355": "B2B6",
    "635E": "C0CC",
    "635F": "CBF0",
    "6361": "BCF1",
    "6362": "BBBB",
    "6363": "B5B7",
    "6367": "C5F5",
    "6369": "DEE6",
    "636D": "DEE3",
    "636E": "BEDD",
    "6371": "DEDF",
    "6376": "B4B7",
    "6377": "BDDD",
    "637A": "DEE0",
    "637B": "C4ED",
    "6380": "CFC6",
    "6382": "B5E0",
    "6387": "B6DE",
    "6388": "CADA",
    "6389": "B5F4",
    "638A": "DEE5",
    "638C": "D5C6",
    "638E": "DEE1",
    "638F": "CCCD",
    "6390": "C6FE",
    "6392": "C5C5",
    "6396": "D2B4",
    "6398": "BEF2",
    "63A0": "C2D3",
    "63A2": "CCBD",
    "63A3": "B3B8",
    "63A5": "BDD3",
    "63A7": "BFD8",
    "63A8": "CDC6",
    "63A9": "D1DA",
    "63AA": "B4EB",
    "63AC": "DEE4",
    "63AD": "DEDD",
    "63AE": "DEE7",
    "63B0": "EAFE",
    "63B3": "C2B0",
    "63B4": "DEE2",
    "63B7": "D6C0",
    "63B8": "B5A7",
    "63BA": "B2F4",
    "63BC": "DEE8",
    "63BE": "DEF2",
    "63C4": "DEED",
    "63C6": "DEF1",
    "63C9": "C8E0",
    "63CD": "D7E1",
    "63CE": "DEEF",
    "63CF": "C3E8",
    "63D0": "CCE1",
    "63D2": "B2E5",
    "63D6": "D2BE",
    "63DE": "DEEE",
    "63E0": "DEEB",
    "63E1": "CED5",
    "63E3": "B4A7",
    "63E9": "BFAB",
    "63EA": "BEBE",
    "63ED": "BDD2",
    "63F2": "DEE9",
    "63F4": "D4AE",
    "63F6": "DEDE",
    "63F8": "DEEA",
    "63FD": "C0BF",
    "63FF": "DEEC",
    "6400": "B2F3",
    "6401": "B8E9",
    "6402": "C2A7",
    "6405": "BDC1",
    "640B": "DEF5",
    "640C": "DEF8",
    "640F": "B2AB",
    "6410": "B4A4",
    "6413": "B4EA",
    "6414": "C9A6",
    "641B": "DEF6",
    "641C": "CBD1",
    "641E": "B8E3",
    "6420": "DEF7",
    "6421": "DEFA",
    "6426": "DEF9",
    "642A": "CCC2",
    "642C": "B0E1",
    "642D": "B4EE",
    "6434": "E5BA",
    "643A": "D0AF",
    "643D": "B2EB",
    "643F": "EBA1",
    "6441": "DEF4",
    "6444": "C9E3",
    "6445": "DEF3",
    "6446": "B0DA",
    "6447": "D2A1",
    "6448": "B1F7",
    "644A": "CCAF",
    "6452": "DEF0",
    "6454": "CBA4",
    "6458": "D5AA",
    "645E": "DEFB",
    "6467": "B4DD",
    "6469": "C4A6",
    "646D": "DEFD",
    "6478": "C3FE",
    "6479": "C4A1",
    "647A": "DFA1",
    "6482": "C1CC",
    "6484": "DEFC",
    "6485": "BEEF",
    "6487": "C6B2",
    "6491": "B3C5",
    "6492": "C8F6",
    "6495": "CBBA",
    "6496": "DEFE",
    "6499": "DFA4",
    "649E": "D7B2",
    "64A4": "B3B7",
    "64A9": "C1C3",
    "64AC": "C7CB",
    "64AD": "B2A5",
    "64AE": "B4E9",
    "64B0": "D7AB",
    "64B5": "C4EC",
    "64B7": "DFA2",
    "64B8": "DFA3",
    "64BA": "DFA5",
    "64BC": "BAB3",
    "64C0": "DFA6",
    "64C2": "C0DE",
    "64C5": "C9C3",
    "64CD": "B2D9",
    "64CE": "C7E6",
    "64D0": "DFA7",
    "64D2": "C7DC",
    "64D7": "DFA8",
    "64D8": "EBA2",
    "64DE": "CBD3",
    "64E2": "DFAA",
    "64E4": "DFA9",
    "64E6": "B2C1",
    "6500": "C5CA",
    "6509": "DFAB",
    "6512": "D4DC",
    "6518": "C8C1",
    "6525": "DFAC",
    "652B": "BEF0",
    "652E": "DFAD",
    "652F": "D6A7",
    "6534": "EAB7",
    "6535": "EBB6",
    "6536": "CAD5",
    "6538": "D8FC",
    "6539": "B8C4",
    "653B": "B9A5",
    "653E": "B7C5",
    "653F": "D5FE",
    "6545": "B9CA",
    "6548": "D0A7",
    "6549": "F4CD",
    "654C": "B5D0",
    "654F": "C3F4",
    "6551": "BEC8",
    "6555": "EBB7",
    "6556": "B0BD",
    "6559": "BDCC",
    "655B": "C1B2",
    "655D": "B1D6",
    "655E": "B3A8",
    "6562": "B8D2",
    "6563": "C9A2",
    "6566": "B6D8",
    "656B": "EBB8",
    "656C": "BEB4",
    "6570": "CAFD",
    "6572": "C7C3",
    "6574": "D5FB",
    "6577": "B7F3",
    "6587": "CEC4",
    "658B": "D5AB",
    "658C": "B1F3",
    "6590": "ECB3",
    "6591": "B0DF",
    "6593": "ECB5",
    "6597": "B6B7",
    "6599": "C1CF",
    "659B": "F5FA",
    "659C": "D0B1",
    "659F": "D5E5",
    "65A1": "CED3",
    "65A4": "BDEF",
    "65A5": "B3E2",
    "65A7": "B8AB",
    "65A9": "D5B6",
    "65AB": "EDBD",
    "65AD": "B6CF",
    "65AF": "CBB9",
    "65B0": "D0C2",
    "65B9": "B7BD",
    "65BC": "ECB6",
    "65BD": "CAA9",
    "65C1": "C5D4",
    "65C3": "ECB9",
    "65C4": "ECB8",
    "65C5": "C2C3",
    "65C6": "ECB7",
    "65CB": "D0FD",
    "65CC": "ECBA",
    "65CE": "ECBB",
    "65CF": "D7E5",
    "65D2": "ECBC",
    "65D6": "ECBD",
    "65D7": "C6EC",
    "65E0": "CEDE",
    "65E2": "BCC8",
    "65E5": "C8D5",
    "65E6": "B5A9",
    "65E7": "BEC9",
    "65E8": "D6BC",
    "65E9": "D4E7",
    "65EC": "D1AE",
    "65ED": "D0F1",
    "65EE": "EAB8",
    "65EF": "EAB9",
    "65F0": "EABA",
    "65F1": "BAB5",
    "65F6": "CAB1",
    "65F7": "BFF5",
    "65FA": "CDFA",
    "6600": "EAC0",
    "6602": "B0BA",
    "6603": "EABE",
    "6606": "C0A5",
    "660A": "EABB",
    "660C": "B2FD",
    "660E": "C3F7",
    "660F": "BBE8",
    "6613": "D2D7",
    "6614": "CEF4",
    "6615": "EABF",
    "6619": "EABC",
    "661D": "EAC3",
    "661F": "D0C7",
    "6620": "D3B3",
    "6625": "B4BA",
    "6627": "C3C1",
    "6628": "D7F2",
    "662D": "D5D1",
    "662F": "CAC7",
    "6631": "EAC5",
    "6634": "EAC4",
    "6635": "EAC7",
    "6636": "EAC6",
    "663C": "D6E7",
    "663E": "CFD4",
    "6641": "EACB",
    "6643": "BBCE",
    "664B": "BDFA",
    "664C": "C9CE",
    "664F": "EACC",
    "6652": "C9B9",
    "6653": "CFFE",
    "6654": "EACA",
    "6655": "D4CE",
    "6656": "EACD",
    "6657": "EACF",
    "665A": "CDED",
    "665F": "EAC9",
    "6661": "EACE",
    "6664": "CEEE",
    "6666": "BBDE",
    "6668": "B3BF",
    "666E": "C6D5",
    "666F": "BEB0",
    "6670": "CEFA",
    "6674": "C7E7",
    "6676": "BEA7",
    "6677": "EAD0",
    "667A": "D6C7",
    "667E": "C1C0",
    "6682": "D4DD",
    "6684": "EAD1",
    "6687": "CFBE",
    "668C": "EAD2",
    "6691": "CAEE",
    "6696": "C5AF",
    "6697": "B0B5",
    "669D": "EAD4",
    "66A7": "EAD3",
    "66A8": "F4DF",
    "66AE": "C4BA",
    "66B4": "B1A9",
    "66B9": "E5DF",
    "66BE": "EAD5",
    "66D9": "CAEF",
    "66DB": "EAD6",
    "66DC": "EAD7",
    "66DD": "C6D8",
    "66E6": "EAD8",
    "66E9": "EAD9",
    "66F0": "D4BB",
    "66F2": "C7FA",
    "66F3": "D2B7",
    "66F4": "B8FC",
    "66F7": "EAC2",
    "66F9": "B2DC",
    "66FC": "C2FC",
    "66FE": "D4F8",
    "66FF": "CCE6",
    "6700": "D7EE",
    "6708": "D4C2",
    "6709": "D3D0",
    "670A": "EBC3",
    "670B": "C5F3",
    "670D": "B7FE",
    "6710": "EBD4",
    "6714": "CBB7",
    "6715": "EBDE",
    "6717": "C0CA",
    "671B": "CDFB",
    "671D": "B3AF",
    "671F": "C6DA",
    "6726": "EBFC",
    "6728": "C4BE",
    "672A": "CEB4",
    "672B": "C4A9",
    "672C": "B1BE",
    "672D": "D4FD",
    "672F": "CAF5",
    "6731": "D6EC",
    "6734": "C6D3",
    "6735": "B6E4",
    "673A": "BBFA",
    "673D": "D0E0",
    "6740": "C9B1",
    "6742": "D4D3",
    "6743": "C8A8",
    "6746": "B8CB",
    "6748": "E8BE",
    "6749": "C9BC",
    "674C": "E8BB",
    "674E": "C0EE",
    "674F": "D0D3",
    "6750": "B2C4",
    "6751": "B4E5",
    "6753": "E8BC",
    "6756": "D5C8",
    "675C": "B6C5",
    "675E": "E8BD",
    "675F": "CAF8",
    "6760": "B8DC",
    "6761": "CCF5",
    "6765": "C0B4",
    "6768": "D1EE",
    "6769": "E8BF",
    "676A": "E8C2",
    "676D": "BABC",
    "676F": "B1AD",
    "6770": "BDDC",
    "6772": "EABD",
    "6773": "E8C3",
    "6775": "E8C6",
    "6777": "E8CB",
    "677C": "E8CC",
    "677E": "CBC9",
    "677F": "B0E5",
    "6781": "BCAB",
    "6784": "B9B9",
    "6787": "E8C1",
    "6789": "CDF7",
    "678B": "E8CA",
    "6790": "CEF6",
    "6795": "D5ED",
    "6797": "C1D6",
    "6798": "E8C4",
    "679A": "C3B6",
    "679C": "B9FB",
    "679D": "D6A6",
    "679E": "E8C8",
    "67A2": "CAE0",
    "67A3": "D4E6",
    "67A5": "E8C0",
    "67A7": "E8C5",
    "67A8": "E8C7",
    "67AA": "C7B9",
    "67AB": "B7E3",
    "67AD": "E8C9",
    "67AF": "BFDD",
    "67B0": "E8D2",
    "67B3": "E8D7",
    "67B5": "E8D5",
    "67B6": "BCDC",
    "67B7": "BCCF",
    "67B8": "E8DB",
    "67C1": "E8DE",
    "67C3": "E8DA",
    "67C4": "B1FA",
    "67CF": "B0D8",
    "67D0": "C4B3",
    "67D1": "B8CC",
    "67D2": "C6E2",
    "67D3": "C8BE",
    "67D4": "C8E1",
    "67D8": "E8CF",
    "67D9": "E8D4",
    "67DA": "E8D6",
    "67DC": "B9F1",
    "67DD": "E8D8",
    "67DE": "D7F5",
    "67E0": "C4FB",
    "67E2": "E8DC",
    "67E5": "B2E9",
    "67E9": "E8D1",
    "67EC": "BCED",
    "67EF": "BFC2",
    "67F0": "E8CD",
    "67F1": "D6F9",
    "67F3": "C1F8",
    "67F4": "B2F1",
    "67FD": "E8DF",
    "67FF": "CAC1",
    "6800": "E8D9",
    "6805": "D5A4",
    "6807": "B1EA",
    "6808": "D5BB",
    "6809": "E8CE",
    "680A": "E8D0",
    "680B": "B6B0",
    "680C": "E8D3",
    "680E": "E8DD",
    "680F": "C0B8",
    "6811": "CAF7",
    "6813": "CBA8",
    "6816": "C6DC",
    "6817": "C0F5",
    "681D": "E8E9",
    "6821": "D0A3",
    "6829": "E8F2",
    "682A": "D6EA",
    "6832": "E8E0",
    "6833": "E8E1",
    "6837": "D1F9",
    "6838": "BACB",
    "6839": "B8F9",
    "683C": "B8F1",
    "683D": "D4D4",
    "683E": "E8EF",
    "6840": "E8EE",
    "6841": "E8EC",
    "6842": "B9F0",
    "6843": "CCD2",
    "6844": "E8E6",
    "6845": "CEA6",
    "6846": "BFF2",
    "6848": "B0B8",
    "6849": "E8F1",
    "684A": "E8F0",
    "684C": "D7C0",
    "684E": "E8E4",
    "6850": "CDA9",
    "6851": "C9A3",
    "6853": "BBB8",
    "6854": "BDDB",
    "6855": "E8EA",
    "6860": "E8E2",
    "6861": "E8E3",
    "6862": "E8E5",
    "6863": "B5B5",
    "6864": "E8E7",
    "6865": "C7C5",
    "6866": "E8EB",
    "6867": "E8ED",
    "6868": "BDB0",
    "6869": "D7AE",
    "686B": "E8F8",
    "6874": "E8F5",
    "6876": "CDB0",
    "6877": "E8F6",
    "6881": "C1BA",
    "6883": "E8E8",
    "6885": "C3B7",
    "6886": "B0F0",
    "688F": "E8F4",
    "6893": "E8F7",
    "6897": "B9A3",
    "68A2": "C9D2",
    "68A6": "C3CE",
    "68A7": "CEE0",
    "68A8": "C0E6",
    "68AD": "CBF3",
    "68AF": "CCDD",
    "68B0": "D0B5",
    "68B3": "CAE1",
    "68B5": "E8F3",
    "68C0": "BCEC",
    "68C2": "E8F9",
    "68C9": "C3DE",
    "68CB": "C6E5",
    "68CD": "B9F7",
    "68D2": "B0F4",
    "68D5": "D7D8",
    "68D8": "BCAC",
    "68DA": "C5EF",
    "68E0": "CCC4",
    "68E3": "E9A6",
    "68EE": "C9AD",
    "68F0": "E9A2",
    "68F1": "C0E2",
    "68F5": "BFC3",
    "68F9": "E8FE",
    "68FA": "B9D7",
    "68FC": "E8FB",
    "6901": "E9A4",
    "6905": "D2CE",
    "690B": "E9A3",
    "690D": "D6B2",
    "690E": "D7B5",
    "6910": "E9A7",
    "6912": "BDB7",
    "691F": "E8FC",
    "6920": "E8FD",
    "6924": "E9A1",
    "692D": "CDD6",
    "6930": "D2AC",
    "6934": "E9B2",
    "6939": "E9A9",
    "693D": "B4AA",
    "693F": "B4BB",
    "6942": "E9AB",
    "6954": "D0A8",
    "6957": "E9A5",
    "695A": "B3FE",
    "695D": "E9AC",
    "695E": "C0E3",
    "6960": "E9AA",
    "6963": "E9B9",
    "6966": "E9B8",
    "696B": "E9AE",
    "696E": "E8FA",
    "6971": "E9A8",
    "6977": "BFAC",
    "6978": "E9B1",
    "6979": "E9BA",
    "697C": "C2A5",
    "6980": "E9AF",
    "6982": "B8C5",
    "6984": "E9AD",
    "6986": "D3DC",
    "6987": "E9B4",
    "6988": "E9B5",
    "6989": "E9B7",
    "698D": "E9C7",
    "6994": "C0C6",
    "6995": "E9C5",
    "6998": "E9B0",
    "699B": "E9BB",
    "699C": "B0F1",
    "69A7": "E9BC",
    "69A8": "D5A5",
    "69AB": "E9BE",
    "69AD": "E9BF",
    "69B1": "E9C1",
    "69B4": "C1F1",
    "69B7": "C8B6",
    "69BB": "E9BD",
    "69C1": "E9C2",
    "69CA": "E9C3",
    "69CC": "E9B3",
    "69CE": "E9B6",
    "69D0": "BBB1",
    "69D4": "E9C0",
    "69DB": "BCF7",
    "69DF": "E9C4",
    "69E0": "E9C6",
    "69ED": "E9CA",
    "69F2": "E9CE",
    "69FD": "B2DB",
    "69FF": "E9C8",
    "6A0A": "B7AE",
    "6A17": "E9CB",
    "6A18": "E9CC",
    "6A1F": "D5C1",
    "6A21": "C4A3",
    "6A28": "E9D8",
    "6A2A": "BAE1",
    "6A2F": "E9C9",
    "6A31": "D3A3",
    "6A35": "E9D4",
    "6A3D": "E9D7",
    "6A3E": "E9D0",
    "6A44": "E9CF",
    "6A47": "C7C1",
    "6A50": "E9D2",
    "6A58": "E9D9",
    "6A59": "B3C8",
    "6A5B": "E9D3",
    "6A61": "CFF0",
    "6A65": "E9CD",
    "6A71": "B3F7",
    "6A79": "E9D6",
    "6A7C": "E9DA",
    "6A80": "CCB4",
    "6A84": "CFAD",
    "6A8E": "E9D5",
    "6A90": "E9DC",
    "6A91": "E9DB",
    "6A97": "E9DE",
    "6AA0": "E9D1",
    "6AA9": "E9DD",
    "6AAB": "E9DF",
    "6AAC": "C3CA",
    "6B20": "C7B7",
    "6B21": "B4CE",
    "6B22": "BBB6",
    "6B23": "D0C0",
    "6B24": "ECA3",
    "6B27": "C5B7",
    "6B32": "D3FB",
    "6B37": "ECA4",
    "6B39": "ECA5",
    "6B3A": "C6DB",
    "6B3E": "BFEE",
    "6B43": "ECA6",
    "6B46": "ECA7",
    "6B47": "D0AA",
    "6B49": "C7B8",
    "6B4C": "B8E8",
    "6B59": "ECA8",
    "6B62": "D6B9",
    "6B63": "D5FD",
    "6B64": "B4CB",
    "6B65": "B2BD",
    "6B66": "CEE4",
    "6B67": "C6E7",
    "6B6A": "CDE1",
    "6B79": "B4F5",
    "6B7B": "CBC0",
    "6B7C": "BCDF",
    "6B81": "E9E2",
    "6B82": "E9E3",
    "6B83": "D1EA",
    "6B84": "E9E5",
    "6B86": "B4F9",
    "6B87": "E9E4",
    "6B89": "D1B3",
    "6B8A": "CAE2",
    "6B8B": "B2D0",
    "6B8D": "E9E8",
    "6B92": "E9E6",
    "6B93": "E9E7",
    "6B96": "D6B3",
    "6B9A": "E9E9",
    "6B9B": "E9EA",
    "6BA1": "E9EB",
    "6BAA": "E9EC",
    "6BB3": "ECAF",
    "6BB4": "C5B9",
    "6BB5": "B6CE",
    "6BB7": "D2F3",
    "6BBF": "B5EE",
    "6BC1": "BBD9",
    "6BC2": "ECB1",
    "6BC5": "D2E3",
    "6BCB": "CEE3",
    "6BCD": "C4B8",
    "6BCF": "C3BF",
    "6BD2": "B6BE",
    "6BD3": "D8B9",
    "6BD4": "B1C8",
    "6BD5": "B1CF",
    "6BD6": "B1D1",
    "6BD7": "C5FE",
    "6BD9": "B1D0",
    "6BDB": "C3AB",
    "6BE1": "D5B1",
    "6BEA": "EBA4",
    "6BEB": "BAC1",
    "6BEF": "CCBA",
    "6BF3": "EBA5",
    "6BF5": "EBA7",
    "6BF9": "EBA8",
    "6BFD": "EBA6",
    "6C05": "EBA9",
    "6C06": "EBAB",
    "6C07": "EBAA",
    "6C0D": "EBAC",
    "6C0F": "CACF",
    "6C10": "D8B5",
    "6C11": "C3F1",
    "6C13": "C3A5",
    "6C14": "C6F8",
    "6C15": "EBAD",
    "6C16": "C4CA",
    "6C18": "EBAE",
    "6C19": "EBAF",
    "6C1A": "EBB0",
    "6C1B": "B7D5",
    "6C1F": "B7FA",
    "6C21": "EBB1",
    "6C22": "C7E2",
    "6C24": "EBB3",
    "6C26": "BAA4",
    "6C27": "D1F5",
    "6C28": "B0B1",
    "6C29": "EBB2",
    "6C2A": "EBB4",
    "6C2E": "B5AA",
    "6C2F": "C2C8",
    "6C30": "C7E8",
    "6C32": "EBB5",
    "6C34": "CBAE",
    "6C35": "E3DF",
    "6C38": "D3C0",
    "6C3D": "D9DB",
    "6C40": "CDA1",
    "6C41": "D6AD",
    "6C42": "C7F3",
    "6C46": "D9E0",
    "6C47": "BBE3",
    "6C49": "BABA",
    "6C4A": "E3E2",
    "6C50": "CFAB",
    "6C54": "E3E0",
    "6C55": "C9C7",
    "6C57": "BAB9",
    "6C5B": "D1B4",
    "6C5C": "E3E1",
    "6C5D": "C8EA",
    "6C5E": "B9AF",
    "6C5F": "BDAD",
    "6C60": "B3D8",
    "6C61": "CEDB",
    "6C64": "CCC0",
    "6C68": "E3E8",
    "6C69": "E3E9",
    "6C6A": "CDF4",
    "6C70": "CCAD",
    "6C72": "BCB3",
    "6C74": "E3EA",
    "6C76": "E3EB",
    "6C79": "D0DA",
    "6C7D": "C6FB",
    "6C7E": "B7DA",
    "6C81": "C7DF",
    "6C82": "D2CA",
    "6C83": "CED6",
    "6C85": "E3E4",
    "6C86": "E3EC",
    "6C88": "C9F2",
    "6C89": "B3C1",
    "6C8C": "E3E7",
    "6C8F": "C6E3",
    "6C90": "E3E5",
    "6C93": "EDB3",
    "6C94": "E3E6",
    "6C99": "C9B3",
    "6C9B": "C5E6",
    "6C9F": "B9B5",
    "6CA1": "C3BB",
    "6CA3": "E3E3",
    "6CA4": "C5BD",
    "6CA5": "C1A4",
    "6CA6": "C2D9",
    "6CA7": "B2D7",
    "6CA9": "E3ED",
    "6CAA": "BBA6",
    "6CAB": "C4AD",
    "6CAD": "E3F0",
    "6CAE": "BEDA",
    "6CB1": "E3FB",
    "6CB2": "E3F5",
    "6CB3": "BAD3",
    "6CB8": "B7D0",
    "6CB9": "D3CD",
    "6CBB": "D6CE",
    "6CBC": "D5D3",
    "6CBD": "B9C1",
    "6CBE": "D5B4",
    "6CBF": "D1D8",
    "6CC4": "D0B9",
    "6CC5": "C7F6",
    "6CC9": "C8AA",
    "6CCA": "B2B4",
    "6CCC": "C3DA",
    "6CD0": "E3EE",
    "6CD3": "E3FC",
    "6CD4": "E3EF",
    "6CD5": "B7A8",
    "6CD6": "E3F7",
    "6CD7": "E3F4",
    "6CDB": "B7BA",
    "6CDE": "C5A2",
    "6CE0": "E3F6",
    "6CE1": "C5DD",
    "6CE2": "B2A8",
    "6CE3": "C6FC",
    "6CE5": "C4E0",
    "6CE8": "D7A2",
    "6CEA": "C0E1",
    "6CEB": "E3F9",
    "6CEE": "E3FA",
    "6CEF": "E3FD",
    "6CF0": "CCA9",
    "6CF1": "E3F3",
    "6CF3": "D3BE",
    "6CF5": "B1C3",
    "6CF6": "EDB4",
    "6CF7": "E3F1",
    "6CF8": "E3F2",
    "6CFA": "E3F8",
    "6CFB": "D0BA",
    "6CFC": "C6C3",
    "6CFD": "D4F3",
    "6CFE": "E3FE",
    "6D01": "BDE0",
    "6D04": "E4A7",
    "6D07": "E4A6",
    "6D0B": "D1F3",
    "6D0C": "E4A3",
    "6D0E": "E4A9",
    "6D12": "C8F7",
    "6D17": "CFB4",
    "6D19": "E4A8",
    "6D1A": "E4AE",
    "6D1B": "C2E5",
    "6D1E": "B6B4",
    "6D25": "BDF2",
    "6D27": "E4A2",
    "6D2A": "BAE9",
    "6D2B": "E4AA",
    "6D2E": "E4AC",
    "6D31": "B6FD",
    "6D32": "D6DE",
    "6D33": "E4B2",
    "6D35": "E4AD",
    "6D39": "E4A1",
    "6D3B": "BBEE",
    "6D3C": "CDDD",
    "6D3D": "C7A2",
    "6D3E": "C5C9",
    "6D41": "C1F7",
    "6D43": "E4A4",
    "6D45": "C7B3",
    "6D46": "BDAC",
    "6D47": "BDBD",
    "6D48": "E4A5",
    "6D4A": "D7C7",
    "6D4B": "B2E2",
    "6D4D": "E4AB",
    "6D4E": "BCC3",
    "6D4F": "E4AF",
    "6D51": "BBEB",
    "6D52": "E4B0",
    "6D53": "C5A8",
    "6D54": "E4B1",
    "6D59": "D5E3",
    "6D5A": "BFA3",
    "6D5C": "E4BA",
    "6D5E": "E4B7",
    "6D60": "E4BB",
    "6D63": "E4BD",
    "6D66": "C6D6",
    "6D69": "BAC6",
    "6D6A": "C0CB",
    "6D6E": "B8A1",
    "6D6F": "E4B4",
    "6D74": "D4A1",
    "6D77": "BAA3",
    "6D78": "BDFE",
    "6D7C": "E4BC",
    "6D82": "CDBF",
    "6D85": "C4F9",
    "6D88": "CFFB",
    "6D89": "C9E6",
    "6D8C": "D3BF",
    "6D8E": "CFD1",
    "6D91": "E4B3",
    "6D93": "E4B8",
    "6D94": "E4B9",
    "6D95": "CCE9",
    "6D9B": "CCCE",
    "6D9D": "C0D4",
    "6D9E": "E4B5",
    "6D9F": "C1B0",
    "6DA0": "E4B6",
    "6DA1": "CED0",
    "6DA3": "BBC1",
    "6DA4": "B5D3",
    "6DA6": "C8F3",
    "6DA7": "BDA7",
    "6DA8": "D5C7",
    "6DA9": "C9AC",
    "6DAA": "B8A2",
    "6DAB": "E4CA",
    "6DAE": "E4CC",
    "6DAF": "D1C4",
    "6DB2": "D2BA",
    "6DB5": "BAAD",
    "6DB8": "BAD4",
    "6DBF": "E4C3",
    "6DC0": "B5ED",
    "6DC4": "D7CD",
    "6DC5": "E4C0",
    "6DC6": "CFFD",
    "6DC7": "E4BF",
    "6DCB": "C1DC",
    "6DCC": "CCCA",
    "6DD1": "CAE7",
    "6DD6": "C4D7",
    "6DD8": "CCD4",
    "6DD9": "E4C8",
    "6DDD": "E4C7",
    "6DDE": "E4C1",
    "6DE0": "E4C4",
    "6DE1": "B5AD",
    "6DE4": "D3D9",
    "6DE6": "E4C6",
    "6DEB": "D2F9",
    "6DEC": "B4E3",
    "6DEE": "BBB4",
    "6DF1": "C9EE",
    "6DF3": "B4BE",
    "6DF7": "BBEC",
    "6DF9": "D1CD",
    "6DFB": "CCED",
    "6DFC": "EDB5",
    "6E05": "C7E5",
    "6E0A": "D4A8",
    "6E0C": "E4CB",
    "6E0D": "D7D5",
    "6E0E": "E4C2",
    "6E10": "BDA5",
    "6E11": "E4C5",
    "6E14": "D3E6",
    "6E16": "E4C9",
    "6E17": "C9F8",
    "6E1A": "E4BE",
    "6E1D": "D3E5",
    "6E20": "C7FE",
    "6E21": "B6C9",
    "6E23": "D4FC",
    "6E24": "B2B3",
    "6E25": "E4D7",
    "6E29": "CEC2",
    "6E2B": "E4CD",
    "6E2D": "CEBC",
    "6E2F": "B8DB",
    "6E32": "E4D6",
    "6E34": "BFCA",
    "6E38": "D3CE",
    "6E3A": "C3EC",
    "6E43": "C5C8",
    "6E44": "E4D8",
    "6E4D": "CDC4",
    "6E4E": "E4CF",
    "6E53": "E4D4",
    "6E54": "E4D5",
    "6E56": "BAFE",
    "6E58": "CFE6",
    "6E5B": "D5BF",
    "6E5F": "E4D2",
    "6E6B": "E4D0",
    "6E6E": "E4CE",
    "6E7E": "CDE5",
    "6E7F": "CAAA",
    "6E83": "C0A3",
    "6E85": "BDA6",
    "6E86": "E4D3",
    "6E89": "B8C8",
    "6E8F": "E4E7",
    "6E90": "D4B4",
    "6E98": "E4DB",
    "6E9C": "C1EF",
    "6E9F": "E4E9",
    "6EA2": "D2E7",
    "6EA5": "E4DF",
    "6EA7": "E4E0",
    "6EAA": "CFAA",
    "6EAF": "CBDD",
    "6EB1": "E4DA",
    "6EB2": "E4D1",
    "6EB4": "E4E5",
    "6EB6": "C8DC",
    "6EB7": "E4E3",
    "6EBA": "C4E7",
    "6EBB": "E4E2",
    "6EBD": "E4E1",
    "6EC1": "B3FC",
    "6EC2": "E4E8",
    "6EC7": "B5E1",
    "6ECB": "D7CC",
    "6ECF": "E4E6",
    "6ED1": "BBAC",
    "6ED3": "D7D2",
    "6ED4": "CCCF",
    "6ED5": "EBF8",
    "6ED7": "E4E4",
    "6EDA": "B9F6",
    "6EDE": "D6CD",
    "6EDF": "E4D9",
    "6EE0": "E4DC",
    "6EE1": "C2FA",
    "6EE2": "E4DE",
    "6EE4": "C2CB",
    "6EE5": "C0C4",
    "6EE6": "C2D0",
    "6EE8": "B1F5",
    "6EE9": "CCB2",
    "6EF4": "B5CE",
    "6EF9": "E4EF",
    "6F02": "C6AF",
    "6F06": "C6E1",
    "6F09": "E4F5",
    "6F0F": "C2A9",
    "6F13": "C0EC",
    "6F14": "D1DD",
    "6F15": "E4EE",
    "6F20": "C4AE",
    "6F24": "E4ED",
    "6F29": "E4F6",
    "6F2A": "E4F4",
    "6F2B": "C2FE",
    "6F2D": "E4DD",
    "6F2F": "E4F0",
    "6F31": "CAFE",
    "6F33": "D5C4",
    "6F36": "E4F1",
    "6F3E": "D1FA",
    "6F46": "E4EB",
    "6F47": "E4EC",
    "6F4B": "E4F2",
    "6F4D": "CEAB",
    "6F58": "C5CB",
    "6F5C": "C7B1",
    "6F5E": "C2BA",
    "6F62": "E4EA",
    "6F66": "C1CA",
    "6F6D": "CCB6",
    "6F6E": "B3B1",
    "6F72": "E4FB",
    "6F74": "E4F3",
    "6F78": "E4FA",
    "6F7A": "E4FD",
    "6F7C": "E4FC",
    "6F84": "B3CE",
    "6F88": "B3BA",
    "6F89": "E4F7",
    "6F8C": "E4F9",
    "6F8D": "E4F8",
    "6F8E": "C5EC",
    "6F9C": "C0BD",
    "6FA1": "D4E8",
    "6FA7": "E5A2",
    "6FB3": "B0C4",
    "6FB6": "E5A4",
    "6FB9": "E5A3",
    "6FC0": "BCA4",
    "6FC2": "E5A5",
    "6FC9": "E5A1",
    "6FD1": "E4FE",
    "6FD2": "B1F4",
    "6FDE": "E5A8",
    "6FE0": "E5A9",
    "6FE1": "E5A6",
    "6FEE": "E5A7",
    "6FEF": "E5AA",
    "7011": "C6D9",
    "701A": "E5AB",
    "701B": "E5AD",
    "7023": "E5AC",
    "7035": "E5AF",
    "7039": "E5AE",
    "704C": "B9E0",
    "704F": "E5B0",
    "705E": "E5B1",
    "706B": "BBF0",
    "706C": "ECE1",
    "706D": "C3F0",
    "706F": "B5C6",
    "7070": "BBD2",
    "7075": "C1E9",
    "7076": "D4EE",
    "7078": "BEC4",
    "707C": "D7C6",
    "707E": "D4D6",
    "707F": "B2D3",
    "7080": "ECBE",
    "7085": "EAC1",
    "7089": "C2AF",
    "708A": "B4B6",
    "708E": "D1D7",
    "7092": "B3B4",
    "7094": "C8B2",
    "7095": "BFBB",
    "7096": "ECC0",
    "7099": "D6CB",
    "709C": "ECBF",
    "709D": "ECC1",
    "70AB": "ECC5",
    "70AC": "BEE6",
    "70AD": "CCBF",
    "70AE": "C5DA",
    "70AF": "BEBC",
    "70B1": "ECC6",
    "70B3": "B1FE",
    "70B7": "ECC4",
    "70B8": "D5A8",
    "70B9": "B5E3",
    "70BB": "ECC2",
    "70BC": "C1B6",
    "70BD": "B3E3",
    "70C0": "ECC3",
    "70C1": "CBB8",
    "70C2": "C0C3",
    "70C3": "CCFE",
    "70C8": "C1D2",
    "70CA": "ECC8",
    "70D8": "BAE6",
    "70D9": "C0D3",
    "70DB": "D6F2",
    "70DF": "D1CC",
    "70E4": "BFBE",
    "70E6": "B7B3",
    "70E7": "C9D5",
    "70E8": "ECC7",
    "70E9": "BBE2",
    "70EB": "CCCC",
    "70EC": "BDFD",
    "70ED": "C8C8",
    "70EF": "CFA9",
    "70F7": "CDE9",
    "70F9": "C5EB",
    "70FD": "B7E9",
    "7109": "D1C9",
    "710A": "BAB8",
    "7110": "ECC9",
    "7113": "ECCA",
    "7115": "BBC0",
    "7116": "ECCB",
    "7118": "ECE2",
    "7119": "B1BA",
    "711A": "B7D9",
    "7126": "BDB9",
    "712F": "ECCC",
    "7130": "D1E6",
    "7131": "ECCD",
    "7136": "C8BB",
    "7145": "ECD1",
    "714A": "ECD3",
    "714C": "BBCD",
    "714E": "BCE5",
    "715C": "ECCF",
    "715E": "C9B7",
    "7164": "C3BA",
    "7166": "ECE3",
    "7167": "D5D5",
    "7168": "ECD0",
    "716E": "D6F3",
    "7172": "ECD2",
    "7173": "ECCE",
    "7178": "ECD4",
    "717A": "ECD5",
    "717D": "C9BF",
    "7184": "CFA8",
    "718A": "D0DC",
    "718F": "D1AC",
    "7194": "C8DB",
    "7198": "ECD6",
    "7199": "CEF5",
    "719F": "CAEC",
    "71A0": "ECDA",
    "71A8": "ECD9",
    "71AC": "B0BE",
    "71B3": "ECD7",
    "71B5": "ECD8",
    "71B9": "ECE4",
    "71C3": "C8BC",
    "71CE": "C1C7",
    "71D4": "ECDC",
    "71D5": "D1E0",
    "71E0": "ECDB",
    "71E5": "D4EF",
    "71E7": "ECDD",
    "71EE": "DBC6",
    "71F9": "ECDE",
    "7206": "B1AC",
    "721D": "ECDF",
    "7228": "ECE0",
    "722A": "D7A6",
    "722C": "C5C0",
    "7230": "EBBC",
    "7231": "B0AE",
    "7235": "BEF4",
    "7236": "B8B8",
    "7237": "D2AF",
    "7238": "B0D6",
    "7239": "B5F9",
    "723B": "D8B3",
    "723D": "CBAC",
    "723F": "E3DD",
    "7247": "C6AC",
    "7248": "B0E6",
    "724C": "C5C6",
    "724D": "EBB9",
    "7252": "EBBA",
    "7256": "EBBB",
    "7259": "D1C0",
    "725B": "C5A3",
    "725D": "EAF2",
    "725F": "C4B2",
    "7261": "C4B5",
    "7262": "C0CE",
    "7266": "EAF3",
    "7267": "C4C1",
    "7269": "CEEF",
    "726E": "EAF0",
    "726F": "EAF4",
    "7272": "C9FC",
    "7275": "C7A3",
    "7279": "CCD8",
    "727A": "CEFE",
    "727E": "EAF5",
    "727F": "EAF6",
    "7280": "CFAC",
    "7281": "C0E7",
    "7284": "EAF7",
    "728A": "B6BF",
    "728B": "EAF8",
    "728D": "EAF9",
    "728F": "EAFA",
    "7292": "EAFB",
    "729F": "EAF1",
    "72AC": "C8AE",
    "72AD": "E1EB",
    "72AF": "B7B8",
    "72B0": "E1EC",
    "72B4": "E1ED",
    "72B6": "D7B4",
    "72B7": "E1EE",
    "72B8": "E1EF",
    "72B9": "D3CC",
    "72C1": "E1F1",
    "72C2": "BFF1",
    "72C3": "E1F0",
    "72C4": "B5D2",
    "72C8": "B1B7",
    "72CD": "E1F3",
    "72CE": "E1F2",
    "72D0": "BAFC",
    "72D2": "E1F4",
    "72D7": "B9B7",
    "72D9": "BED1",
    "72DE": "C4FC",
    "72E0": "BADD",
    "72E1": "BDC6",
    "72E8": "E1F5",
    "72E9": "E1F7",
    "72EC": "B6C0",
    "72ED": "CFC1",
    "72EE": "CAA8",
    "72EF": "E1F6",
    "72F0": "D5F8",
    "72F1": "D3FC",
    "72F2": "E1F8",
    "72F3": "E1FC",
    "72F4": "E1F9",
    "72F7": "E1FA",
    "72F8": "C0EA",
    "72FA": "E1FE",
    "72FB": "E2A1",
    "72FC": "C0C7",
    "7301": "E1FB",
    "7303": "E1FD",
    "730A": "E2A5",
    "730E": "C1D4",
    "7313": "E2A3",
    "7315": "E2A8",
    "7316": "B2FE",
    "7317": "E2A2",
    "731B": "C3CD",
    "731C": "B2C2",
    "731D": "E2A7",
    "731E": "E2A6",
    "7321": "E2A4",
    "7322": "E2A9",
    "7325": "E2AB",
    "7329": "D0C9",
    "732A": "D6ED",
    "732B": "C3A8",
    "732C": "E2AC",
    "732E": "CFD7",
    "7331": "E2AE",
    "7334": "BAEF",
    "7337": "E9E0",
    "7338": "E2AD",
    "7339": "E2AA",
    "733E": "BBAB",
    "733F": "D4B3",
    "734D": "E2B0",
    "7350": "E2AF",
    "7352": "E9E1",
    "7357": "E2B1",
    "7360": "E2B2",
    "736C": "E2B3",
    "736D": "CCA1",
    "736F": "E2B4",
    "737E": "E2B5",
    "7384": "D0FE",
    "7387": "C2CA",
    "7389": "D3F1",
    "738B": "CDF5",
    "738E": "E7E0",
    "7391": "E7E1",
    "7396": "BEC1",
    "739B": "C2EA",
    "739F": "E7E4",
    "73A2": "E7E3",
    "73A9": "CDE6",
    "73AB": "C3B5",
    "73AE": "E7E2",
    "73AF": "BBB7",
    "73B0": "CFD6",
    "73B2": "C1E1",
    "73B3": "E7E9",
    "73B7": "E7E8",
    "73BA": "E7F4",
    "73BB": "B2A3",
    "73C0": "E7EA",
    "73C2": "E7E6",
    "73C8": "E7EC",
    "73C9": "E7EB",
    "73CA": "C9BA",
    "73CD": "D5E4",
    "73CF": "E7E5",
    "73D0": "B7A9",
    "73D1": "E7E7",
    "73D9": "E7EE",
    "73DE": "E7F3",
    "73E0": "D6E9",
    "73E5": "E7ED",
    "73E7": "E7F2",
    "73E9": "E7F1",
    "73ED": "B0E0",
    "73F2": "E7F5",
    "7403": "C7F2",
    "7405": "C0C5",
    "7406": "C0ED",
    "7409": "C1F0",
    "740A": "E7F0",
    "740F": "E7F6",
    "7410": "CBF6",
    "741A": "E8A2",
    "741B": "E8A1",
    "7422": "D7C1",
    "7425": "E7FA",
    "7426": "E7F9",
    "7428": "E7FB",
    "742A": "E7F7",
    "742C": "E7FE",
    "742E": "E7FD",
    "7430": "E7FC",
    "7433": "C1D5",
    "7434": "C7D9",
    "7435": "C5FD",
    "7436": "C5C3",
    "743C": "C7ED",
    "7441": "E8A3",
    "7455": "E8A6",
    "7457": "E8A5",
    "7459": "E8A7",
    "745A": "BAF7",
    "745B": "E7F8",
    "745C": "E8A4",
    "745E": "C8F0",
    "745F": "C9AA",
    "746D": "E8A9",
    "7470": "B9E5",
    "7476": "D1FE",
    "7477": "E8A8",
    "747E": "E8AA",
    "7480": "E8AD",
    "7481": "E8AE",
    "7483": "C1A7",
    "7487": "E8AF",
    "748B": "E8B0",
    "748E": "E8AC",
    "7490": "E8B4",
    "749C": "E8AB",
    "749E": "E8B1",
    "74A7": "E8B5",
    "74A8": "E8B2",
    "74A9": "E8B3",
    "74BA": "E8B7",
    "74D2": "E8B6",
    "74DC": "B9CF",
    "74DE": "F0AC",
    "74E0": "F0AD",
    "74E2": "C6B0",
    "74E3": "B0EA",
    "74E4": "C8BF",
    "74E6": "CDDF",
    "74EE": "CECD",
    "74EF": "EAB1",
    "74F4": "EAB2",
    "74F6": "C6BF",
    "74F7": "B4C9",
    "74FF": "EAB3",
    "7504": "D5E7",
    "750D": "DDF9",
    "750F": "EAB4",
    "7511": "EAB5",
    "7513": "EAB6",
    "7518": "B8CA",
    "7519": "DFB0",
    "751A": "C9F5",
    "751C": "CCF0",
    "751F": "C9FA",
    "7525": "C9FB",
    "7528": "D3C3",
    "7529": "CBA6",
    "752B": "B8A6",
    "752C": "F0AE",
    "752D": "B1C2",
    "752F": "E5B8",
    "7530": "CCEF",
    "7531": "D3C9",
    "7532": "BCD7",
    "7533": "C9EA",
    "7535": "B5E7",
    "7537": "C4D0",
    "7538": "B5E9",
    "753A": "EEAE",
    "753B": "BBAD",
    "753E": "E7DE",
    "7540": "EEAF",
    "7545": "B3A9",
    "7548": "EEB2",
    "754B": "EEB1",
    "754C": "BDE7",
    "754E": "EEB0",
    "754F": "CEB7",
    "7554": "C5CF",
    "7559": "C1F4",
    "755A": "DBCE",
    "755B": "EEB3",
    "755C": "D0F3",
    "7565": "C2D4",
    "7566": "C6E8",
    "756A": "B7AC",
    "7572": "EEB4",
    "7574": "B3EB",
    "7578": "BBFB",
    "7579": "EEB5",
    "757F": "E7DC",
    "7583": "EEB6",
    "7586": "BDAE",
    "758B": "F1E2",
    "758F": "CAE8",
    "7591": "D2C9",
    "7592": "F0DA",
    "7594": "F0DB",
    "7596": "F0DC",
    "7597": "C1C6",
    "7599": "B8ED",
    "759A": "BECE",
    "759D": "F0DE",
    "759F": "C5B1",
    "75A0": "F0DD",
    "75A1": "D1F1",
    "75A3": "F0E0",
    "75A4": "B0CC",
    "75A5": "BDEA",
    "75AB": "D2DF",
    "75AC": "F0DF",
    "75AE": "B4AF",
    "75AF": "B7E8",
    "75B0": "F0E6",
    "75B1": "F0E5",
    "75B2": "C6A3",
    "75B3": "F0E1",
    "75B4": "F0E2",
    "75B5": "B4C3",
    "75B8": "F0E3",
    "75B9": "D5EE",
    "75BC": "CCDB",
    "75BD": "BED2",
    "75BE": "BCB2",
    "75C2": "F0E8",
    "75C3": "F0E7",
    "75C4": "F0E4",
    "75C5": "B2A1",
    "75C7": "D6A2",
    "75C8": "D3B8",
    "75C9": "BEB7",
    "75CA": "C8AC",
    "75CD": "F0EA",
    "75D2": "D1F7",
    "75D4": "D6CC",
    "75D5": "BADB",
    "75D6": "F0E9",
    "75D8": "B6BB",
    "75DB": "CDB4",
    "75DE": "C6A6",
    "75E2": "C1A1",
    "75E3": "F0EB",
    "75E4": "F0EE",
    "75E6": "F0ED",
    "75E7": "F0F0",
    "75E8": "F0EC",
    "75EA": "BBBE",
    "75EB": "F0EF",
    "75F0": "CCB5",
    "75F1": "F0F2",
    "75F4": "B3D5",
    "75F9": "B1D4",
    "75FC": "F0F3",
    "75FF": "F0F4",
    "7600": "F0F6",
    "7601": "B4E1",
    "7603": "F0F1",
    "7605": "F0F7",
    "760A": "F0FA",
    "760C": "F0F8",
    "7610": "F0F5",
    "7615": "F0FD",
    "7617": "F0F9",
    "7618": "F0FC",
    "7619": "F0FE",
    "761B": "F1A1",
    "761F": "CEC1",
    "7620": "F1A4",
    "7622": "F1A3",
    "7624": "C1F6",
    "7625": "F0FB",
    "7626": "CADD",
    "7629": "B4F1",
    "762A": "B1F1",
    "762B": "CCB1",
    "762D": "F1A6",
    "7630": "F1A7",
    "7633": "F1AC",
    "7634": "D5CE",
    "7635": "F1A9",
    "7638": "C8B3",
    "763C": "F1A2",
    "763E": "F1AB",
    "763F": "F1A8",
    "7640": "F1A5",
    "7643": "F1AA",
    "764C": "B0A9",
    "764D": "F1AD",
    "7654": "F1AF",
    "7656": "F1B1",
    "765C": "F1B0",
    "765E": "F1AE",
    "7663": "D1A2",
    "766B": "F1B2",
    "766F": "F1B3",
    "7678": "B9EF",
    "767B": "B5C7",
    "767D": "B0D7",
    "767E": "B0D9",
    "7682": "D4ED",
    "7684": "B5C4",
    "7686": "BDD4",
    "7687": "BBCA",
    "7688": "F0A7",
    "768B": "B8DE",
    "768E": "F0A8",
    "7691": "B0A8",
    "7693": "F0A9",
    "7696": "CDEE",
    "7699": "F0AA",
    "76A4": "F0AB",
    "76AE": "C6A4",
    "76B1": "D6E5",
    "76B2": "F1E4",
    "76B4": "F1E5",
    "76BF": "C3F3",
    "76C2": "D3DB",
    "76C5": "D6D1",
    "76C6": "C5E8",
    "76C8": "D3AF",
    "76CA": "D2E6",
    "76CD": "EEC1",
    "76CE": "B0BB",
    "76CF": "D5B5",
    "76D0": "D1CE",
    "76D1": "BCE0",
    "76D2": "BAD0",
    "76D4": "BFF8",
    "76D6": "B8C7",
    "76D7": "B5C1",
    "76D8": "C5CC",
    "76DB": "CAA2",
    "76DF": "C3CB",
    "76E5": "EEC2",
    "76EE": "C4BF",
    "76EF": "B6A2",
    "76F1": "EDEC",
    "76F2": "C3A4",
    "76F4": "D6B1",
    "76F8": "CFE0",
    "76F9": "EDEF",
    "76FC": "C5CE",
    "76FE": "B6DC",
    "7701": "CAA1",
    "7704": "EDED",
    "7707": "EDF0",
    "7708": "EDF1",
    "7709": "C3BC",
    "770B": "BFB4",
    "770D": "EDEE",
    "7719": "EDF4",
    "771A": "EDF2",
    "771F": "D5E6",
    "7720": "C3DF",
    "7722": "EDF3",
    "7726": "EDF6",
    "7728": "D5A3",
    "7729": "D1A3",
    "772D": "EDF5",
    "772F": "C3D0",
    "7735": "EDF7",
    "7736": "BFF4",
    "7737": "BEEC",
    "7738": "EDF8",
    "773A": "CCF7",
    "773C": "D1DB",
    "7740": "D7C5",
    "7741": "D5F6",
    "7743": "EDFC",
    "7747": "EDFB",
    "7750": "EDF9",
    "7751": "EDFA",
    "775A": "EDFD",
    "775B": "BEA6",
    "7761": "CBAF",
    "7762": "EEA1",
    "7763": "B6BD",
    "7765": "EEA2",
    "7766": "C4C0",
    "7768": "EDFE",
    "776B": "BDDE",
    "776C": "B2C7",
    "7779": "B6C3",
    "777D": "EEA5",
    "777E": "D8BA",
    "777F": "EEA3",
    "7780": "EEA6",
    "7784": "C3E9",
    "7785": "B3F2",
    "778C": "EEA7",
    "778D": "EEA4",
    "778E": "CFB9",
    "7791": "EEA8",
    "7792": "C2F7",
    "779F": "EEA9",
    "77A0": "EEAA",
    "77A2": "DEAB",
    "77A5": "C6B3",
    "77A7": "C7C6",
    "77A9": "D6F5",
    "77AA": "B5C9",
    "77AC": "CBB2",
    "77B0": "EEAB",
    "77B3": "CDAB",
    "77B5": "EEAC",
    "77BB": "D5B0",
    "77BD": "EEAD",
    "77BF": "F6C4",
    "77CD": "DBC7",
    "77D7": "B4A3",
    "77DB": "C3AC",
    "77DC": "F1E6",
    "77E2": "CAB8",
    "77E3": "D2D3",
    "77E5": "D6AA",
    "77E7": "EFF2",
    "77E9": "BED8",
    "77EB": "BDC3",
    "77EC": "EFF3",
    "77ED": "B6CC",
    "77EE": "B0AB",
    "77F3": "CAAF",
    "77F6": "EDB6",
    "77F8": "EDB7",
    "77FD": "CEF9",
    "77FE": "B7AF",
    "77FF": "BFF3",
    "7800": "EDB8",
    "7801": "C2EB",
    "7802": "C9B0",
    "7809": "EDB9",
    "780C": "C6F6",
    "780D": "BFB3",
    "7811": "EDBC",
    "7812": "C5F8",
    "7814": "D1D0",
    "7816": "D7A9",
    "7817": "EDBA",
    "7818": "EDBB",
    "781A": "D1E2",
    "781C": "EDBF",
    "781D": "EDC0",
    "781F": "EDC4",
    "7823": "EDC8",
    "7825": "EDC6",
    "7826": "EDCE",
    "7827": "D5E8",
    "7829": "EDC9",
    "782C": "EDC7",
    "782D": "EDBE",
    "7830": "C5E9",
    "7834": "C6C6",
    "7837": "C9E9",
    "7838": "D4D2",
    "7839": "EDC1",
    "783A": "EDC2",
    "783B": "EDC3",
    "783C": "EDC5",
    "783E": "C0F9",
    "7840": "B4A1",
    "7845": "B9E8",
    "7847": "EDD0",
    "784C": "EDD1",
    "784E": "EDCA",
    "7850": "EDCF",
    "7852": "CEF8",
    "7855": "CBB6",
    "7856": "EDCC",
    "7857": "EDCD",
    "785D": "CFF5",
    "786A": "EDD2",
    "786B": "C1F2",
    "786C": "D3B2",
    "786D": "EDCB",
    "786E": "C8B7",
    "7877": "BCEF",
    "787C": "C5F0",
    "7887": "EDD6",
    "7889": "B5EF",
    "788C": "C2B5",
    "788D": "B0AD",
    "788E": "CBE9",
    "7891": "B1AE",
    "7893": "EDD4",
    "7897": "CDEB",
    "7898": "B5E2",
    "789A": "EDD5",
    "789B": "EDD3",
    "789C": "EDD7",
    "789F": "B5FA",
    "78A1": "EDD8",
    "78A3": "EDD9",
    "78A5": "EDDC",
    "78A7": "B1CC",
    "78B0": "C5F6",
    "78B1": "BCEE",
    "78B2": "EDDA",
    "78B3": "CCBC",
    "78B4": "B2EA",
    "78B9": "EDDB",
    "78BE": "C4EB",
    "78C1": "B4C5",
    "78C5": "B0F5",
    "78C9": "EDDF",
    "78CA": "C0DA",
    "78CB": "B4E8",
    "78D0": "C5CD",
    "78D4": "EDDD",
    "78D5": "BFC4",
    "78D9": "EDDE",
    "78E8": "C4A5",
    "78EC": "EDE0",
    "78F2": "EDE1",
    "78F4": "EDE3",
    "78F7": "C1D7",
    "78FA": "BBC7",
    "7901": "BDB8",
    "7905": "EDE2",
    "7913": "EDE4",
    "791E": "EDE6",
    "7924": "EDE5",
    "7934": "EDE7",
    "793A": "CABE",
    "793B": "ECEA",
    "793C": "C0F1",
    "793E": "C9E7",
    "7940": "ECEB",
    "7941": "C6EE",
    "7946": "ECEC",
    "7948": "C6ED",
    "7949": "ECED",
    "7953": "ECF0",
    "7956": "D7E6",
    "7957": "ECF3",
    "795A": "ECF1",
    "795B": "ECEE",
    "795C": "ECEF",
    "795D": "D7A3",
    "795E": "C9F1",
    "795F": "CBEE",
    "7960": "ECF4",
    "7962": "ECF2",
    "7965": "CFE9",
    "7967": "ECF6",
    "7968": "C6B1",
    "796D": "BCC0",
    "796F": "ECF5",
    "7977": "B5BB",
    "7978": "BBF6",
    "797A": "ECF7",
    "7980": "D9F7",
    "7981": "BDFB",
    "7984": "C2BB",
    "7985": "ECF8",
    "798A": "ECF9",
    "798F": "B8A3",
    "799A": "ECFA",
    "79A7": "ECFB",
    "79B3": "ECFC",
    "79B9": "D3ED",
    "79BA": "D8AE",
    "79BB": "C0EB",
    "79BD": "C7DD",
    "79BE": "BACC",
    "79C0": "D0E3",
    "79C1": "CBBD",
    "79C3": "CDBA",
    "79C6": "B8D1",
    "79C9": "B1FC",
    "79CB": "C7EF",
    "79CD": "D6D6",
    "79D1": "BFC6",
    "79D2": "C3EB",
    "79D5": "EFF5",
    "79D8": "C3D8",
    "79DF": "D7E2",
    "79E3": "EFF7",
    "79E4": "B3D3",
    "79E6": "C7D8",
    "79E7": "D1ED",
    "79E9": "D6C8",
    "79EB": "EFF8",
    "79ED": "EFF6",
    "79EF": "BBFD",
    "79F0": "B3C6",
    "79F8": "BDD5",
    "79FB": "D2C6",
    "79FD": "BBE0",
    "7A00": "CFA1",
    "7A02": "EFFC",
    "7A03": "EFFB",
    "7A06": "EFF9",
    "7A0B": "B3CC",
    "7A0D": "C9D4",
    "7A0E": "CBB0",
    "7A14": "EFFE",
    "7A17": "B0DE",
    "7A1A": "D6C9",
    "7A1E": "EFFD",
    "7A20": "B3ED",
    "7A23": "F6D5",
    "7A33": "CEC8",
    "7A37": "F0A2",
    "7A39": "F0A1",
    "7A3B": "B5BE",
    "7A3C": "BCDA",
    "7A3D": "BBFC",
    "7A3F": "B8E5",
    "7A46": "C4C2",
    "7A51": "F0A3",
    "7A57": "CBEB",
    "7A70": "F0A6",
    "7A74": "D1A8",
    "7A76": "BEBF",
    "7A77": "C7EE",
    "7A78": "F1B6",
    "7A79": "F1B7",
    "7A7A": "BFD5",
    "7A7F": "B4A9",
    "7A80": "F1B8",
    "7A81": "CDBB",
    "7A83": "C7D4",
    "7A84": "D5AD",
    "7A86": "F1B9",
    "7A88": "F1BA",
    "7A8D": "C7CF",
    "7A91": "D2A4",
    "7A92": "D6CF",
    "7A95": "F1BB",
    "7A96": "BDD1",
    "7A97": "B4B0",
    "7A98": "BEBD",
    "7A9C": "B4DC",
    "7A9D": "CED1",
    "7A9F": "BFDF",
    "7AA0": "F1BD",
    "7AA5": "BFFA",
    "7AA6": "F1BC",
    "7AA8": "F1BF",
    "7AAC": "F1BE",
    "7AAD": "F1C0",
    "7AB3": "F1C1",
    "7ABF": "C1FE",
    "7ACB": "C1A2",
    "7AD6": "CAFA",
    "7AD9": "D5BE",
    "7ADE": "BEBA",
    "7ADF": "BEB9",
    "7AE0": "D5C2",
    "7AE3": "BFA2",
    "7AE5": "CDAF",
    "7AE6": "F1B5",
    "7AED": "BDDF",
    "7AEF": "B6CB",
    "7AF9": "D6F1",
    "7AFA": "F3C3",
    "7AFD": "F3C4",
    "7AFF": "B8CD",
    "7B03": "F3C6",
    "7B04": "F3C7",
    "7B06": "B0CA",
    "7B08": "F3C5",
    "7B0A": "F3C9",
    "7B0B": "CBF1",
    "7B0F": "F3CB",
    "7B11": "D0A6",
    "7B14": "B1CA",
    "7B15": "F3C8",
    "7B19": "F3CF",
    "7B1B": "B5D1",
    "7B1E": "F3D7",
    "7B20": "F3D2",
    "7B24": "F3D4",
    "7B25": "F3D3",
    "7B26": "B7FB",
    "7B28": "B1BF",
    "7B2A": "F3CE",
    "7B2B": "F3CA",
    "7B2C": "B5DA",
    "7B2E": "F3D0",
    "7B31": "F3D1",
    "7B33": "F3D5",
    "7B38": "F3CD",
    "7B3A": "BCE3",
    "7B3C": "C1FD",
    "7B3E": "F3D6",
    "7B45": "F3DA",
    "7B47": "F3CC",
    "7B49": "B5C8",
    "7B4B": "BDEE",
    "7B4C": "F3DC",
    "7B4F": "B7A4",
    "7B50": "BFF0",
    "7B51": "D6FE",
    "7B52": "CDB2",
    "7B54": "B4F0",
    "7B56": "B2DF",
    "7B58": "F3D8",
    "7B5A": "F3D9",
    "7B5B": "C9B8",
    "7B5D": "F3DD",
    "7B60": "F3DE",
    "7B62": "F3E1",
    "7B6E": "F3DF",
    "7B71": "F3E3",
    "7B72": "F3E2",
    "7B75": "F3DB",
    "7B77": "BFEA",
    "7B79": "B3EF",
    "7B7B": "F3E0",
    "7B7E": "C7A9",
    "7B80": "BCF2",
    "7B85": "F3EB",
    "7B8D": "B9BF",
    "7B90": "F3E4",
    "7B94": "B2AD",
    "7B95": "BBFE",
    "7B97": "CBE3",
    "7B9C": "F3ED",
    "7B9D": "F3E9",
    "7BA1": "B9DC",
    "7BA2": "F3EE",
    "7BA6": "F3E5",
    "7BA7": "F3E6",
    "7BA8": "F3EA",
    "7BA9": "C2E1",
    "7BAA": "F3EC",
    "7BAB": "F3EF",
    "7BAC": "F3E8",
    "7BAD": "BCFD",
    "7BB1": "CFE4",
    "7BB4": "F3F0",
    "7BB8": "F3E7",
    "7BC1": "F3F2",
    "7BC6": "D7AD",
    "7BC7": "C6AA",
    "7BCC": "F3F3",
    "7BD1": "F3F1",
    "7BD3": "C2A8",
    "7BD9": "B8DD",
    "7BDA": "F3F5",
    "7BDD": "F3F4",
    "7BE1": "B4DB",
    "7BE5": "F3F6",
    "7BE6": "F3F7",
    "7BEA": "F3F8",
    "7BEE": "C0BA",
    "7BF1": "C0E9",
    "7BF7": "C5F1",
    "7BFC": "F3FB",
    "7BFE": "F3FA",
    "7C07": "B4D8",
    "7C0B": "F3FE",
    "7C0C": "F3F9",
    "7C0F": "F3FC",
    "7C16": "F3FD",
    "7C1F": "F4A1",
    "7C26": "F4A3",
    "7C27": "BBC9",
    "7C2A": "F4A2",
    "7C38": "F4A4",
    "7C3F": "B2BE",
    "7C40": "F4A6",
    "7C41": "F4A5",
    "7C4D": "BCAE",
    "7C73": "C3D7",
    "7C74": "D9E1",
    "7C7B": "C0E0",
    "7C7C": "F4CC",
    "7C7D": "D7D1",
    "7C89": "B7DB",
    "7C91": "F4CE",
    "7C92": "C1A3",
    "7C95": "C6C9",
    "7C97": "B4D6",
    "7C98": "D5B3",
    "7C9C": "F4D0",
    "7C9D": "F4CF",
    "7C9E": "F4D1",
    "7C9F": "CBDA",
    "7CA2": "F4D2",
    "7CA4": "D4C1",
    "7CA5": "D6E0",
    "7CAA": "B7E0",
    "7CAE": "C1B8",
    "7CB1": "C1BB",
    "7CB2": "F4D3",
    "7CB3": "BEAC",
    "7CB9": "B4E2",
    "7CBC": "F4D4",
    "7CBD": "F4D5",
    "7CBE": "BEAB",
    "7CC1": "F4D6",
    "7CC5": "F4DB",
    "7CC7": "F4D7",
    "7CC8": "F4DA",
    "7CCA": "BAFD",
    "7CCC": "F4D8",
    "7CCD": "F4D9",
    "7CD5": "B8E2",
    "7CD6": "CCC7",
    "7CD7": "F4DC",
    "7CD9": "B2DA",
    "7CDC": "C3D3",
    "7CDF": "D4E3",
    "7CE0": "BFB7",
    "7CE8": "F4DD",
    "7CEF": "C5B4",
    "7CF8": "F4E9",
    "7CFB": "CFB5",
    "7D0A": "CEC9",
    "7D20": "CBD8",
    "7D22": "CBF7",
    "7D27": "BDF4",
    "7D2B": "D7CF",
    "7D2F": "C0DB",
    "7D6E": "D0F5",
    "7D77": "F4EA",
    "7DA6": "F4EB",
    "7DAE": "F4EC",
    "7E3B": "F7E3",
    "7E41": "B7B1",
    "7E47": "F4ED",
    "7E82": "D7EB",
    "7E9B": "F4EE",
    "7E9F": "E6F9",
    "7EA0": "BEC0",
    "7EA1": "E6FA",
    "7EA2": "BAEC",
    "7EA3": "E6FB",
    "7EA4": "CFCB",
    "7EA5": "E6FC",
    "7EA6": "D4BC",
    "7EA7": "BCB6",
    "7EA8": "E6FD",
    "7EA9": "E6FE",
    "7EAA": "BCCD",
    "7EAB": "C8D2",
    "7EAC": "CEB3",
    "7EAD": "E7A1",
    "7EAF": "B4BF",
    "7EB0": "E7A2",
    "7EB1": "C9B4",
    "7EB2": "B8D9",
    "7EB3": "C4C9",
    "7EB5": "D7DD",
    "7EB6": "C2DA",
    "7EB7": "B7D7",
    "7EB8": "D6BD",
    "7EB9": "CEC6",
    "7EBA": "B7C4",
    "7EBD": "C5A6",
    "7EBE": "E7A3",
    "7EBF": "CFDF",
    "7EC0": "E7A4",
    "7EC1": "E7A5",
    "7EC2": "E7A6",
    "7EC3": "C1B7",
    "7EC4": "D7E9",
    "7EC5": "C9F0",
    "7EC6": "CFB8",
    "7EC7": "D6AF",
    "7EC8": "D6D5",
    "7EC9": "E7A7",
    "7ECA": "B0ED",
    "7ECB": "E7A8",
    "7ECC": "E7A9",
    "7ECD": "C9DC",
    "7ECE": "D2EF",
    "7ECF": "BEAD",
    "7ED0": "E7AA",
    "7ED1": "B0F3",
    "7ED2": "C8DE",
    "7ED3": "BDE1",
    "7ED4": "E7AB",
    "7ED5": "C8C6",
    "7ED7": "E7AC",
    "7ED8": "BBE6",
    "7ED9": "B8F8",
    "7EDA": "D1A4",
    "7EDB": "E7AD",
    "7EDC": "C2E7",
    "7EDD": "BEF8",
    "7EDE": "BDCA",
    "7EDF": "CDB3",
    "7EE0": "E7AE",
    "7EE1": "E7AF",
    "7EE2": "BEEE",
    "7EE3": "D0E5",
    "7EE5": "CBE7",
    "7EE6": "CCD0",
    "7EE7": "BCCC",
    "7EE8": "E7B0",
    "7EE9": "BCA8",
    "7EEA": "D0F7",
    "7EEB": "E7B1",
    "7EED": "D0F8",
    "7EEE": "E7B2",
    "7EEF": "E7B3",
    "7EF0": "B4C2",
    "7EF1": "E7B4",
    "7EF2": "E7B5",
    "7EF3": "C9FE",
    "7EF4": "CEAC",
    "7EF5": "C3E0",
    "7EF6": "E7B7",
    "7EF7": "B1C1",
    "7EF8": "B3F1",
    "7EFA": "E7B8",
    "7EFB": "E7B9",
    "7EFC": "D7DB",
    "7EFD": "D5C0",
    "7EFE": "E7BA",
    "7EFF": "C2CC",
    "7F00": "D7BA",
    "7F01": "E7BB",
    "7F02": "E7BC",
    "7F03": "E7BD",
    "7F04": "BCEA",
    "7F05": "C3E5",
    "7F06": "C0C2",
    "7F07": "E7BE",
    "7F08": "E7BF",
    "7F09": "BCA9",
    "7F0B": "E7C0",
    "7F0C": "E7C1",
    "7F0D": "E7B6",
    "7F0E": "B6D0",
    "7F0F": "E7C2",
    "7F11": "E7C3",
    "7F12": "E7C4",
    "7F13": "BBBA",
    "7F14": "B5DE",
    "7F15": "C2C6",
    "7F16": "B1E0",
    "7F17": "E7C5",
    "7F18": "D4B5",
    "7F19": "E7C6",
    "7F1A": "B8BF",
    "7F1B": "E7C8",
    "7F1C": "E7C7",
    "7F1D": "B7EC",
    "7F1F": "E7C9",
    "7F20": "B2F8",
    "7F21": "E7CA",
    "7F22": "E7CB",
    "7F23": "E7CC",
    "7F24": "E7CD",
    "7F25": "E7CE",
    "7F26": "E7CF",
    "7F27": "E7D0",
    "7F28": "D3A7",
    "7F29": "CBF5",
    "7F2A": "E7D1",
    "7F2B": "E7D2",
    "7F2C": "E7D3",
    "7F2D": "E7D4",
    "7F2E": "C9C9",
    "7F2F": "E7D5",
    "7F30": "E7D6",
    "7F31": "E7D7",
    "7F32": "E7D8",
    "7F33": "E7D9",
    "7F34": "BDC9",
    "7F35": "E7DA",
    "7F36": "F3BE",
    "7F38": "B8D7",
    "7F3A": "C8B1",
    "7F42": "F3BF",
    "7F44": "F3C0",
    "7F45": "F3C1",
    "7F50": "B9DE",
    "7F51": "CDF8",
    "7F54": "D8E8",
    "7F55": "BAB1",
    "7F57": "C2DE",
    "7F58": "EEB7",
    "7F5A": "B7A3",
    "7F5F": "EEB9",
    "7F61": "EEB8",
    "7F62": "B0D5",
    "7F68": "EEBB",
    "7F69": "D5D6",
    "7F6A": "D7EF",
    "7F6E": "D6C3",
    "7F71": "EEBD",
    "7F72": "CAF0",
    "7F74": "EEBC",
    "7F79": "EEBE",
    "7F7E": "EEC0",
    "7F81": "EEBF",
    "7F8A": "D1F2",
    "7F8C": "C7BC",
    "7F8E": "C3C0",
    "7F94": "B8E1",
    "7F9A": "C1E7",
    "7F9D": "F4C6",
    "7F9E": "D0DF",
    "7F9F": "F4C7",
    "7FA1": "CFDB",
    "7FA4": "C8BA",
    "7FA7": "F4C8",
    "7FAF": "F4C9",
    "7FB0": "F4CA",
    "7FB2": "F4CB",
    "7FB8": "D9FA",
    "7FB9": "B8FE",
    "7FBC": "E5F1",
    "7FBD": "D3F0",
    "7FBF": "F4E0",
    "7FC1": "CECC",
    "7FC5": "B3E1",
    "7FCA": "F1B4",
    "7FCC": "D2EE",
    "7FCE": "F4E1",
    "7FD4": "CFE8",
    "7FD5": "F4E2",
    "7FD8": "C7CC",
    "7FDF": "B5D4",
    "7FE0": "B4E4",
    "7FE1": "F4E4",
    "7FE5": "F4E3",
    "7FE6": "F4E5",
    "7FE9": "F4E6",
    "7FEE": "F4E7",
    "7FF0": "BAB2",
    "7FF1": "B0BF",
    "7FF3": "F4E8",
    "7FFB": "B7AD",
    "7FFC": "D2ED",
    "8000": "D2AB",
    "8001": "C0CF",
    "8003": "BFBC",
    "8004": "EBA3",
    "8005": "D5DF",
    "8006": "EAC8",
    "800B": "F1F3",
    "800C": "B6F8",
    "800D": "CBA3",
    "8010": "C4CD",
    "8012": "F1E7",
    "8014": "F1E8",
    "8015": "B8FB",
    "8016": "F1E9",
    "8017": "BAC4",
    "8018": "D4C5",
    "8019": "B0D2",
    "801C": "F1EA",
    "8020": "F1EB",
    "8022": "F1EC",
    "8025": "F1ED",
    "8026": "F1EE",
    "8027": "F1EF",
    "8028": "F1F1",
    "8029": "F1F0",
    "802A": "C5D5",
    "8031": "F1F2",
    "8033": "B6FA",
    "8035": "F1F4",
    "8036": "D2AE",
    "8037": "DEC7",
    "8038": "CBCA",
    "803B": "B3DC",
    "803D": "B5A2",
    "803F": "B9A2",
    "8042": "C4F4",
    "8043": "F1F5",
    "8046": "F1F6",
    "804A": "C1C4",
    "804B": "C1FB",
    "804C": "D6B0",
    "804D": "F1F7",
    "8052": "F1F8",
    "8054": "C1AA",
    "8058": "C6B8",
    "805A": "BEDB",
    "8069": "F1F9",
    "806A": "B4CF",
    "8071": "F1FA",
    "807F": "EDB2",
    "8080": "EDB1",
    "8083": "CBE0",
    "8084": "D2DE",
    "8086": "CBC1",
    "8087": "D5D8",
    "8089": "C8E2",
    "808B": "C0DF",
    "808C": "BCA1",
    "8093": "EBC1",
    "8096": "D0A4",
    "8098": "D6E2",
    "809A": "B6C7",
    "809B": "B8D8",
    "809C": "EBC0",
    "809D": "B8CE",
    "809F": "EBBF",
    "80A0": "B3A6",
    "80A1": "B9C9",
    "80A2": "D6AB",
    "80A4": "B7F4",
    "80A5": "B7CA",
    "80A9": "BCE7",
    "80AA": "B7BE",
    "80AB": "EBC6",
    "80AD": "EBC7",
    "80AE": "B0B9",
    "80AF": "BFCF",
    "80B1": "EBC5",
    "80B2": "D3FD",
    "80B4": "EBC8",
    "80B7": "EBC9",
    "80BA": "B7CE",
    "80BC": "EBC2",
    "80BD": "EBC4",
    "80BE": "C9F6",
    "80BF": "D6D7",
    "80C0": "D5CD",
    "80C1": "D0B2",
    "80C2": "EBCF",
    "80C3": "CEB8",
    "80C4": "EBD0",
    "80C6": "B5A8",
    "80CC": "B1B3",
    "80CD": "EBD2",
    "80CE": "CCA5",
    "80D6": "C5D6",
    "80D7": "EBD3",
    "80D9": "EBD1",
    "80DA": "C5DF",
    "80DB": "EBCE",
    "80DC": "CAA4",
    "80DD": "EBD5",
    "80DE": "B0FB",
    "80E1": "BAFA",
    "80E4": "D8B7",
    "80E5": "F1E3",
    "80E7": "EBCA",
    "80E8": "EBCB",
    "80E9": "EBCC",
    "80EA": "EBCD",
    "80EB": "EBD6",
    "80EC": "E6C0",
    "80ED": "EBD9",
    "80EF": "BFE8",
    "80F0": "D2C8",
    "80F1": "EBD7",
    "80F2": "EBDC",
    "80F3": "B8EC",
    "80F4": "EBD8",
    "80F6": "BDBA",
    "80F8": "D0D8",
    "80FA": "B0B7",
    "80FC": "EBDD",
    "80FD": "C4DC",
    "8102": "D6AC",
    "8106": "B4E0",
    "8109": "C2F6",
    "810A": "BCB9",
    "810D": "EBDA",
    "810E": "EBDB",
    "810F": "D4E0",
    "8110": "C6EA",
    "8111": "C4D4",
    "8112": "EBDF",
    "8113": "C5A7",
    "8114": "D9F5",
    "8116": "B2B1",
    "8118": "EBE4",
    "811A": "BDC5",
    "811E": "EBE2",
    "812C": "EBE3",
    "812F": "B8AC",
    "8131": "CDD1",
    "8132": "EBE5",
    "8136": "EBE1",
    "8138": "C1B3",
    "813E": "C6A2",
    "8146": "CCF3",
    "8148": "EBE6",
    "814A": "C0B0",
    "814B": "D2B8",
    "814C": "EBE7",
    "8150": "B8AF",
    "8151": "B8AD",
    "8153": "EBE8",
    "8154": "C7BB",
    "8155": "CDF3",
    "8159": "EBEA",
    "815A": "EBEB",
    "8160": "EBED",
    "8165": "D0C8",
    "8167": "EBF2",
    "8169": "EBEE",
    "816D": "EBF1",
    "816E": "C8F9",
    "8170": "D1FC",
    "8171": "EBEC",
    "8174": "EBE9",
    "8179": "B8B9",
    "817A": "CFD9",
    "817B": "C4E5",
    "817C": "EBEF",
    "817D": "EBF0",
    "817E": "CCDA",
    "817F": "CDC8",
    "8180": "B0F2",
    "8182": "EBF6",
    "8188": "EBF5",
    "818A": "B2B2",
    "818F": "B8E0",
    "8191": "EBF7",
    "8198": "B1EC",
    "819B": "CCC5",
    "819C": "C4A4",
    "819D": "CFA5",
    "81A3": "EBF9",
    "81A6": "ECA2",
    "81A8": "C5F2",
    "81AA": "EBFA",
    "81B3": "C9C5",
    "81BA": "E2DF",
    "81BB": "EBFE",
    "81C0": "CDCE",
    "81C1": "ECA1",
    "81C2": "B1DB",
    "81C3": "D3B7",
    "81C6": "D2DC",
    "81CA": "EBFD",
    "81CC": "EBFB",
    "81E3": "B3BC",
    "81E7": "EAB0",
    "81EA": "D7D4",
    "81EC": "F4AB",
    "81ED": "B3F4",
    "81F3": "D6C1",
    "81F4": "D6C2",
    "81FB": "D5E9",
    "81FC": "BECA",
    "81FE": "F4A7",
    "8200": "D2A8",
    "8201": "F4A8",
    "8202": "F4A9",
    "8204": "F4AA",
    "8205": "BECB",
    "8206": "D3DF",
    "820C": "C9E0",
    "820D": "C9E1",
    "8210": "F3C2",
    "8212": "CAE6",
    "8214": "CCF2",
    "821B": "E2B6",
    "821C": "CBB4",
    "821E": "CEE8",
    "821F": "D6DB",
    "8221": "F4AD",
    "8222": "F4AE",
    "8223": "F4AF",
    "8228": "F4B2",
    "822A": "BABD",
    "822B": "F4B3",
    "822C": "B0E3",
    "822D": "F4B0",
    "822F": "F4B1",
    "8230": "BDA2",
    "8231": "B2D5",
    "8233": "F4B6",
    "8234": "F4B7",
    "8235": "B6E6",
    "8236": "B2B0",
    "8237": "CFCF",
    "8238": "F4B4",
    "8239": "B4AC",
    "823B": "F4B5",
    "823E": "F4B8",
    "8244": "F4B9",
    "8247": "CDA7",
    "8249": "F4BA",
    "824B": "F4BB",
    "824F": "F4BC",
    "8258": "CBD2",
    "825A": "F4BD",
    "825F": "F4BE",
    "8268": "F4BF",
    "826E": "F4DE",
    "826F": "C1BC",
    "8270": "BCE8",
    "8272": "C9AB",
    "8273": "D1DE",
    "8274": "E5F5",
    "8279": "DCB3",
    "827A": "D2D5",
    "827D": "DCB4",
    "827E": "B0AC",
    "827F": "DCB5",
    "8282": "BDDA",
    "8284": "DCB9",
    "8288": "D8C2",
    "828A": "DCB7",
    "828B": "D3F3",
    "828D": "C9D6",
    "828E": "DCBA",
    "828F": "DCB6",
    "8291": "DCBB",
    "8292": "C3A2",
    "8297": "DCBC",
    "8298": "DCC5",
    "8299": "DCBD",
    "829C": "CEDF",
    "829D": "D6A5",
    "829F": "DCCF",
    "82A1": "DCCD",
    "82A4": "DCD2",
    "82A5": "BDE6",
    "82A6": "C2AB",
    "82A8": "DCB8",
    "82A9": "DCCB",
    "82AA": "DCCE",
    "82AB": "DCBE",
    "82AC": "B7D2",
    "82AD": "B0C5",
    "82AE": "DCC7",
    "82AF": "D0BE",
    "82B0": "DCC1",
    "82B1": "BBA8",
    "82B3": "B7BC",
    "82B4": "DCCC",
    "82B7": "DCC6",
    "82B8": "DCBF",
    "82B9": "C7DB",
    "82BD": "D1BF",
    "82BE": "DCC0",
    "82C1": "DCCA",
    "82C4": "DCD0",
    "82C7": "CEAD",
    "82C8": "DCC2",
    "82CA": "DCC3",
    "82CB": "DCC8",
    "82CC": "DCC9",
    "82CD": "B2D4",
    "82CE": "DCD1",
    "82CF": "CBD5",
    "82D1": "D4B7",
    "82D2": "DCDB",
    "82D3": "DCDF",
    "82D4": "CCA6",
    "82D5": "DCE6",
    "82D7": "C3E7",
    "82D8": "DCDC",
    "82DB": "BFC1",
    "82DC": "DCD9",
    "82DE": "B0FA",
    "82DF": "B9B6",
    "82E0": "DCE5",
    "82E1": "DCD3",
    "82E3": "DCC4",
    "82E4": "DCD6",
    "82E5": "C8F4",
    "82E6": "BFE0",
    "82EB": "C9BB",
    "82EF": "B1BD",
    "82F1": "D3A2",
    "82F4": "DCDA",
    "82F7": "DCD5",
    "82F9": "C6BB",
    "82FB": "DCDE",
    "8301": "D7C2",
    "8302": "C3AF",
    "8303": "B7B6",
    "8304": "C7D1",
    "8305": "C3A9",
    "8306": "DCE2",
    "8307": "DCD8",
    "8308": "DCEB",
    "8309": "DCD4",
    "830C": "DCDD",
    "830E": "BEA5",
    "830F": "DCD7",
    "8311": "DCE0",
    "8314": "DCE3",
    "8315": "DCE4",
    "8317": "DCF8",
    "831A": "DCE1",
    "831B": "DDA2",
    "831C": "DCE7",
    "8327": "BCEB",
    "8328": "B4C4",
    "832B": "C3A3",
    "832C": "B2E7",
    "832D": "DCFA",
    "832F": "DCF2",
    "8331": "DCEF",
    "8333": "DCFC",
    "8334": "DCEE",
    "8335": "D2F0",
    "8336": "B2E8",
    "8338": "C8D7",
    "8339": "C8E3",
    "833A": "DCFB",
    "833C": "DCED",
    "8340": "DCF7",
    "8343": "DCF5",
    "8346": "BEA3",
    "8347": "DCF4",
    "8349": "B2DD",
    "834F": "DCF3",
    "8350": "BCF6",
    "8351": "DCE8",
    "8352": "BBC4",
    "8354": "C0F3",
    "835A": "BCD4",
    "835B": "DCE9",
    "835C": "DCEA",
    "835E": "DCF1",
    "835F": "DCF6",
    "8360": "DCF9",
    "8361": "B5B4",
    "8363": "C8D9",
    "8364": "BBE7",
    "8365": "DCFE",
    "8366": "DCFD",
    "8367": "D3AB",
    "8368": "DDA1",
    "8369": "DDA3",
    "836A": "DDA5",
    "836B": "D2F1",
    "836C": "DDA4",
    "836D": "DDA6",
    "836E": "DDA7",
    "836F": "D2A9",
    "8377": "BAC9",
    "8378": "DDA9",
    "837B": "DDB6",
    "837C": "DDB1",
    "837D": "DDB4",
    "8385": "DDB0",
    "8386": "C6CE",
    "8389": "C0F2",
    "838E": "C9AF",
    "8392": "DCEC",
    "8393": "DDAE",
    "8398": "DDB7",
    "839B": "DCF0",
    "839C": "DDAF",
    "839E": "DDB8",
    "83A0": "DDAC",
    "83A8": "DDB9",
    "83A9": "DDB3",
    "83AA": "DDAD",
    "83AB": "C4AA",
    "83B0": "DDA8",
    "83B1": "C0B3",
    "83B2": "C1AB",
    "83B3": "DDAA",
    "83B4": "DDAB",
    "83B6": "DDB2",
    "83B7": "BBF1",
    "83B8": "DDB5",
    "83B9": "D3A8",
    "83BA": "DDBA",
    "83BC": "DDBB",
    "83BD": "C3A7",
    "83C0": "DDD2",
    "83C1": "DDBC",
    "83C5": "DDD1",
    "83C7": "B9BD",
    "83CA": "BED5",
    "83CC": "BEFA",
    "83CF": "BACA",
    "83D4": "DDCA",
    "83D6": "DDC5",
    "83D8": "DDBF",
    "83DC": "B2CB",
    "83DD": "DDC3",
    "83DF": "DDCB",
    "83E0": "B2A4",
    "83E1": "DDD5",
    "83E5": "DDBE",
    "83E9": "C6D0",
    "83EA": "DDD0",
    "83F0": "DDD4",
    "83F1": "C1E2",
    "83F2": "B7C6",
    "83F8": "DDCE",
    "83F9": "DDCF",
    "83FD": "DDC4",
    "8401": "DDBD",
    "8403": "DDCD",
    "8404": "CCD1",
    "8406": "DDC9",
    "840B": "DDC2",
    "840C": "C3C8",
    "840D": "C6BC",
    "840E": "CEAE",
    "840F": "DDCC",
    "8411": "DDC8",
    "8418": "DDC1",
    "841C": "DDC6",
    "841D": "C2DC",
    "8424": "D3A9",
    "8425": "D3AA",
    "8426": "DDD3",
    "8427": "CFF4",
    "8428": "C8F8",
    "8431": "DDE6",
    "8438": "DDC7",
    "843C": "DDE0",
    "843D": "C2E4",
    "8446": "DDE1",
    "8451": "DDD7",
    "8457": "D6F8",
    "8459": "DDD9",
    "845A": "DDD8",
    "845B": "B8F0",
    "845C": "DDD6",
    "8461": "C6CF",
    "8463": "B6AD",
    "8469": "DDE2",
    "846B": "BAF9",
    "846C": "D4E1",
    "846D": "DDE7",
    "8471": "B4D0",
    "8473": "DDDA",
    "8475": "BFFB",
    "8476": "DDE3",
    "8478": "DDDF",
    "847A": "DDDD",
    "8482": "B5D9",
    "8487": "DDDB",
    "8488": "DDDC",
    "8489": "DDDE",
    "848B": "BDAF",
    "848C": "DDE4",
    "848E": "DDE5",
    "8497": "DDF5",
    "8499": "C3C9",
    "849C": "CBE2",
    "84A1": "DDF2",
    "84AF": "D8E1",
    "84B2": "C6D1",
    "84B4": "DDF4",
    "84B8": "D5F4",
    "84B9": "DDF3",
    "84BA": "DDF0",
    "84BD": "DDEC",
    "84BF": "DDEF",
    "84C1": "DDE8",
    "84C4": "D0EE",
    "84C9": "C8D8",
    "84CA": "DDEE",
    "84CD": "DDE9",
    "84D0": "DDEA",
    "84D1": "CBF2",
    "84D3": "DDED",
    "84D6": "B1CD",
    "84DD": "C0B6",
    "84DF": "BCBB",
    "84E0": "DDF1",
    "84E3": "DDF7",
    "84E5": "DDF6",
    "84E6": "DDEB",
    "84EC": "C5EE",
    "84F0": "DDFB",
    "84FC": "DEA4",
    "84FF": "DEA3",
    "850C": "DDF8",
    "8511": "C3EF",
    "8513": "C2FB",
    "8517": "D5E1",
    "851A": "CEB5",
    "851F": "DDFD",
    "8521": "B2CC",
    "852B": "C4E8",
    "852C": "CADF",
    "8537": "C7BE",
    "8538": "DDFA",
    "8539": "DDFC",
    "853A": "DDFE",
    "853B": "DEA2",
    "853C": "B0AA",
    "853D": "B1CE",
    "8543": "DEAC",
    "8548": "DEA6",
    "8549": "BDB6",
    "854A": "C8EF",
    "8556": "DEA1",
    "8559": "DEA5",
    "855E": "DEA9",
    "8564": "DEA8",
    "8568": "DEA7",
    "8572": "DEAD",
    "8574": "D4CC",
    "8579": "DEB3",
    "857A": "DEAA",
    "857B": "DEAE",
    "857E": "C0D9",
    "8584": "B1A1",
    "8585": "DEB6",
    "8587": "DEB1",
    "858F": "DEB2",
    "859B": "D1A6",
    "859C": "DEB5",
    "85A4": "DEAF",
    "85A8": "DEB0",
    "85AA": "D0BD",
    "85AE": "DEB4",
    "85AF": "CAED",
    "85B0": "DEB9",
    "85B7": "DEB8",
    "85B9": "DEB7",
    "85C1": "DEBB",
    "85C9": "BDE5",
    "85CF": "B2D8",
    "85D0": "C3EA",
    "85D3": "DEBA",
    "85D5": "C5BA",
    "85DC": "DEBC",
    "85E4": "CCD9",
    "85E9": "B7AA",
    "85FB": "D4E5",
    "85FF": "DEBD",
    "8605": "DEBF",
    "8611": "C4A2",
    "8616": "DEC1",
    "8627": "DEBE",
    "8629": "DEC0",
    "8638": "D5BA",
    "863C": "DEC2",
    "864D": "F2AE",
    "864E": "BBA2",
    "864F": "C2B2",
    "8650": "C5B0",
    "8651": "C2C7",
    "8654": "F2AF",
    "865A": "D0E9",
    "865E": "D3DD",
    "8662": "EBBD",
    "866B": "B3E6",
    "866C": "F2B0",
    "866E": "F2B1",
    "8671": "CAAD",
    "8679": "BAE7",
    "867A": "F2B3",
    "867B": "F2B5",
    "867C": "F2B4",
    "867D": "CBE4",
    "867E": "CFBA",
    "867F": "F2B2",
    "8680": "CAB4",
    "8681": "D2CF",
    "8682": "C2EC",
    "868A": "CEC3",
    "868B": "F2B8",
    "868C": "B0F6",
    "868D": "F2B7",
    "8693": "F2BE",
    "8695": "B2CF",
    "869C": "D1C1",
    "869D": "F2BA",
    "86A3": "F2BC",
    "86A4": "D4E9",
    "86A7": "F2BB",
    "86A8": "F2B6",
    "86A9": "F2BF",
    "86AA": "F2BD",
    "86AC": "F2B9",
    "86AF": "F2C7",
    "86B0": "F2C4",
    "86B1": "F2C6",
    "86B4": "F2CA",
    "86B5": "F2C2",
    "86B6": "F2C0",
    "86BA": "F2C5",
    "86C0": "D6FB",
    "86C4": "F2C1",
    "86C6": "C7F9",
    "86C7": "C9DF",
    "86C9": "F2C8",
    "86CA": "B9C6",
    "86CB": "B5B0",
    "86CE": "F2C3",
    "86CF": "F2C9",
    "86D0": "F2D0",
    "86D1": "F2D6",
    "86D4": "BBD7",
    "86D8": "F2D5",
    "86D9": "CDDC",
    "86DB": "D6EB",
    "86DE": "F2D2",
    "86DF": "F2D4",
    "86E4": "B8F2",
    "86E9": "F2CB",
    "86ED": "F2CE",
    "86EE": "C2F9",
    "86F0": "D5DD",
    "86F1": "F2CC",
    "86F2": "F2CD",
    "86F3": "F2CF",
    "86F4": "F2D3",
    "86F8": "F2D9",
    "86F9": "D3BC",
    "86FE": "B6EA",
    "8700": "CAF1",
    "8702": "B7E4",
    "8703": "F2D7",
    "8707": "F2D8",
    "8708": "F2DA",
    "8709": "F2DD",
    "870A": "F2DB",
    "870D": "F2DC",
    "8712": "D1D1",
    "8713": "F2D1",
    "8715": "CDC9",
    "8717": "CECF",
    "8718": "D6A9",
    "871A": "F2E3",
    "871C": "C3DB",
    "871E": "F2E0",
    "8721": "C0AF",
    "8722": "F2EC",
    "8723": "F2DE",
    "8725": "F2E1",
    "8729": "F2E8",
    "872E": "F2E2",
    "8731": "F2E7",
    "8734": "F2E6",
    "8737": "F2E9",
    "873B": "F2DF",
    "873E": "F2E4",
    "873F": "F2EA",
    "8747": "D3AC",
    "8748": "F2E5",
    "8749": "B2F5",
    "874C": "F2F2",
    "874E": "D0AB",
    "8753": "F2F5",
    "8757": "BBC8",
    "8759": "F2F9",
    "8760": "F2F0",
    "8763": "F2F6",
    "8764": "F2F8",
    "8765": "F2FA",
    "876E": "F2F3",
    "8770": "F2F1",
    "8774": "BAFB",
    "8776": "B5FB",
    "877B": "F2EF",
    "877C": "F2F7",
    "877D": "F2ED",
    "877E": "F2EE",
    "8782": "F2EB",
    "8783": "F3A6",
    "8785": "F3A3",
    "8788": "F3A2",
    "878B": "F2F4",
    "878D": "C8DA",
    "8793": "F2FB",
    "8797": "F3A5",
    "879F": "C3F8",
    "87A8": "F2FD",
    "87AB": "F3A7",
    "87AC": "F3A9",
    "87AD": "F3A4",
    "87AF": "F2FC",
    "87B3": "F3AB",
    "87B5": "F3AA",
    "87BA": "C2DD",
    "87BD": "F3AE",
    "87C0": "F3B0",
    "87C6": "F3A1",
    "87CA": "F3B1",
    "87CB": "F3AC",
    "87D1": "F3AF",
    "87D2": "F2FE",
    "87D3": "F3AD",
    "87DB": "F3B2",
    "87E0": "F3B4",
    "87E5": "F3A8",
    "87EA": "F3B3",
    "87EE": "F3B5",
    "87F9": "D0B7",
    "87FE": "F3B8",
    "8803": "D9F9",
    "880A": "F3B9",
    "8813": "F3B7",
    "8815": "C8E4",
    "8816": "F3B6",
    "881B": "F3BA",
    "8821": "F3BB",
    "8822": "B4C0",
    "8832": "EEC3",
    "8839": "F3BC",
    "883C": "F3BD",
    "8840": "D1AA",
    "8844": "F4AC",
    "8845": "D0C6",
    "884C": "D0D0",
    "884D": "D1DC",
    "8854": "CFCE",
    "8857": "BDD6",
    "8859": "D1C3",
    "8861": "BAE2",
    "8862": "E1E9",
    "8863": "D2C2",
    "8864": "F1C2",
    "8865": "B2B9",
    "8868": "B1ED",
    "8869": "F1C3",
    "886B": "C9C0",
    "886C": "B3C4",
    "886E": "D9F2",
    "8870": "CBA5",
    "8872": "F1C4",
    "8877": "D6D4",
    "887D": "F1C5",
    "887E": "F4C0",
    "887F": "F1C6",
    "8881": "D4AC",
    "8882": "F1C7",
    "8884": "B0C0",
    "8885": "F4C1",
    "8888": "F4C2",
    "888B": "B4FC",
    "888D": "C5DB",
    "8892": "CCBB",
    "8896": "D0E4",
    "889C": "CDE0",
    "88A2": "F1C8",
    "88A4": "D9F3",
    "88AB": "B1BB",
    "88AD": "CFAE",
    "88B1": "B8A4",
    "88B7": "F1CA",
    "88BC": "F1CB",
    "88C1": "B2C3",
    "88C2": "C1D1",
    "88C5": "D7B0",
    "88C6": "F1C9",
    "88C9": "F1CC",
    "88CE": "F1CE",
    "88D2": "D9F6",
    "88D4": "D2E1",
    "88D5": "D4A3",
    "88D8": "F4C3",
    "88D9": "C8B9",
    "88DF": "F4C4",
    "88E2": "F1CD",
    "88E3": "F1CF",
    "88E4": "BFE3",
    "88E5": "F1D0",
    "88E8": "F1D4",
    "88F0": "F1D6",
    "88F1": "F1D1",
    "88F3": "C9D1",
    "88F4": "C5E1",
    "88F8": "C2E3",
    "88F9": "B9FC",
    "88FC": "F1D3",
    "88FE": "F1D5",
    "8902": "B9D3",
    "890A": "F1DB",
    "8910": "BAD6",
    "8912": "B0FD",
    "8913": "F1D9",
    "8919": "F1D8",
    "891A": "F1D2",
    "891B": "F1DA",
    "8921": "F1D7",
    "8925": "C8EC",
    "892A": "CDCA",
    "892B": "F1DD",
    "8930": "E5BD",
    "8934": "F1DC",
    "8936": "F1DE",
    "8941": "F1DF",
    "8944": "CFE5",
    "895E": "F4C5",
    "895F": "BDF3",
    "8966": "F1E0",
    "897B": "F1E1",
    "897F": "CEF7",
    "8981": "D2AA",
    "8983": "F1FB",
    "8986": "B8B2",
    "89C1": "BCFB",
    "89C2": "B9DB",
    "89C4": "B9E6",
    "89C5": "C3D9",
    "89C6": "CAD3",
    "89C7": "EAE8",
    "89C8": "C0C0",
    "89C9": "BEF5",
    "89CA": "EAE9",
    "89CB": "EAEA",
    "89CC": "EAEB",
    "89CE": "EAEC",
    "89CF": "EAED",
    "89D0": "EAEE",
    "89D1": "EAEF",
    "89D2": "BDC7",
    "89D6": "F5FB",
    "89DA": "F5FD",
    "89DC": "F5FE",
    "89DE": "F5FC",
    "89E3": "BDE2",
    "89E5": "F6A1",
    "89E6": "B4A5",
    "89EB": "F6A2",
    "89EF": "F6A3",
    "89F3": "ECB2",
    "8A00": "D1D4",
    "8A07": "D9EA",
    "8A3E": "F6A4",
    "8A48": "EEBA",
    "8A79": "D5B2",
    "8A89": "D3FE",
    "8A8A": "CCDC",
    "8A93": "CAC4",
    "8B07": "E5C0",
    "8B26": "F6A5",
    "8B66": "BEAF",
    "8B6C": "C6A9",
    "8BA0": "DAA5",
    "8BA1": "BCC6",
    "8BA2": "B6A9",
    "8BA3": "B8BC",
    "8BA4": "C8CF",
    "8BA5": "BCA5",
    "8BA6": "DAA6",
    "8BA7": "DAA7",
    "8BA8": "CCD6",
    "8BA9": "C8C3",
    "8BAA": "DAA8",
    "8BAB": "C6FD",
    "8BAD": "D1B5",
    "8BAE": "D2E9",
    "8BAF": "D1B6",
    "8BB0": "BCC7",
    "8BB2": "BDB2",
    "8BB3": "BBE4",
    "8BB4": "DAA9",
    "8BB5": "DAAA",
    "8BB6": "D1C8",
    "8BB7": "DAAB",
    "8BB8": "D0ED",
    "8BB9": "B6EF",
    "8BBA": "C2DB",
    "8BBC": "CBCF",
    "8BBD": "B7ED",
    "8BBE": "C9E8",
    "8BBF": "B7C3",
    "8BC0": "BEF7",
    "8BC1": "D6A4",
    "8BC2": "DAAC",
    "8BC3": "DAAD",
    "8BC4": "C6C0",
    "8BC5": "D7E7",
    "8BC6": "CAB6",
    "8BC8": "D5A9",
    "8BC9": "CBDF",
    "8BCA": "D5EF",
    "8BCB": "DAAE",
    "8BCC": "D6DF",
    "8BCD": "B4CA",
    "8BCE": "DAB0",
    "8BCF": "DAAF",
    "8BD1": "D2EB",
    "8BD2": "DAB1",
    "8BD3": "DAB2",
    "8BD4": "DAB3",
    "8BD5": "CAD4",
    "8BD6": "DAB4",
    "8BD7": "CAAB",
    "8BD8": "DAB5",
    "8BD9": "DAB6",
    "8BDA": "B3CF",
    "8BDB": "D6EF",
    "8BDC": "DAB7",
    "8BDD": "BBB0",
    "8BDE": "B5AE",
    "8BDF": "DAB8",
    "8BE0": "DAB9",
    "8BE1": "B9EE",
    "8BE2": "D1AF",
    "8BE3": "D2E8",
    "8BE4": "DABA",
    "8BE5": "B8C3",
    "8BE6": "CFEA",
    "8BE7": "B2EF",
    "8BE8": "DABB",
    "8BE9": "DABC",
    "8BEB": "BDEB",
    "8BEC": "CEDC",
    "8BED": "D3EF",
    "8BEE": "DABD",
    "8BEF": "CEF3",
    "8BF0": "DABE",
    "8BF1": "D3D5",
    "8BF2": "BBE5",
    "8BF3": "DABF",
    "8BF4": "CBB5",
    "8BF5": "CBD0",
    "8BF6": "DAC0",
    "8BF7": "C7EB",
    "8BF8": "D6EE",
    "8BF9": "DAC1",
    "8BFA": "C5B5",
    "8BFB": "B6C1",
    "8BFC": "DAC2",
    "8BFD": "B7CC",
    "8BFE": "BFCE",
    "8BFF": "DAC3",
    "8C00": "DAC4",
    "8C01": "CBAD",
    "8C02": "DAC5",
    "8C03": "B5F7",
    "8C04": "DAC6",
    "8C05": "C1C2",
    "8C06": "D7BB",
    "8C07": "DAC7",
    "8C08": "CCB8",
    "8C0A": "D2EA",
    "8C0B": "C4B1",
    "8C0C": "DAC8",
    "8C0D": "B5FD",
    "8C0E": "BBD1",
    "8C0F": "DAC9",
    "8C10": "D0B3",
    "8C11": "DACA",
    "8C12": "DACB",
    "8C13": "CEBD",
    "8C14": "DACC",
    "8C15": "DACD",
    "8C16": "DACE",
    "8C17": "B2F7",
    "8C18": "DAD1",
    "8C19": "DACF",
    "8C1A": "D1E8",
    "8C1B": "DAD0",
    "8C1C": "C3D5",
    "8C1D": "DAD2",
    "8C1F": "DAD3",
    "8C20": "DAD4",
    "8C21": "DAD5",
    "8C22": "D0BB",
    "8C23": "D2A5",
    "8C24": "B0F9",
    "8C25": "DAD6",
    "8C26": "C7AB",
    "8C27": "DAD7",
    "8C28": "BDF7",
    "8C29": "C3A1",
    "8C2A": "DAD8",
    "8C2B": "DAD9",
    "8C2C": "C3FD",
    "8C2D": "CCB7",
    "8C2E": "DADA",
    "8C2F": "DADB",
    "8C30": "C0BE",
    "8C31": "C6D7",
    "8C32": "DADC",
    "8C33": "DADD",
    "8C34": "C7B4",
    "8C35": "DADE",
    "8C36": "DADF",
    "8C37": "B9C8",
    "8C41": "BBED",
    "8C46": "B6B9",
    "8C47": "F4F8",
    "8C49": "F4F9",
    "8C4C": "CDE3",
    "8C55": "F5B9",
    "8C5A": "EBE0",
    "8C61": "CFF3",
    "8C62": "BBBF",
    "8C6A": "BAC0",
    "8C6B": "D4A5",
    "8C73": "E1D9",
    "8C78": "F5F4",
    "8C79": "B1AA",
    "8C7A": "B2F2",
    "8C82": "F5F5",
    "8C85": "F5F7",
    "8C89": "BAD1",
    "8C8A": "F5F6",
    "8C8C": "C3B2",
    "8C94": "F5F9",
    "8C98": "F5F8",
    "8D1D": "B1B4",
    "8D1E": "D5EA",
    "8D1F": "B8BA",
    "8D21": "B9B1",
    "8D22": "B2C6",
    "8D23": "D4F0",
    "8D24": "CFCD",
    "8D25": "B0DC",
    "8D26": "D5CB",
    "8D27": "BBF5",
    "8D28": "D6CA",
    "8D29": "B7B7",
    "8D2A": "CCB0",
    "8D2B": "C6B6",
    "8D2C": "B1E1",
    "8D2D": "B9BA",
    "8D2E": "D6FC",
    "8D2F": "B9E1",
    "8D30": "B7A1",
    "8D31": "BCFA",
    "8D32": "EADA",
    "8D33": "EADB",
    "8D34": "CCF9",
    "8D35": "B9F3",
    "8D36": "EADC",
    "8D37": "B4FB",
    "8D38": "C3B3",
    "8D39": "B7D1",
    "8D3A": "BAD8",
    "8D3B": "EADD",
    "8D3C": "D4F4",
    "8D3D": "EADE",
    "8D3E": "BCD6",
    "8D3F": "BBDF",
    "8D40": "EADF",
    "8D41": "C1DE",
    "8D42": "C2B8",
    "8D43": "D4DF",
    "8D44": "D7CA",
    "8D45": "EAE0",
    "8D46": "EAE1",
    "8D47": "EAE4",
    "8D48": "EAE2",
    "8D49": "EAE3",
    "8D4A": "C9DE",
    "8D4B": "B8B3",
    "8D4C": "B6C4",
    "8D4D": "EAE5",
    "8D4E": "CAEA",
    "8D4F": "C9CD",
    "8D50": "B4CD",
    "8D53": "E2D9",
    "8D54": "C5E2",
    "8D55": "EAE6",
    "8D56": "C0B5",
    "8D58": "D7B8",
    "8D59": "EAE7",
    "8D5A": "D7AC",
    "8D5B": "C8FC",
    "8D5C": "D8D3",
    "8D5D": "D8CD",
    "8D5E": "D4DE",
    "8D60": "D4F9",
    "8D61": "C9C4",
    "8D62": "D3AE",
    "8D63": "B8D3",
    "8D64": "B3E0",
    "8D66": "C9E2",
    "8D67": "F4F6",
    "8D6B": "BAD5",
    "8D6D": "F4F7",
    "8D70": "D7DF",
    "8D73": "F4F1",
    "8D74": "B8B0",
    "8D75": "D5D4",
    "8D76": "B8CF",
    "8D77": "C6F0",
    "8D81": "B3C3",
    "8D84": "F4F2",
    "8D85": "B3AC",
    "8D8A": "D4BD",
    "8D8B": "C7F7",
    "8D91": "F4F4",
    "8D94": "F4F3",
    "8D9F": "CCCB",
    "8DA3": "C8A4",
    "8DB1": "F4F5",
    "8DB3": "D7E3",
    "8DB4": "C5BF",
    "8DB5": "F5C0",
    "8DB8": "F5BB",
    "8DBA": "F5C3",
    "8DBC": "F5C2",
    "8DBE": "D6BA",
    "8DBF": "F5C1",
    "8DC3": "D4BE",
    "8DC4": "F5C4",
    "8DC6": "F5CC",
    "8DCB": "B0CF",
    "8DCC": "B5F8",
    "8DCE": "F5C9",
    "8DCF": "F5CA",
    "8DD1": "C5DC",
    "8DD6": "F5C5",
    "8DD7": "F5C6",
    "8DDA": "F5C7",
    "8DDB": "F5CB",
    "8DDD": "BEE0",
    "8DDE": "F5C8",
    "8DDF": "B8FA",
    "8DE3": "F5D0",
    "8DE4": "F5D3",
    "8DE8": "BFE7",
    "8DEA": "B9F2",
    "8DEB": "F5BC",
    "8DEC": "F5CD",
    "8DEF": "C2B7",
    "8DF3": "CCF8",
    "8DF5": "BCF9",
    "8DF7": "F5CE",
    "8DF8": "F5CF",
    "8DF9": "F5D1",
    "8DFA": "B6E5",
    "8DFB": "F5D2",
    "8DFD": "F5D5",
    "8E05": "F5BD",
    "8E09": "F5D4",
    "8E0A": "D3BB",
    "8E0C": "B3EC",
    "8E0F": "CCA4",
    "8E14": "F5D6",
    "8E1D": "F5D7",
    "8E1E": "BEE1",
    "8E1F": "F5D8",
    "8E22": "CCDF",
    "8E23": "F5DB",
    "8E29": "B2C8",
    "8E2A": "D7D9",
    "8E2C": "F5D9",
    "8E2E": "F5DA",
    "8E2F": "F5DC",
    "8E31": "F5E2",
    "8E35": "F5E0",
    "8E39": "F5DF",
    "8E3A": "F5DD",
    "8E3D": "F5E1",
    "8E40": "F5DE",
    "8E41": "F5E4",
    "8E42": "F5E5",
    "8E44": "CCE3",
    "8E47": "E5BF",
    "8E48": "B5B8",
    "8E49": "F5E3",
    "8E4A": "F5E8",
    "8E4B": "CCA3",
    "8E51": "F5E6",
    "8E52": "F5E7",
    "8E59": "F5BE",
    "8E66": "B1C4",
    "8E69": "F5BF",
    "8E6C": "B5C5",
    "8E6D": "B2E4",
    "8E6F": "F5EC",
    "8E70": "F5E9",
    "8E72": "B6D7",
    "8E74": "F5ED",
    "8E76": "F5EA",
    "8E7C": "F5EB",
    "8E7F": "B4DA",
    "8E81": "D4EA",
    "8E85": "F5EE",
    "8E87": "B3F9",
    "8E8F": "F5EF",
    "8E90": "F5F1",
    "8E94": "F5F0",
    "8E9C": "F5F2",
    "8E9E": "F5F3",
    "8EAB": "C9ED",
    "8EAC": "B9AA",
    "8EAF": "C7FB",
    "8EB2": "B6E3",
    "8EBA": "CCC9",
    "8ECE": "EAA6",
    "8F66": "B3B5",
    "8F67": "D4FE",
    "8F68": "B9EC",
    "8F69": "D0F9",
    "8F6B": "E9ED",
    "8F6C": "D7AA",
    "8F6D": "E9EE",
    "8F6E": "C2D6",
    "8F6F": "C8ED",
    "8F70": "BAE4",
    "8F71": "E9EF",
    "8F72": "E9F0",
    "8F73": "E9F1",
    "8F74": "D6E1",
    "8F75": "E9F2",
    "8F76": "E9F3",
    "8F77": "E9F5",
    "8F78": "E9F4",
    "8F79": "E9F6",
    "8F7A": "E9F7",
    "8F7B": "C7E1",
    "8F7C": "E9F8",
    "8F7D": "D4D8",
    "8F7E": "E9F9",
    "8F7F": "BDCE",
    "8F81": "E9FA",
    "8F82": "E9FB",
    "8F83": "BDCF",
    "8F84": "E9FC",
    "8F85": "B8A8",
    "8F86": "C1BE",
    "8F87": "E9FD",
    "8F88": "B1B2",
    "8F89": "BBD4",
    "8F8A": "B9F5",
    "8F8B": "E9FE",
    "8F8D": "EAA1",
    "8F8E": "EAA2",
    "8F8F": "EAA3",
    "8F90": "B7F8",
    "8F91": "BCAD",
    "8F93": "CAE4",
    "8F94": "E0CE",
    "8F95": "D4AF",
    "8F96": "CFBD",
    "8F97": "D5B7",
    "8F98": "EAA4",
    "8F99": "D5DE",
    "8F9A": "EAA5",
    "8F9B": "D0C1",
    "8F9C": "B9BC",
    "8F9E": "B4C7",
    "8F9F": "B1D9",
    "8FA3": "C0B1",
    "8FA8": "B1E6",
    "8FA9": "B1E7",
    "8FAB": "B1E8",
    "8FB0": "B3BD",
    "8FB1": "C8E8",
    "8FB6": "E5C1",
    "8FB9": "B1DF",
    "8FBD": "C1C9",
    "8FBE": "B4EF",
    "8FC1": "C7A8",
    "8FC2": "D3D8",
    "8FC4": "C6F9",
    "8FC5": "D1B8",
    "8FC7": "B9FD",
    "8FC8": "C2F5",
    "8FCE": "D3AD",
    "8FD0": "D4CB",
    "8FD1": "BDFC",
    "8FD3": "E5C2",
    "8FD4": "B7B5",
    "8FD5": "E5C3",
    "8FD8": "BBB9",
    "8FD9": "D5E2",
    "8FDB": "BDF8",
    "8FDC": "D4B6",
    "8FDD": "CEA5",
    "8FDE": "C1AC",
    "8FDF": "B3D9",
    "8FE2": "CCF6",
    "8FE4": "E5C6",
    "8FE5": "E5C4",
    "8FE6": "E5C8",
    "8FE8": "E5CA",
    "8FE9": "E5C7",
    "8FEA": "B5CF",
    "8FEB": "C6C8",
    "8FED": "B5FC",
    "8FEE": "E5C5",
    "8FF0": "CAF6",
    "8FF3": "E5C9",
    "8FF7": "C3D4",
    "8FF8": "B1C5",
    "8FF9": "BCA3",
    "8FFD": "D7B7",
    "9000": "CDCB",
    "9001": "CBCD",
    "9002": "CACA",
    "9003": "CCD3",
    "9004": "E5CC",
    "9005": "E5CB",
    "9006": "C4E6",
    "9009": "D1A1",
    "900A": "D1B7",
    "900B": "E5CD",
    "900D": "E5D0",
    "900F": "CDB8",
    "9010": "D6F0",
    "9011": "E5CF",
    "9012": "B5DD",
    "9014": "CDBE",
    "9016": "E5D1",
    "9017": "B6BA",
    "901A": "CDA8",
    "901B": "B9E4",
    "901D": "CAC5",
    "901E": "B3D1",
    "901F": "CBD9",
    "9020": "D4EC",
    "9021": "E5D2",
    "9022": "B7EA",
    "9026": "E5CE",
    "902D": "E5D5",
    "902E": "B4FE",
    "902F": "E5D6",
    "9035": "E5D3",
    "9036": "E5D4",
    "9038": "D2DD",
    "903B": "C2DF",
    "903C": "B1C6",
    "903E": "D3E2",
    "9041": "B6DD",
    "9042": "CBEC",
    "9044": "E5D7",
    "9047": "D3F6",
    "904D": "B1E9",
    "904F": "B6F4",
    "9050": "E5DA",
    "9051": "E5D8",
    "9052": "E5D9",
    "9053": "B5C0",
    "9057": "D2C5",
    "9058": "E5DC",
    "905B": "E5DE",
    "9062": "E5DD",
    "9063": "C7B2",
    "9065": "D2A3",
    "9068": "E5DB",
    "906D": "D4E2",
    "906E": "D5DA",
    "9074": "E5E0",
    "9075": "D7F1",
    "907D": "E5E1",
    "907F": "B1DC",
    "9080": "D1FB",
    "9082": "E5E2",
    "9083": "E5E4",
    "9088": "E5E3",
    "908B": "E5E5",
    "9091": "D2D8",
    "9093": "B5CB",
    "9095": "E7DF",
    "9097": "DAF5",
    "9099": "DAF8",
    "909B": "DAF6",
    "909D": "DAF7",
    "90A1": "DAFA",
    "90A2": "D0CF",
    "90A3": "C4C7",
    "90A6": "B0EE",
    "90AA": "D0B0",
    "90AC": "DAF9",
    "90AE": "D3CA",
    "90AF": "BAAA",
    "90B0": "DBA2",
    "90B1": "C7F1",
    "90B3": "DAFC",
    "90B4": "DAFB",
    "90B5": "C9DB",
    "90B6": "DAFD",
    "90B8": "DBA1",
    "90B9": "D7DE",
    "90BA": "DAFE",
    "90BB": "C1DA",
    "90BE": "DBA5",
    "90C1": "D3F4",
    "90C4": "DBA7",
    "90C5": "DBA4",
    "90C7": "DBA8",
    "90CA": "BDBC",
    "90CE": "C0C9",
    "90CF": "DBA3",
    "90D0": "DBA6",
    "90D1": "D6A3",
    "90D3": "DBA9",
    "90D7": "DBAD",
    "90DB": "DBAE",
    "90DC": "DBAC",
    "90DD": "BAC2",
    "90E1": "BFA4",
    "90E2": "DBAB",
    "90E6": "DBAA",
    "90E7": "D4C7",
    "90E8": "B2BF",
    "90EB": "DBAF",
    "90ED": "B9F9",
    "90EF": "DBB0",
    "90F4": "B3BB",
    "90F8": "B5A6",
    "90FD": "B6BC",
    "90FE": "DBB1",
    "9102": "B6F5",
    "9104": "DBB2",
    "9119": "B1C9",
    "911E": "DBB4",
    "9122": "DBB3",
    "9123": "DBB5",
    "912F": "DBB7",
    "9131": "DBB6",
    "9139": "DBB8",
    "9143": "DBB9",
    "9146": "DBBA",
    "9149": "D3CF",
    "914A": "F4FA",
    "914B": "C7F5",
    "914C": "D7C3",
    "914D": "C5E4",
    "914E": "F4FC",
    "914F": "F4FD",
    "9150": "F4FB",
    "9152": "BEC6",
    "9157": "D0EF",
    "915A": "B7D3",
    "915D": "D4CD",
    "915E": "CCAA",
    "9161": "F5A2",
    "9162": "F5A1",
    "9163": "BAA8",
    "9164": "F4FE",
    "9165": "CBD6",
    "9169": "F5A4",
    "916A": "C0D2",
    "916C": "B3EA",
    "916E": "CDAA",
    "916F": "F5A5",
    "9170": "F5A3",
    "9171": "BDB4",
    "9172": "F5A8",
    "9174": "F5A9",
    "9175": "BDCD",
    "9176": "C3B8",
    "9177": "BFE1",
    "9178": "CBE1",
    "9179": "F5AA",
    "917D": "F5A6",
    "917E": "F5A7",
    "917F": "C4F0",
    "9185": "F5AC",
    "9187": "B4BC",
    "9189": "D7ED",
    "918B": "B4D7",
    "918C": "F5AB",
    "918D": "F5AE",
    "9190": "F5AD",
    "9191": "F5AF",
    "9192": "D0D1",
    "919A": "C3D1",
    "919B": "C8A9",
    "91A2": "F5B0",
    "91A3": "F5B1",
    "91AA": "F5B2",
    "91AD": "F5B3",
    "91AE": "F5B4",
    "91AF": "F5B5",
    "91B4": "F5B7",
    "91B5": "F5B6",
    "91BA": "F5B8",
    "91C7": "B2C9",
    "91C9": "D3D4",
    "91CA": "CACD",
    "91CC": "C0EF",
    "91CD": "D6D8",
    "91CE": "D2B0",
    "91CF": "C1BF",
    "91D1": "BDF0",
    "91DC": "B8AA",
    "9274": "BCF8",
    "928E": "F6C6",
    "92AE": "F6C7",
    "92C8": "F6C8",
    "933E": "F6C9",
    "936A": "F6CA",
    "938F": "F6CC",
    "93CA": "F6CB",
    "93D6": "F7E9",
    "943E": "F6CD",
    "946B": "F6CE",
    "9485": "EEC4",
    "9486": "EEC5",
    "9487": "EEC6",
    "9488": "D5EB",
    "9489": "B6A4",
    "948A": "EEC8",
    "948B": "EEC7",
    "948C": "EEC9",
    "948D": "EECA",
    "948E": "C7A5",
    "948F": "EECB",
    "9490": "EECC",
    "9492": "B7B0",
    "9493": "B5F6",
    "9494": "EECD",
    "9495": "EECF",
    "9497": "EECE",
    "9499": "B8C6",
    "949A": "EED0",
    "949B": "EED1",
    "949C": "EED2",
    "949D": "B6DB",
    "949E": "B3AE",
    "949F": "D6D3",
    "94A0": "C4C6",
    "94A1": "B1B5",
    "94A2": "B8D6",
    "94A3": "EED3",
    "94A4": "EED4",
    "94A5": "D4BF",
    "94A6": "C7D5",
    "94A7": "BEFB",
    "94A8": "CED9",
    "94A9": "B9B3",
    "94AA": "EED6",
    "94AB": "EED5",
    "94AC": "EED8",
    "94AD": "EED7",
    "94AE": "C5A5",
    "94AF": "EED9",
    "94B0": "EEDA",
    "94B1": "C7AE",
    "94B2": "EEDB",
    "94B3": "C7AF",
    "94B4": "EEDC",
    "94B5": "B2A7",
    "94B6": "EEDD",
    "94B7": "EEDE",
    "94B8": "EEDF",
    "94B9": "EEE0",
    "94BA": "EEE1",
    "94BB": "D7EA",
    "94BC": "EEE2",
    "94BD": "EEE3",
    "94BE": "BCD8",
    "94BF": "EEE4",
    "94C0": "D3CB",
    "94C1": "CCFA",
    "94C2": "B2AC",
    "94C3": "C1E5",
    "94C4": "EEE5",
    "94C5": "C7A6",
    "94C6": "C3AD",
    "94C8": "EEE6",
    "94C9": "EEE7",
    "94CA": "EEE8",
    "94CB": "EEE9",
    "94CC": "EEEA",
    "94CD": "EEEB",
    "94CE": "EEEC",
    "94D0": "EEED",
    "94D1": "EEEE",
    "94D2": "EEEF",
    "94D5": "EEF0",
    "94D6": "EEF1",
    "94D7": "EEF2",
    "94D8": "EEF4",
    "94D9": "EEF3",
    "94DB": "EEF5",
    "94DC": "CDAD",
    "94DD": "C2C1",
    "94DE": "EEF6",
    "94DF": "EEF7",
    "94E0": "EEF8",
    "94E1": "D5A1",
    "94E2": "EEF9",
    "94E3": "CFB3",
    "94E4": "EEFA",
    "94E5": "EEFB",
    "94E7": "EEFC",
    "94E8": "EEFD",
    "94E9": "EFA1",
    "94EA": "EEFE",
    "94EB": "EFA2",
    "94EC": "B8F5",
    "94ED": "C3FA",
    "94EE": "EFA3",
    "94EF": "EFA4",
    "94F0": "BDC2",
    "94F1": "D2BF",
    "94F2": "B2F9",
    "94F3": "EFA5",
    "94F4": "EFA6",
    "94F5": "EFA7",
    "94F6": "D2F8",
    "94F7": "EFA8",
    "94F8": "D6FD",
    "94F9": "EFA9",
    "94FA": "C6CC",
    "94FC": "EFAA",
    "94FD": "EFAB",
    "94FE": "C1B4",
    "94FF": "EFAC",
    "9500": "CFFA",
    "9501": "CBF8",
    "9502": "EFAE",
    "9503": "EFAD",
    "9504": "B3FA",
    "9505": "B9F8",
    "9506": "EFAF",
    "9507": "EFB0",
    "9508": "D0E2",
    "9509": "EFB1",
    "950A": "EFB2",
    "950B": "B7E6",
    "950C": "D0BF",
    "950D": "EFB3",
    "950E": "EFB4",
    "950F": "EFB5",
    "9510": "C8F1",
    "9511": "CCE0",
    "9512": "EFB6",
    "9513": "EFB7",
    "9514": "EFB8",
    "9515": "EFB9",
    "9516": "EFBA",
    "9517": "D5E0",
    "9518": "EFBB",
    "9519": "B4ED",
    "951A": "C3AA",
    "951B": "EFBC",
    "951D": "EFBD",
    "951E": "EFBE",
    "951F": "EFBF",
    "9521": "CEFD",
    "9522": "EFC0",
    "9523": "C2E0",
    "9524": "B4B8",
    "9525": "D7B6",
    "9526": "BDF5",
    "9528": "CFC7",
    "9529": "EFC3",
    "952A": "EFC1",
    "952B": "EFC2",
    "952C": "EFC4",
    "952D": "B6A7",
    "952E": "BCFC",
    "952F": "BEE2",
    "9530": "C3CC",
    "9531": "EFC5",
    "9532": "EFC6",
    "9534": "EFC7",
    "9535": "EFCF",
    "9536": "EFC8",
    "9537": "EFC9",
    "9538": "EFCA",
    "9539": "C7C2",
    "953A": "EFF1",
    "953B": "B6CD",
    "953C": "EFCB",
    "953E": "EFCC",
    "953F": "EFCD",
    "9540": "B6C6",
    "9541": "C3BE",
    "9542": "EFCE",
    "9544": "EFD0",
    "9545": "EFD1",
    "9546": "EFD2",
    "9547": "D5F2",
    "9549": "EFD3",
    "954A": "C4F7",
    "954C": "EFD4",
    "954D": "C4F8",
    "954E": "EFD5",
    "954F": "EFD6",
    "9550": "B8E4",
    "9551": "B0F7",
    "9552": "EFD7",
    "9553": "EFD8",
    "9554": "EFD9",
    "9556": "EFDA",
    "9557": "EFDB",
    "9558": "EFDC",
    "9559": "EFDD",
    "955B": "EFDE",
    "955C": "BEB5",
    "955D": "EFE1",
    "955E": "EFDF",
    "955F": "EFE0",
    "9561": "EFE2",
    "9562": "EFE3",
    "9563": "C1CD",
    "9564": "EFE4",
    "9565": "EFE5",
    "9566": "EFE6",
    "9567": "EFE7",
    "9568": "EFE8",
    "9569": "EFE9",
    "956A": "EFEA",
    "956B": "EFEB",
    "956C": "EFEC",
    "956D": "C0D8",
    "956F": "EFED",
    "9570": "C1AD",
    "9571": "EFEE",
    "9572": "EFEF",
    "9573": "EFF0",
    "9576": "CFE2",
    "957F": "B3A4",
    "95E8": "C3C5",
    "95E9": "E3C5",
    "95EA": "C9C1",
    "95EB": "E3C6",
    "95ED": "B1D5",
    "95EE": "CECA",
    "95EF": "B4B3",
    "95F0": "C8F2",
    "95F1": "E3C7",
    "95F2": "CFD0",
    "95F3": "E3C8",
    "95F4": "BCE4",
    "95F5": "E3C9",
    "95F6": "E3CA",
    "95F7": "C3C6",
    "95F8": "D5A2",
    "95F9": "C4D6",
    "95FA": "B9EB",
    "95FB": "CEC5",
    "95FC": "E3CB",
    "95FD": "C3F6",
    "95FE": "E3CC",
    "9600": "B7A7",
    "9601": "B8F3",
    "9602": "BAD2",
    "9603": "E3CD",
    "9604": "E3CE",
    "9605": "D4C4",
    "9606": "E3CF",
    "9608": "E3D0",
    "9609": "D1CB",
    "960A": "E3D1",
    "960B": "E3D2",
    "960C": "E3D3",
    "960D": "E3D4",
    "960E": "D1D6",
    "960F": "E3D5",
    "9610": "B2FB",
    "9611": "C0BB",
    "9612": "E3D6",
    "9614": "C0AB",
    "9615": "E3D7",
    "9616": "E3D8",
    "9617": "E3D9",
    "9619": "E3DA",
    "961A": "E3DB",
    "961C": "B8B7",
    "961D": "DAE2",
    "961F": "B6D3",
    "9621": "DAE4",
    "9622": "DAE3",
    "962A": "DAE6",
    "962E": "C8EE",
    "9631": "DAE5",
    "9632": "B7C0",
    "9633": "D1F4",
    "9634": "D2F5",
    "9635": "D5F3",
    "9636": "BDD7",
    "963B": "D7E8",
    "963C": "DAE8",
    "963D": "DAE7",
    "963F": "B0A2",
    "9640": "CDD3",
    "9642": "DAE9",
    "9644": "B8BD",
    "9645": "BCCA",
    "9646": "C2BD",
    "9647": "C2A4",
    "9648": "B3C2",
    "9649": "DAEA",
    "964B": "C2AA",
    "964C": "C4B0",
    "964D": "BDB5",
    "9650": "CFDE",
    "9654": "DAEB",
    "9655": "C9C2",
    "965B": "B1DD",
    "965F": "DAEC",
    "9661": "B6B8",
    "9662": "D4BA",
    "9664": "B3FD",
    "9667": "DAED",
    "9668": "D4C9",
    "9669": "CFD5",
    "966A": "C5E3",
    "966C": "DAEE",
    "9672": "DAEF",
    "9674": "DAF0",
    "9675": "C1EA",
    "9676": "CCD5",
    "9677": "CFDD",
    "9685": "D3E7",
    "9686": "C2A1",
    "9688": "DAF1",
    "968B": "CBE5",
    "968D": "DAF2",
    "968F": "CBE6",
    "9690": "D2FE",
    "9694": "B8F4",
    "9697": "DAF3",
    "9698": "B0AF",
    "9699": "CFB6",
    "969C": "D5CF",
    "96A7": "CBED",
    "96B0": "DAF4",
    "96B3": "E3C4",
    "96B6": "C1A5",
    "96B9": "F6BF",
    "96BC": "F6C0",
    "96BD": "F6C1",
    "96BE": "C4D1",
    "96C0": "C8B8",
    "96C1": "D1E3",
    "96C4": "D0DB",
    "96C5": "D1C5",
    "96C6": "BCAF",
    "96C7": "B9CD",
    "96C9": "EFF4",
    "96CC": "B4C6",
    "96CD": "D3BA",
    "96CE": "F6C2",
    "96CF": "B3FB",
    "96D2": "F6C3",
    "96D5": "B5F1",
    "96E0": "F6C5",
    "96E8": "D3EA",
    "96E9": "F6A7",
    "96EA": "D1A9",
    "96EF": "F6A9",
    "96F3": "F6A8",
    "96F6": "C1E3",
    "96F7": "C0D7",
    "96F9": "B1A2",
    "96FE": "CEED",
    "9700": "D0E8",
    "9701": "F6AB",
    "9704": "CFF6",
    "9706": "F6AA",
    "9707": "D5F0",
    "9708": "F6AC",
    "9709": "C3B9",
    "970D": "BBF4",
    "970E": "F6AE",
    "970F": "F6AD",
    "9713": "C4DE",
    "9716": "C1D8",
    "971C": "CBAA",
    "971E": "CFBC",
    "972A": "F6AF",
    "972D": "F6B0",
    "9730": "F6B1",
    "9732": "C2B6",
    "9738": "B0D4",
    "9739": "C5F9",
    "973E": "F6B2",
    "9752": "C7E0",
    "9753": "F6A6",
    "9756": "BEB8",
    "9759": "BEB2",
    "975B": "B5E5",
    "975E": "B7C7",
    "9760": "BFBF",
    "9761": "C3D2",
    "9762": "C3E6",
    "9765": "D8CC",
    "9769": "B8EF",
    "9773": "BDF9",
    "9774": "D1A5",
    "9776": "B0D0",
    "977C": "F7B0",
    "9785": "F7B1",
    "978B": "D0AC",
    "978D": "B0B0",
    "9791": "F7B2",
    "9792": "F7B3",
    "9794": "F7B4",
    "9798": "C7CA",
    "97A0": "BECF",
    "97A3": "F7B7",
    "97AB": "F7B6",
    "97AD": "B1DE",
    "97AF": "F7B5",
    "97B2": "F7B8",
    "97B4": "F7B9",
    "97E6": "CEA4",
    "97E7": "C8CD",
    "97E9": "BAAB",
    "97EA": "E8B8",
    "97EB": "E8B9",
    "97EC": "E8BA",
    "97ED": "BEC2",
    "97F3": "D2F4",
    "97F5": "D4CF",
    "97F6": "C9D8",
    "9875": "D2B3",
    "9876": "B6A5",
    "9877": "C7EA",
    "9878": "F1FC",
    "9879": "CFEE",
    "987A": "CBB3",
    "987B": "D0EB",
    "987C": "E7EF",
    "987D": "CDE7",
    "987E": "B9CB",
    "987F": "B6D9",
    "9880": "F1FD",
    "9881": "B0E4",
    "9882": "CBCC",
    "9883": "F1FE",
    "9884": "D4A4",
    "9885": "C2AD",
    "9886": "C1EC",
    "9887": "C6C4",
    "9888": "BEB1",
    "9889": "F2A1",
    "988A": "BCD5",
    "988C": "F2A2",
    "988D": "F2A3",
    "988F": "F2A4",
    "9890": "D2C3",
    "9891": "C6B5",
    "9893": "CDC7",
    "9894": "F2A5",
    "9896": "D3B1",
    "9897": "BFC5",
    "9898": "CCE2",
    "989A": "F2A6",
    "989B": "F2A7",
    "989C": "D1D5",
    "989D": "B6EE",
    "989E": "F2A8",
    "989F": "F2A9",
    "98A0": "B5DF",
    "98A1": "F2AA",
    "98A2": "F2AB",
    "98A4": "B2FC",
    "98A5": "F2AC",
    "98A6": "F2AD",
    "98A7": "C8A7",
    "98CE": "B7E7",
    "98D1": "ECA9",
    "98D2": "ECAA",
    "98D3": "ECAB",
    "98D5": "ECAC",
    "98D8": "C6AE",
    "98D9": "ECAD",
    "98DA": "ECAE",
    "98DE": "B7C9",
    "98DF": "CAB3",
    "98E7": "E2B8",
    "98E8": "F7CF",
    "990D": "F7D0",
    "9910": "B2CD",
    "992E": "F7D1",
    "9954": "F7D3",
    "9955": "F7D2",
    "9963": "E2BB",
    "9965": "BCA2",
    "9967": "E2BC",
    "9968": "E2BD",
    "9969": "E2BE",
    "996A": "E2BF",
    "996B": "E2C0",
    "996C": "E2C1",
    "996D": "B7B9",
    "996E": "D2FB",
    "996F": "BDA4",
    "9970": "CACE",
    "9971": "B1A5",
    "9972": "CBC7",
    "9974": "E2C2",
    "9975": "B6FC",
    "9976": "C8C4",
    "9977": "E2C3",
    "997A": "BDC8",
    "997C": "B1FD",
    "997D": "E2C4",
    "997F": "B6F6",
    "9980": "E2C5",
    "9981": "C4D9",
    "9984": "E2C6",
    "9985": "CFDA",
    "9986": "B9DD",
    "9987": "E2C7",
    "9988": "C0A1",
    "998A": "E2C8",
    "998B": "B2F6",
    "998D": "E2C9",
    "998F": "C1F3",
    "9990": "E2CA",
    "9991": "E2CB",
    "9992": "C2F8",
    "9993": "E2CC",
    "9994": "E2CD",
    "9995": "E2CE",
    "9996": "CAD7",
    "9997": "D8B8",
    "9998": "D9E5",
    "9999": "CFE3",
    "99A5": "F0A5",
    "99A8": "DCB0",
    "9A6C": "C2ED",
    "9A6D": "D4A6",
    "9A6E": "CDD4",
    "9A6F": "D1B1",
    "9A70": "B3DB",
    "9A71": "C7FD",
    "9A73": "B2B5",
    "9A74": "C2BF",
    "9A75": "E6E0",
    "9A76": "CABB",
    "9A77": "E6E1",
    "9A78": "E6E2",
    "9A79": "BED4",
    "9A7A": "E6E3",
    "9A7B": "D7A4",
    "9A7C": "CDD5",
    "9A7D": "E6E5",
    "9A7E": "BCDD",
    "9A7F": "E6E4",
    "9A80": "E6E6",
    "9A81": "E6E7",
    "9A82": "C2EE",
    "9A84": "BDBE",
    "9A85": "E6E8",
    "9A86": "C2E6",
    "9A87": "BAA7",
    "9A88": "E6E9",
    "9A8A": "E6EA",
    "9A8B": "B3D2",
    "9A8C": "D1E9",
    "9A8F": "BFA5",
    "9A90": "E6EB",
    "9A91": "C6EF",
    "9A92": "E6EC",
    "9A93": "E6ED",
    "9A96": "E6EE",
    "9A97": "C6AD",
    "9A98": "E6EF",
    "9A9A": "C9A7",
    "9A9B": "E6F0",
    "9A9C": "E6F1",
    "9A9D": "E6F2",
    "9A9E": "E5B9",
    "9A9F": "E6F3",
    "9AA0": "E6F4",
    "9AA1": "C2E2",
    "9AA2": "E6F5",
    "9AA3": "E6F6",
    "9AA4": "D6E8",
    "9AA5": "E6F7",
    "9AA7": "E6F8",
    "9AA8": "B9C7",
    "9AB0": "F7BB",
    "9AB1": "F7BA",
    "9AB6": "F7BE",
    "9AB7": "F7BC",
    "9AB8": "BAA1",
    "9ABA": "F7BF",
    "9ABC": "F7C0",
    "9AC0": "F7C2",
    "9AC1": "F7C1",
    "9AC2": "F7C4",
    "9AC5": "F7C3",
    "9ACB": "F7C5",
    "9ACC": "F7C6",
    "9AD1": "F7C7",
    "9AD3": "CBE8",
    "9AD8": "B8DF",
    "9ADF": "F7D4",
    "9AE1": "F7D5",
    "9AE6": "F7D6",
    "9AEB": "F7D8",
    "9AED": "F7DA",
    "9AEF": "F7D7",
    "9AF9": "F7DB",
    "9AFB": "F7D9",
    "9B03": "D7D7",
    "9B08": "F7DC",
    "9B0F": "F7DD",
    "9B13": "F7DE",
    "9B1F": "F7DF",
    "9B23": "F7E0",
    "9B2F": "DBCB",
    "9B32": "D8AA",
    "9B3B": "E5F7",
    "9B3C": "B9ED",
    "9B41": "BFFD",
    "9B42": "BBEA",
    "9B43": "F7C9",
    "9B44": "C6C7",
    "9B45": "F7C8",
    "9B47": "F7CA",
    "9B48": "F7CC",
    "9B49": "F7CB",
    "9B4D": "F7CD",
    "9B4F": "CEBA",
    "9B51": "F7CE",
    "9B54": "C4A7",
    "9C7C": "D3E3",
    "9C7F": "F6CF",
    "9C81": "C2B3",
    "9C82": "F6D0",
    "9C85": "F6D1",
    "9C86": "F6D2",
    "9C87": "F6D3",
    "9C88": "F6D4",
    "9C8B": "F6D6",
    "9C8D": "B1AB",
    "9C8E": "F6D7",
    "9C90": "F6D8",
    "9C91": "F6D9",
    "9C92": "F6DA",
    "9C94": "F6DB",
    "9C95": "F6DC",
    "9C9A": "F6DD",
    "9C9B": "F6DE",
    "9C9C": "CFCA",
    "9C9E": "F6DF",
    "9C9F": "F6E0",
    "9CA0": "F6E1",
    "9CA1": "F6E2",
    "9CA2": "F6E3",
    "9CA3": "F6E4",
    "9CA4": "C0F0",
    "9CA5": "F6E5",
    "9CA6": "F6E6",
    "9CA7": "F6E7",
    "9CA8": "F6E8",
    "9CA9": "F6E9",
    "9CAB": "F6EA",
    "9CAD": "F6EB",
    "9CAE": "F6EC",
    "9CB0": "F6ED",
    "9CB1": "F6EE",
    "9CB2": "F6EF",
    "9CB3": "F6F0",
    "9CB4": "F6F1",
    "9CB5": "F6F2",
    "9CB6": "F6F3",
    "9CB7": "F6F4",
    "9CB8": "BEA8",
    "9CBA": "F6F5",
    "9CBB": "F6F6",
    "9CBC": "F6F7",
    "9CBD": "F6F8",
    "9CC3": "C8FA",
    "9CC4": "F6F9",
    "9CC5": "F6FA",
    "9CC6": "F6FB",
    "9CC7": "F6FC",
    "9CCA": "F6FD",
    "9CCB": "F6FE",
    "9CCC": "F7A1",
    "9CCD": "F7A2",
    "9CCE": "F7A3",
    "9CCF": "F7A4",
    "9CD0": "F7A5",
    "9CD3": "F7A6",
    "9CD4": "F7A7",
    "9CD5": "F7A8",
    "9CD6": "B1EE",
    "9CD7": "F7A9",
    "9CD8": "F7AA",
    "9CD9": "F7AB",
    "9CDC": "F7AC",
    "9CDD": "F7AD",
    "9CDE": "C1DB",
    "9CDF": "F7AE",
    "9CE2": "F7AF",
    "9E1F": "C4F1",
    "9E20": "F0AF",
    "9E21": "BCA6",
    "9E22": "F0B0",
    "9E23": "C3F9",
    "9E25": "C5B8",
    "9E26": "D1BB",
    "9E28": "F0B1",
    "9E29": "F0B2",
    "9E2A": "F0B3",
    "9E2B": "F0B4",
    "9E2C": "F0B5",
    "9E2D": "D1BC",
    "9E2F": "D1EC",
    "9E31": "F0B7",
    "9E32": "F0B6",
    "9E33": "D4A7",
    "9E35": "CDD2",
    "9E36": "F0B8",
    "9E37": "F0BA",
    "9E38": "F0B9",
    "9E39": "F0BB",
    "9E3A": "F0BC",
    "9E3D": "B8EB",
    "9E3E": "F0BD",
    "9E3F": "BAE8",
    "9E41": "F0BE",
    "9E42": "F0BF",
    "9E43": "BEE9",
    "9E44": "F0C0",
    "9E45": "B6EC",
    "9E46": "F0C1",
    "9E47": "F0C2",
    "9E48": "F0C3",
    "9E49": "F0C4",
    "9E4A": "C8B5",
    "9E4B": "F0C5",
    "9E4C": "F0C6",
    "9E4E": "F0C7",
    "9E4F": "C5F4",
    "9E51": "F0C8",
    "9E55": "F0C9",
    "9E57": "F0CA",
    "9E58": "F7BD",
    "9E5A": "F0CB",
    "9E5B": "F0CC",
    "9E5C": "F0CD",
    "9E5E": "F0CE",
    "9E63": "F0CF",
    "9E64": "BAD7",
    "9E66": "F0D0",
    "9E67": "F0D1",
    "9E68": "F0D2",
    "9E69": "F0D3",
    "9E6A": "F0D4",
    "9E6B": "F0D5",
    "9E6C": "F0D6",
    "9E6D": "F0D8",
    "9E70": "D3A5",
    "9E71": "F0D7",
    "9E73": "F0D9",
    "9E7E": "F5BA",
    "9E7F": "C2B9",
    "9E82": "F7E4",
    "9E87": "F7E5",
    "9E88": "F7E6",
    "9E8B": "F7E7",
    "9E92": "F7E8",
    "9E93": "C2B4",
    "9E9D": "F7EA",
    "9E9F": "F7EB",
    "9EA6": "C2F3",
    "9EB4": "F4F0",
    "9EB8": "F4EF",
    "9EBB": "C2E9",
    "9EBD": "F7E1",
    "9EBE": "F7E2",
    "9EC4": "BBC6",
    "9EC9": "D9E4",
    "9ECD": "CAF2",
    "9ECE": "C0E8",
    "9ECF": "F0A4",
    "9ED1": "BADA",
    "9ED4": "C7AD",
    "9ED8": "C4AC",
    "9EDB": "F7EC",
    "9EDC": "F7ED",
    "9EDD": "F7EE",
    "9EDF": "F7F0",
    "9EE0": "F7EF",
    "9EE2": "F7F1",
    "9EE5": "F7F4",
    "9EE7": "F7F3",
    "9EE9": "F7F2",
    "9EEA": "F7F5",
    "9EEF": "F7F6",
    "9EF9": "EDE9",
    "9EFB": "EDEA",
    "9EFC": "EDEB",
    "9EFE": "F6BC",
    "9F0B": "F6BD",
    "9F0D": "F6BE",
    "9F0E": "B6A6",
    "9F10": "D8BE",
    "9F13": "B9C4",
    "9F17": "D8BB",
    "9F19": "DCB1",
    "9F20": "CAF3",
    "9F22": "F7F7",
    "9F2C": "F7F8",
    "9F2F": "F7F9",
    "9F37": "F7FB",
    "9F39": "F7FA",
    "9F3B": "B1C7",
    "9F3D": "F7FC",
    "9F3E": "F7FD",
    "9F44": "F7FE",
    "9F50": "C6EB",
    "9F51": "ECB4",
    "9F7F": "B3DD",
    "9F80": "F6B3",
    "9F83": "F6B4",
    "9F84": "C1E4",
    "9F85": "F6B5",
    "9F86": "F6B6",
    "9F87": "F6B7",
    "9F88": "F6B8",
    "9F89": "F6B9",
    "9F8A": "F6BA",
    "9F8B": "C8A3",
    "9F8C": "F6BB",
    "9F99": "C1FA",
    "9F9A": "B9A8",
    "9F9B": "EDE8",
    "9F9F": "B9EA",
    "9FA0": "D9DF",
    "FF01": "A3A1",
    "FF02": "A3A2",
    "FF03": "A3A3",
    "FF04": "A1E7",
    "FF05": "A3A5",
    "FF06": "A3A6",
    "FF07": "A3A7",
    "FF08": "A3A8",
    "FF09": "A3A9",
    "FF0A": "A3AA",
    "FF0B": "A3AB",
    "FF0C": "A3AC",
    "FF0D": "A3AD",
    "FF0E": "A3AE",
    "FF0F": "A3AF",
    "FF10": "A3B0",
    "FF11": "A3B1",
    "FF12": "A3B2",
    "FF13": "A3B3",
    "FF14": "A3B4",
    "FF15": "A3B5",
    "FF16": "A3B6",
    "FF17": "A3B7",
    "FF18": "A3B8",
    "FF19": "A3B9",
    "FF1A": "A3BA",
    "FF1B": "A3BB",
    "FF1C": "A3BC",
    "FF1D": "A3BD",
    "FF1E": "A3BE",
    "FF1F": "A3BF",
    "FF20": "A3C0",
    "FF21": "A3C1",
    "FF22": "A3C2",
    "FF23": "A3C3",
    "FF24": "A3C4",
    "FF25": "A3C5",
    "FF26": "A3C6",
    "FF27": "A3C7",
    "FF28": "A3C8",
    "FF29": "A3C9",
    "FF2A": "A3CA",
    "FF2B": "A3CB",
    "FF2C": "A3CC",
    "FF2D": "A3CD",
    "FF2E": "A3CE",
    "FF2F": "A3CF",
    "FF30": "A3D0",
    "FF31": "A3D1",
    "FF32": "A3D2",
    "FF33": "A3D3",
    "FF34": "A3D4",
    "FF35": "A3D5",
    "FF36": "A3D6",
    "FF37": "A3D7",
    "FF38": "A3D8",
    "FF39": "A3D9",
    "FF3A": "A3DA",
    "FF3B": "A3DB",
    "FF3C": "A3DC",
    "FF3D": "A3DD",
    "FF3E": "A3DE",
    "FF3F": "A3DF",
    "FF40": "A3E0",
    "FF41": "A3E1",
    "FF42": "A3E2",
    "FF43": "A3E3",
    "FF44": "A3E4",
    "FF45": "A3E5",
    "FF46": "A3E6",
    "FF47": "A3E7",
    "FF48": "A3E8",
    "FF49": "A3E9",
    "FF4A": "A3EA",
    "FF4B": "A3EB",
    "FF4C": "A3EC",
    "FF4D": "A3ED",
    "FF4E": "A3EE",
    "FF4F": "A3EF",
    "FF50": "A3F0",
    "FF51": "A3F1",
    "FF52": "A3F2",
    "FF53": "A3F3",
    "FF54": "A3F4",
    "FF55": "A3F5",
    "FF56": "A3F6",
    "FF57": "A3F7",
    "FF58": "A3F8",
    "FF59": "A3F9",
    "FF5A": "A3FA",
    "FF5B": "A3FB",
    "FF5C": "A3FC",
    "FF5D": "A3FD",
    "FF5E": "A1AB",
    "FFE0": "A1E9",
    "FFE1": "A1EA",
    "FFE3": "A3FE",
    "FFE5": "A3A4"
};

var encodeToGb2312 = function (str) {
    var strOut = "";
    for (var i = 0; i < str.length; i++) {
        var c = str.charAt(i);
        var code = str.charCodeAt(i);
        var gcode = json[code.toString(16).toUpperCase()];
        if (gcode && gcode.length % 2 !== 0) gcode = "0" + gcode;
        if (c == " ") {
            strOut += "20";
        } else if (code < 19968) {
            var b = str.charCodeAt(i).toString(16);
            if (b && b.length % 2 !== 0) b = "0" + b;
            strOut += b;
        } else if (gcode) {
            strOut += gcode;
        } else {
            throw Error("not match");
        }
    }
    return strOut;
};

Blockly.Arduino.forBlock['make_tool_encoding'] = function () {
    var text_input_data = this.getFieldValue('input_data');
    var dropdown_type = this.getFieldValue('type');
    var text_output_data = this.getFieldValue('output_data');

    var output_data = "";
    if (dropdown_type == "GB2312") {
        //output_data = UrlEncode1(text_input_data);
        output_data = encodeToGb2312(text_input_data);
        var output_data1 = "";
        for (var i in output_data) {
            if (i > 0 && i % 2 == 1)
                output_data1 = output_data1 + output_data.charAt(i) + " ";
            else
                output_data1 += output_data.charAt(i);
        }
        if (output_data1.charAt(output_data1.length - 1) == ' ')
            output_data = output_data1.substring(0, output_data1.length - 1);
        else
            output_data = output_data1;
        output_data = output_data.toUpperCase();
    }
    else {
        output_data = encodeUnicode1(text_input_data);
    }
    this.setFieldValue(output_data, "output_data");
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_tool_encoding_1'] = function () {
    var dropdown_type = this.getFieldValue('type');
    var text_input_data = this.getFieldValue('input_data');

    var output_data = "";
    if (dropdown_type == "GB2312") {
        //output_data = UrlEncode1(text_input_data);
        output_data = encodeToGb2312(text_input_data);
        var output_data1 = "";
        for (var i in output_data) {
            if (i > 0 && i % 2 == 1)
                output_data1 = output_data1 + output_data.charAt(i) + "%";
            else
                output_data1 += output_data.charAt(i);
        }
        if (output_data1.charAt(output_data1.length - 1) == '%')
            output_data = output_data1.substring(0, output_data1.length - 1);
        else
            output_data = output_data1;
        output_data = '%' + output_data.toUpperCase();
    }
    else {
        output_data = encodeUnicode2(text_input_data);
    }
    this.setTooltip(text_input_data + '的' + dropdown_type + '编码为:\n' + output_data);
    var code = '"' + output_data + '"';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.forBlock['make_arduino_comment_picture'] = function () {
    //var aa = UrlEncode("米");
    //var bb = UrlDecode("你好");
    //var text_picture_width = this.getFieldValue('picture_width');
    //var text_picture_height = this.getFieldValue('picture_height');
    var text_picture_data = this.getFieldValue('picture_data');
    //var code = aa + bb;
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_comment_picture_change_1'] = function () {
    var dropdown_picture_width = this.getFieldValue('picture_width');
    var dropdown_picture_height = this.getFieldValue('picture_height');
    var text_picture_data = this.getFieldValue('picture_data');
    var code = '';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_comment_text'] = function () {
    var text_data = this.getFieldValue('data');
    var code = '/*\n' + text_data + '\n*/\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_comment_text_1'] = function () {
    var text_data = this.getFieldValue('data');
    var code = '//' + text_data + '\n';
    return code;
};

Blockly.Arduino.forBlock['make_arduino_comment_text_2'] = function () {
    if (this.itemCount_) {
        var code1 = new Array(this.itemCount_);
        for (var n = 0; n < this.itemCount_; n++) {
            code1[n] = '*' + this.getFieldValue('data' + (n + 1));
        }
        var code = '';
        for (var n = 0; n < this.itemCount_; n++) {
            code = code + code1[n] + '\n';
        }
        code = '/*\n' + code + '*/\n';
    }
    else {
        var code = this.getFieldValue('data1');
        code = '/*' + code + '*/\n';
    }

    return code;
};

Blockly.Arduino.forBlock['make_arduino_comment_text_3'] = function () {
    var text_data = this.getFieldValue('data');
    var statements_input = Blockly.Arduino.statementToCode(this, 'input');
    statements_input = statements_input.replace(new RegExp(/\n  /g), "\n");
    statements_input = statements_input.replace(/(^\s*)|(\s*$)/g, "");//去除两端空格
    var code = '/*' + text_data + '*/\n' + statements_input + "\n";
    return code;
};

Blockly.Arduino.forBlock['make_arduino_comment_text_4'] = function () {
    var statements_input = Blockly.Arduino.statementToCode(this, 'input');
    var code = '/*\n' + statements_input + '*/';
    return code;
};

/*
Blockly.Arduino.forBlock['make_arduino_tooltip'] = function() {
  var surround_parent = this.getSurroundParent();
  if (surround_parent && surround_parent.type == 'base_setup') {
  var dropdown_type = this.getFieldValue('type');
    if(dropdown_type == 'true')
      Blockly.make_arduino_tooltip = 'true';
    else if(dropdown_type == 'false_part')
      Blockly.make_arduino_tooltip = 'false_part';
    else
      Blockly.make_arduino_tooltip = 'false';
    this.setWarningText(null);
  } else {
    this.setWarningText("此块需放到 初始化 块下");
  }
  var code = '';
  return code;
};
*/

Blockly.Arduino.forBlock['QR_code_display1'] = function () {
    var text_st7735_name = this.getFieldValue('st7735_name');
    var text = Blockly.Arduino.valueToCode(this, 'text', Blockly.Arduino.ORDER_ATOMIC);
    var X = Blockly.Arduino.valueToCode(this, 'X', Blockly.Arduino.ORDER_ATOMIC);
    var Y = Blockly.Arduino.valueToCode(this, 'Y', Blockly.Arduino.ORDER_ATOMIC);
    var Zoom = Blockly.Arduino.valueToCode(this, 'Zoom', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.definitions_["include_qrcode"] = '#include <qrcode.h>';
    var code = 'String strURL = ' + text + ';\n'
        + 'char x[500];\n'
        + 'strURL.toCharArray(x, 500);\n'
        + 'Serial.println (x);\n'
        + 'QRCode qrcode;\n'
        + 'uint8_t qrcodeData[qrcode_getBufferSize(6)];\n'
        + 'qrcode_initText(&qrcode, qrcodeData, 6, 0, x);\n'
        + 'uint8_t x0 = ' + X + '; //横坐标偏移\n'
        + 'uint8_t y0 = ' + Y + '; //纵坐标偏移\n'
        + 'uint8_t Zoom = ' + Zoom + '; //缩放倍数\n'
        + 'Serial.println (qrcode.size);\n'
        + 'for (uint8_t y = 0; y < qrcode.size; y++) {\n'
        + '  for (uint8_t x = 0; x < qrcode.size; x++) {\n'
        + '    if (qrcode_getModule(&qrcode, x, y)) {\n'
        + '      ' + text_st7735_name + '.fillRect(Zoom * x + x0, Zoom * y + y0, Zoom, Zoom, 0x0000);\n'
        + '    } else {\n'
        + '      ' + text_st7735_name + '.fillRect(Zoom * x + x0, Zoom * y + y0, Zoom, Zoom, 0xFFFF);\n'
        + '    }\n'
        + '  }\n'
        + '}\n';
    return code;
};


// 显示SD卡图片积木代码生成器（清理优化版）
Blockly.Arduino.forBlock['LovyanGFX_drawSdImage'] = function(block) {
    var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
    var path = Blockly.Arduino.valueToCode(block, 'PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/image.jpg"';
    var x = Blockly.Arduino.valueToCode(block, 'X', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var y = Blockly.Arduino.valueToCode(block, 'Y', Blockly.Arduino.ORDER_ATOMIC) || '0';

    // 添加FS.h头文件
    Blockly.Arduino.definitions_['include_fs'] = '#include <FS.h>';

    // 生成代码 - 使用内存缓冲方式，自动识别格式
    var code = '{';
    code += '  String _path = String(' + path + ');\n';
    code += '  _path.toLowerCase();\n';
    code += '  // 检查是否为支持的格式\n';
    code += '  bool _isSupported = false;\n';
    code += '  if (_path.endsWith(".jpg") || _path.endsWith(".jpeg")) _isSupported = true;\n';
    code += '  else if (_path.endsWith(".png")) _isSupported = true;\n';
    code += '  else if (_path.endsWith(".bmp")) _isSupported = true;\n';
    code += '  else if (_path.endsWith(".qoi")) _isSupported = true;\n';
    code += '  else if (_path.endsWith(".gif")) {\n';
    code += '    Serial.println("ERROR: GIF format not supported. Please convert to JPG first.");\n';
    code += '  }\n';
    code += '  if (_isSupported) {\n';
    code += '    fs::File _file = SD.open(' + path + ', "r");\n';
    code += '    if (_file) {\n';
    code += '      size_t _fileSize = _file.size();\n';
    code += '      if (_fileSize > 0 && _fileSize < 200000) {\n';
    code += '        uint8_t* _buffer = (uint8_t*)malloc(_fileSize);\n';
    code += '        if (_buffer) {\n';
    code += '          size_t _bytesRead = _file.read(_buffer, _fileSize);\n';
    code += '          _file.close();\n';
    code += '          if (_bytesRead == _fileSize) {\n';
    code += '            ' + deviceName + '.startWrite();\n';
    code += '            if (_path.endsWith(".jpg") || _path.endsWith(".jpeg")) {\n';
    code += '              ' + deviceName + '.drawJpg(_buffer, _fileSize, ' + x + ', ' + y + ');\n';
    code += '            } else if (_path.endsWith(".png")) {\n';
    code += '              ' + deviceName + '.drawPng(_buffer, _fileSize, ' + x + ', ' + y + ');\n';
    code += '            } else if (_path.endsWith(".bmp")) {\n';
    code += '              ' + deviceName + '.drawBmp(_buffer, _fileSize, ' + x + ', ' + y + ');\n';
    code += '            } else if (_path.endsWith(".qoi")) {\n';
    code += '              ' + deviceName + '.drawQoi(_buffer, _fileSize, ' + x + ', ' + y + ');\n';
    code += '            }\n';
    code += '            ' + deviceName + '.endWrite();\n';
    code += '          }\n';
    code += '          free(_buffer);\n';
    code += '        } else {\n';
    code += '          _file.close();\n';
    code += '        }\n';
    code += '      } else {\n';
    code += '        _file.close();\n';
    code += '      }\n';
    code += '    }\n';
    code += '  }\n';
    code += '}\n';

    return code;
};

// 显示RGB565图片积木代码生成器
Blockly.Arduino.forBlock['LovyanGFX_drawArrayImage'] = function(block) {
    var deviceName = block.getFieldValue('DEVICE_NAME') || 'tft';
    var imageName = block.getFieldValue('IMAGE_NAME') || 'image1';
    var width = Blockly.Arduino.valueToCode(block, 'WIDTH', Blockly.Arduino.ORDER_ATOMIC) || '240';
    var height = Blockly.Arduino.valueToCode(block, 'HEIGHT', Blockly.Arduino.ORDER_ATOMIC) || '320';
    var imageData = block.getFieldValue('IMAGE_DATA') || '{0x4B41, 0x4301, 0x4B41}';
    var x = Blockly.Arduino.valueToCode(block, 'X', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var y = Blockly.Arduino.valueToCode(block, 'Y', Blockly.Arduino.ORDER_ATOMIC) || '0';
    
    // 使用用户输入的图片名称作为数组变量名
    var arrayVarName = imageName;
    
    // 确保数据有大括号
    if (!imageData.startsWith('{')) {
        imageData = '{' + imageData;
    }
    if (!imageData.endsWith('}')) {
        imageData = imageData + '}';
    }
    
    // 在全局变量区域定义数组（16位RGB565类型）
    Blockly.Arduino.definitions_['var_declare_' + arrayVarName] = 'const uint16_t ' + arrayVarName + '[] PROGMEM = ' + imageData + ';';
    
    // 在setup中设置字节交换（一次性设置）
    Blockly.Arduino.setups_['setup_swap_bytes_' + deviceName] = deviceName + '.setSwapBytes(true);';
    
    // 在loop中显示图片
    var code = deviceName + '.pushImage(' + x + ', ' + y + ', ' + width + ', ' + height + ', ' + arrayVarName + ');\n';
    
    return code;
};
// 初始化ST7305显示器（支持默认引脚）
Blockly.Arduino.forBlock['st7305_init'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var display_size = block.getFieldValue('DISPLAY_SIZE');
    
    // 检查是否提供了引脚参数，如果没有则使用默认引脚
    var hasPins = false;
    var dc_pin, rst_pin, cs_pin, sclk_pin, sdin_pin;
    
    try {
        dc_pin = Blockly.Arduino.valueToCode(block, 'DC_PIN', Blockly.Arduino.ORDER_ATOMIC);
        rst_pin = Blockly.Arduino.valueToCode(block, 'RST_PIN', Blockly.Arduino.ORDER_ATOMIC);
        cs_pin = Blockly.Arduino.valueToCode(block, 'CS_PIN', Blockly.Arduino.ORDER_ATOMIC);
        sclk_pin = Blockly.Arduino.valueToCode(block, 'SCLK_PIN', Blockly.Arduino.ORDER_ATOMIC);
        sdin_pin = Blockly.Arduino.valueToCode(block, 'SDIN_PIN', Blockly.Arduino.ORDER_ATOMIC);
        
        // 如果所有引脚都有值，使用自定义引脚配置
        if (dc_pin && rst_pin && cs_pin && sclk_pin && sdin_pin) {
            hasPins = true;
        }
    } catch (e) {
        // 如果获取引脚失败，使用默认引脚
        hasPins = false;
    }
    
    // 添加头文件
    Blockly.Arduino.definitions_['include_spi'] = '#include <SPI.h>';
    
    // 根据显示屏尺寸选择对应的驱动头文件
    if (display_size === '4p2') {
        Blockly.Arduino.definitions_['include_st7305_driver'] = '#include <ST7305_4p2_BW_DisplayDriver.h>';
    } else if (display_size === '1p5') {
        Blockly.Arduino.definitions_['include_st7305_driver'] = '#include <ST7305_1p5_BW_DisplayDriver.h>';
    } else {
        Blockly.Arduino.definitions_['include_st7305_driver'] = '#include <ST7305_2p9_BW_DisplayDriver.h>';
    }
    
    Blockly.Arduino.definitions_['include_st73xx_ui'] = '#include <ST73XX_UI.h>';
    Blockly.Arduino.definitions_['include_st73xx_pins'] = '#include <ST73xxPins.h>';
    Blockly.Arduino.definitions_['include_u8g2'] = '#include <U8g2_for_ST73XX.h>';
    
    if (hasPins) {
        // 使用自定义引脚配置
        Blockly.Arduino.definitions_['var_declare_' + display_name] = 
            'const ST73xxPins PINS_' + display_name + '{' + dc_pin + ', ' + cs_pin + ', ' + sclk_pin + ', ' + sdin_pin + ', ' + rst_pin + '};\n';
        
        // 根据显示屏尺寸选择对应的驱动类
        if (display_size === '4p2') {
            Blockly.Arduino.definitions_['var_declare_' + display_name] += 
                'ST7305_4p2_BW_DisplayDriver ' + display_name + '(PINS_' + display_name + ', SPI);';
        } else if (display_size === '1p5') {
            Blockly.Arduino.definitions_['var_declare_' + display_name] += 
                'ST7305_1p5_BW_DisplayDriver ' + display_name + '(PINS_' + display_name + ', SPI);';
        } else {
            Blockly.Arduino.definitions_['var_declare_' + display_name] += 
                'ST7305_2p9_BW_DisplayDriver ' + display_name + '(PINS_' + display_name + ', SPI);';
        }
        
        // Setup代码
        Blockly.Arduino.setups_['setup_spi_' + display_name] = 'SPI.begin(' + sclk_pin + ', -1, ' + sdin_pin + ', ' + cs_pin + ');';
    } else {
        // 使用默认引脚配置（简化版）
        if (display_size === '4p2') {
            Blockly.Arduino.definitions_['var_declare_' + display_name] = 
                'ST7305_4p2_BW_DisplayDriver ' + display_name + '(SPI);';
        } else if (display_size === '1p5') {
            Blockly.Arduino.definitions_['var_declare_' + display_name] = 
                'ST7305_1p5_BW_DisplayDriver ' + display_name + '(SPI);';
        } else {
            Blockly.Arduino.definitions_['var_declare_' + display_name] = 
                'ST7305_2p9_BW_DisplayDriver ' + display_name + '(SPI);';
        }
        
        // Setup代码 - 使用默认SPI引脚
        Blockly.Arduino.setups_['setup_spi_' + display_name] = 'SPI.begin();';
    }
    
    // 通用的显示器初始化代码
    Blockly.Arduino.setups_['setup_display_' + display_name] = 
        display_name + '.initialize();';
    
    return '';
};

// 初始化ST7305显示器（简化版）- 已弃用，使用st7305_init替代
Blockly.Arduino.forBlock['st7305_init_simple'] = function(block) {
    // 重定向到st7305_init的代码生成器
    return Blockly.Arduino.forBlock['st7305_init'](block);
};

// 清屏
Blockly.Arduino.forBlock['st7305_clear'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var code = display_name + '.clearDisplay();\n';
    return code;
};

// 显示更新
Blockly.Arduino.forBlock['st7305_display'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var code = display_name + '.display();\n';
    return code;
};

// 设置显示反转
Blockly.Arduino.forBlock['st7305_invert'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var invert_state = block.getFieldValue('INVERT_STATE');
    var code = display_name + '.display_Inversion(' + invert_state + ');\n';
    return code;
};

// 设置电源模式
Blockly.Arduino.forBlock['st7305_power_mode'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var power_mode = block.getFieldValue('POWER_MODE');
    var code = display_name + '.' + power_mode + '();\n';
    return code;
};

// 设置显示开关
Blockly.Arduino.forBlock['st7305_display_on'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var display_state = block.getFieldValue('DISPLAY_STATE');
    var code = display_name + '.display_on(' + display_state + ');\n';
    return code;
};

// 画点
Blockly.Arduino.forBlock['st7305_draw_pixel'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var x = Blockly.Arduino.valueToCode(this, 'X', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var y = Blockly.Arduino.valueToCode(this, 'Y', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var color = block.getFieldValue('COLOR');
    var code = display_name + '.writePoint(' + x + ', ' + y + ', ' + color + ');\n';
    return code;
};

// 画线
Blockly.Arduino.forBlock['st7305_draw_line'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var x1 = Blockly.Arduino.valueToCode(this, 'X1', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var y1 = Blockly.Arduino.valueToCode(this, 'Y1', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var x2 = Blockly.Arduino.valueToCode(this, 'X2', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var y2 = Blockly.Arduino.valueToCode(this, 'Y2', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var color = block.getFieldValue('COLOR');
    var code = display_name + '.drawLine(' + x1 + ', ' + y1 + ', ' + x2 + ', ' + y2 + ', ' + color + ');\n';
    return code;
};

// 画矩形
Blockly.Arduino.forBlock['st7305_draw_rect'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var x1 = Blockly.Arduino.valueToCode(this, 'X1', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var y1 = Blockly.Arduino.valueToCode(this, 'Y1', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var x2 = Blockly.Arduino.valueToCode(this, 'X2', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var y2 = Blockly.Arduino.valueToCode(this, 'Y2', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var color = block.getFieldValue('COLOR');
    var code = display_name + '.drawRectangle(' + x1 + ', ' + y1 + ', ' + x2 + ', ' + y2 + ', ' + color + ');\n';
    return code;
};

// 画填充矩形
Blockly.Arduino.forBlock['st7305_draw_fill_rect'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var x1 = Blockly.Arduino.valueToCode(this, 'X1', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var y1 = Blockly.Arduino.valueToCode(this, 'Y1', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var x2 = Blockly.Arduino.valueToCode(this, 'X2', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var y2 = Blockly.Arduino.valueToCode(this, 'Y2', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var color = block.getFieldValue('COLOR');
    var code = display_name + '.drawFilledRectangle(' + x1 + ', ' + y1 + ', ' + x2 + ', ' + y2 + ', ' + color + ');\n';
    return code;
};

// 画圆
Blockly.Arduino.forBlock['st7305_draw_circle'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var x = Blockly.Arduino.valueToCode(this, 'X', Blockly.Arduino.ORDER_ATOMIC) || '50';
    var y = Blockly.Arduino.valueToCode(this, 'Y', Blockly.Arduino.ORDER_ATOMIC) || '50';
    var r = Blockly.Arduino.valueToCode(this, 'R', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var color = block.getFieldValue('COLOR');
    var code = display_name + '.drawCircle(' + x + ', ' + y + ', ' + r + ', ' + color + ');\n';
    return code;
};

// 画填充圆
Blockly.Arduino.forBlock['st7305_draw_fill_circle'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var x = Blockly.Arduino.valueToCode(this, 'X', Blockly.Arduino.ORDER_ATOMIC) || '50';
    var y = Blockly.Arduino.valueToCode(this, 'Y', Blockly.Arduino.ORDER_ATOMIC) || '50';
    var r = Blockly.Arduino.valueToCode(this, 'R', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var color = block.getFieldValue('COLOR');
    var code = display_name + '.drawFilledCircle(' + x + ', ' + y + ', ' + r + ', ' + color + ');\n';
    return code;
};

// 画三角形
Blockly.Arduino.forBlock['st7305_draw_triangle'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var x1 = Blockly.Arduino.valueToCode(this, 'X1', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var y1 = Blockly.Arduino.valueToCode(this, 'Y1', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var x2 = Blockly.Arduino.valueToCode(this, 'X2', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var y2 = Blockly.Arduino.valueToCode(this, 'Y2', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var x3 = Blockly.Arduino.valueToCode(this, 'X3', Blockly.Arduino.ORDER_ATOMIC) || '5';
    var y3 = Blockly.Arduino.valueToCode(this, 'Y3', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var color = block.getFieldValue('COLOR');
    var code = display_name + '.drawTriangle(' + x1 + ', ' + y1 + ', ' + x2 + ', ' + y2 + ', ' + x3 + ', ' + y3 + ', ' + color + ');\n';
    return code;
};

// 画填充三角形
Blockly.Arduino.forBlock['st7305_draw_fill_triangle'] = function(block) {
    var display_name = block.getFieldValue('DISPLAY_NAME');
    var x1 = Blockly.Arduino.valueToCode(this, 'X1', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var y1 = Blockly.Arduino.valueToCode(this, 'Y1', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var x2 = Blockly.Arduino.valueToCode(this, 'X2', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var y2 = Blockly.Arduino.valueToCode(this, 'Y2', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var x3 = Blockly.Arduino.valueToCode(this, 'X3', Blockly.Arduino.ORDER_ATOMIC) || '5';
    var y3 = Blockly.Arduino.valueToCode(this, 'Y3', Blockly.Arduino.ORDER_ATOMIC) || '10';
    var color = block.getFieldValue('COLOR');
    var code = display_name + '.drawFilledTriangle(' + x1 + ', ' + y1 + ', ' + x2 + ', ' + y2 + ', ' + x3 + ', ' + y3 + ', ' + color + ');\n';
    return code;
};

// 初始化U8g2文本显示
Blockly.Arduino.forBlock['st7305_u8g2_init'] = function(block) {
    var u8g2_name = block.getFieldValue('U8G2_NAME');
    var display_name = block.getFieldValue('DISPLAY_NAME');
    
    // 定义U8g2对象
    Blockly.Arduino.definitions_['var_declare_' + u8g2_name] = 
        'U8G2_FOR_ST73XX ' + u8g2_name + ';';
    
    // Setup代码
    Blockly.Arduino.setups_['setup_u8g2_' + u8g2_name] = 
        u8g2_name + '.begin(' + display_name + ');';
    
    return '';
};

// 设置字体
Blockly.Arduino.forBlock['st7305_set_font'] = function(block) {
    var u8g2_name = block.getFieldValue('U8G2_NAME');
    var font = Blockly.Arduino.valueToCode(block, 'FONT', Blockly.Arduino.ORDER_ATOMIC);
    // 如果没有提供字体值，使用默认字体
    if (!font) {
        font = 'u8g2_font_6x10_tf';
    }
    // 移除可能存在的双引号
    font = font.replace(/^"(.*)"$/, '$1');
    var code = u8g2_name + '.setFont(' + font + ');\n';
    return code;
};

// 设置文本颜色
Blockly.Arduino.forBlock['st7305_set_text_color'] = function(block) {
    var u8g2_name = block.getFieldValue('U8G2_NAME');
    var fg_color = block.getFieldValue('FG_COLOR');
    var bg_color = block.getFieldValue('BG_COLOR');
    var code = u8g2_name + '.setForegroundColor(' + fg_color + ');\n' +
               u8g2_name + '.setBackgroundColor(' + bg_color + ');\n';
    return code;
};

// 显示器显示内容（合并了设置光标位置、显示文本和显示变量，支持IP地址显示）
Blockly.Arduino.forBlock['st7305_display_content'] = function(block) {
    var u8g2_name = block.getFieldValue('U8G2_NAME');
    var x = Blockly.Arduino.valueToCode(this, 'X', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var y = Blockly.Arduino.valueToCode(this, 'Y', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var content = Blockly.Arduino.valueToCode(this, 'CONTENT', Blockly.Arduino.ORDER_ATOMIC) || '""';
    
    // 生成代码：先设置光标位置
    var code = u8g2_name + '.setCursor(' + x + ', ' + y + ');\n';
    
    // 检查是否是IPAddress类型的变量（通常包含.localIP()或IPAddress关键字）
    if (content.indexOf('localIP()') !== -1 || content.indexOf('IPAddress') !== -1) {
        // 对于IP地址，使用格式化方式显示
        code += 'char ipStr[16];\n';
        code += 'snprintf(ipStr, sizeof(ipStr), "%d.%d.%d.%d", ' + content + '[0], ' + content + '[1], ' + content + '[2], ' + content + '[3]);\n';
        code += u8g2_name + '.print(ipStr);\n';
    } else {
        // 对于普通内容，使用原来的方式显示
        code += u8g2_name + '.print(String(' + content + '));\n';
    }
    
    return code;
};

// 设置字体方向
Blockly.Arduino.forBlock['st7305_set_font_direction'] = function(block) {
    var u8g2_name = block.getFieldValue('U8G2_NAME');
    var direction = block.getFieldValue('DIRECTION');
    var code = u8g2_name + '.setFontDirection(' + direction + ');\n';
    return code;
};

    // 记录触发时间积木代码生成器
    Blockly.Arduino.forBlock['debounce_trigger'] = function() {
        var instance = this.getFieldValue('INSTANCE');
        
        // 定义全局数组变量
        Blockly.Arduino.definitions_['debounce_var'] = 
            'unsigned long debounce_lastUpdate[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\n' +
            'int debounce_executeCount[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};';
        
        // 生成记录时间的代码
        var code = 'debounce_lastUpdate[' + instance + '] = millis();\n';
        code += 'debounce_executeCount[' + instance + '] = 0;\n';  // 重置执行计数
        
        return code;
    };

    // 检查时间差后执行积木代码生成器
    Blockly.Arduino.forBlock['debounce_check_execute'] = function() {
        var instance = this.getFieldValue('INSTANCE');
        var delayTime = this.getFieldValue('DEBOUNCE_DELAY');
        var executeCount = this.getFieldValue('EXECUTE_COUNT');
        var statements_do = Blockly.Arduino.statementToCode(this, 'DO');
        
        // 生成检查时间和执行的代码
        var code = 'if (millis() - debounce_lastUpdate[' + instance + '] >= ' + delayTime + ' && ';
        code += 'debounce_executeCount[' + instance + '] < ' + executeCount + ') {\n';
        code += statements_do;
        code += '\n  debounce_lastUpdate[' + instance + '] = millis();\n';  // 添加时间戳更新
        code += '  debounce_executeCount[' + instance + ']++;\n';  // 增加执行计数
        code += '}\n';
        
        return code;
    };



    // 生成必要的头文件和变量声明
    function generateTaskSchedulerSetup() {
        // 包含TaskScheduler库
        Blockly.Arduino.definitions_['include_taskscheduler'] = '#define _TASK_PRIORITY\n#include <TaskScheduler.h>';
        
        // 声明调度器对象
        Blockly.Arduino.definitions_['declare_scheduler'] = 'Scheduler ts;';
        
        // 声明任务数组（用于存储创建的任务）
        Blockly.Arduino.definitions_['declare_task_array'] = 'Task* taskArray[10];\nint taskCount = 0;';
        
        // 声明当前任务指针（用于任务切换）
        Blockly.Arduino.definitions_['declare_current_task'] = 'Task* currentTask = NULL;';
        
        // 通用回调函数
        Blockly.Arduino.definitions_['generic_callbacks'] = `
void genericCallback() {
    // 通用回调函数
}

void genericOnEnable() {
    // 任务启用回调
}

void genericOnDisable() {
    // 任务禁用回调
}

// 减少millis()调用频率
unsigned long lastMillis = 0;
unsigned long currentMillis = 0;

// 优化的millis()函数，减少调用频率
inline unsigned long optimizedMillis() {
    currentMillis = millis();
    // 只有当时间实际变化时才更新
    if (currentMillis != lastMillis) {
        lastMillis = currentMillis;
    }
    return currentMillis;
}
`;
    }
    
    // 添加任务前向声明
    function addTaskForwardDeclaration(taskName) {
        // 确保总是添加前向声明
        Blockly.Arduino.definitions_['var_declare_task_forward_declare_' + taskName] = 
            'extern Task ' + taskName + ';';
    }
    
    // 统一任务创建代码生成器 - 简化版
    Blockly.Arduino.forBlock['tasks_scheduler_create_unified'] = function(block) {
        generateTaskSchedulerSetup();
        
        const taskName = block.getFieldValue('taskName') || 'myTask';
        let interval = Blockly.Arduino.valueToCode(block, 'interval', Blockly.Arduino.ORDER_ATOMIC) || '1000';
        
        // 获取控制方式
        const controlMode = block.getFieldValue('controlMode') || 'byCount';
        
        // 获取运行时长和切换到字段
        const executionDuration = Blockly.Arduino.valueToCode(block, 'executionDuration', Blockly.Arduino.ORDER_ATOMIC) || '0';
        const switchTo = block.getFieldValue('switchTo') || 'none';
        const switchToTask = Blockly.Arduino.valueToCode(block, 'switchToTask', Blockly.Arduino.ORDER_ATOMIC) || '';
        
        // 根据控制方式确定运行次数和间隔
        let iterations = '10'; // 默认值
        let taskComment = '任务回调代码';
        
        if (controlMode === 'byDuration') {
            // 按时长运行：设置为无限循环，间隔设为100ms（用于检查时间）
            interval = '100'; // 每100ms检查一次
            iterations = '-1';
            taskComment = '按时长运行任务回调代码';
        } else {
            // 按次数运行
            iterations = Blockly.Arduino.valueToCode(block, 'iterations', Blockly.Arduino.ORDER_ATOMIC) || '10';
            taskComment = '任务回调代码';
        }
        
        // 生成唯一的回调函数名
        const callbackName = 'taskCallback_' + taskName;
        
        // 获取语句输入的代码
        const callbackCode = Blockly.Arduino.statementToCode(block, 'callback');
        
        // 为所有任务添加时间跟踪变量（支持任务切换时的状态重置）
        Blockly.Arduino.definitions_['var_declare_task_start_time_' + taskName] = 
            'unsigned long ' + taskName + '_startTime = 0;';
        
        Blockly.Arduino.definitions_['var_declare_task_executing_' + taskName] = 
            'bool ' + taskName + '_isExecuting = false;';
        
        // 如果是按时长运行，添加运行时长变量
        if (controlMode === 'byDuration' && executionDuration !== '0' && parseInt(executionDuration) > 0) {
            Blockly.Arduino.definitions_['var_declare_task_duration_' + taskName] = 
                'unsigned long ' + taskName + '_executionDuration = ' + executionDuration + ';';
        }
        
        // 生成回调函数
        if (callbackCode.trim()) {
            // Add proper indentation to match function body
            const indentedCallback = callbackCode.split('\n').map(line => line.trim() ? '  ' + line : line).join('\n');
            
            // 如果是按时长运行，添加时间检查逻辑
            if (controlMode === 'byDuration' && executionDuration !== '0' && parseInt(executionDuration) > 0) {
                let switchCode = '';
                
                // 根据切换到选项生成不同的切换代码
                if (switchTo === 'specified' && switchToTask) {
                    const targetTaskName = switchToTask.replace(/"/g, '');
                    switchCode = `
  // 切换到指定任务
  ${taskName}.disable();
  ${targetTaskName}.enable();
  ${targetTaskName}_isExecuting = false; // 重置目标任务执行状态
  ${targetTaskName}_startTime = 0; // 重置目标任务开始时间
  taskCallback_${targetTaskName}(); // 立即执行一次回调
  currentTask = &${targetTaskName};
  ${taskName}_isExecuting = false;`;
                }
                
                Blockly.Arduino.definitions_['callback_' + callbackName] = 
                    'void ' + callbackName + '() {\n' + 
                    '  // 检查运行时长\n' +
                    '  if (!' + taskName + '_isExecuting) {\n' +
                    '    ' + taskName + '_startTime = millis();\n' +
                    '    ' + taskName + '_isExecuting = true;\n' +
                    '  }\n' +
                    '  \n' +
                    '  unsigned long currentTime = millis();\n' +
                    '  if (currentTime - ' + taskName + '_startTime >= ' + taskName + '_executionDuration) {\n' +
                    switchCode + '\n' +
                    '    return;\n' +
                    '  }\n' +
                    '  \n' +
                    indentedCallback + 
                    '}\n';
            } else {
                // 按次数运行模式
                let switchCode = '';
                
                if (switchTo === 'specified' && switchToTask) {
                    const targetTaskName = switchToTask.replace(/"/g, '');
                    switchCode = `
  // 检查是否执行完所有次数
  if (${taskName}.getRunCounter() >= ${iterations} - 1) {
    ${taskName}.disable();
    ${targetTaskName}.enable();
    ${targetTaskName}_isExecuting = false; // 重置目标任务执行状态
    ${targetTaskName}_startTime = 0; // 重置目标任务开始时间
    taskCallback_${targetTaskName}(); // 立即执行一次回调
    currentTask = &${targetTaskName};
  }
`;
                }
                
                Blockly.Arduino.definitions_['callback_' + callbackName] = 
                    'void ' + callbackName + '() {\n' + 
                    indentedCallback + 
                    switchCode +
                    '}\n';
            }
        } else {
                // 如果没有回调代码，生成默认回调
                if (controlMode === 'byDuration' && executionDuration !== '0' && parseInt(executionDuration) > 0) {
                    let switchCode = '';
                    
                    if (switchTo === 'specified' && switchToTask) {
                        const targetTaskName = switchToTask.replace(/"/g, '');
                    switchCode = `
  // 切换到指定任务
  ${taskName}.disable();
  ${targetTaskName}.enable();
  ${targetTaskName}_isExecuting = false; // 重置目标任务执行状态
  ${targetTaskName}_startTime = 0; // 重置目标任务开始时间
  taskCallback_${targetTaskName}(); // 立即执行一次回调
  currentTask = &${targetTaskName};
  ${taskName}_isExecuting = false;`;
                    }
                
                Blockly.Arduino.definitions_['callback_' + callbackName] = 
                    'void ' + callbackName + '() {\n' + 
                    '  // ' + taskComment + '\n' +
                    '  // 检查运行时长\n' +
                    '  if (!' + taskName + '_isExecuting) {\n' +
                    '    ' + taskName + '_startTime = millis();\n' +
                    '    ' + taskName + '_isExecuting = true;\n' +
                    '  }\n' +
                    '  \n' +
                    '  unsigned long currentTime = millis();\n' +
                    '  if (currentTime - ' + taskName + '_startTime >= ' + taskName + '_executionDuration) {\n' +
                    switchCode + '\n' +
                    '    return;\n' +
                    '  }\n' +
                    '}\n';
            } else {
                // 按次数运行模式
                let switchCode = '';
                
                if (switchTo === 'specified' && switchToTask) {
                    const targetTaskName = switchToTask.replace(/"/g, '');
                    switchCode = `
  // 检查是否执行完所有次数
  if (${taskName}.getRunCounter() >= ${iterations} - 1) {
    ${taskName}.disable();
    ${targetTaskName}.enable();
    ${targetTaskName}_isExecuting = false; // 重置目标任务执行状态
    ${targetTaskName}_startTime = 0; // 重置目标任务开始时间
    taskCallback_${targetTaskName}(); // 立即执行一次回调
    currentTask = &${targetTaskName};
  }
`;
                }
                
                Blockly.Arduino.definitions_['callback_' + callbackName] = 
                    'void ' + callbackName + '() {\n' + 
                    '  // ' + taskComment + '\n' + 
                    switchCode +
                    '}\n';
            }
        }
        
        // 添加任务前向声明
        addTaskForwardDeclaration(taskName);
        
        // 生成任务声明 - 必须放在全局作用域
        Blockly.Arduino.definitions_['task_declare_' + taskName] = 
            'Task ' + taskName + '(' + interval + ', ' + iterations + ', &' + callbackName + ', &ts, false, NULL, NULL);';
        
        // 重置任务数组计数器为0
        if (!Blockly.Arduino.setups_['setup_reset_task_count_unified']) {
            Blockly.Arduino.setups_['setup_reset_task_count_unified'] = '  taskCount = 0; // 重置任务计数器\n';
        }
        
        // 将任务添加到数组的代码应该在setup函数中执行
        if (!Blockly.Arduino.setups_['setup_add_task_' + taskName]) {
            Blockly.Arduino.setups_['setup_add_task_' + taskName] = '  taskArray[taskCount++] = &' + taskName + '; // 添加任务 "' + taskName + '" 到数组\n';
        }
        
        // 设置第一个任务为当前任务
        if (!Blockly.Arduino.setups_['setup_set_current_task']) {
            Blockly.Arduino.setups_['setup_set_current_task'] = '  currentTask = taskArray[0]; // 设置第一个任务为当前任务\n';
        }
        
        // 使用definitions_添加宏定义作为标志，确保ts.execute()只添加一次
        if (!Blockly.Arduino.definitions_['execute_scheduler_added']) {
            Blockly.Arduino.definitions_['execute_scheduler_added'] = '#define EXECUTE_SCHEDULER_ADDED';
            // 返回ts.execute()代码，确保它在loop函数中被执行
            return '  ts.execute();\n';
        }
        
        // 返回空字符串，避免重复添加ts.execute()
        return '';
    };
    
    // 设置任务间隔代码生成器
    
    // 设置任务间隔代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_set_interval'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || '"task"';
        var interval = Blockly.Arduino.valueToCode(block, 'interval', Blockly.Arduino.ORDER_ATOMIC) || '1000';
        
        var code = task.replace(/"/g, '') + '.setInterval(' + interval + ');\n';
        return code;
    };
    
    // 设置运行次数代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_set_iterations'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || '"task"';
        var iterations = Blockly.Arduino.valueToCode(block, 'iterations', Blockly.Arduino.ORDER_ATOMIC) || '10';
        
        var code = task.replace(/"/g, '') + '.setIterations(' + iterations + ');\n';
        return code;
    };
    
    // 设置运行时长代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_set_duration'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || '"task"';
        var duration = Blockly.Arduino.valueToCode(block, 'duration', Blockly.Arduino.ORDER_ATOMIC) || '3000';
        var taskName = task.replace(/"/g, '');
        
        // 修改运行时长变量
        var code = taskName + '_executionDuration = ' + duration + ';\n';
        return code;
    };
    
    // 任务启用状态查询代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_is_enabled'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || '"task"';
        
        var code = task.replace(/"/g, '') + '.isEnabled()';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };
    
    // 重置任务代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_restart'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || '"task"';
        
        var code = task.replace(/"/g, '') + '.restart();\n';
        return code;
    };
    
    // 获取任务剩余迭代次数代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_get_iterations'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || '"task"';
        
        var code = task.replace(/"/g, '') + '.getIterations()';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };
    
    // 获取任务时间间隔代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_get_interval'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || '"task"';
        
        var code = task.replace(/"/g, '') + '.getInterval()';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };
    
    // 获取任务运行时长代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_get_duration'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || '"task"';
        var taskName = task.replace(/"/g, '');
        
        var code = taskName + '_executionDuration';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };
    
    // 通用任务切换代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_switch'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || 'otherTask';
        
        // 清理任务名称（去掉引号）
        var cleanTaskName = task.replace(/"/g, '');
        
        // 先禁用当前任务，再启用新任务
        var code = '// 任务切换到: ' + cleanTaskName + '\n';
        code += 'if (currentTask != NULL) {\n';
        code += '  currentTask->disable();\n';
        code += '}\n';
        code += cleanTaskName + '.enable();\n';
        code += 'currentTask = &' + cleanTaskName + ';\n';
        
        return code;
    };
    
    // 执行任务代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_enable'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || '"task"';
        var taskName = task.replace(/"/g, '');
        
        // 重置任务计数器并启用任务，然后立即执行一次回调
        var code = taskName + '.restart();\n';  // 重置计数器并启用任务
        code += 'taskCallback_' + taskName + '(); // 立即执行一次回调\n';
        code += 'currentTask = &' + taskName + '; // 设置为当前任务\n';
        return code;
    };
    
    // 禁用任务代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_disable'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || '"task"';
        
        var code = task.replace(/"/g, '') + '.disable();\n';
        return code;
    };
    // RTC整数变量
    Blockly.Arduino.forBlock['espsleep_esp32_rtc_int'] = function(block) {
        var varName = block.getFieldValue('VAR_NAME');
        var initVal = Blockly.Arduino.valueToCode(block, 'INIT_VAL', Blockly.Arduino.ORDER_ATOMIC) || '0';

        Blockly.Arduino.definitions_['var_declare_' + varName] = 'RTC_DATA_ATTR int ' + varName + ' = ' + initVal + ';';
        return '';
    };

    // 设置RTC变量
    Blockly.Arduino.forBlock['espsleep_esp32_set_rtc'] = function(block) {
        var varName = block.getFieldValue('VAR_NAME');
        var value = Blockly.Arduino.valueToCode(block, 'VALUE', Blockly.Arduino.ORDER_ATOMIC) || '0';

        var code = varName + ' = ' + value + ';\n';
        return code;
    };

    // 获取RTC变量
    Blockly.Arduino.forBlock['espsleep_esp32_get_rtc'] = function(block) {
        var varName = block.getFieldValue('VAR_NAME');

        var code = varName;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };
    Blockly.Arduino.forBlock['espsleep_esp32_info'] = function(block) {
  return '';
    };
    // 设置定时唤醒睡眠
    Blockly.Arduino.forBlock['espsleep_esp32_timer_wakeup'] = function(block) {
        var sec = Blockly.Arduino.valueToCode(block, 'SEC', Blockly.Arduino.ORDER_ATOMIC) || '60';

        Blockly.Arduino.definitions_['include_esp_sleep'] = '#include <esp_sleep.h>';

        var code = 'esp_sleep_enable_timer_wakeup(' + sec + ' * 1000000ULL);\n';
        return code;
    };

    // 设置外部引脚唤醒
    Blockly.Arduino.forBlock['espsleep_esp32_gpio_wakeup'] = function(block) {
        var pin = Blockly.Arduino.valueToCode(block, 'PIN', Blockly.Arduino.ORDER_ATOMIC) || '0';
        var level = block.getFieldValue('LEVEL');

        Blockly.Arduino.definitions_['include_esp_sleep'] = '#include <esp_sleep.h>';

        var code = 
            '#if CONFIG_IDF_TARGET_ESP32\n' +
            '    esp_sleep_enable_ext0_wakeup(GPIO_NUM_' + pin + ', ' + level + ');\n' +
            '#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3\n' +
            '    gpio_wakeup_enable(GPIO_NUM_' + pin + ', GPIO_INTR_' + (level === '1' ? 'POSEDGE' : 'NEGEDGE') + ');\n' +
            '    esp_sleep_enable_gpio_wakeup();\n' +
            '#endif\n';
        return code;
    };

    // 进入深度睡眠
    Blockly.Arduino.forBlock['espsleep_esp32_deep_sleep'] = function(block) {
        Blockly.Arduino.definitions_['include_esp_sleep'] = '#include <esp_sleep.h>';

        var code = 'esp_deep_sleep_start();\n';
        return code;
    };

    // 进入浅度睡眠
    Blockly.Arduino.forBlock['espsleep_esp32_light_sleep'] = function(block) {
        Blockly.Arduino.definitions_['include_esp_sleep'] = '#include <esp_sleep.h>';

        var code = 'esp_light_sleep_start();\n';
        return code;
    };

    // 快速深度睡眠
    Blockly.Arduino.forBlock['espsleep_esp32_quick_sleep'] = function(block) {
        var sec = Blockly.Arduino.valueToCode(block, 'SEC', Blockly.Arduino.ORDER_ATOMIC) || '60';

        Blockly.Arduino.definitions_['include_esp_sleep'] = '#include <esp_sleep.h>';

        var code = 
            'esp_sleep_enable_timer_wakeup(' + sec + ' * 1000000ULL);\n' +
            'esp_deep_sleep_start();\n';
        return code;
    };

    // 设置CPU频率
    Blockly.Arduino.forBlock['espsleep_esp32_set_cpu_freq'] = function(block) {
        var freq = block.getFieldValue('FREQ');

        Blockly.Arduino.definitions_['include_esp_system'] = '#include <esp_system.h>';

        var code = 'setCpuFrequencyMhz(' + freq + ');\n';
        return code;
    };
    // 简单无阻塞延时代码生成器 - 使用状态机模式实现非阻塞延时
    Blockly.Arduino.forBlock['tasks_scheduler_yield'] = function (block) {
        var duration = Blockly.Arduino.valueToCode(this, 'duration', Blockly.Arduino.ORDER_ATOMIC) || '1000';
        
        // 自动检测当前任务上下文
        var currentTask = '';
        
        // 查找当前所在的回调函数
        var parentBlock = block.getSurroundParent();
        while (parentBlock) {
            if (parentBlock.type === 'tasks_scheduler_create_unified') {
                // 从统一任务创建积木获取任务名称
                currentTask = parentBlock.getFieldValue('taskName') || 'myTask';
                break;
            } else if (parentBlock.type === 'tasks_scheduler_create_multiple' || parentBlock.type === 'tasks_scheduler_create_multiple_simple') {
                // 从多任务创建积木获取当前任务名称
                // 改进方法：检查当前块是否在某个任务的回调语句中
                var taskCount = 0;
                while (parentBlock.getInput('TASK_CALLBACK' + taskCount)) {
                    var callbackInput = parentBlock.getInput('TASK_CALLBACK' + taskCount);
                    if (callbackInput && callbackInput.connection) {
                        // 获取回调语句中的第一个块
                        var firstBlockInCallback = callbackInput.connection.targetBlock();
                        if (firstBlockInCallback) {
                            // 检查当前块是否在回调语句的块链中
                            // 方法1：直接检查是否是第一个块
                            if (block === firstBlockInCallback) {
                                var taskName = Blockly.Arduino.valueToCode(parentBlock, 'TASK_NAME' + taskCount, Blockly.Arduino.ORDER_ATOMIC) || ('"task' + (taskCount + 1) + '"');
                                currentTask = taskName.replace(/"/g, '');
                                break;
                            }
                            
                            // 方法2：检查是否在块链中（向后遍历）
                            var checkBlock = firstBlockInCallback;
                            while (checkBlock) {
                                if (checkBlock === block) {
                                    var taskName = Blockly.Arduino.valueToCode(parentBlock, 'TASK_NAME' + taskCount, Blockly.Arduino.ORDER_ATOMIC) || ('"task' + (taskCount + 1) + '"');
                                    currentTask = taskName.replace(/"/g, '');
                                    break;
                                }
                                checkBlock = checkBlock.getNextBlock();
                            }
                            
                            // 方法3：如果方法2没找到，尝试从当前块向上遍历到第一个块
                            if (!currentTask) {
                                checkBlock = block;
                                while (checkBlock) {
                                    if (checkBlock === firstBlockInCallback) {
                                        var taskName = Blockly.Arduino.valueToCode(parentBlock, 'TASK_NAME' + taskCount, Blockly.Arduino.ORDER_ATOMIC) || ('"task' + (taskCount + 1) + '"');
                                        currentTask = taskName.replace(/"/g, '');
                                        break;
                                    }
                                    checkBlock = checkBlock.getSurroundParent();
                                }
                            }
                            
                            if (currentTask) break;
                        }
                    }
                    if (currentTask) break;
                    taskCount++;
                }
                break;
            }
            parentBlock = parentBlock.getSurroundParent();
        }
        
        // 如果没有找到任务上下文，使用默认值
        if (!currentTask) {
            currentTask = 'myTask';
        }
        
        // 生成非阻塞延时代码 - 使用静态变量和状态机模式
        var stateVar = currentTask + '_delayState';
        var timeVar = currentTask + '_delayTime';
        
        var code = '// 非阻塞延时实现 - 状态机模式\n';
        code += 'static unsigned long ' + timeVar + ' = 0;\n';
        code += 'static int ' + stateVar + ' = 0;\n';
        code += 'switch(' + stateVar + ') {\n';
        code += '  case 0:\n';
        code += '    ' + timeVar + ' = optimizedMillis();\n';
        code += '    ' + stateVar + ' = 1;\n';
        code += '    return; // 立即返回，下次继续\n';
        code += '  case 1:\n';
        code += '    if (optimizedMillis() - ' + timeVar + ' >= ' + duration + ') {\n';
        code += '      ' + stateVar + ' = 0; // 重置状态\n';
        code += '      // 延时结束，继续执行后面的代码\n';
        code += '    } else {\n';
        code += '      return; // 延时未结束，继续等待\n';
        code += '    }\n';
        code += '    break;\n';
        code += '}\n';
        
        return code;
    };
    
    // 通用任务切换代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_switch'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || 'otherTask';
        
        // 清理任务名称（去掉引号）
        var cleanTaskName = task.replace(/"/g, '');
        
        // 先禁用当前任务，再启用新任务
        var code = '// 任务切换到: ' + cleanTaskName + '\n';
        code += 'if (currentTask != NULL) {\n';
        code += '  currentTask->disable();\n';
        code += '}\n';
        code += cleanTaskName + '.enable();\n';
        code += 'currentTask = &' + cleanTaskName + ';\n';
        
        return code;
    };
    

    
    // 禁用任务代码生成器
    Blockly.Arduino.forBlock['tasks_scheduler_disable'] = function(block) {
        var task = Blockly.Arduino.valueToCode(block, 'task', Blockly.Arduino.ORDER_ATOMIC) || '"task"';
        
        var code = task.replace(/"/g, '') + '.disable();\n';
        return code;
    };
    
Blockly.Arduino.forBlock['make_arduino_describe'] = function(block) {

  return  ' 作  者 ： \n' +
  ' 回到  未来\n' +
  ' QQ : 375091377\n';
};
    Blockly.Arduino.forBlock['acan_esp32_init'] = function(block) {
        var bitRate = block.getFieldValue('BIT_RATE');
        var canMode = block.getFieldValue('CAN_MODE');
        var rxPin = Blockly.Arduino.valueToCode(block, 'RX_PIN', Blockly.Arduino.ORDER_ATOMIC);
        var txPin = Blockly.Arduino.valueToCode(block, 'TX_PIN', Blockly.Arduino.ORDER_ATOMIC);

        rxPin = 'GPIO_NUM_' + rxPin;
        txPin = 'GPIO_NUM_' + txPin;

        var code = '';
        Blockly.Arduino.definitions_['include_acanesp32'] = '#include <ACAN_ESP32.h>';
        Blockly.Arduino.setups_['setup_acan_settings'] =
            'ACAN_ESP32_Settings settings (' + bitRate + ' * 1000UL);\n' +
            '  settings.mRequestedCANMode = ACAN_ESP32_Settings::' + canMode + ';\n' +
            '  settings.mRxPin = ' + rxPin + ';\n' +
            '  settings.mTxPin = ' + txPin + ';\n' +
            '  const uint32_t errorCode = ACAN_ESP32::can.begin(settings);\n' +
            '  if (errorCode == 0) {\n' +
            '    Serial.println("CAN配置成功!");\n' +
            '    Serial.print("实际波特率: ");\n' +
            '    Serial.print(settings.actualBitRate());\n' +
            '    Serial.println(" bit/s");\n' +
            '  } else {\n' +
            '    Serial.print("CAN配置错误 0x");\n' +
            '    Serial.println(errorCode, HEX);\n' +
            '  }';

        return code;
    };

    Blockly.Arduino.forBlock['acan_esp32_send'] = function(block) {
        var canId = Blockly.Arduino.valueToCode(block, 'CAN_ID', Blockly.Arduino.ORDER_ATOMIC);
        var ext = block.getFieldValue('EXT') === 'TRUE';
        var rtr = block.getFieldValue('RTR') === 'TRUE';
        var dataLength = Blockly.Arduino.valueToCode(block, 'DATA_LENGTH', Blockly.Arduino.ORDER_ATOMIC);
        var data = Blockly.Arduino.valueToCode(block, 'DATA', Blockly.Arduino.ORDER_ATOMIC);

        Blockly.Arduino.definitions_['var_declare_can_frame'] = 'CANMessage frame;';

        var code = 'frame.id = ' + canId + ';\n';
        code += 'frame.ext = ' + ext + ';\n';
        code += 'frame.rtr = ' + rtr + ';\n';
        code += 'frame.len = ' + dataLength + ';\n';
        code += 'frame.data[0] = (' + data + ' >> 0) & 0xFF;\n';
        code += 'frame.data[1] = (' + data + ' >> 8) & 0xFF;\n';
        code += 'frame.data[2] = (' + data + ' >> 16) & 0xFF;\n';
        code += 'frame.data[3] = (' + data + ' >> 24) & 0xFF;\n';
        code += 'ACAN_ESP32::can.tryToSend(frame);\n';

        return code;
    };

    Blockly.Arduino.forBlock['acan_esp32_available'] = function(block) {
        var code = 'ACAN_ESP32::can.available()';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    Blockly.Arduino.forBlock['acan_esp32_receive'] = function(block) {
        var varName = Blockly.Arduino.valueToCode(block, 'VAR', Blockly.Arduino.ORDER_ATOMIC);
        Blockly.Arduino.definitions_['var_declare_canmessage'] = 'CANMessage ' + varName + ';';
        var code = 'ACAN_ESP32::can.receive(' + varName + ');\n';
        return code;
    };

    Blockly.Arduino.forBlock['acan_esp32_get_id'] = function(block) {
        var varName = Blockly.Arduino.valueToCode(block, 'VAR', Blockly.Arduino.ORDER_ATOMIC);

        var code = varName + '.id';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    Blockly.Arduino.forBlock['acan_esp32_get_data'] = function(block) {
        var varName = Blockly.Arduino.valueToCode(block, 'VAR', Blockly.Arduino.ORDER_ATOMIC);
        var index = Blockly.Arduino.valueToCode(block, 'INDEX', Blockly.Arduino.ORDER_ATOMIC);

        var code = varName + '.data[' + index + ']';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    Blockly.Arduino.forBlock['acan_esp32_get_length'] = function(block) {
        var varName = Blockly.Arduino.valueToCode(block, 'VAR', Blockly.Arduino.ORDER_ATOMIC);

        var code = varName + '.len';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    Blockly.Arduino.forBlock['acan_esp32_status'] = function(block) {
        var statusType = block.getFieldValue('STATUS_TYPE');
        var code = '';

        switch(statusType) {
            case 'RX_ERR':
                code = 'ACAN_ESP32::can.TWAI_RX_ERR_CNT_REG()';
                break;
            case 'TX_ERR':
                code = 'ACAN_ESP32::can.TWAI_TX_ERR_CNT_REG()';
                break;
            case 'BUSOFF':
                code = '((ACAN_ESP32::can.statusFlags() & 4) ? "BusOff" : "正常")';
                break;
        }

        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    Blockly.Arduino.forBlock['acan_esp32_recover_busoff'] = function(block) {
        var code = 'ACAN_ESP32::can.recoverFromBusOff();\n';
        return code;
    };

    Blockly.Arduino.forBlock['u8g2_init'] = function(block) {
      // 获取用户选择的参数
      var object_name = block.getFieldValue('object_name');
      var display_type = block.getFieldValue('display_type');
      var rotation = block.getFieldValue('rotation');
      // 从下拉选择框获取SCL和SDA引脚值
      var scl_pin = block.getFieldValue('scl_value') || '21';
      var sda_pin = block.getFieldValue('sda_value') || '20';
      var i2c_address = block.getFieldValue('i2c_address') || '0x3C';
      
      // 添加头文件
      Blockly.Arduino.definitions_['include_u8g2'] = '#include <U8g2lib.h>';
      // 确保添加Wire库头文件
      Blockly.Arduino.definitions_['include_wire'] = '#include <Wire.h>';
      
      // 检查是否为软件I2C
      var isSoftwareI2C = display_type && display_type.includes('_SW_I2C');
      
      // 直接使用display_type作为构造函数名（已包含完整接口后缀）
      var constructor_name = 'U8G2_' + display_type;
      
      // 根据是否为软件I2C选择构造函数格式
      var u8g2_declaration;
      
      if (isSoftwareI2C) {
        // 软件I2C构造函数格式，参数顺序为：rotation, scl, sda, reset
        u8g2_declaration = constructor_name + ' ' + object_name + '(' + rotation + ', ' + scl_pin + ', ' + sda_pin + ', U8X8_PIN_NONE);';
      } else {
        // 硬件I2C构造函数格式，参数顺序为：rotation, reset
        u8g2_declaration = constructor_name + ' ' + object_name + '(' + rotation + ', U8X8_PIN_NONE);';
      }
      
      // 添加全局变量声明
      Blockly.Arduino.definitions_['u8g2_object'] = u8g2_declaration;
      
      // 生成setup代码
      var setup_code = object_name + '.setI2CAddress(' + i2c_address + '*2);\n' + object_name + '.begin();';
      
      // 添加setup代码
      Blockly.Arduino.setups_['setup_u8g2'] = setup_code;
      
      return '';
    };
    
    // 8080协议初始化块的代码生成器
    Blockly.Arduino.forBlock['u8g2_8080_init'] = function(block) {
      // 获取用户选择的参数
      var object_name = block.getFieldValue('object_name');
      var display_type = block.getFieldValue('display_type');
      var rotation = block.getFieldValue('rotation');
      
      // 添加头文件
      Blockly.Arduino.definitions_['include_u8g2'] = '#include <U8g2lib.h>';
      
      // 根据设备类型生成声明
      var u8g2_declaration;
      
      // 处理NULL设备
      if (display_type === 'U8G2_NULL') {
        // NULL设备构造函数格式
        u8g2_declaration = display_type + ' ' + object_name + ';';
      } else {
        // 从下拉选择框获取引脚值
        var d0 = block.getFieldValue('d0_value') || '2';
        var d1 = block.getFieldValue('d1_value') || '3';
        var d2 = block.getFieldValue('d2_value') || '4';
        var d3 = block.getFieldValue('d3_value') || '5';
        var d4 = block.getFieldValue('d4_value') || '6';
        var d5 = block.getFieldValue('d5_value') || '7';
        var d6 = block.getFieldValue('d6_value') || '8';
        var d7 = block.getFieldValue('d7_value') || '9';
        var enable = block.getFieldValue('enable_value') || '10';
        var cs = block.getFieldValue('cs_value') || '11';
        var reset = block.getFieldValue('reset_value') || 'U8X8_PIN_NONE';
        
        // 使用8080接口构造函数格式
        // 参数顺序：rotation, d0, d1, d2, d3, d4, d5, d6, d7, enable, cs, dc, reset
        u8g2_declaration = display_type + ' ' + object_name + '(' + rotation + ', ' + 
                             d0 + ', ' + d1 + ', ' + d2 + ', ' + d3 + ', ' + 
                             d4 + ', ' + d5 + ', ' + d6 + ', ' + d7 + ', ' + 
                             enable + ', ' + cs + ', ' + reset + ');';
      }
      
      // 添加全局变量声明
      Blockly.Arduino.definitions_['u8g2_8080_object'] = u8g2_declaration;
      
      // 生成setup代码
      var setup_code = object_name + '.begin();';
      
      // 添加setup代码
      Blockly.Arduino.setups_['setup_u8g2_8080'] = setup_code;
      
      return '';
    };
  
    Blockly.Arduino.forBlock['u8g2_spi_init'] = function(block) {
      // 获取用户选择的参数
      var object_name = block.getFieldValue('object_name');
      var display_type = block.getFieldValue('display_type');
      var rotation = block.getFieldValue('rotation');
      
      // 添加头文件
      Blockly.Arduino.definitions_['include_u8g2'] = '#include <U8g2lib.h>';
      // 确保添加SPI库头文件
      Blockly.Arduino.definitions_['include_spi'] = '#include <SPI.h>';
      
      // 根据设备类型生成声明
      var u8g2_declaration;
      
      // 处理NULL设备
      if (display_type === 'U8G2_NULL') {
        // NULL设备构造函数格式
        u8g2_declaration = display_type + ' ' + object_name + ';';
      } else {
        
        // 从下拉选择框获取SPI引脚值
        var cs = block.getFieldValue('cs_value') || '10';
        var dc = block.getFieldValue('dc_value') || '9';
        var reset = block.getFieldValue('reset_value') || '8';
        var sck = block.getFieldValue('sck_value') || '13';
        var mosi = block.getFieldValue('mosi_value') || '11';
        
        // 直接使用display_type作为构造函数名（已包含U8G2_前缀）
        var constructor_name = display_type;
        
        // 检查是否为硬件SPI模式 - 注意：先检查2ND再检查HW，因为2ND包含HW
        // 3线SPI格式: _3W_HW_SPI (硬件) 或 _3W_SW_SPI (软件)
        var is3WireSPI = display_type.includes('_3W_');
        
        if (display_type.includes('_2ND_4W_HW_SPI')) {
          // 第二硬件SPI构造函数格式，参数顺序为：rotation, cs, dc, reset
          u8g2_declaration = constructor_name + ' ' + object_name + '(' + rotation + ',' + cs + ',' + dc + ',' + reset + ');';
        } else if (display_type.includes('_HW_SPI')) {
          if (is3WireSPI) {
            // 3线硬件SPI构造函数格式，参数顺序为：rotation, cs, reset
            u8g2_declaration = constructor_name + ' ' + object_name + '(' + rotation + ',' + cs + ',' + reset + ');';
          } else {
            // 4线硬件SPI构造函数格式，参数顺序为：rotation, cs, dc, reset
            u8g2_declaration = constructor_name + ' ' + object_name + '(' + rotation + ',' + cs + ',' + dc + ',' + reset + ');';
          }
        } else {
          if (is3WireSPI) {
            // 3线软件SPI构造函数格式，参数顺序为：rotation, sck, mosi, cs, reset
            u8g2_declaration = constructor_name + ' ' + object_name + '(' + rotation + ',' + sck + ',' + mosi + ',' + cs + ',' + reset + ');';
          } else {
            // 4线软件SPI构造函数格式，参数顺序为：rotation, sck, mosi, cs, dc, reset
            u8g2_declaration = constructor_name + ' ' + object_name + '(' + rotation + ',' + sck + ',' + mosi + ',' + cs + ',' + dc + ',' + reset + ');';
          }
        }
      }
      
      // 添加全局变量声明
      Blockly.Arduino.definitions_['u8g2_spi_object'] = u8g2_declaration;
      
      // 生成setup代码
      var setup_code = object_name + '.begin();';
      
      // 添加setup代码
      Blockly.Arduino.setups_['setup_u8g2_spi'] = setup_code;
      
      return '';
    };
    
    Blockly.Arduino.forBlock['u8g2_drawGlyph'] = function(block) {
      // 获取用户选择的参数
      var object_name = block.getFieldValue('object_name');
      var x = Blockly.Arduino.valueToCode(block, 'x', Blockly.Arduino.ORDER_ATOMIC) || '0';
      var y = Blockly.Arduino.valueToCode(block, 'y', Blockly.Arduino.ORDER_ATOMIC) || '0';
      var format = block.getFieldValue('format');
      var glyph = Blockly.Arduino.valueToCode(block, 'code', Blockly.Arduino.ORDER_ATOMIC) || '0';
      
      // 根据选择的格式处理字符编码
      var glyph_code = glyph;
      if (format === 'hex' && !glyph_code.startsWith('0x')) {
        // 如果是十六进制格式但没有0x前缀，添加前缀
        glyph_code = '0x' + glyph_code;
      }
      
      // 生成代码
      var code = object_name + '.drawGlyph(' + x + ', ' + y + ', ' + glyph_code + ');\n';
      
      return code;
    };
  
    Blockly.Arduino.forBlock['u8g2_setEnglishFont'] = function(block) {
      // 获取用户选择的参数
      var object_name = block.getFieldValue('object_name');
      var font = block.getFieldValue('font');
      
      // 确保包含头文件
      Blockly.Arduino.definitions_['include_u8g2'] = '#include <U8g2lib.h>';
      
      // 生成设置英文字体和字体位置的代码
      var code = object_name + '.setFont(' + font + ');\n';
      code += object_name + '.setFontPosTop();\n';
      
      return code;
    };
    
    // 中文字体设置代码生成器
    Blockly.Arduino.forBlock['u8g2_setChineseFont'] = function(block) {
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      
      // 获取字体集和字号（使用下拉选择）
      var font_set = block.getFieldValue('font_set') || 'chinese1';
      var font_size = block.getFieldValue('font_size') || '16';
      
      // 构建字体名
      var font_name = 'u8g2_font_wqy' + font_size + '_t_' + font_set;
      
      // 确保包含头文件
      Blockly.Arduino.definitions_['include_u8g2'] = '#include <U8g2lib.h>';
      
      // 生成代码
      var code = object_name + '.setFont(' + font_name + ');\n';
      code += object_name + '.setFontPosTop();\n';
      
      return code;
    };
    
    // 时钟翻页积木代码生成器 - 支持多种动画效果
    Blockly.Arduino.forBlock['u8g2_clock_flip'] = function(block) {
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var content = Blockly.Arduino.valueToCode(block, 'content', Blockly.Arduino.ORDER_ATOMIC);
      var x_pos = Blockly.Arduino.valueToCode(block, 'x_pos', Blockly.Arduino.ORDER_ATOMIC) || '0';
      var y_pos = Blockly.Arduino.valueToCode(block, 'y_pos', Blockly.Arduino.ORDER_ATOMIC) || '30';
      var direction = block.getFieldValue('direction') || 'up';
      var effect = block.getFieldValue('effect') || 'flip';
      
      var unique_id = object_name.replace(/[^a-zA-Z0-9_]/g, '_');
      
      Blockly.Arduino.definitions_['include_u8g2'] = '#include <U8g2lib.h>';
      
      var vars_key = 'u8g2_clock_vars_' + unique_id;
      Blockly.Arduino.definitions_[vars_key] = 
        'String u8g2_clock_prev_' + unique_id + ' = "";\n' +
        'bool u8g2_clock_animating_' + unique_id + ' = false;\n';
      
      var flip_func = '';
      var update_func = '';
      
      if (effect === 'flip') {
        Blockly.Arduino.definitions_[vars_key] += 
          'const int u8g2_clock_total_frames_' + unique_id + ' = 16;\n' +
          'const int u8g2_clock_anim_delay_' + unique_id + ' = 12;\n';
        
        flip_func = 
          'void u8g2_clock_flip_' + unique_id + '(String new_content, int x, int y, String direction) {\n' +
          '  u8g2_clock_animating_' + unique_id + ' = true;\n' +
          '  int font_height = ' + object_name + '.getAscent() - ' + object_name + '.getDescent() + 4;\n' +
          '  ' + object_name + '.setFontPosTop();\n' +
          '  \n' +
          '  for (int frame = 0; frame <= u8g2_clock_total_frames_' + unique_id + '; frame++) {\n' +
          '    ' + object_name + '.clearBuffer();\n' +
          '    \n' +
          '    float t = (float)frame / u8g2_clock_total_frames_' + unique_id + ';\n' +
          '    float ease = t < 0.5 ? 2 * t * t : 1 - pow(-2 * t + 2, 2) / 2;\n' +
          '    \n' +
          '    int prev_x_offset = 0, prev_y_offset = 0, new_x_offset = 0, new_y_offset = 0;\n' +
          '    if (direction == "up") {\n' +
          '      prev_y_offset = -font_height * ease;\n' +
          '      new_y_offset = font_height * (1 - ease);\n' +
          '    } else if (direction == "down") {\n' +
          '      prev_y_offset = font_height * ease;\n' +
          '      new_y_offset = -font_height * (1 - ease);\n' +
          '    } else if (direction == "left") {\n' +
          '      prev_x_offset = -font_height * ease;\n' +
          '      new_x_offset = font_height * (1 - ease);\n' +
          '    } else if (direction == "right") {\n' +
          '      prev_x_offset = font_height * ease;\n' +
          '      new_x_offset = -font_height * (1 - ease);\n' +
          '    }\n' +
          '    \n' +
          '    if (t > 0.7) {\n' +
          '      float bounce = sin((t - 0.7) / 0.3 * PI) * font_height * 0.15 * (1 - (t - 0.7) / 0.3);\n' +
          '      if (direction == "up") new_y_offset -= bounce;\n' +
          '      else if (direction == "down") new_y_offset += bounce;\n' +
          '      else if (direction == "left") new_x_offset -= bounce;\n' +
          '      else if (direction == "right") new_x_offset += bounce;\n' +
          '    }\n' +
          '    \n' +
          '    ' + object_name + '.setColorIndex(1);\n' +
          '    ' + object_name + '.setCursor(x + prev_x_offset, y + prev_y_offset);\n' +
          '    ' + object_name + '.print(u8g2_clock_prev_' + unique_id + ');\n' +
          '    \n' +
          '    ' + object_name + '.setCursor(x + new_x_offset, y + new_y_offset);\n' +
          '    ' + object_name + '.print(new_content);\n' +
          '    \n' +
          '    ' + object_name + '.sendBuffer();\n' +
          '    delay(u8g2_clock_anim_delay_' + unique_id + ');\n' +
          '  }\n' +
          '  \n' +
          '  u8g2_clock_prev_' + unique_id + ' = new_content;\n' +
          '  u8g2_clock_animating_' + unique_id + ' = false;\n' +
          '}\n';
      } else if (effect === 'mechanical') {
        Blockly.Arduino.definitions_[vars_key] += 
          'int u8g2_clock_mech_speed_' + unique_id + ' = 6;\n' +
          'int u8g2_clock_mech_y_' + unique_id + ' = 0;\n';
        
        flip_func = 
          'void u8g2_clock_mechanical_' + unique_id + '(String new_content, int x, int y, String direction) {\n' +
          '  u8g2_clock_animating_' + unique_id + ' = true;\n' +
          '  ' + object_name + '.setFontPosTop();\n' +
          '  int font_height = ' + object_name + '.getAscent() - ' + object_name + '.getDescent() + 4;\n' +
          '  \n' +
          '  for(int i=0; i<8; i++) {\n' +
          '    ' + object_name + '.clearBuffer();\n' +
          '    ' + object_name + '.setColorIndex(1);\n' +
          '    ' + object_name + '.setCursor(x, y);\n' +
          '    ' + object_name + '.print(u8g2_clock_prev_' + unique_id + ');\n' +
          '    ' + object_name + '.sendBuffer();\n' +
          '    delay(30);\n' +
          '  }\n' +
          '  \n' +
          '  u8g2_clock_mech_y_' + unique_id + ' = 0;\n' +
          '  int target = 0;\n' +
          '  if (direction == "up") target = -font_height;\n' +
          '  else if (direction == "down") target = font_height;\n' +
          '  else if (direction == "left") target = -font_height;\n' +
          '  else if (direction == "right") target = font_height;\n' +
          '  \n' +
          '  while (true) {\n' +
          '    ' + object_name + '.clearBuffer();\n' +
          '    \n' +
          '    int dist = target - u8g2_clock_mech_y_' + unique_id + ';\n' +
          '    \n' +
          '    if (abs(dist) > 15) {\n' +
          '      u8g2_clock_mech_y_' + unique_id + ' += (dist > 0 ? u8g2_clock_mech_speed_' + unique_id + ' : -u8g2_clock_mech_speed_' + unique_id + ');\n' +
          '    } else {\n' +
          '      u8g2_clock_mech_y_' + unique_id + ' = target;\n' +
          '    }\n' +
          '    \n' +
          '    int prev_x = x, prev_y = y, new_x = x, new_y = y;\n' +
          '    if (direction == "up") {\n' +
          '      prev_y = y + u8g2_clock_mech_y_' + unique_id + ';\n' +
          '      new_y = y + u8g2_clock_mech_y_' + unique_id + ' + font_height;\n' +
          '    } else if (direction == "down") {\n' +
          '      prev_y = y + u8g2_clock_mech_y_' + unique_id + ';\n' +
          '      new_y = y + u8g2_clock_mech_y_' + unique_id + ' - font_height;\n' +
          '    } else if (direction == "left") {\n' +
          '      prev_x = x + u8g2_clock_mech_y_' + unique_id + ';\n' +
          '      new_x = x + u8g2_clock_mech_y_' + unique_id + ' + font_height;\n' +
          '    } else if (direction == "right") {\n' +
          '      prev_x = x + u8g2_clock_mech_y_' + unique_id + ';\n' +
          '      new_x = x + u8g2_clock_mech_y_' + unique_id + ' - font_height;\n' +
          '    }\n' +
          '    \n' +
          '    ' + object_name + '.setColorIndex(1);\n' +
          '    ' + object_name + '.setCursor(prev_x, prev_y);\n' +
          '    ' + object_name + '.print(u8g2_clock_prev_' + unique_id + ');\n' +
          '    \n' +
          '    ' + object_name + '.setCursor(new_x, new_y);\n' +
          '    ' + object_name + '.print(new_content);\n' +
          '    \n' +
          '    ' + object_name + '.sendBuffer();\n' +
          '    delay(15);\n' +
          '    \n' +
          '    if (u8g2_clock_mech_y_' + unique_id + ' == target) break;\n' +
          '  }\n' +
          '  \n' +
          '  u8g2_clock_prev_' + unique_id + ' = new_content;\n' +
          '  u8g2_clock_animating_' + unique_id + ' = false;\n' +
          '}\n';
      } else if (effect === 'slide') {
        Blockly.Arduino.definitions_[vars_key] += 
          'const int u8g2_clock_slide_frames_' + unique_id + ' = 12;\n' +
          'const int u8g2_clock_slide_delay_' + unique_id + ' = 15;\n';
        
        flip_func = 
          'void u8g2_clock_slide_' + unique_id + '(String new_content, int x, int y, String direction) {\n' +
          '  u8g2_clock_animating_' + unique_id + ' = true;\n' +
          '  int display_height = ' + object_name + '.getDisplayHeight();\n' +
          '  int display_width = ' + object_name + '.getDisplayWidth();\n' +
          '  \n' +
          '  for (int frame = 0; frame <= u8g2_clock_slide_frames_' + unique_id + '; frame++) {\n' +
          '    ' + object_name + '.clearBuffer();\n' +
          '    \n' +
          '    float t = (float)frame / u8g2_clock_slide_frames_' + unique_id + ';\n' +
          '    float ease = 1 - pow(1 - t, 3);\n' +
          '    \n' +
          '    int prev_x_offset = 0, prev_y_offset = 0, new_x_offset = 0, new_y_offset = 0;\n' +
          '    if (direction == "up") {\n' +
          '      prev_y_offset = -display_height * ease;\n' +
          '      new_y_offset = display_height * (1 - ease);\n' +
          '    } else if (direction == "down") {\n' +
          '      prev_y_offset = display_height * ease;\n' +
          '      new_y_offset = -display_height * (1 - ease);\n' +
          '    } else if (direction == "left") {\n' +
          '      prev_x_offset = -display_width * ease;\n' +
          '      new_x_offset = display_width * (1 - ease);\n' +
          '    } else if (direction == "right") {\n' +
          '      prev_x_offset = display_width * ease;\n' +
          '      new_x_offset = -display_width * (1 - ease);\n' +
          '    }\n' +
          '    \n' +
          '    ' + object_name + '.setColorIndex(1);\n' +
          '    ' + object_name + '.setCursor(x + prev_x_offset, y + prev_y_offset);\n' +
          '    ' + object_name + '.print(u8g2_clock_prev_' + unique_id + ');\n' +
          '    \n' +
          '    ' + object_name + '.setCursor(x + new_x_offset, y + new_y_offset);\n' +
          '    ' + object_name + '.print(new_content);\n' +
          '    \n' +
          '    ' + object_name + '.sendBuffer();\n' +
          '    delay(u8g2_clock_slide_delay_' + unique_id + ');\n' +
          '  }\n' +
          '  \n' +
          '  u8g2_clock_prev_' + unique_id + ' = new_content;\n' +
          '  u8g2_clock_animating_' + unique_id + ' = false;\n' +
          '}\n';
      }
      
      if (effect === 'flip') {
        update_func = 
          'void u8g2_clock_update_' + unique_id + '(String current_val, int x, int y, String direction) {\n' +
          '  if (u8g2_clock_animating_' + unique_id + ') return;\n' +
          '  \n' +
          '  ' + object_name + '.setFontPosTop();\n' +
          '  if (u8g2_clock_prev_' + unique_id + ' == "") {\n' +
          '    ' + object_name + '.clearBuffer();\n' +
          '    ' + object_name + '.setColorIndex(1);\n' +
          '    ' + object_name + '.setCursor(x, y);\n' +
          '    ' + object_name + '.print(current_val);\n' +
          '    ' + object_name + '.sendBuffer();\n' +
          '    u8g2_clock_prev_' + unique_id + ' = current_val;\n' +
          '  } else if (u8g2_clock_prev_' + unique_id + ' != current_val) {\n' +
          '    u8g2_clock_flip_' + unique_id + '(current_val, x, y, direction);\n' +
          '  }\n' +
          '}\n';
      } else if (effect === 'mechanical') {
        update_func = 
          'void u8g2_clock_update_' + unique_id + '(String current_val, int x, int y, String direction) {\n' +
          '  if (u8g2_clock_animating_' + unique_id + ') return;\n' +
          '  \n' +
          '  ' + object_name + '.setFontPosTop();\n' +
          '  if (u8g2_clock_prev_' + unique_id + ' == "") {\n' +
          '    ' + object_name + '.clearBuffer();\n' +
          '    ' + object_name + '.setColorIndex(1);\n' +
          '    ' + object_name + '.setCursor(x, y);\n' +
          '    ' + object_name + '.print(current_val);\n' +
          '    ' + object_name + '.sendBuffer();\n' +
          '    u8g2_clock_prev_' + unique_id + ' = current_val;\n' +
          '  } else if (u8g2_clock_prev_' + unique_id + ' != current_val) {\n' +
          '    u8g2_clock_mechanical_' + unique_id + '(current_val, x, y, direction);\n' +
          '  }\n' +
          '}\n';
      } else if (effect === 'slide') {
        update_func = 
          'void u8g2_clock_update_' + unique_id + '(String current_val, int x, int y, String direction) {\n' +
          '  if (u8g2_clock_animating_' + unique_id + ') return;\n' +
          '  \n' +
          '  if (u8g2_clock_prev_' + unique_id + ' == "") {\n' +
          '    ' + object_name + '.clearBuffer();\n' +
          '    ' + object_name + '.setColorIndex(1);\n' +
          '    ' + object_name + '.setCursor(x, y);\n' +
          '    ' + object_name + '.print(current_val);\n' +
          '    ' + object_name + '.sendBuffer();\n' +
          '    u8g2_clock_prev_' + unique_id + ' = current_val;\n' +
          '  } else if (u8g2_clock_prev_' + unique_id + ' != current_val) {\n' +
          '    u8g2_clock_slide_' + unique_id + '(current_val, x, y, direction);\n' +
          '  }\n' +
          '}\n';
      }
      
      Blockly.Arduino.definitions_['func_u8g2_clock_' + unique_id] = flip_func + update_func;
      
      var code = '';
      if (content) {
        code += 'u8g2_clock_update_' + unique_id + '(String(' + content + '), ' + x_pos + ', ' + y_pos + ', "' + direction + '");\n';
      }
      
      return code;
    };
    
    Blockly.Arduino.forBlock['u8g2_print'] = function(block) {
      // 获取用户选择的参数
      var object_name = block.getFieldValue('object_name');
      var x = Blockly.Arduino.valueToCode(block, 'x', Blockly.Arduino.ORDER_ATOMIC) || '0';
      var y = Blockly.Arduino.valueToCode(block, 'y', Blockly.Arduino.ORDER_ATOMIC) || '0';
      var content = Blockly.Arduino.valueToCode(block, 'content', Blockly.Arduino.ORDER_ATOMIC) || '""';
      var display_mode = block.getFieldValue('display_mode') || 'normal';
      
      // 确保包含头文件
      Blockly.Arduino.definitions_['include_u8g2'] = '#include <U8g2lib.h>';
      
      var isStringLiteral = content.startsWith('"') && content.endsWith('"');
      var textParam = isStringLiteral ? content : (content + '.c_str()');
      
      var code = '';
      
      if (display_mode === 'inverse') {
        code += object_name + '.setFontMode(0);\n';
        code += '{\n';
        code += '  uint16_t tbw = ' + object_name + '.getUTF8Width(' + textParam + ');\n';
        code += '  uint16_t tbh = ' + object_name + '.getAscent() - ' + object_name + '.getDescent() + 4;\n';
        code += '  ' + object_name + '.setColorIndex(1);\n';
        code += '  ' + object_name + '.drawBox(' + x + ', ' + y + ' - 2, tbw, tbh);\n';
        code += '  ' + object_name + '.setColorIndex(0);\n';
        if (isStringLiteral) {
          code += '  ' + object_name + '.drawUTF8(' + x + ', ' + y + ', ' + textParam + ');\n';
        } else {
          code += '  ' + object_name + '.setCursor(' + x + ', ' + y + ');\n';
          code += '  ' + object_name + '.print(' + textParam + ');\n';
        }
        code += '  ' + object_name + '.setColorIndex(1);\n';
        code += '}\n';
      } else {
        if (isStringLiteral) {
          code = object_name + '.drawUTF8(' + x + ', ' + y + ', ' + content + ');\n';
        } else {
          code = object_name + '.setCursor(' + x + ', ' + y + ');\n';
          code += object_name + '.print(' + content + ');\n';
        }
      }
      
      return code;
    };
    
    Blockly.Arduino.forBlock['u8g2_clearBuffer'] = function(block) {
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      Blockly.Arduino.definitions_['include_u8g2'] = '#include <U8g2lib.h>';
      var code = object_name + '.clearBuffer();\n';
      return code;
    };
    
    Blockly.Arduino.forBlock['u8g2_sendBuffer'] = function(block) {
      // 获取用户选择的参数
      var object_name = block.getFieldValue('object_name');
      
      // 确保包含头文件
      Blockly.Arduino.definitions_['include_u8g2'] = '#include <U8g2lib.h>';
      
      // 生成发送缓冲区的代码
      var code = object_name + '.sendBuffer();\n';
      
      return code;
    };
    
    Blockly.Arduino.forBlock['u8g2_fill_effect'] = function(block) {
      // 获取用户选择的参数
      var object_name = block.getFieldValue('object_name');
      var effect_type = block.getFieldValue('effect_type');
      var fill_char = block.getFieldValue('fill_char') || '@';
      var color = Blockly.Arduino.valueToCode(block, 'color', Blockly.Arduino.ORDER_ATOMIC) || '1';
      
      // 确保包含头文件
      Blockly.Arduino.definitions_['include_u8g2'] = '#include <U8g2lib.h>';
      
      // 声明一次变量
      var varKey = 'u8g2_fill_vars_' + object_name;
      if (!Blockly.Arduino.definitions_[varKey]) {
        Blockly.Arduino.definitions_[varKey] = 
          'char u8g2_fill_buf[2];\n' +
          'u8g2_uint_t u8g2_fill_i, u8g2_fill_start_x, u8g2_fill_start_y;\n' +
          'u8g2_uint_t u8g2_fill_x, u8g2_fill_y, u8g2_fill_w, u8g2_fill_h;\n';
      }
      
      // 生成代码
      var code = '';
      
      // 设置颜色索引
      code += object_name + '.setColorIndex(' + color + ');\n';
      
      // 根据效果类型生成不同的代码
      if (effect_type === 'char') {
        // 字符填充效果
        var charToUse = fill_char && fill_char.length > 0 ? fill_char.charAt(0) : '@';
        code += object_name + '.setFont(u8g2_font_6x10_tf);\n';
        code += 'u8g2_fill_buf[0] = \'' + charToUse + '\';\n';
        code += 'u8g2_fill_start_x = 0;\n';
        code += 'u8g2_fill_start_y = 8;\n';
        code += 'for(;;) {\n';
        code += '  u8g2_fill_i = u8g2_fill_start_x;\n';
        code += '  for(;;) {\n';
        code += '    ' + object_name + '.drawStr(u8g2_fill_i, u8g2_fill_start_y, u8g2_fill_buf);\n';
        code += '    u8g2_fill_i += 8;\n';
        code += '    if (u8g2_fill_i > ' + object_name + '.getWidth())\n';
        code += '      break;\n';
        code += '  }\n';
        code += '  u8g2_fill_start_y += 8;\n';
        code += '  if (u8g2_fill_start_y > ' + object_name + '.getHeight())\n';
        code += '    break;\n';
        code += '}\n';
      } else if (effect_type === 'pixel') {
        // 像素填充效果
        code += 'u8g2_fill_w = ' + object_name + '.getWidth();\n';
        code += 'u8g2_fill_h = ' + object_name + '.getHeight();\n';
        code += 'u8g2_fill_w /= 2;\n';
        code += 'u8g2_fill_h /= 2;\n';
        code += 'for(u8g2_fill_y = 0; u8g2_fill_y < u8g2_fill_h; u8g2_fill_y++) {\n';
        code += '  for(u8g2_fill_x = 0; u8g2_fill_x < u8g2_fill_w; u8g2_fill_x++) {\n';
        code += '    if ((u8g2_fill_x + u8g2_fill_y) & 1) {\n';
        code += '      ' + object_name + '.drawPixel(u8g2_fill_x, u8g2_fill_y);\n';
        code += '      ' + object_name + '.drawPixel(u8g2_fill_x, u8g2_fill_y + u8g2_fill_h);\n';
        code += '      ' + object_name + '.drawPixel(u8g2_fill_x + u8g2_fill_w, u8g2_fill_y);\n';
        code += '      ' + object_name + '.drawPixel(u8g2_fill_x + u8g2_fill_w, u8g2_fill_y + u8g2_fill_h);\n';
        code += '    }\n';
        code += '  }\n';
        code += '}\n';
      }
      
      code += object_name + '.sendBuffer();\n';
      
      return code;
    };
    
    // 向左滚动文字的代码生成器
    Blockly.Arduino.forBlock['u8g2_scroll_text_left'] = function(block) {
      // 获取积木参数，添加默认值防御
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var text_content = Blockly.Arduino.valueToCode(block, 'text_content', Blockly.Arduino.ORDER_ATOMIC);
      if (!text_content || text_content === 'undefined') {
        text_content = '"你好米思奇"';
      } else if (!text_content.match(/^['"]/)) {
        text_content = '"' + text_content + '"';
      }
      
      // 简化值输入处理，确保获取到有效数值
      var y_position = Blockly.Arduino.valueToCode(block, 'y_position', Blockly.Arduino.ORDER_ATOMIC);
      if (y_position === null || y_position === undefined || y_position === '') {
        y_position = '20';
      }
      
      var scroll_delta = Blockly.Arduino.valueToCode(block, 'scroll_delta', Blockly.Arduino.ORDER_ATOMIC);
      if (scroll_delta === null || scroll_delta === undefined || scroll_delta === '') {
        scroll_delta = '2';
      }
      
      var scroll_delay = Blockly.Arduino.valueToCode(block, 'scroll_delay', Blockly.Arduino.ORDER_ATOMIC);
      if (scroll_delay === null || scroll_delay === undefined || scroll_delay === '') {
        scroll_delay = '200';
      }
      
      // 使用对象名作为唯一标识，避免重复定义
      var unique_id = object_name.replace(/[^a-zA-Z0-9_]/g, '_');
      var text_id = 'u8g2_scroll_text_left_' + unique_id;
      
      // 判断是否为字符串字面量
      var isStringLiteral = text_content.match(/^['"].*['"]$/);
      var textVariable;
      
      if (isStringLiteral) {
        var escaped_text = text_content.slice(1, -1).replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
        Blockly.Arduino.definitions_[text_id] = 'const char ' + text_id + '[] = "' + escaped_text + '";\n';
        textVariable = text_id;
      } else {
        textVariable = text_content;
      }
      
      // 定义必需的变量
      var vars_key = 'u8g2_scroll_vars_left_' + unique_id;
      Blockly.Arduino.definitions_[vars_key] = 
        'uint16_t u8g2_scroll_pos_left_' + unique_id + ' = 0;\n' +
        'uint16_t u8g2_scroll_text_width_' + unique_id + ' = 0;\n';
      
      // 生成简化的向左滚动代码
      var code = 
        object_name + '.clearBuffer();\n' +
        'int display_width = ' + object_name + '.getDisplayWidth();\n' +
        'if (u8g2_scroll_text_width_' + unique_id + ' == 0) {\n' +
        '  u8g2_scroll_text_width_' + unique_id + ' = ' + object_name + '.getUTF8Width(' + textVariable + ');\n' +
        '}\n' +
        'int x_pos = display_width - u8g2_scroll_pos_left_' + unique_id + ';\n' +
        'if (x_pos < display_width) {\n' +
        '  ' + object_name + '.drawUTF8(x_pos, ' + y_position + ', ' + textVariable + ');\n' +
        '}\n' +
        'int x_pos_next = x_pos + u8g2_scroll_text_width_' + unique_id + ';\n' +
        'if (x_pos_next < display_width) {\n' +
        '  ' + object_name + '.drawUTF8(x_pos_next, ' + y_position + ', ' + textVariable + ');\n' +
        '}\n' +
        object_name + '.sendBuffer();\n' +
        'u8g2_scroll_pos_left_' + unique_id + ' += ' + scroll_delta + ';\n' +
        'if (u8g2_scroll_pos_left_' + unique_id + ' > display_width + u8g2_scroll_text_width_' + unique_id + ') {\n' +
        '  u8g2_scroll_pos_left_' + unique_id + ' = 0;\n' +
        '}\n' +
        'delay(' + scroll_delay + ');\n';
      
      return code;
    };
    
    Blockly.Arduino.forBlock['u8g2_scroll_text_right'] = function(block) {
      // 获取积木参数，添加默认值防御
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var text_content = Blockly.Arduino.valueToCode(block, 'text_content', Blockly.Arduino.ORDER_ATOMIC);
      if (!text_content || text_content === 'undefined') {
        text_content = '"你好米思奇"';
      } else if (!text_content.match(/^['"]/)) {
        text_content = '"' + text_content + '"';
      }
      
      // 简化值输入处理，确保获取到有效数值
      var y_position = Blockly.Arduino.valueToCode(block, 'y_position', Blockly.Arduino.ORDER_ATOMIC);
      if (y_position === null || y_position === undefined || y_position === '') {
        y_position = '20';
      }
      
      var scroll_delta = Blockly.Arduino.valueToCode(block, 'scroll_delta', Blockly.Arduino.ORDER_ATOMIC);
      if (scroll_delta === null || scroll_delta === undefined || scroll_delta === '') {
        scroll_delta = '2';
      }
      
      var scroll_delay = Blockly.Arduino.valueToCode(block, 'scroll_delay', Blockly.Arduino.ORDER_ATOMIC);
      if (scroll_delay === null || scroll_delay === undefined || scroll_delay === '') {
        scroll_delay = '200';
      }
      
      // 使用对象名作为唯一标识，避免重复定义
      var unique_id = object_name.replace(/[^a-zA-Z0-9_]/g, '_');
      var text_id = 'u8g2_scroll_text_right_' + unique_id;
      
      // 判断是否为字符串字面量
      var isStringLiteral = text_content.match(/^['"].*['"]$/);
      var textVariable;
      
      if (isStringLiteral) {
        var escaped_text = text_content.slice(1, -1).replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
        Blockly.Arduino.definitions_[text_id] = 'const char ' + text_id + '[] = "' + escaped_text + '";\n';
        textVariable = text_id;
      } else {
        textVariable = text_content;
      }
      
      // 定义必需的变量
      var vars_key = 'u8g2_scroll_vars_right_' + unique_id;
      Blockly.Arduino.definitions_[vars_key] = 
        'uint16_t u8g2_scroll_pos_right_' + unique_id + ' = 0;\n' +
        'uint16_t u8g2_scroll_text_width_right_' + unique_id + ' = 0;\n';
      
      // 生成向右滚动代码
      var code = 
        object_name + '.clearBuffer();\n' +
        'int display_width = ' + object_name + '.getDisplayWidth();\n' +
        'if (u8g2_scroll_text_width_right_' + unique_id + ' == 0) {\n' +
        '  u8g2_scroll_text_width_right_' + unique_id + ' = ' + object_name + '.getUTF8Width(' + textVariable + ');\n' +
        '}\n' +
        'int x_pos = -u8g2_scroll_text_width_right_' + unique_id + ' + u8g2_scroll_pos_right_' + unique_id + ';\n' +
        'if (x_pos > -u8g2_scroll_text_width_right_' + unique_id + ') {\n' +
        '  ' + object_name + '.drawUTF8(x_pos, ' + y_position + ', ' + textVariable + ');\n' +
        '}\n' +
        'int x_pos_prev = x_pos - u8g2_scroll_text_width_right_' + unique_id + ';\n' +
        'if (x_pos_prev > -u8g2_scroll_text_width_right_' + unique_id + ') {\n' +
        '  ' + object_name + '.drawUTF8(x_pos_prev, ' + y_position + ', ' + textVariable + ');\n' +
        '}\n' +
        object_name + '.sendBuffer();\n' +
        'u8g2_scroll_pos_right_' + unique_id + ' += ' + scroll_delta + ';\n' +
        'if (u8g2_scroll_pos_right_' + unique_id + ' > display_width + u8g2_scroll_text_width_right_' + unique_id + ') {\n' +
        '  u8g2_scroll_pos_right_' + unique_id + ' = 0;\n' +
        '}\n' +
        'delay(' + scroll_delay + ');\n';
      
      return code;
      };

    // 水平滚动文字的代码生成器（合并向左和向右滚动）
    Blockly.Arduino.forBlock['u8g2_scroll_text_horizontal'] = function(block) {
      // 获取积木参数，添加默认值防御
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var text_content = Blockly.Arduino.valueToCode(block, 'text_content', Blockly.Arduino.ORDER_ATOMIC);
      if (!text_content || text_content === 'undefined') {
        text_content = '"你好米思奇"';
      } else if (!text_content.match(/^['"]/)) {
        text_content = '"' + text_content + '"';
      }
      var direction = block.getFieldValue('direction') || 'left';
      
      // 简化值输入处理，确保获取到有效数值
      var y_position = Blockly.Arduino.valueToCode(block, 'y_position', Blockly.Arduino.ORDER_ATOMIC);
      if (y_position === null || y_position === undefined || y_position === '') {
        y_position = '20';
      }
      
      var scroll_delta = Blockly.Arduino.valueToCode(block, 'scroll_delta', Blockly.Arduino.ORDER_ATOMIC);
      if (scroll_delta === null || scroll_delta === undefined || scroll_delta === '') {
        scroll_delta = '2';
      }
      
      var scroll_delay = Blockly.Arduino.valueToCode(block, 'scroll_delay', Blockly.Arduino.ORDER_ATOMIC);
      if (scroll_delay === null || scroll_delay === undefined || scroll_delay === '') {
        scroll_delay = '200';
      }
      
      // 使用对象名作为唯一标识，避免重复定义
      var unique_id = object_name.replace(/[^a-zA-Z0-9_]/g, '_');
      var text_id = 'u8g2_scroll_text_horizontal_' + unique_id + '_' + direction;
      
      // 判断是否为字符串字面量，如果是则定义常量，否则直接使用变量
      var isStringLiteral = text_content.match(/^['"].*['"]$/);
      var textVariable = isStringLiteral ? text_id : text_content;
      if (isStringLiteral) {
        var escaped_text = text_content.slice(1, -1).replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
        Blockly.Arduino.definitions_[text_id] = 'const char ' + text_id + '[] = "' + escaped_text + '";';
      }
      
      // 定义必需的变量
      var vars_key = 'u8g2_scroll_vars_horizontal_' + unique_id + '_' + direction;
      Blockly.Arduino.definitions_[vars_key] = 
        'uint16_t u8g2_scroll_pos_horizontal_' + unique_id + '_' + direction + ' = 0;\n' +
        'uint16_t u8g2_scroll_text_width_horizontal_' + unique_id + '_' + direction + ' = 0;\n';
      
      // 初始化代码
      var code = object_name + '.clearBuffer();\n' +
                 'int display_width = ' + object_name + '.getDisplayWidth();\n' +
                 'if (u8g2_scroll_text_width_horizontal_' + unique_id + '_' + direction + ' == 0) {\n' +
                 '  u8g2_scroll_text_width_horizontal_' + unique_id + '_' + direction + ' = ' + object_name + '.getUTF8Width(' + textVariable + ');\n' +
                 '}\n';
      
      // 根据方向生成不同的滚动代码
      if (direction === 'left') {
        // 向左滚动
        code += 'int x_pos = display_width - u8g2_scroll_pos_horizontal_' + unique_id + '_' + direction + ';\n' +
                'if (x_pos < display_width) {\n' +
                '  ' + object_name + '.drawUTF8(x_pos, ' + y_position + ', ' + textVariable + ');\n' +
                '}\n' +
                'int x_pos_next = x_pos + u8g2_scroll_text_width_horizontal_' + unique_id + '_' + direction + ';\n' +
                'if (x_pos_next < display_width) {\n' +
                '  ' + object_name + '.drawUTF8(x_pos_next, ' + y_position + ', ' + textVariable + ');\n' +
                '}\n';
      } else { // right
        // 向右滚动
        code += 'int x_pos = -u8g2_scroll_text_width_horizontal_' + unique_id + '_' + direction + ' + u8g2_scroll_pos_horizontal_' + unique_id + '_' + direction + ';\n' +
                'if (x_pos > -u8g2_scroll_text_width_horizontal_' + unique_id + '_' + direction + ') {\n' +
                '  ' + object_name + '.drawUTF8(x_pos, ' + y_position + ', ' + textVariable + ');\n' +
                '}\n' +
                'int x_pos_prev = x_pos - u8g2_scroll_text_width_horizontal_' + unique_id + '_' + direction + ';\n' +
                'if (x_pos_prev > -u8g2_scroll_text_width_horizontal_' + unique_id + '_' + direction + ') {\n' +
                '  ' + object_name + '.drawUTF8(x_pos_prev, ' + y_position + ', ' + textVariable + ');\n' +
                '}\n';
      }
      
      // 完成滚动逻辑
      code += object_name + '.sendBuffer();\n' +
              'u8g2_scroll_pos_horizontal_' + unique_id + '_' + direction + ' += ' + scroll_delta + ';\n' +
              'if (u8g2_scroll_pos_horizontal_' + unique_id + '_' + direction + ' > display_width + u8g2_scroll_text_width_horizontal_' + unique_id + '_' + direction + ') {\n' +
              '  u8g2_scroll_pos_horizontal_' + unique_id + '_' + direction + ' = 0;\n' +
              '}\n' +
              'delay(' + scroll_delay + ');\n';
      
      return code;
    };
    
    // 垂直滚动文字的代码生成器
    Blockly.Arduino.forBlock['u8g2_scroll_text_vertical'] = function(block) {
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var direction = block.getFieldValue('direction') || 'up';
      var line_count = parseInt(block.getFieldValue('line_count') || '1');
      
      var x_position = Blockly.Arduino.valueToCode(block, 'x_position', Blockly.Arduino.ORDER_ATOMIC);
      if (!x_position || x_position === '') x_position = '0';
      
      var scroll_delta = Blockly.Arduino.valueToCode(block, 'scroll_delta', Blockly.Arduino.ORDER_ATOMIC);
      if (!scroll_delta || scroll_delta === '') scroll_delta = '2';
      
      var scroll_delay = Blockly.Arduino.valueToCode(block, 'scroll_delay', Blockly.Arduino.ORDER_ATOMIC);
      if (!scroll_delay || scroll_delay === '') scroll_delay = '50';
      
      var textLines = [];
      for (var i = 1; i <= line_count; i++) {
        var textInput = Blockly.Arduino.valueToCode(block, 'text_line' + i, Blockly.Arduino.ORDER_ATOMIC);
        if (!textInput || textInput === 'undefined') {
          textInput = '"第' + i + '行"';
        } else if (!textInput.match(/^['"]/)) {
          textInput = '"' + textInput + '"';
        }
        textLines.push(textInput);
      }
      
      var unique_id = object_name.replace(/[^a-zA-Z0-9_]/g, '_');
      var var_prefix = 'u8g2_scroll_v_' + unique_id + '_' + direction;
      
      var text_array_id = var_prefix + '_texts';
      var text_def = 'const char* ' + text_array_id + '[] = {';
      for (var i = 0; i < textLines.length; i++) {
        text_def += textLines[i] + (i < textLines.length - 1 ? ', ' : '');
      }
      text_def += '};\n';
      Blockly.Arduino.definitions_[text_array_id] = text_def;
      
      Blockly.Arduino.definitions_[var_prefix] = 
        'uint16_t ' + var_prefix + '_pos = 0;\n' +
        'int ' + var_prefix + '_height = 0;\n' +
        'const int ' + var_prefix + '_lines = ' + line_count + ';\n';
      
      var code = object_name + '.clearBuffer();\n' +
                 'int ' + var_prefix + '_disp_h = ' + object_name + '.getDisplayHeight();\n' +
                 'if (' + var_prefix + '_height == 0) {\n' +
                 '  ' + var_prefix + '_height = ' + object_name + '.getFontAscent() - ' + object_name + '.getFontDescent();\n' +
                 '}\n';
      
      if (direction === 'up') {
        code += 'for (int i = 0; i < ' + var_prefix + '_lines; i++) {\n' +
                '  int ' + var_prefix + '_y = ' + var_prefix + '_disp_h + ((' + var_prefix + '_lines - 1 - i) * (' + var_prefix + '_height + 5)) - ' + var_prefix + '_pos;\n' +
                '  if (' + var_prefix + '_y < ' + var_prefix + '_disp_h && ' + var_prefix + '_y + ' + var_prefix + '_height > 0) {\n' +
                '    ' + object_name + '.drawUTF8(' + x_position + ', ' + var_prefix + '_y, ' + text_array_id + '[' + var_prefix + '_lines - 1 - i]);\n' +
                '  }\n' +
                '}\n';
      } else {
        code += 'for (int i = 0; i < ' + var_prefix + '_lines; i++) {\n' +
                '  int ' + var_prefix + '_y = ' + var_prefix + '_pos - (i * (' + var_prefix + '_height + 5));\n' +
                '  if (' + var_prefix + '_y < ' + var_prefix + '_disp_h && ' + var_prefix + '_y + ' + var_prefix + '_height > 0) {\n' +
                '    ' + object_name + '.drawUTF8(' + x_position + ', ' + var_prefix + '_y, ' + text_array_id + '[i]);\n' +
                '  }\n' +
                '}\n';
      }
      
      code += object_name + '.sendBuffer();\n' +
              var_prefix + '_pos += ' + scroll_delta + ';\n' +
              'if (' + var_prefix + '_pos > ' + var_prefix + '_disp_h + ((' + var_prefix + '_lines + 1) * (' + var_prefix + '_height + 5))) {\n' +
              '  ' + var_prefix + '_pos = 0;\n' +
              '}\n' +
              'delay(' + scroll_delay + ');\n';
      
      return code;
    };
      Blockly.Arduino.forBlock['u8g2_scroll_text_up'] = function(block) {
        // 获取积木参数，添加默认值防御
        var object_name = block.getFieldValue('object_name') || 'u8g2';
        var text_content = Blockly.Arduino.valueToCode(block, 'text_content', Blockly.Arduino.ORDER_ATOMIC);
        if (!text_content || text_content === 'undefined') {
          text_content = '"你好米思奇"';
        } else if (!text_content.match(/^['"]/)) {
          text_content = '"' + text_content + '"';
        }
        
        // 简化值输入处理，确保获取到有效数值
        var x_position = Blockly.Arduino.valueToCode(block, 'x_position', Blockly.Arduino.ORDER_ATOMIC);
        if (x_position === null || x_position === undefined || x_position === '') {
          x_position = '0';
        }
        
        var scroll_delta = Blockly.Arduino.valueToCode(block, 'scroll_delta', Blockly.Arduino.ORDER_ATOMIC);
        if (scroll_delta === null || scroll_delta === undefined || scroll_delta === '') {
          scroll_delta = '2';
        }
        
        var scroll_delay = Blockly.Arduino.valueToCode(block, 'scroll_delay', Blockly.Arduino.ORDER_ATOMIC);
        if (scroll_delay === null || scroll_delay === undefined || scroll_delay === '') {
          scroll_delay = '50';
        }
        
        // 使用对象名作为唯一标识，避免重复定义
        var unique_id = object_name.replace(/[^a-zA-Z0-9_]/g, '_');
        
        // 判断是否为字符串字面量
        var isStringLiteral = text_content.match(/^['"].*['"]$/);
        var lines = [];
        var text_array_id;
        var textVariable;
        
        if (isStringLiteral) {
          // 如果是字符串字面量，分割文本为多行
          var rawText = text_content.slice(1, -1);
          lines = rawText.split('，');
          if (lines.length <= 1) {
            lines = rawText.split(',');
          }
          
          // 定义文本常量数组
          text_array_id = 'u8g2_scroll_text_array_up_' + unique_id;
          var text_definitions = '';
          for (var i = 0; i < lines.length; i++) {
            var line_id = 'u8g2_scroll_line_' + i + '_up_' + unique_id;
            var escaped_line = lines[i].trim().replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
            text_definitions += 'const char ' + line_id + '[] = "' + escaped_line + '";\n';
          }
          text_definitions += 'const char* ' + text_array_id + '[] = {';
          for (var i = 0; i < lines.length; i++) {
            var line_id = 'u8g2_scroll_line_' + i + '_up_' + unique_id;
            text_definitions += line_id + (i < lines.length - 1 ? ', ' : '');
          }
          text_definitions += '};\n';
          Blockly.Arduino.definitions_[text_array_id] = text_definitions;
          textVariable = text_array_id;
        } else {
          // 如果是变量输入，直接使用变量
          lines = [''];
          textVariable = text_content;
        }
        
        // 定义必需的变量
        var vars_key = 'u8g2_scroll_vars_up_' + unique_id;
        Blockly.Arduino.definitions_[vars_key] = 
          'uint16_t u8g2_scroll_pos_up_' + unique_id + ' = 0;\n' +
          'uint16_t u8g2_scroll_text_height_' + unique_id + ' = 0;\n' +
          'const int u8g2_scroll_total_lines_' + unique_id + ' = ' + lines.length + ';\n';
        
        // 生成向上滚动代码 - 支持多行文本依次显示
        var code = 
          object_name + '.clearBuffer();\n' +
          'int display_width = ' + object_name + '.getDisplayWidth();\n' +
          'int display_height = ' + object_name + '.getDisplayHeight();\n' +
          'if (u8g2_scroll_text_height_' + unique_id + ' == 0) {\n' +
          '  u8g2_scroll_text_height_' + unique_id + ' = ' + object_name + '.getFontAscent() - ' + object_name + '.getFontDescent();\n' +
          '}\n';
        
        if (isStringLiteral) {
          code += '\n' +
          // 绘制多行文本，每行显示不同内容
          'for (int i = 0; i < u8g2_scroll_total_lines_' + unique_id + '; i++) {\n' +
          '  // 计算当前行的Y坐标，考虑滚动位置\n' +
          '  int line_y_pos = display_height - u8g2_scroll_pos_up_' + unique_id + ' + (i * u8g2_scroll_text_height_' + unique_id + ');\n' +
          '  \n' +
          '  // 检查该行是否在可视区域内\n' +
          '  if (line_y_pos > -u8g2_scroll_text_height_' + unique_id + ' && line_y_pos < display_height + u8g2_scroll_text_height_' + unique_id + ') {\n' +
          '    ' + object_name + '.drawUTF8(' + x_position + ', line_y_pos, ' + textVariable + '[i]);\n' +
          '  }\n' +
          '}\n';
        } else {
          code += '\n' +
          '// 绘制单行文本（变量输入）\n' +
          'int line_y_pos = display_height - u8g2_scroll_pos_up_' + unique_id + ';\n' +
          'if (line_y_pos > 0 && line_y_pos < display_height) {\n' +
          '  ' + object_name + '.drawUTF8(' + x_position + ', line_y_pos, ' + textVariable + '.c_str());\n' +
          '}\n';
        }
        
        var lineCount = isStringLiteral ? 'u8g2_scroll_total_lines_' + unique_id : '1';
        code += '\n' +
          object_name + '.sendBuffer();\n' +
          '\n' +
          '// 更新滚动位置\n' +
          'u8g2_scroll_pos_up_' + unique_id + ' += ' + scroll_delta + ';\n' +
          '\n' +
          '// 重置滚动位置\n' +
          'if (u8g2_scroll_pos_up_' + unique_id + ' > display_height + (' + lineCount + ' * u8g2_scroll_text_height_' + unique_id + ')) {\n' +
          '  u8g2_scroll_pos_up_' + unique_id + ' = 0;\n' +
          '}\n' +
          '\n' +
          'delay(' + scroll_delay + ');\n';
        
        return code;
      };
      
      Blockly.Arduino.forBlock['u8g2_scroll_text_down'] = function(block) {
        // 获取积木参数，添加默认值防御
        var object_name = block.getFieldValue('object_name') || 'u8g2';
        var text_content = Blockly.Arduino.valueToCode(block, 'text_content', Blockly.Arduino.ORDER_ATOMIC);
        if (!text_content || text_content === 'undefined') {
          text_content = '"你好米思奇"';
        } else if (!text_content.match(/^['"]/)) {
          text_content = '"' + text_content + '"';
        }
        
        // 简化值输入处理，确保获取到有效数值
        var x_position = Blockly.Arduino.valueToCode(block, 'x_position', Blockly.Arduino.ORDER_ATOMIC);
        if (x_position === null || x_position === undefined || x_position === '') {
          x_position = '0';
        }
        
        var scroll_delta = Blockly.Arduino.valueToCode(block, 'scroll_delta', Blockly.Arduino.ORDER_ATOMIC);
        if (scroll_delta === null || scroll_delta === undefined || scroll_delta === '') {
          scroll_delta = '2';
        }
        
        var scroll_delay = Blockly.Arduino.valueToCode(block, 'scroll_delay', Blockly.Arduino.ORDER_ATOMIC);
        if (scroll_delay === null || scroll_delay === undefined || scroll_delay === '') {
          scroll_delay = '50';
        }
        
        // 使用对象名作为唯一标识，避免重复定义
        var unique_id = object_name.replace(/[^a-zA-Z0-9_]/g, '_');
        
        // 判断是否为字符串字面量
        var isStringLiteral = text_content.match(/^['"].*['"]$/);
        var lines = [];
        var text_array_id;
        var textVariable;
        
        if (isStringLiteral) {
          // 如果是字符串字面量，分割文本为多行
          var rawText = text_content.slice(1, -1);
          lines = rawText.split('，');
          if (lines.length <= 1) {
            lines = rawText.split(',');
          }
          
          // 定义文本常量数组
          text_array_id = 'u8g2_scroll_text_array_down_' + unique_id;
          var text_definitions = '';
          for (var i = 0; i < lines.length; i++) {
            var line_id = 'u8g2_scroll_line_' + i + '_down_' + unique_id;
            var escaped_line = lines[i].trim().replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
            text_definitions += 'const char ' + line_id + '[] = "' + escaped_line + '";\n';
          }
          text_definitions += 'const char* ' + text_array_id + '[] = {';
          for (var i = 0; i < lines.length; i++) {
            var line_id = 'u8g2_scroll_line_' + i + '_down_' + unique_id;
            text_definitions += line_id + (i < lines.length - 1 ? ', ' : '');
          }
          text_definitions += '};\n';
          Blockly.Arduino.definitions_[text_array_id] = text_definitions;
          textVariable = text_array_id;
        } else {
          // 如果是变量输入，直接使用变量
          lines = [''];
          textVariable = text_content;
        }
        
        // 定义必需的变量
        var vars_key = 'u8g2_scroll_vars_down_' + unique_id;
        Blockly.Arduino.definitions_[vars_key] = 
          'uint16_t u8g2_scroll_pos_down_' + unique_id + ' = 0;\n' +
          'uint16_t u8g2_scroll_text_height_down_' + unique_id + ' = 0;\n' +
          'const int u8g2_scroll_total_lines_down_' + unique_id + ' = ' + lines.length + ';\n';
        
        // 生成向下滚动代码
        var code = 
          object_name + '.clearBuffer();\n' +
          'int display_width = ' + object_name + '.getDisplayWidth();\n' +
          'int display_height = ' + object_name + '.getDisplayHeight();\n' +
          'if (u8g2_scroll_text_height_down_' + unique_id + ' == 0) {\n' +
          '  u8g2_scroll_text_height_down_' + unique_id + ' = ' + object_name + '.getFontAscent() - ' + object_name + '.getFontDescent();\n' +
          '}\n';
        
        if (isStringLiteral) {
          code += '\n' +
          'for (int i = 0; i < u8g2_scroll_total_lines_down_' + unique_id + '; i++) {\n' +
          '  int line_y_pos = -u8g2_scroll_text_height_down_' + unique_id + ' + u8g2_scroll_pos_down_' + unique_id + ' - i * u8g2_scroll_text_height_down_' + unique_id + ';\n' +
          '  if (line_y_pos > -u8g2_scroll_text_height_down_' + unique_id + ' && line_y_pos < display_height + u8g2_scroll_text_height_down_' + unique_id + ') {\n' +
          '    ' + object_name + '.drawUTF8(' + x_position + ', line_y_pos, ' + textVariable + '[i]);\n' +
          '  }\n' +
          '}\n';
        } else {
          code += '\n' +
          '// 绘制单行文本（变量输入）\n' +
          'int line_y_pos = u8g2_scroll_pos_down_' + unique_id + ';\n' +
          'if (line_y_pos > 0 && line_y_pos < display_height) {\n' +
          '  ' + object_name + '.drawUTF8(' + x_position + ', line_y_pos, ' + textVariable + '.c_str());\n' +
          '}\n';
        }
        
        var lineCount = isStringLiteral ? 'u8g2_scroll_total_lines_down_' + unique_id : '1';
        code += '\n' +
          object_name + '.sendBuffer();\n' +
          'u8g2_scroll_pos_down_' + unique_id + ' += ' + scroll_delta + ';\n' +
          'if (u8g2_scroll_pos_down_' + unique_id + ' > display_height + (' + lineCount + ' * u8g2_scroll_text_height_down_' + unique_id + ')) {\n' +
          '  u8g2_scroll_pos_down_' + unique_id + ' = 0;\n' +
          '}\n' +
          'delay(' + scroll_delay + ');\n';
        
        return code;
    };

    // 屏幕旋转显示的代码生成器
    Blockly.Arduino.forBlock['u8g2_set_display_rotation'] = function(block) {
      // 获取积木参数，添加默认值防御
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var x_position = Blockly.Arduino.valueToCode(block, 'x_position', Blockly.Arduino.ORDER_ATOMIC) || '2';
      var dx = Blockly.Arduino.valueToCode(block, 'dx', Blockly.Arduino.ORDER_ATOMIC) || '16';
      var y_position = Blockly.Arduino.valueToCode(block, 'y_position', Blockly.Arduino.ORDER_ATOMIC) || '32';
      var step = Blockly.Arduino.valueToCode(block, 'step', Blockly.Arduino.ORDER_ATOMIC) || '0';
      var step_increment = Blockly.Arduino.valueToCode(block, 'step_increment', Blockly.Arduino.ORDER_ATOMIC) || '3';
      var max_step = Blockly.Arduino.valueToCode(block, 'max_step', Blockly.Arduino.ORDER_ATOMIC) || '160';
      var delay_ms = Blockly.Arduino.valueToCode(block, 'delay_ms', Blockly.Arduino.ORDER_ATOMIC) || '100';
      
      // 使用对象名作为唯一标识，避免重复定义
      var unique_id = object_name.replace(/[^a-zA-Z0-9_]/g, '_');
      
      // 定义必要的全局变量和函数
      Blockly.Arduino.definitions_['u8g2_rndz_' + unique_id] = 'uint16_t u8g2_rndz_' + unique_id + ' = 127;';
      Blockly.Arduino.definitions_['u8g2_prev_counter_' + unique_id] = 'char u8g2_prev_counter_' + unique_id + '[] = "    ";';
      Blockly.Arduino.definitions_['u8g2_next_counter_' + unique_id] = 'char u8g2_next_counter_' + unique_id + '[] = "    ";';
      Blockly.Arduino.definitions_['u8g2_rnd_counter_' + unique_id] = 'uint16_t u8g2_rnd_counter_' + unique_id + ' = 0;';
      Blockly.Arduino.definitions_['u8g2_step_' + unique_id] = 'uint8_t u8g2_step_' + unique_id + ' = ' + step + ';';
      
      // 定义lcg随机数生成函数
      if (!Blockly.Arduino.definitions_['u8g2_lcg_' + unique_id]) {
        Blockly.Arduino.definitions_['u8g2_lcg_' + unique_id] = `
uint16_t u8g2_lcg_${unique_id}(void) {
  u8g2_rndz_${unique_id} = ((uint16_t)65*(uint16_t)u8g2_rndz_${unique_id} + (uint16_t)17);
  return u8g2_rndz_${unique_id};
}

uint16_t u8g2_get_counter_y_pos_${unique_id}(uint16_t x) {
#define U8G2_ELEMENTS_${unique_id} 7

  static const int16_t u8g2_xa_${unique_id}[U8G2_ELEMENTS_${unique_id}] = { 0, 25, 50, 80, 100, 114, 127 } ;
  static const int16_t u8g2_ya_${unique_id}[U8G2_ELEMENTS_${unique_id}] = { 0, 10, 38, 100, 128, 137, 128};

  int i = 1;
  if (x > u8g2_xa_${unique_id}[U8G2_ELEMENTS_${unique_id}-1])
    return u8g2_ya_${unique_id}[U8G2_ELEMENTS_${unique_id}-1];
  while(u8g2_xa_${unique_id}[i] < x)
    i++;
  return ((int32_t)(x-u8g2_xa_${unique_id}[i-1]) * (int32_t)(u8g2_ya_${unique_id}[i]-u8g2_ya_${unique_id}[i-1])) / (u8g2_xa_${unique_id}[i]-u8g2_xa_${unique_id}[i-1]) + u8g2_ya_${unique_id}[i-1];
}

void u8g2_draw_mech_counter_${unique_id}(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, int16_t step, const char *prev, const char *next) {
  u8g2_uint_t h = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2);
  u8g2_uint_t shift = 0;

  if (step >= 0) {
    shift = (u8g2_get_counter_y_pos_${unique_id}(step)*h)/128;
  }

  y += shift;
  if (prev[0] == '1')
    u8g2_DrawStr(u8g2, x+4, y, prev);
  else
    u8g2_DrawStr(u8g2, x, y, prev);
  y -= h;
  if (next[0] == '1')
    u8g2_DrawStr(u8g2, x+4, y, next);
  else
    u8g2_DrawStr(u8g2, x, y, next);
}

void u8g2_draw_4_counter_${unique_id}(u8g2_t *u8g2, uint16_t rnd, u8g2_uint_t x, u8g2_uint_t dx, u8g2_uint_t y, uint8_t step, const char *prev, const char *next) {
  u8g2_uint_t ex = 3;
  u8g2_uint_t h = u8g2_GetAscent(u8g2);
  uint8_t i;
    
  char p[2] = "0";
  char n[2] = "0";
  
  u8g2_DrawFrame(u8g2, x-1, y-h-ex-1, 4*dx+3, h+2*ex+2);
  u8g2_SetClipWindow(u8g2, x, y-h-ex, x+4*dx, y+ex);

  for(i = 0; i < 4; i++) {
    p[0] = prev[i];
    n[0] = next[i];
    u8g2_draw_mech_counter_${unique_id}(u8g2, x, y, step + (rnd & 31), p, n);
    rnd >>= 2;
    x += dx;
  }
  
  u8g2_SetMaxClipWindow(u8g2);
}

void u8g2_init_counter_${unique_id}(uint16_t value) {
  strcpy(u8g2_prev_counter_${unique_id}, u8g2_next_counter_${unique_id});
  strcpy(u8g2_next_counter_${unique_id}, u8x8_u16toa(value, 4));
  u8g2_rnd_counter_${unique_id} = u8g2_lcg_${unique_id}();
}

void u8g2_draw_counter_${unique_id}(u8g2_uint_t x, u8g2_uint_t dx, u8g2_uint_t y, uint8_t step) {
  u8g2_draw_4_counter_${unique_id}(${object_name}.getU8g2(), u8g2_rnd_counter_${unique_id}, x, dx, y, step, u8g2_prev_counter_${unique_id}, u8g2_next_counter_${unique_id});
}`;
      }
      
      // 初始化代码（只执行一次）
      if (!Blockly.Arduino.setups_['u8g2_init_counter_' + unique_id]) {
        Blockly.Arduino.setups_['u8g2_init_counter_' + unique_id] = `u8g2_init_counter_${unique_id}(u8g2_lcg_${unique_id}());`;
      }
      
      // 生成自由落体动画代码
      var code = '';
      code += object_name + '.firstPage();\n';
      code += 'do {\n';
      code += '  ' + object_name + '.setFont(u8g2_font_mystery_quest_32_tr);\n';
      code += '  u8g2_draw_counter_' + unique_id + '(' + x_position + ', ' + dx + ', ' + y_position + ', u8g2_step_' + unique_id + ');\n';
      code += '} while (' + object_name + '.nextPage());\n';
      
      // 更新步进值和重置逻辑
      code += 'u8g2_step_' + unique_id + ' += ' + step_increment + ';\n';
      code += 'if (u8g2_step_' + unique_id + ' > ' + max_step + ') {\n';
      code += '  u8g2_init_counter_' + unique_id + '(u8g2_lcg_' + unique_id + '());\n';
      code += '  u8g2_step_' + unique_id + ' = 0;\n';
      code += '}\n';
      
      // 添加延迟
      if (delay_ms > 0) {
        code += 'delay(' + delay_ms + ');\n';
      }
      
      return code;
    };

    // 屏幕旋转显示的代码生成器
    Blockly.Arduino.forBlock['u8g2_set_display_rotation'] = function(block) {
      // 获取积木参数，添加默认值防御
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var rotation = block.getFieldValue('rotation') || 'U8G2_R0';
      var flip_mode = block.getFieldValue('flip_mode') || '0';
      
      // 生成设置显示旋转和翻转模式的代码
      var code = '';
      code += object_name + '.clearDisplay();\n';
      code += object_name + '.setDisplayRotation(' + rotation + ');\n';
      code += object_name + '.setFlipMode(' + flip_mode + ');\n';
      
      return code;
    };

    // 字体模式设置的代码生成器
    Blockly.Arduino.forBlock['u8g2_set_font_mode'] = function(block) {
      // 获取积木参数，添加默认值防御
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var font_mode = block.getFieldValue('font_mode') || '1';
      
      // 生成设置字体模式的代码
      var code = object_name + '.setFontMode(' + font_mode + ');\n';
      
      return code;
    };

    // 绘制颜色设置的代码生成器
    Blockly.Arduino.forBlock['u8g2_set_draw_color'] = function(block) {
      // 获取积木参数，添加默认值防御
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var draw_color = block.getFieldValue('draw_color') || '1';
      
      // 生成设置绘制颜色的代码
      var code = object_name + '.setDrawColor(' + draw_color + ');\n';
      
      return code;
    };

    // 三角形绘制的代码生成器
    Blockly.Arduino.forBlock['u8g2_draw_triangle'] = function(block) {
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var x = Blockly.Arduino.valueToCode(block, 'x', Blockly.Arduino.ORDER_ATOMIC) || '64';
      var y = Blockly.Arduino.valueToCode(block, 'y', Blockly.Arduino.ORDER_ATOMIC) || '20';
      var x2 = Blockly.Arduino.valueToCode(block, 'x2', Blockly.Arduino.ORDER_ATOMIC) || '44';
      var y2 = Blockly.Arduino.valueToCode(block, 'y2', Blockly.Arduino.ORDER_ATOMIC) || '44';
      var x3 = Blockly.Arduino.valueToCode(block, 'x3', Blockly.Arduino.ORDER_ATOMIC) || '84';
      var y3 = Blockly.Arduino.valueToCode(block, 'y3', Blockly.Arduino.ORDER_ATOMIC) || '44';
      var filled = block.getFieldValue('filled') || 'false';
      
      if (!Blockly.Arduino.definitions_['draw_triangle_helper']) {
        Blockly.Arduino.definitions_['draw_triangle_helper'] = 
          'void drawTriangle(U8G2 &g, int x0, int y0, int x1, int y1, int x2, int y2) {\n' +
          '  g.drawTriangle(x0, y0, x1, y1, x2, y2);\n' +
          '}\n';
      }
      
      var code;
      if (filled === 'true') {
        code = 'drawTriangle(' + object_name + ', ' + x + ', ' + y + ', ' + x2 + ', ' + y2 + ', ' + x3 + ', ' + y3 + ');\n';
      } else {
        code = object_name + '.drawLine(' + x + ', ' + y + ', ' + x2 + ', ' + y2 + ');\n';
        code += object_name + '.drawLine(' + x2 + ', ' + y2 + ', ' + x3 + ', ' + y3 + ');\n';
        code += object_name + '.drawLine(' + x3 + ', ' + y3 + ', ' + x + ', ' + y + ');\n';
      }
      
      return code;
    };

    // 正五边形绘制的代码生成器
    Blockly.Arduino.forBlock['u8g2_draw_pentagon'] = function(block) {
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var cx = Blockly.Arduino.valueToCode(block, 'x', Blockly.Arduino.ORDER_ATOMIC) || '64';
      var cy = Blockly.Arduino.valueToCode(block, 'y', Blockly.Arduino.ORDER_ATOMIC) || '32';
      var r = Blockly.Arduino.valueToCode(block, 'radius', Blockly.Arduino.ORDER_ATOMIC) || '20';
      var filled = block.getFieldValue('filled') || 'false';
      
      if (!Blockly.Arduino.definitions_['include_math']) {
        Blockly.Arduino.definitions_['include_math'] = '#include <math.h>';
      }
      
      if (!Blockly.Arduino.definitions_['draw_pentagon_helper']) {
        Blockly.Arduino.definitions_['draw_pentagon_helper'] = 
          'void drawPentagon(U8G2 &g, int cx, int cy, int r) {\n' +
          '  float angle = -1.5708;\n' +
          '  float step = 1.25664;\n' +
          '  int x[5], y[5];\n' +
          '  for(int i=0; i<5; i++) {\n' +
          '    x[i] = cx + r * cos(angle);\n' +
          '    y[i] = cy + r * sin(angle);\n' +
          '    angle += step;\n' +
          '  }\n' +
          '  g.drawTriangle(cx, cy, x[0], y[0], x[1], y[1]);\n' +
          '  g.drawTriangle(cx, cy, x[1], y[1], x[2], y[2]);\n' +
          '  g.drawTriangle(cx, cy, x[2], y[2], x[3], y[3]);\n' +
          '  g.drawTriangle(cx, cy, x[3], y[3], x[4], y[4]);\n' +
          '  g.drawTriangle(cx, cy, x[4], y[4], x[0], y[0]);\n' +
          '}\n' +
          'void drawPentagonOutline(U8G2 &g, int cx, int cy, int r) {\n' +
          '  float angle = -1.5708;\n' +
          '  float step = 1.25664;\n' +
          '  int x[5], y[5];\n' +
          '  for(int i=0; i<5; i++) {\n' +
          '    x[i] = cx + r * cos(angle);\n' +
          '    y[i] = cy + r * sin(angle);\n' +
          '    angle += step;\n' +
          '  }\n' +
          '  for(int i=0; i<5; i++) {\n' +
          '    g.drawLine(x[i], y[i], x[(i+1)%5], y[(i+1)%5]);\n' +
          '  }\n' +
          '}\n';
      }
      
      var code;
      if (filled === 'true') {
        code = 'drawPentagon(' + object_name + ', ' + cx + ', ' + cy + ', ' + r + ');\n';
      } else {
        code = 'drawPentagonOutline(' + object_name + ', ' + cx + ', ' + cy + ', ' + r + ');\n';
      }
      
      return code;
    };

    // 正六边形绘制的代码生成器
    Blockly.Arduino.forBlock['u8g2_draw_hexagon'] = function(block) {
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var cx = Blockly.Arduino.valueToCode(block, 'x', Blockly.Arduino.ORDER_ATOMIC) || '64';
      var cy = Blockly.Arduino.valueToCode(block, 'y', Blockly.Arduino.ORDER_ATOMIC) || '32';
      var r = Blockly.Arduino.valueToCode(block, 'radius', Blockly.Arduino.ORDER_ATOMIC) || '20';
      var filled = block.getFieldValue('filled') || 'false';
      
      if (!Blockly.Arduino.definitions_['draw_hexagon_helper']) {
        Blockly.Arduino.definitions_['draw_hexagon_helper'] = 
          'void drawHexagon(U8G2 &g, int cx, int cy, int r) {\n' +
          '  float a = r * 0.866;\n' +
          '  float b = r * 0.5;\n' +
          '  int x0 = cx, y0 = cy - r;\n' +
          '  int x1 = cx + a, y1 = cy - b;\n' +
          '  int x2 = cx + a, y2 = cy + b;\n' +
          '  int x3 = cx, y3 = cy + r;\n' +
          '  int x4 = cx - a, y4 = cy + b;\n' +
          '  int x5 = cx - a, y5 = cy - b;\n' +
          '  g.drawTriangle(x0,y0, x1,y1, x2,y2);\n' +
          '  g.drawTriangle(x0,y0, x2,y2, x3,y3);\n' +
          '  g.drawTriangle(x3,y3, x4,y4, x5,y5);\n' +
          '  g.drawTriangle(x3,y3, x5,y5, x0,y0);\n' +
          '}\n' +
          'void drawHexagonOutline(U8G2 &g, int cx, int cy, int r) {\n' +
          '  int x0 = cx, y0 = cy - r;\n' +
          '  int x1 = cx + r*0.866, y1 = cy - r*0.5;\n' +
          '  int x2 = cx + r*0.866, y2 = cy + r*0.5;\n' +
          '  int x3 = cx, y3 = cy + r;\n' +
          '  int x4 = cx - r*0.866, y4 = cy + r*0.5;\n' +
          '  int x5 = cx - r*0.866, y5 = cy - r*0.5;\n' +
          '  g.drawLine(x0, y0, x1, y1);\n' +
          '  g.drawLine(x1, y1, x2, y2);\n' +
          '  g.drawLine(x2, y2, x3, y3);\n' +
          '  g.drawLine(x3, y3, x4, y4);\n' +
          '  g.drawLine(x4, y4, x5, y5);\n' +
          '  g.drawLine(x5, y5, x0, y0);\n' +
          '}\n';
      }
      
      var code;
      if (filled === 'true') {
        code = 'drawHexagon(' + object_name + ', ' + cx + ', ' + cy + ', ' + r + ');\n';
      } else {
        code = 'drawHexagonOutline(' + object_name + ', ' + cx + ', ' + cy + ', ' + r + ');\n';
      }
      
      return code;
    };

    // 五角星绘制的代码生成器
    Blockly.Arduino.forBlock['u8g2_draw_star'] = function(block) {
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var cx = Blockly.Arduino.valueToCode(block, 'x', Blockly.Arduino.ORDER_ATOMIC) || '64';
      var cy = Blockly.Arduino.valueToCode(block, 'y', Blockly.Arduino.ORDER_ATOMIC) || '32';
      var size = Blockly.Arduino.valueToCode(block, 'radius', Blockly.Arduino.ORDER_ATOMIC) || '25';
      var filled = block.getFieldValue('filled') || 'false';
      
      if (!Blockly.Arduino.definitions_['draw_star_helper']) {
        Blockly.Arduino.definitions_['draw_star_helper'] = 
          'void drawStar(U8G2 &g, int cx, int cy, int size) {\n' +
          '  float angle = -1.5708;\n' +
          '  float step = 0.62832;\n' +
          '  int ox[10], oy[10];\n' +
          '  for(int i=0; i<10; i++) {\n' +
          '    float r = (i % 2 == 0) ? size : size * 0.382;\n' +
          '    ox[i] = cx + r * cos(angle);\n' +
          '    oy[i] = cy + r * sin(angle);\n' +
          '    angle += step;\n' +
          '  }\n' +
          '  for(int i=0; i<10; i++) {\n' +
          '    g.drawTriangle(cx, cy, ox[i], oy[i], ox[(i+1)%10], oy[(i+1)%10]);\n' +
          '  }\n' +
          '}\n' +
          'void drawStarOutline(U8G2 &g, int cx, int cy, int size) {\n' +
          '  float angle = -1.5708;\n' +
          '  float step = 0.62832;\n' +
          '  int ox[10], oy[10];\n' +
          '  for(int i=0; i<10; i++) {\n' +
          '    float r = (i % 2 == 0) ? size : size * 0.382;\n' +
          '    ox[i] = cx + r * cos(angle);\n' +
          '    oy[i] = cy + r * sin(angle);\n' +
          '    angle += step;\n' +
          '  }\n' +
          '  for(int i=0; i<10; i++) {\n' +
          '    g.drawLine(ox[i], oy[i], ox[(i+1)%10], oy[(i+1)%10]);\n' +
          '  }\n' +
          '}\n';
      }
      
      var code;
      if (filled === 'true') {
        code = 'drawStar(' + object_name + ', ' + cx + ', ' + cy + ', ' + size + ');\n';
      } else {
        code = 'drawStarOutline(' + object_name + ', ' + cx + ', ' + cy + ', ' + size + ');\n';
      }
      
      return code;
    };

    // N边形绘制的代码生成器
    Blockly.Arduino.forBlock['u8g2_draw_npolygon'] = function(block) {
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var cx = Blockly.Arduino.valueToCode(block, 'x', Blockly.Arduino.ORDER_ATOMIC) || '64';
      var cy = Blockly.Arduino.valueToCode(block, 'y', Blockly.Arduino.ORDER_ATOMIC) || '32';
      var r = Blockly.Arduino.valueToCode(block, 'radius', Blockly.Arduino.ORDER_ATOMIC) || '20';
      var sides = Blockly.Arduino.valueToCode(block, 'sides', Blockly.Arduino.ORDER_ATOMIC) || '5';
      var filled = block.getFieldValue('filled') || 'false';
      
      if (!Blockly.Arduino.definitions_['include_math']) {
        Blockly.Arduino.definitions_['include_math'] = '#include <math.h>';
      }
      
      if (!Blockly.Arduino.definitions_['draw_npolygon_helper']) {
        Blockly.Arduino.definitions_['draw_npolygon_helper'] = 
          'void drawNPolygon(U8G2 &g, int cx, int cy, int r, int sides) {\n' +
          '  float angle = -1.5708;\n' +
          '  float step = 6.28318 / sides;\n' +
          '  int x[100], y[100];\n' +
          '  for(int i=0; i<sides; i++) {\n' +
          '    x[i] = cx + r * cos(angle);\n' +
          '    y[i] = cy + r * sin(angle);\n' +
          '    angle += step;\n' +
          '  }\n' +
          '  for(int i=0; i<sides; i++) {\n' +
          '    g.drawTriangle(cx, cy, x[i], y[i], x[(i+1)%sides], y[(i+1)%sides]);\n' +
          '  }\n' +
          '}\n' +
          'void drawNPolygonOutline(U8G2 &g, int cx, int cy, int r, int sides) {\n' +
          '  float angle = -1.5708;\n' +
          '  float step = 6.28318 / sides;\n' +
          '  int x[100], y[100];\n' +
          '  for(int i=0; i<sides; i++) {\n' +
          '    x[i] = cx + r * cos(angle);\n' +
          '    y[i] = cy + r * sin(angle);\n' +
          '    angle += step;\n' +
          '  }\n' +
          '  for(int i=0; i<sides; i++) {\n' +
          '    g.drawLine(x[i], y[i], x[(i+1)%sides], y[(i+1)%sides]);\n' +
          '  }\n' +
          '}\n';
      }
      
      var code;
      if (filled === 'true') {
        code = 'drawNPolygon(' + object_name + ', ' + cx + ', ' + cy + ', ' + r + ', ' + sides + ');\n';
      } else {
        code = 'drawNPolygonOutline(' + object_name + ', ' + cx + ', ' + cy + ', ' + r + ', ' + sides + ');\n';
      }
      
      return code;
    };

    // N角星绘制的代码生成器
    Blockly.Arduino.forBlock['u8g2_draw_nstar'] = function(block) {
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var cx = Blockly.Arduino.valueToCode(block, 'x', Blockly.Arduino.ORDER_ATOMIC) || '64';
      var cy = Blockly.Arduino.valueToCode(block, 'y', Blockly.Arduino.ORDER_ATOMIC) || '32';
      var size = Blockly.Arduino.valueToCode(block, 'radius', Blockly.Arduino.ORDER_ATOMIC) || '25';
      var points = Blockly.Arduino.valueToCode(block, 'points', Blockly.Arduino.ORDER_ATOMIC) || '5';
      var filled = block.getFieldValue('filled') || 'false';
      
      if (!Blockly.Arduino.definitions_['include_math']) {
        Blockly.Arduino.definitions_['include_math'] = '#include <math.h>';
      }
      
      if (!Blockly.Arduino.definitions_['draw_nstar_helper']) {
        Blockly.Arduino.definitions_['draw_nstar_helper'] = 
          'void drawNStar(U8G2 &g, int cx, int cy, int size, int points) {\n' +
          '  float angle = -1.5708;\n' +
          '  float step = 6.28318 / points;\n' +
          '  float innerRatio = 0.382;\n' +
          '  int ox[200], oy[200];\n' +
          '  for(int i=0; i<points*2; i++) {\n' +
          '    float r = (i % 2 == 0) ? size : size * innerRatio;\n' +
          '    ox[i] = cx + r * cos(angle);\n' +
          '    oy[i] = cy + r * sin(angle);\n' +
          '    angle += step;\n' +
          '  }\n' +
          '  for(int i=0; i<points*2; i++) {\n' +
          '    g.drawTriangle(cx, cy, ox[i], oy[i], ox[(i+1)%(points*2)], oy[(i+1)%(points*2)]);\n' +
          '  }\n' +
          '}\n' +
          'void drawNStarOutline(U8G2 &g, int cx, int cy, int size, int points) {\n' +
          '  float angle = -1.5708;\n' +
          '  float step = 6.28318 / points;\n' +
          '  float innerRatio = 0.382;\n' +
          '  int ox[200], oy[200];\n' +
          '  for(int i=0; i<points*2; i++) {\n' +
          '    float r = (i % 2 == 0) ? size : size * innerRatio;\n' +
          '    ox[i] = cx + r * cos(angle);\n' +
          '    oy[i] = cy + r * sin(angle);\n' +
          '    angle += step;\n' +
          '  }\n' +
          '  for(int i=0; i<points*2; i++) {\n' +
          '    g.drawLine(ox[i], oy[i], ox[(i+1)%(points*2)], oy[(i+1)%(points*2)]);\n' +
          '  }\n' +
          '}\n';
      }
      
      var code;
      if (filled === 'true') {
        code = 'drawNStar(' + object_name + ', ' + cx + ', ' + cy + ', ' + size + ', ' + points + ');\n';
      } else {
        code = 'drawNStarOutline(' + object_name + ', ' + cx + ', ' + cy + ', ' + size + ', ' + points + ');\n';
      }
      
      return code;
    };

    // 局部滚动文字的代码生成器
    Blockly.Arduino.forBlock['u8g2_scroll_text_partial'] = function(block) {
      // 获取积木参数，添加默认值防御
      var object_name = block.getFieldValue('object_name') || 'u8g2';
      var text_content = Blockly.Arduino.valueToCode(block, 'text_content', Blockly.Arduino.ORDER_ATOMIC);
      if (!text_content || text_content === 'undefined') {
        text_content = '"你好世界"';
      } else if (!text_content.match(/^['"]/)) {
        text_content = '"' + text_content + '"';
      }
      
      // 处理所有坐标和参数，确保获取到有效数值
      var clip_x1 = Blockly.Arduino.valueToCode(block, 'clip_x1', Blockly.Arduino.ORDER_ATOMIC) || '35';
      var clip_y1 = Blockly.Arduino.valueToCode(block, 'clip_y1', Blockly.Arduino.ORDER_ATOMIC) || '11';
      var clip_x2 = Blockly.Arduino.valueToCode(block, 'clip_x2', Blockly.Arduino.ORDER_ATOMIC) || '74';
      var clip_y2 = Blockly.Arduino.valueToCode(block, 'clip_y2', Blockly.Arduino.ORDER_ATOMIC) || '27';
      var y_position = Blockly.Arduino.valueToCode(block, 'y_position', Blockly.Arduino.ORDER_ATOMIC) || '23';
      var scroll_speed = Blockly.Arduino.valueToCode(block, 'scroll_speed', Blockly.Arduino.ORDER_ATOMIC) || '1';
      var scroll_delay = Blockly.Arduino.valueToCode(block, 'scroll_delay', Blockly.Arduino.ORDER_ATOMIC) || '10';
      
      // 使用对象名作为唯一标识，避免重复定义
      var unique_id = object_name.replace(/[^a-zA-Z0-9_]/g, '_');
      var text_id = 'u8g2_scroll_text_partial_' + unique_id;
      
      // 判断是否为字符串字面量
      var isStringLiteral = text_content.match(/^['"].*['"]$/);
      var textVariable;
      
      if (isStringLiteral) {
        // 定义文本常量
        var escaped_text = text_content.slice(1, -1).replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
        Blockly.Arduino.definitions_[text_id] = 'const char ' + text_id + '[] = "' + escaped_text + '";\n';
        textVariable = text_id;
      } else {
        textVariable = text_content;
      }
      
      // 定义滚动位置变量
      var vars_key = 'u8g2_scroll_vars_partial_' + unique_id;
      Blockly.Arduino.definitions_[vars_key] = 'u8g2_uint_t u8g2_scroll_pos_partial_' + unique_id + ' = 0;\n';
      
      // 生成局部滚动代码
      var code = '';
      code += object_name + '.firstPage();\n';
      code += 'do {\n';
      
      // 重置滚动位置逻辑
      code += '  if (u8g2_scroll_pos_partial_' + unique_id + ' == 0) {\n';
      code += '    u8g2_scroll_pos_partial_' + unique_id + ' = ' + clip_x2 + ' - ' + clip_x1 + ' + 10;\n';
      code += '  } else {\n';
      code += '    u8g2_scroll_pos_partial_' + unique_id + ' -= ' + scroll_speed + ';\n';
      code += '  }\n';
      
      // 设置剪辑窗口
      code += '  ' + object_name + '.setClipWindow(' + clip_x1 + ', ' + clip_y1 + ', ' + clip_x2 + ', ' + clip_y2 + ');\n';
      
      // 绘制滚动文字
      if (isStringLiteral) {
        code += '  ' + object_name + '.drawUTF8(u8g2_scroll_pos_partial_' + unique_id + ', ' + y_position + ', ' + textVariable + ');\n';
      } else {
        code += '  ' + object_name + '.drawUTF8(u8g2_scroll_pos_partial_' + unique_id + ', ' + y_position + ', ' + textVariable + '.c_str());\n';
      }
      
      // 重置剪辑窗口
      code += '  ' + object_name + '.setMaxClipWindow();\n';
      
      // 绘制边框
      code += '  ' + object_name + '.drawFrame(' + (clip_x1 - 1) + ', ' + (clip_y1 - 1) + ', ' + (clip_x2 - clip_x1 + 2) + ', ' + (clip_y2 - clip_y1 + 2) + ');\n';
      
      code += '} while (' + object_name + '.nextPage());\n';
      code += 'delay(' + scroll_delay + ');\n';
      
      return code;
    };
  // 来回滚动文字
  Blockly.Arduino.forBlock['u8g2_scroll_text_bounce'] = function(block) {
    var object_name = block.getFieldValue('object_name') || 'u8g2';
    
    var text_content = Blockly.Arduino.valueToCode(block, 'text_content', Blockly.Arduino.ORDER_ATOMIC);
    if (!text_content || text_content === 'undefined') {
      text_content = '"来回滚动"';
    } else if (!text_content.match(/^['"]/)) {
      text_content = '"' + text_content + '"';
    }
    
    var y_pos = Blockly.Arduino.valueToCode(block, 'y_pos', Blockly.Arduino.ORDER_ATOMIC);
    if (!y_pos || y_pos === '') y_pos = '30';
    
    var scroll_speed = Blockly.Arduino.valueToCode(block, 'scroll_speed', Blockly.Arduino.ORDER_ATOMIC);
    if (!scroll_speed || scroll_speed === '') scroll_speed = '2';
    
    var scroll_delay = Blockly.Arduino.valueToCode(block, 'scroll_delay', Blockly.Arduino.ORDER_ATOMIC);
    if (!scroll_delay || scroll_delay === '') scroll_delay = '50';
    
    var unique_id = object_name.replace(/[^a-zA-Z0-9_]/g, '_');
    
    var vars_key = 'u8g2_bounce_vars_' + unique_id;
    Blockly.Arduino.definitions_[vars_key] = 
      'unsigned long u8g2_bounce_last_time_' + unique_id + ' = 0;\n' +
      'int u8g2_bounce_x_pos_' + unique_id + ' = 0;\n' +
      'int u8g2_bounce_dir_' + unique_id + ' = 1;\n' +
      'unsigned int u8g2_bounce_text_width_' + unique_id + ' = 0;\n';
    
    // 生成代码
    var code = '';
    code += object_name + '.clearBuffer();\n';
    code += '// 计算文本宽度（只在初始化时计算一次）\n';
    code += 'if (u8g2_bounce_text_width_' + unique_id + ' == 0) {\n';
    code += '  u8g2_bounce_text_width_' + unique_id + ' = ' + object_name + '.getUTF8Width(' + text_content + ');\n';
    code += '}\n';
    
    code += '// 检查是否需要更新位置\n';
    code += 'if (millis() - u8g2_bounce_last_time_' + unique_id + ' >= ' + scroll_delay + ') {\n';
    code += '  u8g2_bounce_last_time_' + unique_id + ' = millis();\n';
    code += '  \n';
    code += '  // 更新位置\n';
    code += '  u8g2_bounce_x_pos_' + unique_id + ' += u8g2_bounce_dir_' + unique_id + ' * ' + scroll_speed + ';\n';
    code += '  \n';
    code += '  // 检查边界条件，改变方向\n';
    code += '  if (u8g2_bounce_x_pos_' + unique_id + ' >= ' + object_name + '.getDisplayWidth() - u8g2_bounce_text_width_' + unique_id + ' && u8g2_bounce_dir_' + unique_id + ' > 0) {\n';
    code += '    u8g2_bounce_dir_' + unique_id + ' = -1; // 向左滚动\n';
    code += '  }\n';
    code += '  else if (u8g2_bounce_x_pos_' + unique_id + ' <= 0 && u8g2_bounce_dir_' + unique_id + ' < 0) {\n';
    code += '    u8g2_bounce_dir_' + unique_id + ' = 1; // 向右滚动\n';
    code += '  }\n';
    code += '}\n';
    code += '  \n';
    code += '// 绘制文本\n';
    code += object_name + '.drawUTF8(u8g2_bounce_x_pos_' + unique_id + ', ' + y_pos + ', ' + text_content + ');\n';
    
    return code;
  };

  Blockly.Arduino.forBlock['u8g2_example'] = function(block) {
    return '';
  };

  Blockly.Arduino.forBlock['u8g2_setRotate180'] = function(block) {
    var object_name = block.getFieldValue('object_name') || 'u8g2';
    var rotate = block.getFieldValue('rotate');
    var code = object_name + '.setDisplayRotation(U8G2_R' + (rotate ? '2' : '0') + ');\n';
    return code;
  };

  Blockly.Arduino.forBlock['u8g2_setColorIndex'] = function(block) {
    var object_name = block.getFieldValue('object_name') || 'u8g2';
    var color = Blockly.Arduino.valueToCode(block, 'color', Blockly.Arduino.ORDER_ATOMIC) || '1';
    var code = object_name + '.setColorIndex(' + color + ');\n';
    return code;
  };

  Blockly.Arduino.forBlock['u8g2_drawStr'] = function(block) {
    var object_name = block.getFieldValue('object_name') || 'u8g2';
    var x = Blockly.Arduino.valueToCode(block, 'x', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var y = Blockly.Arduino.valueToCode(block, 'y', Blockly.Arduino.ORDER_ATOMIC) || '0';
    var content = Blockly.Arduino.valueToCode(block, 'content', Blockly.Arduino.ORDER_ATOMIC) || '""';
    var code = object_name + '.drawStr(' + x + ', ' + y + ', ' + content + ');\n';
    return code;
  };

    // 红外发送高级版代码生成器（带长度和频率参数）
    Blockly.Arduino.forBlock['make_arduino_ir_send_advanced'] = function() {
        // 获取引脚值
        var pin = Blockly.Arduino.valueToCode(this, 'PIN', Blockly.Arduino.ORDER_ATOMIC) || '0';

        // 获取红外数据
        var irData = Blockly.Arduino.valueToCode(this, 'IR_DATA', Blockly.Arduino.ORDER_ATOMIC) || '"0,0,0,0,0,0,0,0"';

        // 获取长度参数
        var length = Blockly.Arduino.valueToCode(this, 'LENGTH', Blockly.Arduino.ORDER_ATOMIC) || '0';

        // 获取频率参数
        var freq = Blockly.Arduino.valueToCode(this, 'FREQ', Blockly.Arduino.ORDER_ATOMIC) || '38';

        // 添加头文件
        Blockly.Arduino.definitions_['include_IRremoteESP8266'] = '#include <IRremoteESP8266.h>';
        Blockly.Arduino.definitions_['include_IRsend'] = '#include <IRsend.h>';

        // 定义IRsend对象（使用唯一键避免冲突）
        Blockly.Arduino.definitions_['var_declare_irsend_advanced'] = 'IRsend irsend_advanced(' + pin + ');';

        // 定义rawData数组
        Blockly.Arduino.definitions_['var_declare_rawData_advanced'] = 'uint16_t rawDataAdvanced[500];';

        // setup代码 - 初始化irsend
        Blockly.Arduino.setups_['setup_irsend_advanced'] = 'irsend_advanced.begin();';

        // 生成代码：解析字符串并发送
        var code =
            '// 解析红外数据字符串\n' +
            'String irDataStr = String(' + irData + ');\n' +
            '// 去除大括号、空格等无关字符\n' +
            'irDataStr.replace("{", "");\n' +
            'irDataStr.replace("}", "");\n' +
            'irDataStr.replace(" ", "");\n' +
            'int dataIndex = 0;\n' +
            'int commaIndex = 0;\n' +
            'while ((commaIndex = irDataStr.indexOf(\',\')) != -1 && dataIndex < 500) {\n' +
            '  rawDataAdvanced[dataIndex++] = irDataStr.substring(0, commaIndex).toInt();\n' +
            '  irDataStr = irDataStr.substring(commaIndex + 1);\n' +
            '}\n' +
            'if (dataIndex < 500) {\n' +
            '  rawDataAdvanced[dataIndex++] = irDataStr.toInt();\n' +
            '}\n' +
            '// 使用指定长度和频率发送\n' +
            'int sendLength = (' + length + ' > 0) ? ' + length + ' : dataIndex;\n' +
            'if (sendLength > dataIndex) sendLength = dataIndex;\n' +
            'irsend_advanced.sendRaw(rawDataAdvanced, sendLength, ' + freq + ');\n';

        return code;
    };

    // ==================== LD2450 雷达模块代码生成器 ====================

    // LD2450 初始化并读取数据代码生成器（合并版）
    Blockly.Arduino.forBlock['ld2450_init_and_read'] = function() {
        var rxPin = Blockly.Arduino.valueToCode(this, 'RX_PIN', Blockly.Arduino.ORDER_ATOMIC) || '16';
        var txPin = Blockly.Arduino.valueToCode(this, 'TX_PIN', Blockly.Arduino.ORDER_ATOMIC) || '17';
        var baud = this.getFieldValue('BAUD');
        
        // 添加头文件
        Blockly.Arduino.definitions_['include_ld2450'] = '#include <HardwareSerial.h>\n#include <math.h>';
        
        // 定义LD2450串口
        Blockly.Arduino.definitions_['var_declare_ld2450_serial'] = 
            `// LD2450 雷达串口定义\n` +
            `#define LD2450_RX_PIN ${rxPin}\n` +
            `#define LD2450_TX_PIN ${txPin}\n` +
            `HardwareSerial ld2450Serial(1);`;
        
        // 定义目标数据结构
        Blockly.Arduino.definitions_['var_declare_ld2450_struct'] = 
            `// LD2450 目标数据结构\n` +
            `struct LD2450_Target {\n` +
            `  int16_t x;        // X坐标，单位mm\n` +
            `  int16_t y;        // Y坐标，单位mm\n` +
            `  int16_t speed;    // 速度，单位cm/s\n` +
            `  uint16_t resolution; // 距离分辨率\n` +
            `  bool valid;       // 目标是否有效\n` +
            `};\n` +
            `\n` +
            `LD2450_Target ld2450_targets[3];  // 最多3个目标\n` +
            `uint8_t ld2450_target_count = 0;  // 有效目标数量`;
        
        // 添加解析函数
        Blockly.Arduino.definitions_['function_ld2450_parse'] = 
            `// LD2450 数据解析函数\n` +
            `void ld2450_parseData() {\n` +
            `  // 清空目标数据\n` +
            `  for (int i = 0; i < 3; i++) {\n` +
            `    ld2450_targets[i].valid = false;\n` +
            `    ld2450_targets[i].x = 0;\n` +
            `    ld2450_targets[i].y = 0;\n` +
            `    ld2450_targets[i].speed = 0;\n` +
            `    ld2450_targets[i].resolution = 0;\n` +
            `  }\n` +
            `  ld2450_target_count = 0;\n` +
            `  \n` +
            `  // 检查串口是否有数据\n` +
            `  int availableBytes = ld2450Serial.available();\n` +
            `  if (availableBytes < 30) {\n` +
            `    return;\n` +
            `  }\n` +
            `  \n` +
            `  // 读取数据到缓冲区（最多读取60字节）\n` +
            `  uint8_t buffer[60];\n` +
            `  if (availableBytes > 60) availableBytes = 60;\n` +
            `  for (int i = 0; i < availableBytes; i++) {\n` +
            `    buffer[i] = ld2450Serial.read();\n` +
            `  }\n` +
            `  \n` +
            `  // 在缓冲区中查找帧头 AA FF 03 00\n` +
            `  for (int i = 0; i <= availableBytes - 30; i++) {\n` +
            `    if (buffer[i] == 0xAA && buffer[i+1] == 0xFF && buffer[i+2] == 0x03 && buffer[i+3] == 0x00) {\n` +
            `      // 检查帧尾 55 CC\n` +
            `      if (buffer[i+28] == 0x55 && buffer[i+29] == 0xCC) {\n` +
            `        // 解析3个目标数据\n` +
            `        for (int t = 0; t < 3; t++) {\n` +
            `          int offset = i + 4 + t * 8;\n` +
            `          \n` +
            `          // X坐标 (小端格式，有符号)\n` +
            `          uint16_t x_raw = buffer[offset] | ((uint16_t)buffer[offset + 1] << 8);\n` +
            `          if (x_raw & 0x8000) {\n` +
            `            ld2450_targets[t].x = -(int16_t)(x_raw & 0x7FFF);\n` +
            `          } else {\n` +
            `            ld2450_targets[t].x = (int16_t)(x_raw & 0x7FFF);\n` +
            `          }\n` +
            `          \n` +
            `          // Y坐标 (小端格式，有符号)\n` +
            `          uint16_t y_raw = buffer[offset + 2] | ((uint16_t)buffer[offset + 3] << 8);\n` +
            `          if (y_raw & 0x8000) {\n` +
            `            ld2450_targets[t].y = (int16_t)(y_raw & 0x7FFF);\n` +
            `          } else {\n` +
            `            ld2450_targets[t].y = -(int16_t)(y_raw & 0x7FFF);\n` +
            `          }\n` +
            `          \n` +
            `          // 速度 (小端格式，有符号)\n` +
            `          uint16_t speed_raw = buffer[offset + 4] | ((uint16_t)buffer[offset + 5] << 8);\n` +
            `          if (speed_raw & 0x8000) {\n` +
            `            ld2450_targets[t].speed = (int16_t)(speed_raw & 0x7FFF);\n` +
            `          } else {\n` +
            `            ld2450_targets[t].speed = -(int16_t)(speed_raw & 0x7FFF);\n` +
            `          }\n` +
            `          \n` +
            `          // 距离分辨率\n` +
            `          ld2450_targets[t].resolution = buffer[offset + 6] | ((uint16_t)buffer[offset + 7] << 8);\n` +
            `          \n` +
            `          // 判断目标是否有效（距离大于50mm）\n` +
            `          float distance = sqrt((float)ld2450_targets[t].x * ld2450_targets[t].x + \n` +
            `                               (float)ld2450_targets[t].y * ld2450_targets[t].y);\n` +
            `          if (distance > 50) {\n` +
            `            ld2450_targets[t].valid = true;\n` +
            `            ld2450_target_count++;\n` +
            `          }\n` +
            `        }\n` +
            `        return;  // 成功解析一帧，退出\n` +
            `      }\n` +
            `    }\n` +
            `  }\n` +
            `}`;
        
        // Setup代码
        Blockly.Arduino.setups_['setup_ld2450'] = 
            `// 初始化LD2450串口\n` +
            `ld2450Serial.begin(${baud}, SERIAL_8N1, LD2450_RX_PIN, LD2450_TX_PIN);`;
        
        // 返回读取数据代码 + 200ms延时
        return 'ld2450_parseData();\ndelay(200);';
    };

    // LD2450 获取目标数量代码生成器
    Blockly.Arduino.forBlock['ld2450_get_target_count'] = function() {
        var code = 'ld2450_target_count';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // LD2450 获取目标X坐标代码生成器
    Blockly.Arduino.forBlock['ld2450_get_target_x'] = function() {
        var target = this.getFieldValue('TARGET');
        var code = `ld2450_targets[${target}].x`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // LD2450 获取目标Y坐标代码生成器
    Blockly.Arduino.forBlock['ld2450_get_target_y'] = function() {
        var target = this.getFieldValue('TARGET');
        var code = `ld2450_targets[${target}].y`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // LD2450 获取目标距离代码生成器
    Blockly.Arduino.forBlock['ld2450_get_target_distance'] = function() {
        var target = this.getFieldValue('TARGET');
        var code = `(int)sqrt(ld2450_targets[${target}].x * ld2450_targets[${target}].x + ld2450_targets[${target}].y * ld2450_targets[${target}].y)`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // LD2450 获取目标速度代码生成器
    Blockly.Arduino.forBlock['ld2450_get_target_speed'] = function() {
        var target = this.getFieldValue('TARGET');
        var code = `ld2450_targets[${target}].speed`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // LD2450 获取目标角度代码生成器
    Blockly.Arduino.forBlock['ld2450_get_target_angle'] = function() {
        var target = this.getFieldValue('TARGET');
        var code = `(-atan2(ld2450_targets[${target}].x, ld2450_targets[${target}].y) * 180.0 / PI)`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // LD2450 设置追踪模式代码生成器
    Blockly.Arduino.forBlock['ld2450_set_tracking_mode'] = function() {
        var mode = this.getFieldValue('MODE');
        
        // 添加发送命令函数
        Blockly.Arduino.definitions_['function_ld2450_send_cmd'] = 
            `// LD2450 发送命令函数\n` +
            `void ld2450_sendCommand(uint16_t cmd, uint8_t* data, uint8_t len) {\n` +
            `  uint8_t frame[64];\n` +
            `  uint8_t idx = 0;\n` +
            `  \n` +
            `  // 帧头\n` +
            `  frame[idx++] = 0xFD;\n` +
            `  frame[idx++] = 0xFC;\n` +
            `  frame[idx++] = 0xFB;\n` +
            `  frame[idx++] = 0xFA;\n` +
            `  \n` +
            `  // 数据长度\n` +
            `  frame[idx++] = (len + 2) & 0xFF;\n` +
            `  frame[idx++] = ((len + 2) >> 8) & 0xFF;\n` +
            `  \n` +
            `  // 命令字\n` +
            `  frame[idx++] = cmd & 0xFF;\n` +
            `  frame[idx++] = (cmd >> 8) & 0xFF;\n` +
            `  \n` +
            `  // 数据\n` +
            `  for (int i = 0; i < len; i++) {\n` +
            `    frame[idx++] = data[i];\n` +
            `  }\n` +
            `  \n` +
            `  // 帧尾\n` +
            `  frame[idx++] = 0x04;\n` +
            `  frame[idx++] = 0x03;\n` +
            `  frame[idx++] = 0x02;\n` +
            `  frame[idx++] = 0x01;\n` +
            `  \n` +
            `  // 发送\n` +
            `  ld2450Serial.write(frame, idx);\n` +
            `}`;
        
        var code = '';
        if (mode === '0x80') {
            code = `// 设置单目标追踪模式\n` +
                   `ld2450_sendCommand(0x80, NULL, 0);`;
        } else {
            code = `// 设置多目标追踪模式\n` +
                   `ld2450_sendCommand(0x90, NULL, 0);`;
        }
        
        return code;
    };

    // LD2450 目标存在判断代码生成器
    Blockly.Arduino.forBlock['ld2450_target_exists'] = function() {
        var target = this.getFieldValue('TARGET');
        var code = `ld2450_targets[${target}].valid`;
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // IR发送代码生成器（合并版）
    Blockly.Arduino.forBlock['make_arduino_ir_send'] = function() {
        var pin = Blockly.Arduino.valueToCode(this, 'PIN', Blockly.Arduino.ORDER_ATOMIC) || '4';
        var protocol = this.getFieldValue('PROTOCOL');
        var data = Blockly.Arduino.valueToCode(this, 'DATA', Blockly.Arduino.ORDER_ATOMIC) || '0x00FFE01F';
        var bits = Blockly.Arduino.valueToCode(this, 'BITS', Blockly.Arduino.ORDER_ATOMIC) || '32';
        
        // 添加头文件 - 使用Make包装库避免冲突
        Blockly.Arduino.definitions_['include_irremotemake'] = '#include <IRremoteMake.h>';
        Blockly.Arduino.definitions_['include_irsendmake'] = '#include <IRsendMake.h>';
        
        // 生成IRsend对象声明（使用唯一的变量名）
        var irsendVar = 'irsend_' + pin;
        Blockly.Arduino.definitions_['var_declare_irsend_' + pin] = 'IRsend ' + irsendVar + '(' + pin + ');';
        
        // setup初始化
        Blockly.Arduino.setups_['setup_irsend_' + pin] = irsendVar + '.begin();';
        
        // 生成发送代码
        var code = '';
        switch(protocol) {
            case 'NEC':
                code = irsendVar + '.sendNEC(' + data + ', ' + bits + ');';
                break;
            case 'SONY':
                code = irsendVar + '.sendSony(' + data + ', ' + bits + ');';
                break;
            case 'SAMSUNG':
                code = irsendVar + '.sendSAMSUNG(' + data + ', ' + bits + ');';
                break;
            case 'PANASONIC':
                code = irsendVar + '.sendPanasonic(0x4004, ' + data + ');';
                break;
            case 'LG':
                code = irsendVar + '.sendLG(' + data + ', ' + bits + ');';
                break;
            case 'JVC':
                code = irsendVar + '.sendJVC(' + data + ', ' + bits + ');';
                break;
            case 'RC5':
                code = irsendVar + '.sendRC5(' + data + ', ' + bits + ');';
                break;
            case 'RC6':
                code = irsendVar + '.sendRC6(' + data + ', ' + bits + ');';
                break;
            case 'SHARP':
                code = irsendVar + '.sendSharpRaw(' + data + ', ' + bits + ');';
                break;
            case 'DENON':
                code = irsendVar + '.sendDenon(' + data + ', ' + bits + ');';
                break;
            default:
                code = irsendVar + '.sendNEC(' + data + ', ' + bits + ');';
        }
        return code + '\n';
    };
    
    // IR发送Raw数据代码生成器
    Blockly.Arduino.forBlock['make_arduino_ir_send_raw'] = function() {
        var pin = Blockly.Arduino.valueToCode(this, 'PIN', Blockly.Arduino.ORDER_ATOMIC) || '4';
        var data = Blockly.Arduino.valueToCode(this, 'DATA', Blockly.Arduino.ORDER_ATOMIC) || 'rawData';
        var length = Blockly.Arduino.valueToCode(this, 'LENGTH', Blockly.Arduino.ORDER_ATOMIC) || '67';
        var freq = Blockly.Arduino.valueToCode(this, 'FREQ', Blockly.Arduino.ORDER_ATOMIC) || '38';
        
        // 添加头文件 - 使用Make包装库避免冲突
        Blockly.Arduino.definitions_['include_irremotemake'] = '#include <IRremoteMake.h>';
        Blockly.Arduino.definitions_['include_irsendmake'] = '#include <IRsendMake.h>';
        
        // 生成IRsend对象声明
        var irsendVar = 'irsend_raw_' + pin;
        Blockly.Arduino.definitions_['var_declare_irsend_raw_' + pin] = 'IRsend ' + irsendVar + '(' + pin + ');';
        
        // setup初始化
        Blockly.Arduino.setups_['setup_irsend_raw_' + pin] = irsendVar + '.begin();';
        
        return irsendVar + '.sendRaw(' + data + ', ' + length + ', ' + freq + ');\n';
    };
    
    // IR接收代码生成器（合并版）- 类似图片中的if-else结构
    Blockly.Arduino.forBlock['make_arduino_ir_recv'] = function() {
        var pin = Blockly.Arduino.valueToCode(this, 'PIN', Blockly.Arduino.ORDER_ATOMIC) || '14';
        // 获取变量名 - 从FieldTextInput获取值
        var varName = this.getFieldValue('VAR') || 'ir_item';
        var branchDo = Blockly.Arduino.statementToCode(this, 'DO');
        var branchElse = Blockly.Arduino.statementToCode(this, 'ELSE');
        
        branchDo = Blockly.Arduino.addLoopTrap(branchDo, this.id);
        branchElse = Blockly.Arduino.addLoopTrap(branchElse, this.id);
        
        // 添加头文件 - 使用Make包装库避免冲突
        Blockly.Arduino.definitions_['include_irremotemake'] = '#include <IRremoteMake.h>';
        Blockly.Arduino.definitions_['include_irrecvmake'] = '#include <IRrecvMake.h>';
        Blockly.Arduino.definitions_['include_irutils'] = '#include <IRutils.h>';
        
        // 生成IRrecv对象声明
        var irrecvVar = 'irrecv_' + pin;
        Blockly.Arduino.definitions_['var_declare_irrecv_' + pin] = 'IRrecv ' + irrecvVar + '(' + pin + ');';
        Blockly.Arduino.definitions_['var_declare_results_' + pin] = 'decode_results results_' + pin + ';';
        
        // setup初始化
        Blockly.Arduino.setups_['setup_irrecv_' + pin] = irrecvVar + '.enableIRIn();';
        
        // 生成代码 - if-else结构
        var code = 'if (' + irrecvVar + '.decode(&results_' + pin + ')) {\n' +
                   '  uint64_t ' + varName + ' = results_' + pin + '.value;\n' +
                   branchDo +
                   '  ' + irrecvVar + '.resume();\n' +
                   '} else {\n' +
                   branchElse +
                   '}\n';
        
        return code;
    };
    
    // 通用空调控制代码生成器（合并版）
    Blockly.Arduino.forBlock['make_arduino_ir_ac_control'] = function() {
        var pin = Blockly.Arduino.valueToCode(this, 'PIN', Blockly.Arduino.ORDER_ATOMIC) || '4';
        var protocol = this.getFieldValue('PROTOCOL');
        var power = this.getFieldValue('POWER');
        var mode = this.getFieldValue('MODE');
        var temp = Blockly.Arduino.valueToCode(this, 'TEMP', Blockly.Arduino.ORDER_ATOMIC) || '25';
        var fan = this.getFieldValue('FAN');
        
        // 添加头文件 - 使用Make包装库避免冲突
        Blockly.Arduino.definitions_['include_irremotemake'] = '#include <IRremoteMake.h>';
        Blockly.Arduino.definitions_['include_iracmake'] = '#include <IRacMake.h>';
        
        // 生成IRac对象声明
        var acVar = 'ac_' + pin;
        Blockly.Arduino.definitions_['var_declare_irac_' + pin] = 'IRac ' + acVar + '(' + pin + ');';
        
        // setup初始化
        Blockly.Arduino.setups_['setup_irac_' + pin] = acVar + '.next.protocol = decode_type_t::' + protocol + ';\n' +
                                                        '  ' + acVar + '.next.model = 1;\n' +
                                                        '  ' + acVar + '.next.celsius = true;\n' +
                                                        '  ' + acVar + '.next.swingv = stdAc::swingv_t::kOff;\n' +
                                                        '  ' + acVar + '.next.swingh = stdAc::swingh_t::kOff;';
        
        // 生成控制代码
        var code = acVar + '.next.power = ' + power + ';\n' +
                   acVar + '.next.mode = stdAc::opmode_t::' + mode + ';\n' +
                   acVar + '.next.degrees = ' + temp + ';\n' +
                   acVar + '.next.fanspeed = stdAc::fanspeed_t::' + fan + ';\n' +
                   acVar + '.sendAc();';
        
        return code + '\n';
    };

// ===== SGP30 空气质量传感器 =====
    // 初始化SGP30传感器 - 使用硬件I2C
    Blockly.Arduino.forBlock['sgp30_init'] = function() {
        var sdaPin = Blockly.Arduino.valueToCode(this, 'SDA', Blockly.Arduino.ORDER_ATOMIC) || '21';
        var sclPin = Blockly.Arduino.valueToCode(this, 'SCL', Blockly.Arduino.ORDER_ATOMIC) || '22';

        Blockly.Arduino.definitions_['include_wire'] = '#include <Wire.h>';
        Blockly.Arduino.definitions_['include_adafruit_sgp30'] = '#include <Adafruit_SGP30.h>';

        Blockly.Arduino.definitions_['var_declare_sgp30'] = 'Adafruit_SGP30 sgp30;';

        Blockly.Arduino.definitions_['var_declare_eco2_baseline'] = 'uint16_t sgp30_eco2_baseline = 0;';
        Blockly.Arduino.definitions_['var_declare_tvoc_baseline'] = 'uint16_t sgp30_tvoc_baseline = 0;';

        Blockly.Arduino.setups_['setup_i2c_sgp30'] = `Wire.begin(${sdaPin}, ${sclPin});`;

        Blockly.Arduino.setups_['setup_sgp30'] = `if (!sgp30.begin()) {
    Serial.println("SGP30传感器未找到!");
    while (1);
  }
  Serial.print("SGP30序列号: ");
  Serial.print(sgp30.serialnumber[0], HEX);
  Serial.print(sgp30.serialnumber[1], HEX);
  Serial.println(sgp30.serialnumber[2], HEX);`;

        return '';
    };

    // 获取TVOC值（自动测量）
    Blockly.Arduino.forBlock['sgp30_get_tvoc'] = function() {
        Blockly.Arduino.definitions_['function_sgp30_measure_iaq'] = 
            `void sgp30MeasureIAQ() {
  if (!sgp30.IAQmeasure()) {
    Serial.println("空气质量测量失败");
  }
}`;
        return ['(sgp30MeasureIAQ(), sgp30.TVOC)', Blockly.Arduino.ORDER_ATOMIC];
    };

    // 获取eCO2值（自动测量）
    Blockly.Arduino.forBlock['sgp30_get_eco2'] = function() {
        Blockly.Arduino.definitions_['function_sgp30_measure_iaq'] = 
            `void sgp30MeasureIAQ() {
  if (!sgp30.IAQmeasure()) {
    Serial.println("空气质量测量失败");
  }
}`;
        return ['(sgp30MeasureIAQ(), sgp30.eCO2)', Blockly.Arduino.ORDER_ATOMIC];
    };

    // 获取原始H2信号（自动测量）
    Blockly.Arduino.forBlock['sgp30_get_raw_h2'] = function() {
        Blockly.Arduino.definitions_['function_sgp30_measure_raw'] = 
            `void sgp30MeasureRaw() {
  if (!sgp30.IAQmeasureRaw()) {
    Serial.println("原始数据测量失败");
  }
}`;
        return ['(sgp30MeasureRaw(), sgp30.rawH2)', Blockly.Arduino.ORDER_ATOMIC];
    };

    // 获取原始乙醇信号（自动测量）
    Blockly.Arduino.forBlock['sgp30_get_raw_ethanol'] = function() {
        Blockly.Arduino.definitions_['function_sgp30_measure_raw'] = 
            `void sgp30MeasureRaw() {
  if (!sgp30.IAQmeasureRaw()) {
    Serial.println("原始数据测量失败");
  }
}`;
        return ['(sgp30MeasureRaw(), sgp30.rawEthanol)', Blockly.Arduino.ORDER_ATOMIC];
    };

    // 计算绝对湿度的辅助函数
    Blockly.Arduino.forBlock['sgp30_set_humidity'] = function() {
        var temp = Blockly.Arduino.valueToCode(this, 'TEMP', Blockly.Arduino.ORDER_ATOMIC) || '25';
        var humidity = Blockly.Arduino.valueToCode(this, 'HUMIDITY', Blockly.Arduino.ORDER_ATOMIC) || '50';

        Blockly.Arduino.definitions_['function_get_absolute_humidity'] = 
            `uint32_t getAbsoluteHumidity(float temperature, float humidity) {
  const float absoluteHumidity = 216.7f * ((humidity / 100.0f) * 6.112f * exp((17.62f * temperature) / (243.12f + temperature)) / (273.15f + temperature));
  return (uint32_t)(1000.0f * absoluteHumidity);
}`;

        return `sgp30.setHumidity(getAbsoluteHumidity(${temp}, ${humidity}));`;
    };

    // 获取eCO2基线值（自动获取）
    Blockly.Arduino.forBlock['sgp30_get_eco2_baseline'] = function() {
        Blockly.Arduino.definitions_['function_sgp30_get_baseline'] = 
            `void sgp30GetBaseline() {
  if (!sgp30.getIAQBaseline(&sgp30_eco2_baseline, &sgp30_tvoc_baseline)) {
    Serial.println("获取基线值失败");
  }
}`;
        return ['(sgp30GetBaseline(), sgp30_eco2_baseline)', Blockly.Arduino.ORDER_ATOMIC];
    };

    // 获取TVOC基线值（自动获取）
    Blockly.Arduino.forBlock['sgp30_get_tvoc_baseline'] = function() {
        Blockly.Arduino.definitions_['function_sgp30_get_baseline'] = 
            `void sgp30GetBaseline() {
  if (!sgp30.getIAQBaseline(&sgp30_eco2_baseline, &sgp30_tvoc_baseline)) {
    Serial.println("获取基线值失败");
  }
}`;
        return ['(sgp30GetBaseline(), sgp30_tvoc_baseline)', Blockly.Arduino.ORDER_ATOMIC];
    };

    // 设置基线值
    Blockly.Arduino.forBlock['sgp30_set_baseline'] = function() {
        var eco2Base = Blockly.Arduino.valueToCode(this, 'ECO2_BASE', Blockly.Arduino.ORDER_ATOMIC) || '0';
        var tvocBase = Blockly.Arduino.valueToCode(this, 'TVOC_BASE', Blockly.Arduino.ORDER_ATOMIC) || '0';
        return `sgp30.setIAQBaseline(${eco2Base}, ${tvocBase});`;
    };

    // 获取序列号
    Blockly.Arduino.forBlock['sgp30_get_serial'] = function() {
        Blockly.Arduino.definitions_['function_get_sgp30_serial'] = 
            `String getSGP30Serial() {
  String serial = "";
  serial += String(sgp30.serialnumber[0], HEX);
  serial += String(sgp30.serialnumber[1], HEX);
  serial += String(sgp30.serialnumber[2], HEX);
  return serial;
}`;
        return ['getSGP30Serial()', Blockly.Arduino.ORDER_ATOMIC];
    };

    // 软复位
    Blockly.Arduino.forBlock['sgp30_soft_reset'] = function() {
        return `if (!sgp30.softReset()) {
    Serial.println("软复位失败");
  }`;
    };

    // ==================== 初始化类积木 ====================

    // 初始化 SD_MMC（默认引脚）
    Blockly.Arduino.forBlock['sd_mmc_init_default'] = function() {
        var mode = this.getFieldValue('MODE');

        // 检查是否已设置串口波特率，如果没有则自动添加
        var hasSerialBegin = false;
        for (var key in Blockly.Arduino.setups_) {
            if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
                hasSerialBegin = true;
                break;
            }
        }
        if (!hasSerialBegin) {
            Blockly.Arduino.setups_['setup_serial_auto'] = 'Serial.begin(115200);';
        }

        // 头文件
        Blockly.Arduino.definitions_['include_fs'] = '#include "FS.h"';
        Blockly.Arduino.definitions_['include_sd_mmc'] = '#include "SD_MMC.h"';

        // Setup代码
        var modeParam = (mode === '1BIT') ? 'true' : 'false';  // true=1-bit, false=4-bit
        Blockly.Arduino.setups_['setup_sd_mmc'] =
            `if (!SD_MMC.begin("/sdcard", ${modeParam})) {
    Serial.println("SD卡初始化失败");
    return;
  }
  Serial.println("SD卡初始化成功");`;

        return '';
    };

    // 初始化 SD_MMC（自定义引脚 - ESP32-S3专用）
    Blockly.Arduino.forBlock['sd_mmc_init_custom_pins'] = function() {
        var mode = this.getFieldValue('MODE');
        var clk = Blockly.Arduino.valueToCode(this, 'CLK', Blockly.Arduino.ORDER_ATOMIC) || '36';
        var cmd = Blockly.Arduino.valueToCode(this, 'CMD', Blockly.Arduino.ORDER_ATOMIC) || '35';
        var d0 = Blockly.Arduino.valueToCode(this, 'D0', Blockly.Arduino.ORDER_ATOMIC) || '37';
        var d1 = Blockly.Arduino.valueToCode(this, 'D1', Blockly.Arduino.ORDER_ATOMIC) || '38';
        var d2 = Blockly.Arduino.valueToCode(this, 'D2', Blockly.Arduino.ORDER_ATOMIC) || '33';
        var d3 = Blockly.Arduino.valueToCode(this, 'D3', Blockly.Arduino.ORDER_ATOMIC) || '39';

        // 检查是否已设置串口波特率
        var hasSerialBegin = false;
        for (var key in Blockly.Arduino.setups_) {
            if (Blockly.Arduino.setups_[key].indexOf('Serial.begin') !== -1) {
                hasSerialBegin = true;
                break;
            }
        }
        if (!hasSerialBegin) {
            Blockly.Arduino.setups_['setup_serial_auto'] = 'Serial.begin(115200);';
        }

        // 头文件
        Blockly.Arduino.definitions_['include_fs'] = '#include "FS.h"';
        Blockly.Arduino.definitions_['include_sd_mmc'] = '#include "SD_MMC.h"';

        // Setup代码
        var modeParam = (mode === '1BIT') ? 'true' : 'false';
        Blockly.Arduino.setups_['setup_sd_mmc'] =
            `if (!SD_MMC.setPins(${clk}, ${cmd}, ${d0}, ${d1}, ${d2}, ${d3})) {
    Serial.println("引脚设置失败");
    return;
  }
  if (!SD_MMC.begin("/sdcard", ${modeParam})) {
    Serial.println("SD卡初始化失败");
    return;
  }
  Serial.println("SD卡初始化成功");`;

        return '';
    };

    // ==================== 文件操作类积木 ====================

    // 列出目录文件
    Blockly.Arduino.forBlock['sd_mmc_list_dir'] = function() {
        var path = Blockly.Arduino.valueToCode(this, 'PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/"';
        var levels = Blockly.Arduino.valueToCode(this, 'LEVELS', Blockly.Arduino.ORDER_ATOMIC) || '0';

        Blockly.Arduino.definitions_['include_fs'] = '#include "FS.h"';
        Blockly.Arduino.definitions_['include_sd_mmc'] = '#include "SD_MMC.h"';

        // 定义递归列出目录函数
        var funcName = 'listDir';
        Blockly.Arduino.definitions_['function_' + funcName] =
            `void ${funcName}(fs::FS &fs, const char * dirname, uint8_t levels) {
  Serial.printf("列出目录: %s\\n", dirname);

  File root = fs.open(dirname);
  if (!root) {
    Serial.println("打开目录失败");
    return;
  }
  if (!root.isDirectory()) {
    Serial.println("不是目录");
    return;
  }

  File file = root.openNextFile();
  while (file) {
    if (file.isDirectory()) {
      Serial.print("  [DIR] ");
      Serial.println(file.name());
      if (levels) {
        ${funcName}(fs, file.path(), levels - 1);
      }
    } else {
      Serial.print("  [FILE] ");
      Serial.print(file.name());
      Serial.print("  大小: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
}`;

        return funcName + '(SD_MMC, ' + path + ', ' + levels + ');';
    };

    // 创建目录
    Blockly.Arduino.forBlock['sd_mmc_mkdir'] = function() {
        var path = Blockly.Arduino.valueToCode(this, 'PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/mydir"';

        Blockly.Arduino.definitions_['include_fs'] = '#include "FS.h"';
        Blockly.Arduino.definitions_['include_sd_mmc'] = '#include "SD_MMC.h"';

        var code = 'if (SD_MMC.mkdir(' + path + ')) {\n';
        code += '  Serial.println("目录创建成功");\n';
        code += '} else {\n';
        code += '  Serial.println("目录创建失败");\n';
        code += '}';

        return code;
    };

    // 删除目录
    Blockly.Arduino.forBlock['sd_mmc_rmdir'] = function() {
        var path = Blockly.Arduino.valueToCode(this, 'PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/mydir"';

        Blockly.Arduino.definitions_['include_fs'] = '#include "FS.h"';
        Blockly.Arduino.definitions_['include_sd_mmc'] = '#include "SD_MMC.h"';

        var code = 'if (SD_MMC.rmdir(' + path + ')) {\n';
        code += '  Serial.println("目录删除成功");\n';
        code += '} else {\n';
        code += '  Serial.println("目录删除失败");\n';
        code += '}';

        return code;
    };

    // 读取文件内容
    Blockly.Arduino.forBlock['sd_mmc_read_file'] = function() {
        var path = Blockly.Arduino.valueToCode(this, 'PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/test.txt"';

        Blockly.Arduino.definitions_['include_fs'] = '#include "FS.h"';
        Blockly.Arduino.definitions_['include_sd_mmc'] = '#include "SD_MMC.h"';

        var funcName = 'readFile';
        Blockly.Arduino.definitions_['function_' + funcName] =
            `String ${funcName}(fs::FS &fs, const char * path) {
  Serial.printf("读取文件: %s\\n", path);

  File file = fs.open(path);
  if (!file) {
    Serial.println("打开文件失败");
    return "";
  }

  String content = "";
  while (file.available()) {
    content += (char)file.read();
  }
  file.close();
  return content;
}`;

        var code = funcName + '(SD_MMC, ' + path + ')';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // 写入文件
    Blockly.Arduino.forBlock['sd_mmc_write_file'] = function() {
        var path = Blockly.Arduino.valueToCode(this, 'PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/test.txt"';
        var data = Blockly.Arduino.valueToCode(this, 'DATA', Blockly.Arduino.ORDER_ATOMIC) || '"Hello"';

        Blockly.Arduino.definitions_['include_fs'] = '#include "FS.h"';
        Blockly.Arduino.definitions_['include_sd_mmc'] = '#include "SD_MMC.h"';

        var funcName = 'writeFile';
        Blockly.Arduino.definitions_['function_' + funcName] =
            `void ${funcName}(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("写入文件: %s\\n", path);

  File file = fs.open(path, FILE_WRITE);
  if (!file) {
    Serial.println("打开文件失败");
    return;
  }
  if (file.print(message)) {
    Serial.println("文件写入成功");
  } else {
    Serial.println("文件写入失败");
  }
  file.close();
}`;

        return funcName + '(SD_MMC, ' + path + ', String(' + data + ').c_str());';
    };

    // 追加文件内容
    Blockly.Arduino.forBlock['sd_mmc_append_file'] = function() {
        var path = Blockly.Arduino.valueToCode(this, 'PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/test.txt"';
        var data = Blockly.Arduino.valueToCode(this, 'DATA', Blockly.Arduino.ORDER_ATOMIC) || '"World"';

        Blockly.Arduino.definitions_['include_fs'] = '#include "FS.h"';
        Blockly.Arduino.definitions_['include_sd_mmc'] = '#include "SD_MMC.h"';

        var funcName = 'appendFile';
        Blockly.Arduino.definitions_['function_' + funcName] =
            `void ${funcName}(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("追加文件: %s\\n", path);

  File file = fs.open(path, FILE_APPEND);
  if (!file) {
    Serial.println("打开文件失败");
    return;
  }
  if (file.print(message)) {
    Serial.println("文件追加成功");
  } else {
    Serial.println("文件追加失败");
  }
  file.close();
}`;

        return funcName + '(SD_MMC, ' + path + ', String(' + data + ').c_str());';
    };

    // 重命名文件
    Blockly.Arduino.forBlock['sd_mmc_rename_file'] = function() {
        var oldPath = Blockly.Arduino.valueToCode(this, 'OLD_PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/old.txt"';
        var newPath = Blockly.Arduino.valueToCode(this, 'NEW_PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/new.txt"';

        Blockly.Arduino.definitions_['include_fs'] = '#include "FS.h"';
        Blockly.Arduino.definitions_['include_sd_mmc'] = '#include "SD_MMC.h"';

        var code = 'if (SD_MMC.rename(' + oldPath + ', ' + newPath + ')) {\n';
        code += '  Serial.println("文件重命名成功");\n';
        code += '} else {\n';
        code += '  Serial.println("文件重命名失败");\n';
        code += '}';

        return code;
    };

    // 删除文件
    Blockly.Arduino.forBlock['sd_mmc_delete_file'] = function() {
        var path = Blockly.Arduino.valueToCode(this, 'PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/test.txt"';

        Blockly.Arduino.definitions_['include_fs'] = '#include "FS.h"';
        Blockly.Arduino.definitions_['include_sd_mmc'] = '#include "SD_MMC.h"';

        var code = 'if (SD_MMC.remove(' + path + ')) {\n';
        code += '  Serial.println("文件删除成功");\n';
        code += '} else {\n';
        code += '  Serial.println("文件删除失败");\n';
        code += '}';

        return code;
    };

    // 检查文件是否存在
    Blockly.Arduino.forBlock['sd_mmc_file_exists'] = function() {
        var path = Blockly.Arduino.valueToCode(this, 'PATH', Blockly.Arduino.ORDER_ATOMIC) || '"/test.txt"';

        Blockly.Arduino.definitions_['include_fs'] = '#include "FS.h"';
        Blockly.Arduino.definitions_['include_sd_mmc'] = '#include "SD_MMC.h"';

        var code = 'SD_MMC.exists(' + path + ')';
        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };

    // ==================== SD卡信息类积木 ====================

    // 获取SD卡信息
    Blockly.Arduino.forBlock['sd_mmc_card_info'] = function() {
        var infoType = this.getFieldValue('INFO_TYPE');

        Blockly.Arduino.definitions_['include_fs'] = '#include "FS.h"';
        Blockly.Arduino.definitions_['include_sd_mmc'] = '#include "SD_MMC.h"';

        var code;
        switch (infoType) {
            case 'cardType':
                var funcName = 'getCardType';
                Blockly.Arduino.definitions_['function_' + funcName] =
                    `String ${funcName}() {
  uint8_t cardType = SD_MMC.cardType();
  if (cardType == CARD_NONE) return "未插入";
  if (cardType == CARD_MMC) return "MMC";
  if (cardType == CARD_SD) return "SDSC";
  if (cardType == CARD_SDHC) return "SDHC";
  return "未知";
}`;
                code = funcName + '()';
                break;

            case 'totalMB':
                code = 'SD_MMC.cardSize() / (1024 * 1024)';
                break;

            case 'usedMB':
                code = 'SD_MMC.usedBytes() / (1024 * 1024)';
                break;

            case 'freeMB':
                code = '(SD_MMC.cardSize() - SD_MMC.usedBytes()) / (1024 * 1024)';
                break;

            case 'totalGB':
                code = 'SD_MMC.cardSize() / (1024.0 * 1024 * 1024)';
                break;

            case 'usedGB':
                code = 'SD_MMC.usedBytes() / (1024.0 * 1024 * 1024)';
                break;

            case 'freeGB':
                code = '(SD_MMC.cardSize() - SD_MMC.usedBytes()) / (1024.0 * 1024 * 1024)';
                break;

            case 'mounted':
                code = '(SD_MMC.cardType() != CARD_NONE)';
                break;

            default:
                code = '0';
        }

        return [code, Blockly.Arduino.ORDER_ATOMIC];
    };
})();
