From 073e875b2c2b2b64b24007247a0688548263f57f Mon Sep 17 00:00:00 2001 From: wangfeng <47658706+wangfeng-1@users.noreply.github.com> Date: Tue, 13 Apr 2021 11:04:26 +0800 Subject: [PATCH 01/92] Update build.gradle update org.fisco-bcos.java-sdk:fisco-bcos-java-sdk version --- build.gradle | 2 +- script/gm/webase-dml-gm.sql | 2 +- script/webase-dml.sql | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 021b285b9..54084758b 100644 --- a/build.gradle +++ b/build.gradle @@ -80,7 +80,7 @@ List mbg = [ dependencies { compile springboot,spring,jaxb,jackson,log4j - compile "org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.7.2-SNAPSHOT" + compile "org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.7.2" compile "org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.0" compile "org.apache.commons:commons-lang3:3.8.1" compile "mysql:mysql-connector-java:8.0.22" diff --git a/script/gm/webase-dml-gm.sql b/script/gm/webase-dml-gm.sql index cda8c7475..232c9d8d5 100644 --- a/script/gm/webase-dml-gm.sql +++ b/script/gm/webase-dml-gm.sql @@ -1,6 +1,6 @@ -- ---------------------------- --- 1、init tb_account_info data admin/password4 // 国密版 sm3.hash(password) +-- 1、init tb_account_info data admin/Abcd1234 // 国密版 sm3.hash(Abcd123) -- ---------------------------- INSERT INTO tb_account_info (account,account_pwd,role_id,create_time,modify_time)values('admin', '$2a$10$F/aEB1iEx/FvVh0fMn6L/uyy.PkpTy8Kd9EdbqLGo7Bw7eCivpq.m',100000,now(),now()); diff --git a/script/webase-dml.sql b/script/webase-dml.sql index d4e7165c5..7d50e7c09 100644 --- a/script/webase-dml.sql +++ b/script/webase-dml.sql @@ -1,6 +1,6 @@ -- ---------------------------- --- 1、init tb_account_info data admin/password4 +-- 1、init tb_account_info data admin/Abcd1234 -- ---------------------------- INSERT INTO tb_account_info (account,account_pwd,role_id,create_time,modify_time)values('admin', '$2a$10$F/aEB1iEx/FvVh0fMn6L/uyy.PkpTy8Kd9EdbqLGo7Bw7eCivpq.m',100000,now(),now()); From 1aba6d94d40917fdedd2c02a76735a62abe1e47c Mon Sep 17 00:00:00 2001 From: marsli Date: Mon, 19 Apr 2021 15:15:16 +0800 Subject: [PATCH 02/92] remove snapshot --- build.gradle | 2 +- script/gm/webase-dml-gm.sql | 2 +- script/webase-dml.sql | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 021b285b9..54084758b 100644 --- a/build.gradle +++ b/build.gradle @@ -80,7 +80,7 @@ List mbg = [ dependencies { compile springboot,spring,jaxb,jackson,log4j - compile "org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.7.2-SNAPSHOT" + compile "org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.7.2" compile "org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.0" compile "org.apache.commons:commons-lang3:3.8.1" compile "mysql:mysql-connector-java:8.0.22" diff --git a/script/gm/webase-dml-gm.sql b/script/gm/webase-dml-gm.sql index cda8c7475..232c9d8d5 100644 --- a/script/gm/webase-dml-gm.sql +++ b/script/gm/webase-dml-gm.sql @@ -1,6 +1,6 @@ -- ---------------------------- --- 1、init tb_account_info data admin/password4 // 国密版 sm3.hash(password) +-- 1、init tb_account_info data admin/Abcd1234 // 国密版 sm3.hash(Abcd123) -- ---------------------------- INSERT INTO tb_account_info (account,account_pwd,role_id,create_time,modify_time)values('admin', '$2a$10$F/aEB1iEx/FvVh0fMn6L/uyy.PkpTy8Kd9EdbqLGo7Bw7eCivpq.m',100000,now(),now()); diff --git a/script/webase-dml.sql b/script/webase-dml.sql index d4e7165c5..7d50e7c09 100644 --- a/script/webase-dml.sql +++ b/script/webase-dml.sql @@ -1,6 +1,6 @@ -- ---------------------------- --- 1、init tb_account_info data admin/password4 +-- 1、init tb_account_info data admin/Abcd1234 -- ---------------------------- INSERT INTO tb_account_info (account,account_pwd,role_id,create_time,modify_time)values('admin', '$2a$10$F/aEB1iEx/FvVh0fMn6L/uyy.PkpTy8Kd9EdbqLGo7Bw7eCivpq.m',100000,now(),now()); From e225f881c3bd27d7836693d36bfc83b7c891d1d0 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 22 Apr 2021 16:24:05 +0800 Subject: [PATCH 03/92] optimize cert code --- .../webase/node/mgr/base/tools/ZipUtils.java | 112 +++++++ .../webase/node/mgr/cert/CertController.java | 2 +- .../webase/node/mgr/cert/CertService.java | 307 +++++++++++------- 3 files changed, 310 insertions(+), 111 deletions(-) create mode 100644 src/main/java/com/webank/webase/node/mgr/base/tools/ZipUtils.java diff --git a/src/main/java/com/webank/webase/node/mgr/base/tools/ZipUtils.java b/src/main/java/com/webank/webase/node/mgr/base/tools/ZipUtils.java new file mode 100644 index 000000000..20d2ac605 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/base/tools/ZipUtils.java @@ -0,0 +1,112 @@ +/** + * Copyright 2014-2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.webank.webase.node.mgr.base.tools; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import lombok.extern.slf4j.Slf4j; + +/** + * @author marsli + */ +@Slf4j +public class ZipUtils { + + /** + * @param path 要压缩的文件路径 + * @param outputDir zip包的生成目录,默认为tempZip + * @param dirInZip directory in zip file, if blank, no dir in zip + */ + public static void generateZipFile(String path, String outputDir, String dirInZip, String zipFileName) throws Exception { + + File file2Zip = new File(CleanPathUtil.cleanString(path)); + // 压缩文件的路径不存在 + if (!file2Zip.exists()) { + log.error("file not exist:{}", path); + throw new Exception("file not exist: " + path); + } + // 用于存放压缩文件的文件夹 + File compress = new File(outputDir); + // 如果文件夹不存在,进行创建 + if (!compress.exists() ){ + compress.mkdirs(); + } + // 目的压缩文件,已存在则先删除 + // tempZip/conf.zip + String generateFileName = CleanPathUtil.cleanString(compress.getAbsolutePath() + File.separator + zipFileName); + File confZip = new File(generateFileName); + if (confZip.exists() ) { + log.info("confZip exist, now delete:{}", confZip); + boolean result = confZip.delete(); + log.info("confZip exist, delete result:{}", result); + } + // 输出流 + FileOutputStream outputStream = new FileOutputStream(generateFileName); + // 压缩输出流 + ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(outputStream)); + // 传入输出流,传入需要压缩的file路径 + generateFile(zipOutputStream, file2Zip, dirInZip); + + log.info("file2Zip:{} and outputFile:{}" ,file2Zip.getAbsolutePath(), generateFileName); + // 关闭 输出流 + zipOutputStream.close(); + outputStream.close(); + } + + + /** + * @param out 输出流 + * @param file 目标文件 + * @param dir 在压缩包中的文件夹 + * @throws Exception + */ + private static void generateFile(ZipOutputStream out, File file, String dir) throws Exception { + + // 当前的是文件夹,则进行一步处理 + if (file.isDirectory()) { + //得到文件列表信息 + File[] files = file.listFiles(); + + //将文件夹添加到下一级打包目录 + out.putNextEntry(new ZipEntry(dir + "/")); + + dir = dir.length() == 0 ? "" : dir + "/"; + + //循环将文件夹中的文件打包 + for (int i = 0; i < files.length; i++) { + generateFile(out, files[i], dir + files[i].getName()); + } + + } else { // 当前是文件 + + // 输入流 + FileInputStream inputStream = new FileInputStream(file); + // 标记要打包的条目 + out.putNextEntry(new ZipEntry(dir)); + // 进行写操作 + int len = 0; + byte[] bytes = new byte[1024]; + while ((len = inputStream.read(bytes)) > 0) { + out.write(bytes, 0, len); + } + // 关闭输入流 + inputStream.close(); + } + } +} diff --git a/src/main/java/com/webank/webase/node/mgr/cert/CertController.java b/src/main/java/com/webank/webase/node/mgr/cert/CertController.java index c190d26e1..eac79a2c9 100644 --- a/src/main/java/com/webank/webase/node/mgr/cert/CertController.java +++ b/src/main/java/com/webank/webase/node/mgr/cert/CertController.java @@ -89,7 +89,7 @@ public ResponseEntity getSdkCertZip(@PathVariable("frontId" Instant startTime = Instant.now(); log.info("start getSdkCertZip startTime:{},frontId:{}", startTime.toEpochMilli(), frontId); // get file - FileContentHandle fileContentHandle = certService.getFrontSdkFiles(frontId); + FileContentHandle fileContentHandle = certService.getFrontSdkZipFile(frontId); log.info("end getSdkCertZip fileContentHandle:{}useTime:{}", fileContentHandle, Duration.between(startTime, Instant.now()).toMillis()); return ResponseEntity.ok().headers(HttpRequestTools.headers(fileContentHandle.getFileName())) diff --git a/src/main/java/com/webank/webase/node/mgr/cert/CertService.java b/src/main/java/com/webank/webase/node/mgr/cert/CertService.java index d2be97799..77cdad83b 100644 --- a/src/main/java/com/webank/webase/node/mgr/cert/CertService.java +++ b/src/main/java/com/webank/webase/node/mgr/cert/CertService.java @@ -21,6 +21,7 @@ import com.webank.webase.node.mgr.base.tools.CertTools; import com.webank.webase.node.mgr.base.tools.CleanPathUtil; import com.webank.webase.node.mgr.base.tools.NodeMgrTools; +import com.webank.webase.node.mgr.base.tools.ZipUtils; import com.webank.webase.node.mgr.cert.entity.CertParam; import com.webank.webase.node.mgr.cert.entity.FileContentHandle; import com.webank.webase.node.mgr.cert.entity.TbCert; @@ -471,7 +472,13 @@ public Map getFrontSdkContent(int frontId) { return frontInterfaceService.getSdkFilesFromSpecificFront(front.getFrontIp(), front.getFrontPort()); } - public synchronized FileContentHandle getFrontSdkFiles(int frontId) { + + /** + * get sdk cert key files' zip + * @return + */ + public synchronized FileContentHandle getFrontSdkZipFile(int frontId) { + // get sdk cert content Map sdkContentMap = this.getFrontSdkContent(frontId); if (sdkContentMap.isEmpty()) { throw new NodeMgrException(ConstantCode.SDK_CRT_KEY_FILE_NOT_FOUND); @@ -479,9 +486,19 @@ public synchronized FileContentHandle getFrontSdkFiles(int frontId) { // get if guomi sdk String key = sdkContentMap.keySet().iterator().next(); boolean useGm = key.contains("gm"); + + // if guomi, create conf/gm, else create conf/ + File sdkDir; + if (useGm) { + sdkDir = new File(TEMP_SDK_DIR + File.separator + "gm"); + } else { + sdkDir = new File(TEMP_SDK_DIR); + } + log.info("writeSdkAsFile sdkDir:{}", sdkDir); // create dir and zip - writeSdkAsFile(sdkContentMap, useGm); + writeSdkFilesAndZip(sdkContentMap, sdkDir, useGm); try { + // FileInputStream would be closed by web return new FileContentHandle(TEMP_ZIP_FILE_NAME, new FileInputStream(TEMP_ZIP_FILE_PATH)); } catch (IOException e) { log.error("getFrontSdkFiles fail:[]", e); @@ -489,15 +506,29 @@ public synchronized FileContentHandle getFrontSdkFiles(int frontId) { } } - private void writeSdkAsFile(Map sdkContentMap, boolean useGm) { - // if guomi, create conf/gm, else create conf/ - File sdkDir; - if (useGm) { - sdkDir = new File(TEMP_SDK_DIR + File.separator + "gm"); - } else { - sdkDir = new File(TEMP_SDK_DIR); + private void writeSdkFilesAndZip(Map sdkContentMap, File sdkDir, boolean useGm) { + this.writeSdkAsFile(sdkContentMap, sdkDir); + // zip the directory of conf(guomi: conf/gm) + String gmDirInZip = useGm ? "gm" : ""; + try { + ZipUtils.generateZipFile(sdkDir.getPath(), TEMP_ZIP_DIR, gmDirInZip, TEMP_ZIP_FILE_NAME); + } catch (Exception e) { + log.error("writeSdkAsFile generateZipFile fail:[]", e); + throw new NodeMgrException(ConstantCode.WRITE_SDK_CRT_KEY_FILE_FAIL); } - log.info("writeSdkAsFile sdkDir:{}", sdkDir); + + // rm conf dir + boolean resultDel = sdkDir.delete(); + log.info("delete for temp sdk file, result:{}", resultDel); + } + + /** + * write sdk file of ca.crt, sdk.crt, sdk.key + * @param sdkContentMap + * @param sdkDir sdk file output directory + * @return + */ + public void writeSdkAsFile(Map sdkContentMap, File sdkDir) { // create sdk dir if (sdkDir.exists()) { @@ -511,10 +542,12 @@ private void writeSdkAsFile(Map sdkContentMap, boolean useGm) { // gm: gmca.crt, gmsdk.crt, gmsdk.key // else: ca.crt, sdk.crt, sdk.key for (String fileName : sdkContentMap.keySet()) { - Path sdkFilePath = Paths.get(sdkDir.getPath() + File.separator + CleanPathUtil.cleanString(fileName)); + Path sdkFilePath = Paths + .get(CleanPathUtil.cleanString(sdkDir.getPath() + File.separator + fileName)); String fileContent = sdkContentMap.get(fileName); log.info("writeSdkAsFile sdkPath:{}, content:{}", sdkFilePath, fileContent); - try (BufferedWriter writer = Files.newBufferedWriter(sdkFilePath, StandardCharsets.UTF_8)) { + try (BufferedWriter writer = Files + .newBufferedWriter(sdkFilePath, StandardCharsets.UTF_8)) { // write to relative path writer.write(fileContent); } catch (IOException e) { @@ -522,105 +555,159 @@ private void writeSdkAsFile(Map sdkContentMap, boolean useGm) { throw new NodeMgrException(ConstantCode.WRITE_SDK_CRT_KEY_FILE_FAIL); } } - // zip the directory of conf(guomi: conf/gm) - try { - generateZipFile(sdkDir.getPath(), TEMP_ZIP_DIR, useGm); - } catch (Exception e) { - log.error("writeSdkAsFile generateZipFile fail:[]", e); - throw new NodeMgrException(ConstantCode.WRITE_SDK_CRT_KEY_FILE_FAIL); - } - - // rm conf dir - boolean resultDel = sdkDir.delete(); - log.info("delete for temp sdk file, result:{}", resultDel); } - /** - * @param path 要压缩的文件路径 - * @param outputDir zip包的生成目录,默认为tempZip - * @param useGm if use gm, there is gm dir in zip - */ - public static void generateZipFile(String path, String outputDir, boolean useGm) throws Exception { - - File file2Zip = new File(CleanPathUtil.cleanString(path)); - // 压缩文件的路径不存在 - if (!file2Zip.exists()) { - log.error("file not exist:{}", path); - throw new Exception("file not exist: " + path); - } - // 用于存放压缩文件的文件夹 - File compress = new File(outputDir); - // 如果文件夹不存在,进行创建 - if (!compress.exists() ){ - compress.mkdirs(); - } - // 目的压缩文件,已存在则先删除 - // tempZip/conf.zip - String generateFileName = compress.getAbsolutePath() + File.separator + CleanPathUtil.cleanString(TEMP_ZIP_FILE_NAME); - File confZip = new File(generateFileName); - if (confZip.exists() ) { - log.info("confZip exist, now delete:{}", confZip); - confZip.delete(); - } - // 输出流 - FileOutputStream outputStream = new FileOutputStream(CleanPathUtil.cleanString(generateFileName)); - // 压缩输出流 - ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(outputStream)); - // 传入输出流,传入需要压缩的file路径 - String gmDir = useGm ? "gm" : ""; - generateFile(zipOutputStream, file2Zip, gmDir); - - log.info("file2Zip:{} and outputFile:{}" ,file2Zip.getAbsolutePath(), generateFileName); - // 关闭 输出流 - zipOutputStream.close(); - outputStream.close(); - } - - - /** - * @param out 输出流 - * @param file 目标文件 - * @param dir 在压缩包中的文件夹 - * @throws Exception - */ - private static void generateFile(ZipOutputStream out, File file, String dir) throws Exception { - - // 当前的是文件夹,则进行一步处理 - if (file.isDirectory()) { - //得到文件列表信息 - File[] files = file.listFiles(); - - //将文件夹添加到下一级打包目录 - out.putNextEntry(new ZipEntry(dir + "/")); - - dir = dir.length() == 0 ? "" : dir + "/"; - - //循环将文件夹中的文件打包 - for (int i = 0; i < files.length; i++) { - generateFile(out, files[i], dir + files[i].getName()); - } - - } else { // 当前是文件 - FileInputStream inputStream = null; - try { - inputStream = new FileInputStream(file); - // 标记要打包的条目 - out.putNextEntry(new ZipEntry(dir)); - // 进行写操作 - int len = 0; - byte[] bytes = new byte[1024]; - while ((len = inputStream.read(bytes)) > 0) { - out.write(bytes, 0, len); - } - } catch (IOException e) { - log.error("base64ToFile IOException:[{}]", e.toString()); - } finally { - if (inputStream != null) { - inputStream.close(); - } - } - } - - } +// +// public synchronized FileContentHandle getFrontSdkFiles(int frontId) { +// Map sdkContentMap = this.getFrontSdkContent(frontId); +// if (sdkContentMap.isEmpty()) { +// throw new NodeMgrException(ConstantCode.SDK_CRT_KEY_FILE_NOT_FOUND); +// } +// // get if guomi sdk +// String key = sdkContentMap.keySet().iterator().next(); +// boolean useGm = key.contains("gm"); +// // create dir and zip +// writeSdkAsFile(sdkContentMap, useGm); +// try { +// return new FileContentHandle(TEMP_ZIP_FILE_NAME, new FileInputStream(TEMP_ZIP_FILE_PATH)); +// } catch (IOException e) { +// log.error("getFrontSdkFiles fail:[]", e); +// throw new NodeMgrException(ConstantCode.WRITE_SDK_CRT_KEY_FILE_FAIL); +// } +// } +// +// private void writeSdkAsFile(Map sdkContentMap, boolean useGm) { +// // if guomi, create conf/gm, else create conf/ +// File sdkDir; +// if (useGm) { +// sdkDir = new File(TEMP_SDK_DIR + File.separator + "gm"); +// } else { +// sdkDir = new File(TEMP_SDK_DIR); +// } +// log.info("writeSdkAsFile sdkDir:{}", sdkDir); +// +// // create sdk dir +// if (sdkDir.exists()) { +// boolean result = sdkDir.delete(); +// log.info("delete existed gm dir, result:{}", result); +// } +// boolean result = sdkDir.mkdirs(); +// log.info("mkdir for temp sdk file, result:{}", result); +// +// // write each content to each file in conf/ or conf/gm/ +// // gm: gmca.crt, gmsdk.crt, gmsdk.key +// // else: ca.crt, sdk.crt, sdk.key +// for (String fileName : sdkContentMap.keySet()) { +// Path sdkFilePath = Paths.get(sdkDir.getPath() + File.separator + CleanPathUtil.cleanString(fileName)); +// String fileContent = sdkContentMap.get(fileName); +// log.info("writeSdkAsFile sdkPath:{}, content:{}", sdkFilePath, fileContent); +// try (BufferedWriter writer = Files.newBufferedWriter(sdkFilePath, StandardCharsets.UTF_8)) { +// // write to relative path +// writer.write(fileContent); +// } catch (IOException e) { +// log.error("writeSdkAsFile fail:[]", e); +// throw new NodeMgrException(ConstantCode.WRITE_SDK_CRT_KEY_FILE_FAIL); +// } +// } +// // zip the directory of conf(guomi: conf/gm) +// try { +// generateZipFile(sdkDir.getPath(), TEMP_ZIP_DIR, useGm); +// } catch (Exception e) { +// log.error("writeSdkAsFile generateZipFile fail:[]", e); +// throw new NodeMgrException(ConstantCode.WRITE_SDK_CRT_KEY_FILE_FAIL); +// } +// +// // rm conf dir +// boolean resultDel = sdkDir.delete(); +// log.info("delete for temp sdk file, result:{}", resultDel); +// } +// +// /** +// * @param path 要压缩的文件路径 +// * @param outputDir zip包的生成目录,默认为tempZip +// * @param useGm if use gm, there is gm dir in zip +// */ +// public static void generateZipFile(String path, String outputDir, boolean useGm) throws Exception { +// +// File file2Zip = new File(CleanPathUtil.cleanString(path)); +// // 压缩文件的路径不存在 +// if (!file2Zip.exists()) { +// log.error("file not exist:{}", path); +// throw new Exception("file not exist: " + path); +// } +// // 用于存放压缩文件的文件夹 +// File compress = new File(outputDir); +// // 如果文件夹不存在,进行创建 +// if (!compress.exists() ){ +// compress.mkdirs(); +// } +// // 目的压缩文件,已存在则先删除 +// // tempZip/conf.zip +// String generateFileName = compress.getAbsolutePath() + File.separator + CleanPathUtil.cleanString(TEMP_ZIP_FILE_NAME); +// File confZip = new File(generateFileName); +// if (confZip.exists() ) { +// log.info("confZip exist, now delete:{}", confZip); +// confZip.delete(); +// } +// // 输出流 +// FileOutputStream outputStream = new FileOutputStream(CleanPathUtil.cleanString(generateFileName)); +// // 压缩输出流 +// ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(outputStream)); +// // 传入输出流,传入需要压缩的file路径 +// String gmDir = useGm ? "gm" : ""; +// generateFile(zipOutputStream, file2Zip, gmDir); +// +// log.info("file2Zip:{} and outputFile:{}" ,file2Zip.getAbsolutePath(), generateFileName); +// // 关闭 输出流 +// zipOutputStream.close(); +// outputStream.close(); +// } +// +// +// /** +// * @param out 输出流 +// * @param file 目标文件 +// * @param dir 在压缩包中的文件夹 +// * @throws Exception +// */ +// private static void generateFile(ZipOutputStream out, File file, String dir) throws Exception { +// +// // 当前的是文件夹,则进行一步处理 +// if (file.isDirectory()) { +// //得到文件列表信息 +// File[] files = file.listFiles(); +// +// //将文件夹添加到下一级打包目录 +// out.putNextEntry(new ZipEntry(dir + "/")); +// +// dir = dir.length() == 0 ? "" : dir + "/"; +// +// //循环将文件夹中的文件打包 +// for (int i = 0; i < files.length; i++) { +// generateFile(out, files[i], dir + files[i].getName()); +// } +// +// } else { // 当前是文件 +// FileInputStream inputStream = null; +// try { +// inputStream = new FileInputStream(file); +// // 标记要打包的条目 +// out.putNextEntry(new ZipEntry(dir)); +// // 进行写操作 +// int len = 0; +// byte[] bytes = new byte[1024]; +// while ((len = inputStream.read(bytes)) > 0) { +// out.write(bytes, 0, len); +// } +// } catch (IOException e) { +// log.error("base64ToFile IOException:[{}]", e.toString()); +// } finally { +// if (inputStream != null) { +// inputStream.close(); +// } +// } +// } +// +// } } From c71a6fe13506373a2039abb5cfb96182a5030fd9 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 22 Apr 2021 16:24:29 +0800 Subject: [PATCH 04/92] update sdk --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 021b285b9..54084758b 100644 --- a/build.gradle +++ b/build.gradle @@ -80,7 +80,7 @@ List mbg = [ dependencies { compile springboot,spring,jaxb,jackson,log4j - compile "org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.7.2-SNAPSHOT" + compile "org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.7.2" compile "org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.0" compile "org.apache.commons:commons-lang3:3.8.1" compile "mysql:mysql-connector-java:8.0.22" From 6c3f3ada6243689ea283dfa55e198e3d56ffdc92 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 22 Apr 2021 16:31:14 +0800 Subject: [PATCH 05/92] merge upstream --- .../java/com/webank/webase/node/mgr/cert/CertService.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/cert/CertService.java b/src/main/java/com/webank/webase/node/mgr/cert/CertService.java index c359d985a..1fa586bfe 100644 --- a/src/main/java/com/webank/webase/node/mgr/cert/CertService.java +++ b/src/main/java/com/webank/webase/node/mgr/cert/CertService.java @@ -52,10 +52,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -<<<<<<>>>>>>upstream/dev - @Log4j2 @Service public class CertService { From 84beb6c7d92bb126fb3c465336f9b51fe7bf989c Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 23 Apr 2021 14:35:35 +0800 Subject: [PATCH 06/92] update version --- .../mgr/base/tools/SM3PasswordEncoder.java | 72 ------------------- src/main/resources/application.yml | 2 +- 2 files changed, 1 insertion(+), 73 deletions(-) delete mode 100644 src/main/java/com/webank/webase/node/mgr/base/tools/SM3PasswordEncoder.java diff --git a/src/main/java/com/webank/webase/node/mgr/base/tools/SM3PasswordEncoder.java b/src/main/java/com/webank/webase/node/mgr/base/tools/SM3PasswordEncoder.java deleted file mode 100644 index 80109626e..000000000 --- a/src/main/java/com/webank/webase/node/mgr/base/tools/SM3PasswordEncoder.java +++ /dev/null @@ -1,72 +0,0 @@ -///** -// * Copyright 2014-2021 the original author or authors. -// *

-// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// *

-// * http://www.apache.org/licenses/LICENSE-2.0 -// *

-// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ -// -//package com.webank.webase.node.mgr.base.tools; -// -//import org.apache.commons.logging.Log; -//import org.apache.commons.logging.LogFactory; -//import org.fisco.bcos.web3j.crypto.gm.sm3.SM3Digest; -//import org.fisco.bcos.web3j.utils.Numeric; -//import org.springframework.security.crypto.password.PasswordEncoder; -// -///** -// * PasswordEncoder using guomi sm3 encrypt -// */ -//public class SM3PasswordEncoder implements PasswordEncoder { -// private final Log logger = LogFactory.getLog(getClass()); -// -// public SM3PasswordEncoder() {} -// -// @Override -// public String encode(CharSequence rawPassword) { -// SM3Digest sm3Digest = new SM3Digest(); -// byte[] pwdInput = rawPassword.toString().getBytes(); -// byte[] hashed = sm3Digest.hash(pwdInput); -// return Numeric.toHexString(hashed); -// } -// -// /** -// * -// * @param rawPassword pwd (not decoded) to be checked -// * @param encodedPassword -// * @return -// */ -// @Override -// public boolean matches(CharSequence rawPassword, String encodedPassword){ -// if (encodedPassword == null || encodedPassword.length() == 0) { -// logger.warn("Empty encoded password"); -// return false; -// } -// String plainText = encode(rawPassword); -// return checkPwd(plainText, encodedPassword); -// } -// -// private boolean checkPwd(String plainText, String hashed) { -// char[] caa = plainText.toCharArray(); -// char[] cab = hashed.toCharArray(); -// -// if (caa.length != cab.length) { -// return false; -// } -// -// byte ret = 0; -// for (int i = 0; i < caa.length; i++) { -// ret |= caa[i] ^ cab[i]; -// } -// return ret == 0; -// } -// -//} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0eed26969..f71de8a42 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,5 +1,5 @@ # server version -version: v1.5.0 +version: v1.5.1 #server config server: From 4b42613ca3a673d1764b7e9f261b49b05f254a92 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 23 Apr 2021 14:56:24 +0800 Subject: [PATCH 07/92] add scaffold & ut --- .../node/mgr/scaffold/ScaffoldController.java | 56 ++++++ .../node/mgr/scaffold/ScaffoldService.java | 188 ++++++++++++++++++ .../node/mgr/scaffold/entity/ReqProject.java | 40 ++++ .../node/mgr/scaffold/entity/RspFile.java | 34 ++++ .../mgr/test/scaffold/ScaffoldBuildTest.java | 172 ++++++++++++++++ .../test/scaffold/ScaffoldControllerTest.java | 64 ++++++ .../test/scaffold/ScaffoldServiceTest.java | 56 ++++++ 7 files changed, 610 insertions(+) create mode 100644 src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java create mode 100644 src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java create mode 100644 src/main/java/com/webank/webase/node/mgr/scaffold/entity/ReqProject.java create mode 100644 src/main/java/com/webank/webase/node/mgr/scaffold/entity/RspFile.java create mode 100644 src/test/java/node/mgr/test/scaffold/ScaffoldBuildTest.java create mode 100644 src/test/java/node/mgr/test/scaffold/ScaffoldControllerTest.java create mode 100644 src/test/java/node/mgr/test/scaffold/ScaffoldServiceTest.java diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java new file mode 100644 index 000000000..8bada00c8 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java @@ -0,0 +1,56 @@ +/** + * Copyright 2014-2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.webank.webase.node.mgr.scaffold; + +import com.webank.webase.node.mgr.base.code.ConstantCode; +import com.webank.webase.node.mgr.base.controller.BaseController; +import com.webank.webase.node.mgr.base.entity.BaseResponse; +import com.webank.webase.node.mgr.base.properties.ConstantProperties; +import com.webank.webase.node.mgr.base.tools.JsonTools; +import com.webank.webase.node.mgr.scaffold.entity.ReqProject; +import com.webank.webase.node.mgr.scaffold.entity.RspFile; +import java.time.Duration; +import java.time.Instant; +import javax.validation.Valid; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author marsli + */ +@Log4j2 +@RestController +@RequestMapping(value = "scaffold") +public class ScaffoldController extends BaseController { + @Autowired + private ScaffoldService scaffoldService; + + @PostMapping("/export") + @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN_OR_DEVELOPER) + public BaseResponse exportProjectApi(@Valid @RequestBody ReqProject param) { + Instant startTime = Instant.now(); + log.info("start exportProjectApi param:{} groupId:{}", startTime.toEpochMilli(), + param); + RspFile rspFile = scaffoldService.exportProject(param); + log.info("end exportProjectApi useTime:{} result:{}", + Duration.between(startTime, Instant.now()).toMillis(), rspFile); + return new BaseResponse(ConstantCode.SUCCESS, rspFile); + } +} diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java new file mode 100644 index 000000000..1f01c0c41 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java @@ -0,0 +1,188 @@ +/** + * Copyright 2014-2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.webank.webase.node.mgr.scaffold; + +import com.webank.scaffold.artifact.ProjectArtifact; +import com.webank.scaffold.artifact.webase.NewMainResourceDir.ContractInfo; +import com.webank.scaffold.factory.ProjectFactory; +import com.webank.webase.node.mgr.base.code.ConstantCode; +import com.webank.webase.node.mgr.base.exception.NodeMgrException; +import com.webank.webase.node.mgr.base.tools.NodeMgrTools; +import com.webank.webase.node.mgr.base.tools.ZipUtils; +import com.webank.webase.node.mgr.cert.CertService; +import com.webank.webase.node.mgr.contract.ContractService; +import com.webank.webase.node.mgr.contract.entity.TbContract; +import com.webank.webase.node.mgr.front.FrontService; +import com.webank.webase.node.mgr.front.entity.FrontNodeConfig; +import com.webank.webase.node.mgr.front.entity.TbFront; +import com.webank.webase.node.mgr.frontinterface.FrontInterfaceService; +import com.webank.webase.node.mgr.scaffold.entity.ReqProject; +import com.webank.webase.node.mgr.scaffold.entity.RspFile; +import com.webank.webase.node.mgr.user.UserService; +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.fisco.bcos.sdk.crypto.CryptoSuite; +import org.fisco.bcos.sdk.model.CryptoType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * use webank-blockchain-smart-dev-scaffold + * to generate demo project of contract + * @author marsli + */ +@Slf4j +@Service +public class ScaffoldService { + @Autowired + private ContractService contractService; + @Autowired + private CryptoSuite cryptoSuite; + @Autowired + private CertService certService; + @Autowired + private FrontService frontService; + @Autowired + private UserService userService; + @Autowired + private FrontInterfaceService frontInterfaceService; + + private static final String OUTPUT_DIR = "output"; + private static final String ZIP_SUFFIX = ".zip"; + private static final String OUTPUT_ZIP_DIR = OUTPUT_DIR + File.separator + "zip"; + + /** + * generate by contract with sol + */ + public RspFile exportProject(ReqProject reqProject) { + String artifactName = reqProject.getArtifactName(); + // check dir exist + File checkProjectDir = new File(OUTPUT_DIR + File.separator + artifactName); + if (checkProjectDir.exists()) { + log.error("exportProject dir exist: {}", artifactName); + throw new NodeMgrException(ConstantCode.PROJECT_NAME_ALREADY_EXIST); + } + // get contract info list + List contractIdList = reqProject.getContractIdList(); + List tbContractList = new ArrayList<>(); + for (Integer id : contractIdList) { + TbContract contract = contractService.queryByContractId(id); + if (contract == null || StringUtils.isBlank(contract.getBytecodeBin())) { + log.error("exportProject contract not exist or not compiled, id:{}", id); + throw new NodeMgrException(ConstantCode.INVALID_CONTRACT_ID); + } + tbContractList.add(contract); + } + // get from front + TbFront front = frontService.getById(reqProject.getFrontId()); + if (front == null) { + log.error("exportProject front not exist:{}", reqProject.getFrontId()); + throw new NodeMgrException(ConstantCode.INVALID_FRONT_ID); + } + // get front's p2p ip and channel port + FrontNodeConfig frontNodeConfig = frontInterfaceService + .getNodeConfigFromSpecificFront(front.getFrontIp(), front.getFrontPort()); + log.info("exportProject get frontNodeConfig:{}", frontNodeConfig); + // get front's sdk key cert + Map sdkMap = certService.getFrontSdkContent(front.getFrontId()); + log.info("exportProject get sdkMap size:{}", sdkMap.size()); + // get user private key if set + String hexPrivateKey = ""; + if (StringUtils.isNotBlank(reqProject.getUserAddress())) { + hexPrivateKey = userService.queryUserDetail(reqProject.getGroupId(), reqProject.getUserAddress()); + } + log.info("exportProject get hexPrivateKey length:{}", hexPrivateKey.length()); + // generate + String projectPath = this.generateProject(frontNodeConfig, reqProject.getGroup(), reqProject.getArtifactName(), + tbContractList, reqProject.getGroupId(), hexPrivateKey, sdkMap); + String zipFileName = artifactName + ZIP_SUFFIX; + try { + ZipUtils.generateZipFile(projectPath, OUTPUT_ZIP_DIR, "", zipFileName); + } catch (Exception e) { + log.error("exportProject generateZipFile failed:[]", e); + // if failed, delete project dir + boolean result = checkProjectDir.delete(); + log.error("zip failed, now delete project dir, result:{}", result); + } + String zipFileFullPath = OUTPUT_ZIP_DIR + File.separator + zipFileName; + log.info("exportProject zipFileName:{}, zipFileFullPath{}", zipFileName, zipFileFullPath); + RspFile rspFile = new RspFile(); + rspFile.setFileName(zipFileName); + rspFile.setFileStreamBase64(NodeMgrTools.fileToBase64(zipFileFullPath)); + return rspFile; + } + + /** + * generate project + * @param nodeConfig ip channel port + * @param projectGroup + * @param artifactName + * @param tbContractList + * @param groupId + * @param hexPrivateKey + * @param sdkMap + * @return path string of project + */ + public String generateProject(FrontNodeConfig nodeConfig, String projectGroup, String artifactName, + List tbContractList, int groupId, String hexPrivateKey, Map sdkMap) { + log.info("generateProject sdkMap size:{}", sdkMap.size()); + List contractInfoList = this.handleContractList(tbContractList); + String frontChannelIpPort = nodeConfig.getP2pip() + ":" + nodeConfig.getChannelPort(); + ProjectFactory projectFactory = new ProjectFactory(); + log.info("generateProject projectGroup:{},artifactName:{},OUTPUT_DIR:{},frontChannelIpPort:{},groupId:{}", + projectGroup, artifactName, OUTPUT_DIR, frontChannelIpPort, groupId); + ProjectArtifact result = projectFactory.buildProjectDir(contractInfoList, + projectGroup, artifactName, OUTPUT_DIR, + frontChannelIpPort, groupId, hexPrivateKey, sdkMap); + String projectDir = OUTPUT_DIR + File.separator + artifactName; + log.info("generateProject result:{}", projectDir); + return projectDir; + } + + private List handleContractList(List contractList) { + List contractInfoList = new ArrayList<>(); + log.info("handleContractList param contractList size:{}", contractList.size()); + for (TbContract contract : contractList) { + String sourceCodeBase64 = contract.getContractSource(); + String solSourceCode = new String(Base64.getDecoder().decode(sourceCodeBase64)); + String contractName = contract.getContractName(); + String contractAddress = contract.getContractAddress(); + String contractAbi = contract.getContractAbi(); + String bytecodeBin = contract.getBytecodeBin(); + + ContractInfo contractInfo = new ContractInfo(); + contractInfo.setSolRawString(solSourceCode); + contractInfo.setContractName(contractName); + contractInfo.setContractAddress(contractAddress); + contractInfo.setAbiStr(contractAbi); + if (cryptoSuite.getCryptoTypeConfig() == CryptoType.SM_TYPE) { + contractInfo.setSmBinStr(bytecodeBin); + } else { + contractInfo.setBinStr(bytecodeBin); + } + contractInfoList.add(contractInfo); + } + log.info("handleContractList result contractInfoList size:{}", contractInfoList.size()); + return contractInfoList; + } +} diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/entity/ReqProject.java b/src/main/java/com/webank/webase/node/mgr/scaffold/entity/ReqProject.java new file mode 100644 index 000000000..be2ec707d --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/entity/ReqProject.java @@ -0,0 +1,40 @@ +/** + * Copyright 2014-2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.webank.webase.node.mgr.scaffold.entity; + +import java.util.List; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author marsli + */ +@Data +@NoArgsConstructor +public class ReqProject { + @NotNull + private List contractIdList; + @NotBlank + private String group; + @NotBlank + private String artifactName; + @NotNull + private Integer frontId; + @NotNull + private Integer groupId; + private String userAddress; +} diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/entity/RspFile.java b/src/main/java/com/webank/webase/node/mgr/scaffold/entity/RspFile.java new file mode 100644 index 000000000..6b709be1f --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/entity/RspFile.java @@ -0,0 +1,34 @@ +/** + * Copyright 2014-2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.webank.webase.node.mgr.scaffold.entity; + +import com.webank.webase.node.mgr.base.tools.NodeMgrTools; +import java.io.InputStream; +import java.util.Base64; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author marsli + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class RspFile { + private String fileName; + private String fileStreamBase64; + +} diff --git a/src/test/java/node/mgr/test/scaffold/ScaffoldBuildTest.java b/src/test/java/node/mgr/test/scaffold/ScaffoldBuildTest.java new file mode 100644 index 000000000..c93b9846b --- /dev/null +++ b/src/test/java/node/mgr/test/scaffold/ScaffoldBuildTest.java @@ -0,0 +1,172 @@ +/** + * Copyright 2014-2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package node.mgr.test.scaffold; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.webank.scaffold.artifact.ProjectArtifact; +import com.webank.scaffold.artifact.webase.NewMainResourceDir.ContractInfo; +import com.webank.scaffold.factory.ProjectFactory; +import com.webank.scaffold.util.IOUtil; +import com.webank.webase.node.mgr.base.tools.CleanPathUtil; +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.Map; +import org.junit.Test; + +public class ScaffoldBuildTest { + // hello world + public final static String helloWorldSolBase64Str = "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjsNCmNvbnRyYWN0IEhlbGxvV29ybGR7DQogICAgc3RyaW5nIG5hbWU7DQogICAgZXZlbnQgU2V0TmFtZShzdHJpbmcgbmFtZSk7DQogICAgZnVuY3Rpb24gZ2V0KCljb25zdGFudCByZXR1cm5zKHN0cmluZyl7DQogICAgICAgIHJldHVybiBuYW1lOw0KICAgIH0NCiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nIG4pew0KICAgICAgICBlbWl0IFNldE5hbWUobik7DQogICAgICAgIG5hbWU9bjsNCiAgICB9DQp9"; + public final static String contractAddress = "0xd5d4fcf2a46831510f095bfb447bc945f99309f7"; + public final static String contractName = "HelloWorld"; + public final static String abiStr = "[{\"constant\":false,\"inputs\":[{\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"name\",\"type\":\"string\"}],\"name\":\"SetName\",\"type\":\"event\"}]"; + public final static String binStr = "608060405234801561001057600080fd5b50610373806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634ed3885e146100515780636d4ce63c146100ba575b600080fd5b34801561005d57600080fd5b506100b8600480360381019080803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061014a565b005b3480156100c657600080fd5b506100cf610200565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010f5780820151818401526020810190506100f4565b50505050905090810190601f16801561013c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b7f4df9dcd34ae35f40f2c756fd8ac83210ed0b76d065543ee73d868aec7c7fcf02816040518080602001828103825283818151815260200191508051906020019080838360005b838110156101ac578082015181840152602081019050610191565b50505050905090810190601f1680156101d95780820380516001836020036101000a031916815260200191505b509250505060405180910390a180600090805190602001906101fc9291906102a2565b5050565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102985780601f1061026d57610100808354040283529160200191610298565b820191906000526020600020905b81548152906001019060200180831161027b57829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102e357805160ff1916838001178555610311565b82800160010185558215610311579182015b828111156103105782518255916020019190600101906102f5565b5b50905061031e9190610322565b5090565b61034491905b80821115610340576000816000905550600101610328565b5090565b905600a165627a7a72305820baa9e2a7ab055843a8a3de62b50fba49e6309323fb92358b598491fa5a76b9e90029"; + public final static String smBinStr = ""; + public final static String sdkMapStr = "{\"sdk.key\":\"-----BEGIN PRIVATE KEY-----\\nMIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgxqr/d/VgQ0fAr/KvyAeW\\nJ6bD1tqxZ5gYOdfIJiK7WOmhRANCAAT3g/OsuSAD2I/dKLWnZTbMGQ8l9WnkD/wr\\npyoiQkMy1qI5/3Sj4WFKGcVu9vhsd0nLoP+y1QttYKM0m5QGcuhP\\n-----END PRIVATE KEY-----\\n\",\"ca.crt\":\"-----BEGIN CERTIFICATE-----\\nMIIBsDCCAVagAwIBAgIJAPwQ7ISyofOIMAoGCCqGSM49BAMCMDUxDjAMBgNVBAMM\\nBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAgFw0y\\nMTA0MDYxMjMwNDBaGA8yMTIxMDMxMzEyMzA0MFowNTEOMAwGA1UEAwwFY2hhaW4x\\nEzARBgNVBAoMCmZpc2NvLWJjb3MxDjAMBgNVBAsMBWNoYWluMFYwEAYHKoZIzj0C\\nAQYFK4EEAAoDQgAE6UcrK7ukGBVvBmWYwgIloM38ibqtxF2zBnM9zgU4bujjJU1Y\\nCZsHGKVGuNstSOZYfYulnTtFUoHhUEyhddvql6NQME4wHQYDVR0OBBYEFBBSyZi8\\nk/Hz/Q2SAin5bMnE1nOFMB8GA1UdIwQYMBaAFBBSyZi8k/Hz/Q2SAin5bMnE1nOF\\nMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgEpuPZypVImOtDty9p50X\\njeD4wdgzHXpd3CDPui4CnZYCIQC4n+r97cCB51dPb+WjDNV5C18S2uI8LlNVj+xL\\ndSweAg==\\n-----END CERTIFICATE-----\\n\",\"sdk.crt\":\"-----BEGIN CERTIFICATE-----\\nMIIBeDCCAR+gAwIBAgIJAJoEtSMUsa8HMAoGCCqGSM49BAMCMDgxEDAOBgNVBAMM\\nB2FnZW5jeUExEzARBgNVBAoMCmZpc2NvLWJjb3MxDzANBgNVBAsMBmFnZW5jeTAg\\nFw0yMTA0MDYxMjMwNDBaGA8yMTIxMDMxMzEyMzA0MFowMTEMMAoGA1UEAwwDc2Rr\\nMRMwEQYDVQQKDApmaXNjby1iY29zMQwwCgYDVQQLDANzZGswVjAQBgcqhkjOPQIB\\nBgUrgQQACgNCAAT3g/OsuSAD2I/dKLWnZTbMGQ8l9WnkD/wrpyoiQkMy1qI5/3Sj\\n4WFKGcVu9vhsd0nLoP+y1QttYKM0m5QGcuhPoxowGDAJBgNVHRMEAjAAMAsGA1Ud\\nDwQEAwIF4DAKBggqhkjOPQQDAgNHADBEAiANbeRFiiS6mH+vcAOwV3wXd9YW/B2a\\n+vrHMm6NwtliRAIgRH4gSF0XLmpVOEO21bJFDGWm9siIX0cnj0R3kNGZcB4=\\n-----END CERTIFICATE-----\\n-----BEGIN CERTIFICATE-----\\nMIIBcTCCARegAwIBAgIJANrOZ+FrVNpIMAoGCCqGSM49BAMCMDUxDjAMBgNVBAMM\\nBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAeFw0y\\nMTA0MDYxMjMwNDBaFw0zMTA0MDQxMjMwNDBaMDgxEDAOBgNVBAMMB2FnZW5jeUEx\\nEzARBgNVBAoMCmZpc2NvLWJjb3MxDzANBgNVBAsMBmFnZW5jeTBWMBAGByqGSM49\\nAgEGBSuBBAAKA0IABIqMDvvzvTq8WW1UtJrnnsifw9/OrPsMc9CrrYBsWdwOGhdx\\nfNTJA1ss+vngjrhAmWHczvbh+E1WOlDGzpCumeqjEDAOMAwGA1UdEwQFMAMBAf8w\\nCgYIKoZIzj0EAwIDSAAwRQIhALsAbAQ9BDeofk4VYzYx2ZAHB1HviDp9ndvXAkLN\\nsfHZAiAjViK97dDr3gxP/qHg0e8BG9ptEv7Do8caOPj33F+yOQ==\\n-----END CERTIFICATE-----\\n-----BEGIN CERTIFICATE-----\\nMIIBsDCCAVagAwIBAgIJAPwQ7ISyofOIMAoGCCqGSM49BAMCMDUxDjAMBgNVBAMM\\nBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAgFw0y\\nMTA0MDYxMjMwNDBaGA8yMTIxMDMxMzEyMzA0MFowNTEOMAwGA1UEAwwFY2hhaW4x\\nEzARBgNVBAoMCmZpc2NvLWJjb3MxDjAMBgNVBAsMBWNoYWluMFYwEAYHKoZIzj0C\\nAQYFK4EEAAoDQgAE6UcrK7ukGBVvBmWYwgIloM38ibqtxF2zBnM9zgU4bujjJU1Y\\nCZsHGKVGuNstSOZYfYulnTtFUoHhUEyhddvql6NQME4wHQYDVR0OBBYEFBBSyZi8\\nk/Hz/Q2SAin5bMnE1nOFMB8GA1UdIwQYMBaAFBBSyZi8k/Hz/Q2SAin5bMnE1nOF\\nMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgEpuPZypVImOtDty9p50X\\njeD4wdgzHXpd3CDPui4CnZYCIQC4n+r97cCB51dPb+WjDNV5C18S2uI8LlNVj+xL\\ndSweAg==\\n-----END CERTIFICATE-----\\n\"}"; + + // build params + String group = "org.webase.example"; + String artifactName = "demo"; + String outputDir = "output"; + + String solDir = outputDir + File.separator + "contracts"; + String resourcesDir = outputDir + File.separator + artifactName + + File.separator + "src" + File.separator + "main" + File.separator + "resources"; + String confDir = resourcesDir + File.separator + "conf"; + /** + * 生成sol文件到指定目录 + */ + @Test + public void writeSolFile() { + String solSourceCode = new String(Base64.getDecoder().decode(helloWorldSolBase64Str)); + String solFileName = "HelloWorld.sol"; + System.out.println("solSourceCode: " + solSourceCode); + File solDirCheck = new File(solDir); + if (!solDirCheck.exists()) { + boolean createSolDir = solDirCheck.mkdirs(); + System.out.println("createSolDir: " + createSolDir); + } + Path solFilePath = Paths + .get(CleanPathUtil.cleanString(solDir + File.separator + solFileName)); + System.out.println("solFilePath: " + solFilePath); + try (BufferedWriter writer = Files + .newBufferedWriter(solFilePath, StandardCharsets.UTF_8)) { + // write to relative path + writer.write(solSourceCode); + } catch (IOException e) { + System.out.println("error: " + Arrays.toString(e.getStackTrace())); + } + + } + + /** + * 根据sol文件生成项目 + */ + @Test + public void testFactory() { + ProjectFactory projectFactory = new ProjectFactory(); + ProjectArtifact artifact = projectFactory.buildProjectDir(solDir, group, artifactName, outputDir, contractName); + System.out.println("artifact: " + artifact); + } + + /** + * 根据入参生成项目 + */ + @Test + public void testBuildByParam() throws JsonProcessingException { + String solSourceCode = new String(Base64.getDecoder().decode(helloWorldSolBase64Str)); + + ContractInfo contractInfo = new ContractInfo(); + contractInfo.setContractName(contractName); + contractInfo.setAbiStr(abiStr); + contractInfo.setBinStr(binStr); + contractInfo.setSolRawString(solSourceCode); + contractInfo.setContractAddress(contractAddress); + System.out.println("contractInfo: "); + System.out.println(contractInfo); + + ObjectMapper mapper = new ObjectMapper(); + Map sdkMap = mapper.readValue(sdkMapStr, Map.class); + System.out.println("sdkMap: "); + System.out.println(sdkMap); + + ProjectFactory projectFactory = new ProjectFactory(); + ProjectArtifact result = projectFactory.buildProjectDir(Collections.singletonList(contractInfo), + group, artifactName, outputDir, + //null, null, null, null); + "127.0.0.1:25200", 2, "0x123", sdkMap); + } + + /** + * build with multi sol contract + */ + @Test + public void testBuildMultiSol() throws JsonProcessingException { + String solSourceCode = new String(Base64.getDecoder().decode(helloWorldSolBase64Str)); + + ContractInfo contractInfo = new ContractInfo(); + contractInfo.setContractName(contractName); + contractInfo.setAbiStr(abiStr); + contractInfo.setBinStr(binStr); + contractInfo.setSolRawString(solSourceCode); + contractInfo.setContractAddress("0xd5d4fcf2a46831510f095bfb447bc945f99309f7"); + + ContractInfo creditContract = new ContractInfo(); + creditContract.setContractName("Credit"); + creditContract.setAbiStr("[{\"constant\":false,\"inputs\":[{\"name\":\"comName\",\"type\":\"string\"},{\"name\":\"mergeField\",\"type\":\"string\"}],\"name\":\"register\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"comName\",\"type\":\"string\"}],\"name\":\"selectList\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"},{\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"comName\",\"type\":\"string\"},{\"name\":\"mergeField\",\"type\":\"string\"}],\"name\":\"selectOne\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"ret\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"comName\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"mergeField\",\"type\":\"string\"}],\"name\":\"RegisterEvent\",\"type\":\"event\"}]"); + creditContract.setBinStr("60806040523480156200001157600080fd5b506200002b62000031640100000000026401000000009004565b62000224565b600061100190508073ffffffffffffffffffffffffffffffffffffffff166356004b6a6040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016200008d90620001ce565b602060405180830381600087803b158015620000a857600080fd5b505af1158015620000bd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620000e39190810190620000fd565b5050565b6000620000f582516200021a565b905092915050565b6000602082840312156200011057600080fd5b60006200012084828501620000e7565b91505092915050565b6000601182527f6d657267654669656c642c7374617475730000000000000000000000000000006020830152604082019050919050565b6000601982527f745f6372656469745f636f6d70616e795f7265706f72745f31000000000000006020830152604082019050919050565b6000600782527f636f6d4e616d65000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006060820190508181036000830152620001e98162000160565b90508181036020830152620001fe8162000197565b90508181036040830152620002138162000129565b9050919050565b6000819050919050565b6116f780620002346000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633ffbd47f1461005c5780636d50e48214610099578063edf90a89146100d7575b600080fd5b34801561006857600080fd5b50610083600480360361007e91908101906110e3565b610114565b6040516100909190611369565b60405180910390f35b3480156100a557600080fd5b506100c060048036036100bb9190810190611061565b6104c9565b6040516100ce929190611384565b60405180910390f35b3480156100e357600080fd5b506100fe60048036036100f991908101906110e3565b610a8c565b60405161010b9190611369565b60405180910390f35b600080600080600080600094506000935061012f8888610a8c565b935060008414151561045c57610143610dcb565b92508273ffffffffffffffffffffffffffffffffffffffff166313db93466040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156101a957600080fd5b505af11580156101bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506101e19190810190610fe6565b91508173ffffffffffffffffffffffffffffffffffffffff1663e942b516896040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016102389190611479565b600060405180830381600087803b15801561025257600080fd5b505af1158015610266573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663e942b516886040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016102bf9190611501565b600060405180830381600087803b1580156102d957600080fd5b505af11580156102ed573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663e942b5166040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610344906114ae565b600060405180830381600087803b15801561035e57600080fd5b505af1158015610372573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff166331afac3689846040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016103cd929190611429565b602060405180830381600087803b1580156103e757600080fd5b505af11580156103fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061041f9190810190611038565b905060018114156104335760009450610457565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe94505b610480565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b7fe71002dee81d9ff68a8184c07ed89508062d232ea9979314fd048b99aca6f25e8589896040516104b3939291906113b4565b60405180910390a1849550505050505092915050565b60006060600080600060606000806104df610dcb565b95508573ffffffffffffffffffffffffffffffffffffffff16637857d7c96040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561054557600080fd5b505af1158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061057d9190810190610f94565b94508473ffffffffffffffffffffffffffffffffffffffff1663cd30a1d16040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016105d2906114ae565b600060405180830381600087803b1580156105ec57600080fd5b505af1158015610600573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff1663e8434e398a876040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161065b9291906113f9565b602060405180830381600087803b15801561067557600080fd5b505af1158015610689573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106ad9190810190610fbd565b93508373ffffffffffffffffffffffffffffffffffffffff1663949d225d6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561071357600080fd5b505af1158015610727573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061074b9190810190611038565b60405190808252806020026020018201604052801561077e57816020015b60608152602001906001900390816107695790505b5092508373ffffffffffffffffffffffffffffffffffffffff1663949d225d6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156107e557600080fd5b505af11580156107f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061081d9190810190611038565b60001415610853577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381915097509750610a81565b600091505b8373ffffffffffffffffffffffffffffffffffffffff1663949d225d6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156108bc57600080fd5b505af11580156108d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108f49190810190611038565b821215610a76578373ffffffffffffffffffffffffffffffffffffffff1663846719e0836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016109509190611369565b602060405180830381600087803b15801561096a57600080fd5b505af115801561097e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109a29190810190610fe6565b90508073ffffffffffffffffffffffffffffffffffffffff16639c981fcb6040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016109f7906114e1565b600060405180830381600087803b158015610a1157600080fd5b505af1158015610a25573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250610a4e91908101906110a2565b8383815181101515610a5c57fe5b906020019060200201819052508180600101925050610858565b600083819150975097505b505050505050915091565b600080600080610a9a610dcb565b92508273ffffffffffffffffffffffffffffffffffffffff16637857d7c96040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015610b0057600080fd5b505af1158015610b14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b389190810190610f94565b91508173ffffffffffffffffffffffffffffffffffffffff1663cd30a1d1866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610b8f9190611501565b600060405180830381600087803b158015610ba957600080fd5b505af1158015610bbd573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663cd30a1d16040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610c14906114ae565b600060405180830381600087803b158015610c2e57600080fd5b505af1158015610c42573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff1663e8434e3987846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610c9d9291906113f9565b602060405180830381600087803b158015610cb757600080fd5b505af1158015610ccb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610cef9190810190610fbd565b90508073ffffffffffffffffffffffffffffffffffffffff1663949d225d6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015610d5557600080fd5b505af1158015610d69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d8d9190810190611038565b60001415610dbd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9350610dc2565b600093505b50505092915050565b600080600061100191508173ffffffffffffffffffffffffffffffffffffffff1663f23f63c96040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610e2890611459565b602060405180830381600087803b158015610e4257600080fd5b505af1158015610e56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e7a919081019061100f565b9050809250505090565b6000610e9082516115f4565b905092915050565b6000610ea48251611606565b905092915050565b6000610eb88251611618565b905092915050565b6000610ecc825161162a565b905092915050565b6000610ee0825161163c565b905092915050565b600082601f8301121515610efb57600080fd5b8135610f0e610f0982611563565b611536565b91508082526020830160208301858383011115610f2a57600080fd5b610f3583828461166a565b50505092915050565b600082601f8301121515610f5157600080fd5b8151610f64610f5f82611563565b611536565b91508082526020830160208301858383011115610f8057600080fd5b610f8b838284611679565b50505092915050565b600060208284031215610fa657600080fd5b6000610fb484828501610e84565b91505092915050565b600060208284031215610fcf57600080fd5b6000610fdd84828501610e98565b91505092915050565b600060208284031215610ff857600080fd5b600061100684828501610eac565b91505092915050565b60006020828403121561102157600080fd5b600061102f84828501610ec0565b91505092915050565b60006020828403121561104a57600080fd5b600061105884828501610ed4565b91505092915050565b60006020828403121561107357600080fd5b600082013567ffffffffffffffff81111561108d57600080fd5b61109984828501610ee8565b91505092915050565b6000602082840312156110b457600080fd5b600082015167ffffffffffffffff8111156110ce57600080fd5b6110da84828501610f3e565b91505092915050565b600080604083850312156110f657600080fd5b600083013567ffffffffffffffff81111561111057600080fd5b61111c85828601610ee8565b925050602083013567ffffffffffffffff81111561113957600080fd5b61114585828601610ee8565b9150509250929050565b600061115a8261159c565b808452602084019350836020820285016111738561158f565b60005b848110156111ac57838303885261118e838351611220565b9250611199826115bd565b9150602088019750600181019050611176565b508196508694505050505092915050565b6111c681611646565b82525050565b6111d581611658565b82525050565b6111e4816115ea565b82525050565b60006111f5826115b2565b808452611209816020860160208601611679565b611212816116ac565b602085010191505092915050565b600061122b826115a7565b80845261123f816020860160208601611679565b611248816116ac565b602085010191505092915050565b6000601982527f745f6372656469745f636f6d70616e795f7265706f72745f31000000000000006020830152604082019050919050565b6000600182527f31000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000600782527f636f6d4e616d65000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000600682527f73746174757300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000600a82527f6d657267654669656c64000000000000000000000000000000000000000000006020830152604082019050919050565b600060208201905061137e60008301846111db565b92915050565b600060408201905061139960008301856111db565b81810360208301526113ab818461114f565b90509392505050565b60006060820190506113c960008301866111db565b81810360208301526113db81856111ea565b905081810360408301526113ef81846111ea565b9050949350505050565b6000604082019050818103600083015261141381856111ea565b905061142260208301846111bd565b9392505050565b6000604082019050818103600083015261144381856111ea565b905061145260208301846111cc565b9392505050565b6000602082019050818103600083015261147281611256565b9050919050565b60006040820190508181036000830152611492816112c4565b905081810360208301526114a681846111ea565b905092915050565b600060408201905081810360008301526114c7816112fb565b905081810360208301526114da8161128d565b9050919050565b600060208201905081810360008301526114fa81611332565b9050919050565b6000604082019050818103600083015261151a81611332565b9050818103602083015261152e81846111ea565b905092915050565b6000604051905081810181811067ffffffffffffffff8211171561155957600080fd5b8060405250919050565b600067ffffffffffffffff82111561157a57600080fd5b601f19601f8301169050602081019050919050565b6000602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006115ff826115ca565b9050919050565b6000611611826115ca565b9050919050565b6000611623826115ca565b9050919050565b6000611635826115ca565b9050919050565b6000819050919050565b6000611651826115ca565b9050919050565b6000611663826115ca565b9050919050565b82818337600083830152505050565b60005b8381101561169757808201518184015260208101905061167c565b838111156116a6576000848401525b50505050565b6000601f19601f83011690509190505600a265627a7a723058207a7c4cd11c41ef79317b6d0e3563f05519a5f9157c55514b193d40d2257793226c6578706572696d656e74616cf50037"); + String bbbSource = new String(Base64.getDecoder().decode("cHJhZ21hIHNvbGlkaXR5ID49MC40LjIyIDwwLjcuMDsKcHJhZ21hIGV4cGVyaW1lbnRhbCBBQklFbmNvZGVyVjI7CmltcG9ydCAiLi9BZG1pbi5zb2wiOwppbXBvcnQgIi4vVXNlci5zb2wiOwoKY29udHJhY3QgTWFuYWdlbWVudENlbnRlciBpcyBBZG1pbiB7CgogICAgbWFwcGluZyhhZGRyZXNzID0+IGJvb2wpIHByaXZhdGUgdXNlcnM7CiAgICBtYXBwaW5nKGFkZHJlc3MgPT4gYWRkcmVzcykgcHJpdmF0ZSB1c2Vyc0NvbnRyYWN0OwogICAgYWRkcmVzc1tdIHByaXZhdGUgdXNlcmxpc3Q7CiAgICBtYXBwaW5nKGFkZHJlc3MgPT4gYm9vbCkgcHJpdmF0ZSBncmFudG9yczsKICAgIGFkZHJlc3NbXSBwcml2YXRlIGdyYW50b3JsaXN0OwoKICAgY29uc3RydWN0b3IoKSBwdWJsaWMgQWRtaW4obXNnLnNlbmRlcikKICAgIHsKICAgIH0KICAgICAgICAKICAgIGZ1bmN0aW9uIHJlZ2lzdGVyVXNlcihhZGRyZXNzIF91c2VyLCBzdHJpbmcgX2luZm8pIHB1YmxpYyBvbmx5QWRtaW4gcmV0dXJucyhhZGRyZXNzKSB7CiAgICAgICAgcmVxdWlyZSh1c2Vyc0NvbnRyYWN0W191c2VyXSA9PSBhZGRyZXNzKDApLCAidXNlciBhbHJlYWR5IGV4aXN0Iik7CiAgICAgICAgdXNlcnNbX3VzZXJdID0gdHJ1ZTsKICAgICAgICB1c2VybGlzdC5wdXNoKF91c2VyKTsKICAgICAgICB1c2Vyc0NvbnRyYWN0W191c2VyXSA9IG5ldyBVc2VyKF9pbmZvKTsKICAgICAgICByZXR1cm4gdXNlcnNDb250cmFjdFtfdXNlcl07CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIHVucmVnaXN0ZXJVc2VyKGFkZHJlc3MgX3VzZXIpIHB1YmxpYyBvbmx5QWRtaW4gewogICAgICAgIHJlcXVpcmUodXNlcnNDb250cmFjdFtfdXNlcl0gIT0gYWRkcmVzcygwKSwgInVzZXIgbm90IGV4aXN0Iik7CiAgICAgICAgdXNlcnNbX3VzZXJdID0gZmFsc2U7CiAgICB9ICAgIAogICAgCiAgICBmdW5jdGlvbiBpc1VzZXJFeGlzdChhZGRyZXNzIF91c2VyKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyAoYm9vbCl7CiAgICAgICAgcmV0dXJuIHVzZXJzW191c2VyXTsKICAgIH0KCiAgICBmdW5jdGlvbiByZWdpc3RlckdyYW50b3IoYWRkcmVzcyBfZ3JhbnRvcikgcHVibGljIG9ubHlBZG1pbiByZXR1cm5zKGJvb2wpIHsKICAgICAgICBncmFudG9yc1tfZ3JhbnRvcl0gPSB0cnVlOwogICAgICAgIHJldHVybiBncmFudG9yc1tfZ3JhbnRvcl07CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIHVucmVnaXN0ZXJHcmFudG9yKGFkZHJlc3MgX2dyYW50b3IpIHB1YmxpYyBvbmx5QWRtaW4gewogICAgICAgIGdyYW50b3JzW19ncmFudG9yXSA9IGZhbHNlOwogICAgfSAgICAKICAgIAogICAgZnVuY3Rpb24gaXNVc2VyR3JhbnRvcihhZGRyZXNzIF9ncmFudG9yKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyAoYm9vbCl7CiAgICAgICAgcmV0dXJuIGdyYW50b3JzW19ncmFudG9yXTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRVc2VyQ2VydGlmaWNhdGUoc3RyaW5nIF9jZXJ0aWZpY2F0ZUhhc2gsIHN0cmluZyBfY2VydGlmaWNhdGVzRGVzYywgYWRkcmVzcyBfZ3JhbnRvcikgcHVibGljIHJldHVybnMoYWRkcmVzcykgewogICAgICAgICAgICByZXF1aXJlKHVzZXJzQ29udHJhY3RbbXNnLnNlbmRlcl0gIT0gYWRkcmVzcygwKSwgInVzZXIgbm90IGV4aXN0Iik7CiAgICAgICAgICAgIHJlcXVpcmUodXNlcnNbbXNnLnNlbmRlcl0sICJ1bnJlZ2lzdGVyZWQgVXNlciIpOwogICAgICAgICAgICByZXR1cm4gVXNlcih1c2Vyc0NvbnRyYWN0W21zZy5zZW5kZXJdKS5hZGRDZXJ0aWZpY2F0ZShfY2VydGlmaWNhdGVIYXNoLCBfY2VydGlmaWNhdGVzRGVzYywgX2dyYW50b3IpOwogICAgfQoKICAgIGZ1bmN0aW9uIGdyYW50VXNlckNlcnRpZmljYXRlKGFkZHJlc3MgX3VzZXIsIHN0cmluZyBfY2VydGlmaWNhdGVIYXNoKSBwdWJsaWMgcmV0dXJucyhib29sKSB7CiAgICAgICAgICAgIHJlcXVpcmUoZ3JhbnRvcnNbbXNnLnNlbmRlcl0sICJ1bnJlZ2lzdGVyZWQgZ3JhbnRvciIpOwogICAgICAgICAgICByZXR1cm4gVXNlcih1c2Vyc0NvbnRyYWN0W191c2VyXSkuZ3JhbnRDZXJ0aWZpY2F0ZShfY2VydGlmaWNhdGVIYXNoLCBtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBWZXJpZnlVc2VyQ2VydGlmaWNhdGUoIGFkZHJlc3MgX3VzZXIsIHN0cmluZyBfY2VydGlmaWNhdGVIYXNoKSBwdWJsaWMgcmV0dXJucyhib29sKSB7CiAgICAgICAgICAgIHJlcXVpcmUodXNlcnNDb250cmFjdFtfdXNlcl0gIT0gYWRkcmVzcygwKSwgImNlcnRpZmljYXRlIGRvZXMgbm90IGV4aXN0Iik7CiAgICAgICAgICAgIHJlcXVpcmUodXNlcnNbX3VzZXJdLCAidW5yZWdpc3RlcmVkIFVzZXIiKTsKICAgICAgICAgICAgcmV0dXJuIFVzZXIodXNlcnNDb250cmFjdFtfdXNlcl0pLnZlcmlmeUNlcnRpZmljYXRlKF9jZXJ0aWZpY2F0ZUhhc2gpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRVc2VySW5mbyhhZGRyZXNzIF91c2VyKSAgcHVibGljIGNvbnN0YW50IHJldHVybnMgKHN0cmluZywgc3RyaW5nW10sIHN0cmluZ1tdLCBhZGRyZXNzW10sIGJvb2xbXSkgewogICAgICAgIHJlcXVpcmUodXNlcnNDb250cmFjdFtfdXNlcl0gIT0gYWRkcmVzcygwKSwgImNlcnRpZmljYXRlIGRvZXMgbm90IGV4aXN0Iik7CiAgICAgICAgcmVxdWlyZSh1c2Vyc1tfdXNlcl0sICJ1bnJlZ2lzdGVyZWQgVXNlciIpOwogICAgICAgIHJldHVybiAgIFVzZXIodXNlcnNDb250cmFjdFtfdXNlcl0pLmdldENlcnRpZmljYXRlKCk7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0VXNlckxpc3QoKSAgcHVibGljIGNvbnN0YW50IHJldHVybnMgKGFkZHJlc3NbXSkgewogICAgICAgIHJldHVybiAgdXNlcmxpc3Q7CiAgICB9Cn0K")); + creditContract.setSolRawString(bbbSource); + creditContract.setContractAddress("0x646e909af2caae3bdfa78b069e0c3b52f569fd71"); + + ObjectMapper mapper = new ObjectMapper(); + Map sdkMap = mapper.readValue(sdkMapStr, Map.class); + + ProjectFactory projectFactory = new ProjectFactory(); + // ProjectArtifact result = projectFactory.buildProjectDir(Collections.singletonList(contractInfo), + ProjectArtifact result = projectFactory.buildProjectDir(Arrays.asList(contractInfo, creditContract), + group, artifactName, outputDir, + //null, null, null, null); + "127.0.0.1:25200", 2, "0x123", sdkMap); + System.out.println("result: "); + System.out.println(result); + + } + + /** + * 项目中添加sdk证书:./output/webaseDemo/src/resources/conf + * 修改.properties:./output/webaseDemo/src/resources/application.properties + * system.peers=127.0.0.1:20200,127.0.0.1:20201 + * system.groupId=1 + * system.hexPrivateKey= + * system.contract.helloWorldAddress= + * 载入合约地址可能有多个 + */ + @Test + public void testCopySdk() throws IOException { + File srcConf = new File("./src/main/resources/conf"); + File targetConf = new File(confDir); + IOUtil.copyFolder(srcConf, targetConf); + } + +} diff --git a/src/test/java/node/mgr/test/scaffold/ScaffoldControllerTest.java b/src/test/java/node/mgr/test/scaffold/ScaffoldControllerTest.java new file mode 100644 index 000000000..4795f0aa3 --- /dev/null +++ b/src/test/java/node/mgr/test/scaffold/ScaffoldControllerTest.java @@ -0,0 +1,64 @@ +/** + * Copyright 2014-2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package node.mgr.test.scaffold; + +import com.webank.webase.node.mgr.base.tools.JsonTools; +import com.webank.webase.node.mgr.node.NodeService; +import com.webank.webase.node.mgr.scaffold.entity.ReqProject; +import java.util.Collections; +import node.mgr.test.base.TestBase; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +public class ScaffoldControllerTest extends TestBase { + + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext webApplicationContext; + + @Before + public void setUp() throws Exception { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); + } + + @Test + public void testExportProject() throws Exception { + ReqProject param = new ReqProject(); + param.setArtifactName("demo"); + param.setGroup("org.webank"); + param.setContractIdList(Collections.singletonList(1)); + param.setFrontId(1); + param.setGroupId(1); + ResultActions resultActions = mockMvc.perform( + MockMvcRequestBuilders.post( "/scaffold/export"). + content(JsonTools.toJSONString(param)). + contentType(MediaType.APPLICATION_JSON_UTF8) + ); + resultActions. +// andExpect(MockMvcResultMatchers.status().isOk()). + andDo(MockMvcResultHandlers.print()); + System.out.println("response:"+resultActions.andReturn().getResponse().getContentAsString()); + } +} diff --git a/src/test/java/node/mgr/test/scaffold/ScaffoldServiceTest.java b/src/test/java/node/mgr/test/scaffold/ScaffoldServiceTest.java new file mode 100644 index 000000000..e8ca1baf7 --- /dev/null +++ b/src/test/java/node/mgr/test/scaffold/ScaffoldServiceTest.java @@ -0,0 +1,56 @@ +/** + * Copyright 2014-2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package node.mgr.test.scaffold; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.webank.webase.node.mgr.contract.entity.TbContract; +import com.webank.webase.node.mgr.front.entity.FrontNodeConfig; +import com.webank.webase.node.mgr.front.entity.TbFront; +import com.webank.webase.node.mgr.scaffold.ScaffoldService; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javafx.animation.ScaleTransition; +import node.mgr.test.base.TestBase; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +public class ScaffoldServiceTest extends TestBase { + + @Autowired + private ScaffoldService scaffoldService; + + @Test + public void testGenerate() throws JsonProcessingException { + FrontNodeConfig nodeConfig = new FrontNodeConfig(); + nodeConfig.setP2pip("127.0.0.1"); + nodeConfig.setChannelPort(25210); + ObjectMapper mapper = new ObjectMapper(); + Map sdkMap = mapper.readValue(ScaffoldBuildTest.sdkMapStr, Map.class); + String groupName = "org.webank"; + String artifact = "demo"; + TbContract contract = new TbContract(); + contract.setContractAddress(ScaffoldBuildTest.contractAddress); + contract.setContractSource(ScaffoldBuildTest.helloWorldSolBase64Str); + contract.setContractAbi(ScaffoldBuildTest.abiStr); + contract.setBytecodeBin(ScaffoldBuildTest.binStr); + contract.setContractName(ScaffoldBuildTest.contractName); + List tbContractList = Collections.singletonList(contract); + + scaffoldService.generateProject(nodeConfig, groupName, artifact, + tbContractList, 1, "", sdkMap); + } +} From e5fb2abfffd9aa9602b18ec500cc2d21865e70b5 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 23 Apr 2021 14:57:02 +0800 Subject: [PATCH 08/92] add util & update node config api --- .../node/mgr/base/code/ConstantCode.java | 5 +++ .../node/mgr/base/tools/NodeMgrTools.java | 32 +++++++++++++++++++ .../webase/node/mgr/cert/CertService.java | 7 +++- .../frontinterface/FrontInterfaceService.java | 12 +++++-- .../mgr/frontinterface/FrontRestTools.java | 4 +-- .../webase/node/mgr/user/UserService.java | 16 ++++++++++ 6 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java index d9fc087f0..8e93fe799 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java +++ b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java @@ -311,6 +311,11 @@ public class ConstantCode { public static final RetCode APPKEY_NOT_EXISTS = RetCode.mark(202525, "app key not exists"); public static final RetCode SIGNATURE_NOT_MATCH = RetCode.mark(202526, "signature not match"); + // add in v1.5.1 + public static final RetCode PROJECT_NAME_ALREADY_EXIST = RetCode.mark(202531, "directory of project's artifact name already exist"); + public static final RetCode GET_FRONT_SDK_MAP_FAIL = RetCode.mark(202532, "get sdk cert/key content map failed"); + + /* auth */ public static final RetCode USER_NOT_LOGGED_IN = RetCode.mark(302000, "user not logged in"); public static final RetCode ACCESS_DENIED = RetCode.mark(302001, "access denied"); diff --git a/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java b/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java index e4cffd15a..926b5023b 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java +++ b/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java @@ -19,6 +19,7 @@ import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.base.tools.pagetools.entity.MapHandle; import java.io.File; +import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -676,4 +677,35 @@ public static String writePrivateKeyP12(String p12Password, String rawPrivateKey return exportedKeyPath; } + /** + * 文件转Base64 + * + * @param filePath 文件路径 + * @return + */ + public static String fileToBase64(String filePath) { + if (filePath == null) { + return null; + } + FileInputStream inputFile = null; + try { + File file = new File(CleanPathUtil.cleanString(filePath)); + inputFile = new FileInputStream(file); + byte[] buffer = new byte[(int) file.length()]; + int size = inputFile.read(buffer); + log.debug("fileToBase64 inputFile size:{}", size); + return Base64.getEncoder().encodeToString(buffer); + } catch (IOException e) { + log.error("base64ToFile IOException:[{}]", e.toString()); + } finally { + if (inputFile != null) { + try { + inputFile.close(); + } catch (IOException e) { + log.error("closeable IOException:[{}]", e.toString()); + } + } + } + return null; + } } diff --git a/src/main/java/com/webank/webase/node/mgr/cert/CertService.java b/src/main/java/com/webank/webase/node/mgr/cert/CertService.java index 1fa586bfe..ad48bd49d 100644 --- a/src/main/java/com/webank/webase/node/mgr/cert/CertService.java +++ b/src/main/java/com/webank/webase/node/mgr/cert/CertService.java @@ -465,7 +465,12 @@ public Map getFrontSdkContent(int frontId) { if (front == null) { throw new NodeMgrException(ConstantCode.INVALID_FRONT_ID); } - return frontInterfaceService.getSdkFilesFromSpecificFront(front.getFrontIp(), front.getFrontPort()); + Map sdkMap = frontInterfaceService.getSdkFilesFromSpecificFront(front.getFrontIp(), front.getFrontPort()); + if (sdkMap == null || sdkMap.isEmpty()) { + log.error("getFrontSdkContent failed frontId:{}", frontId); + throw new NodeMgrException(ConstantCode.GET_FRONT_SDK_MAP_FAIL); + } + return sdkMap; } diff --git a/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontInterfaceService.java b/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontInterfaceService.java index 86b8bb65a..6490ef369 100644 --- a/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontInterfaceService.java +++ b/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontInterfaceService.java @@ -49,6 +49,7 @@ import org.fisco.bcos.sdk.client.protocol.response.BcosBlock.TransactionResult; import org.fisco.bcos.sdk.client.protocol.response.BcosBlockHeader; import org.fisco.bcos.sdk.client.protocol.response.ConsensusStatus.ConsensusInfo; +import org.fisco.bcos.sdk.client.protocol.response.NodeInfo; import org.fisco.bcos.sdk.client.protocol.response.SyncStatus.SyncStatusInfo; import org.fisco.bcos.sdk.model.NodeVersion.ClientVersion; import org.fisco.bcos.sdk.model.TransactionReceipt; @@ -516,8 +517,15 @@ public String getSignVersionFromSpecificFront(String frontIp, Integer frontPort) */ public FrontNodeConfig getNodeConfigFromSpecificFront(String frontIp, Integer frontPort) { Integer groupId = Integer.MAX_VALUE; - FrontNodeConfig nodeInfo = getFromSpecificFront(groupId, frontIp, frontPort, - FrontRestTools.URI_NODECONFIG, FrontNodeConfig.class); + FrontNodeConfig nodeConfig = getFromSpecificFront(groupId, frontIp, frontPort, + FrontRestTools.URI_NODE_CONFIG, FrontNodeConfig.class); + return nodeConfig; + } + + public NodeInfo getNodeInfoFromSpecificFront(String frontIp, Integer frontPort) { + Integer groupId = Integer.MAX_VALUE; + NodeInfo nodeInfo = getFromSpecificFront(groupId, frontIp, frontPort, + FrontRestTools.URI_NODE_INFO, NodeInfo.class); return nodeInfo; } diff --git a/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontRestTools.java b/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontRestTools.java index 4cda0a31b..7a00dc816 100644 --- a/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontRestTools.java +++ b/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontRestTools.java @@ -88,8 +88,8 @@ public class FrontRestTools { public static final String URI_BLOCK_HEADER_BY_NUMBER = "web3/blockHeaderByNumber/%1d"; public static final String URI_BLOCK_HEADER_BY_HASH = "web3/blockHeaderByHash/%1s"; public static final String URI_SEARCH_BLOCK_OR_TX = "web3/search"; - public static final String URI_NODECONFIG = "web3/nodeConfig"; - public static final String URI_NODEINFO = "web3/nodeInfo"; + public static final String URI_NODE_CONFIG = "web3/nodeConfig"; + public static final String URI_NODE_INFO = "web3/nodeInfo"; public static final String FRONT_PERFORMANCE_RATIO = "performance"; public static final String FRONT_PERFORMANCE_CONFIG = "performance/config"; public static final String URI_KEY_PAIR = "privateKey"; diff --git a/src/main/java/com/webank/webase/node/mgr/user/UserService.java b/src/main/java/com/webank/webase/node/mgr/user/UserService.java index 2f2e35ff2..a36b2d039 100644 --- a/src/main/java/com/webank/webase/node/mgr/user/UserService.java +++ b/src/main/java/com/webank/webase/node/mgr/user/UserService.java @@ -318,6 +318,22 @@ public TbUser queryUserDetail(Integer userId) throws NodeMgrException { return user; } + public String queryUserDetail(int groupId, String userAddress) throws NodeMgrException { + // query sign user id + String signUserId = getSignUserIdByAddress(groupId, userAddress); + // get key from sign + KeyPair keyPair = this.getUserKeyPairFromSign(groupId, signUserId); + // decode key + String privateKeyRaw = new String(Base64.getDecoder().decode(keyPair.getPrivateKey())); + return privateKeyRaw; + } + + /** + * return key pair with private key encoded in base64 + * @param groupId + * @param signUserId + * @return the private key of KeyPair is encoded in base64 + */ private KeyPair getUserKeyPairFromSign(int groupId, String signUserId) { Map param = new HashMap<>(); param.put("signUserId", signUserId); From 2cdc4e55a37f2c12ae282d7b711dd74c74a4211c Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 23 Apr 2021 14:57:18 +0800 Subject: [PATCH 09/92] ignore output --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 62f34feb2..0c5ac9f2d 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ *.srl gmcert.cnf gmsm2.param +/output/ From 10d3334cd764e76a17a64e448d7ee621b8cab083 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 23 Apr 2021 14:57:35 +0800 Subject: [PATCH 10/92] update api test --- .../java/node/mgr/test/front/FrontControllerTest.java | 3 ++- .../java/node/mgr/test/node/NodeControllerTest.java | 11 +---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/test/java/node/mgr/test/front/FrontControllerTest.java b/src/test/java/node/mgr/test/front/FrontControllerTest.java index 7f5a0be6c..36cb37865 100644 --- a/src/test/java/node/mgr/test/front/FrontControllerTest.java +++ b/src/test/java/node/mgr/test/front/FrontControllerTest.java @@ -49,7 +49,8 @@ public void testNewFront() throws Exception { param.setFrontPort(8081); param.setAgency("1fe"); - ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders.post( "/front/new"). + ResultActions resultActions = mockMvc.perform( + MockMvcRequestBuilders.post( "/front/new"). content(JsonTools.toJSONString(param)). contentType(MediaType.APPLICATION_JSON_UTF8) ); diff --git a/src/test/java/node/mgr/test/node/NodeControllerTest.java b/src/test/java/node/mgr/test/node/NodeControllerTest.java index 0296f8cf6..de5ca34d7 100644 --- a/src/test/java/node/mgr/test/node/NodeControllerTest.java +++ b/src/test/java/node/mgr/test/node/NodeControllerTest.java @@ -15,7 +15,6 @@ */ package node.mgr.test.node; -import com.webank.webase.node.mgr.node.NodeService; import node.mgr.test.base.TestBase; import org.junit.Before; import org.junit.Test; @@ -33,8 +32,7 @@ public class NodeControllerTest extends TestBase { @Autowired private WebApplicationContext webApplicationContext; - @Autowired - private NodeService nodeService; + @Before public void setUp() throws Exception { @@ -48,13 +46,6 @@ public void testNewFront() throws Exception { andDo(MockMvcResultHandlers.print()); System.out.println("======================response:"+resultActions.andReturn().getResponse().getContentAsString()); } -// -// @Test -// public void testQueryNodeId() { -// TbNode tbNode = nodeService.queryByNodeId("e5e7efc9e8d5bed699313d5a0cd5b024b3c11811d50473b987b9429c2f6379742c88249a7a8ea64ab0e6f2b69fb8bb280454f28471e38621bea8f38be45bc42d"); -// System.out.println(tbNode); -// Assert.assertNull(tbNode); -// } @Test public void testGetNodeIdList() throws Exception { From 5c4aff2c46bc8c0440f6e2c6f3209a64138bf128 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Sun, 25 Apr 2021 15:52:58 +0800 Subject: [PATCH 11/92] update gradle wrapper --- .../node/mgr/base/code/ConstantCode.java | 1 + .../node/mgr/scaffold/ScaffoldService.java | 20 ++++++++++++------- .../mgr/test/scaffold/ScaffoldBuildTest.java | 11 +++++----- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java index 8e93fe799..f99510601 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java +++ b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java @@ -314,6 +314,7 @@ public class ConstantCode { // add in v1.5.1 public static final RetCode PROJECT_NAME_ALREADY_EXIST = RetCode.mark(202531, "directory of project's artifact name already exist"); public static final RetCode GET_FRONT_SDK_MAP_FAIL = RetCode.mark(202532, "get sdk cert/key content map failed"); + public static final RetCode GENERATE_CONTRACT_PROJECT_FAIL = RetCode.mark(202533, "generate project of contract failed"); /* auth */ diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java index 1f01c0c41..cb335c2c6 100644 --- a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java @@ -14,7 +14,6 @@ package com.webank.webase.node.mgr.scaffold; -import com.webank.scaffold.artifact.ProjectArtifact; import com.webank.scaffold.artifact.webase.NewMainResourceDir.ContractInfo; import com.webank.scaffold.factory.ProjectFactory; import com.webank.webase.node.mgr.base.code.ConstantCode; @@ -32,9 +31,6 @@ import com.webank.webase.node.mgr.scaffold.entity.RspFile; import com.webank.webase.node.mgr.user.UserService; import java.io.File; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Base64; import java.util.List; @@ -67,6 +63,9 @@ public class ScaffoldService { @Autowired private FrontInterfaceService frontInterfaceService; + // gradle not in package, skip + private static final String GRADLE_WRAPPER_DIR = ""; + private static final String OUTPUT_DIR = "output"; private static final String ZIP_SUFFIX = ".zip"; private static final String OUTPUT_ZIP_DIR = OUTPUT_DIR + File.separator + "zip"; @@ -151,15 +150,21 @@ public String generateProject(FrontNodeConfig nodeConfig, String projectGroup, S ProjectFactory projectFactory = new ProjectFactory(); log.info("generateProject projectGroup:{},artifactName:{},OUTPUT_DIR:{},frontChannelIpPort:{},groupId:{}", projectGroup, artifactName, OUTPUT_DIR, frontChannelIpPort, groupId); - ProjectArtifact result = projectFactory.buildProjectDir(contractInfoList, - projectGroup, artifactName, OUTPUT_DIR, - frontChannelIpPort, groupId, hexPrivateKey, sdkMap); + try { + projectFactory.buildProjectDir(contractInfoList, + projectGroup, artifactName, OUTPUT_DIR, GRADLE_WRAPPER_DIR, + frontChannelIpPort, groupId, hexPrivateKey, sdkMap); + } catch (Exception e) { + log.error("generateProject error:[]", e); + throw new NodeMgrException(ConstantCode.GENERATE_CONTRACT_PROJECT_FAIL.attach(e.getMessage())); + } String projectDir = OUTPUT_DIR + File.separator + artifactName; log.info("generateProject result:{}", projectDir); return projectDir; } private List handleContractList(List contractList) { + log.info("handleContractList contractList:{}", contractList); List contractInfoList = new ArrayList<>(); log.info("handleContractList param contractList size:{}", contractList.size()); for (TbContract contract : contractList) { @@ -183,6 +188,7 @@ private List handleContractList(List contractList) { contractInfoList.add(contractInfo); } log.info("handleContractList result contractInfoList size:{}", contractInfoList.size()); + log.info("handleContractList contractList:{}", contractInfoList); return contractInfoList; } } diff --git a/src/test/java/node/mgr/test/scaffold/ScaffoldBuildTest.java b/src/test/java/node/mgr/test/scaffold/ScaffoldBuildTest.java index c93b9846b..eed5d2145 100644 --- a/src/test/java/node/mgr/test/scaffold/ScaffoldBuildTest.java +++ b/src/test/java/node/mgr/test/scaffold/ScaffoldBuildTest.java @@ -93,7 +93,7 @@ public void testFactory() { * 根据入参生成项目 */ @Test - public void testBuildByParam() throws JsonProcessingException { + public void testBuildByParam() throws Exception { String solSourceCode = new String(Base64.getDecoder().decode(helloWorldSolBase64Str)); ContractInfo contractInfo = new ContractInfo(); @@ -111,8 +111,9 @@ public void testBuildByParam() throws JsonProcessingException { System.out.println(sdkMap); ProjectFactory projectFactory = new ProjectFactory(); - ProjectArtifact result = projectFactory.buildProjectDir(Collections.singletonList(contractInfo), - group, artifactName, outputDir, + ProjectArtifact result = projectFactory.buildProjectDir( + Collections.singletonList(contractInfo), + group, artifactName, outputDir, "gradle", //null, null, null, null); "127.0.0.1:25200", 2, "0x123", sdkMap); } @@ -121,7 +122,7 @@ public void testBuildByParam() throws JsonProcessingException { * build with multi sol contract */ @Test - public void testBuildMultiSol() throws JsonProcessingException { + public void testBuildMultiSol() throws Exception { String solSourceCode = new String(Base64.getDecoder().decode(helloWorldSolBase64Str)); ContractInfo contractInfo = new ContractInfo(); @@ -145,7 +146,7 @@ public void testBuildMultiSol() throws JsonProcessingException { ProjectFactory projectFactory = new ProjectFactory(); // ProjectArtifact result = projectFactory.buildProjectDir(Collections.singletonList(contractInfo), ProjectArtifact result = projectFactory.buildProjectDir(Arrays.asList(contractInfo, creditContract), - group, artifactName, outputDir, + group, artifactName, outputDir, "gradle", //null, null, null, null); "127.0.0.1:25200", 2, "0x123", sdkMap); System.out.println("result: "); From fd56ce078a46075f119c2fd8a4193c1fcf8e7db7 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Sun, 25 Apr 2021 15:56:54 +0800 Subject: [PATCH 12/92] update ignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 0c5ac9f2d..c9310f4e9 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ gmcert.cnf gmsm2.param /output/ +generatorConfig.xml +mbg.properties +GenerateToolTest.java From b5430b30b1ba953d4259e1286d179876f0fa8e88 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Sun, 25 Apr 2021 17:58:30 +0800 Subject: [PATCH 13/92] add base warehouse code & ut --- .../warehouse/WareHouseController.java | 113 ++++++++ .../contract/warehouse/WareHouseService.java | 89 +++++++ .../warehouse/entity/TbContractFolder.java | 103 +++++++ .../warehouse/entity/TbContractItem.java | 103 +++++++ .../warehouse/entity/TbWareHouse.java | 121 +++++++++ .../mapper/TbContractFolderMapper.java | 105 ++++++++ .../mapper/TbContractFolderSqlProvider.java | 106 ++++++++ .../mapper/TbContractItemMapper.java | 102 +++++++ .../mapper/TbContractItemSqlProvider.java | 106 ++++++++ .../warehouse/mapper/TbWareHouseMapper.java | 106 ++++++++ .../mapper/TbWareHouseSqlProvider.java | 122 +++++++++ .../contract/warehouse/WareHouseMdTest.java | 252 ++++++++++++++++++ 12 files changed, 1428 insertions(+) create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseController.java create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseService.java create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractFolder.java create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractItem.java create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbWareHouse.java create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderSqlProvider.java create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemSqlProvider.java create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseMapper.java create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseSqlProvider.java create mode 100644 src/test/java/node/mgr/test/contract/warehouse/WareHouseMdTest.java diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseController.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseController.java new file mode 100644 index 000000000..f1279775d --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseController.java @@ -0,0 +1,113 @@ +/** + * Copyright 2014-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.webank.webase.node.mgr.contract.warehouse; + +import com.webank.webase.node.mgr.base.code.ConstantCode; +import com.webank.webase.node.mgr.base.controller.BaseController; +import com.webank.webase.node.mgr.base.entity.BaseResponse; +import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractFolder; +import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractItem; +import com.webank.webase.node.mgr.contract.warehouse.entity.TbWareHouse; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +/** + * ContractStoreController. + */ +@Slf4j +@RestController +@RequestMapping(value = "/contractStore") +public class WareHouseController extends BaseController { + + @Autowired + WareHouseService wareHouseService; + + /** + * query the list of contract store item + */ + @GetMapping(value = "/getContractStoreList") + public BaseResponse getContractStoreList() { + + List storeItemList = wareHouseService.getStoreList(); + BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); + response.setData(storeItemList); + return response; + } + + /** + * query a contract store item + */ + @GetMapping(value = "/getContractStoreById/{storeId}") + public BaseResponse getContractStoreById(@PathVariable("storeId") Integer storeId) { + log.info("getContractStoreById start. storeId:{}", storeId); + TbWareHouse storeItem = wareHouseService.getStoreItemById(storeId); + BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); + response.setData(storeItem); + return response; + } + + /** + * query a contract folder item + */ + @GetMapping(value = "/getContractFolderById/{contractFolderId}") + public BaseResponse getContractFolderById(@PathVariable("contractFolderId") Integer contractFolderId) { + log.info("getContractStoreById start. contractFolderId:{}", contractFolderId); + TbContractFolder contractFolderItem = wareHouseService.getContractFolderById(contractFolderId); + BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); + response.setData(contractFolderItem); + return response; + } + + /** + * query a contract item + */ + @GetMapping(value = "/getContractItemById/{contractId}") + public BaseResponse getContractItemById(@PathVariable("contractId") Integer contractId) { + log.info("getContractStoreById start. contractId:{}", contractId); + TbContractItem contractItem = wareHouseService.getContractItemById(contractId); + BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); + response.setData(contractItem); + return response; + } + + /** + * get folderItemList by storeId + */ + @GetMapping(value = "/getFolderItemListByStoreId/{storeId}") + public BaseResponse getFolderItemListByStoreId(@PathVariable("storeId") Integer storeId) { + log.info("getFolderItemListByStoreId start. storeId:{}", storeId); + List contractFolderItemList = wareHouseService.getFolderItemListByStoreId(storeId); + BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); + response.setData(contractFolderItemList); + return response; + } + + /** + * get contractItemList by folderId + */ + @GetMapping(value = "/getContractItemByFolderId/{folderId}") + public BaseResponse getContractItemByFolderId(@PathVariable("folderId") Integer folderId) { + log.info("getContractItemByFolderId start. storeId:{}", folderId); + List contractItemList = wareHouseService.getContractItemByFolderId(folderId); + BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); + response.setData(contractItemList); + return response; + } +} diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseService.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseService.java new file mode 100644 index 000000000..04903c5cc --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseService.java @@ -0,0 +1,89 @@ +/* + * Copyright 2014-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.webank.webase.node.mgr.contract.warehouse; + +import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractFolder; +import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractItem; +import com.webank.webase.node.mgr.contract.warehouse.entity.TbWareHouse; +import com.webank.webase.node.mgr.contract.warehouse.mapper.TbContractFolderMapper; +import com.webank.webase.node.mgr.contract.warehouse.mapper.TbContractItemMapper; +import com.webank.webase.node.mgr.contract.warehouse.mapper.TbWareHouseMapper; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * @author marsli + */ +@Slf4j +@Service +public class WareHouseService { + @Autowired + private TbContractItemMapper contractItemMapper; + @Autowired + private TbContractFolderMapper contractFolderMapper; + @Autowired + private TbWareHouseMapper wareHouseMapper; + + /** + * + */ + public List getStoreList() { + List storeItemList = wareHouseMapper.findAll(); + return storeItemList; + } + + /** + * + */ + public TbWareHouse getStoreItemById(Integer wareHouseId) { + TbWareHouse storeItem = wareHouseMapper.selectByPrimaryKey(wareHouseId); + return storeItem; + } + + /** + * + */ + public TbContractItem getContractItemById(Integer contractId) { + TbContractItem contractItem = contractItemMapper.selectByPrimaryKey(contractId); + return contractItem; + } + + /** + * + */ + public List getContractItemByFolderId(Integer contractFolderId) { + List contractItemList = contractItemMapper.listByFolderId(contractFolderId); + return contractItemList; + } + + /** + * + */ + public TbContractFolder getContractFolderById(Integer contractFolderId) { + TbContractFolder contractFolderItem = contractFolderMapper.selectByPrimaryKey(contractFolderId); + return contractFolderItem; + } + + /** + * + */ + public List getFolderItemListByStoreId(Integer wareHouseId) { + List contractFolderItemList = contractFolderMapper.findByWareHouseId(wareHouseId); + return contractFolderItemList; + } + +} diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractFolder.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractFolder.java new file mode 100644 index 000000000..061baea35 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractFolder.java @@ -0,0 +1,103 @@ +package com.webank.webase.node.mgr.contract.warehouse.entity; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@ToString +@NoArgsConstructor +@EqualsAndHashCode +public class TbContractFolder implements Serializable { + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_folder.id + * + * @mbg.generated + */ + private Integer id; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_folder.folder_name + * + * @mbg.generated + */ + private String folderName; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_folder.create_time + * + * @mbg.generated + */ + private Date createTime; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_folder.modify_time + * + * @mbg.generated + */ + private Date modifyTime; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_folder.ware_house_id + * + * @mbg.generated + */ + private Integer wareHouseId; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_folder.description + * + * @mbg.generated + */ + private String description; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_folder.description_en + * + * @mbg.generated + */ + private String descriptionEn; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_folder.folder_detail + * + * @mbg.generated + */ + private String folderDetail; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_folder.folder_detail_en + * + * @mbg.generated + */ + private String folderDetailEn; + + /** + * This field was generated by MyBatis Generator. + * This field corresponds to the database table tb_contract_folder + * + * @mbg.generated + */ + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractItem.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractItem.java new file mode 100644 index 000000000..161dd672b --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractItem.java @@ -0,0 +1,103 @@ +package com.webank.webase.node.mgr.contract.warehouse.entity; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@ToString +@NoArgsConstructor +@EqualsAndHashCode +public class TbContractItem implements Serializable { + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_item.id + * + * @mbg.generated + */ + private Integer id; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_item.contract_name + * + * @mbg.generated + */ + private String contractName; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_item.create_time + * + * @mbg.generated + */ + private Date createTime; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_item.modify_time + * + * @mbg.generated + */ + private Date modifyTime; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_item.ware_house_id + * + * @mbg.generated + */ + private Integer wareHouseId; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_item.contract_folder_id + * + * @mbg.generated + */ + private Integer contractFolderId; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_item.contract_source + * + * @mbg.generated + */ + private String contractSource; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_item.description + * + * @mbg.generated + */ + private String description; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_contract_item.description_en + * + * @mbg.generated + */ + private String descriptionEn; + + /** + * This field was generated by MyBatis Generator. + * This field corresponds to the database table tb_contract_item + * + * @mbg.generated + */ + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbWareHouse.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbWareHouse.java new file mode 100644 index 000000000..b72aa643c --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbWareHouse.java @@ -0,0 +1,121 @@ +package com.webank.webase.node.mgr.contract.warehouse.entity; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@ToString +@NoArgsConstructor +@EqualsAndHashCode +public class TbWareHouse implements Serializable { + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_ware_house.id + * + * @mbg.generated + */ + private Integer id; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_ware_house.ware_house_name + * + * @mbg.generated + */ + private String wareHouseName; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_ware_house.ware_house_name_en + * + * @mbg.generated + */ + private String wareHouseNameEn; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_ware_house.type + * + * @mbg.generated + */ + private String type; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_ware_house.create_time + * + * @mbg.generated + */ + private Date createTime; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_ware_house.modify_time + * + * @mbg.generated + */ + private Date modifyTime; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_ware_house.ware_house_icon + * + * @mbg.generated + */ + private String wareHouseIcon; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_ware_house.description + * + * @mbg.generated + */ + private String description; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_ware_house.description_en + * + * @mbg.generated + */ + private String descriptionEn; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_ware_house.ware_house_detail + * + * @mbg.generated + */ + private String wareHouseDetail; + + /** + * + * This field was generated by MyBatis Generator. + * This field corresponds to the database column tb_ware_house.ware_house_detail_en + * + * @mbg.generated + */ + private String wareHouseDetailEn; + + /** + * This field was generated by MyBatis Generator. + * This field corresponds to the database table tb_ware_house + * + * @mbg.generated + */ + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java new file mode 100644 index 000000000..eb7d50aa7 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java @@ -0,0 +1,105 @@ +package com.webank.webase.node.mgr.contract.warehouse.mapper; + +import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractFolder; +import com.webank.webase.node.mgr.contract.warehouse.entity.TbWareHouse; +import java.util.List; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.InsertProvider; +import org.apache.ibatis.annotations.Options; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.SelectKey; +import org.apache.ibatis.annotations.UpdateProvider; +import org.apache.ibatis.type.JdbcType; + +/** + * @author marsli + */ +public interface TbContractFolderMapper { + + @Select({"select", TbWareHouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_contract_folder", + "where ware_house_id = #{wareHouseId}"}) + List findByWareHouseId(@Param("wareHouseId") Integer wareHouseId); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_folder + * + * @mbg.generated + */ + @Delete({ + "delete from tb_contract_folder", + "where id = #{id,jdbcType=INTEGER}" + }) + int deleteByPrimaryKey(Integer id); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_folder + * + * @mbg.generated + */ + @InsertProvider(type=TbContractFolderSqlProvider.class, method="insertSelective") + @SelectKey(statement="SELECT LAST_INSERT_ID()", keyProperty="id", before=false, resultType=Integer.class) + int insertSelective(TbContractFolder record); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_folder + * + * @mbg.generated + */ + @Select({ + "select", + "id, folder_name, create_time, modify_time, ware_house_id, description, description_en, ", + "folder_detail, folder_detail_en", + "from tb_contract_folder", + "where id = #{id,jdbcType=INTEGER}" + }) + @Results({ + @Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true), + @Result(column="folder_name", property="folderName", jdbcType=JdbcType.VARCHAR), + @Result(column="create_time", property="createTime", jdbcType=JdbcType.TIMESTAMP), + @Result(column="modify_time", property="modifyTime", jdbcType=JdbcType.TIMESTAMP), + @Result(column="ware_house_id", property="wareHouseId", jdbcType=JdbcType.INTEGER), + @Result(column="description", property="description", jdbcType=JdbcType.LONGVARCHAR), + @Result(column="description_en", property="descriptionEn", jdbcType=JdbcType.LONGVARCHAR), + @Result(column="folder_detail", property="folderDetail", jdbcType=JdbcType.LONGVARCHAR), + @Result(column="folder_detail_en", property="folderDetailEn", jdbcType=JdbcType.LONGVARCHAR) + }) + TbContractFolder selectByPrimaryKey(Integer id); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_folder + * + * @mbg.generated + */ + @UpdateProvider(type=TbContractFolderSqlProvider.class, method="updateByPrimaryKeySelective") + int updateByPrimaryKeySelective(TbContractFolder record); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_folder + * + * @mbg.generated + */ + @Options(useGeneratedKeys = true,keyProperty="id",keyColumn = "id") + @Insert({ + "", + }) + int batchInsert(java.util.List list); +} \ No newline at end of file diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderSqlProvider.java new file mode 100644 index 000000000..0a0afa86a --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderSqlProvider.java @@ -0,0 +1,106 @@ +package com.webank.webase.node.mgr.contract.warehouse.mapper; + +import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractFolder; +import org.apache.ibatis.jdbc.SQL; + +public class TbContractFolderSqlProvider { + /** + * This field was generated by MyBatis Generator. + * This field corresponds to the database table tb_contract_folder + * + * @mbg.generated + */ + public static final String ALL_COLUMN_FIELDS = "id,folder_name,create_time,modify_time,ware_house_id,description,description_en,folder_detail,folder_detail_en"; + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_folder + * + * @mbg.generated + */ + public String insertSelective(TbContractFolder record) { + SQL sql = new SQL(); + sql.INSERT_INTO("tb_contract_folder"); + + if (record.getFolderName() != null) { + sql.VALUES("folder_name", "#{folderName,jdbcType=VARCHAR}"); + } + + if (record.getCreateTime() != null) { + sql.VALUES("create_time", "#{createTime,jdbcType=TIMESTAMP}"); + } + + if (record.getModifyTime() != null) { + sql.VALUES("modify_time", "#{modifyTime,jdbcType=TIMESTAMP}"); + } + + if (record.getWareHouseId() != null) { + sql.VALUES("ware_house_id", "#{wareHouseId,jdbcType=INTEGER}"); + } + + if (record.getDescription() != null) { + sql.VALUES("description", "#{description,jdbcType=LONGVARCHAR}"); + } + + if (record.getDescriptionEn() != null) { + sql.VALUES("description_en", "#{descriptionEn,jdbcType=LONGVARCHAR}"); + } + + if (record.getFolderDetail() != null) { + sql.VALUES("folder_detail", "#{folderDetail,jdbcType=LONGVARCHAR}"); + } + + if (record.getFolderDetailEn() != null) { + sql.VALUES("folder_detail_en", "#{folderDetailEn,jdbcType=LONGVARCHAR}"); + } + + return sql.toString(); + } + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_folder + * + * @mbg.generated + */ + public String updateByPrimaryKeySelective(TbContractFolder record) { + SQL sql = new SQL(); + sql.UPDATE("tb_contract_folder"); + + if (record.getFolderName() != null) { + sql.SET("folder_name = #{folderName,jdbcType=VARCHAR}"); + } + + if (record.getCreateTime() != null) { + sql.SET("create_time = #{createTime,jdbcType=TIMESTAMP}"); + } + + if (record.getModifyTime() != null) { + sql.SET("modify_time = #{modifyTime,jdbcType=TIMESTAMP}"); + } + + if (record.getWareHouseId() != null) { + sql.SET("ware_house_id = #{wareHouseId,jdbcType=INTEGER}"); + } + + if (record.getDescription() != null) { + sql.SET("description = #{description,jdbcType=LONGVARCHAR}"); + } + + if (record.getDescriptionEn() != null) { + sql.SET("description_en = #{descriptionEn,jdbcType=LONGVARCHAR}"); + } + + if (record.getFolderDetail() != null) { + sql.SET("folder_detail = #{folderDetail,jdbcType=LONGVARCHAR}"); + } + + if (record.getFolderDetailEn() != null) { + sql.SET("folder_detail_en = #{folderDetailEn,jdbcType=LONGVARCHAR}"); + } + + sql.WHERE("id = #{id,jdbcType=INTEGER}"); + + return sql.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java new file mode 100644 index 000000000..4ec91dbc5 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java @@ -0,0 +1,102 @@ +package com.webank.webase.node.mgr.contract.warehouse.mapper; + +import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractItem; +import java.util.List; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.InsertProvider; +import org.apache.ibatis.annotations.Options; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.SelectKey; +import org.apache.ibatis.annotations.UpdateProvider; +import org.apache.ibatis.type.JdbcType; + +public interface TbContractItemMapper { + + + @Select({"select", TbWareHouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_contract_folder", + "where contract_folder_id = #{contractFolderId}"}) + List listByFolderId(@Param("contractFolderId") Integer contractFolderId); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_item + * + * @mbg.generated + */ + @Delete({ + "delete from tb_contract_item", + "where id = #{id,jdbcType=INTEGER}" + }) + int deleteByPrimaryKey(Integer id); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_item + * + * @mbg.generated + */ + @InsertProvider(type=TbContractItemSqlProvider.class, method="insertSelective") + @SelectKey(statement="SELECT LAST_INSERT_ID()", keyProperty="id", before=false, resultType=Integer.class) + int insertSelective(TbContractItem record); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_item + * + * @mbg.generated + */ + @Select({ + "select", + "id, contract_name, create_time, modify_time, ware_house_id, contract_folder_id, ", + "contract_source, description, description_en", + "from tb_contract_item", + "where id = #{id,jdbcType=INTEGER}" + }) + @Results({ + @Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true), + @Result(column="contract_name", property="contractName", jdbcType=JdbcType.VARCHAR), + @Result(column="create_time", property="createTime", jdbcType=JdbcType.TIMESTAMP), + @Result(column="modify_time", property="modifyTime", jdbcType=JdbcType.TIMESTAMP), + @Result(column="ware_house_id", property="wareHouseId", jdbcType=JdbcType.INTEGER), + @Result(column="contract_folder_id", property="contractFolderId", jdbcType=JdbcType.INTEGER), + @Result(column="contract_source", property="contractSource", jdbcType=JdbcType.LONGVARCHAR), + @Result(column="description", property="description", jdbcType=JdbcType.LONGVARCHAR), + @Result(column="description_en", property="descriptionEn", jdbcType=JdbcType.LONGVARCHAR) + }) + TbContractItem selectByPrimaryKey(Integer id); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_item + * + * @mbg.generated + */ + @UpdateProvider(type=TbContractItemSqlProvider.class, method="updateByPrimaryKeySelective") + int updateByPrimaryKeySelective(TbContractItem record); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_item + * + * @mbg.generated + */ + @Options(useGeneratedKeys = true,keyProperty="id",keyColumn = "id") + @Insert({ + "", + }) + int batchInsert(java.util.List list); +} \ No newline at end of file diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemSqlProvider.java new file mode 100644 index 000000000..d692e0dcf --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemSqlProvider.java @@ -0,0 +1,106 @@ +package com.webank.webase.node.mgr.contract.warehouse.mapper; + +import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractItem; +import org.apache.ibatis.jdbc.SQL; + +public class TbContractItemSqlProvider { + /** + * This field was generated by MyBatis Generator. + * This field corresponds to the database table tb_contract_item + * + * @mbg.generated + */ + public static final String ALL_COLUMN_FIELDS = "id,contract_name,create_time,modify_time,ware_house_id,contract_folder_id,contract_source,description,description_en"; + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_item + * + * @mbg.generated + */ + public String insertSelective(TbContractItem record) { + SQL sql = new SQL(); + sql.INSERT_INTO("tb_contract_item"); + + if (record.getContractName() != null) { + sql.VALUES("contract_name", "#{contractName,jdbcType=VARCHAR}"); + } + + if (record.getCreateTime() != null) { + sql.VALUES("create_time", "#{createTime,jdbcType=TIMESTAMP}"); + } + + if (record.getModifyTime() != null) { + sql.VALUES("modify_time", "#{modifyTime,jdbcType=TIMESTAMP}"); + } + + if (record.getWareHouseId() != null) { + sql.VALUES("ware_house_id", "#{wareHouseId,jdbcType=INTEGER}"); + } + + if (record.getContractFolderId() != null) { + sql.VALUES("contract_folder_id", "#{contractFolderId,jdbcType=INTEGER}"); + } + + if (record.getContractSource() != null) { + sql.VALUES("contract_source", "#{contractSource,jdbcType=LONGVARCHAR}"); + } + + if (record.getDescription() != null) { + sql.VALUES("description", "#{description,jdbcType=LONGVARCHAR}"); + } + + if (record.getDescriptionEn() != null) { + sql.VALUES("description_en", "#{descriptionEn,jdbcType=LONGVARCHAR}"); + } + + return sql.toString(); + } + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_contract_item + * + * @mbg.generated + */ + public String updateByPrimaryKeySelective(TbContractItem record) { + SQL sql = new SQL(); + sql.UPDATE("tb_contract_item"); + + if (record.getContractName() != null) { + sql.SET("contract_name = #{contractName,jdbcType=VARCHAR}"); + } + + if (record.getCreateTime() != null) { + sql.SET("create_time = #{createTime,jdbcType=TIMESTAMP}"); + } + + if (record.getModifyTime() != null) { + sql.SET("modify_time = #{modifyTime,jdbcType=TIMESTAMP}"); + } + + if (record.getWareHouseId() != null) { + sql.SET("ware_house_id = #{wareHouseId,jdbcType=INTEGER}"); + } + + if (record.getContractFolderId() != null) { + sql.SET("contract_folder_id = #{contractFolderId,jdbcType=INTEGER}"); + } + + if (record.getContractSource() != null) { + sql.SET("contract_source = #{contractSource,jdbcType=LONGVARCHAR}"); + } + + if (record.getDescription() != null) { + sql.SET("description = #{description,jdbcType=LONGVARCHAR}"); + } + + if (record.getDescriptionEn() != null) { + sql.SET("description_en = #{descriptionEn,jdbcType=LONGVARCHAR}"); + } + + sql.WHERE("id = #{id,jdbcType=INTEGER}"); + + return sql.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseMapper.java new file mode 100644 index 000000000..e8b20a881 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseMapper.java @@ -0,0 +1,106 @@ +package com.webank.webase.node.mgr.contract.warehouse.mapper; + +import com.webank.webase.node.mgr.contract.warehouse.entity.TbWareHouse; +import java.util.List; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.InsertProvider; +import org.apache.ibatis.annotations.Options; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.SelectKey; +import org.apache.ibatis.annotations.UpdateProvider; +import org.apache.ibatis.type.JdbcType; + +/** + * @author marsli + */ +public interface TbWareHouseMapper { + + @Select({"select", TbWareHouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_ware_house"}) + List findAll(); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_ware_house + * + * @mbg.generated + */ + @Delete({ + "delete from tb_ware_house", + "where id = #{id,jdbcType=INTEGER}" + }) + int deleteByPrimaryKey(Integer id); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_ware_house + * + * @mbg.generated + */ + @InsertProvider(type=TbWareHouseSqlProvider.class, method="insertSelective") + @SelectKey(statement="SELECT LAST_INSERT_ID()", keyProperty="id", before=false, resultType=Integer.class) + int insertSelective(TbWareHouse record); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_ware_house + * + * @mbg.generated + */ + @Select({ + "select", + "id, ware_house_name, ware_house_name_en, type, create_time, modify_time, ware_house_icon, ", + "description, description_en, ware_house_detail, ware_house_detail_en", + "from tb_ware_house", + "where id = #{id,jdbcType=INTEGER}" + }) + @Results({ + @Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true), + @Result(column="ware_house_name", property="wareHouseName", jdbcType=JdbcType.VARCHAR), + @Result(column="ware_house_name_en", property="wareHouseNameEn", jdbcType=JdbcType.VARCHAR), + @Result(column="type", property="type", jdbcType=JdbcType.VARCHAR), + @Result(column="create_time", property="createTime", jdbcType=JdbcType.TIMESTAMP), + @Result(column="modify_time", property="modifyTime", jdbcType=JdbcType.TIMESTAMP), + @Result(column="ware_house_icon", property="wareHouseIcon", jdbcType=JdbcType.LONGVARCHAR), + @Result(column="description", property="description", jdbcType=JdbcType.LONGVARCHAR), + @Result(column="description_en", property="descriptionEn", jdbcType=JdbcType.LONGVARCHAR), + @Result(column="ware_house_detail", property="wareHouseDetail", jdbcType=JdbcType.LONGVARCHAR), + @Result(column="ware_house_detail_en", property="wareHouseDetailEn", jdbcType=JdbcType.LONGVARCHAR) + }) + TbWareHouse selectByPrimaryKey(Integer id); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_ware_house + * + * @mbg.generated + */ + @UpdateProvider(type=TbWareHouseSqlProvider.class, method="updateByPrimaryKeySelective") + int updateByPrimaryKeySelective(TbWareHouse record); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_ware_house + * + * @mbg.generated + */ + @Options(useGeneratedKeys = true,keyProperty="id",keyColumn = "id") + @Insert({ + "", + }) + int batchInsert(java.util.List list); +} \ No newline at end of file diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseSqlProvider.java new file mode 100644 index 000000000..85f9f3ce8 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseSqlProvider.java @@ -0,0 +1,122 @@ +package com.webank.webase.node.mgr.contract.warehouse.mapper; + +import com.webank.webase.node.mgr.contract.warehouse.entity.TbWareHouse; +import org.apache.ibatis.jdbc.SQL; + +public class TbWareHouseSqlProvider { + /** + * This field was generated by MyBatis Generator. + * This field corresponds to the database table tb_ware_house + * + * @mbg.generated + */ + public static final String ALL_COLUMN_FIELDS = "id,ware_house_name,ware_house_name_en,type,create_time,modify_time,ware_house_icon,description,description_en,ware_house_detail,ware_house_detail_en"; + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_ware_house + * + * @mbg.generated + */ + public String insertSelective(TbWareHouse record) { + SQL sql = new SQL(); + sql.INSERT_INTO("tb_ware_house"); + + if (record.getWareHouseName() != null) { + sql.VALUES("ware_house_name", "#{wareHouseName,jdbcType=VARCHAR}"); + } + + if (record.getWareHouseNameEn() != null) { + sql.VALUES("ware_house_name_en", "#{wareHouseNameEn,jdbcType=VARCHAR}"); + } + + if (record.getType() != null) { + sql.VALUES("type", "#{type,jdbcType=VARCHAR}"); + } + + if (record.getCreateTime() != null) { + sql.VALUES("create_time", "#{createTime,jdbcType=TIMESTAMP}"); + } + + if (record.getModifyTime() != null) { + sql.VALUES("modify_time", "#{modifyTime,jdbcType=TIMESTAMP}"); + } + + if (record.getWareHouseIcon() != null) { + sql.VALUES("ware_house_icon", "#{wareHouseIcon,jdbcType=LONGVARCHAR}"); + } + + if (record.getDescription() != null) { + sql.VALUES("description", "#{description,jdbcType=LONGVARCHAR}"); + } + + if (record.getDescriptionEn() != null) { + sql.VALUES("description_en", "#{descriptionEn,jdbcType=LONGVARCHAR}"); + } + + if (record.getWareHouseDetail() != null) { + sql.VALUES("ware_house_detail", "#{wareHouseDetail,jdbcType=LONGVARCHAR}"); + } + + if (record.getWareHouseDetailEn() != null) { + sql.VALUES("ware_house_detail_en", "#{wareHouseDetailEn,jdbcType=LONGVARCHAR}"); + } + + return sql.toString(); + } + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_ware_house + * + * @mbg.generated + */ + public String updateByPrimaryKeySelective(TbWareHouse record) { + SQL sql = new SQL(); + sql.UPDATE("tb_ware_house"); + + if (record.getWareHouseName() != null) { + sql.SET("ware_house_name = #{wareHouseName,jdbcType=VARCHAR}"); + } + + if (record.getWareHouseNameEn() != null) { + sql.SET("ware_house_name_en = #{wareHouseNameEn,jdbcType=VARCHAR}"); + } + + if (record.getType() != null) { + sql.SET("type = #{type,jdbcType=VARCHAR}"); + } + + if (record.getCreateTime() != null) { + sql.SET("create_time = #{createTime,jdbcType=TIMESTAMP}"); + } + + if (record.getModifyTime() != null) { + sql.SET("modify_time = #{modifyTime,jdbcType=TIMESTAMP}"); + } + + if (record.getWareHouseIcon() != null) { + sql.SET("ware_house_icon = #{wareHouseIcon,jdbcType=LONGVARCHAR}"); + } + + if (record.getDescription() != null) { + sql.SET("description = #{description,jdbcType=LONGVARCHAR}"); + } + + if (record.getDescriptionEn() != null) { + sql.SET("description_en = #{descriptionEn,jdbcType=LONGVARCHAR}"); + } + + if (record.getWareHouseDetail() != null) { + sql.SET("ware_house_detail = #{wareHouseDetail,jdbcType=LONGVARCHAR}"); + } + + if (record.getWareHouseDetailEn() != null) { + sql.SET("ware_house_detail_en = #{wareHouseDetailEn,jdbcType=LONGVARCHAR}"); + } + + sql.WHERE("id = #{id,jdbcType=INTEGER}"); + + return sql.toString(); + } +} \ No newline at end of file diff --git a/src/test/java/node/mgr/test/contract/warehouse/WareHouseMdTest.java b/src/test/java/node/mgr/test/contract/warehouse/WareHouseMdTest.java new file mode 100644 index 000000000..2918fb958 --- /dev/null +++ b/src/test/java/node/mgr/test/contract/warehouse/WareHouseMdTest.java @@ -0,0 +1,252 @@ +/** + * Copyright 2014-2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package node.mgr.test.contract.warehouse; + +import java.util.Base64; +import org.junit.Test; + +public class WareHouseMdTest { + public static final String ADDRESS_MD = "# Address\n" + + "\n" + + "Address library\n" + + "\n" + + "Address contract usage methods can refer to the Points contract warehouse。\n" + + "\n" + + "1. Detect whether the address is a contract\n" + + "2. Detect if the address is 0x0"; + public static final String LIB_STRING_MD = "# String library\n" + + "\n" + + "String library\n" + + "\n" + + "Provides common string-related operations, including copying, finding, replacing, and so on。"; + public static final String SAFE_MATH_MD = "# SafeMath\n" + + "\n" + + "SafeMath library\n" + + "\n" + + "A secure mathematical library that provides a safe addition, subtract, and divide。The use of secure mathematical contracts can refer to the Points contract warehouse。"; + public static final String TABLE_MD = "# table\n" + + "\n" + + "table library\n" + + "\n" + + "BCOS CRUD uses the base library, which you can reference by re-contract calling CRUD.Table contract usage methods can be described by referring to the assat example in the bcos document https://fisco-bcos-documentation.readthedocs.io."; + public static final String ROLES_MD ="# Roles\n" + + "\n" + + "Role permissions control contracts\n"; + + @Test + public void testToolMdToBase64() { + System.out.println("ADDRESS_MD:\n" + Base64.getEncoder().encodeToString(ADDRESS_MD.getBytes())); + System.out.println("LIB_STRING_MD:\n" + Base64.getEncoder().encodeToString(LIB_STRING_MD.getBytes())); + System.out.println("SAFE_MATH_MD:\n" + Base64.getEncoder().encodeToString(SAFE_MATH_MD.getBytes())); + System.out.println("TABLE_MD:\n" + Base64.getEncoder().encodeToString(TABLE_MD.getBytes())); + System.out.println("ROLES_MD:\n" + Base64.getEncoder().encodeToString(ROLES_MD.getBytes())); + + System.out.println("EVIDENCE_MD:\n" + Base64.getEncoder().encodeToString(EVIDENCE_MD.getBytes())); + System.out.println("BAC001_MD:\n" + Base64.getEncoder().encodeToString(BAC001_MD.getBytes())); + } + + public static final String EVIDENCE_MD = "# Evidence 合约\n" + + "\n" + + "## 简介\n" + + "Evidence 示例合约,使用分层的智能合约结构: \n" + + "1)工厂合约(EvidenceSignersData.sol),由存证各方事前约定,存储存证生效条件,并管理存证的生成。 \n" + + "2)存证合约(Evidence.sol),由工厂合约生成,存储存证id,hash和各方签名(每张存证一个合约)。 "; + public static final String BAC001_MD = "# 积分合约\n" + + "\n" + + "## 简介\n" + + " BAC001 是一套区块链积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能。\n" + + "\n" + + "## 四个基本元素\n" + + "\n" + + "- description \n" + + "\n" + + " 此积分的具体描述\n" + + "\n" + + "- shortName \n" + + "\n" + + " 积分简称\n" + + "\n" + + "- minUnit \n" + + "\n" + + " 积分最小单位\n" + + "\n" + + "- totalAmount \n" + + "\n" + + " 积分总数量\n" + + "\n" + + "## 五个基本行为: \n" + + "\n" + + "- 发行\n" + + "\n" + + " 调用合约的 deploy 方法,传入你初始化的四个元素即可,即在区块链上发行了你指定总量和名称的积分。\n" + + "\n" + + " - 其中 minUnit 和 totalAmount 不能为负数或小数\n" + + "\n" + + "- 转账\n" + + "\n" + + " 调用 send 方法即可实现转账,之后调用 balance 方法可以查看自己的积分余额\n" + + "\n" + + "- 增发\n" + + "\n" + + " 调用 issue 方法特定地址增发积分, 并可以通过 addIssuer 增加有权限增发积分的人,也可以通过renounceIssuer 方法移除增发权限\n" + + "\n" + + "- 销毁\n" + + "\n" + + " 调用 destory 以及 destoryFrom 销毁自己地址下积分和特定地址下的积分\n" + + "\n" + + "- 暂停\n" + + "\n" + + " 遇到紧急状况,你可以调用 suspend 方法,暂停合约,这样任何人都不能调用 send 函数。故障修复后,可以调用 unSuspend 方法解除暂停。也可以通过 addSuspender 和 renounceSuspender 相应增加和移除暂停者权限\n" + + "\n" + + "\n" + + "## 接口说明\n" + + "\n" + + "- totalAmount()\n" + + "\n" + + " 返回积分总量\n" + + "\n" + + " - 这里的积分总量需要计算最小转账单位,所以实际返回值为 totalAmount * 10minUnit \n" + + "\n" + + "- balance(address owner)\n" + + "\n" + + " 返回owner的帐户的积分余额\n" + + "\n" + + "- send(address to, uint256 value , string data)\n" + + "\n" + + " 将数量为value的积分转入地址 to 并触发 transfer 事件, data 是转账备注\n" + + "\n" + + " - suspend 状态下无法进行此操作\n" + + " - 请避免 to 为自身进行操作\n" + + "\n" + + "- sendFrom(address from,address to,uint256 value,string data))\n" + + "\n" + + " 将地址 from 中的 value 数量的积分转入地址 to ,并触发 transfer 事件,data 是转账备注。\n" + + "\n" + + " - 方法的调用者可以不为 from, 此时需要预先进行 approve 授权\n" + + "\n" + + " - from 不能为调用者自身地址,否则会报错\n" + + " - suspend 状态下无法执行此操作\n" + + "\n" + + "- safeSendFrom(address from, address to, uint256 value, string data)\n" + + "\n" + + " 安全的将地址 from 中的 value 数量的积分转入地址 to ( to如果是合约地址,必须实现接收接口 BAC001Holder 才可以接收转账) ,并触发 transfer 事件,data 是转账备注\n" + + "\n" + + " - suspend 状态下无法执行此操作\n" + + "\n" + + "- safeBatchSend( address[] to, uint256[] values, string data)\n" + + "\n" + + " 批量将自己账户下的积分转给 to 数组的地址, to 和 values 的个数要一致\n" + + "\n" + + " - suspend 状态下无法执行此操作\n" + + "\n" + + "- approve(address spender,uint256 value)\n" + + "\n" + + " 允许 spender 从自己账户提取限额 value 的积分\n" + + "\n" + + " - 此方法配合 sendfrom / safesendfrom 一起使用\n" + + " - 重复授权时,最终授权额度为最后一次授权的值\n" + + "\n" + + "- allowance(address owner,address spender)\n" + + "\n" + + " 返回 spender 可从 owner 提取的积分数量上限\n" + + "\n" + + " - 此方法配合 approve 一起使用\n" + + "\n" + + "- increaseAllowance(address spender, uint256 addedValue)\n" + + "\n" + + " 允许 spender 提取的积分上限在原有基础上增加 addedValue\n" + + "\n" + + " - 此方法配合 approve 使用\n" + + "\n" + + "- decreaseAllowance(address spender, uint256 subtractedValue)\n" + + "\n" + + " 允许 spender 提取的积分上限在原有基础上减少 subtractedValue\n" + + "\n" + + " - 此方法配合 approve 使用\n" + + "\n" + + "- minUnit()\n" + + "\n" + + " 积分最小单位\n" + + "\n" + + "- shortName()\n" + + "\n" + + " 积分简称\n" + + "\n" + + "- description()\n" + + "\n" + + " 积分描述\n" + + "\n" + + "- destory(uint256 value, string data)\n" + + "\n" + + " 减少自己的积分,data 是转账备注\n" + + "\n" + + " - 调用时,value 值需要小于等于目前自己的积分总量\n" + + "\n" + + "- destroyFrom(address from, uint256 value, string data)\n" + + "\n" + + " 减少地址 from 积分,data 是转账备注\n" + + "\n" + + " - 调用此方法时,需要配合 approve 进行使用\n" + + "\n" + + "- issue(address to, uint256 value,string data)\n" + + "\n" + + " 给地址 to 增加数量为 value 的积分,data 是转账备注\n" + + "\n" + + "- isIssuer(address account)\n" + + "\n" + + " 检查 account 是否有增加积分的权限\n" + + "\n" + + "- addIssuer(address account)\n" + + "\n" + + " 使地址 account 拥有增加积分的权限\n" + + "\n" + + "- renounceIssuer()\n" + + "\n" + + " 移除增加积分的权限\n" + + "\n" + + "- suspend()\n" + + "\n" + + " 暂停合约\n" + + "\n" + + " - suspend 后无法进行 send / safesendfrom / sendfrom / safeBatchSend / approves 操作\n" + + "\n" + + "- unSuspend()\n" + + "\n" + + " 重启合约\n" + + " \n" + + "- suspended\n" + + "\n" + + " 判断合约是否处于暂停状态\n" + + "\n" + + "- isSuspender(address account)\n" + + "\n" + + " 是否有暂停合约权限\n" + + "\n" + + " - 配合 suspend 方法一起使用\n" + + "\n" + + "- addSuspender(address account)\n" + + "\n" + + " 增加暂停权限者\n" + + "\n" + + " - 配合 suspend 方法一起使用\n" + + "\n" + + "- renounceSuspender()\n" + + "\n" + + " 移除暂停权限\n" + + "\n" + + " - 配合 suspend / addSuspender 方法使用\n" + + "\n" + + "\n"; +} From df99cd07d7f5d1388a445294f13c4aeb3daac32b Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Sun, 25 Apr 2021 17:59:05 +0800 Subject: [PATCH 14/92] add warehouse sql & rm gm dir --- script/gm/webase-dml-gm.sql | 108 -------------------------------- script/gm/webase-gm.sh | 32 ---------- script/gm/webase-sql-gm.list | 4 -- script/webase-ddl.sql | 50 ++++++++++++++- script/webase-dml.sql | 118 +++++++++++++++++++++++++++++------ 5 files changed, 147 insertions(+), 165 deletions(-) delete mode 100644 script/gm/webase-dml-gm.sql delete mode 100644 script/gm/webase-gm.sh delete mode 100644 script/gm/webase-sql-gm.list diff --git a/script/gm/webase-dml-gm.sql b/script/gm/webase-dml-gm.sql deleted file mode 100644 index cda8c7475..000000000 --- a/script/gm/webase-dml-gm.sql +++ /dev/null @@ -1,108 +0,0 @@ - --- ---------------------------- --- 1、init tb_account_info data admin/password4 // 国密版 sm3.hash(password) --- ---------------------------- -INSERT INTO tb_account_info (account,account_pwd,role_id,create_time,modify_time)values('admin', '$2a$10$F/aEB1iEx/FvVh0fMn6L/uyy.PkpTy8Kd9EdbqLGo7Bw7eCivpq.m',100000,now(),now()); - - --- ---------------------------- --- 2、init tb_role data --- ---------------------------- -INSERT INTO `tb_role` (role_name,role_name_zh,create_time,modify_time)VALUES ('admin', '管理员', now(), now()); -INSERT INTO `tb_role` (role_name,role_name_zh,create_time,modify_time)VALUES ('visitor', '普通用户', now(), now()); -INSERT INTO `tb_role` (role_name,role_name_zh,create_time,modify_time)VALUES ('developer', '开发者', now(), now()); - - --- ---------------------------- --- 3、init tb_user data 国密版 --- ---------------------------- --- INSERT INTO tb_user(user_name, public_key, user_status, user_type, address, has_pk, create_time, modify_time) VALUES ( 'systemUser', '0xc5d877bff9923af55f248fb48b8907dc7d00cac3ba19b4259aebefe325510af7bd0a75e9a8e8234aa7aa58bc70510ee4bef02201a86006196da4e771c47b71b4', 1, 2, '0xf1585b8d0e08a0a00fff662e24d67ba95a438256', 1, Now(), Now()); - - - --- ---------------------------- --- 4、init tb_user_key_mapping data 国密版 --- ---------------------------- --- INSERT INTO tb_user_key_mapping(user_id, private_key, map_status, create_time, modify_time) VALUES (700001, 'SzK9KCjpyVCW0T9K9r/MSlmcpkeckYKVn/D1X7fzzp18MM7yHhUHQugTxKXVJJY5XWOb4zZ79IXMBu77zmXsr0mCRnATZTUqFfWLX6tUBIw=', 1, now(), now()); - - --- ---------------------------- --- 5、init tb_method (repeated methodId is removed, ex: remove(string)) methodId 国密版 --- ---------------------------- --- (system config info 0x1000) setValueByKey -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x0749b518', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"value\",\"type\":\"string\"}],\"name\":\"setValueByKey\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); --- (table factory 0x1001) createTable openTable -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xc92a7801', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"tableName\",\"type\":\"string\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"valueField\",\"type\":\"string\"}],\"name\":\"createTable\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x59a48b65', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"string\"}],\"name\":\"openTable\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, now(), now()); --- (crud info 0x1002) update select remove insert(same as cns's insert) -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x10bd675b', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"tableName\",\"type\":\"string\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"entry\",\"type\":\"string\"},{\"name\":\"condition\",\"type\":\"string\"},{\"name\":\"optional\",\"type\":\"string\"}],\"name\":\"update\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x7388111f', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"tableName\",\"type\":\"string\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"condition\",\"type\":\"string\"},{\"name\":\"optional\",\"type\":\"string\"}],\"name\":\"select\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x81b81824', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"tableName\",\"type\":\"string\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"condition\",\"type\":\"string\"},{\"name\":\"optional\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xb8eaa08d', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"version\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"string\"},{\"name\":\"abi\",\"type\":\"string\"}],\"name\":\"insert\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-06-17 20:32:30', '2019-06-17 20:32:30'); --- (consensus info node manage 0x1003) addObserver addSealer remove -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x25e85d16', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"nodeID\",\"type\":\"string\"}],\"name\":\"addObserver\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xdf434acc', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"nodeID\",\"type\":\"string\"}],\"name\":\"addSealer\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x86b733f9', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"nodeID\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); --- (cns info 0x1004) selectByName selectByNameAndVersion // insert(ignored, same as crud's insert method: insert(string,string,string,string) -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x078af4af', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"}],\"name\":\"selectByName\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2019-06-17 20:32:30', '2019-06-17 20:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xec72a422', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"version\",\"type\":\"string\"}],\"name\":\"selectByNameAndVersion\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2019-06-17 20:32:30', '2019-06-17 20:32:30'); --- INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xb8eaa08d', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"version\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"string\"},{\"name\":\"abi\",\"type\":\"string\"}],\"name\":\"insert\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-06-17 20:32:30', '2019-06-17 20:32:30'); --- (permission manage 0x1005) insert queryByName remove grantWrite revokeWrite -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xce0a9fb9', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"table_name\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"string\"}],\"name\":\"insert\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xbbec3f91', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"table_name\",\"type\":\"string\"}],\"name\":\"queryByName\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x85d23afc', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"table_name\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xd010d23c', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"contractAddr\",\"type\":\"address\"},{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"grantWrite\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, now(), now()); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xdf12fe78', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"contractAddr\",\"type\":\"address\"},{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"revokeWrite\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, now(), now()); --- (contract life cycle 0x1007) --- getStatus unfreeze freeze grantManager queryManager revokeManager -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xbca14431', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x61cb24c3', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"unfreeze\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xf12c66df', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"freeze\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x27c46414', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"contractAddr\",\"type\":\"address\"},{\"name\":\"userAddr\",\"type\":\"address\"}],\"name\":\"grantManager\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xa450e730', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryManager\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x00c77684', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"contractAddr\",\"type\":\"address\"},{\"name\":\"userAddr\",\"type\":\"address\"}],\"name\":\"revokeManager\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, now(), now()); --- (chain governance 0x1008) --- listOperators updateCommitteeMemberWeight queryThreshold queryCommitteeMemberWeight grantCommitteeMember -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xb90059a3', 0, '{\"constant\":true,\"inputs\":[],\"name\":\"listOperators\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x95e96f8f', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"},{\"name\":\"weight\",\"type\":\"int256\"}],\"name\":\"updateCommitteeMemberWeight\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x35365efb', 0, '{\"constant\":true,\"inputs\":[],\"name\":\"queryThreshold\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xc784c982', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"queryCommitteeMemberWeight\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"},{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xcbff0346', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"grantCommitteeMember\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); --- unfreezeAccount listCommitteeMembers updateThreshold revokeCommitteeMember grantOperator -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x2312386d', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"account\",\"type\":\"address\"}],\"name\":\"unfreezeAccount\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x77cb0994', 0, '{\"constant\":true,\"inputs\":[],\"name\":\"listCommitteeMembers\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x931af204', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"threshold\",\"type\":\"int256\"}],\"name\":\"updateThreshold\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x681362f3', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"revokeCommitteeMember\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xd1db6540', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"grantOperator\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); --- freezeAccount revokeOperator getAccountStatus -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x563e46a5', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"account\",\"type\":\"address\"}],\"name\":\"freezeAccount\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xc9ab2069', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"revokeOperator\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xa41e61cc', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); - - --- ---------------------------- --- 6、init tb_alert_rule --- ---------------------------- --- add node status alert rule template -INSERT INTO `tb_alert_rule`(`rule_name`,`enable`,`alert_type`,`alert_level`,`alert_interval_seconds`,`alert_content`,`content_param_list`,`create_time`,`modify_time`) VALUES ('节点异常告警/Node Exception', 0, 1, 1, 3600, '{nodeId}节点异常,请到“节点管理”页面查看具体信息 / Node: {nodeIdEn} node status exception,please check out in \"Node Management\"', '[\"{nodeId}\", \"{nodeIdEn}\"]', '2019-10-29 20:02:30', '2019-10-29 20:02:30'); --- add audit alert rule template -INSERT INTO `tb_alert_rule`(`rule_name`,`enable`,`alert_type`,`alert_level`,`alert_interval_seconds`,`alert_content`,`content_param_list`,`create_time`,`modify_time`) VALUES ('审计异常告警/Audit Exception', 0, 2, 1, 3600, '审计异常:{auditType},请到“交易审计”页面查看具体信息 / Audit alert: {auditTypeEn},please check out in \"Transaction Audit\"', '[\"{auditType}\", \"{auditTypeEn}\"]', '2019-10-29 20:02:30', '2019-10-29 20:02:30'); --- add cert alert rule template -INSERT INTO `tb_alert_rule`(`rule_name`,`enable`,`alert_type`,`alert_level`,`alert_interval_seconds`,`alert_content`,`content_param_list`,`create_time`,`modify_time`) VALUES ('证书有效期告警/Cert Validity Exception', 0, 3, 1, 3600, '证书将在{time}过期,请到“证书管理”页面查看具体信息 / Cert validity exception:invalid at {timeEn},please check out in \"Cert Management\"', '[\"{time}\", \"{timeEn}\"]', '2019-10-29 20:02:30', '2019-10-29 20:02:30'); - --- ---------------------------- --- 7、init tb_mail_server_config --- ---------------------------- --- add mail_server_config template -INSERT INTO `tb_mail_server_config`(`server_name`,`host`,`port`,`username`,`password`,`protocol`,`default_encoding`,`create_time`,`modify_time`,`authentication`,`starttls_enable`,`starttls_required`,`socket_factory_port`,`socket_factory_class`,`socket_factory_fallback`,`enable`) VALUES ('Default config', 'smtp.qq.com', '25', 'yourmail@qq.com', 'yourpassword','smtp', 'UTF-8','2019-10-29 20:02:30', '2019-10-29 20:02:30', 1, 1, 0, 465, 'javax.net.ssl.SSLSocketFactory', 0, 0); - - --- ---------------------------- --- 8、init tb_config --- ---------------------------- -INSERT INTO `tb_config`(`config_name`, `config_type`, `config_value`, `create_time`, `modify_time`) VALUES ('docker 镜像版本', 1, 'v2.7.2', '2020-07-22 17:14:23', '2020-07-22 17:14:23'); - --- ---------------------------- --- 9、init tb_app_info data (template) --- ---------------------------- -INSERT INTO `tb_app_info` (`app_name`, `app_key`, `app_type`, `app_doc_link`, `app_icon`, `app_desc`, `app_detail`, `create_time`, `modify_time`) VALUES ('WeId-temp', 'app00001', 1, 'https://weidentity.readthedocs.io/zh_CN/latest/docs/deploy-via-web.html', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFGmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDIgNzkuMTY0MzUyLCAyMDIwLzAxLzMwLTE1OjUwOjM4ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjEtMDMtMThUMTY6NTc6MzQrMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTAzLTE4VDE4OjAyOjAxKzA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIxLTAzLTE4VDE4OjAyOjAxKzA4OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg1NDJjNjJlLTZjYTUtNGI2My05ZDg5LWNhMjVmOTU1NTA4OSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4NTQyYzYyZS02Y2E1LTRiNjMtOWQ4OS1jYTI1Zjk1NTUwODkiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo4NTQyYzYyZS02Y2E1LTRiNjMtOWQ4OS1jYTI1Zjk1NTUwODkiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg1NDJjNjJlLTZjYTUtNGI2My05ZDg5LWNhMjVmOTU1NTA4OSIgc3RFdnQ6d2hlbj0iMjAyMS0wMy0xOFQxNjo1NzozNCswODowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+5hbXdAAADNFJREFUeJzt23msXOV5x/Hf877vWWa/q++177VZvG8EMEUyxXIxFBVaCIEEiFJVCS0ohJRIVGoiHFVKlTZVUUvVqE5omlBQiJIoAYKdpTipgZrGtdsa8IIDxtf7vXPX2c+c8y5P/7gusgWWKs4fVdXzlY5mzoxm5ugz533PnNEMMTOyPnjif3sD/q+XAaYsA0xZBpiyDDBlGWDKMsCUZYApywBTlgGmLANMWQaYsgwwZRlgyjLAlGWAKcsAU5YBpiwDTFkGmLIMMGUZYMoywJRlgCnLAFOWAaYsA0xZBpiyDDBlGWDKMsCUZYApU+ev7BscAACQ4z8E+F6AzmilPu6SxOpaDcrzkKuUoZmhmB8F8NsCOGRIPNBRCtfUa4i6MeoAdpVG8ceb/xxOEPIm7hVSfpcFiuToaXJ4go3F5PFZeJVRRHsfATCO4Vv+7ouyOHiN6UZfJNBB9iUmIwbXE3jVMbjxz8Jf4iCW/gDtX2nArwGiC7SuQLGyFkr8CI2DHoZuvBQQDqSMAsMRsSMSSIwFMcMraIzv+DRs504Az2H4lm1QuQEZcR1e3trG/jY6y0eBmTaw+ygABq68BNiwEDgyDd5937tmF+yB1hoYa0DgO4UQ17E1Vw83Gq7cbCIGYJhhnIXHFkS4WwLXGaI1LBREHAFOgwDUAVzZPI3bT7+Ebq4PQnmXQ4qb4XCd82yv6zEwXgI2ANsWQFchXHV3KILcl9jqD1OCAF0Bqx1AH+AXtJ4AyN3DJF8URI8JcujYGKKwACS9e532tlfWvXZL4cqrkVt3Vwjpf4dZv1gIzSaSOSRQ82j/gy4A7NYaiOtNYuZhQQQnxY8Xx13utxYGQCIEClGMdfVmAUyDICBW8meVdhMDtQYiIgAEB6AD4IGjOzEY94C4uNzBQBkfjcWzL1evOo220nANB4gIhBUIeu4YkMW8YKNnRIiDwjOwksEMwAI2tgAIIIJzDCQO0BrQCRADzoQQ2sBpwoxrgVh/VBLfEDu3uJoEmK2fQnPPX0GwfkSEg7+T739hsR7oR7j2viEVhB9n57Z0Dg9MTbV9GIQAM2AZgJ5fDANCAPZCwAuGMJVKUMxLQHS5cw6WxL+9XanAEj08RFjM1o012W07kMuNMHgRSEBq/VrS6SAI/HUn8+GtfkENsDFvuyj67vJoqrkh2o9dvUvWFNsMp2yjPN73TjhRhq4J5IbsQG5B4faem1cvANorTduHyvceiN55LtZtDX/9J5A30yNcoLJclDvWqqrYJha5nKpgUIxC9cagoqA8tB+cHpOyiNzyYpFjsxC+t5xIwMbRW6xxSSBl0m0cnSi55BvKo58kzdzTaMxWKAhvF6EPFlRruZovOnJJ2KdaRDyIvLK4ZOAoSQaX1RC6yQjnaAbAiXfNzv+R+duVChIpb+pKsZOZoVrt/sT3Nsl8/nlhLAQB2tg+Q1jhS7GHGci12wMNqW4LCoUnnbVwAJQgdEkc2Dg1ufnrC1bPPbjlL7+/KKp9jHz7n2bSbuicaiF3VeXWUPrfccZVWAmwTqBjoHcg/Gp1998+bMPVC3vWfXgbktodQkk4ZU5Ep8r3q1DvVP2dL0tWf+ScDBkSUna7znZ+Fkf0US+f+5Jif6tOOgADJCWk9EFEX+F8cZttNX/BNjluJX0+8MLnXBJf6nQMCAmVF0CizjCZbcKpraTsfqvN9dGcRWEw/yKMu8mS23r62d/7yvsO4csaDZTjeLkmgmT+VRD6GzzPe4a1hiaODAAy5pNerFcRCUjr9rHnXxfkwyfJ6rjjzF01nVwmnP3moDXrX63kH/mzbg3FuVOXE4WgUB7pNM+CKV4f+P4LOtIVSPsZ6Zl1MO7nni9Qn2nt0SOfQmnFzS+5ePYO5+zTJokftW0xWrx8ZruefWdYV80yYzhkE00LW//XpKN9oHSHjeKHda1x1MEend89iJntK4xkX7fTebF1trpWslnh4BY1g6QOVT3I1tQgJEA4biJ+xbjkWWvMUGKTPCs5kUwZzO09nddGbzZkSZE9eNE5cF9/P8bDcJ1nLSxAdeU9AaICrH2Iou5niRnsew+50L+PrYURNNb2vDthGZYxFRCuLyvxB4YxFMQNVPMjG6tbHivnw+IyRgNmRu6Tc7+J4orRx2yspVK8tXus+bXJXdVDELIowBCJ+mWp7N1NHK1gxlGAdoH5EGB2mygInF+5Ex73WMso+rUHB/NTv86gZzk2oL7eNVGl5x9trL9AQgEQY2Da7Ky5Vgj3kpTY7GDgecnhYHzx2NSu226DoINCCQB4HLCbRYKH4WiESEB33ctqMIcFNy1cxQ4+O5oulczrF50DBSAUYSUzwMAKjxkW9KqRcpsiGRDRV8G8FMBSx4ATmBbgZc4BDtBSqt8loGwZdUt0tKTEy4NEqxPIihARuh25p0aSFnp8I6yFFfxUtx5BaN0Hhw0msEYPd06G9dJWxw4A50DeYyBVIbY1js3JwuJSDxu7lo3GlN70HxPxCeRp9hJBEuzweqvuID2+qqwYlvh1BYXW3BxcHqiU+tdar4b2W1ccaO3/Naglb5YYvB6OAZb/LkSMaKgNrzG4WloCkuQN6gIoFZeK+e05XGuEpy+6Bw7U60uYeZWjcxOkc6eDSuUjpUUjoGIxZuZvERgMQFgDUSn/knK5cWEtIOkFS2IJQKGQNBpKcc8sgr+oW3WFhAV0Qa/sa78+eu3PfSBW7ASccZcV1veg78ZFq8HkOfAh7WsLiw5IAsB25/QKa5JhNm4jC3UDEncSjFEhvbkW+2Nt3Q0J+JABo2i6+wbDLnyPN1rrAMHHHFnfy+UXdN7aEcTNqTWsywiHq2/037QDg5t2XgNGhR054VyVWfZSnvIkbczMIBJbWGHYQd8COBD4DTC7iwLGYXgFAyPEgCICCXFvrrd3SrdaqI+Po9vp/L2SCsQASQW0u6+Fid4mPQnB/LnA6O+x0V9W1vyDY/e91VMnSz2ms9pAwlIy1WARVZKlCVjuhyAI8reTVttMh7/OwsHv8FhfdRFEaegbpHyA8WlI+hrDfU746m+I6JPO8HKAwMRnh8XLGFHtjSxCH8ygmeLhAoUIfXGZA8COHmDId6hU+OvCpZsGSQXLWDMczR4JShMQjQXDRBIgJ5wnfgqZO+MdqHyIWvZPAYA8+hMqyBPS8qdkcRitsZ1vntlxPy4K2MyFS8tKtrRSk7FOHmo1W6/OHDuG5pkzcNYgjroHusZ82w+8VqzkW6bZrO6Zq+2dTsxH8ky/6Cp1a+J5X4CjDUlsn/inNVc2m8PBQFgM2iL0fjqRAOPdNjO7e8jxM+SDPd970DM9SwOIVryosKua/AumX3n0QFI9cr3I9X9fsLxBKf9+a9jYKP4xCxcTYSZK3A8n20VoCgaIxGkh5Q87SjerEwnaHbdVenIPQJMCNNM15nnuW1lWfukEg3dOT/DxiagHM36w0zl+iki+CSZBQrzSmWqedNo8T8Jd09L4TBLbx0kQXNJCoW/Vgf7Vd18AeMHHmAO5cOiQoNxGYj3p4jNzESABEOYvEwALwtCLlRgdMKZxtpvM7ACwsVDApWGISjdaSACdEmrSRg2zdfG38Wq4cmFZ/yhMcksnuwvWtkvqOEphDc7zYCbcYOS3QwwfYdFe6XVP3HVGjx9MUP0t9Fx9F4rrHkIyN1ZWoc+1I7NNlRCK6ytFtrpQb4npTgw7UHR54Ym8MKIBQ8lEtQMMFLCoQgHrxGcr2haJ0+QCXwQFZtFmR/FMPg+GQblVR9nLVQwnGvA6IvBBVv8GAzOtBMd9a34/zNHjrAonWiRXkMolc8/c+v4HEb8bVw8D+BiAZh6YPQcHzJ/YWCIUnNOtVndsEMAkgADzwz0hwlDUHScAY6USyAfCsTUA+sYbOAaUh4AR9e4ZEgUSetpOtQstYPkeoDMCvDYCYATAKpBqg9kCQGN+A/i/B0wLQIsIoPnx0wHQYQCCBaQUcILAQAwgnn/752eocwtAgGSGAc/fzairqQ5mKEQSuuJQj/c8GJWK52A9D5DFY93xvZ+on92bwDkAFwF0AAoAYjl/nXBhdA6RiKB5/mBC592XCAE6d50YEF4D0EUAOSCUwPnzr2OQB0BJwFbm3yoP82dO0JhfOf/F6b0b9EE7/zTXMoRwmLttPaJiEaLTTcSe459n5+6xgvu8XPxku3HtUzO7t9eAf37PU6n33PL/LHLzO0K0ZRnQV4SYaSZiz7EfWMfTQqCkPPsTZ4Ia0Pv+j8/+L5yu7AvVlGWAKcsAU5YBpiwDTFkGmLIMMGUZYMoywJRlgCnLAFOWAaYsA0xZBpiyDDBlGWDKMsCUZYApywBTlgGmLANMWQaYsgwwZRlgyjLAlGWAKcsAU5YBpiwDTFkGmLIMMGX/BTNpY2P8E+A7AAAAAElFTkSuQmCC', 'WeIdentity是一套分布式多中心的技术解决方案。', 'WeIdentity目前主要包含两大模块:WeIdentity DID以及WeIdentity Credential。 WeIdentity DID模块在FISCO-BCOS区块链底层平台上实现了一套符合W3C DID规范的分布式多中心的身份标识协议,使实体(人或物)的现实身份实现了链上的身份标识;WeIdentity Credential提供了一整套基于W3C VC规范的解决方案,旨在对这一类数据进行标准化、电子化,生成可验证、可交换的「凭证」(Credential),支持对凭证的属性进行选择性披露,及生成链上存证(Evidence)。', now(), now()); diff --git a/script/gm/webase-gm.sh b/script/gm/webase-gm.sh deleted file mode 100644 index 131330a84..000000000 --- a/script/gm/webase-gm.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - - -echo -e "\n init start...." - -IP=${1} -PORT=${2} - -if [[ ! $IP || ! $PORT ]] ; then - echo "Usage: sh ${0} ip port" - echo "eg: sh ${0} 127.0.0.1 8501" - exit 1 -fi - -#dbUser -DBUSER="defaultAccount" -#dbPass -PASSWD="defaultPassword" -#dbName -DBNAME="webasenodemanager" - - -#connect to database then execute init -cat webase-sql-gm.list | mysql --user=$DBUSER --password=$PASSWD --host=$IP --database=$DBNAME --port=$PORT --default-character-set=utf8; - -if [ "$?" == "0" ]; then - echo -e "init success... \n" -else - echo -e "init fail... \n" -fi - -exit diff --git a/script/gm/webase-sql-gm.list b/script/gm/webase-sql-gm.list deleted file mode 100644 index 6f172a3d9..000000000 --- a/script/gm/webase-sql-gm.list +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -source ../webase-ddl.sql; -source webase-dml-gm.sql; \ No newline at end of file diff --git a/script/webase-ddl.sql b/script/webase-ddl.sql index 67025d5c3..96d8019f3 100644 --- a/script/webase-ddl.sql +++ b/script/webase-ddl.sql @@ -527,6 +527,7 @@ CREATE TABLE IF NOT EXISTS tb_app_info ( -- ---------------------------- -- Table structure for tb_contract_store +-- contract from application manage -- ---------------------------- CREATE TABLE IF NOT EXISTS tb_contract_store ( id int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号', @@ -541,6 +542,53 @@ CREATE TABLE IF NOT EXISTS tb_contract_store ( modify_time datetime DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (id), UNIQUE KEY uk_version (app_key,contract_name,contract_version) -) ENGINE=InnoDB AUTO_INCREMENT=300001 DEFAULT CHARSET=utf8 COMMENT='应用合约仓库'; +) ENGINE=InnoDB AUTO_INCREMENT=300001 DEFAULT CHARSET=utf8 COMMENT='应用合约信息'; SET FOREIGN_KEY_CHECKS = 1; + +-- ---------------------------- +-- Table structure for tb_contract_store +-- ---------------------------- +CREATE TABLE IF NOT EXISTS tb_ware_house ( + id int(11) NOT NULL COMMENT '自增编号', + ware_house_name varchar(255) binary NOT NULL COMMENT '合约仓库名', + ware_house_name_en varchar(255) binary NOT NULL COMMENT '仓库名(英文)', + type int(11) binary NOT NULL COMMENT '仓库类型', + ware_house_icon mediumtext COMMENT '仓库图标(Base64)', + description mediumtext COMMENT '仓库描述(Base64)', + description_en mediumtext COMMENT '仓库描述(英文)(Base64)', + ware_house_detail mediumtext COMMENT '仓库详情', + ware_house_detail_en mediumtext COMMENT '仓库详情(英文)', + create_time datetime DEFAULT NULL COMMENT '创建时间', + modify_time datetime DEFAULT NULL COMMENT '修改时间', + PRIMARY KEY (id), + UNIQUE KEY uk_name(ware_house_name) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='合约仓库'; + +CREATE TABLE IF NOT EXISTS tb_contract_folder ( + id int(11) NOT NULL COMMENT '自增编号', + folder_name varchar(255) binary NOT NULL COMMENT '合约目录名', + description mediumtext COMMENT '目录描述(Base64)', + description_en mediumtext COMMENT '目录描述(英文)(Base64)', + folder_detail mediumtext COMMENT '目录详情', + folder_detail_en mediumtext COMMENT '目录详情(英文)', + create_time datetime DEFAULT NULL COMMENT '创建时间', + modify_time datetime DEFAULT NULL COMMENT '修改时间', + ware_house_id int(11) NOT NULL COMMENT '合约仓库编号', + PRIMARY KEY (id), + UNIQUE KEY uk_name(ware_house_id,folder_name) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='合约仓库目录'; + +CREATE TABLE IF NOT EXISTS tb_contract_item ( + id int(11) NOT NULL COMMENT '自增编号', + contract_name varchar(255) binary NOT NULL COMMENT '合约名称', + contract_source mediumtext COMMENT '合约源码(Base64)', + description mediumtext COMMENT '合约描述(Base64)', + description_en mediumtext COMMENT '合约描述(英文)(Base64)', + create_time datetime DEFAULT NULL COMMENT '创建时间', + modify_time datetime DEFAULT NULL COMMENT '修改时间', + ware_house_id int(11) NOT NULL COMMENT '合约仓库编号', + contract_folder_id int(11) NOT NULL COMMENT '合约目录编号', + PRIMARY KEY (id), + UNIQUE KEY uk_name(ware_house_id,contract_folder_id,contract_name) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='合约仓库合约信息'; diff --git a/script/webase-dml.sql b/script/webase-dml.sql index d4e7165c5..cc8ea4396 100644 --- a/script/webase-dml.sql +++ b/script/webase-dml.sql @@ -13,23 +13,8 @@ INSERT INTO `tb_role` (role_name,role_name_zh,create_time,modify_time)VALUES ('a INSERT INTO `tb_role` (role_name,role_name_zh,create_time,modify_time)VALUES ('visitor', '普通用户', now(), now()); INSERT INTO `tb_role` (role_name,role_name_zh,create_time,modify_time)VALUES ('developer', '开发者', now(), now()); - --- ---------------------------- --- 3、init tb_user data --- ---------------------------- --- INSERT INTO tb_user(user_name, public_key, user_status, user_type, address, has_pk, create_time, modify_time) VALUES ( 'systemUser', '0xc5d877bff9923af55f248fb48b8907dc7d00cac3ba19b4259aebefe325510af7bd0a75e9a8e8234aa7aa58bc70510ee4bef02201a86006196da4e771c47b71b4', 1, 2, '0xf1585b8d0e08a0a00fff662e24d67ba95a438256', 1, Now(), Now()); - - - --- ---------------------------- --- 4、init tb_user_key_mapping data -- ---------------------------- --- INSERT INTO tb_user_key_mapping(user_id, private_key, map_status, create_time, modify_time) VALUES (700001, 'SzK9KCjpyVCW0T9K9r/MSlmcpkeckYKVn/D1X7fzzp18MM7yHhUHQugTxKXVJJY5XWOb4zZ79IXMBu77zmXsr0mCRnATZTUqFfWLX6tUBIw=', 1, now(), now()); - - - --- ---------------------------- --- 5、init tb_method (repeated methodId is removed, ex: remove(string)) +-- 3、init tb_method (repeated methodId is removed, ex: remove(string)) -- ---------------------------- -- (system config info 0x1000) setValueByKey INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xbd291aef', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"value\",\"type\":\"string\"}],\"name\":\"setValueByKey\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); @@ -81,9 +66,62 @@ INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `con INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xfad8b32a', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"revokeOperator\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xfd4fa05a', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +-- ---------------------------- +-- 4、init tb_method of guomi encrypt type (repeated methodId is removed, ex: remove(string)) +-- ---------------------------- +-- (system config info 0x1000) setValueByKey +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x0749b518', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"value\",\"type\":\"string\"}],\"name\":\"setValueByKey\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); +-- (table factory 0x1001) createTable openTable +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xc92a7801', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"tableName\",\"type\":\"string\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"valueField\",\"type\":\"string\"}],\"name\":\"createTable\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x59a48b65', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"string\"}],\"name\":\"openTable\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, now(), now()); +-- (crud info 0x1002) update select remove insert(same as cns's insert) +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x10bd675b', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"tableName\",\"type\":\"string\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"entry\",\"type\":\"string\"},{\"name\":\"condition\",\"type\":\"string\"},{\"name\":\"optional\",\"type\":\"string\"}],\"name\":\"update\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x7388111f', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"tableName\",\"type\":\"string\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"condition\",\"type\":\"string\"},{\"name\":\"optional\",\"type\":\"string\"}],\"name\":\"select\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x81b81824', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"tableName\",\"type\":\"string\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"condition\",\"type\":\"string\"},{\"name\":\"optional\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xb8eaa08d', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"version\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"string\"},{\"name\":\"abi\",\"type\":\"string\"}],\"name\":\"insert\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-06-17 20:32:30', '2019-06-17 20:32:30'); +-- (consensus info node manage 0x1003) addObserver addSealer remove +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x25e85d16', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"nodeID\",\"type\":\"string\"}],\"name\":\"addObserver\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xdf434acc', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"nodeID\",\"type\":\"string\"}],\"name\":\"addSealer\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x86b733f9', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"nodeID\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); +-- (cns info 0x1004) selectByName selectByNameAndVersion // insert(ignored, same as crud's insert method: insert(string,string,string,string) +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x078af4af', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"}],\"name\":\"selectByName\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2019-06-17 20:32:30', '2019-06-17 20:32:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xec72a422', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"version\",\"type\":\"string\"}],\"name\":\"selectByNameAndVersion\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2019-06-17 20:32:30', '2019-06-17 20:32:30'); +-- INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xb8eaa08d', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"version\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"string\"},{\"name\":\"abi\",\"type\":\"string\"}],\"name\":\"insert\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-06-17 20:32:30', '2019-06-17 20:32:30'); +-- (permission manage 0x1005) insert queryByName remove grantWrite revokeWrite +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xce0a9fb9', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"table_name\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"string\"}],\"name\":\"insert\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xbbec3f91', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"table_name\",\"type\":\"string\"}],\"name\":\"queryByName\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x85d23afc', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"table_name\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xd010d23c', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"contractAddr\",\"type\":\"address\"},{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"grantWrite\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, now(), now()); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xdf12fe78', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"contractAddr\",\"type\":\"address\"},{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"revokeWrite\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, now(), now()); +-- (contract life cycle 0x1007) +-- getStatus unfreeze freeze grantManager queryManager revokeManager +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xbca14431', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x61cb24c3', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"unfreeze\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xf12c66df', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"freeze\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x27c46414', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"contractAddr\",\"type\":\"address\"},{\"name\":\"userAddr\",\"type\":\"address\"}],\"name\":\"grantManager\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xa450e730', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryManager\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x00c77684', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"contractAddr\",\"type\":\"address\"},{\"name\":\"userAddr\",\"type\":\"address\"}],\"name\":\"revokeManager\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, now(), now()); +-- (chain governance 0x1008) +-- listOperators updateCommitteeMemberWeight queryThreshold queryCommitteeMemberWeight grantCommitteeMember +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xb90059a3', 0, '{\"constant\":true,\"inputs\":[],\"name\":\"listOperators\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x95e96f8f', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"},{\"name\":\"weight\",\"type\":\"int256\"}],\"name\":\"updateCommitteeMemberWeight\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x35365efb', 0, '{\"constant\":true,\"inputs\":[],\"name\":\"queryThreshold\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xc784c982', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"queryCommitteeMemberWeight\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"},{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xcbff0346', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"grantCommitteeMember\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +-- unfreezeAccount listCommitteeMembers updateThreshold revokeCommitteeMember grantOperator +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x2312386d', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"account\",\"type\":\"address\"}],\"name\":\"unfreezeAccount\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x77cb0994', 0, '{\"constant\":true,\"inputs\":[],\"name\":\"listCommitteeMembers\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x931af204', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"threshold\",\"type\":\"int256\"}],\"name\":\"updateThreshold\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x681362f3', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"revokeCommitteeMember\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xd1db6540', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"grantOperator\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +-- freezeAccount revokeOperator getAccountStatus +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x563e46a5', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"account\",\"type\":\"address\"}],\"name\":\"freezeAccount\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xc9ab2069', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"revokeOperator\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); +INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xa41e61cc', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); + -- ---------------------------- --- 6、init tb_alert_rule +-- 5、init tb_alert_rule -- ---------------------------- -- add node status alert rule template INSERT INTO `tb_alert_rule`(`rule_name`,`enable`,`alert_type`,`alert_level`,`alert_interval_seconds`,`alert_content`,`content_param_list`,`create_time`,`modify_time`) VALUES ('节点异常告警/Node Exception', 0, 1, 1, 3600, '{nodeId}节点异常,请到“节点管理”页面查看具体信息 / Node: {nodeIdEn} node status exception,please check out in \"Node Management\"', '[\"{nodeId}\", \"{nodeIdEn}\"]', '2019-10-29 20:02:30', '2019-10-29 20:02:30'); @@ -94,19 +132,59 @@ INSERT INTO `tb_alert_rule`(`rule_name`,`enable`,`alert_type`,`alert_level`,`ale -- ---------------------------- --- 7、init tb_mail_server_config +-- 6、init tb_mail_server_config -- ---------------------------- -- add mail_server_config template INSERT INTO `tb_mail_server_config`(`server_name`,`host`,`port`,`username`,`password`,`protocol`,`default_encoding`,`create_time`,`modify_time`,`authentication`,`starttls_enable`,`starttls_required`,`socket_factory_port`,`socket_factory_class`,`socket_factory_fallback`,`enable`) VALUES ('Default config', 'smtp.qq.com', '25', 'yourmail@qq.com', 'yourpassword','smtp', 'UTF-8','2019-10-29 20:02:30', '2019-10-29 20:02:30', 1, 1, 0, 465, 'javax.net.ssl.SSLSocketFactory', 0, 0); -- ---------------------------- --- 8、init tb_config +-- 7、init tb_config -- ---------------------------- INSERT INTO `tb_config`(`config_name`, `config_type`, `config_value`, `create_time`, `modify_time`) VALUES ('docker 镜像版本', 1, 'v2.7.2', '2020-09-22 17:14:23', '2020-09-22 17:14:23'); -- ---------------------------- --- 9、init tb_app_info data (template) +-- 8、init tb_app_info data (template) -- ---------------------------- INSERT INTO `tb_app_info` (`app_name`, `app_key`, `app_type`, `app_doc_link`, `app_icon`, `app_desc`, `app_detail`, `create_time`, `modify_time`) VALUES ('WeId-temp', 'app00001', 1, 'https://weidentity.readthedocs.io/zh_CN/latest/docs/deploy-via-web.html', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFGmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDIgNzkuMTY0MzUyLCAyMDIwLzAxLzMwLTE1OjUwOjM4ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjEtMDMtMThUMTY6NTc6MzQrMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTAzLTE4VDE4OjAyOjAxKzA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIxLTAzLTE4VDE4OjAyOjAxKzA4OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg1NDJjNjJlLTZjYTUtNGI2My05ZDg5LWNhMjVmOTU1NTA4OSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4NTQyYzYyZS02Y2E1LTRiNjMtOWQ4OS1jYTI1Zjk1NTUwODkiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo4NTQyYzYyZS02Y2E1LTRiNjMtOWQ4OS1jYTI1Zjk1NTUwODkiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg1NDJjNjJlLTZjYTUtNGI2My05ZDg5LWNhMjVmOTU1NTA4OSIgc3RFdnQ6d2hlbj0iMjAyMS0wMy0xOFQxNjo1NzozNCswODowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+5hbXdAAADNFJREFUeJzt23msXOV5x/Hf877vWWa/q++177VZvG8EMEUyxXIxFBVaCIEEiFJVCS0ohJRIVGoiHFVKlTZVUUvVqE5omlBQiJIoAYKdpTipgZrGtdsa8IIDxtf7vXPX2c+c8y5P/7gusgWWKs4fVdXzlY5mzoxm5ugz533PnNEMMTOyPnjif3sD/q+XAaYsA0xZBpiyDDBlGWDKMsCUZYApywBTlgGmLANMWQaYsgwwZRlgyjLAlGWAKcsAU5YBpiwDTFkGmLIMMGUZYMoywJRlgCnLAFOWAaYsA0xZBpiyDDBlGWDKMsCUZYApU+ev7BscAACQ4z8E+F6AzmilPu6SxOpaDcrzkKuUoZmhmB8F8NsCOGRIPNBRCtfUa4i6MeoAdpVG8ceb/xxOEPIm7hVSfpcFiuToaXJ4go3F5PFZeJVRRHsfATCO4Vv+7ouyOHiN6UZfJNBB9iUmIwbXE3jVMbjxz8Jf4iCW/gDtX2nArwGiC7SuQLGyFkr8CI2DHoZuvBQQDqSMAsMRsSMSSIwFMcMraIzv+DRs504Az2H4lm1QuQEZcR1e3trG/jY6y0eBmTaw+ygABq68BNiwEDgyDd5937tmF+yB1hoYa0DgO4UQ17E1Vw83Gq7cbCIGYJhhnIXHFkS4WwLXGaI1LBREHAFOgwDUAVzZPI3bT7+Ebq4PQnmXQ4qb4XCd82yv6zEwXgI2ANsWQFchXHV3KILcl9jqD1OCAF0Bqx1AH+AXtJ4AyN3DJF8URI8JcujYGKKwACS9e532tlfWvXZL4cqrkVt3Vwjpf4dZv1gIzSaSOSRQ82j/gy4A7NYaiOtNYuZhQQQnxY8Xx13utxYGQCIEClGMdfVmAUyDICBW8meVdhMDtQYiIgAEB6AD4IGjOzEY94C4uNzBQBkfjcWzL1evOo220nANB4gIhBUIeu4YkMW8YKNnRIiDwjOwksEMwAI2tgAIIIJzDCQO0BrQCRADzoQQ2sBpwoxrgVh/VBLfEDu3uJoEmK2fQnPPX0GwfkSEg7+T739hsR7oR7j2viEVhB9n57Z0Dg9MTbV9GIQAM2AZgJ5fDANCAPZCwAuGMJVKUMxLQHS5cw6WxL+9XanAEj08RFjM1o012W07kMuNMHgRSEBq/VrS6SAI/HUn8+GtfkENsDFvuyj67vJoqrkh2o9dvUvWFNsMp2yjPN73TjhRhq4J5IbsQG5B4faem1cvANorTduHyvceiN55LtZtDX/9J5A30yNcoLJclDvWqqrYJha5nKpgUIxC9cagoqA8tB+cHpOyiNzyYpFjsxC+t5xIwMbRW6xxSSBl0m0cnSi55BvKo58kzdzTaMxWKAhvF6EPFlRruZovOnJJ2KdaRDyIvLK4ZOAoSQaX1RC6yQjnaAbAiXfNzv+R+duVChIpb+pKsZOZoVrt/sT3Nsl8/nlhLAQB2tg+Q1jhS7GHGci12wMNqW4LCoUnnbVwAJQgdEkc2Dg1ufnrC1bPPbjlL7+/KKp9jHz7n2bSbuicaiF3VeXWUPrfccZVWAmwTqBjoHcg/Gp1998+bMPVC3vWfXgbktodQkk4ZU5Ep8r3q1DvVP2dL0tWf+ScDBkSUna7znZ+Fkf0US+f+5Jif6tOOgADJCWk9EFEX+F8cZttNX/BNjluJX0+8MLnXBJf6nQMCAmVF0CizjCZbcKpraTsfqvN9dGcRWEw/yKMu8mS23r62d/7yvsO4csaDZTjeLkmgmT+VRD6GzzPe4a1hiaODAAy5pNerFcRCUjr9rHnXxfkwyfJ6rjjzF01nVwmnP3moDXrX63kH/mzbg3FuVOXE4WgUB7pNM+CKV4f+P4LOtIVSPsZ6Zl1MO7nni9Qn2nt0SOfQmnFzS+5ePYO5+zTJokftW0xWrx8ZruefWdYV80yYzhkE00LW//XpKN9oHSHjeKHda1x1MEend89iJntK4xkX7fTebF1trpWslnh4BY1g6QOVT3I1tQgJEA4biJ+xbjkWWvMUGKTPCs5kUwZzO09nddGbzZkSZE9eNE5cF9/P8bDcJ1nLSxAdeU9AaICrH2Iou5niRnsew+50L+PrYURNNb2vDthGZYxFRCuLyvxB4YxFMQNVPMjG6tbHivnw+IyRgNmRu6Tc7+J4orRx2yspVK8tXus+bXJXdVDELIowBCJ+mWp7N1NHK1gxlGAdoH5EGB2mygInF+5Ex73WMso+rUHB/NTv86gZzk2oL7eNVGl5x9trL9AQgEQY2Da7Ky5Vgj3kpTY7GDgecnhYHzx2NSu226DoINCCQB4HLCbRYKH4WiESEB33ctqMIcFNy1cxQ4+O5oulczrF50DBSAUYSUzwMAKjxkW9KqRcpsiGRDRV8G8FMBSx4ATmBbgZc4BDtBSqt8loGwZdUt0tKTEy4NEqxPIihARuh25p0aSFnp8I6yFFfxUtx5BaN0Hhw0msEYPd06G9dJWxw4A50DeYyBVIbY1js3JwuJSDxu7lo3GlN70HxPxCeRp9hJBEuzweqvuID2+qqwYlvh1BYXW3BxcHqiU+tdar4b2W1ccaO3/Naglb5YYvB6OAZb/LkSMaKgNrzG4WloCkuQN6gIoFZeK+e05XGuEpy+6Bw7U60uYeZWjcxOkc6eDSuUjpUUjoGIxZuZvERgMQFgDUSn/knK5cWEtIOkFS2IJQKGQNBpKcc8sgr+oW3WFhAV0Qa/sa78+eu3PfSBW7ASccZcV1veg78ZFq8HkOfAh7WsLiw5IAsB25/QKa5JhNm4jC3UDEncSjFEhvbkW+2Nt3Q0J+JABo2i6+wbDLnyPN1rrAMHHHFnfy+UXdN7aEcTNqTWsywiHq2/037QDg5t2XgNGhR054VyVWfZSnvIkbczMIBJbWGHYQd8COBD4DTC7iwLGYXgFAyPEgCICCXFvrrd3SrdaqI+Po9vp/L2SCsQASQW0u6+Fid4mPQnB/LnA6O+x0V9W1vyDY/e91VMnSz2ms9pAwlIy1WARVZKlCVjuhyAI8reTVttMh7/OwsHv8FhfdRFEaegbpHyA8WlI+hrDfU746m+I6JPO8HKAwMRnh8XLGFHtjSxCH8ygmeLhAoUIfXGZA8COHmDId6hU+OvCpZsGSQXLWDMczR4JShMQjQXDRBIgJ5wnfgqZO+MdqHyIWvZPAYA8+hMqyBPS8qdkcRitsZ1vntlxPy4K2MyFS8tKtrRSk7FOHmo1W6/OHDuG5pkzcNYgjroHusZ82w+8VqzkW6bZrO6Zq+2dTsxH8ky/6Cp1a+J5X4CjDUlsn/inNVc2m8PBQFgM2iL0fjqRAOPdNjO7e8jxM+SDPd970DM9SwOIVryosKua/AumX3n0QFI9cr3I9X9fsLxBKf9+a9jYKP4xCxcTYSZK3A8n20VoCgaIxGkh5Q87SjerEwnaHbdVenIPQJMCNNM15nnuW1lWfukEg3dOT/DxiagHM36w0zl+iki+CSZBQrzSmWqedNo8T8Jd09L4TBLbx0kQXNJCoW/Vgf7Vd18AeMHHmAO5cOiQoNxGYj3p4jNzESABEOYvEwALwtCLlRgdMKZxtpvM7ACwsVDApWGISjdaSACdEmrSRg2zdfG38Wq4cmFZ/yhMcksnuwvWtkvqOEphDc7zYCbcYOS3QwwfYdFe6XVP3HVGjx9MUP0t9Fx9F4rrHkIyN1ZWoc+1I7NNlRCK6ytFtrpQb4npTgw7UHR54Ym8MKIBQ8lEtQMMFLCoQgHrxGcr2haJ0+QCXwQFZtFmR/FMPg+GQblVR9nLVQwnGvA6IvBBVv8GAzOtBMd9a34/zNHjrAonWiRXkMolc8/c+v4HEb8bVw8D+BiAZh6YPQcHzJ/YWCIUnNOtVndsEMAkgADzwz0hwlDUHScAY6USyAfCsTUA+sYbOAaUh4AR9e4ZEgUSetpOtQstYPkeoDMCvDYCYATAKpBqg9kCQGN+A/i/B0wLQIsIoPnx0wHQYQCCBaQUcILAQAwgnn/752eocwtAgGSGAc/fzairqQ5mKEQSuuJQj/c8GJWK52A9D5DFY93xvZ+on92bwDkAFwF0AAoAYjl/nXBhdA6RiKB5/mBC592XCAE6d50YEF4D0EUAOSCUwPnzr2OQB0BJwFbm3yoP82dO0JhfOf/F6b0b9EE7/zTXMoRwmLttPaJiEaLTTcSe459n5+6xgvu8XPxku3HtUzO7t9eAf37PU6n33PL/LHLzO0K0ZRnQV4SYaSZiz7EfWMfTQqCkPPsTZ4Ia0Pv+j8/+L5yu7AvVlGWAKcsAU5YBpiwDTFkGmLIMMGUZYMoywJRlgCnLAFOWAaYsA0xZBpiyDDBlGWDKMsCUZYApywBTlgGmLANMWQaYsgwwZRlgyjLAlGWAKcsAU5YBpiwDTFkGmLIMMGX/BTNpY2P8E+A7AAAAAElFTkSuQmCC', 'WeIdentity是一套分布式多中心的技术解决方案。', 'WeIdentity目前主要包含两大模块:WeIdentity DID以及WeIdentity Credential。 WeIdentity DID模块在FISCO-BCOS区块链底层平台上实现了一套符合W3C DID规范的分布式多中心的身份标识协议,使实体(人或物)的现实身份实现了链上的身份标识;WeIdentity Credential提供了一整套基于W3C VC规范的解决方案,旨在对这一类数据进行标准化、电子化,生成可验证、可交换的「凭证」(Credential),支持对凭证的属性进行选择性披露,及生成链上存证(Evidence)。', now(), now()); + +-- ---------------------------- +-- 9、init contract warehouse data (tb_ware_house, tb_contract_folder, tb_contract_item) +-- ---------------------------- +-- warehouse +INSERT INTO `tb_ware_house` (`id`, `ware_house_name`, `ware_house_name_en`, `type`, `ware_house_icon`, `description`, `description_en`, `ware_house_detail`, `ware_house_detail_en`, `create_time`, `modify_time`) VALUES (1, '工具箱', 'Toolbox', 1, 'toolboxId', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); +INSERT INTO `tb_ware_house` (`id`, `ware_house_name`, `ware_house_name_en`, `type`, `ware_house_icon`, `description`, `description_en`, `ware_house_detail`, `ware_house_detail_en`, `create_time`, `modify_time`) VALUES (2, '存证应用', 'Evidence', 2, 'evidenceId', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', now(), now()); +INSERT INTO `tb_ware_house` (`id`, `ware_house_name`, `ware_house_name_en`, `type`, `ware_house_icon`, `description`, `description_en`, `ware_house_detail`, `ware_house_detail_en`, `create_time`, `modify_time`) VALUES (3, '积分应用', 'Points', 3, 'pointsId', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); +-- folder +INSERT INTO `tb_contract_folder` (`id`, `ware_house_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (1, 1, 'Tools', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `ware_house_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (2, 2, 'Evidence', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `ware_house_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (3, 3, 'Points', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); +-- contract item of contract source & md desc, including tools, evidence, points(BAC) -- +-- tools -- +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(1, 1, 1, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(2, 1, 1, 'LibString', 'Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgXjAuNC4xMTsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gUmV0dXJucyB0aGUgbWVtb3J5IGFkZHJlc3Mgb2YgdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YKICAgIC8vIGBuZWVkbGVgIGluIGBzZWxmYCwgb3IgdGhlIGZpcnN0IGJ5dGUgYWZ0ZXIgYHNlbGZgIGlmIG5vdCBmb3VuZC4KICAgIGZ1bmN0aW9uIGZpbmRQdHIodWludCBzZWxmbGVuLCB1aW50IHNlbGZwdHIsIHVpbnQgbmVlZGxlbGVuLCB1aW50IG5lZWRsZXB0cikgcHJpdmF0ZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgdWludCBwdHI7CiAgICAgICAgdWludCBpZHg7CgogICAgICAgIGlmIChuZWVkbGVsZW4gPD0gc2VsZmxlbikgewogICAgICAgICAgICBpZiAobmVlZGxlbGVuIDw9IDMyKSB7CiAgICAgICAgICAgICAgICAvLyBPcHRpbWl6ZWQgYXNzZW1ibHkgZm9yIDY4IGdhcyBwZXIgYnl0ZSBvbiBzaG9ydCBzdHJpbmdzCiAgICAgICAgICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IG1hc2sgOj0gbm90KHN1YihleHAoMiwgbXVsKDgsIHN1YigzMiwgbmVlZGxlbGVuKSkpLCAxKSkKICAgICAgICAgICAgICAgICAgICBsZXQgbmVlZGxlZGF0YSA6PSBhbmQobWxvYWQobmVlZGxlcHRyKSwgbWFzaykKICAgICAgICAgICAgICAgICAgICBsZXQgZW5kIDo9IGFkZChzZWxmcHRyLCBzdWIoc2VsZmxlbiwgbmVlZGxlbGVuKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gc2VsZnB0cgogICAgICAgICAgICAgICAgICAgIGxvb3A6CiAgICAgICAgICAgICAgICAgICAganVtcGkoZXhpdCwgZXEoYW5kKG1sb2FkKHB0ciksIG1hc2spLCBuZWVkbGVkYXRhKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHB0ciwgMSkKICAgICAgICAgICAgICAgICAgICBqdW1waShsb29wLCBsdChzdWIocHRyLCAxKSwgZW5kKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHNlbGZwdHIsIHNlbGZsZW4pCiAgICAgICAgICAgICAgICAgICAgZXhpdDoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBGb3IgbG9uZyBuZWVkbGVzLCB1c2UgaGFzaGluZwogICAgICAgICAgICAgICAgYnl0ZXMzMiBoYXNoOwogICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBoYXNoIDo9IHNoYTMobmVlZGxlcHRyLCBuZWVkbGVsZW4pIH0KICAgICAgICAgICAgICAgIHB0ciA9IHNlbGZwdHI7CiAgICAgICAgICAgICAgICBmb3IgKGlkeCA9IDA7IGlkeCA8PSBzZWxmbGVuIC0gbmVlZGxlbGVuOyBpZHgrKykgewogICAgICAgICAgICAgICAgICAgIGJ5dGVzMzIgdGVzdEhhc2g7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibHkgeyB0ZXN0SGFzaCA6PSBzaGEzKHB0ciwgbmVlZGxlbGVuKSB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc2ggPT0gdGVzdEhhc2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgICAgICAgICAgcHRyICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGZwdHIgKyBzZWxmbGVuOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9zdHIpIGludGVybmFsIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY29tcGFyZU5vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBieXRlIGNoMSA9IGJ5dGVzKF9zZWxmKVtpXXwweDIwOwogICAgICAgICAgICBieXRlIGNoMiA9IGJ5dGVzKF9zdHIpW2ldfDB4MjA7CiAgICAgICAgICAgIGlmIChjaDEgPj0gJ2EnICYmIGNoMSA8PSd6JyAmJiBjaDIgPj0gJ2EnICYmIGNoMiA8PSd6JykgewogICAgICAgICAgICAgICAgaWYgKGNoMSA+IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaDEgPCBjaDIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFscyhzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgYnl0ZSBjaDEgPSBieXRlcyhfc2VsZilbaV18MHgyMDsKICAgICAgICAgICAgYnl0ZSBjaDIgPSBieXRlcyhfc3RyKVtpXXwweDIwOwogICAgICAgICAgICBpZiAoY2gxID49ICdhJyAmJiBjaDEgPD0neicgJiYgY2gyID49ICdhJyAmJiBjaDIgPD0neicpIHsKICAgICAgICAgICAgICAgIGlmIChjaDEgIT0gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gc3Vic3RyKHN0cmluZyBfc2VsZiwgdWludCBfc3RhcnQsIHVpbnQgX2xlbikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKF9sZW4pOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK19zdGFydCwgX2xlbik7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIG1lbWNweShyZXRwdHIrYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc3RycHRyLCBieXRlcyhfc3RyKS5sZW5ndGgpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb25jYXQoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cjEsIHN0cmluZyBfc3RyMikKICAgICAgICBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyMSwgc3RyaW5nIF9zdHIyLCBzdHJpbmcgX3N0cjMpCiAgICAgICAgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhieXRlcyhfc2VsZikubGVuZ3RoICsgYnl0ZXMoX3N0cjEpLmxlbmd0aCArIGJ5dGVzKF9zdHIyKS5sZW5ndGgKICAgICAgICAgICAgKyBieXRlcyhfc3RyMykubGVuZ3RoKTsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgc3RyMXB0cjsKICAgICAgICB1aW50IHN0cjJwdHI7CiAgICAgICAgdWludCBzdHIzcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgc3RyM3B0ciA6PSBhZGQoX3N0cjMsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMXB0ciwgYnl0ZXMoX3N0cjEpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIxKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjJwdHIsIGJ5dGVzKF9zdHIyKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIzcHRyLCBieXRlcyhfc3RyMykubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjMpLmxlbmd0aDsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgdWludCBpOwogICAgICAgIHVpbnQ4IGNoOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBjaCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgaT4wOyAtLWkpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaS0xXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IGVuZCA9IGk7CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50MTYgajsKICAgICAgICBib29sIG1hdGNoZWQ7CiAgICAgICAgZm9yIChpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgc3RhcnQgPSBpOwogICAgICAgIAogICAgICAgIGZvciAoaT11aW50MTYoYnl0ZXMoX3NlbGYpLmxlbmd0aCk7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpLTFdID09IGJ5dGVzKF9jaGFycylbal0pIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIW1hdGNoZWQpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHVpbnQxNiBlbmQgPSBpOwoKICAgICAgICBpZiAoZW5kIDw9IHN0YXJ0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfZGVsaW0sIHN0cmluZ1tdIHN0b3JhZ2UgX2FycmF5KSBpbnRlcm5hbCB7CiAgICAgICAgLy9XaHkgY2FuIG5vdCB1c2UgZGVsZXRlIF9hcnJheT8KICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPF9hcnJheS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkZWxldGUgX2FycmF5W2ldOwogICAgICAgIH0KICAgICAgICBfYXJyYXkubGVuZ3RoID0gMDsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgZGVsaW1wdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgZGVsaW1wdHIgOj0gYWRkKF9kZWxpbSwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIHVpbnQgcHRyOwogICAgICAgICAgICBib29sIGZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChieXRlcyhfZGVsaW0pLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfZGVsaW0pLmxlbmd0aCwgZGVsaW1wdHIpIC0gc2VsZnB0cjsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKHB0ciA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHB0ciA9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwdHIgPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IGVsZW0gPSBuZXcgc3RyaW5nKHB0ci1wb3MpOwogICAgICAgICAgICB1aW50IGVsZW1wdHI7CiAgICAgICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgICAgIGVsZW1wdHIgOj0gYWRkKGVsZW0sIDB4MjApCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWVtY3B5KGVsZW1wdHIsIHNlbGZwdHIrcG9zLCBwdHItcG9zKTsKICAgICAgICAgICAgcG9zID0gcHRyICsgYnl0ZXMoX2RlbGltKS5sZW5ndGg7CiAgICAgICAgICAgIF9hcnJheS5wdXNoKGVsZW0pOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCFmb3VuZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc2VsZnB0ciwgYnl0ZXMoX3N0cikubGVuZ3RoLCBzdHJwdHIpIC0gc2VsZnB0cjsKICAgICAgICBpZiAocHRyIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICBfcmV0ID0gaW50KHB0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3JldCA9IC0xOwogICAgICAgIH0KICAgIH0KICAgIAogICAgZnVuY3Rpb24gaW5kZXhPZihzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyLCB1aW50IHBvcykgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfc3RyKS5sZW5ndGgsIHN0cnB0cikgLSBzZWxmcHRyOwogICAgICAgIGlmIChwdHIgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgIF9yZXQgPSBpbnQocHRyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBfcmV0ID0gLTE7CiAgICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0ludChzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGludCBfcmV0KSB7CiAgICAgICAgX3JldCA9IDA7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID09ICcrJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9IGVsc2UgaWYoYnl0ZXMoX3NlbGYpW2ldID09ICctJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQoKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA+PSAweDMwICYmIGRpZ2l0IDw9IDB4MzkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGFkZHJlc3MgX3JldCkgewogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aC1pIDwgMikgewogICAgICAgICAgICByZXR1cm4gYWRkcmVzcygwKTsKICAgICAgICB9CgogICAgICAgIC8vbXVzdCBzdGFydCB3aXRoIDB4CiAgICAgICAgaWYgKCEoYnl0ZXMoX3NlbGYpW2ldID09ICcwJyAmJiBieXRlcyhfc2VsZilbaSsxXXwweDIwID09ICd4JykpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICB1aW50IGFkZHIgPSAwOwogICAgICAgIAogICAgICAgIGZvciAoaSs9MjsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSAvLycwJy0nOScKICAgICAgICAgICAgICAgIGRpZ2l0IC09IDB4MzA7CiAgICAgICAgICAgIGVsc2UgaWYgKGRpZ2l0fDB4MjAgPj0gMHg2MSAmJiBkaWdpdHwweDIwIDw9IDB4NjYpIC8vJ2EnLSdmJwogICAgICAgICAgICAgICAgZGlnaXQgPSBkaWdpdC0weDYxKzEwOwogICAgICAgICAgICBlbHNlIAogICAgICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7IAogICAgICAgICAgICAKICAgICAgICAgICAgYWRkciA9IGFkZHIqMTYrZGlnaXQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBhZGRyZXNzKGFkZHIpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0tleVZhbHVlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9rZXkpLmxlbmd0aCArIDUpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IGtleXB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBrZXlwdHIgOj0gYWRkKF9rZXksIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwoKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIGtleXB0ciwgYnl0ZXMoX2tleSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX2tleSkubGVuZ3RoOwogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICAKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnOic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldFN0cmluZ1ZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc3RhcnQgKz0gMTsKICAgICAgICAKICAgICAgICBpbnQgZW5kOwogICAgICAgIGlmIChkb3VibGVRdW90ZXMpIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHN0YXJ0KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiJyIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVuZCA9PSAtMSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZi5zdWJzdHIodWludChzdGFydCksIHVpbnQoZW5kLXN0YXJ0KSk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldEludFZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdWludCBpID0gdWludChwb3MpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEgCiAgICAgICAgICAgIHx8IGRpZ2l0ID09IDB4M0EgLyo6Ki8gfHwgZGlnaXQgPT0gMHgyMiAvKiIqLyB8fCBkaWdpdCA9PSAweDI3IC8qJyovKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gdG9VcHBlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnYScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICd6JykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldICY9IH4weDIwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZjsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9Mb3dlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnQScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICdaJykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldIHw9IDB4MjA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IF9zZWxmOwogICAgfQoJCiAgICBmdW5jdGlvbiBrZXlFeGlzdHMoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFscyhfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogCiAgICBmdW5jdGlvbiBpbkFycmF5Tm9DYXNlKHN0cmluZyBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHNOb0Nhc2UoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgfQ==', 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(3, 1, 1, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(4, 1, 1, 'Table', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7Cgpjb250cmFjdCBUYWJsZUZhY3RvcnkgewogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoVGFibGUpOyAvL29wZW4gdGFibGUKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOyAvL2NyZWF0ZSB0YWJsZQp9CgovL3NlbGVjdCBjb25kaXRpb24KY29udHJhY3QgQ29uZGl0aW9uIHsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgc3RyaW5nKSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgYWRkcmVzcykgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBpbnQyNTYpIHB1YmxpYyB2aWV3OwogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyB2aWV3OwoKICAgIGZ1bmN0aW9uIEdUKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEdFKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKCiAgICBmdW5jdGlvbiBMVChzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CiAgICBmdW5jdGlvbiBMRShzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gbGltaXQoaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIGxpbWl0KGludDI1NiwgaW50MjU2KSBwdWJsaWMgdmlldzsKfQoKLy9vbmUgcmVjb3JkCmNvbnRyYWN0IEVudHJ5IHsKICAgIGZ1bmN0aW9uIGdldEludChzdHJpbmcpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRVSW50KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRBZGRyZXNzKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcyk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczY0KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMxWzY0XSk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczMyKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMzMik7CiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcpOwoKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcsIGludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgdWludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgc3RyaW5nKSBwdWJsaWM7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBhZGRyZXNzKSBwdWJsaWM7Cn0KCi8vcmVjb3JkIHNldHMKY29udHJhY3QgRW50cmllcyB7CiAgICBmdW5jdGlvbiBnZXQoaW50MjU2KSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBzaXplKCkgcHVibGljIHZpZXcgcmV0dXJucyAoaW50MjU2KTsKfQoKLy9UYWJsZSBtYWluIGNvbnRyYWN0CmNvbnRyYWN0IFRhYmxlIHsKICAgIGZ1bmN0aW9uIHNlbGVjdChzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHZpZXcgcmV0dXJucyAoRW50cmllcyk7CiAgICBmdW5jdGlvbiBpbnNlcnQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiB1cGRhdGUoc3RyaW5nLCBFbnRyeSwgQ29uZGl0aW9uKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KTsKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHJldHVybnMgKGludDI1Nik7CgogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBuZXdDb25kaXRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChDb25kaXRpb24pOwp9Cgpjb250cmFjdCBLVlRhYmxlRmFjdG9yeSB7CiAgICBmdW5jdGlvbiBvcGVuVGFibGUoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChLVlRhYmxlKTsKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOwp9CgovL0tWVGFibGUgcGVyIHBlcm1pYXJ5IGtleSBoYXMgb25seSBvbmUgRW50cnkKY29udHJhY3QgS1ZUYWJsZSB7CiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sLCBFbnRyeSk7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBuZXdFbnRyeSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KTsKfQo=', 'IyB0YWJsZQoKdGFibGUgbGlicmFyeQoKQkNPUyBDUlVEIHVzZXMgdGhlIGJhc2UgbGlicmFyeSwgd2hpY2ggeW91IGNhbiByZWZlcmVuY2UgYnkgcmUtY29udHJhY3QgY2FsbGluZyBDUlVELlRhYmxlIGNvbnRyYWN0IHVzYWdlIG1ldGhvZHMgY2FuIGJlIGRlc2NyaWJlZCBieSByZWZlcnJpbmcgdG8gdGhlIGFzc2F0IGV4YW1wbGUgaW4gdGhlIGJjb3MgZG9jdW1lbnQgaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8u', 'IyB0YWJsZQoKdGFibGUgbGlicmFyeQoKQkNPUyBDUlVEIHVzZXMgdGhlIGJhc2UgbGlicmFyeSwgd2hpY2ggeW91IGNhbiByZWZlcmVuY2UgYnkgcmUtY29udHJhY3QgY2FsbGluZyBDUlVELlRhYmxlIGNvbnRyYWN0IHVzYWdlIG1ldGhvZHMgY2FuIGJlIGRlc2NyaWJlZCBieSByZWZlcnJpbmcgdG8gdGhlIGFzc2F0IGV4YW1wbGUgaW4gdGhlIGJjb3MgZG9jdW1lbnQgaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8u', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(5, 1, 1, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +-- evidence -- +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(6, 2, 2, 'Evidence', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YUFCSXsgZnVuY3Rpb24gdmVyaWZ5KGFkZHJlc3MgYWRkcilwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhib29sKXt9CmZ1bmN0aW9uIGdldFNpZ25lcih1aW50IGluZGV4KXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3Mpe30gCmZ1bmN0aW9uIGdldFNpZ25lcnNTaXplKCkgcHVibGljIGNvbnN0YW50IHJldHVybnModWludCl7fQp9Cgpjb250cmFjdCBFdmlkZW5jZXsKICAgIAogICAgc3RyaW5nIGV2aWRlbmNlOwogICAgc3RyaW5nIGV2aWRlbmNlSW5mbzsKICAgIHN0cmluZyBldmlkZW5jZUlkOwogICAgdWludDhbXSBfdjsKICAgIGJ5dGVzMzJbXSBfcjsKICAgIGJ5dGVzMzJbXSBfczsKICAgIGFkZHJlc3NbXSBzaWduZXJzOwogICAgYWRkcmVzcyBwdWJsaWMgc2lnbmVyc0FkZHI7CiAgICAKICAgICAgICBldmVudCBhZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IG5ld1NpZ25hdHVyZXNFdmVudChzdHJpbmcgZXZpLCBzdHJpbmcgaW5mbywgc3RyaW5nIGlkLCB1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcyxhZGRyZXNzIGFkZHIpOwogICAgICAgIGV2ZW50IGVycm9yTmV3U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLGFkZHJlc3MgYWRkcik7CiAgICAgICAgZXZlbnQgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsYWRkcmVzcyBhZGRyKTsKICAgICAgICBldmVudCBhZGRSZXBlYXRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsIGFkZHJlc3MgYWRkcik7CgogICAgZnVuY3Rpb24gQ2FsbFZlcmlmeShhZGRyZXNzIGFkZHIpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpIHsKICAgICAgICByZXR1cm4gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikudmVyaWZ5KGFkZHIpOwogICAgfQoKICAgICAgIGZ1bmN0aW9uIEV2aWRlbmNlKHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLCBhZGRyZXNzIGFkZHIsIGFkZHJlc3Mgc2VuZGVyKSBwdWJsaWMgewogICAgICAgc2lnbmVyc0FkZHIgPSBhZGRyOwogICAgICAgaWYoQ2FsbFZlcmlmeShzZW5kZXIpKQogICAgICAgewogICAgICAgICAgIGV2aWRlbmNlID0gZXZpOwogICAgICAgICAgIGV2aWRlbmNlSW5mbyA9IGluZm87CiAgICAgICAgICAgZXZpZGVuY2VJZCA9IGlkOwogICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgX3IucHVzaChyKTsKICAgICAgICAgICBfcy5wdXNoKHMpOwogICAgICAgICAgIHNpZ25lcnMucHVzaChzZW5kZXIpOwogICAgICAgICAgIG5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgICAgIGVsc2UKICAgICAgIHsKICAgICAgICAgICBlcnJvck5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgIH0KCiAgICAgICAgZnVuY3Rpb24gZ2V0RXZpZGVuY2VJbmZvKCkgcHVibGljIGNvbnN0YW50IHJldHVybnMoc3RyaW5nKXsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlSW5mbzsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRFdmlkZW5jZSgpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKHN0cmluZyxzdHJpbmcsc3RyaW5nLHVpbnQ4W10sYnl0ZXMzMltdLGJ5dGVzMzJbXSxhZGRyZXNzW10pewogICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICByZXR1cm4oZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsX3YsX3IsX3Msc2lnbmVyTGlzdCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkU2lnbmF0dXJlcyh1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcykgcHVibGljIHJldHVybnMoYm9vbCkgewogICAgICAgIGZvcih1aW50IGk9IDAgO2k8c2lnbmVycy5sZW5ndGggO2krKykKICAgICAgICB7CiAgICAgICAgICAgIGlmKG1zZy5zZW5kZXIgPT0gc2lnbmVyc1tpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoIF92W2ldID09IHYgJiYgX3JbaV0gPT0gciAmJiBfc1tpXSA9PSBzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFkZFJlcGVhdFNpZ25hdHVyZXNFdmVudChldmlkZW5jZSxldmlkZW5jZUluZm8sZXZpZGVuY2VJZCx2LHIscyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgIGlmKENhbGxWZXJpZnkobXNnLnNlbmRlcikpCiAgICAgICB7CiAgICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgIF9yLnB1c2gocik7CiAgICAgICAgICAgIF9zLnB1c2gocyk7CiAgICAgICAgICAgIHNpZ25lcnMucHVzaChtc2cuc2VuZGVyKTsKICAgICAgICAgICAgYWRkU2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSW5mbyxldmlkZW5jZUlkLHYscixzKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICB9CiAgICAgICBlbHNlCiAgICAgICB7CiAgICAgICAgICAgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTaWduZXJzKClwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhhZGRyZXNzW10pCiAgICB7CiAgICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHNpZ25lckxpc3Q7CiAgICB9Cn0=', 'IyBFdmlkZW5jZSDlkIjnuqYKCiMjIOeugOS7iwpFdmlkZW5jZSDnpLrkvovlkIjnuqbvvIzkvb/nlKjliIblsYLnmoTmmbrog73lkIjnuqbnu5PmnoTvvJogCjHvvInlt6XljoLlkIjnuqbvvIhFdmlkZW5jZVNpZ25lcnNEYXRhLnNvbO+8ie+8jOeUseWtmOivgeWQhOaWueS6i+WJjee6puWumu+8jOWtmOWCqOWtmOivgeeUn+aViOadoeS7tu+8jOW5tueuoeeQhuWtmOivgeeahOeUn+aIkOOAgiAgCjLvvInlrZjor4HlkIjnuqbvvIhFdmlkZW5jZS5zb2zvvInvvIznlLHlt6XljoLlkIjnuqbnlJ/miJDvvIzlrZjlgqjlrZjor4FpZO+8jGhhc2jlkozlkITmlrnnrb7lkI3vvIjmr4/lvKDlrZjor4HkuIDkuKrlkIjnuqbvvInjgIIgIA==', '', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(7, 2, 2, 'EvidenceSignersData', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKaW1wb3J0ICJFdmlkZW5jZS5zb2wiOwoKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YXsKICAgICAgICBhZGRyZXNzW10gc2lnbmVyczsKCQlldmVudCBuZXdFdmlkZW5jZUV2ZW50KGFkZHJlc3MgYWRkcik7CiAgICAgICAgZnVuY3Rpb24gbmV3RXZpZGVuY2Uoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sc3RyaW5nIGlkLHVpbnQ4IHYsIGJ5dGVzMzIgcixieXRlczMyIHMpcHVibGljIHJldHVybnMoYWRkcmVzcykKICAgICAgICB7CiAgICAgICAgICAgIEV2aWRlbmNlIGV2aWRlbmNlID0gbmV3IEV2aWRlbmNlKGV2aSwgaW5mbywgaWQsIHYsIHIsIHMsIHRoaXMsIG1zZy5zZW5kZXIpOwogICAgICAgICAgICBuZXdFdmlkZW5jZUV2ZW50KGV2aWRlbmNlKTsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gRXZpZGVuY2VTaWduZXJzRGF0YShhZGRyZXNzW10gZXZpZGVuY2VTaWduZXJzKXB1YmxpY3sKICAgICAgICAgICAgZm9yKHVpbnQgaT0wOyBpPGV2aWRlbmNlU2lnbmVycy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBzaWduZXJzLnB1c2goZXZpZGVuY2VTaWduZXJzW2ldKTsKCQkJfQoJCX0KCiAgICBmdW5jdGlvbiB2ZXJpZnkoYWRkcmVzcyBhZGRyKXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpewogICAgZm9yKHVpbnQgaT0wOyBpPHNpZ25lcnMubGVuZ3RoOyArK2kpIHsKICAgICAgICBpZiAoYWRkciA9PSBzaWduZXJzW2ldKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyKHVpbnQgaW5kZXgpcHVibGljIGNvbnN0YW50IHJldHVybnMoYWRkcmVzcyl7CiAgICAgICAgdWludCBsaXN0U2l6ZSA9IHNpZ25lcnMubGVuZ3RoOwogICAgICAgIGlmKGluZGV4IDwgbGlzdFNpemUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc2lnbmVyc1tpbmRleF07CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyc1NpemUoKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyh1aW50KXsKICAgICAgICByZXR1cm4gc2lnbmVycy5sZW5ndGg7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVycygpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3NbXSl7CiAgICAgICAgcmV0dXJuIHNpZ25lcnM7CiAgICB9Cgp9', 'IyBFdmlkZW5jZSDlkIjnuqYKCiMjIOeugOS7iwpFdmlkZW5jZSDnpLrkvovlkIjnuqbvvIzkvb/nlKjliIblsYLnmoTmmbrog73lkIjnuqbnu5PmnoTvvJogCjHvvInlt6XljoLlkIjnuqbvvIhFdmlkZW5jZVNpZ25lcnNEYXRhLnNvbO+8ie+8jOeUseWtmOivgeWQhOaWueS6i+WJjee6puWumu+8jOWtmOWCqOWtmOivgeeUn+aViOadoeS7tu+8jOW5tueuoeeQhuWtmOivgeeahOeUn+aIkOOAgiAgCjLvvInlrZjor4HlkIjnuqbvvIhFdmlkZW5jZS5zb2zvvInvvIznlLHlt6XljoLlkIjnuqbnlJ/miJDvvIzlrZjlgqjlrZjor4FpZO+8jGhhc2jlkozlkITmlrnnrb7lkI3vvIjmr4/lvKDlrZjor4HkuIDkuKrlkIjnuqbvvInjgIIgIA==', '', now(), now()); +-- bac points -- +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(8, 3, 3, 'BAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgppbXBvcnQgIi4vU2FmZU1hdGguc29sIjsKaW1wb3J0ICIuL1JvbGVzLnNvbCI7CmltcG9ydCAiLi9BZGRyZXNzLnNvbCI7Cgpjb250cmFjdCBJc3N1ZXJSb2xlIHsKICAgIHVzaW5nIFJvbGVzIGZvciBSb2xlcy5Sb2xlOwoKICAgIGV2ZW50IElzc3VlckFkZGVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKICAgIGV2ZW50IElzc3VlclJlbW92ZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwoKICAgIFJvbGVzLlJvbGUgcHJpdmF0ZSBfaXNzdWVyczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX2FkZElzc3Vlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBtb2RpZmllciBvbmx5SXNzdWVyKCkgewogICAgICAgIHJlcXVpcmUoaXNJc3N1ZXIobXNnLnNlbmRlciksICJJc3N1ZXJSb2xlOiBjYWxsZXIgZG9lcyBub3QgaGF2ZSB0aGUgSXNzdWVyIHJvbGUiKTsKICAgICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfaXNzdWVycy5oYXMoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIG9ubHlJc3N1ZXIgewogICAgICAgIF9hZGRJc3N1ZXIoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVub3VuY2VJc3N1ZXIoKSBwdWJsaWMgewogICAgICAgIF9yZW1vdmVJc3N1ZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZElzc3VlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfaXNzdWVycy5hZGQoYWNjb3VudCk7CiAgICAgICAgZW1pdCBJc3N1ZXJBZGRlZChhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcmVtb3ZlSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9pc3N1ZXJzLnJlbW92ZShhY2NvdW50KTsKICAgICAgICBlbWl0IElzc3VlclJlbW92ZWQoYWNjb3VudCk7CiAgICB9Cn0KCmNvbnRyYWN0IFN1c3BlbmRlclJvbGUgewogICAgdXNpbmcgUm9sZXMgZm9yIFJvbGVzLlJvbGU7CgogICAgZXZlbnQgU3VzcGVuZGVyQWRkZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwogICAgZXZlbnQgU3VzcGVuZGVyUmVtb3ZlZChhZGRyZXNzIGluZGV4ZWQgYWNjb3VudCk7CgogICAgUm9sZXMuUm9sZSBwcml2YXRlIF9zdXNwZW5kZXJzOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfYWRkU3VzcGVuZGVyKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIG1vZGlmaWVyIG9ubHlTdXNwZW5kZXIoKSB7CiAgICAgICAgcmVxdWlyZShpc1N1c3BlbmRlcihtc2cuc2VuZGVyKSwgIlN1c3BlbmRlclJvbGU6IGNhbGxlciBkb2VzIG5vdCBoYXZlIHRoZSBTdXNwZW5kZXIgcm9sZSIpOwogICAgICAgIF87CiAgICB9CgogICAgZnVuY3Rpb24gaXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZXJzLmhhcyhhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgb25seVN1c3BlbmRlciB7CiAgICAgICAgX2FkZFN1c3BlbmRlcihhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiByZW5vdW5jZVN1c3BlbmRlcigpIHB1YmxpYyB7CiAgICAgICAgX3JlbW92ZVN1c3BlbmRlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBfYWRkU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9zdXNwZW5kZXJzLmFkZChhY2NvdW50KTsKICAgICAgICBlbWl0IFN1c3BlbmRlckFkZGVkKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9yZW1vdmVTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB7CiAgICAgICAgX3N1c3BlbmRlcnMucmVtb3ZlKGFjY291bnQpOwogICAgICAgIGVtaXQgU3VzcGVuZGVyUmVtb3ZlZChhY2NvdW50KTsKICAgIH0KfQoKY29udHJhY3QgU3VzcGVuZGFibGUgaXMgU3VzcGVuZGVyUm9sZSB7CgogICAgZXZlbnQgU3VzcGVuZGVkKGFkZHJlc3MgYWNjb3VudCk7CiAgICBldmVudCBVblN1c3BlbmRlZChhZGRyZXNzIGFjY291bnQpOwoKICAgIGJvb2wgcHJpdmF0ZSBfc3VzcGVuZGVkOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfc3VzcGVuZGVkID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNvbnRyYWN0IGlzIHN1c3BlbmRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBmdW5jdGlvbiBzdXNwZW5kZWQoKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IE1vZGlmaWVyIHRvIG1ha2UgYSBmdW5jdGlvbiBjYWxsYWJsZSBvbmx5IHdoZW4gdGhlIGNvbnRyYWN0IGlzIG5vdCBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5Ob3RTdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZSghX3N1c3BlbmRlZCwgIlN1c3BlbmRhYmxlOiBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNb2RpZmllciB0byBtYWtlIGEgZnVuY3Rpb24gY2FsbGFibGUgb25seSB3aGVuIHRoZSBjb250cmFjdCBpcyBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5TdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZShfc3VzcGVuZGVkLCAiU3VzcGVuZGFibGU6IG5vdCBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gc3VzcGVuZCwgdHJpZ2dlcnMgc3RvcHBlZCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VzcGVuZCgpIHB1YmxpYyBvbmx5U3VzcGVuZGVyIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zdXNwZW5kZWQgPSB0cnVlOwogICAgICAgIGVtaXQgU3VzcGVuZGVkKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gdW5TdXNwZW5kLCByZXR1cm5zIHRvIG5vcm1hbCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gdW5TdXNwZW5kKCkgcHVibGljIG9ubHlTdXNwZW5kZXIgd2hlblN1c3BlbmRlZCB7CiAgICAgICAgX3N1c3BlbmRlZCA9IGZhbHNlOwogICAgICAgIGVtaXQgVW5TdXNwZW5kZWQobXNnLnNlbmRlcik7CiAgICB9Cn0KCmNvbnRyYWN0IElCQUMwMDFSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBub3RpY2UgSGFuZGxlIHRoZSByZWNlaXB0IG9mIGFuIE5GVAogICAgICogQGRldiBUaGUgQkFDMDAxIHNtYXJ0IGNvbnRyYWN0IGNhbGxzIHRoaXMgZnVuY3Rpb24gb24gdGhlIHJlY2lwaWVudAogICAgICovCiAgICBmdW5jdGlvbiBvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3Mgb3BlcmF0b3IsIGFkZHJlc3MgZnJvbSwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkKICAgIHB1YmxpYyByZXR1cm5zIChieXRlczQpOwp9Cgpjb250cmFjdCBCQUMwMDFIb2xkZXIgaXMgSUJBQzAwMVJlY2VpdmVyIHsKICAgIGZ1bmN0aW9uIG9uQkFDMDAxUmVjZWl2ZWQoYWRkcmVzcywgYWRkcmVzcywgdWludDI1NiwgYnl0ZXMpIHB1YmxpYyByZXR1cm5zIChieXRlczQpIHsKICAgICAgICByZXR1cm4gdGhpcy5vbkJBQzAwMVJlY2VpdmVkLnNlbGVjdG9yOwogICAgfQp9CgoKLyoqCiAqIEB0aXRsZSBTdGFuZGFyZCBCQUMwMDEgYXNzZXQKICovCmNvbnRyYWN0IEJBQzAwMSBpcyBJc3N1ZXJSb2xlLCBTdXNwZW5kYWJsZSB7CiAgICB1c2luZyBTYWZlTWF0aCBmb3IgdWludDI1NjsKICAgIHVzaW5nIEFkZHJlc3MgZm9yIGFkZHJlc3M7CgogICAgbWFwcGluZyhhZGRyZXNzID0+IHVpbnQyNTYpIHByaXZhdGUgX2JhbGFuY2VzOwogICAgbWFwcGluZyhhZGRyZXNzID0+IG1hcHBpbmcoYWRkcmVzcyA9PiB1aW50MjU2KSkgcHJpdmF0ZSBfYWxsb3dlZDsKICAgIHVpbnQyNTYgcHJpdmF0ZSBfdG90YWxBbW91bnQ7CiAgICBzdHJpbmcgcHJpdmF0ZSBfZGVzY3JpcHRpb247CiAgICBzdHJpbmcgcHJpdmF0ZSBfc2hvcnROYW1lOwogICAgdWludDggcHJpdmF0ZSAgX21pblVuaXQ7CgogICAgLy8gRXF1YWxzIHRvIGBieXRlczQoa2VjY2FrMjU2KCJvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3MsYWRkcmVzcyx1aW50MjU2LGJ5dGVzKSIpKWAKICAgIGJ5dGVzNCBwcml2YXRlIGNvbnN0YW50IF9CQUMwMDFfUkVDRUlWRUQgPSAweGM3M2QxNmFlOwoKCiAgICBldmVudCBTZW5kKCBhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKTsKICAgIGV2ZW50IEFwcHJvdmFsKCBhZGRyZXNzIGluZGV4ZWQgb3duZXIsIGFkZHJlc3MgaW5kZXhlZCBzcGVuZGVyLCB1aW50MjU2IHZhbHVlKTsKCgogICAgY29uc3RydWN0b3Ioc3RyaW5nIG1lbW9yeSBkZXNjcmlwdGlvbiwgc3RyaW5nIG1lbW9yeSBzaG9ydE5hbWUsIHVpbnQ4IG1pblVuaXQsIHVpbnQyNTYgdG90YWxBbW91bnQpIHB1YmxpYyB7CiAgICAgICAgX2Rlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgX3Nob3J0TmFtZSA9IHNob3J0TmFtZTsKICAgICAgICBfbWluVW5pdCA9IG1pblVuaXQ7CiAgICAgICAgX2lzc3VlKG1zZy5zZW5kZXIsIHRvdGFsQW1vdW50ICogKDEwICoqIHVpbnQyNTYobWluVW5pdCkpLCAiIik7CiAgICB9CgoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJldHVybiBfdG90YWxBbW91bnQ7CiAgICB9CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9iYWxhbmNlc1tvd25lcl07CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEZ1bmN0aW9uIHRvIGNoZWNrIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFsbG93YW5jZShhZGRyZXNzIG93bmVyLCBhZGRyZXNzIHNwZW5kZXIpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2FsbG93ZWRbb3duZXJdW3NwZW5kZXJdOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zZW5kKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7CgogICAgfQoKLy8gICAgZnVuY3Rpb24gc2FmZVNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewovLyAgICAgICAgc2VuZCh0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgLyoqCiAgICAgKiBAZGV2IEFwcHJvdmUgdGhlIHBhc3NlZCBhZGRyZXNzIHRvIHNwZW5kIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIGFzc2V0cyBvbiBiZWhhbGYgb2YgbXNnLnNlbmRlci4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBfYXBwcm92ZShtc2cuc2VuZGVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlbmQgYXNzZXRzIGZyb20gb25lIGFkZHJlc3MgdG8gYW5vdGhlci4KICAgICAqLwogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgX3NlbmQoZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgICAgICBfYXBwcm92ZShmcm9tLCBtc2cuc2VuZGVyLCBfYWxsb3dlZFtmcm9tXVttc2cuc2VuZGVyXS5zdWIodmFsdWUpKTsKICAgICAgICAvL2FkZAogICAgICAgIHJlcXVpcmUoX2NoZWNrT25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpLCAiQkFDMDAxOiBzZW5kIHRvIG5vbiBCQUMwMDFSZWNlaXZlciBpbXBsZW1lbnRlciIpOwoKCiAgICB9CgovLy8vIHNhZmUgdG9kbwovLyAgICBmdW5jdGlvbiBzYWZlU2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7Ci8vICAgICAgICBzZW5kRnJvbShmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKGZyb20sIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgZnVuY3Rpb24gYmF0Y2hTZW5kKGFkZHJlc3NbXSB0bywgdWludDI1NltdIHZhbHVlcywgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewoKICAgICAgICAvLyBNVVNUIFRocm93IG9uIGVycm9ycwoKICAgICAgICByZXF1aXJlKHRvLmxlbmd0aCA9PSB2YWx1ZXMubGVuZ3RoLCAidG8gYW5kIHZhbHVlcyBhcnJheSBsZW5naHQgbXVzdCBtYXRjaC4iKTsKCiAgICAgICAgZm9yICh1aW50MjU2IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVxdWlyZSh0b1tpXSAhPSBhZGRyZXNzKDB4MCksICJkZXN0aW5hdGlvbiBhZGRyZXNzIG11c3QgYmUgbm9uLXplcm8uIik7CgogICAgICAgICAgICBzZW5kKHRvW2ldLCB2YWx1ZXNbaV0sIGRhdGEpOwogICAgICAgIH0KICAgIH0KCgogICAgZnVuY3Rpb24gX2NoZWNrT25CQUMwMDFSZWNlaXZlZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpCiAgICBpbnRlcm5hbCByZXR1cm5zIChib29sKQogICAgewogICAgICAgIGlmICghdG8uaXNDb250cmFjdCgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgYnl0ZXM0IHJldHZhbCA9IElCQUMwMDFSZWNlaXZlcih0bykub25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwogICAgICAgIHJldHVybiAocmV0dmFsID09IF9CQUMwMDFfUkVDRUlWRUQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbmNyZWFzZSB0aGUgYW1vdW50IG9mIGFzc2V0cyB0aGF0IGFuIG93bmVyIGFsbG93ZWQgdG8gYSBzcGVuZGVyLgogICAgICovCiAgICBmdW5jdGlvbiBpbmNyZWFzZUFsbG93YW5jZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYWRkZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLmFkZChhZGRlZFZhbHVlKSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IERlY3JlYXNlIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKiBhcHByb3ZlIHNob3VsZCBiZSBjYWxsZWQgd2hlbiBfYWxsb3dlZFttc2cuc2VuZGVyXVtzcGVuZGVyXSA9PSAwLiBUbyBkZWNyZW1lbnQKICAgICAqLwogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLnN1YihzdWJ0cmFjdGVkVmFsdWUpKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXN0cm95KHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3kobXNnLnNlbmRlciwgdmFsdWUsIGRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBCdXJucyBhIHNwZWNpZmljIGFtb3VudCBvZiBhc3NldHMgZnJvbSB0aGUgdGFyZ2V0IGFkZHJlc3MgYW5kIGRlY3JlbWVudHMgYWxsb3dhbmNlLgogICAgICovCiAgICBmdW5jdGlvbiBkZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3lGcm9tKGZyb20sIHZhbHVlLCBkYXRhKTsKICAgIH0KCgogICAgZnVuY3Rpb24gZGVzY3JpcHRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIF9kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIHNob3J0TmFtZSBvZiB0aGUgYXNzZXQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNob3J0TmFtZSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX3Nob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBtaW5Vbml0IG9mIHRoZSBhc3NldC4KICAgICAqLwogICAgZnVuY3Rpb24gbWluVW5pdCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQ4KSB7CiAgICAgICAgcmV0dXJuIF9taW5Vbml0OwogICAgfQoKCiAgICBmdW5jdGlvbiBpc3N1ZShhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgb25seUlzc3VlciByZXR1cm5zIChib29sKSB7CiAgICAgICAgX2lzc3VlKHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXYgU2VuZCBhc3NldCBmb3IgYSBzcGVjaWZpZWQgYWRkcmVzc2VzLgogICAgICovCiAgICBmdW5jdGlvbiBfc2VuZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKHRvICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IHNlbmQgdG8gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfYmFsYW5jZXNbZnJvbV0gPSBfYmFsYW5jZXNbZnJvbV0uc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbdG9dID0gX2JhbGFuY2VzW3RvXS5hZGQodmFsdWUpOwogICAgICAgIGVtaXQgU2VuZCggZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCBpc3N1ZXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBhbmQgYXNzaWducyBpdCB0bwogICAgICovCiAgICBmdW5jdGlvbiBfaXNzdWUoYWRkcmVzcyBhY2NvdW50LCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShhY2NvdW50ICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IGlzc3VlIHRvIHRoZSB6ZXJvIGFkZHJlc3MiKTsKCiAgICAgICAgX3RvdGFsQW1vdW50ID0gX3RvdGFsQW1vdW50LmFkZCh2YWx1ZSk7CiAgICAgICAgX2JhbGFuY2VzW2FjY291bnRdID0gX2JhbGFuY2VzW2FjY291bnRdLmFkZCh2YWx1ZSk7CiAgICAgICAgZW1pdCBTZW5kKCBhZGRyZXNzKDApLCBhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95KGFkZHJlc3MgYWNjb3VudCwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiQkFDMDAxOiBkZXN0cm95IGZyb20gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfdG90YWxBbW91bnQgPSBfdG90YWxBbW91bnQuc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbYWNjb3VudF0gPSBfYmFsYW5jZXNbYWNjb3VudF0uc3ViKHZhbHVlKTsKICAgICAgICBlbWl0IFNlbmQoIGFjY291bnQsIGFkZHJlc3MoMCksIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZSBhbiBhZGRyZXNzIHRvIHNwZW5kIGFub3RoZXIgYWRkcmVzc2VzJyBhc3NldHMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hcHByb3ZlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiB2YWx1ZSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUob3duZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSBmcm9tIHRoZSB6ZXJvIGFkZHJlc3MiKTsKICAgICAgICByZXF1aXJlKHNwZW5kZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSB0byB0aGUgemVybyBhZGRyZXNzIik7CgogICAgICAgIF9hbGxvd2VkW293bmVyXVtzcGVuZGVyXSA9IHZhbHVlOwogICAgICAgIGVtaXQgQXBwcm92YWwoIG93bmVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95RnJvbShhZGRyZXNzIGFjY291bnQsIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICBfZGVzdHJveShhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgX2FwcHJvdmUoYWNjb3VudCwgbXNnLnNlbmRlciwgX2FsbG93ZWRbYWNjb3VudF1bbXNnLnNlbmRlcl0uc3ViKHZhbHVlKSk7CiAgICB9Cn0KCg==', 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(9, 3, 3, 'IBAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKaW50ZXJmYWNlIElCQUMwMDEgewoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KTsKCiAgICBmdW5jdGlvbiBzZW5kKGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyA7CgogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gYWxsb3dhbmNlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYW1vdW50KSBwdWJsaWMgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVzdHJveSh1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gZGVzdHJveUZyb20oYWRkcmVzcyBmcm9tLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBmdW5jdGlvbiBiYXRjaFNlbmQoYWRkcmVzc1tdIHRvLCB1aW50MjU2W10gdmFsdWVzLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaW5jcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IGFkZGVkVmFsdWUpIHB1YmxpYyAgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBldmVudCBTZW5kKGFkZHJlc3MgaW5kZXhlZCBmcm9tLCBhZGRyZXNzIGluZGV4ZWQgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpOwoKICAgIGV2ZW50IEFwcHJvdmFsKGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpOwoKfQ==', 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(10, 3, 3, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(11, 3, 3 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(12, 3, 3, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); From 2bc837c6e82fc90eb6201b4fae1a9995c6842663 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Sun, 25 Apr 2021 17:59:27 +0800 Subject: [PATCH 15/92] update code impor --- .../com/webank/webase/node/mgr/scaffold/entity/RspFile.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/entity/RspFile.java b/src/main/java/com/webank/webase/node/mgr/scaffold/entity/RspFile.java index 6b709be1f..3c8aa695e 100644 --- a/src/main/java/com/webank/webase/node/mgr/scaffold/entity/RspFile.java +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/entity/RspFile.java @@ -14,9 +14,6 @@ package com.webank.webase.node.mgr.scaffold.entity; -import com.webank.webase.node.mgr.base.tools.NodeMgrTools; -import java.io.InputStream; -import java.util.Base64; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; From ef8578d0d77e60c9a53f6e23916460a16411152c Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Sun, 25 Apr 2021 18:09:15 +0800 Subject: [PATCH 16/92] fix sql --- script/webase-ddl.sql | 2 +- script/webase-dml.sql | 48 +++++++++++++++++++++---------------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/script/webase-ddl.sql b/script/webase-ddl.sql index 96d8019f3..d8134cff4 100644 --- a/script/webase-ddl.sql +++ b/script/webase-ddl.sql @@ -553,7 +553,7 @@ CREATE TABLE IF NOT EXISTS tb_ware_house ( id int(11) NOT NULL COMMENT '自增编号', ware_house_name varchar(255) binary NOT NULL COMMENT '合约仓库名', ware_house_name_en varchar(255) binary NOT NULL COMMENT '仓库名(英文)', - type int(11) binary NOT NULL COMMENT '仓库类型', + type int(11) NOT NULL COMMENT '仓库类型', ware_house_icon mediumtext COMMENT '仓库图标(Base64)', description mediumtext COMMENT '仓库描述(Base64)', description_en mediumtext COMMENT '仓库描述(英文)(Base64)', diff --git a/script/webase-dml.sql b/script/webase-dml.sql index cc8ea4396..67af4c02a 100644 --- a/script/webase-dml.sql +++ b/script/webase-dml.sql @@ -162,29 +162,29 @@ INSERT INTO `tb_contract_folder` (`id`, `ware_house_id`, `folder_name`, `descrip INSERT INTO `tb_contract_folder` (`id`, `ware_house_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (3, 3, 'Points', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); -- contract item of contract source & md desc, including tools, evidence, points(BAC) -- -- tools -- -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(1, 1, 1, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(2, 1, 1, 'LibString', 'Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgXjAuNC4xMTsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gUmV0dXJucyB0aGUgbWVtb3J5IGFkZHJlc3Mgb2YgdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YKICAgIC8vIGBuZWVkbGVgIGluIGBzZWxmYCwgb3IgdGhlIGZpcnN0IGJ5dGUgYWZ0ZXIgYHNlbGZgIGlmIG5vdCBmb3VuZC4KICAgIGZ1bmN0aW9uIGZpbmRQdHIodWludCBzZWxmbGVuLCB1aW50IHNlbGZwdHIsIHVpbnQgbmVlZGxlbGVuLCB1aW50IG5lZWRsZXB0cikgcHJpdmF0ZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgdWludCBwdHI7CiAgICAgICAgdWludCBpZHg7CgogICAgICAgIGlmIChuZWVkbGVsZW4gPD0gc2VsZmxlbikgewogICAgICAgICAgICBpZiAobmVlZGxlbGVuIDw9IDMyKSB7CiAgICAgICAgICAgICAgICAvLyBPcHRpbWl6ZWQgYXNzZW1ibHkgZm9yIDY4IGdhcyBwZXIgYnl0ZSBvbiBzaG9ydCBzdHJpbmdzCiAgICAgICAgICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IG1hc2sgOj0gbm90KHN1YihleHAoMiwgbXVsKDgsIHN1YigzMiwgbmVlZGxlbGVuKSkpLCAxKSkKICAgICAgICAgICAgICAgICAgICBsZXQgbmVlZGxlZGF0YSA6PSBhbmQobWxvYWQobmVlZGxlcHRyKSwgbWFzaykKICAgICAgICAgICAgICAgICAgICBsZXQgZW5kIDo9IGFkZChzZWxmcHRyLCBzdWIoc2VsZmxlbiwgbmVlZGxlbGVuKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gc2VsZnB0cgogICAgICAgICAgICAgICAgICAgIGxvb3A6CiAgICAgICAgICAgICAgICAgICAganVtcGkoZXhpdCwgZXEoYW5kKG1sb2FkKHB0ciksIG1hc2spLCBuZWVkbGVkYXRhKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHB0ciwgMSkKICAgICAgICAgICAgICAgICAgICBqdW1waShsb29wLCBsdChzdWIocHRyLCAxKSwgZW5kKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHNlbGZwdHIsIHNlbGZsZW4pCiAgICAgICAgICAgICAgICAgICAgZXhpdDoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBGb3IgbG9uZyBuZWVkbGVzLCB1c2UgaGFzaGluZwogICAgICAgICAgICAgICAgYnl0ZXMzMiBoYXNoOwogICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBoYXNoIDo9IHNoYTMobmVlZGxlcHRyLCBuZWVkbGVsZW4pIH0KICAgICAgICAgICAgICAgIHB0ciA9IHNlbGZwdHI7CiAgICAgICAgICAgICAgICBmb3IgKGlkeCA9IDA7IGlkeCA8PSBzZWxmbGVuIC0gbmVlZGxlbGVuOyBpZHgrKykgewogICAgICAgICAgICAgICAgICAgIGJ5dGVzMzIgdGVzdEhhc2g7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibHkgeyB0ZXN0SGFzaCA6PSBzaGEzKHB0ciwgbmVlZGxlbGVuKSB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc2ggPT0gdGVzdEhhc2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgICAgICAgICAgcHRyICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGZwdHIgKyBzZWxmbGVuOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9zdHIpIGludGVybmFsIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY29tcGFyZU5vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBieXRlIGNoMSA9IGJ5dGVzKF9zZWxmKVtpXXwweDIwOwogICAgICAgICAgICBieXRlIGNoMiA9IGJ5dGVzKF9zdHIpW2ldfDB4MjA7CiAgICAgICAgICAgIGlmIChjaDEgPj0gJ2EnICYmIGNoMSA8PSd6JyAmJiBjaDIgPj0gJ2EnICYmIGNoMiA8PSd6JykgewogICAgICAgICAgICAgICAgaWYgKGNoMSA+IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaDEgPCBjaDIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFscyhzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgYnl0ZSBjaDEgPSBieXRlcyhfc2VsZilbaV18MHgyMDsKICAgICAgICAgICAgYnl0ZSBjaDIgPSBieXRlcyhfc3RyKVtpXXwweDIwOwogICAgICAgICAgICBpZiAoY2gxID49ICdhJyAmJiBjaDEgPD0neicgJiYgY2gyID49ICdhJyAmJiBjaDIgPD0neicpIHsKICAgICAgICAgICAgICAgIGlmIChjaDEgIT0gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gc3Vic3RyKHN0cmluZyBfc2VsZiwgdWludCBfc3RhcnQsIHVpbnQgX2xlbikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKF9sZW4pOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK19zdGFydCwgX2xlbik7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIG1lbWNweShyZXRwdHIrYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc3RycHRyLCBieXRlcyhfc3RyKS5sZW5ndGgpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb25jYXQoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cjEsIHN0cmluZyBfc3RyMikKICAgICAgICBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyMSwgc3RyaW5nIF9zdHIyLCBzdHJpbmcgX3N0cjMpCiAgICAgICAgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhieXRlcyhfc2VsZikubGVuZ3RoICsgYnl0ZXMoX3N0cjEpLmxlbmd0aCArIGJ5dGVzKF9zdHIyKS5sZW5ndGgKICAgICAgICAgICAgKyBieXRlcyhfc3RyMykubGVuZ3RoKTsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgc3RyMXB0cjsKICAgICAgICB1aW50IHN0cjJwdHI7CiAgICAgICAgdWludCBzdHIzcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgc3RyM3B0ciA6PSBhZGQoX3N0cjMsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMXB0ciwgYnl0ZXMoX3N0cjEpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIxKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjJwdHIsIGJ5dGVzKF9zdHIyKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIzcHRyLCBieXRlcyhfc3RyMykubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjMpLmxlbmd0aDsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgdWludCBpOwogICAgICAgIHVpbnQ4IGNoOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBjaCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgaT4wOyAtLWkpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaS0xXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IGVuZCA9IGk7CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50MTYgajsKICAgICAgICBib29sIG1hdGNoZWQ7CiAgICAgICAgZm9yIChpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgc3RhcnQgPSBpOwogICAgICAgIAogICAgICAgIGZvciAoaT11aW50MTYoYnl0ZXMoX3NlbGYpLmxlbmd0aCk7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpLTFdID09IGJ5dGVzKF9jaGFycylbal0pIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIW1hdGNoZWQpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHVpbnQxNiBlbmQgPSBpOwoKICAgICAgICBpZiAoZW5kIDw9IHN0YXJ0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfZGVsaW0sIHN0cmluZ1tdIHN0b3JhZ2UgX2FycmF5KSBpbnRlcm5hbCB7CiAgICAgICAgLy9XaHkgY2FuIG5vdCB1c2UgZGVsZXRlIF9hcnJheT8KICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPF9hcnJheS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkZWxldGUgX2FycmF5W2ldOwogICAgICAgIH0KICAgICAgICBfYXJyYXkubGVuZ3RoID0gMDsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgZGVsaW1wdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgZGVsaW1wdHIgOj0gYWRkKF9kZWxpbSwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIHVpbnQgcHRyOwogICAgICAgICAgICBib29sIGZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChieXRlcyhfZGVsaW0pLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfZGVsaW0pLmxlbmd0aCwgZGVsaW1wdHIpIC0gc2VsZnB0cjsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKHB0ciA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHB0ciA9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwdHIgPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IGVsZW0gPSBuZXcgc3RyaW5nKHB0ci1wb3MpOwogICAgICAgICAgICB1aW50IGVsZW1wdHI7CiAgICAgICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgICAgIGVsZW1wdHIgOj0gYWRkKGVsZW0sIDB4MjApCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWVtY3B5KGVsZW1wdHIsIHNlbGZwdHIrcG9zLCBwdHItcG9zKTsKICAgICAgICAgICAgcG9zID0gcHRyICsgYnl0ZXMoX2RlbGltKS5sZW5ndGg7CiAgICAgICAgICAgIF9hcnJheS5wdXNoKGVsZW0pOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCFmb3VuZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc2VsZnB0ciwgYnl0ZXMoX3N0cikubGVuZ3RoLCBzdHJwdHIpIC0gc2VsZnB0cjsKICAgICAgICBpZiAocHRyIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICBfcmV0ID0gaW50KHB0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3JldCA9IC0xOwogICAgICAgIH0KICAgIH0KICAgIAogICAgZnVuY3Rpb24gaW5kZXhPZihzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyLCB1aW50IHBvcykgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfc3RyKS5sZW5ndGgsIHN0cnB0cikgLSBzZWxmcHRyOwogICAgICAgIGlmIChwdHIgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgIF9yZXQgPSBpbnQocHRyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBfcmV0ID0gLTE7CiAgICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0ludChzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGludCBfcmV0KSB7CiAgICAgICAgX3JldCA9IDA7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID09ICcrJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9IGVsc2UgaWYoYnl0ZXMoX3NlbGYpW2ldID09ICctJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQoKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA+PSAweDMwICYmIGRpZ2l0IDw9IDB4MzkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGFkZHJlc3MgX3JldCkgewogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aC1pIDwgMikgewogICAgICAgICAgICByZXR1cm4gYWRkcmVzcygwKTsKICAgICAgICB9CgogICAgICAgIC8vbXVzdCBzdGFydCB3aXRoIDB4CiAgICAgICAgaWYgKCEoYnl0ZXMoX3NlbGYpW2ldID09ICcwJyAmJiBieXRlcyhfc2VsZilbaSsxXXwweDIwID09ICd4JykpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICB1aW50IGFkZHIgPSAwOwogICAgICAgIAogICAgICAgIGZvciAoaSs9MjsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSAvLycwJy0nOScKICAgICAgICAgICAgICAgIGRpZ2l0IC09IDB4MzA7CiAgICAgICAgICAgIGVsc2UgaWYgKGRpZ2l0fDB4MjAgPj0gMHg2MSAmJiBkaWdpdHwweDIwIDw9IDB4NjYpIC8vJ2EnLSdmJwogICAgICAgICAgICAgICAgZGlnaXQgPSBkaWdpdC0weDYxKzEwOwogICAgICAgICAgICBlbHNlIAogICAgICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7IAogICAgICAgICAgICAKICAgICAgICAgICAgYWRkciA9IGFkZHIqMTYrZGlnaXQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBhZGRyZXNzKGFkZHIpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0tleVZhbHVlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9rZXkpLmxlbmd0aCArIDUpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IGtleXB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBrZXlwdHIgOj0gYWRkKF9rZXksIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwoKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIGtleXB0ciwgYnl0ZXMoX2tleSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX2tleSkubGVuZ3RoOwogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICAKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnOic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldFN0cmluZ1ZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc3RhcnQgKz0gMTsKICAgICAgICAKICAgICAgICBpbnQgZW5kOwogICAgICAgIGlmIChkb3VibGVRdW90ZXMpIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHN0YXJ0KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiJyIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVuZCA9PSAtMSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZi5zdWJzdHIodWludChzdGFydCksIHVpbnQoZW5kLXN0YXJ0KSk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldEludFZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdWludCBpID0gdWludChwb3MpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEgCiAgICAgICAgICAgIHx8IGRpZ2l0ID09IDB4M0EgLyo6Ki8gfHwgZGlnaXQgPT0gMHgyMiAvKiIqLyB8fCBkaWdpdCA9PSAweDI3IC8qJyovKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gdG9VcHBlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnYScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICd6JykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldICY9IH4weDIwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZjsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9Mb3dlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnQScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICdaJykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldIHw9IDB4MjA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IF9zZWxmOwogICAgfQoJCiAgICBmdW5jdGlvbiBrZXlFeGlzdHMoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFscyhfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogCiAgICBmdW5jdGlvbiBpbkFycmF5Tm9DYXNlKHN0cmluZyBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHNOb0Nhc2UoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgfQ==', 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(3, 1, 1, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(4, 1, 1, 'Table', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7Cgpjb250cmFjdCBUYWJsZUZhY3RvcnkgewogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoVGFibGUpOyAvL29wZW4gdGFibGUKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOyAvL2NyZWF0ZSB0YWJsZQp9CgovL3NlbGVjdCBjb25kaXRpb24KY29udHJhY3QgQ29uZGl0aW9uIHsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgc3RyaW5nKSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgYWRkcmVzcykgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBpbnQyNTYpIHB1YmxpYyB2aWV3OwogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyB2aWV3OwoKICAgIGZ1bmN0aW9uIEdUKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEdFKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKCiAgICBmdW5jdGlvbiBMVChzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CiAgICBmdW5jdGlvbiBMRShzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gbGltaXQoaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIGxpbWl0KGludDI1NiwgaW50MjU2KSBwdWJsaWMgdmlldzsKfQoKLy9vbmUgcmVjb3JkCmNvbnRyYWN0IEVudHJ5IHsKICAgIGZ1bmN0aW9uIGdldEludChzdHJpbmcpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRVSW50KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRBZGRyZXNzKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcyk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczY0KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMxWzY0XSk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczMyKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMzMik7CiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcpOwoKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcsIGludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgdWludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgc3RyaW5nKSBwdWJsaWM7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBhZGRyZXNzKSBwdWJsaWM7Cn0KCi8vcmVjb3JkIHNldHMKY29udHJhY3QgRW50cmllcyB7CiAgICBmdW5jdGlvbiBnZXQoaW50MjU2KSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBzaXplKCkgcHVibGljIHZpZXcgcmV0dXJucyAoaW50MjU2KTsKfQoKLy9UYWJsZSBtYWluIGNvbnRyYWN0CmNvbnRyYWN0IFRhYmxlIHsKICAgIGZ1bmN0aW9uIHNlbGVjdChzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHZpZXcgcmV0dXJucyAoRW50cmllcyk7CiAgICBmdW5jdGlvbiBpbnNlcnQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiB1cGRhdGUoc3RyaW5nLCBFbnRyeSwgQ29uZGl0aW9uKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KTsKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHJldHVybnMgKGludDI1Nik7CgogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBuZXdDb25kaXRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChDb25kaXRpb24pOwp9Cgpjb250cmFjdCBLVlRhYmxlRmFjdG9yeSB7CiAgICBmdW5jdGlvbiBvcGVuVGFibGUoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChLVlRhYmxlKTsKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOwp9CgovL0tWVGFibGUgcGVyIHBlcm1pYXJ5IGtleSBoYXMgb25seSBvbmUgRW50cnkKY29udHJhY3QgS1ZUYWJsZSB7CiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sLCBFbnRyeSk7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBuZXdFbnRyeSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KTsKfQo=', 'IyB0YWJsZQoKdGFibGUgbGlicmFyeQoKQkNPUyBDUlVEIHVzZXMgdGhlIGJhc2UgbGlicmFyeSwgd2hpY2ggeW91IGNhbiByZWZlcmVuY2UgYnkgcmUtY29udHJhY3QgY2FsbGluZyBDUlVELlRhYmxlIGNvbnRyYWN0IHVzYWdlIG1ldGhvZHMgY2FuIGJlIGRlc2NyaWJlZCBieSByZWZlcnJpbmcgdG8gdGhlIGFzc2F0IGV4YW1wbGUgaW4gdGhlIGJjb3MgZG9jdW1lbnQgaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8u', 'IyB0YWJsZQoKdGFibGUgbGlicmFyeQoKQkNPUyBDUlVEIHVzZXMgdGhlIGJhc2UgbGlicmFyeSwgd2hpY2ggeW91IGNhbiByZWZlcmVuY2UgYnkgcmUtY29udHJhY3QgY2FsbGluZyBDUlVELlRhYmxlIGNvbnRyYWN0IHVzYWdlIG1ldGhvZHMgY2FuIGJlIGRlc2NyaWJlZCBieSByZWZlcnJpbmcgdG8gdGhlIGFzc2F0IGV4YW1wbGUgaW4gdGhlIGJjb3MgZG9jdW1lbnQgaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8u', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(5, 1, 1, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (1, 1, 1, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', + 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (2, 1, 1, 'LibString', 'Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgXjAuNC4xMTsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gUmV0dXJucyB0aGUgbWVtb3J5IGFkZHJlc3Mgb2YgdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YKICAgIC8vIGBuZWVkbGVgIGluIGBzZWxmYCwgb3IgdGhlIGZpcnN0IGJ5dGUgYWZ0ZXIgYHNlbGZgIGlmIG5vdCBmb3VuZC4KICAgIGZ1bmN0aW9uIGZpbmRQdHIodWludCBzZWxmbGVuLCB1aW50IHNlbGZwdHIsIHVpbnQgbmVlZGxlbGVuLCB1aW50IG5lZWRsZXB0cikgcHJpdmF0ZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgdWludCBwdHI7CiAgICAgICAgdWludCBpZHg7CgogICAgICAgIGlmIChuZWVkbGVsZW4gPD0gc2VsZmxlbikgewogICAgICAgICAgICBpZiAobmVlZGxlbGVuIDw9IDMyKSB7CiAgICAgICAgICAgICAgICAvLyBPcHRpbWl6ZWQgYXNzZW1ibHkgZm9yIDY4IGdhcyBwZXIgYnl0ZSBvbiBzaG9ydCBzdHJpbmdzCiAgICAgICAgICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IG1hc2sgOj0gbm90KHN1YihleHAoMiwgbXVsKDgsIHN1YigzMiwgbmVlZGxlbGVuKSkpLCAxKSkKICAgICAgICAgICAgICAgICAgICBsZXQgbmVlZGxlZGF0YSA6PSBhbmQobWxvYWQobmVlZGxlcHRyKSwgbWFzaykKICAgICAgICAgICAgICAgICAgICBsZXQgZW5kIDo9IGFkZChzZWxmcHRyLCBzdWIoc2VsZmxlbiwgbmVlZGxlbGVuKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gc2VsZnB0cgogICAgICAgICAgICAgICAgICAgIGxvb3A6CiAgICAgICAgICAgICAgICAgICAganVtcGkoZXhpdCwgZXEoYW5kKG1sb2FkKHB0ciksIG1hc2spLCBuZWVkbGVkYXRhKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHB0ciwgMSkKICAgICAgICAgICAgICAgICAgICBqdW1waShsb29wLCBsdChzdWIocHRyLCAxKSwgZW5kKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHNlbGZwdHIsIHNlbGZsZW4pCiAgICAgICAgICAgICAgICAgICAgZXhpdDoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBGb3IgbG9uZyBuZWVkbGVzLCB1c2UgaGFzaGluZwogICAgICAgICAgICAgICAgYnl0ZXMzMiBoYXNoOwogICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBoYXNoIDo9IHNoYTMobmVlZGxlcHRyLCBuZWVkbGVsZW4pIH0KICAgICAgICAgICAgICAgIHB0ciA9IHNlbGZwdHI7CiAgICAgICAgICAgICAgICBmb3IgKGlkeCA9IDA7IGlkeCA8PSBzZWxmbGVuIC0gbmVlZGxlbGVuOyBpZHgrKykgewogICAgICAgICAgICAgICAgICAgIGJ5dGVzMzIgdGVzdEhhc2g7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibHkgeyB0ZXN0SGFzaCA6PSBzaGEzKHB0ciwgbmVlZGxlbGVuKSB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc2ggPT0gdGVzdEhhc2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgICAgICAgICAgcHRyICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGZwdHIgKyBzZWxmbGVuOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9zdHIpIGludGVybmFsIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY29tcGFyZU5vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBieXRlIGNoMSA9IGJ5dGVzKF9zZWxmKVtpXXwweDIwOwogICAgICAgICAgICBieXRlIGNoMiA9IGJ5dGVzKF9zdHIpW2ldfDB4MjA7CiAgICAgICAgICAgIGlmIChjaDEgPj0gJ2EnICYmIGNoMSA8PSd6JyAmJiBjaDIgPj0gJ2EnICYmIGNoMiA8PSd6JykgewogICAgICAgICAgICAgICAgaWYgKGNoMSA+IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaDEgPCBjaDIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFscyhzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgYnl0ZSBjaDEgPSBieXRlcyhfc2VsZilbaV18MHgyMDsKICAgICAgICAgICAgYnl0ZSBjaDIgPSBieXRlcyhfc3RyKVtpXXwweDIwOwogICAgICAgICAgICBpZiAoY2gxID49ICdhJyAmJiBjaDEgPD0neicgJiYgY2gyID49ICdhJyAmJiBjaDIgPD0neicpIHsKICAgICAgICAgICAgICAgIGlmIChjaDEgIT0gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gc3Vic3RyKHN0cmluZyBfc2VsZiwgdWludCBfc3RhcnQsIHVpbnQgX2xlbikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKF9sZW4pOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK19zdGFydCwgX2xlbik7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIG1lbWNweShyZXRwdHIrYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc3RycHRyLCBieXRlcyhfc3RyKS5sZW5ndGgpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb25jYXQoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cjEsIHN0cmluZyBfc3RyMikKICAgICAgICBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyMSwgc3RyaW5nIF9zdHIyLCBzdHJpbmcgX3N0cjMpCiAgICAgICAgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhieXRlcyhfc2VsZikubGVuZ3RoICsgYnl0ZXMoX3N0cjEpLmxlbmd0aCArIGJ5dGVzKF9zdHIyKS5sZW5ndGgKICAgICAgICAgICAgKyBieXRlcyhfc3RyMykubGVuZ3RoKTsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgc3RyMXB0cjsKICAgICAgICB1aW50IHN0cjJwdHI7CiAgICAgICAgdWludCBzdHIzcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgc3RyM3B0ciA6PSBhZGQoX3N0cjMsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMXB0ciwgYnl0ZXMoX3N0cjEpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIxKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjJwdHIsIGJ5dGVzKF9zdHIyKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIzcHRyLCBieXRlcyhfc3RyMykubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjMpLmxlbmd0aDsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgdWludCBpOwogICAgICAgIHVpbnQ4IGNoOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBjaCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgaT4wOyAtLWkpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaS0xXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IGVuZCA9IGk7CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50MTYgajsKICAgICAgICBib29sIG1hdGNoZWQ7CiAgICAgICAgZm9yIChpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgc3RhcnQgPSBpOwogICAgICAgIAogICAgICAgIGZvciAoaT11aW50MTYoYnl0ZXMoX3NlbGYpLmxlbmd0aCk7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpLTFdID09IGJ5dGVzKF9jaGFycylbal0pIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIW1hdGNoZWQpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHVpbnQxNiBlbmQgPSBpOwoKICAgICAgICBpZiAoZW5kIDw9IHN0YXJ0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfZGVsaW0sIHN0cmluZ1tdIHN0b3JhZ2UgX2FycmF5KSBpbnRlcm5hbCB7CiAgICAgICAgLy9XaHkgY2FuIG5vdCB1c2UgZGVsZXRlIF9hcnJheT8KICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPF9hcnJheS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkZWxldGUgX2FycmF5W2ldOwogICAgICAgIH0KICAgICAgICBfYXJyYXkubGVuZ3RoID0gMDsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgZGVsaW1wdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgZGVsaW1wdHIgOj0gYWRkKF9kZWxpbSwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIHVpbnQgcHRyOwogICAgICAgICAgICBib29sIGZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChieXRlcyhfZGVsaW0pLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfZGVsaW0pLmxlbmd0aCwgZGVsaW1wdHIpIC0gc2VsZnB0cjsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKHB0ciA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHB0ciA9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwdHIgPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IGVsZW0gPSBuZXcgc3RyaW5nKHB0ci1wb3MpOwogICAgICAgICAgICB1aW50IGVsZW1wdHI7CiAgICAgICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgICAgIGVsZW1wdHIgOj0gYWRkKGVsZW0sIDB4MjApCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWVtY3B5KGVsZW1wdHIsIHNlbGZwdHIrcG9zLCBwdHItcG9zKTsKICAgICAgICAgICAgcG9zID0gcHRyICsgYnl0ZXMoX2RlbGltKS5sZW5ndGg7CiAgICAgICAgICAgIF9hcnJheS5wdXNoKGVsZW0pOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCFmb3VuZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc2VsZnB0ciwgYnl0ZXMoX3N0cikubGVuZ3RoLCBzdHJwdHIpIC0gc2VsZnB0cjsKICAgICAgICBpZiAocHRyIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICBfcmV0ID0gaW50KHB0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3JldCA9IC0xOwogICAgICAgIH0KICAgIH0KICAgIAogICAgZnVuY3Rpb24gaW5kZXhPZihzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyLCB1aW50IHBvcykgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfc3RyKS5sZW5ndGgsIHN0cnB0cikgLSBzZWxmcHRyOwogICAgICAgIGlmIChwdHIgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgIF9yZXQgPSBpbnQocHRyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBfcmV0ID0gLTE7CiAgICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0ludChzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGludCBfcmV0KSB7CiAgICAgICAgX3JldCA9IDA7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID09ICcrJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9IGVsc2UgaWYoYnl0ZXMoX3NlbGYpW2ldID09ICctJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQoKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA+PSAweDMwICYmIGRpZ2l0IDw9IDB4MzkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGFkZHJlc3MgX3JldCkgewogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aC1pIDwgMikgewogICAgICAgICAgICByZXR1cm4gYWRkcmVzcygwKTsKICAgICAgICB9CgogICAgICAgIC8vbXVzdCBzdGFydCB3aXRoIDB4CiAgICAgICAgaWYgKCEoYnl0ZXMoX3NlbGYpW2ldID09ICcwJyAmJiBieXRlcyhfc2VsZilbaSsxXXwweDIwID09ICd4JykpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICB1aW50IGFkZHIgPSAwOwogICAgICAgIAogICAgICAgIGZvciAoaSs9MjsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSAvLycwJy0nOScKICAgICAgICAgICAgICAgIGRpZ2l0IC09IDB4MzA7CiAgICAgICAgICAgIGVsc2UgaWYgKGRpZ2l0fDB4MjAgPj0gMHg2MSAmJiBkaWdpdHwweDIwIDw9IDB4NjYpIC8vJ2EnLSdmJwogICAgICAgICAgICAgICAgZGlnaXQgPSBkaWdpdC0weDYxKzEwOwogICAgICAgICAgICBlbHNlIAogICAgICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7IAogICAgICAgICAgICAKICAgICAgICAgICAgYWRkciA9IGFkZHIqMTYrZGlnaXQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBhZGRyZXNzKGFkZHIpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0tleVZhbHVlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9rZXkpLmxlbmd0aCArIDUpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IGtleXB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBrZXlwdHIgOj0gYWRkKF9rZXksIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwoKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIGtleXB0ciwgYnl0ZXMoX2tleSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX2tleSkubGVuZ3RoOwogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICAKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnOic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldFN0cmluZ1ZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc3RhcnQgKz0gMTsKICAgICAgICAKICAgICAgICBpbnQgZW5kOwogICAgICAgIGlmIChkb3VibGVRdW90ZXMpIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHN0YXJ0KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiJyIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVuZCA9PSAtMSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZi5zdWJzdHIodWludChzdGFydCksIHVpbnQoZW5kLXN0YXJ0KSk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldEludFZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdWludCBpID0gdWludChwb3MpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEgCiAgICAgICAgICAgIHx8IGRpZ2l0ID09IDB4M0EgLyo6Ki8gfHwgZGlnaXQgPT0gMHgyMiAvKiIqLyB8fCBkaWdpdCA9PSAweDI3IC8qJyovKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gdG9VcHBlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnYScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICd6JykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldICY9IH4weDIwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZjsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9Mb3dlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnQScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICdaJykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldIHw9IDB4MjA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IF9zZWxmOwogICAgfQoJCiAgICBmdW5jdGlvbiBrZXlFeGlzdHMoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFscyhfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogCiAgICBmdW5jdGlvbiBpbkFycmF5Tm9DYXNlKHN0cmluZyBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHNOb0Nhc2UoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgfQ==', + 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (3, 1, 1, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', + 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (4, 1, 1, 'Table', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7Cgpjb250cmFjdCBUYWJsZUZhY3RvcnkgewogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoVGFibGUpOyAvL29wZW4gdGFibGUKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOyAvL2NyZWF0ZSB0YWJsZQp9CgovL3NlbGVjdCBjb25kaXRpb24KY29udHJhY3QgQ29uZGl0aW9uIHsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgc3RyaW5nKSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgYWRkcmVzcykgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBpbnQyNTYpIHB1YmxpYyB2aWV3OwogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyB2aWV3OwoKICAgIGZ1bmN0aW9uIEdUKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEdFKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKCiAgICBmdW5jdGlvbiBMVChzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CiAgICBmdW5jdGlvbiBMRShzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gbGltaXQoaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIGxpbWl0KGludDI1NiwgaW50MjU2KSBwdWJsaWMgdmlldzsKfQoKLy9vbmUgcmVjb3JkCmNvbnRyYWN0IEVudHJ5IHsKICAgIGZ1bmN0aW9uIGdldEludChzdHJpbmcpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRVSW50KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRBZGRyZXNzKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcyk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczY0KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMxWzY0XSk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczMyKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMzMik7CiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcpOwoKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcsIGludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgdWludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgc3RyaW5nKSBwdWJsaWM7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBhZGRyZXNzKSBwdWJsaWM7Cn0KCi8vcmVjb3JkIHNldHMKY29udHJhY3QgRW50cmllcyB7CiAgICBmdW5jdGlvbiBnZXQoaW50MjU2KSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBzaXplKCkgcHVibGljIHZpZXcgcmV0dXJucyAoaW50MjU2KTsKfQoKLy9UYWJsZSBtYWluIGNvbnRyYWN0CmNvbnRyYWN0IFRhYmxlIHsKICAgIGZ1bmN0aW9uIHNlbGVjdChzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHZpZXcgcmV0dXJucyAoRW50cmllcyk7CiAgICBmdW5jdGlvbiBpbnNlcnQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiB1cGRhdGUoc3RyaW5nLCBFbnRyeSwgQ29uZGl0aW9uKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KTsKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHJldHVybnMgKGludDI1Nik7CgogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBuZXdDb25kaXRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChDb25kaXRpb24pOwp9Cgpjb250cmFjdCBLVlRhYmxlRmFjdG9yeSB7CiAgICBmdW5jdGlvbiBvcGVuVGFibGUoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChLVlRhYmxlKTsKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOwp9CgovL0tWVGFibGUgcGVyIHBlcm1pYXJ5IGtleSBoYXMgb25seSBvbmUgRW50cnkKY29udHJhY3QgS1ZUYWJsZSB7CiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sLCBFbnRyeSk7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBuZXdFbnRyeSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KTsKfQo=', + 'IyB0YWJsZQoKdGFibGUgbGlicmFyeQoKQkNPUyBDUlVEIHVzZXMgdGhlIGJhc2UgbGlicmFyeSwgd2hpY2ggeW91IGNhbiByZWZlcmVuY2UgYnkgcmUtY29udHJhY3QgY2FsbGluZyBDUlVELlRhYmxlIGNvbnRyYWN0IHVzYWdlIG1ldGhvZHMgY2FuIGJlIGRlc2NyaWJlZCBieSByZWZlcnJpbmcgdG8gdGhlIGFzc2F0IGV4YW1wbGUgaW4gdGhlIGJjb3MgZG9jdW1lbnQgaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8u', 'IyB0YWJsZQoKdGFibGUgbGlicmFyeQoKQkNPUyBDUlVEIHVzZXMgdGhlIGJhc2UgbGlicmFyeSwgd2hpY2ggeW91IGNhbiByZWZlcmVuY2UgYnkgcmUtY29udHJhY3QgY2FsbGluZyBDUlVELlRhYmxlIGNvbnRyYWN0IHVzYWdlIG1ldGhvZHMgY2FuIGJlIGRlc2NyaWJlZCBieSByZWZlcnJpbmcgdG8gdGhlIGFzc2F0IGV4YW1wbGUgaW4gdGhlIGJjb3MgZG9jdW1lbnQgaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8u', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (5, 1, 1, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', + 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); -- evidence -- -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(6, 2, 2, 'Evidence', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YUFCSXsgZnVuY3Rpb24gdmVyaWZ5KGFkZHJlc3MgYWRkcilwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhib29sKXt9CmZ1bmN0aW9uIGdldFNpZ25lcih1aW50IGluZGV4KXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3Mpe30gCmZ1bmN0aW9uIGdldFNpZ25lcnNTaXplKCkgcHVibGljIGNvbnN0YW50IHJldHVybnModWludCl7fQp9Cgpjb250cmFjdCBFdmlkZW5jZXsKICAgIAogICAgc3RyaW5nIGV2aWRlbmNlOwogICAgc3RyaW5nIGV2aWRlbmNlSW5mbzsKICAgIHN0cmluZyBldmlkZW5jZUlkOwogICAgdWludDhbXSBfdjsKICAgIGJ5dGVzMzJbXSBfcjsKICAgIGJ5dGVzMzJbXSBfczsKICAgIGFkZHJlc3NbXSBzaWduZXJzOwogICAgYWRkcmVzcyBwdWJsaWMgc2lnbmVyc0FkZHI7CiAgICAKICAgICAgICBldmVudCBhZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IG5ld1NpZ25hdHVyZXNFdmVudChzdHJpbmcgZXZpLCBzdHJpbmcgaW5mbywgc3RyaW5nIGlkLCB1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcyxhZGRyZXNzIGFkZHIpOwogICAgICAgIGV2ZW50IGVycm9yTmV3U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLGFkZHJlc3MgYWRkcik7CiAgICAgICAgZXZlbnQgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsYWRkcmVzcyBhZGRyKTsKICAgICAgICBldmVudCBhZGRSZXBlYXRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsIGFkZHJlc3MgYWRkcik7CgogICAgZnVuY3Rpb24gQ2FsbFZlcmlmeShhZGRyZXNzIGFkZHIpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpIHsKICAgICAgICByZXR1cm4gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikudmVyaWZ5KGFkZHIpOwogICAgfQoKICAgICAgIGZ1bmN0aW9uIEV2aWRlbmNlKHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLCBhZGRyZXNzIGFkZHIsIGFkZHJlc3Mgc2VuZGVyKSBwdWJsaWMgewogICAgICAgc2lnbmVyc0FkZHIgPSBhZGRyOwogICAgICAgaWYoQ2FsbFZlcmlmeShzZW5kZXIpKQogICAgICAgewogICAgICAgICAgIGV2aWRlbmNlID0gZXZpOwogICAgICAgICAgIGV2aWRlbmNlSW5mbyA9IGluZm87CiAgICAgICAgICAgZXZpZGVuY2VJZCA9IGlkOwogICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgX3IucHVzaChyKTsKICAgICAgICAgICBfcy5wdXNoKHMpOwogICAgICAgICAgIHNpZ25lcnMucHVzaChzZW5kZXIpOwogICAgICAgICAgIG5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgICAgIGVsc2UKICAgICAgIHsKICAgICAgICAgICBlcnJvck5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgIH0KCiAgICAgICAgZnVuY3Rpb24gZ2V0RXZpZGVuY2VJbmZvKCkgcHVibGljIGNvbnN0YW50IHJldHVybnMoc3RyaW5nKXsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlSW5mbzsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRFdmlkZW5jZSgpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKHN0cmluZyxzdHJpbmcsc3RyaW5nLHVpbnQ4W10sYnl0ZXMzMltdLGJ5dGVzMzJbXSxhZGRyZXNzW10pewogICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICByZXR1cm4oZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsX3YsX3IsX3Msc2lnbmVyTGlzdCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkU2lnbmF0dXJlcyh1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcykgcHVibGljIHJldHVybnMoYm9vbCkgewogICAgICAgIGZvcih1aW50IGk9IDAgO2k8c2lnbmVycy5sZW5ndGggO2krKykKICAgICAgICB7CiAgICAgICAgICAgIGlmKG1zZy5zZW5kZXIgPT0gc2lnbmVyc1tpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoIF92W2ldID09IHYgJiYgX3JbaV0gPT0gciAmJiBfc1tpXSA9PSBzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFkZFJlcGVhdFNpZ25hdHVyZXNFdmVudChldmlkZW5jZSxldmlkZW5jZUluZm8sZXZpZGVuY2VJZCx2LHIscyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgIGlmKENhbGxWZXJpZnkobXNnLnNlbmRlcikpCiAgICAgICB7CiAgICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgIF9yLnB1c2gocik7CiAgICAgICAgICAgIF9zLnB1c2gocyk7CiAgICAgICAgICAgIHNpZ25lcnMucHVzaChtc2cuc2VuZGVyKTsKICAgICAgICAgICAgYWRkU2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSW5mbyxldmlkZW5jZUlkLHYscixzKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICB9CiAgICAgICBlbHNlCiAgICAgICB7CiAgICAgICAgICAgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTaWduZXJzKClwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhhZGRyZXNzW10pCiAgICB7CiAgICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHNpZ25lckxpc3Q7CiAgICB9Cn0=', 'IyBFdmlkZW5jZSDlkIjnuqYKCiMjIOeugOS7iwpFdmlkZW5jZSDnpLrkvovlkIjnuqbvvIzkvb/nlKjliIblsYLnmoTmmbrog73lkIjnuqbnu5PmnoTvvJogCjHvvInlt6XljoLlkIjnuqbvvIhFdmlkZW5jZVNpZ25lcnNEYXRhLnNvbO+8ie+8jOeUseWtmOivgeWQhOaWueS6i+WJjee6puWumu+8jOWtmOWCqOWtmOivgeeUn+aViOadoeS7tu+8jOW5tueuoeeQhuWtmOivgeeahOeUn+aIkOOAgiAgCjLvvInlrZjor4HlkIjnuqbvvIhFdmlkZW5jZS5zb2zvvInvvIznlLHlt6XljoLlkIjnuqbnlJ/miJDvvIzlrZjlgqjlrZjor4FpZO+8jGhhc2jlkozlkITmlrnnrb7lkI3vvIjmr4/lvKDlrZjor4HkuIDkuKrlkIjnuqbvvInjgIIgIA==', '', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(7, 2, 2, 'EvidenceSignersData', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKaW1wb3J0ICJFdmlkZW5jZS5zb2wiOwoKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YXsKICAgICAgICBhZGRyZXNzW10gc2lnbmVyczsKCQlldmVudCBuZXdFdmlkZW5jZUV2ZW50KGFkZHJlc3MgYWRkcik7CiAgICAgICAgZnVuY3Rpb24gbmV3RXZpZGVuY2Uoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sc3RyaW5nIGlkLHVpbnQ4IHYsIGJ5dGVzMzIgcixieXRlczMyIHMpcHVibGljIHJldHVybnMoYWRkcmVzcykKICAgICAgICB7CiAgICAgICAgICAgIEV2aWRlbmNlIGV2aWRlbmNlID0gbmV3IEV2aWRlbmNlKGV2aSwgaW5mbywgaWQsIHYsIHIsIHMsIHRoaXMsIG1zZy5zZW5kZXIpOwogICAgICAgICAgICBuZXdFdmlkZW5jZUV2ZW50KGV2aWRlbmNlKTsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gRXZpZGVuY2VTaWduZXJzRGF0YShhZGRyZXNzW10gZXZpZGVuY2VTaWduZXJzKXB1YmxpY3sKICAgICAgICAgICAgZm9yKHVpbnQgaT0wOyBpPGV2aWRlbmNlU2lnbmVycy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBzaWduZXJzLnB1c2goZXZpZGVuY2VTaWduZXJzW2ldKTsKCQkJfQoJCX0KCiAgICBmdW5jdGlvbiB2ZXJpZnkoYWRkcmVzcyBhZGRyKXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpewogICAgZm9yKHVpbnQgaT0wOyBpPHNpZ25lcnMubGVuZ3RoOyArK2kpIHsKICAgICAgICBpZiAoYWRkciA9PSBzaWduZXJzW2ldKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyKHVpbnQgaW5kZXgpcHVibGljIGNvbnN0YW50IHJldHVybnMoYWRkcmVzcyl7CiAgICAgICAgdWludCBsaXN0U2l6ZSA9IHNpZ25lcnMubGVuZ3RoOwogICAgICAgIGlmKGluZGV4IDwgbGlzdFNpemUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc2lnbmVyc1tpbmRleF07CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyc1NpemUoKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyh1aW50KXsKICAgICAgICByZXR1cm4gc2lnbmVycy5sZW5ndGg7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVycygpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3NbXSl7CiAgICAgICAgcmV0dXJuIHNpZ25lcnM7CiAgICB9Cgp9', 'IyBFdmlkZW5jZSDlkIjnuqYKCiMjIOeugOS7iwpFdmlkZW5jZSDnpLrkvovlkIjnuqbvvIzkvb/nlKjliIblsYLnmoTmmbrog73lkIjnuqbnu5PmnoTvvJogCjHvvInlt6XljoLlkIjnuqbvvIhFdmlkZW5jZVNpZ25lcnNEYXRhLnNvbO+8ie+8jOeUseWtmOivgeWQhOaWueS6i+WJjee6puWumu+8jOWtmOWCqOWtmOivgeeUn+aViOadoeS7tu+8jOW5tueuoeeQhuWtmOivgeeahOeUn+aIkOOAgiAgCjLvvInlrZjor4HlkIjnuqbvvIhFdmlkZW5jZS5zb2zvvInvvIznlLHlt6XljoLlkIjnuqbnlJ/miJDvvIzlrZjlgqjlrZjor4FpZO+8jGhhc2jlkozlkITmlrnnrb7lkI3vvIjmr4/lvKDlrZjor4HkuIDkuKrlkIjnuqbvvInjgIIgIA==', '', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (6, 2, 2, 'Evidence', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YUFCSXsgZnVuY3Rpb24gdmVyaWZ5KGFkZHJlc3MgYWRkcilwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhib29sKXt9CmZ1bmN0aW9uIGdldFNpZ25lcih1aW50IGluZGV4KXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3Mpe30gCmZ1bmN0aW9uIGdldFNpZ25lcnNTaXplKCkgcHVibGljIGNvbnN0YW50IHJldHVybnModWludCl7fQp9Cgpjb250cmFjdCBFdmlkZW5jZXsKICAgIAogICAgc3RyaW5nIGV2aWRlbmNlOwogICAgc3RyaW5nIGV2aWRlbmNlSW5mbzsKICAgIHN0cmluZyBldmlkZW5jZUlkOwogICAgdWludDhbXSBfdjsKICAgIGJ5dGVzMzJbXSBfcjsKICAgIGJ5dGVzMzJbXSBfczsKICAgIGFkZHJlc3NbXSBzaWduZXJzOwogICAgYWRkcmVzcyBwdWJsaWMgc2lnbmVyc0FkZHI7CiAgICAKICAgICAgICBldmVudCBhZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IG5ld1NpZ25hdHVyZXNFdmVudChzdHJpbmcgZXZpLCBzdHJpbmcgaW5mbywgc3RyaW5nIGlkLCB1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcyxhZGRyZXNzIGFkZHIpOwogICAgICAgIGV2ZW50IGVycm9yTmV3U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLGFkZHJlc3MgYWRkcik7CiAgICAgICAgZXZlbnQgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsYWRkcmVzcyBhZGRyKTsKICAgICAgICBldmVudCBhZGRSZXBlYXRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsIGFkZHJlc3MgYWRkcik7CgogICAgZnVuY3Rpb24gQ2FsbFZlcmlmeShhZGRyZXNzIGFkZHIpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpIHsKICAgICAgICByZXR1cm4gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikudmVyaWZ5KGFkZHIpOwogICAgfQoKICAgICAgIGZ1bmN0aW9uIEV2aWRlbmNlKHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLCBhZGRyZXNzIGFkZHIsIGFkZHJlc3Mgc2VuZGVyKSBwdWJsaWMgewogICAgICAgc2lnbmVyc0FkZHIgPSBhZGRyOwogICAgICAgaWYoQ2FsbFZlcmlmeShzZW5kZXIpKQogICAgICAgewogICAgICAgICAgIGV2aWRlbmNlID0gZXZpOwogICAgICAgICAgIGV2aWRlbmNlSW5mbyA9IGluZm87CiAgICAgICAgICAgZXZpZGVuY2VJZCA9IGlkOwogICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgX3IucHVzaChyKTsKICAgICAgICAgICBfcy5wdXNoKHMpOwogICAgICAgICAgIHNpZ25lcnMucHVzaChzZW5kZXIpOwogICAgICAgICAgIG5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgICAgIGVsc2UKICAgICAgIHsKICAgICAgICAgICBlcnJvck5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgIH0KCiAgICAgICAgZnVuY3Rpb24gZ2V0RXZpZGVuY2VJbmZvKCkgcHVibGljIGNvbnN0YW50IHJldHVybnMoc3RyaW5nKXsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlSW5mbzsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRFdmlkZW5jZSgpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKHN0cmluZyxzdHJpbmcsc3RyaW5nLHVpbnQ4W10sYnl0ZXMzMltdLGJ5dGVzMzJbXSxhZGRyZXNzW10pewogICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICByZXR1cm4oZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsX3YsX3IsX3Msc2lnbmVyTGlzdCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkU2lnbmF0dXJlcyh1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcykgcHVibGljIHJldHVybnMoYm9vbCkgewogICAgICAgIGZvcih1aW50IGk9IDAgO2k8c2lnbmVycy5sZW5ndGggO2krKykKICAgICAgICB7CiAgICAgICAgICAgIGlmKG1zZy5zZW5kZXIgPT0gc2lnbmVyc1tpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoIF92W2ldID09IHYgJiYgX3JbaV0gPT0gciAmJiBfc1tpXSA9PSBzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFkZFJlcGVhdFNpZ25hdHVyZXNFdmVudChldmlkZW5jZSxldmlkZW5jZUluZm8sZXZpZGVuY2VJZCx2LHIscyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgIGlmKENhbGxWZXJpZnkobXNnLnNlbmRlcikpCiAgICAgICB7CiAgICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgIF9yLnB1c2gocik7CiAgICAgICAgICAgIF9zLnB1c2gocyk7CiAgICAgICAgICAgIHNpZ25lcnMucHVzaChtc2cuc2VuZGVyKTsKICAgICAgICAgICAgYWRkU2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSW5mbyxldmlkZW5jZUlkLHYscixzKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICB9CiAgICAgICBlbHNlCiAgICAgICB7CiAgICAgICAgICAgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTaWduZXJzKClwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhhZGRyZXNzW10pCiAgICB7CiAgICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHNpZ25lckxpc3Q7CiAgICB9Cn0=', + 'IyBFdmlkZW5jZSDlkIjnuqYKCiMjIOeugOS7iwpFdmlkZW5jZSDnpLrkvovlkIjnuqbvvIzkvb/nlKjliIblsYLnmoTmmbrog73lkIjnuqbnu5PmnoTvvJogCjHvvInlt6XljoLlkIjnuqbvvIhFdmlkZW5jZVNpZ25lcnNEYXRhLnNvbO+8ie+8jOeUseWtmOivgeWQhOaWueS6i+WJjee6puWumu+8jOWtmOWCqOWtmOivgeeUn+aViOadoeS7tu+8jOW5tueuoeeQhuWtmOivgeeahOeUn+aIkOOAgiAgCjLvvInlrZjor4HlkIjnuqbvvIhFdmlkZW5jZS5zb2zvvInvvIznlLHlt6XljoLlkIjnuqbnlJ/miJDvvIzlrZjlgqjlrZjor4FpZO+8jGhhc2jlkozlkITmlrnnrb7lkI3vvIjmr4/lvKDlrZjor4HkuIDkuKrlkIjnuqbvvInjgIIgIA==', '', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (7, 2, 2, 'EvidenceSignersData', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKaW1wb3J0ICJFdmlkZW5jZS5zb2wiOwoKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YXsKICAgICAgICBhZGRyZXNzW10gc2lnbmVyczsKCQlldmVudCBuZXdFdmlkZW5jZUV2ZW50KGFkZHJlc3MgYWRkcik7CiAgICAgICAgZnVuY3Rpb24gbmV3RXZpZGVuY2Uoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sc3RyaW5nIGlkLHVpbnQ4IHYsIGJ5dGVzMzIgcixieXRlczMyIHMpcHVibGljIHJldHVybnMoYWRkcmVzcykKICAgICAgICB7CiAgICAgICAgICAgIEV2aWRlbmNlIGV2aWRlbmNlID0gbmV3IEV2aWRlbmNlKGV2aSwgaW5mbywgaWQsIHYsIHIsIHMsIHRoaXMsIG1zZy5zZW5kZXIpOwogICAgICAgICAgICBuZXdFdmlkZW5jZUV2ZW50KGV2aWRlbmNlKTsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gRXZpZGVuY2VTaWduZXJzRGF0YShhZGRyZXNzW10gZXZpZGVuY2VTaWduZXJzKXB1YmxpY3sKICAgICAgICAgICAgZm9yKHVpbnQgaT0wOyBpPGV2aWRlbmNlU2lnbmVycy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBzaWduZXJzLnB1c2goZXZpZGVuY2VTaWduZXJzW2ldKTsKCQkJfQoJCX0KCiAgICBmdW5jdGlvbiB2ZXJpZnkoYWRkcmVzcyBhZGRyKXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpewogICAgZm9yKHVpbnQgaT0wOyBpPHNpZ25lcnMubGVuZ3RoOyArK2kpIHsKICAgICAgICBpZiAoYWRkciA9PSBzaWduZXJzW2ldKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyKHVpbnQgaW5kZXgpcHVibGljIGNvbnN0YW50IHJldHVybnMoYWRkcmVzcyl7CiAgICAgICAgdWludCBsaXN0U2l6ZSA9IHNpZ25lcnMubGVuZ3RoOwogICAgICAgIGlmKGluZGV4IDwgbGlzdFNpemUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc2lnbmVyc1tpbmRleF07CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyc1NpemUoKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyh1aW50KXsKICAgICAgICByZXR1cm4gc2lnbmVycy5sZW5ndGg7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVycygpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3NbXSl7CiAgICAgICAgcmV0dXJuIHNpZ25lcnM7CiAgICB9Cgp9', + 'IyBFdmlkZW5jZSDlkIjnuqYKCiMjIOeugOS7iwpFdmlkZW5jZSDnpLrkvovlkIjnuqbvvIzkvb/nlKjliIblsYLnmoTmmbrog73lkIjnuqbnu5PmnoTvvJogCjHvvInlt6XljoLlkIjnuqbvvIhFdmlkZW5jZVNpZ25lcnNEYXRhLnNvbO+8ie+8jOeUseWtmOivgeWQhOaWueS6i+WJjee6puWumu+8jOWtmOWCqOWtmOivgeeUn+aViOadoeS7tu+8jOW5tueuoeeQhuWtmOivgeeahOeUn+aIkOOAgiAgCjLvvInlrZjor4HlkIjnuqbvvIhFdmlkZW5jZS5zb2zvvInvvIznlLHlt6XljoLlkIjnuqbnlJ/miJDvvIzlrZjlgqjlrZjor4FpZO+8jGhhc2jlkozlkITmlrnnrb7lkI3vvIjmr4/lvKDlrZjor4HkuIDkuKrlkIjnuqbvvInjgIIgIA==', '', now(), now()); -- bac points -- -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(8, 3, 3, 'BAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgppbXBvcnQgIi4vU2FmZU1hdGguc29sIjsKaW1wb3J0ICIuL1JvbGVzLnNvbCI7CmltcG9ydCAiLi9BZGRyZXNzLnNvbCI7Cgpjb250cmFjdCBJc3N1ZXJSb2xlIHsKICAgIHVzaW5nIFJvbGVzIGZvciBSb2xlcy5Sb2xlOwoKICAgIGV2ZW50IElzc3VlckFkZGVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKICAgIGV2ZW50IElzc3VlclJlbW92ZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwoKICAgIFJvbGVzLlJvbGUgcHJpdmF0ZSBfaXNzdWVyczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX2FkZElzc3Vlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBtb2RpZmllciBvbmx5SXNzdWVyKCkgewogICAgICAgIHJlcXVpcmUoaXNJc3N1ZXIobXNnLnNlbmRlciksICJJc3N1ZXJSb2xlOiBjYWxsZXIgZG9lcyBub3QgaGF2ZSB0aGUgSXNzdWVyIHJvbGUiKTsKICAgICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfaXNzdWVycy5oYXMoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIG9ubHlJc3N1ZXIgewogICAgICAgIF9hZGRJc3N1ZXIoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVub3VuY2VJc3N1ZXIoKSBwdWJsaWMgewogICAgICAgIF9yZW1vdmVJc3N1ZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZElzc3VlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfaXNzdWVycy5hZGQoYWNjb3VudCk7CiAgICAgICAgZW1pdCBJc3N1ZXJBZGRlZChhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcmVtb3ZlSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9pc3N1ZXJzLnJlbW92ZShhY2NvdW50KTsKICAgICAgICBlbWl0IElzc3VlclJlbW92ZWQoYWNjb3VudCk7CiAgICB9Cn0KCmNvbnRyYWN0IFN1c3BlbmRlclJvbGUgewogICAgdXNpbmcgUm9sZXMgZm9yIFJvbGVzLlJvbGU7CgogICAgZXZlbnQgU3VzcGVuZGVyQWRkZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwogICAgZXZlbnQgU3VzcGVuZGVyUmVtb3ZlZChhZGRyZXNzIGluZGV4ZWQgYWNjb3VudCk7CgogICAgUm9sZXMuUm9sZSBwcml2YXRlIF9zdXNwZW5kZXJzOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfYWRkU3VzcGVuZGVyKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIG1vZGlmaWVyIG9ubHlTdXNwZW5kZXIoKSB7CiAgICAgICAgcmVxdWlyZShpc1N1c3BlbmRlcihtc2cuc2VuZGVyKSwgIlN1c3BlbmRlclJvbGU6IGNhbGxlciBkb2VzIG5vdCBoYXZlIHRoZSBTdXNwZW5kZXIgcm9sZSIpOwogICAgICAgIF87CiAgICB9CgogICAgZnVuY3Rpb24gaXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZXJzLmhhcyhhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgb25seVN1c3BlbmRlciB7CiAgICAgICAgX2FkZFN1c3BlbmRlcihhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiByZW5vdW5jZVN1c3BlbmRlcigpIHB1YmxpYyB7CiAgICAgICAgX3JlbW92ZVN1c3BlbmRlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBfYWRkU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9zdXNwZW5kZXJzLmFkZChhY2NvdW50KTsKICAgICAgICBlbWl0IFN1c3BlbmRlckFkZGVkKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9yZW1vdmVTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB7CiAgICAgICAgX3N1c3BlbmRlcnMucmVtb3ZlKGFjY291bnQpOwogICAgICAgIGVtaXQgU3VzcGVuZGVyUmVtb3ZlZChhY2NvdW50KTsKICAgIH0KfQoKY29udHJhY3QgU3VzcGVuZGFibGUgaXMgU3VzcGVuZGVyUm9sZSB7CgogICAgZXZlbnQgU3VzcGVuZGVkKGFkZHJlc3MgYWNjb3VudCk7CiAgICBldmVudCBVblN1c3BlbmRlZChhZGRyZXNzIGFjY291bnQpOwoKICAgIGJvb2wgcHJpdmF0ZSBfc3VzcGVuZGVkOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfc3VzcGVuZGVkID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNvbnRyYWN0IGlzIHN1c3BlbmRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBmdW5jdGlvbiBzdXNwZW5kZWQoKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IE1vZGlmaWVyIHRvIG1ha2UgYSBmdW5jdGlvbiBjYWxsYWJsZSBvbmx5IHdoZW4gdGhlIGNvbnRyYWN0IGlzIG5vdCBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5Ob3RTdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZSghX3N1c3BlbmRlZCwgIlN1c3BlbmRhYmxlOiBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNb2RpZmllciB0byBtYWtlIGEgZnVuY3Rpb24gY2FsbGFibGUgb25seSB3aGVuIHRoZSBjb250cmFjdCBpcyBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5TdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZShfc3VzcGVuZGVkLCAiU3VzcGVuZGFibGU6IG5vdCBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gc3VzcGVuZCwgdHJpZ2dlcnMgc3RvcHBlZCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VzcGVuZCgpIHB1YmxpYyBvbmx5U3VzcGVuZGVyIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zdXNwZW5kZWQgPSB0cnVlOwogICAgICAgIGVtaXQgU3VzcGVuZGVkKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gdW5TdXNwZW5kLCByZXR1cm5zIHRvIG5vcm1hbCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gdW5TdXNwZW5kKCkgcHVibGljIG9ubHlTdXNwZW5kZXIgd2hlblN1c3BlbmRlZCB7CiAgICAgICAgX3N1c3BlbmRlZCA9IGZhbHNlOwogICAgICAgIGVtaXQgVW5TdXNwZW5kZWQobXNnLnNlbmRlcik7CiAgICB9Cn0KCmNvbnRyYWN0IElCQUMwMDFSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBub3RpY2UgSGFuZGxlIHRoZSByZWNlaXB0IG9mIGFuIE5GVAogICAgICogQGRldiBUaGUgQkFDMDAxIHNtYXJ0IGNvbnRyYWN0IGNhbGxzIHRoaXMgZnVuY3Rpb24gb24gdGhlIHJlY2lwaWVudAogICAgICovCiAgICBmdW5jdGlvbiBvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3Mgb3BlcmF0b3IsIGFkZHJlc3MgZnJvbSwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkKICAgIHB1YmxpYyByZXR1cm5zIChieXRlczQpOwp9Cgpjb250cmFjdCBCQUMwMDFIb2xkZXIgaXMgSUJBQzAwMVJlY2VpdmVyIHsKICAgIGZ1bmN0aW9uIG9uQkFDMDAxUmVjZWl2ZWQoYWRkcmVzcywgYWRkcmVzcywgdWludDI1NiwgYnl0ZXMpIHB1YmxpYyByZXR1cm5zIChieXRlczQpIHsKICAgICAgICByZXR1cm4gdGhpcy5vbkJBQzAwMVJlY2VpdmVkLnNlbGVjdG9yOwogICAgfQp9CgoKLyoqCiAqIEB0aXRsZSBTdGFuZGFyZCBCQUMwMDEgYXNzZXQKICovCmNvbnRyYWN0IEJBQzAwMSBpcyBJc3N1ZXJSb2xlLCBTdXNwZW5kYWJsZSB7CiAgICB1c2luZyBTYWZlTWF0aCBmb3IgdWludDI1NjsKICAgIHVzaW5nIEFkZHJlc3MgZm9yIGFkZHJlc3M7CgogICAgbWFwcGluZyhhZGRyZXNzID0+IHVpbnQyNTYpIHByaXZhdGUgX2JhbGFuY2VzOwogICAgbWFwcGluZyhhZGRyZXNzID0+IG1hcHBpbmcoYWRkcmVzcyA9PiB1aW50MjU2KSkgcHJpdmF0ZSBfYWxsb3dlZDsKICAgIHVpbnQyNTYgcHJpdmF0ZSBfdG90YWxBbW91bnQ7CiAgICBzdHJpbmcgcHJpdmF0ZSBfZGVzY3JpcHRpb247CiAgICBzdHJpbmcgcHJpdmF0ZSBfc2hvcnROYW1lOwogICAgdWludDggcHJpdmF0ZSAgX21pblVuaXQ7CgogICAgLy8gRXF1YWxzIHRvIGBieXRlczQoa2VjY2FrMjU2KCJvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3MsYWRkcmVzcyx1aW50MjU2LGJ5dGVzKSIpKWAKICAgIGJ5dGVzNCBwcml2YXRlIGNvbnN0YW50IF9CQUMwMDFfUkVDRUlWRUQgPSAweGM3M2QxNmFlOwoKCiAgICBldmVudCBTZW5kKCBhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKTsKICAgIGV2ZW50IEFwcHJvdmFsKCBhZGRyZXNzIGluZGV4ZWQgb3duZXIsIGFkZHJlc3MgaW5kZXhlZCBzcGVuZGVyLCB1aW50MjU2IHZhbHVlKTsKCgogICAgY29uc3RydWN0b3Ioc3RyaW5nIG1lbW9yeSBkZXNjcmlwdGlvbiwgc3RyaW5nIG1lbW9yeSBzaG9ydE5hbWUsIHVpbnQ4IG1pblVuaXQsIHVpbnQyNTYgdG90YWxBbW91bnQpIHB1YmxpYyB7CiAgICAgICAgX2Rlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgX3Nob3J0TmFtZSA9IHNob3J0TmFtZTsKICAgICAgICBfbWluVW5pdCA9IG1pblVuaXQ7CiAgICAgICAgX2lzc3VlKG1zZy5zZW5kZXIsIHRvdGFsQW1vdW50ICogKDEwICoqIHVpbnQyNTYobWluVW5pdCkpLCAiIik7CiAgICB9CgoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJldHVybiBfdG90YWxBbW91bnQ7CiAgICB9CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9iYWxhbmNlc1tvd25lcl07CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEZ1bmN0aW9uIHRvIGNoZWNrIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFsbG93YW5jZShhZGRyZXNzIG93bmVyLCBhZGRyZXNzIHNwZW5kZXIpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2FsbG93ZWRbb3duZXJdW3NwZW5kZXJdOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zZW5kKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7CgogICAgfQoKLy8gICAgZnVuY3Rpb24gc2FmZVNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewovLyAgICAgICAgc2VuZCh0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgLyoqCiAgICAgKiBAZGV2IEFwcHJvdmUgdGhlIHBhc3NlZCBhZGRyZXNzIHRvIHNwZW5kIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIGFzc2V0cyBvbiBiZWhhbGYgb2YgbXNnLnNlbmRlci4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBfYXBwcm92ZShtc2cuc2VuZGVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlbmQgYXNzZXRzIGZyb20gb25lIGFkZHJlc3MgdG8gYW5vdGhlci4KICAgICAqLwogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgX3NlbmQoZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgICAgICBfYXBwcm92ZShmcm9tLCBtc2cuc2VuZGVyLCBfYWxsb3dlZFtmcm9tXVttc2cuc2VuZGVyXS5zdWIodmFsdWUpKTsKICAgICAgICAvL2FkZAogICAgICAgIHJlcXVpcmUoX2NoZWNrT25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpLCAiQkFDMDAxOiBzZW5kIHRvIG5vbiBCQUMwMDFSZWNlaXZlciBpbXBsZW1lbnRlciIpOwoKCiAgICB9CgovLy8vIHNhZmUgdG9kbwovLyAgICBmdW5jdGlvbiBzYWZlU2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7Ci8vICAgICAgICBzZW5kRnJvbShmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKGZyb20sIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgZnVuY3Rpb24gYmF0Y2hTZW5kKGFkZHJlc3NbXSB0bywgdWludDI1NltdIHZhbHVlcywgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewoKICAgICAgICAvLyBNVVNUIFRocm93IG9uIGVycm9ycwoKICAgICAgICByZXF1aXJlKHRvLmxlbmd0aCA9PSB2YWx1ZXMubGVuZ3RoLCAidG8gYW5kIHZhbHVlcyBhcnJheSBsZW5naHQgbXVzdCBtYXRjaC4iKTsKCiAgICAgICAgZm9yICh1aW50MjU2IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVxdWlyZSh0b1tpXSAhPSBhZGRyZXNzKDB4MCksICJkZXN0aW5hdGlvbiBhZGRyZXNzIG11c3QgYmUgbm9uLXplcm8uIik7CgogICAgICAgICAgICBzZW5kKHRvW2ldLCB2YWx1ZXNbaV0sIGRhdGEpOwogICAgICAgIH0KICAgIH0KCgogICAgZnVuY3Rpb24gX2NoZWNrT25CQUMwMDFSZWNlaXZlZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpCiAgICBpbnRlcm5hbCByZXR1cm5zIChib29sKQogICAgewogICAgICAgIGlmICghdG8uaXNDb250cmFjdCgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgYnl0ZXM0IHJldHZhbCA9IElCQUMwMDFSZWNlaXZlcih0bykub25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwogICAgICAgIHJldHVybiAocmV0dmFsID09IF9CQUMwMDFfUkVDRUlWRUQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbmNyZWFzZSB0aGUgYW1vdW50IG9mIGFzc2V0cyB0aGF0IGFuIG93bmVyIGFsbG93ZWQgdG8gYSBzcGVuZGVyLgogICAgICovCiAgICBmdW5jdGlvbiBpbmNyZWFzZUFsbG93YW5jZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYWRkZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLmFkZChhZGRlZFZhbHVlKSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IERlY3JlYXNlIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKiBhcHByb3ZlIHNob3VsZCBiZSBjYWxsZWQgd2hlbiBfYWxsb3dlZFttc2cuc2VuZGVyXVtzcGVuZGVyXSA9PSAwLiBUbyBkZWNyZW1lbnQKICAgICAqLwogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLnN1YihzdWJ0cmFjdGVkVmFsdWUpKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXN0cm95KHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3kobXNnLnNlbmRlciwgdmFsdWUsIGRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBCdXJucyBhIHNwZWNpZmljIGFtb3VudCBvZiBhc3NldHMgZnJvbSB0aGUgdGFyZ2V0IGFkZHJlc3MgYW5kIGRlY3JlbWVudHMgYWxsb3dhbmNlLgogICAgICovCiAgICBmdW5jdGlvbiBkZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3lGcm9tKGZyb20sIHZhbHVlLCBkYXRhKTsKICAgIH0KCgogICAgZnVuY3Rpb24gZGVzY3JpcHRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIF9kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIHNob3J0TmFtZSBvZiB0aGUgYXNzZXQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNob3J0TmFtZSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX3Nob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBtaW5Vbml0IG9mIHRoZSBhc3NldC4KICAgICAqLwogICAgZnVuY3Rpb24gbWluVW5pdCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQ4KSB7CiAgICAgICAgcmV0dXJuIF9taW5Vbml0OwogICAgfQoKCiAgICBmdW5jdGlvbiBpc3N1ZShhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgb25seUlzc3VlciByZXR1cm5zIChib29sKSB7CiAgICAgICAgX2lzc3VlKHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXYgU2VuZCBhc3NldCBmb3IgYSBzcGVjaWZpZWQgYWRkcmVzc2VzLgogICAgICovCiAgICBmdW5jdGlvbiBfc2VuZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKHRvICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IHNlbmQgdG8gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfYmFsYW5jZXNbZnJvbV0gPSBfYmFsYW5jZXNbZnJvbV0uc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbdG9dID0gX2JhbGFuY2VzW3RvXS5hZGQodmFsdWUpOwogICAgICAgIGVtaXQgU2VuZCggZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCBpc3N1ZXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBhbmQgYXNzaWducyBpdCB0bwogICAgICovCiAgICBmdW5jdGlvbiBfaXNzdWUoYWRkcmVzcyBhY2NvdW50LCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShhY2NvdW50ICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IGlzc3VlIHRvIHRoZSB6ZXJvIGFkZHJlc3MiKTsKCiAgICAgICAgX3RvdGFsQW1vdW50ID0gX3RvdGFsQW1vdW50LmFkZCh2YWx1ZSk7CiAgICAgICAgX2JhbGFuY2VzW2FjY291bnRdID0gX2JhbGFuY2VzW2FjY291bnRdLmFkZCh2YWx1ZSk7CiAgICAgICAgZW1pdCBTZW5kKCBhZGRyZXNzKDApLCBhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95KGFkZHJlc3MgYWNjb3VudCwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiQkFDMDAxOiBkZXN0cm95IGZyb20gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfdG90YWxBbW91bnQgPSBfdG90YWxBbW91bnQuc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbYWNjb3VudF0gPSBfYmFsYW5jZXNbYWNjb3VudF0uc3ViKHZhbHVlKTsKICAgICAgICBlbWl0IFNlbmQoIGFjY291bnQsIGFkZHJlc3MoMCksIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZSBhbiBhZGRyZXNzIHRvIHNwZW5kIGFub3RoZXIgYWRkcmVzc2VzJyBhc3NldHMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hcHByb3ZlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiB2YWx1ZSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUob3duZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSBmcm9tIHRoZSB6ZXJvIGFkZHJlc3MiKTsKICAgICAgICByZXF1aXJlKHNwZW5kZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSB0byB0aGUgemVybyBhZGRyZXNzIik7CgogICAgICAgIF9hbGxvd2VkW293bmVyXVtzcGVuZGVyXSA9IHZhbHVlOwogICAgICAgIGVtaXQgQXBwcm92YWwoIG93bmVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95RnJvbShhZGRyZXNzIGFjY291bnQsIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICBfZGVzdHJveShhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgX2FwcHJvdmUoYWNjb3VudCwgbXNnLnNlbmRlciwgX2FsbG93ZWRbYWNjb3VudF1bbXNnLnNlbmRlcl0uc3ViKHZhbHVlKSk7CiAgICB9Cn0KCg==', 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(9, 3, 3, 'IBAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKaW50ZXJmYWNlIElCQUMwMDEgewoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KTsKCiAgICBmdW5jdGlvbiBzZW5kKGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyA7CgogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gYWxsb3dhbmNlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYW1vdW50KSBwdWJsaWMgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVzdHJveSh1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gZGVzdHJveUZyb20oYWRkcmVzcyBmcm9tLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBmdW5jdGlvbiBiYXRjaFNlbmQoYWRkcmVzc1tdIHRvLCB1aW50MjU2W10gdmFsdWVzLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaW5jcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IGFkZGVkVmFsdWUpIHB1YmxpYyAgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBldmVudCBTZW5kKGFkZHJlc3MgaW5kZXhlZCBmcm9tLCBhZGRyZXNzIGluZGV4ZWQgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpOwoKICAgIGV2ZW50IEFwcHJvdmFsKGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpOwoKfQ==', 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(10, 3, 3, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(11, 3, 3 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(12, 3, 3, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (8, 3, 3, 'BAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgppbXBvcnQgIi4vU2FmZU1hdGguc29sIjsKaW1wb3J0ICIuL1JvbGVzLnNvbCI7CmltcG9ydCAiLi9BZGRyZXNzLnNvbCI7Cgpjb250cmFjdCBJc3N1ZXJSb2xlIHsKICAgIHVzaW5nIFJvbGVzIGZvciBSb2xlcy5Sb2xlOwoKICAgIGV2ZW50IElzc3VlckFkZGVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKICAgIGV2ZW50IElzc3VlclJlbW92ZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwoKICAgIFJvbGVzLlJvbGUgcHJpdmF0ZSBfaXNzdWVyczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX2FkZElzc3Vlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBtb2RpZmllciBvbmx5SXNzdWVyKCkgewogICAgICAgIHJlcXVpcmUoaXNJc3N1ZXIobXNnLnNlbmRlciksICJJc3N1ZXJSb2xlOiBjYWxsZXIgZG9lcyBub3QgaGF2ZSB0aGUgSXNzdWVyIHJvbGUiKTsKICAgICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfaXNzdWVycy5oYXMoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIG9ubHlJc3N1ZXIgewogICAgICAgIF9hZGRJc3N1ZXIoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVub3VuY2VJc3N1ZXIoKSBwdWJsaWMgewogICAgICAgIF9yZW1vdmVJc3N1ZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZElzc3VlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfaXNzdWVycy5hZGQoYWNjb3VudCk7CiAgICAgICAgZW1pdCBJc3N1ZXJBZGRlZChhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcmVtb3ZlSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9pc3N1ZXJzLnJlbW92ZShhY2NvdW50KTsKICAgICAgICBlbWl0IElzc3VlclJlbW92ZWQoYWNjb3VudCk7CiAgICB9Cn0KCmNvbnRyYWN0IFN1c3BlbmRlclJvbGUgewogICAgdXNpbmcgUm9sZXMgZm9yIFJvbGVzLlJvbGU7CgogICAgZXZlbnQgU3VzcGVuZGVyQWRkZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwogICAgZXZlbnQgU3VzcGVuZGVyUmVtb3ZlZChhZGRyZXNzIGluZGV4ZWQgYWNjb3VudCk7CgogICAgUm9sZXMuUm9sZSBwcml2YXRlIF9zdXNwZW5kZXJzOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfYWRkU3VzcGVuZGVyKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIG1vZGlmaWVyIG9ubHlTdXNwZW5kZXIoKSB7CiAgICAgICAgcmVxdWlyZShpc1N1c3BlbmRlcihtc2cuc2VuZGVyKSwgIlN1c3BlbmRlclJvbGU6IGNhbGxlciBkb2VzIG5vdCBoYXZlIHRoZSBTdXNwZW5kZXIgcm9sZSIpOwogICAgICAgIF87CiAgICB9CgogICAgZnVuY3Rpb24gaXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZXJzLmhhcyhhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgb25seVN1c3BlbmRlciB7CiAgICAgICAgX2FkZFN1c3BlbmRlcihhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiByZW5vdW5jZVN1c3BlbmRlcigpIHB1YmxpYyB7CiAgICAgICAgX3JlbW92ZVN1c3BlbmRlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBfYWRkU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9zdXNwZW5kZXJzLmFkZChhY2NvdW50KTsKICAgICAgICBlbWl0IFN1c3BlbmRlckFkZGVkKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9yZW1vdmVTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB7CiAgICAgICAgX3N1c3BlbmRlcnMucmVtb3ZlKGFjY291bnQpOwogICAgICAgIGVtaXQgU3VzcGVuZGVyUmVtb3ZlZChhY2NvdW50KTsKICAgIH0KfQoKY29udHJhY3QgU3VzcGVuZGFibGUgaXMgU3VzcGVuZGVyUm9sZSB7CgogICAgZXZlbnQgU3VzcGVuZGVkKGFkZHJlc3MgYWNjb3VudCk7CiAgICBldmVudCBVblN1c3BlbmRlZChhZGRyZXNzIGFjY291bnQpOwoKICAgIGJvb2wgcHJpdmF0ZSBfc3VzcGVuZGVkOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfc3VzcGVuZGVkID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNvbnRyYWN0IGlzIHN1c3BlbmRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBmdW5jdGlvbiBzdXNwZW5kZWQoKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IE1vZGlmaWVyIHRvIG1ha2UgYSBmdW5jdGlvbiBjYWxsYWJsZSBvbmx5IHdoZW4gdGhlIGNvbnRyYWN0IGlzIG5vdCBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5Ob3RTdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZSghX3N1c3BlbmRlZCwgIlN1c3BlbmRhYmxlOiBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNb2RpZmllciB0byBtYWtlIGEgZnVuY3Rpb24gY2FsbGFibGUgb25seSB3aGVuIHRoZSBjb250cmFjdCBpcyBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5TdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZShfc3VzcGVuZGVkLCAiU3VzcGVuZGFibGU6IG5vdCBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gc3VzcGVuZCwgdHJpZ2dlcnMgc3RvcHBlZCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VzcGVuZCgpIHB1YmxpYyBvbmx5U3VzcGVuZGVyIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zdXNwZW5kZWQgPSB0cnVlOwogICAgICAgIGVtaXQgU3VzcGVuZGVkKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gdW5TdXNwZW5kLCByZXR1cm5zIHRvIG5vcm1hbCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gdW5TdXNwZW5kKCkgcHVibGljIG9ubHlTdXNwZW5kZXIgd2hlblN1c3BlbmRlZCB7CiAgICAgICAgX3N1c3BlbmRlZCA9IGZhbHNlOwogICAgICAgIGVtaXQgVW5TdXNwZW5kZWQobXNnLnNlbmRlcik7CiAgICB9Cn0KCmNvbnRyYWN0IElCQUMwMDFSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBub3RpY2UgSGFuZGxlIHRoZSByZWNlaXB0IG9mIGFuIE5GVAogICAgICogQGRldiBUaGUgQkFDMDAxIHNtYXJ0IGNvbnRyYWN0IGNhbGxzIHRoaXMgZnVuY3Rpb24gb24gdGhlIHJlY2lwaWVudAogICAgICovCiAgICBmdW5jdGlvbiBvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3Mgb3BlcmF0b3IsIGFkZHJlc3MgZnJvbSwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkKICAgIHB1YmxpYyByZXR1cm5zIChieXRlczQpOwp9Cgpjb250cmFjdCBCQUMwMDFIb2xkZXIgaXMgSUJBQzAwMVJlY2VpdmVyIHsKICAgIGZ1bmN0aW9uIG9uQkFDMDAxUmVjZWl2ZWQoYWRkcmVzcywgYWRkcmVzcywgdWludDI1NiwgYnl0ZXMpIHB1YmxpYyByZXR1cm5zIChieXRlczQpIHsKICAgICAgICByZXR1cm4gdGhpcy5vbkJBQzAwMVJlY2VpdmVkLnNlbGVjdG9yOwogICAgfQp9CgoKLyoqCiAqIEB0aXRsZSBTdGFuZGFyZCBCQUMwMDEgYXNzZXQKICovCmNvbnRyYWN0IEJBQzAwMSBpcyBJc3N1ZXJSb2xlLCBTdXNwZW5kYWJsZSB7CiAgICB1c2luZyBTYWZlTWF0aCBmb3IgdWludDI1NjsKICAgIHVzaW5nIEFkZHJlc3MgZm9yIGFkZHJlc3M7CgogICAgbWFwcGluZyhhZGRyZXNzID0+IHVpbnQyNTYpIHByaXZhdGUgX2JhbGFuY2VzOwogICAgbWFwcGluZyhhZGRyZXNzID0+IG1hcHBpbmcoYWRkcmVzcyA9PiB1aW50MjU2KSkgcHJpdmF0ZSBfYWxsb3dlZDsKICAgIHVpbnQyNTYgcHJpdmF0ZSBfdG90YWxBbW91bnQ7CiAgICBzdHJpbmcgcHJpdmF0ZSBfZGVzY3JpcHRpb247CiAgICBzdHJpbmcgcHJpdmF0ZSBfc2hvcnROYW1lOwogICAgdWludDggcHJpdmF0ZSAgX21pblVuaXQ7CgogICAgLy8gRXF1YWxzIHRvIGBieXRlczQoa2VjY2FrMjU2KCJvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3MsYWRkcmVzcyx1aW50MjU2LGJ5dGVzKSIpKWAKICAgIGJ5dGVzNCBwcml2YXRlIGNvbnN0YW50IF9CQUMwMDFfUkVDRUlWRUQgPSAweGM3M2QxNmFlOwoKCiAgICBldmVudCBTZW5kKCBhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKTsKICAgIGV2ZW50IEFwcHJvdmFsKCBhZGRyZXNzIGluZGV4ZWQgb3duZXIsIGFkZHJlc3MgaW5kZXhlZCBzcGVuZGVyLCB1aW50MjU2IHZhbHVlKTsKCgogICAgY29uc3RydWN0b3Ioc3RyaW5nIG1lbW9yeSBkZXNjcmlwdGlvbiwgc3RyaW5nIG1lbW9yeSBzaG9ydE5hbWUsIHVpbnQ4IG1pblVuaXQsIHVpbnQyNTYgdG90YWxBbW91bnQpIHB1YmxpYyB7CiAgICAgICAgX2Rlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgX3Nob3J0TmFtZSA9IHNob3J0TmFtZTsKICAgICAgICBfbWluVW5pdCA9IG1pblVuaXQ7CiAgICAgICAgX2lzc3VlKG1zZy5zZW5kZXIsIHRvdGFsQW1vdW50ICogKDEwICoqIHVpbnQyNTYobWluVW5pdCkpLCAiIik7CiAgICB9CgoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJldHVybiBfdG90YWxBbW91bnQ7CiAgICB9CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9iYWxhbmNlc1tvd25lcl07CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEZ1bmN0aW9uIHRvIGNoZWNrIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFsbG93YW5jZShhZGRyZXNzIG93bmVyLCBhZGRyZXNzIHNwZW5kZXIpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2FsbG93ZWRbb3duZXJdW3NwZW5kZXJdOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zZW5kKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7CgogICAgfQoKLy8gICAgZnVuY3Rpb24gc2FmZVNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewovLyAgICAgICAgc2VuZCh0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgLyoqCiAgICAgKiBAZGV2IEFwcHJvdmUgdGhlIHBhc3NlZCBhZGRyZXNzIHRvIHNwZW5kIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIGFzc2V0cyBvbiBiZWhhbGYgb2YgbXNnLnNlbmRlci4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBfYXBwcm92ZShtc2cuc2VuZGVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlbmQgYXNzZXRzIGZyb20gb25lIGFkZHJlc3MgdG8gYW5vdGhlci4KICAgICAqLwogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgX3NlbmQoZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgICAgICBfYXBwcm92ZShmcm9tLCBtc2cuc2VuZGVyLCBfYWxsb3dlZFtmcm9tXVttc2cuc2VuZGVyXS5zdWIodmFsdWUpKTsKICAgICAgICAvL2FkZAogICAgICAgIHJlcXVpcmUoX2NoZWNrT25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpLCAiQkFDMDAxOiBzZW5kIHRvIG5vbiBCQUMwMDFSZWNlaXZlciBpbXBsZW1lbnRlciIpOwoKCiAgICB9CgovLy8vIHNhZmUgdG9kbwovLyAgICBmdW5jdGlvbiBzYWZlU2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7Ci8vICAgICAgICBzZW5kRnJvbShmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKGZyb20sIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgZnVuY3Rpb24gYmF0Y2hTZW5kKGFkZHJlc3NbXSB0bywgdWludDI1NltdIHZhbHVlcywgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewoKICAgICAgICAvLyBNVVNUIFRocm93IG9uIGVycm9ycwoKICAgICAgICByZXF1aXJlKHRvLmxlbmd0aCA9PSB2YWx1ZXMubGVuZ3RoLCAidG8gYW5kIHZhbHVlcyBhcnJheSBsZW5naHQgbXVzdCBtYXRjaC4iKTsKCiAgICAgICAgZm9yICh1aW50MjU2IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVxdWlyZSh0b1tpXSAhPSBhZGRyZXNzKDB4MCksICJkZXN0aW5hdGlvbiBhZGRyZXNzIG11c3QgYmUgbm9uLXplcm8uIik7CgogICAgICAgICAgICBzZW5kKHRvW2ldLCB2YWx1ZXNbaV0sIGRhdGEpOwogICAgICAgIH0KICAgIH0KCgogICAgZnVuY3Rpb24gX2NoZWNrT25CQUMwMDFSZWNlaXZlZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpCiAgICBpbnRlcm5hbCByZXR1cm5zIChib29sKQogICAgewogICAgICAgIGlmICghdG8uaXNDb250cmFjdCgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgYnl0ZXM0IHJldHZhbCA9IElCQUMwMDFSZWNlaXZlcih0bykub25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwogICAgICAgIHJldHVybiAocmV0dmFsID09IF9CQUMwMDFfUkVDRUlWRUQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbmNyZWFzZSB0aGUgYW1vdW50IG9mIGFzc2V0cyB0aGF0IGFuIG93bmVyIGFsbG93ZWQgdG8gYSBzcGVuZGVyLgogICAgICovCiAgICBmdW5jdGlvbiBpbmNyZWFzZUFsbG93YW5jZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYWRkZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLmFkZChhZGRlZFZhbHVlKSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IERlY3JlYXNlIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKiBhcHByb3ZlIHNob3VsZCBiZSBjYWxsZWQgd2hlbiBfYWxsb3dlZFttc2cuc2VuZGVyXVtzcGVuZGVyXSA9PSAwLiBUbyBkZWNyZW1lbnQKICAgICAqLwogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLnN1YihzdWJ0cmFjdGVkVmFsdWUpKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXN0cm95KHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3kobXNnLnNlbmRlciwgdmFsdWUsIGRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBCdXJucyBhIHNwZWNpZmljIGFtb3VudCBvZiBhc3NldHMgZnJvbSB0aGUgdGFyZ2V0IGFkZHJlc3MgYW5kIGRlY3JlbWVudHMgYWxsb3dhbmNlLgogICAgICovCiAgICBmdW5jdGlvbiBkZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3lGcm9tKGZyb20sIHZhbHVlLCBkYXRhKTsKICAgIH0KCgogICAgZnVuY3Rpb24gZGVzY3JpcHRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIF9kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIHNob3J0TmFtZSBvZiB0aGUgYXNzZXQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNob3J0TmFtZSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX3Nob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBtaW5Vbml0IG9mIHRoZSBhc3NldC4KICAgICAqLwogICAgZnVuY3Rpb24gbWluVW5pdCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQ4KSB7CiAgICAgICAgcmV0dXJuIF9taW5Vbml0OwogICAgfQoKCiAgICBmdW5jdGlvbiBpc3N1ZShhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgb25seUlzc3VlciByZXR1cm5zIChib29sKSB7CiAgICAgICAgX2lzc3VlKHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXYgU2VuZCBhc3NldCBmb3IgYSBzcGVjaWZpZWQgYWRkcmVzc2VzLgogICAgICovCiAgICBmdW5jdGlvbiBfc2VuZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKHRvICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IHNlbmQgdG8gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfYmFsYW5jZXNbZnJvbV0gPSBfYmFsYW5jZXNbZnJvbV0uc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbdG9dID0gX2JhbGFuY2VzW3RvXS5hZGQodmFsdWUpOwogICAgICAgIGVtaXQgU2VuZCggZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCBpc3N1ZXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBhbmQgYXNzaWducyBpdCB0bwogICAgICovCiAgICBmdW5jdGlvbiBfaXNzdWUoYWRkcmVzcyBhY2NvdW50LCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShhY2NvdW50ICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IGlzc3VlIHRvIHRoZSB6ZXJvIGFkZHJlc3MiKTsKCiAgICAgICAgX3RvdGFsQW1vdW50ID0gX3RvdGFsQW1vdW50LmFkZCh2YWx1ZSk7CiAgICAgICAgX2JhbGFuY2VzW2FjY291bnRdID0gX2JhbGFuY2VzW2FjY291bnRdLmFkZCh2YWx1ZSk7CiAgICAgICAgZW1pdCBTZW5kKCBhZGRyZXNzKDApLCBhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95KGFkZHJlc3MgYWNjb3VudCwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiQkFDMDAxOiBkZXN0cm95IGZyb20gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfdG90YWxBbW91bnQgPSBfdG90YWxBbW91bnQuc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbYWNjb3VudF0gPSBfYmFsYW5jZXNbYWNjb3VudF0uc3ViKHZhbHVlKTsKICAgICAgICBlbWl0IFNlbmQoIGFjY291bnQsIGFkZHJlc3MoMCksIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZSBhbiBhZGRyZXNzIHRvIHNwZW5kIGFub3RoZXIgYWRkcmVzc2VzJyBhc3NldHMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hcHByb3ZlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiB2YWx1ZSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUob3duZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSBmcm9tIHRoZSB6ZXJvIGFkZHJlc3MiKTsKICAgICAgICByZXF1aXJlKHNwZW5kZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSB0byB0aGUgemVybyBhZGRyZXNzIik7CgogICAgICAgIF9hbGxvd2VkW293bmVyXVtzcGVuZGVyXSA9IHZhbHVlOwogICAgICAgIGVtaXQgQXBwcm92YWwoIG93bmVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95RnJvbShhZGRyZXNzIGFjY291bnQsIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICBfZGVzdHJveShhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgX2FwcHJvdmUoYWNjb3VudCwgbXNnLnNlbmRlciwgX2FsbG93ZWRbYWNjb3VudF1bbXNnLnNlbmRlcl0uc3ViKHZhbHVlKSk7CiAgICB9Cn0KCg==', + 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (9, 3, 3, 'IBAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKaW50ZXJmYWNlIElCQUMwMDEgewoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KTsKCiAgICBmdW5jdGlvbiBzZW5kKGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyA7CgogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gYWxsb3dhbmNlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYW1vdW50KSBwdWJsaWMgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVzdHJveSh1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gZGVzdHJveUZyb20oYWRkcmVzcyBmcm9tLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBmdW5jdGlvbiBiYXRjaFNlbmQoYWRkcmVzc1tdIHRvLCB1aW50MjU2W10gdmFsdWVzLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaW5jcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IGFkZGVkVmFsdWUpIHB1YmxpYyAgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBldmVudCBTZW5kKGFkZHJlc3MgaW5kZXhlZCBmcm9tLCBhZGRyZXNzIGluZGV4ZWQgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpOwoKICAgIGV2ZW50IEFwcHJvdmFsKGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpOwoKfQ==', + 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (10, 3, 3, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', + 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (11, 3, 3 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', + 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (12, 3, 3, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', + 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); From 6eae9e64799b3138d9204f8136109849bdcc95dc Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Sun, 25 Apr 2021 18:17:06 +0800 Subject: [PATCH 17/92] fix sql final --- script/webase-dml.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/webase-dml.sql b/script/webase-dml.sql index 67af4c02a..7428d046c 100644 --- a/script/webase-dml.sql +++ b/script/webase-dml.sql @@ -184,7 +184,7 @@ INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `co 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (10, 3, 3, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (11, 3, 3 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', +INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (11, 3, 3, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (12, 3, 3, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); From 27609b6435b81a6dac8521da0e5df4ebfb1f3974 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Mon, 26 Apr 2021 10:12:35 +0800 Subject: [PATCH 18/92] update warehouse url & name --- .../warehouse/WareHouseController.java | 21 +-- .../contract/warehouse/WareHouseService.java | 17 +-- .../warehouse/entity/TbContractFolder.java | 7 +- .../warehouse/entity/TbContractItem.java | 7 +- .../{TbWareHouse.java => TbWarehouse.java} | 44 ++++--- .../mapper/TbContractFolderMapper.java | 52 ++------ .../mapper/TbContractFolderSqlProvider.java | 32 +---- .../mapper/TbContractItemMapper.java | 53 ++------ .../mapper/TbContractItemSqlProvider.java | 32 +---- .../warehouse/mapper/TbWareHouseMapper.java | 106 --------------- .../mapper/TbWareHouseSqlProvider.java | 122 ------------------ .../warehouse/mapper/TbWarehouseMapper.java | 69 ++++++++++ .../mapper/TbWarehouseSqlProvider.java | 103 +++++++++++++++ 13 files changed, 258 insertions(+), 407 deletions(-) rename src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/{TbWareHouse.java => TbWarehouse.java} (56%) delete mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseMapper.java delete mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseSqlProvider.java create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWarehouseMapper.java create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWarehouseSqlProvider.java diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseController.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseController.java index f1279775d..b876bea8a 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseController.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseController.java @@ -18,7 +18,7 @@ import com.webank.webase.node.mgr.base.entity.BaseResponse; import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractFolder; import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractItem; -import com.webank.webase.node.mgr.contract.warehouse.entity.TbWareHouse; +import com.webank.webase.node.mgr.contract.warehouse.entity.TbWarehouse; import java.util.List; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -30,10 +30,11 @@ /** * ContractStoreController. + * @author marsli */ @Slf4j @RestController -@RequestMapping(value = "/contractStore") +@RequestMapping(value = "/warehouse") public class WareHouseController extends BaseController { @Autowired @@ -42,10 +43,10 @@ public class WareHouseController extends BaseController { /** * query the list of contract store item */ - @GetMapping(value = "/getContractStoreList") + @GetMapping(value = "/list") public BaseResponse getContractStoreList() { - List storeItemList = wareHouseService.getStoreList(); + List storeItemList = wareHouseService.getStoreList(); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(storeItemList); return response; @@ -54,10 +55,10 @@ public BaseResponse getContractStoreList() { /** * query a contract store item */ - @GetMapping(value = "/getContractStoreById/{storeId}") + @GetMapping(value = "/{storeId}") public BaseResponse getContractStoreById(@PathVariable("storeId") Integer storeId) { log.info("getContractStoreById start. storeId:{}", storeId); - TbWareHouse storeItem = wareHouseService.getStoreItemById(storeId); + TbWarehouse storeItem = wareHouseService.getStoreItemById(storeId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(storeItem); return response; @@ -66,7 +67,7 @@ public BaseResponse getContractStoreById(@PathVariable("storeId") Integer storeI /** * query a contract folder item */ - @GetMapping(value = "/getContractFolderById/{contractFolderId}") + @GetMapping(value = "/folder/{contractFolderId}") public BaseResponse getContractFolderById(@PathVariable("contractFolderId") Integer contractFolderId) { log.info("getContractStoreById start. contractFolderId:{}", contractFolderId); TbContractFolder contractFolderItem = wareHouseService.getContractFolderById(contractFolderId); @@ -78,7 +79,7 @@ public BaseResponse getContractFolderById(@PathVariable("contractFolderId") Inte /** * query a contract item */ - @GetMapping(value = "/getContractItemById/{contractId}") + @GetMapping(value = "/item/{contractId}") public BaseResponse getContractItemById(@PathVariable("contractId") Integer contractId) { log.info("getContractStoreById start. contractId:{}", contractId); TbContractItem contractItem = wareHouseService.getContractItemById(contractId); @@ -90,7 +91,7 @@ public BaseResponse getContractItemById(@PathVariable("contractId") Integer cont /** * get folderItemList by storeId */ - @GetMapping(value = "/getFolderItemListByStoreId/{storeId}") + @GetMapping(value = "/folder/list/{storeId}") public BaseResponse getFolderItemListByStoreId(@PathVariable("storeId") Integer storeId) { log.info("getFolderItemListByStoreId start. storeId:{}", storeId); List contractFolderItemList = wareHouseService.getFolderItemListByStoreId(storeId); @@ -102,7 +103,7 @@ public BaseResponse getFolderItemListByStoreId(@PathVariable("storeId") Integer /** * get contractItemList by folderId */ - @GetMapping(value = "/getContractItemByFolderId/{folderId}") + @GetMapping(value = "/item/list/{folderId}") public BaseResponse getContractItemByFolderId(@PathVariable("folderId") Integer folderId) { log.info("getContractItemByFolderId start. storeId:{}", folderId); List contractItemList = wareHouseService.getContractItemByFolderId(folderId); diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseService.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseService.java index 04903c5cc..1813191f9 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseService.java @@ -15,17 +15,18 @@ import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractFolder; import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractItem; -import com.webank.webase.node.mgr.contract.warehouse.entity.TbWareHouse; +import com.webank.webase.node.mgr.contract.warehouse.entity.TbWarehouse; import com.webank.webase.node.mgr.contract.warehouse.mapper.TbContractFolderMapper; import com.webank.webase.node.mgr.contract.warehouse.mapper.TbContractItemMapper; -import com.webank.webase.node.mgr.contract.warehouse.mapper.TbWareHouseMapper; +import com.webank.webase.node.mgr.contract.warehouse.mapper.TbWarehouseMapper; import java.util.List; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** - * + * contract warehouse service + * include warehouse, contract folder of warehouse, contract item of contract folder * @author marsli */ @Slf4j @@ -36,21 +37,21 @@ public class WareHouseService { @Autowired private TbContractFolderMapper contractFolderMapper; @Autowired - private TbWareHouseMapper wareHouseMapper; + private TbWarehouseMapper wareHouseMapper; /** * */ - public List getStoreList() { - List storeItemList = wareHouseMapper.findAll(); + public List getStoreList() { + List storeItemList = wareHouseMapper.findAll(); return storeItemList; } /** * */ - public TbWareHouse getStoreItemById(Integer wareHouseId) { - TbWareHouse storeItem = wareHouseMapper.selectByPrimaryKey(wareHouseId); + public TbWarehouse getStoreItemById(Integer wareHouseId) { + TbWarehouse storeItem = wareHouseMapper.selectByPrimaryKey(wareHouseId); return storeItem; } diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractFolder.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractFolder.java index 061baea35..f45867e76 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractFolder.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractFolder.java @@ -12,6 +12,7 @@ @NoArgsConstructor @EqualsAndHashCode public class TbContractFolder implements Serializable { + /** * * This field was generated by MyBatis Generator. @@ -51,11 +52,11 @@ public class TbContractFolder implements Serializable { /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_contract_folder.ware_house_id + * This field corresponds to the database column tb_contract_folder.warehouse_id * * @mbg.generated */ - private Integer wareHouseId; + private Integer warehouseId; /** * @@ -100,4 +101,4 @@ public class TbContractFolder implements Serializable { * @mbg.generated */ private static final long serialVersionUID = 1L; -} \ No newline at end of file +} diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractItem.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractItem.java index 161dd672b..d0ab948da 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractItem.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbContractItem.java @@ -12,6 +12,7 @@ @NoArgsConstructor @EqualsAndHashCode public class TbContractItem implements Serializable { + /** * * This field was generated by MyBatis Generator. @@ -51,11 +52,11 @@ public class TbContractItem implements Serializable { /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_contract_item.ware_house_id + * This field corresponds to the database column tb_contract_item.warehouse_id * * @mbg.generated */ - private Integer wareHouseId; + private Integer warehouseId; /** * @@ -100,4 +101,4 @@ public class TbContractItem implements Serializable { * @mbg.generated */ private static final long serialVersionUID = 1L; -} \ No newline at end of file +} diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbWareHouse.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbWarehouse.java similarity index 56% rename from src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbWareHouse.java rename to src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbWarehouse.java index b72aa643c..54925709d 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbWareHouse.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/entity/TbWarehouse.java @@ -7,15 +7,19 @@ import lombok.NoArgsConstructor; import lombok.ToString; +/** + * @author marsli + */ @Data @ToString @NoArgsConstructor @EqualsAndHashCode -public class TbWareHouse implements Serializable { +public class TbWarehouse implements Serializable { + /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_ware_house.id + * This field corresponds to the database column tb_warehouse.id * * @mbg.generated */ @@ -24,34 +28,34 @@ public class TbWareHouse implements Serializable { /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_ware_house.ware_house_name + * This field corresponds to the database column tb_warehouse.warehouse_name * * @mbg.generated */ - private String wareHouseName; + private String warehouseName; /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_ware_house.ware_house_name_en + * This field corresponds to the database column tb_warehouse.warehouse_name_en * * @mbg.generated */ - private String wareHouseNameEn; + private String warehouseNameEn; /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_ware_house.type + * This field corresponds to the database column tb_warehouse.type * * @mbg.generated */ - private String type; + private Integer type; /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_ware_house.create_time + * This field corresponds to the database column tb_warehouse.create_time * * @mbg.generated */ @@ -60,7 +64,7 @@ public class TbWareHouse implements Serializable { /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_ware_house.modify_time + * This field corresponds to the database column tb_warehouse.modify_time * * @mbg.generated */ @@ -69,16 +73,16 @@ public class TbWareHouse implements Serializable { /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_ware_house.ware_house_icon + * This field corresponds to the database column tb_warehouse.warehouse_icon * * @mbg.generated */ - private String wareHouseIcon; + private String warehouseIcon; /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_ware_house.description + * This field corresponds to the database column tb_warehouse.description * * @mbg.generated */ @@ -87,7 +91,7 @@ public class TbWareHouse implements Serializable { /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_ware_house.description_en + * This field corresponds to the database column tb_warehouse.description_en * * @mbg.generated */ @@ -96,26 +100,26 @@ public class TbWareHouse implements Serializable { /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_ware_house.ware_house_detail + * This field corresponds to the database column tb_warehouse.warehouse_detail * * @mbg.generated */ - private String wareHouseDetail; + private String warehouseDetail; /** * * This field was generated by MyBatis Generator. - * This field corresponds to the database column tb_ware_house.ware_house_detail_en + * This field corresponds to the database column tb_warehouse.warehouse_detail_en * * @mbg.generated */ - private String wareHouseDetailEn; + private String warehouseDetailEn; /** * This field was generated by MyBatis Generator. - * This field corresponds to the database table tb_ware_house + * This field corresponds to the database table tb_warehouse * * @mbg.generated */ private static final long serialVersionUID = 1L; -} \ No newline at end of file +} diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java index eb7d50aa7..74792b3eb 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java @@ -20,8 +20,7 @@ */ public interface TbContractFolderMapper { - @Select({"select", TbWareHouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_contract_folder", - "where ware_house_id = #{wareHouseId}"}) + @Select({ "select", TbWarehouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_contract_folder", "where ware_house_id = #{wareHouseId}" }) List findByWareHouseId(@Param("wareHouseId") Integer wareHouseId); /** @@ -30,10 +29,7 @@ public interface TbContractFolderMapper { * * @mbg.generated */ - @Delete({ - "delete from tb_contract_folder", - "where id = #{id,jdbcType=INTEGER}" - }) + @Delete({ "delete from tb_contract_folder", "where id = #{id,jdbcType=INTEGER}" }) int deleteByPrimaryKey(Integer id); /** @@ -42,8 +38,8 @@ public interface TbContractFolderMapper { * * @mbg.generated */ - @InsertProvider(type=TbContractFolderSqlProvider.class, method="insertSelective") - @SelectKey(statement="SELECT LAST_INSERT_ID()", keyProperty="id", before=false, resultType=Integer.class) + @InsertProvider(type = TbContractFolderSqlProvider.class, method = "insertSelective") + @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "id", before = false, resultType = Integer.class) int insertSelective(TbContractFolder record); /** @@ -52,24 +48,8 @@ public interface TbContractFolderMapper { * * @mbg.generated */ - @Select({ - "select", - "id, folder_name, create_time, modify_time, ware_house_id, description, description_en, ", - "folder_detail, folder_detail_en", - "from tb_contract_folder", - "where id = #{id,jdbcType=INTEGER}" - }) - @Results({ - @Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true), - @Result(column="folder_name", property="folderName", jdbcType=JdbcType.VARCHAR), - @Result(column="create_time", property="createTime", jdbcType=JdbcType.TIMESTAMP), - @Result(column="modify_time", property="modifyTime", jdbcType=JdbcType.TIMESTAMP), - @Result(column="ware_house_id", property="wareHouseId", jdbcType=JdbcType.INTEGER), - @Result(column="description", property="description", jdbcType=JdbcType.LONGVARCHAR), - @Result(column="description_en", property="descriptionEn", jdbcType=JdbcType.LONGVARCHAR), - @Result(column="folder_detail", property="folderDetail", jdbcType=JdbcType.LONGVARCHAR), - @Result(column="folder_detail_en", property="folderDetailEn", jdbcType=JdbcType.LONGVARCHAR) - }) + @Select({ "select", "id, folder_name, create_time, modify_time, warehouse_id, description, description_en, ", "folder_detail, folder_detail_en", "from tb_contract_folder", "where id = #{id,jdbcType=INTEGER}" }) + @Results({ @Result(column = "id", property = "id", jdbcType = JdbcType.INTEGER, id = true), @Result(column = "folder_name", property = "folderName", jdbcType = JdbcType.VARCHAR), @Result(column = "create_time", property = "createTime", jdbcType = JdbcType.TIMESTAMP), @Result(column = "modify_time", property = "modifyTime", jdbcType = JdbcType.TIMESTAMP), @Result(column = "warehouse_id", property = "warehouseId", jdbcType = JdbcType.INTEGER), @Result(column = "description", property = "description", jdbcType = JdbcType.LONGVARCHAR), @Result(column = "description_en", property = "descriptionEn", jdbcType = JdbcType.LONGVARCHAR), @Result(column = "folder_detail", property = "folderDetail", jdbcType = JdbcType.LONGVARCHAR), @Result(column = "folder_detail_en", property = "folderDetailEn", jdbcType = JdbcType.LONGVARCHAR) }) TbContractFolder selectByPrimaryKey(Integer id); /** @@ -78,7 +58,7 @@ public interface TbContractFolderMapper { * * @mbg.generated */ - @UpdateProvider(type=TbContractFolderSqlProvider.class, method="updateByPrimaryKeySelective") + @UpdateProvider(type = TbContractFolderSqlProvider.class, method = "updateByPrimaryKeySelective") int updateByPrimaryKeySelective(TbContractFolder record); /** @@ -87,19 +67,7 @@ public interface TbContractFolderMapper { * * @mbg.generated */ - @Options(useGeneratedKeys = true,keyProperty="id",keyColumn = "id") - @Insert({ - "", - }) + @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") + @Insert({ "" }) int batchInsert(java.util.List list); -} \ No newline at end of file +} diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderSqlProvider.java index 0a0afa86a..e4feea1e0 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderSqlProvider.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderSqlProvider.java @@ -4,13 +4,14 @@ import org.apache.ibatis.jdbc.SQL; public class TbContractFolderSqlProvider { + /** * This field was generated by MyBatis Generator. * This field corresponds to the database table tb_contract_folder * * @mbg.generated */ - public static final String ALL_COLUMN_FIELDS = "id,folder_name,create_time,modify_time,ware_house_id,description,description_en,folder_detail,folder_detail_en"; + public static final String ALL_COLUMN_FIELDS = "id,folder_name,create_time,modify_time,warehouse_id,description,description_en,folder_detail,folder_detail_en"; /** * This method was generated by MyBatis Generator. @@ -21,39 +22,30 @@ public class TbContractFolderSqlProvider { public String insertSelective(TbContractFolder record) { SQL sql = new SQL(); sql.INSERT_INTO("tb_contract_folder"); - if (record.getFolderName() != null) { sql.VALUES("folder_name", "#{folderName,jdbcType=VARCHAR}"); } - if (record.getCreateTime() != null) { sql.VALUES("create_time", "#{createTime,jdbcType=TIMESTAMP}"); } - if (record.getModifyTime() != null) { sql.VALUES("modify_time", "#{modifyTime,jdbcType=TIMESTAMP}"); } - - if (record.getWareHouseId() != null) { - sql.VALUES("ware_house_id", "#{wareHouseId,jdbcType=INTEGER}"); + if (record.getWarehouseId() != null) { + sql.VALUES("warehouse_id", "#{warehouseId,jdbcType=INTEGER}"); } - if (record.getDescription() != null) { sql.VALUES("description", "#{description,jdbcType=LONGVARCHAR}"); } - if (record.getDescriptionEn() != null) { sql.VALUES("description_en", "#{descriptionEn,jdbcType=LONGVARCHAR}"); } - if (record.getFolderDetail() != null) { sql.VALUES("folder_detail", "#{folderDetail,jdbcType=LONGVARCHAR}"); } - if (record.getFolderDetailEn() != null) { sql.VALUES("folder_detail_en", "#{folderDetailEn,jdbcType=LONGVARCHAR}"); } - return sql.toString(); } @@ -66,41 +58,31 @@ public String insertSelective(TbContractFolder record) { public String updateByPrimaryKeySelective(TbContractFolder record) { SQL sql = new SQL(); sql.UPDATE("tb_contract_folder"); - if (record.getFolderName() != null) { sql.SET("folder_name = #{folderName,jdbcType=VARCHAR}"); } - if (record.getCreateTime() != null) { sql.SET("create_time = #{createTime,jdbcType=TIMESTAMP}"); } - if (record.getModifyTime() != null) { sql.SET("modify_time = #{modifyTime,jdbcType=TIMESTAMP}"); } - - if (record.getWareHouseId() != null) { - sql.SET("ware_house_id = #{wareHouseId,jdbcType=INTEGER}"); + if (record.getWarehouseId() != null) { + sql.SET("warehouse_id = #{warehouseId,jdbcType=INTEGER}"); } - if (record.getDescription() != null) { sql.SET("description = #{description,jdbcType=LONGVARCHAR}"); } - if (record.getDescriptionEn() != null) { sql.SET("description_en = #{descriptionEn,jdbcType=LONGVARCHAR}"); } - if (record.getFolderDetail() != null) { sql.SET("folder_detail = #{folderDetail,jdbcType=LONGVARCHAR}"); } - if (record.getFolderDetailEn() != null) { sql.SET("folder_detail_en = #{folderDetailEn,jdbcType=LONGVARCHAR}"); } - sql.WHERE("id = #{id,jdbcType=INTEGER}"); - return sql.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java index 4ec91dbc5..dd5111afb 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java @@ -16,9 +16,7 @@ public interface TbContractItemMapper { - - @Select({"select", TbWareHouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_contract_folder", - "where contract_folder_id = #{contractFolderId}"}) + @Select({ "select", TbWarehouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_contract_folder", "where contract_folder_id = #{contractFolderId}" }) List listByFolderId(@Param("contractFolderId") Integer contractFolderId); /** @@ -27,10 +25,7 @@ public interface TbContractItemMapper { * * @mbg.generated */ - @Delete({ - "delete from tb_contract_item", - "where id = #{id,jdbcType=INTEGER}" - }) + @Delete({ "delete from tb_contract_item", "where id = #{id,jdbcType=INTEGER}" }) int deleteByPrimaryKey(Integer id); /** @@ -39,8 +34,8 @@ public interface TbContractItemMapper { * * @mbg.generated */ - @InsertProvider(type=TbContractItemSqlProvider.class, method="insertSelective") - @SelectKey(statement="SELECT LAST_INSERT_ID()", keyProperty="id", before=false, resultType=Integer.class) + @InsertProvider(type = TbContractItemSqlProvider.class, method = "insertSelective") + @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "id", before = false, resultType = Integer.class) int insertSelective(TbContractItem record); /** @@ -49,24 +44,8 @@ public interface TbContractItemMapper { * * @mbg.generated */ - @Select({ - "select", - "id, contract_name, create_time, modify_time, ware_house_id, contract_folder_id, ", - "contract_source, description, description_en", - "from tb_contract_item", - "where id = #{id,jdbcType=INTEGER}" - }) - @Results({ - @Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true), - @Result(column="contract_name", property="contractName", jdbcType=JdbcType.VARCHAR), - @Result(column="create_time", property="createTime", jdbcType=JdbcType.TIMESTAMP), - @Result(column="modify_time", property="modifyTime", jdbcType=JdbcType.TIMESTAMP), - @Result(column="ware_house_id", property="wareHouseId", jdbcType=JdbcType.INTEGER), - @Result(column="contract_folder_id", property="contractFolderId", jdbcType=JdbcType.INTEGER), - @Result(column="contract_source", property="contractSource", jdbcType=JdbcType.LONGVARCHAR), - @Result(column="description", property="description", jdbcType=JdbcType.LONGVARCHAR), - @Result(column="description_en", property="descriptionEn", jdbcType=JdbcType.LONGVARCHAR) - }) + @Select({ "select", "id, contract_name, create_time, modify_time, warehouse_id, contract_folder_id, ", "contract_source, description, description_en", "from tb_contract_item", "where id = #{id,jdbcType=INTEGER}" }) + @Results({ @Result(column = "id", property = "id", jdbcType = JdbcType.INTEGER, id = true), @Result(column = "contract_name", property = "contractName", jdbcType = JdbcType.VARCHAR), @Result(column = "create_time", property = "createTime", jdbcType = JdbcType.TIMESTAMP), @Result(column = "modify_time", property = "modifyTime", jdbcType = JdbcType.TIMESTAMP), @Result(column = "warehouse_id", property = "warehouseId", jdbcType = JdbcType.INTEGER), @Result(column = "contract_folder_id", property = "contractFolderId", jdbcType = JdbcType.INTEGER), @Result(column = "contract_source", property = "contractSource", jdbcType = JdbcType.LONGVARCHAR), @Result(column = "description", property = "description", jdbcType = JdbcType.LONGVARCHAR), @Result(column = "description_en", property = "descriptionEn", jdbcType = JdbcType.LONGVARCHAR) }) TbContractItem selectByPrimaryKey(Integer id); /** @@ -75,7 +54,7 @@ public interface TbContractItemMapper { * * @mbg.generated */ - @UpdateProvider(type=TbContractItemSqlProvider.class, method="updateByPrimaryKeySelective") + @UpdateProvider(type = TbContractItemSqlProvider.class, method = "updateByPrimaryKeySelective") int updateByPrimaryKeySelective(TbContractItem record); /** @@ -84,19 +63,7 @@ public interface TbContractItemMapper { * * @mbg.generated */ - @Options(useGeneratedKeys = true,keyProperty="id",keyColumn = "id") - @Insert({ - "", - }) + @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") + @Insert({ "" }) int batchInsert(java.util.List list); -} \ No newline at end of file +} diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemSqlProvider.java index d692e0dcf..a6481ab3c 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemSqlProvider.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemSqlProvider.java @@ -4,13 +4,14 @@ import org.apache.ibatis.jdbc.SQL; public class TbContractItemSqlProvider { + /** * This field was generated by MyBatis Generator. * This field corresponds to the database table tb_contract_item * * @mbg.generated */ - public static final String ALL_COLUMN_FIELDS = "id,contract_name,create_time,modify_time,ware_house_id,contract_folder_id,contract_source,description,description_en"; + public static final String ALL_COLUMN_FIELDS = "id,contract_name,create_time,modify_time,warehouse_id,contract_folder_id,contract_source,description,description_en"; /** * This method was generated by MyBatis Generator. @@ -21,39 +22,30 @@ public class TbContractItemSqlProvider { public String insertSelective(TbContractItem record) { SQL sql = new SQL(); sql.INSERT_INTO("tb_contract_item"); - if (record.getContractName() != null) { sql.VALUES("contract_name", "#{contractName,jdbcType=VARCHAR}"); } - if (record.getCreateTime() != null) { sql.VALUES("create_time", "#{createTime,jdbcType=TIMESTAMP}"); } - if (record.getModifyTime() != null) { sql.VALUES("modify_time", "#{modifyTime,jdbcType=TIMESTAMP}"); } - - if (record.getWareHouseId() != null) { - sql.VALUES("ware_house_id", "#{wareHouseId,jdbcType=INTEGER}"); + if (record.getWarehouseId() != null) { + sql.VALUES("warehouse_id", "#{warehouseId,jdbcType=INTEGER}"); } - if (record.getContractFolderId() != null) { sql.VALUES("contract_folder_id", "#{contractFolderId,jdbcType=INTEGER}"); } - if (record.getContractSource() != null) { sql.VALUES("contract_source", "#{contractSource,jdbcType=LONGVARCHAR}"); } - if (record.getDescription() != null) { sql.VALUES("description", "#{description,jdbcType=LONGVARCHAR}"); } - if (record.getDescriptionEn() != null) { sql.VALUES("description_en", "#{descriptionEn,jdbcType=LONGVARCHAR}"); } - return sql.toString(); } @@ -66,41 +58,31 @@ public String insertSelective(TbContractItem record) { public String updateByPrimaryKeySelective(TbContractItem record) { SQL sql = new SQL(); sql.UPDATE("tb_contract_item"); - if (record.getContractName() != null) { sql.SET("contract_name = #{contractName,jdbcType=VARCHAR}"); } - if (record.getCreateTime() != null) { sql.SET("create_time = #{createTime,jdbcType=TIMESTAMP}"); } - if (record.getModifyTime() != null) { sql.SET("modify_time = #{modifyTime,jdbcType=TIMESTAMP}"); } - - if (record.getWareHouseId() != null) { - sql.SET("ware_house_id = #{wareHouseId,jdbcType=INTEGER}"); + if (record.getWarehouseId() != null) { + sql.SET("warehouse_id = #{warehouseId,jdbcType=INTEGER}"); } - if (record.getContractFolderId() != null) { sql.SET("contract_folder_id = #{contractFolderId,jdbcType=INTEGER}"); } - if (record.getContractSource() != null) { sql.SET("contract_source = #{contractSource,jdbcType=LONGVARCHAR}"); } - if (record.getDescription() != null) { sql.SET("description = #{description,jdbcType=LONGVARCHAR}"); } - if (record.getDescriptionEn() != null) { sql.SET("description_en = #{descriptionEn,jdbcType=LONGVARCHAR}"); } - sql.WHERE("id = #{id,jdbcType=INTEGER}"); - return sql.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseMapper.java deleted file mode 100644 index e8b20a881..000000000 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseMapper.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.webank.webase.node.mgr.contract.warehouse.mapper; - -import com.webank.webase.node.mgr.contract.warehouse.entity.TbWareHouse; -import java.util.List; -import org.apache.ibatis.annotations.Delete; -import org.apache.ibatis.annotations.Insert; -import org.apache.ibatis.annotations.InsertProvider; -import org.apache.ibatis.annotations.Options; -import org.apache.ibatis.annotations.Result; -import org.apache.ibatis.annotations.Results; -import org.apache.ibatis.annotations.Select; -import org.apache.ibatis.annotations.SelectKey; -import org.apache.ibatis.annotations.UpdateProvider; -import org.apache.ibatis.type.JdbcType; - -/** - * @author marsli - */ -public interface TbWareHouseMapper { - - @Select({"select", TbWareHouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_ware_house"}) - List findAll(); - - /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table tb_ware_house - * - * @mbg.generated - */ - @Delete({ - "delete from tb_ware_house", - "where id = #{id,jdbcType=INTEGER}" - }) - int deleteByPrimaryKey(Integer id); - - /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table tb_ware_house - * - * @mbg.generated - */ - @InsertProvider(type=TbWareHouseSqlProvider.class, method="insertSelective") - @SelectKey(statement="SELECT LAST_INSERT_ID()", keyProperty="id", before=false, resultType=Integer.class) - int insertSelective(TbWareHouse record); - - /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table tb_ware_house - * - * @mbg.generated - */ - @Select({ - "select", - "id, ware_house_name, ware_house_name_en, type, create_time, modify_time, ware_house_icon, ", - "description, description_en, ware_house_detail, ware_house_detail_en", - "from tb_ware_house", - "where id = #{id,jdbcType=INTEGER}" - }) - @Results({ - @Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true), - @Result(column="ware_house_name", property="wareHouseName", jdbcType=JdbcType.VARCHAR), - @Result(column="ware_house_name_en", property="wareHouseNameEn", jdbcType=JdbcType.VARCHAR), - @Result(column="type", property="type", jdbcType=JdbcType.VARCHAR), - @Result(column="create_time", property="createTime", jdbcType=JdbcType.TIMESTAMP), - @Result(column="modify_time", property="modifyTime", jdbcType=JdbcType.TIMESTAMP), - @Result(column="ware_house_icon", property="wareHouseIcon", jdbcType=JdbcType.LONGVARCHAR), - @Result(column="description", property="description", jdbcType=JdbcType.LONGVARCHAR), - @Result(column="description_en", property="descriptionEn", jdbcType=JdbcType.LONGVARCHAR), - @Result(column="ware_house_detail", property="wareHouseDetail", jdbcType=JdbcType.LONGVARCHAR), - @Result(column="ware_house_detail_en", property="wareHouseDetailEn", jdbcType=JdbcType.LONGVARCHAR) - }) - TbWareHouse selectByPrimaryKey(Integer id); - - /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table tb_ware_house - * - * @mbg.generated - */ - @UpdateProvider(type=TbWareHouseSqlProvider.class, method="updateByPrimaryKeySelective") - int updateByPrimaryKeySelective(TbWareHouse record); - - /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table tb_ware_house - * - * @mbg.generated - */ - @Options(useGeneratedKeys = true,keyProperty="id",keyColumn = "id") - @Insert({ - "", - }) - int batchInsert(java.util.List list); -} \ No newline at end of file diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseSqlProvider.java deleted file mode 100644 index 85f9f3ce8..000000000 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWareHouseSqlProvider.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.webank.webase.node.mgr.contract.warehouse.mapper; - -import com.webank.webase.node.mgr.contract.warehouse.entity.TbWareHouse; -import org.apache.ibatis.jdbc.SQL; - -public class TbWareHouseSqlProvider { - /** - * This field was generated by MyBatis Generator. - * This field corresponds to the database table tb_ware_house - * - * @mbg.generated - */ - public static final String ALL_COLUMN_FIELDS = "id,ware_house_name,ware_house_name_en,type,create_time,modify_time,ware_house_icon,description,description_en,ware_house_detail,ware_house_detail_en"; - - /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table tb_ware_house - * - * @mbg.generated - */ - public String insertSelective(TbWareHouse record) { - SQL sql = new SQL(); - sql.INSERT_INTO("tb_ware_house"); - - if (record.getWareHouseName() != null) { - sql.VALUES("ware_house_name", "#{wareHouseName,jdbcType=VARCHAR}"); - } - - if (record.getWareHouseNameEn() != null) { - sql.VALUES("ware_house_name_en", "#{wareHouseNameEn,jdbcType=VARCHAR}"); - } - - if (record.getType() != null) { - sql.VALUES("type", "#{type,jdbcType=VARCHAR}"); - } - - if (record.getCreateTime() != null) { - sql.VALUES("create_time", "#{createTime,jdbcType=TIMESTAMP}"); - } - - if (record.getModifyTime() != null) { - sql.VALUES("modify_time", "#{modifyTime,jdbcType=TIMESTAMP}"); - } - - if (record.getWareHouseIcon() != null) { - sql.VALUES("ware_house_icon", "#{wareHouseIcon,jdbcType=LONGVARCHAR}"); - } - - if (record.getDescription() != null) { - sql.VALUES("description", "#{description,jdbcType=LONGVARCHAR}"); - } - - if (record.getDescriptionEn() != null) { - sql.VALUES("description_en", "#{descriptionEn,jdbcType=LONGVARCHAR}"); - } - - if (record.getWareHouseDetail() != null) { - sql.VALUES("ware_house_detail", "#{wareHouseDetail,jdbcType=LONGVARCHAR}"); - } - - if (record.getWareHouseDetailEn() != null) { - sql.VALUES("ware_house_detail_en", "#{wareHouseDetailEn,jdbcType=LONGVARCHAR}"); - } - - return sql.toString(); - } - - /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table tb_ware_house - * - * @mbg.generated - */ - public String updateByPrimaryKeySelective(TbWareHouse record) { - SQL sql = new SQL(); - sql.UPDATE("tb_ware_house"); - - if (record.getWareHouseName() != null) { - sql.SET("ware_house_name = #{wareHouseName,jdbcType=VARCHAR}"); - } - - if (record.getWareHouseNameEn() != null) { - sql.SET("ware_house_name_en = #{wareHouseNameEn,jdbcType=VARCHAR}"); - } - - if (record.getType() != null) { - sql.SET("type = #{type,jdbcType=VARCHAR}"); - } - - if (record.getCreateTime() != null) { - sql.SET("create_time = #{createTime,jdbcType=TIMESTAMP}"); - } - - if (record.getModifyTime() != null) { - sql.SET("modify_time = #{modifyTime,jdbcType=TIMESTAMP}"); - } - - if (record.getWareHouseIcon() != null) { - sql.SET("ware_house_icon = #{wareHouseIcon,jdbcType=LONGVARCHAR}"); - } - - if (record.getDescription() != null) { - sql.SET("description = #{description,jdbcType=LONGVARCHAR}"); - } - - if (record.getDescriptionEn() != null) { - sql.SET("description_en = #{descriptionEn,jdbcType=LONGVARCHAR}"); - } - - if (record.getWareHouseDetail() != null) { - sql.SET("ware_house_detail = #{wareHouseDetail,jdbcType=LONGVARCHAR}"); - } - - if (record.getWareHouseDetailEn() != null) { - sql.SET("ware_house_detail_en = #{wareHouseDetailEn,jdbcType=LONGVARCHAR}"); - } - - sql.WHERE("id = #{id,jdbcType=INTEGER}"); - - return sql.toString(); - } -} \ No newline at end of file diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWarehouseMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWarehouseMapper.java new file mode 100644 index 000000000..53b06e309 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWarehouseMapper.java @@ -0,0 +1,69 @@ +package com.webank.webase.node.mgr.contract.warehouse.mapper; + +import com.webank.webase.node.mgr.contract.warehouse.entity.TbWarehouse; +import java.util.List; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.InsertProvider; +import org.apache.ibatis.annotations.Options; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.UpdateProvider; +import org.apache.ibatis.type.JdbcType; + +/** + * @author marsli + */ +public interface TbWarehouseMapper { + + @Select({ "select", TbWarehouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_ware_house" }) + List findAll(); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_warehouse + * + * @mbg.generated + */ + @Delete({ "delete from tb_warehouse", "where id = #{id,jdbcType=INTEGER}" }) + int deleteByPrimaryKey(Integer id); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_warehouse + * + * @mbg.generated + */ + @InsertProvider(type = TbWarehouseSqlProvider.class, method = "insertSelective") + int insertSelective(TbWarehouse record); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_warehouse + * + * @mbg.generated + */ + @Select({ "select", "id, warehouse_name, warehouse_name_en, type, create_time, modify_time, warehouse_icon, ", "description, description_en, warehouse_detail, warehouse_detail_en", "from tb_warehouse", "where id = #{id,jdbcType=INTEGER}" }) + @Results({ @Result(column = "id", property = "id", jdbcType = JdbcType.INTEGER, id = true), @Result(column = "warehouse_name", property = "warehouseName", jdbcType = JdbcType.VARCHAR), @Result(column = "warehouse_name_en", property = "warehouseNameEn", jdbcType = JdbcType.VARCHAR), @Result(column = "type", property = "type", jdbcType = JdbcType.INTEGER), @Result(column = "create_time", property = "createTime", jdbcType = JdbcType.TIMESTAMP), @Result(column = "modify_time", property = "modifyTime", jdbcType = JdbcType.TIMESTAMP), @Result(column = "warehouse_icon", property = "warehouseIcon", jdbcType = JdbcType.LONGVARCHAR), @Result(column = "description", property = "description", jdbcType = JdbcType.LONGVARCHAR), @Result(column = "description_en", property = "descriptionEn", jdbcType = JdbcType.LONGVARCHAR), @Result(column = "warehouse_detail", property = "warehouseDetail", jdbcType = JdbcType.LONGVARCHAR), @Result(column = "warehouse_detail_en", property = "warehouseDetailEn", jdbcType = JdbcType.LONGVARCHAR) }) + TbWarehouse selectByPrimaryKey(Integer id); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_warehouse + * + * @mbg.generated + */ + @UpdateProvider(type = TbWarehouseSqlProvider.class, method = "updateByPrimaryKeySelective") + int updateByPrimaryKeySelective(TbWarehouse record); + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_warehouse + * + * @mbg.generated + */ + @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") + @Insert({ "" }) + int batchInsert(java.util.List list); +} diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWarehouseSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWarehouseSqlProvider.java new file mode 100644 index 000000000..ebc6daa9c --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWarehouseSqlProvider.java @@ -0,0 +1,103 @@ +package com.webank.webase.node.mgr.contract.warehouse.mapper; + +import com.webank.webase.node.mgr.contract.warehouse.entity.TbWarehouse; +import org.apache.ibatis.jdbc.SQL; + +public class TbWarehouseSqlProvider { + + /** + * This field was generated by MyBatis Generator. + * This field corresponds to the database table tb_warehouse + * + * @mbg.generated + */ + public static final String ALL_COLUMN_FIELDS = "id,warehouse_name,warehouse_name_en,type,create_time,modify_time,warehouse_icon,description,description_en,warehouse_detail,warehouse_detail_en"; + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_warehouse + * + * @mbg.generated + */ + public String insertSelective(TbWarehouse record) { + SQL sql = new SQL(); + sql.INSERT_INTO("tb_warehouse"); + if (record.getId() != null) { + sql.VALUES("id", "#{id,jdbcType=INTEGER}"); + } + if (record.getWarehouseName() != null) { + sql.VALUES("warehouse_name", "#{warehouseName,jdbcType=VARCHAR}"); + } + if (record.getWarehouseNameEn() != null) { + sql.VALUES("warehouse_name_en", "#{warehouseNameEn,jdbcType=VARCHAR}"); + } + if (record.getType() != null) { + sql.VALUES("type", "#{type,jdbcType=INTEGER}"); + } + if (record.getCreateTime() != null) { + sql.VALUES("create_time", "#{createTime,jdbcType=TIMESTAMP}"); + } + if (record.getModifyTime() != null) { + sql.VALUES("modify_time", "#{modifyTime,jdbcType=TIMESTAMP}"); + } + if (record.getWarehouseIcon() != null) { + sql.VALUES("warehouse_icon", "#{warehouseIcon,jdbcType=LONGVARCHAR}"); + } + if (record.getDescription() != null) { + sql.VALUES("description", "#{description,jdbcType=LONGVARCHAR}"); + } + if (record.getDescriptionEn() != null) { + sql.VALUES("description_en", "#{descriptionEn,jdbcType=LONGVARCHAR}"); + } + if (record.getWarehouseDetail() != null) { + sql.VALUES("warehouse_detail", "#{warehouseDetail,jdbcType=LONGVARCHAR}"); + } + if (record.getWarehouseDetailEn() != null) { + sql.VALUES("warehouse_detail_en", "#{warehouseDetailEn,jdbcType=LONGVARCHAR}"); + } + return sql.toString(); + } + + /** + * This method was generated by MyBatis Generator. + * This method corresponds to the database table tb_warehouse + * + * @mbg.generated + */ + public String updateByPrimaryKeySelective(TbWarehouse record) { + SQL sql = new SQL(); + sql.UPDATE("tb_warehouse"); + if (record.getWarehouseName() != null) { + sql.SET("warehouse_name = #{warehouseName,jdbcType=VARCHAR}"); + } + if (record.getWarehouseNameEn() != null) { + sql.SET("warehouse_name_en = #{warehouseNameEn,jdbcType=VARCHAR}"); + } + if (record.getType() != null) { + sql.SET("type = #{type,jdbcType=INTEGER}"); + } + if (record.getCreateTime() != null) { + sql.SET("create_time = #{createTime,jdbcType=TIMESTAMP}"); + } + if (record.getModifyTime() != null) { + sql.SET("modify_time = #{modifyTime,jdbcType=TIMESTAMP}"); + } + if (record.getWarehouseIcon() != null) { + sql.SET("warehouse_icon = #{warehouseIcon,jdbcType=LONGVARCHAR}"); + } + if (record.getDescription() != null) { + sql.SET("description = #{description,jdbcType=LONGVARCHAR}"); + } + if (record.getDescriptionEn() != null) { + sql.SET("description_en = #{descriptionEn,jdbcType=LONGVARCHAR}"); + } + if (record.getWarehouseDetail() != null) { + sql.SET("warehouse_detail = #{warehouseDetail,jdbcType=LONGVARCHAR}"); + } + if (record.getWarehouseDetailEn() != null) { + sql.SET("warehouse_detail_en = #{warehouseDetailEn,jdbcType=LONGVARCHAR}"); + } + sql.WHERE("id = #{id,jdbcType=INTEGER}"); + return sql.toString(); + } +} From 1162e397958d639671180f1941d09595e07482ae Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Mon, 26 Apr 2021 10:12:49 +0800 Subject: [PATCH 19/92] update warehouse --- script/webase-ddl.sql | 22 +++++++++++----------- script/webase-dml.sql | 38 +++++++++++++++++++------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/script/webase-ddl.sql b/script/webase-ddl.sql index d8134cff4..ce4ecc528 100644 --- a/script/webase-ddl.sql +++ b/script/webase-ddl.sql @@ -549,20 +549,20 @@ SET FOREIGN_KEY_CHECKS = 1; -- ---------------------------- -- Table structure for tb_contract_store -- ---------------------------- -CREATE TABLE IF NOT EXISTS tb_ware_house ( +CREATE TABLE IF NOT EXISTS tb_warehouse ( id int(11) NOT NULL COMMENT '自增编号', - ware_house_name varchar(255) binary NOT NULL COMMENT '合约仓库名', - ware_house_name_en varchar(255) binary NOT NULL COMMENT '仓库名(英文)', + warehouse_name varchar(255) binary NOT NULL COMMENT '合约仓库名', + warehouse_name_en varchar(255) binary NOT NULL COMMENT '仓库名(英文)', type int(11) NOT NULL COMMENT '仓库类型', - ware_house_icon mediumtext COMMENT '仓库图标(Base64)', + warehouse_icon mediumtext COMMENT '仓库图标(Base64)', description mediumtext COMMENT '仓库描述(Base64)', description_en mediumtext COMMENT '仓库描述(英文)(Base64)', - ware_house_detail mediumtext COMMENT '仓库详情', - ware_house_detail_en mediumtext COMMENT '仓库详情(英文)', + warehouse_detail mediumtext COMMENT '仓库详情', + warehouse_detail_en mediumtext COMMENT '仓库详情(英文)', create_time datetime DEFAULT NULL COMMENT '创建时间', modify_time datetime DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (id), - UNIQUE KEY uk_name(ware_house_name) + UNIQUE KEY uk_name(warehouse_name) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='合约仓库'; CREATE TABLE IF NOT EXISTS tb_contract_folder ( @@ -574,9 +574,9 @@ CREATE TABLE IF NOT EXISTS tb_contract_folder ( folder_detail_en mediumtext COMMENT '目录详情(英文)', create_time datetime DEFAULT NULL COMMENT '创建时间', modify_time datetime DEFAULT NULL COMMENT '修改时间', - ware_house_id int(11) NOT NULL COMMENT '合约仓库编号', + warehouse_id int(11) NOT NULL COMMENT '合约仓库编号', PRIMARY KEY (id), - UNIQUE KEY uk_name(ware_house_id,folder_name) + UNIQUE KEY uk_name(warehouse_id,folder_name) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='合约仓库目录'; CREATE TABLE IF NOT EXISTS tb_contract_item ( @@ -587,8 +587,8 @@ CREATE TABLE IF NOT EXISTS tb_contract_item ( description_en mediumtext COMMENT '合约描述(英文)(Base64)', create_time datetime DEFAULT NULL COMMENT '创建时间', modify_time datetime DEFAULT NULL COMMENT '修改时间', - ware_house_id int(11) NOT NULL COMMENT '合约仓库编号', + warehouse_id int(11) NOT NULL COMMENT '合约仓库编号', contract_folder_id int(11) NOT NULL COMMENT '合约目录编号', PRIMARY KEY (id), - UNIQUE KEY uk_name(ware_house_id,contract_folder_id,contract_name) + UNIQUE KEY uk_name(warehouse_id,contract_folder_id,contract_name) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='合约仓库合约信息'; diff --git a/script/webase-dml.sql b/script/webase-dml.sql index 7428d046c..57106a3b2 100644 --- a/script/webase-dml.sql +++ b/script/webase-dml.sql @@ -150,41 +150,41 @@ INSERT INTO `tb_config`(`config_name`, `config_type`, `config_value`, `create_ti INSERT INTO `tb_app_info` (`app_name`, `app_key`, `app_type`, `app_doc_link`, `app_icon`, `app_desc`, `app_detail`, `create_time`, `modify_time`) VALUES ('WeId-temp', 'app00001', 1, 'https://weidentity.readthedocs.io/zh_CN/latest/docs/deploy-via-web.html', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFGmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDIgNzkuMTY0MzUyLCAyMDIwLzAxLzMwLTE1OjUwOjM4ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjEtMDMtMThUMTY6NTc6MzQrMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTAzLTE4VDE4OjAyOjAxKzA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIxLTAzLTE4VDE4OjAyOjAxKzA4OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg1NDJjNjJlLTZjYTUtNGI2My05ZDg5LWNhMjVmOTU1NTA4OSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4NTQyYzYyZS02Y2E1LTRiNjMtOWQ4OS1jYTI1Zjk1NTUwODkiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo4NTQyYzYyZS02Y2E1LTRiNjMtOWQ4OS1jYTI1Zjk1NTUwODkiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg1NDJjNjJlLTZjYTUtNGI2My05ZDg5LWNhMjVmOTU1NTA4OSIgc3RFdnQ6d2hlbj0iMjAyMS0wMy0xOFQxNjo1NzozNCswODowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+5hbXdAAADNFJREFUeJzt23msXOV5x/Hf877vWWa/q++177VZvG8EMEUyxXIxFBVaCIEEiFJVCS0ohJRIVGoiHFVKlTZVUUvVqE5omlBQiJIoAYKdpTipgZrGtdsa8IIDxtf7vXPX2c+c8y5P/7gusgWWKs4fVdXzlY5mzoxm5ugz533PnNEMMTOyPnjif3sD/q+XAaYsA0xZBpiyDDBlGWDKMsCUZYApywBTlgGmLANMWQaYsgwwZRlgyjLAlGWAKcsAU5YBpiwDTFkGmLIMMGUZYMoywJRlgCnLAFOWAaYsA0xZBpiyDDBlGWDKMsCUZYApU+ev7BscAACQ4z8E+F6AzmilPu6SxOpaDcrzkKuUoZmhmB8F8NsCOGRIPNBRCtfUa4i6MeoAdpVG8ceb/xxOEPIm7hVSfpcFiuToaXJ4go3F5PFZeJVRRHsfATCO4Vv+7ouyOHiN6UZfJNBB9iUmIwbXE3jVMbjxz8Jf4iCW/gDtX2nArwGiC7SuQLGyFkr8CI2DHoZuvBQQDqSMAsMRsSMSSIwFMcMraIzv+DRs504Az2H4lm1QuQEZcR1e3trG/jY6y0eBmTaw+ygABq68BNiwEDgyDd5937tmF+yB1hoYa0DgO4UQ17E1Vw83Gq7cbCIGYJhhnIXHFkS4WwLXGaI1LBREHAFOgwDUAVzZPI3bT7+Ebq4PQnmXQ4qb4XCd82yv6zEwXgI2ANsWQFchXHV3KILcl9jqD1OCAF0Bqx1AH+AXtJ4AyN3DJF8URI8JcujYGKKwACS9e532tlfWvXZL4cqrkVt3Vwjpf4dZv1gIzSaSOSRQ82j/gy4A7NYaiOtNYuZhQQQnxY8Xx13utxYGQCIEClGMdfVmAUyDICBW8meVdhMDtQYiIgAEB6AD4IGjOzEY94C4uNzBQBkfjcWzL1evOo220nANB4gIhBUIeu4YkMW8YKNnRIiDwjOwksEMwAI2tgAIIIJzDCQO0BrQCRADzoQQ2sBpwoxrgVh/VBLfEDu3uJoEmK2fQnPPX0GwfkSEg7+T739hsR7oR7j2viEVhB9n57Z0Dg9MTbV9GIQAM2AZgJ5fDANCAPZCwAuGMJVKUMxLQHS5cw6WxL+9XanAEj08RFjM1o012W07kMuNMHgRSEBq/VrS6SAI/HUn8+GtfkENsDFvuyj67vJoqrkh2o9dvUvWFNsMp2yjPN73TjhRhq4J5IbsQG5B4faem1cvANorTduHyvceiN55LtZtDX/9J5A30yNcoLJclDvWqqrYJha5nKpgUIxC9cagoqA8tB+cHpOyiNzyYpFjsxC+t5xIwMbRW6xxSSBl0m0cnSi55BvKo58kzdzTaMxWKAhvF6EPFlRruZovOnJJ2KdaRDyIvLK4ZOAoSQaX1RC6yQjnaAbAiXfNzv+R+duVChIpb+pKsZOZoVrt/sT3Nsl8/nlhLAQB2tg+Q1jhS7GHGci12wMNqW4LCoUnnbVwAJQgdEkc2Dg1ufnrC1bPPbjlL7+/KKp9jHz7n2bSbuicaiF3VeXWUPrfccZVWAmwTqBjoHcg/Gp1998+bMPVC3vWfXgbktodQkk4ZU5Ep8r3q1DvVP2dL0tWf+ScDBkSUna7znZ+Fkf0US+f+5Jif6tOOgADJCWk9EFEX+F8cZttNX/BNjluJX0+8MLnXBJf6nQMCAmVF0CizjCZbcKpraTsfqvN9dGcRWEw/yKMu8mS23r62d/7yvsO4csaDZTjeLkmgmT+VRD6GzzPe4a1hiaODAAy5pNerFcRCUjr9rHnXxfkwyfJ6rjjzF01nVwmnP3moDXrX63kH/mzbg3FuVOXE4WgUB7pNM+CKV4f+P4LOtIVSPsZ6Zl1MO7nni9Qn2nt0SOfQmnFzS+5ePYO5+zTJokftW0xWrx8ZruefWdYV80yYzhkE00LW//XpKN9oHSHjeKHda1x1MEend89iJntK4xkX7fTebF1trpWslnh4BY1g6QOVT3I1tQgJEA4biJ+xbjkWWvMUGKTPCs5kUwZzO09nddGbzZkSZE9eNE5cF9/P8bDcJ1nLSxAdeU9AaICrH2Iou5niRnsew+50L+PrYURNNb2vDthGZYxFRCuLyvxB4YxFMQNVPMjG6tbHivnw+IyRgNmRu6Tc7+J4orRx2yspVK8tXus+bXJXdVDELIowBCJ+mWp7N1NHK1gxlGAdoH5EGB2mygInF+5Ex73WMso+rUHB/NTv86gZzk2oL7eNVGl5x9trL9AQgEQY2Da7Ky5Vgj3kpTY7GDgecnhYHzx2NSu226DoINCCQB4HLCbRYKH4WiESEB33ctqMIcFNy1cxQ4+O5oulczrF50DBSAUYSUzwMAKjxkW9KqRcpsiGRDRV8G8FMBSx4ATmBbgZc4BDtBSqt8loGwZdUt0tKTEy4NEqxPIihARuh25p0aSFnp8I6yFFfxUtx5BaN0Hhw0msEYPd06G9dJWxw4A50DeYyBVIbY1js3JwuJSDxu7lo3GlN70HxPxCeRp9hJBEuzweqvuID2+qqwYlvh1BYXW3BxcHqiU+tdar4b2W1ccaO3/Naglb5YYvB6OAZb/LkSMaKgNrzG4WloCkuQN6gIoFZeK+e05XGuEpy+6Bw7U60uYeZWjcxOkc6eDSuUjpUUjoGIxZuZvERgMQFgDUSn/knK5cWEtIOkFS2IJQKGQNBpKcc8sgr+oW3WFhAV0Qa/sa78+eu3PfSBW7ASccZcV1veg78ZFq8HkOfAh7WsLiw5IAsB25/QKa5JhNm4jC3UDEncSjFEhvbkW+2Nt3Q0J+JABo2i6+wbDLnyPN1rrAMHHHFnfy+UXdN7aEcTNqTWsywiHq2/037QDg5t2XgNGhR054VyVWfZSnvIkbczMIBJbWGHYQd8COBD4DTC7iwLGYXgFAyPEgCICCXFvrrd3SrdaqI+Po9vp/L2SCsQASQW0u6+Fid4mPQnB/LnA6O+x0V9W1vyDY/e91VMnSz2ms9pAwlIy1WARVZKlCVjuhyAI8reTVttMh7/OwsHv8FhfdRFEaegbpHyA8WlI+hrDfU746m+I6JPO8HKAwMRnh8XLGFHtjSxCH8ygmeLhAoUIfXGZA8COHmDId6hU+OvCpZsGSQXLWDMczR4JShMQjQXDRBIgJ5wnfgqZO+MdqHyIWvZPAYA8+hMqyBPS8qdkcRitsZ1vntlxPy4K2MyFS8tKtrRSk7FOHmo1W6/OHDuG5pkzcNYgjroHusZ82w+8VqzkW6bZrO6Zq+2dTsxH8ky/6Cp1a+J5X4CjDUlsn/inNVc2m8PBQFgM2iL0fjqRAOPdNjO7e8jxM+SDPd970DM9SwOIVryosKua/AumX3n0QFI9cr3I9X9fsLxBKf9+a9jYKP4xCxcTYSZK3A8n20VoCgaIxGkh5Q87SjerEwnaHbdVenIPQJMCNNM15nnuW1lWfukEg3dOT/DxiagHM36w0zl+iki+CSZBQrzSmWqedNo8T8Jd09L4TBLbx0kQXNJCoW/Vgf7Vd18AeMHHmAO5cOiQoNxGYj3p4jNzESABEOYvEwALwtCLlRgdMKZxtpvM7ACwsVDApWGISjdaSACdEmrSRg2zdfG38Wq4cmFZ/yhMcksnuwvWtkvqOEphDc7zYCbcYOS3QwwfYdFe6XVP3HVGjx9MUP0t9Fx9F4rrHkIyN1ZWoc+1I7NNlRCK6ytFtrpQb4npTgw7UHR54Ym8MKIBQ8lEtQMMFLCoQgHrxGcr2haJ0+QCXwQFZtFmR/FMPg+GQblVR9nLVQwnGvA6IvBBVv8GAzOtBMd9a34/zNHjrAonWiRXkMolc8/c+v4HEb8bVw8D+BiAZh6YPQcHzJ/YWCIUnNOtVndsEMAkgADzwz0hwlDUHScAY6USyAfCsTUA+sYbOAaUh4AR9e4ZEgUSetpOtQstYPkeoDMCvDYCYATAKpBqg9kCQGN+A/i/B0wLQIsIoPnx0wHQYQCCBaQUcILAQAwgnn/752eocwtAgGSGAc/fzairqQ5mKEQSuuJQj/c8GJWK52A9D5DFY93xvZ+on92bwDkAFwF0AAoAYjl/nXBhdA6RiKB5/mBC592XCAE6d50YEF4D0EUAOSCUwPnzr2OQB0BJwFbm3yoP82dO0JhfOf/F6b0b9EE7/zTXMoRwmLttPaJiEaLTTcSe459n5+6xgvu8XPxku3HtUzO7t9eAf37PU6n33PL/LHLzO0K0ZRnQV4SYaSZiz7EfWMfTQqCkPPsTZ4Ia0Pv+j8/+L5yu7AvVlGWAKcsAU5YBpiwDTFkGmLIMMGUZYMoywJRlgCnLAFOWAaYsA0xZBpiyDDBlGWDKMsCUZYApywBTlgGmLANMWQaYsgwwZRlgyjLAlGWAKcsAU5YBpiwDTFkGmLIMMGX/BTNpY2P8E+A7AAAAAElFTkSuQmCC', 'WeIdentity是一套分布式多中心的技术解决方案。', 'WeIdentity目前主要包含两大模块:WeIdentity DID以及WeIdentity Credential。 WeIdentity DID模块在FISCO-BCOS区块链底层平台上实现了一套符合W3C DID规范的分布式多中心的身份标识协议,使实体(人或物)的现实身份实现了链上的身份标识;WeIdentity Credential提供了一整套基于W3C VC规范的解决方案,旨在对这一类数据进行标准化、电子化,生成可验证、可交换的「凭证」(Credential),支持对凭证的属性进行选择性披露,及生成链上存证(Evidence)。', now(), now()); -- ---------------------------- --- 9、init contract warehouse data (tb_ware_house, tb_contract_folder, tb_contract_item) +-- 9、init contract warehouse data (tb_warehouse, tb_contract_folder, tb_contract_item) -- ---------------------------- -- warehouse -INSERT INTO `tb_ware_house` (`id`, `ware_house_name`, `ware_house_name_en`, `type`, `ware_house_icon`, `description`, `description_en`, `ware_house_detail`, `ware_house_detail_en`, `create_time`, `modify_time`) VALUES (1, '工具箱', 'Toolbox', 1, 'toolboxId', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); -INSERT INTO `tb_ware_house` (`id`, `ware_house_name`, `ware_house_name_en`, `type`, `ware_house_icon`, `description`, `description_en`, `ware_house_detail`, `ware_house_detail_en`, `create_time`, `modify_time`) VALUES (2, '存证应用', 'Evidence', 2, 'evidenceId', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', now(), now()); -INSERT INTO `tb_ware_house` (`id`, `ware_house_name`, `ware_house_name_en`, `type`, `ware_house_icon`, `description`, `description_en`, `ware_house_detail`, `ware_house_detail_en`, `create_time`, `modify_time`) VALUES (3, '积分应用', 'Points', 3, 'pointsId', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); +INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES (1, '工具箱', 'Toolbox', 1, 'toolboxId', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); +INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES (2, '存证应用', 'Evidence', 2, 'evidenceId', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', now(), now()); +INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES (3, '积分应用', 'Points', 3, 'pointsId', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); -- folder -INSERT INTO `tb_contract_folder` (`id`, `ware_house_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (1, 1, 'Tools', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); -INSERT INTO `tb_contract_folder` (`id`, `ware_house_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (2, 2, 'Evidence', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', now(), now()); -INSERT INTO `tb_contract_folder` (`id`, `ware_house_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (3, 3, 'Points', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (1, 1, 'Tools', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (2, 2, 'Evidence', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (3, 3, 'Points', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); -- contract item of contract source & md desc, including tools, evidence, points(BAC) -- -- tools -- -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (1, 1, 1, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (1, 1, 1, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (2, 1, 1, 'LibString', 'Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgXjAuNC4xMTsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gUmV0dXJucyB0aGUgbWVtb3J5IGFkZHJlc3Mgb2YgdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YKICAgIC8vIGBuZWVkbGVgIGluIGBzZWxmYCwgb3IgdGhlIGZpcnN0IGJ5dGUgYWZ0ZXIgYHNlbGZgIGlmIG5vdCBmb3VuZC4KICAgIGZ1bmN0aW9uIGZpbmRQdHIodWludCBzZWxmbGVuLCB1aW50IHNlbGZwdHIsIHVpbnQgbmVlZGxlbGVuLCB1aW50IG5lZWRsZXB0cikgcHJpdmF0ZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgdWludCBwdHI7CiAgICAgICAgdWludCBpZHg7CgogICAgICAgIGlmIChuZWVkbGVsZW4gPD0gc2VsZmxlbikgewogICAgICAgICAgICBpZiAobmVlZGxlbGVuIDw9IDMyKSB7CiAgICAgICAgICAgICAgICAvLyBPcHRpbWl6ZWQgYXNzZW1ibHkgZm9yIDY4IGdhcyBwZXIgYnl0ZSBvbiBzaG9ydCBzdHJpbmdzCiAgICAgICAgICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IG1hc2sgOj0gbm90KHN1YihleHAoMiwgbXVsKDgsIHN1YigzMiwgbmVlZGxlbGVuKSkpLCAxKSkKICAgICAgICAgICAgICAgICAgICBsZXQgbmVlZGxlZGF0YSA6PSBhbmQobWxvYWQobmVlZGxlcHRyKSwgbWFzaykKICAgICAgICAgICAgICAgICAgICBsZXQgZW5kIDo9IGFkZChzZWxmcHRyLCBzdWIoc2VsZmxlbiwgbmVlZGxlbGVuKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gc2VsZnB0cgogICAgICAgICAgICAgICAgICAgIGxvb3A6CiAgICAgICAgICAgICAgICAgICAganVtcGkoZXhpdCwgZXEoYW5kKG1sb2FkKHB0ciksIG1hc2spLCBuZWVkbGVkYXRhKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHB0ciwgMSkKICAgICAgICAgICAgICAgICAgICBqdW1waShsb29wLCBsdChzdWIocHRyLCAxKSwgZW5kKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHNlbGZwdHIsIHNlbGZsZW4pCiAgICAgICAgICAgICAgICAgICAgZXhpdDoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBGb3IgbG9uZyBuZWVkbGVzLCB1c2UgaGFzaGluZwogICAgICAgICAgICAgICAgYnl0ZXMzMiBoYXNoOwogICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBoYXNoIDo9IHNoYTMobmVlZGxlcHRyLCBuZWVkbGVsZW4pIH0KICAgICAgICAgICAgICAgIHB0ciA9IHNlbGZwdHI7CiAgICAgICAgICAgICAgICBmb3IgKGlkeCA9IDA7IGlkeCA8PSBzZWxmbGVuIC0gbmVlZGxlbGVuOyBpZHgrKykgewogICAgICAgICAgICAgICAgICAgIGJ5dGVzMzIgdGVzdEhhc2g7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibHkgeyB0ZXN0SGFzaCA6PSBzaGEzKHB0ciwgbmVlZGxlbGVuKSB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc2ggPT0gdGVzdEhhc2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgICAgICAgICAgcHRyICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGZwdHIgKyBzZWxmbGVuOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9zdHIpIGludGVybmFsIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY29tcGFyZU5vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBieXRlIGNoMSA9IGJ5dGVzKF9zZWxmKVtpXXwweDIwOwogICAgICAgICAgICBieXRlIGNoMiA9IGJ5dGVzKF9zdHIpW2ldfDB4MjA7CiAgICAgICAgICAgIGlmIChjaDEgPj0gJ2EnICYmIGNoMSA8PSd6JyAmJiBjaDIgPj0gJ2EnICYmIGNoMiA8PSd6JykgewogICAgICAgICAgICAgICAgaWYgKGNoMSA+IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaDEgPCBjaDIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFscyhzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgYnl0ZSBjaDEgPSBieXRlcyhfc2VsZilbaV18MHgyMDsKICAgICAgICAgICAgYnl0ZSBjaDIgPSBieXRlcyhfc3RyKVtpXXwweDIwOwogICAgICAgICAgICBpZiAoY2gxID49ICdhJyAmJiBjaDEgPD0neicgJiYgY2gyID49ICdhJyAmJiBjaDIgPD0neicpIHsKICAgICAgICAgICAgICAgIGlmIChjaDEgIT0gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gc3Vic3RyKHN0cmluZyBfc2VsZiwgdWludCBfc3RhcnQsIHVpbnQgX2xlbikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKF9sZW4pOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK19zdGFydCwgX2xlbik7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIG1lbWNweShyZXRwdHIrYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc3RycHRyLCBieXRlcyhfc3RyKS5sZW5ndGgpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb25jYXQoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cjEsIHN0cmluZyBfc3RyMikKICAgICAgICBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyMSwgc3RyaW5nIF9zdHIyLCBzdHJpbmcgX3N0cjMpCiAgICAgICAgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhieXRlcyhfc2VsZikubGVuZ3RoICsgYnl0ZXMoX3N0cjEpLmxlbmd0aCArIGJ5dGVzKF9zdHIyKS5sZW5ndGgKICAgICAgICAgICAgKyBieXRlcyhfc3RyMykubGVuZ3RoKTsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgc3RyMXB0cjsKICAgICAgICB1aW50IHN0cjJwdHI7CiAgICAgICAgdWludCBzdHIzcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgc3RyM3B0ciA6PSBhZGQoX3N0cjMsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMXB0ciwgYnl0ZXMoX3N0cjEpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIxKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjJwdHIsIGJ5dGVzKF9zdHIyKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIzcHRyLCBieXRlcyhfc3RyMykubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjMpLmxlbmd0aDsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgdWludCBpOwogICAgICAgIHVpbnQ4IGNoOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBjaCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgaT4wOyAtLWkpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaS0xXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IGVuZCA9IGk7CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50MTYgajsKICAgICAgICBib29sIG1hdGNoZWQ7CiAgICAgICAgZm9yIChpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgc3RhcnQgPSBpOwogICAgICAgIAogICAgICAgIGZvciAoaT11aW50MTYoYnl0ZXMoX3NlbGYpLmxlbmd0aCk7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpLTFdID09IGJ5dGVzKF9jaGFycylbal0pIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIW1hdGNoZWQpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHVpbnQxNiBlbmQgPSBpOwoKICAgICAgICBpZiAoZW5kIDw9IHN0YXJ0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfZGVsaW0sIHN0cmluZ1tdIHN0b3JhZ2UgX2FycmF5KSBpbnRlcm5hbCB7CiAgICAgICAgLy9XaHkgY2FuIG5vdCB1c2UgZGVsZXRlIF9hcnJheT8KICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPF9hcnJheS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkZWxldGUgX2FycmF5W2ldOwogICAgICAgIH0KICAgICAgICBfYXJyYXkubGVuZ3RoID0gMDsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgZGVsaW1wdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgZGVsaW1wdHIgOj0gYWRkKF9kZWxpbSwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIHVpbnQgcHRyOwogICAgICAgICAgICBib29sIGZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChieXRlcyhfZGVsaW0pLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfZGVsaW0pLmxlbmd0aCwgZGVsaW1wdHIpIC0gc2VsZnB0cjsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKHB0ciA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHB0ciA9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwdHIgPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IGVsZW0gPSBuZXcgc3RyaW5nKHB0ci1wb3MpOwogICAgICAgICAgICB1aW50IGVsZW1wdHI7CiAgICAgICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgICAgIGVsZW1wdHIgOj0gYWRkKGVsZW0sIDB4MjApCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWVtY3B5KGVsZW1wdHIsIHNlbGZwdHIrcG9zLCBwdHItcG9zKTsKICAgICAgICAgICAgcG9zID0gcHRyICsgYnl0ZXMoX2RlbGltKS5sZW5ndGg7CiAgICAgICAgICAgIF9hcnJheS5wdXNoKGVsZW0pOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCFmb3VuZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc2VsZnB0ciwgYnl0ZXMoX3N0cikubGVuZ3RoLCBzdHJwdHIpIC0gc2VsZnB0cjsKICAgICAgICBpZiAocHRyIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICBfcmV0ID0gaW50KHB0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3JldCA9IC0xOwogICAgICAgIH0KICAgIH0KICAgIAogICAgZnVuY3Rpb24gaW5kZXhPZihzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyLCB1aW50IHBvcykgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfc3RyKS5sZW5ndGgsIHN0cnB0cikgLSBzZWxmcHRyOwogICAgICAgIGlmIChwdHIgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgIF9yZXQgPSBpbnQocHRyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBfcmV0ID0gLTE7CiAgICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0ludChzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGludCBfcmV0KSB7CiAgICAgICAgX3JldCA9IDA7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID09ICcrJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9IGVsc2UgaWYoYnl0ZXMoX3NlbGYpW2ldID09ICctJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQoKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA+PSAweDMwICYmIGRpZ2l0IDw9IDB4MzkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGFkZHJlc3MgX3JldCkgewogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aC1pIDwgMikgewogICAgICAgICAgICByZXR1cm4gYWRkcmVzcygwKTsKICAgICAgICB9CgogICAgICAgIC8vbXVzdCBzdGFydCB3aXRoIDB4CiAgICAgICAgaWYgKCEoYnl0ZXMoX3NlbGYpW2ldID09ICcwJyAmJiBieXRlcyhfc2VsZilbaSsxXXwweDIwID09ICd4JykpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICB1aW50IGFkZHIgPSAwOwogICAgICAgIAogICAgICAgIGZvciAoaSs9MjsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSAvLycwJy0nOScKICAgICAgICAgICAgICAgIGRpZ2l0IC09IDB4MzA7CiAgICAgICAgICAgIGVsc2UgaWYgKGRpZ2l0fDB4MjAgPj0gMHg2MSAmJiBkaWdpdHwweDIwIDw9IDB4NjYpIC8vJ2EnLSdmJwogICAgICAgICAgICAgICAgZGlnaXQgPSBkaWdpdC0weDYxKzEwOwogICAgICAgICAgICBlbHNlIAogICAgICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7IAogICAgICAgICAgICAKICAgICAgICAgICAgYWRkciA9IGFkZHIqMTYrZGlnaXQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBhZGRyZXNzKGFkZHIpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0tleVZhbHVlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9rZXkpLmxlbmd0aCArIDUpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IGtleXB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBrZXlwdHIgOj0gYWRkKF9rZXksIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwoKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIGtleXB0ciwgYnl0ZXMoX2tleSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX2tleSkubGVuZ3RoOwogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICAKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnOic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldFN0cmluZ1ZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc3RhcnQgKz0gMTsKICAgICAgICAKICAgICAgICBpbnQgZW5kOwogICAgICAgIGlmIChkb3VibGVRdW90ZXMpIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHN0YXJ0KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiJyIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVuZCA9PSAtMSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZi5zdWJzdHIodWludChzdGFydCksIHVpbnQoZW5kLXN0YXJ0KSk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldEludFZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdWludCBpID0gdWludChwb3MpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEgCiAgICAgICAgICAgIHx8IGRpZ2l0ID09IDB4M0EgLyo6Ki8gfHwgZGlnaXQgPT0gMHgyMiAvKiIqLyB8fCBkaWdpdCA9PSAweDI3IC8qJyovKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gdG9VcHBlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnYScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICd6JykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldICY9IH4weDIwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZjsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9Mb3dlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnQScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICdaJykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldIHw9IDB4MjA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IF9zZWxmOwogICAgfQoJCiAgICBmdW5jdGlvbiBrZXlFeGlzdHMoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFscyhfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogCiAgICBmdW5jdGlvbiBpbkFycmF5Tm9DYXNlKHN0cmluZyBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHNOb0Nhc2UoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgfQ==', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (2, 1, 1, 'LibString', 'Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgXjAuNC4xMTsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gUmV0dXJucyB0aGUgbWVtb3J5IGFkZHJlc3Mgb2YgdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YKICAgIC8vIGBuZWVkbGVgIGluIGBzZWxmYCwgb3IgdGhlIGZpcnN0IGJ5dGUgYWZ0ZXIgYHNlbGZgIGlmIG5vdCBmb3VuZC4KICAgIGZ1bmN0aW9uIGZpbmRQdHIodWludCBzZWxmbGVuLCB1aW50IHNlbGZwdHIsIHVpbnQgbmVlZGxlbGVuLCB1aW50IG5lZWRsZXB0cikgcHJpdmF0ZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgdWludCBwdHI7CiAgICAgICAgdWludCBpZHg7CgogICAgICAgIGlmIChuZWVkbGVsZW4gPD0gc2VsZmxlbikgewogICAgICAgICAgICBpZiAobmVlZGxlbGVuIDw9IDMyKSB7CiAgICAgICAgICAgICAgICAvLyBPcHRpbWl6ZWQgYXNzZW1ibHkgZm9yIDY4IGdhcyBwZXIgYnl0ZSBvbiBzaG9ydCBzdHJpbmdzCiAgICAgICAgICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IG1hc2sgOj0gbm90KHN1YihleHAoMiwgbXVsKDgsIHN1YigzMiwgbmVlZGxlbGVuKSkpLCAxKSkKICAgICAgICAgICAgICAgICAgICBsZXQgbmVlZGxlZGF0YSA6PSBhbmQobWxvYWQobmVlZGxlcHRyKSwgbWFzaykKICAgICAgICAgICAgICAgICAgICBsZXQgZW5kIDo9IGFkZChzZWxmcHRyLCBzdWIoc2VsZmxlbiwgbmVlZGxlbGVuKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gc2VsZnB0cgogICAgICAgICAgICAgICAgICAgIGxvb3A6CiAgICAgICAgICAgICAgICAgICAganVtcGkoZXhpdCwgZXEoYW5kKG1sb2FkKHB0ciksIG1hc2spLCBuZWVkbGVkYXRhKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHB0ciwgMSkKICAgICAgICAgICAgICAgICAgICBqdW1waShsb29wLCBsdChzdWIocHRyLCAxKSwgZW5kKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHNlbGZwdHIsIHNlbGZsZW4pCiAgICAgICAgICAgICAgICAgICAgZXhpdDoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBGb3IgbG9uZyBuZWVkbGVzLCB1c2UgaGFzaGluZwogICAgICAgICAgICAgICAgYnl0ZXMzMiBoYXNoOwogICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBoYXNoIDo9IHNoYTMobmVlZGxlcHRyLCBuZWVkbGVsZW4pIH0KICAgICAgICAgICAgICAgIHB0ciA9IHNlbGZwdHI7CiAgICAgICAgICAgICAgICBmb3IgKGlkeCA9IDA7IGlkeCA8PSBzZWxmbGVuIC0gbmVlZGxlbGVuOyBpZHgrKykgewogICAgICAgICAgICAgICAgICAgIGJ5dGVzMzIgdGVzdEhhc2g7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibHkgeyB0ZXN0SGFzaCA6PSBzaGEzKHB0ciwgbmVlZGxlbGVuKSB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc2ggPT0gdGVzdEhhc2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgICAgICAgICAgcHRyICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGZwdHIgKyBzZWxmbGVuOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9zdHIpIGludGVybmFsIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY29tcGFyZU5vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBieXRlIGNoMSA9IGJ5dGVzKF9zZWxmKVtpXXwweDIwOwogICAgICAgICAgICBieXRlIGNoMiA9IGJ5dGVzKF9zdHIpW2ldfDB4MjA7CiAgICAgICAgICAgIGlmIChjaDEgPj0gJ2EnICYmIGNoMSA8PSd6JyAmJiBjaDIgPj0gJ2EnICYmIGNoMiA8PSd6JykgewogICAgICAgICAgICAgICAgaWYgKGNoMSA+IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaDEgPCBjaDIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFscyhzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgYnl0ZSBjaDEgPSBieXRlcyhfc2VsZilbaV18MHgyMDsKICAgICAgICAgICAgYnl0ZSBjaDIgPSBieXRlcyhfc3RyKVtpXXwweDIwOwogICAgICAgICAgICBpZiAoY2gxID49ICdhJyAmJiBjaDEgPD0neicgJiYgY2gyID49ICdhJyAmJiBjaDIgPD0neicpIHsKICAgICAgICAgICAgICAgIGlmIChjaDEgIT0gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gc3Vic3RyKHN0cmluZyBfc2VsZiwgdWludCBfc3RhcnQsIHVpbnQgX2xlbikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKF9sZW4pOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK19zdGFydCwgX2xlbik7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIG1lbWNweShyZXRwdHIrYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc3RycHRyLCBieXRlcyhfc3RyKS5sZW5ndGgpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb25jYXQoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cjEsIHN0cmluZyBfc3RyMikKICAgICAgICBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyMSwgc3RyaW5nIF9zdHIyLCBzdHJpbmcgX3N0cjMpCiAgICAgICAgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhieXRlcyhfc2VsZikubGVuZ3RoICsgYnl0ZXMoX3N0cjEpLmxlbmd0aCArIGJ5dGVzKF9zdHIyKS5sZW5ndGgKICAgICAgICAgICAgKyBieXRlcyhfc3RyMykubGVuZ3RoKTsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgc3RyMXB0cjsKICAgICAgICB1aW50IHN0cjJwdHI7CiAgICAgICAgdWludCBzdHIzcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgc3RyM3B0ciA6PSBhZGQoX3N0cjMsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMXB0ciwgYnl0ZXMoX3N0cjEpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIxKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjJwdHIsIGJ5dGVzKF9zdHIyKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIzcHRyLCBieXRlcyhfc3RyMykubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjMpLmxlbmd0aDsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgdWludCBpOwogICAgICAgIHVpbnQ4IGNoOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBjaCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgaT4wOyAtLWkpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaS0xXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IGVuZCA9IGk7CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50MTYgajsKICAgICAgICBib29sIG1hdGNoZWQ7CiAgICAgICAgZm9yIChpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgc3RhcnQgPSBpOwogICAgICAgIAogICAgICAgIGZvciAoaT11aW50MTYoYnl0ZXMoX3NlbGYpLmxlbmd0aCk7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpLTFdID09IGJ5dGVzKF9jaGFycylbal0pIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIW1hdGNoZWQpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHVpbnQxNiBlbmQgPSBpOwoKICAgICAgICBpZiAoZW5kIDw9IHN0YXJ0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfZGVsaW0sIHN0cmluZ1tdIHN0b3JhZ2UgX2FycmF5KSBpbnRlcm5hbCB7CiAgICAgICAgLy9XaHkgY2FuIG5vdCB1c2UgZGVsZXRlIF9hcnJheT8KICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPF9hcnJheS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkZWxldGUgX2FycmF5W2ldOwogICAgICAgIH0KICAgICAgICBfYXJyYXkubGVuZ3RoID0gMDsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgZGVsaW1wdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgZGVsaW1wdHIgOj0gYWRkKF9kZWxpbSwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIHVpbnQgcHRyOwogICAgICAgICAgICBib29sIGZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChieXRlcyhfZGVsaW0pLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfZGVsaW0pLmxlbmd0aCwgZGVsaW1wdHIpIC0gc2VsZnB0cjsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKHB0ciA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHB0ciA9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwdHIgPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IGVsZW0gPSBuZXcgc3RyaW5nKHB0ci1wb3MpOwogICAgICAgICAgICB1aW50IGVsZW1wdHI7CiAgICAgICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgICAgIGVsZW1wdHIgOj0gYWRkKGVsZW0sIDB4MjApCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWVtY3B5KGVsZW1wdHIsIHNlbGZwdHIrcG9zLCBwdHItcG9zKTsKICAgICAgICAgICAgcG9zID0gcHRyICsgYnl0ZXMoX2RlbGltKS5sZW5ndGg7CiAgICAgICAgICAgIF9hcnJheS5wdXNoKGVsZW0pOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCFmb3VuZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc2VsZnB0ciwgYnl0ZXMoX3N0cikubGVuZ3RoLCBzdHJwdHIpIC0gc2VsZnB0cjsKICAgICAgICBpZiAocHRyIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICBfcmV0ID0gaW50KHB0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3JldCA9IC0xOwogICAgICAgIH0KICAgIH0KICAgIAogICAgZnVuY3Rpb24gaW5kZXhPZihzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyLCB1aW50IHBvcykgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfc3RyKS5sZW5ndGgsIHN0cnB0cikgLSBzZWxmcHRyOwogICAgICAgIGlmIChwdHIgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgIF9yZXQgPSBpbnQocHRyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBfcmV0ID0gLTE7CiAgICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0ludChzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGludCBfcmV0KSB7CiAgICAgICAgX3JldCA9IDA7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID09ICcrJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9IGVsc2UgaWYoYnl0ZXMoX3NlbGYpW2ldID09ICctJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQoKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA+PSAweDMwICYmIGRpZ2l0IDw9IDB4MzkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGFkZHJlc3MgX3JldCkgewogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aC1pIDwgMikgewogICAgICAgICAgICByZXR1cm4gYWRkcmVzcygwKTsKICAgICAgICB9CgogICAgICAgIC8vbXVzdCBzdGFydCB3aXRoIDB4CiAgICAgICAgaWYgKCEoYnl0ZXMoX3NlbGYpW2ldID09ICcwJyAmJiBieXRlcyhfc2VsZilbaSsxXXwweDIwID09ICd4JykpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICB1aW50IGFkZHIgPSAwOwogICAgICAgIAogICAgICAgIGZvciAoaSs9MjsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSAvLycwJy0nOScKICAgICAgICAgICAgICAgIGRpZ2l0IC09IDB4MzA7CiAgICAgICAgICAgIGVsc2UgaWYgKGRpZ2l0fDB4MjAgPj0gMHg2MSAmJiBkaWdpdHwweDIwIDw9IDB4NjYpIC8vJ2EnLSdmJwogICAgICAgICAgICAgICAgZGlnaXQgPSBkaWdpdC0weDYxKzEwOwogICAgICAgICAgICBlbHNlIAogICAgICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7IAogICAgICAgICAgICAKICAgICAgICAgICAgYWRkciA9IGFkZHIqMTYrZGlnaXQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBhZGRyZXNzKGFkZHIpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0tleVZhbHVlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9rZXkpLmxlbmd0aCArIDUpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IGtleXB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBrZXlwdHIgOj0gYWRkKF9rZXksIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwoKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIGtleXB0ciwgYnl0ZXMoX2tleSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX2tleSkubGVuZ3RoOwogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICAKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnOic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldFN0cmluZ1ZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc3RhcnQgKz0gMTsKICAgICAgICAKICAgICAgICBpbnQgZW5kOwogICAgICAgIGlmIChkb3VibGVRdW90ZXMpIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHN0YXJ0KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiJyIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVuZCA9PSAtMSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZi5zdWJzdHIodWludChzdGFydCksIHVpbnQoZW5kLXN0YXJ0KSk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldEludFZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdWludCBpID0gdWludChwb3MpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEgCiAgICAgICAgICAgIHx8IGRpZ2l0ID09IDB4M0EgLyo6Ki8gfHwgZGlnaXQgPT0gMHgyMiAvKiIqLyB8fCBkaWdpdCA9PSAweDI3IC8qJyovKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gdG9VcHBlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnYScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICd6JykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldICY9IH4weDIwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZjsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9Mb3dlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnQScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICdaJykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldIHw9IDB4MjA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IF9zZWxmOwogICAgfQoJCiAgICBmdW5jdGlvbiBrZXlFeGlzdHMoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFscyhfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogCiAgICBmdW5jdGlvbiBpbkFycmF5Tm9DYXNlKHN0cmluZyBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHNOb0Nhc2UoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgfQ==', 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (3, 1, 1, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (3, 1, 1, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (4, 1, 1, 'Table', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7Cgpjb250cmFjdCBUYWJsZUZhY3RvcnkgewogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoVGFibGUpOyAvL29wZW4gdGFibGUKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOyAvL2NyZWF0ZSB0YWJsZQp9CgovL3NlbGVjdCBjb25kaXRpb24KY29udHJhY3QgQ29uZGl0aW9uIHsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgc3RyaW5nKSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgYWRkcmVzcykgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBpbnQyNTYpIHB1YmxpYyB2aWV3OwogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyB2aWV3OwoKICAgIGZ1bmN0aW9uIEdUKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEdFKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKCiAgICBmdW5jdGlvbiBMVChzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CiAgICBmdW5jdGlvbiBMRShzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gbGltaXQoaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIGxpbWl0KGludDI1NiwgaW50MjU2KSBwdWJsaWMgdmlldzsKfQoKLy9vbmUgcmVjb3JkCmNvbnRyYWN0IEVudHJ5IHsKICAgIGZ1bmN0aW9uIGdldEludChzdHJpbmcpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRVSW50KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRBZGRyZXNzKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcyk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczY0KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMxWzY0XSk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczMyKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMzMik7CiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcpOwoKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcsIGludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgdWludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgc3RyaW5nKSBwdWJsaWM7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBhZGRyZXNzKSBwdWJsaWM7Cn0KCi8vcmVjb3JkIHNldHMKY29udHJhY3QgRW50cmllcyB7CiAgICBmdW5jdGlvbiBnZXQoaW50MjU2KSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBzaXplKCkgcHVibGljIHZpZXcgcmV0dXJucyAoaW50MjU2KTsKfQoKLy9UYWJsZSBtYWluIGNvbnRyYWN0CmNvbnRyYWN0IFRhYmxlIHsKICAgIGZ1bmN0aW9uIHNlbGVjdChzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHZpZXcgcmV0dXJucyAoRW50cmllcyk7CiAgICBmdW5jdGlvbiBpbnNlcnQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiB1cGRhdGUoc3RyaW5nLCBFbnRyeSwgQ29uZGl0aW9uKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KTsKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHJldHVybnMgKGludDI1Nik7CgogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBuZXdDb25kaXRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChDb25kaXRpb24pOwp9Cgpjb250cmFjdCBLVlRhYmxlRmFjdG9yeSB7CiAgICBmdW5jdGlvbiBvcGVuVGFibGUoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChLVlRhYmxlKTsKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOwp9CgovL0tWVGFibGUgcGVyIHBlcm1pYXJ5IGtleSBoYXMgb25seSBvbmUgRW50cnkKY29udHJhY3QgS1ZUYWJsZSB7CiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sLCBFbnRyeSk7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBuZXdFbnRyeSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KTsKfQo=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (4, 1, 1, 'Table', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7Cgpjb250cmFjdCBUYWJsZUZhY3RvcnkgewogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoVGFibGUpOyAvL29wZW4gdGFibGUKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOyAvL2NyZWF0ZSB0YWJsZQp9CgovL3NlbGVjdCBjb25kaXRpb24KY29udHJhY3QgQ29uZGl0aW9uIHsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgc3RyaW5nKSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgYWRkcmVzcykgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBpbnQyNTYpIHB1YmxpYyB2aWV3OwogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyB2aWV3OwoKICAgIGZ1bmN0aW9uIEdUKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEdFKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKCiAgICBmdW5jdGlvbiBMVChzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CiAgICBmdW5jdGlvbiBMRShzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gbGltaXQoaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIGxpbWl0KGludDI1NiwgaW50MjU2KSBwdWJsaWMgdmlldzsKfQoKLy9vbmUgcmVjb3JkCmNvbnRyYWN0IEVudHJ5IHsKICAgIGZ1bmN0aW9uIGdldEludChzdHJpbmcpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRVSW50KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRBZGRyZXNzKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcyk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczY0KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMxWzY0XSk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczMyKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMzMik7CiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcpOwoKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcsIGludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgdWludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgc3RyaW5nKSBwdWJsaWM7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBhZGRyZXNzKSBwdWJsaWM7Cn0KCi8vcmVjb3JkIHNldHMKY29udHJhY3QgRW50cmllcyB7CiAgICBmdW5jdGlvbiBnZXQoaW50MjU2KSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBzaXplKCkgcHVibGljIHZpZXcgcmV0dXJucyAoaW50MjU2KTsKfQoKLy9UYWJsZSBtYWluIGNvbnRyYWN0CmNvbnRyYWN0IFRhYmxlIHsKICAgIGZ1bmN0aW9uIHNlbGVjdChzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHZpZXcgcmV0dXJucyAoRW50cmllcyk7CiAgICBmdW5jdGlvbiBpbnNlcnQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiB1cGRhdGUoc3RyaW5nLCBFbnRyeSwgQ29uZGl0aW9uKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KTsKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHJldHVybnMgKGludDI1Nik7CgogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBuZXdDb25kaXRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChDb25kaXRpb24pOwp9Cgpjb250cmFjdCBLVlRhYmxlRmFjdG9yeSB7CiAgICBmdW5jdGlvbiBvcGVuVGFibGUoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChLVlRhYmxlKTsKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOwp9CgovL0tWVGFibGUgcGVyIHBlcm1pYXJ5IGtleSBoYXMgb25seSBvbmUgRW50cnkKY29udHJhY3QgS1ZUYWJsZSB7CiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sLCBFbnRyeSk7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBuZXdFbnRyeSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KTsKfQo=', 'IyB0YWJsZQoKdGFibGUgbGlicmFyeQoKQkNPUyBDUlVEIHVzZXMgdGhlIGJhc2UgbGlicmFyeSwgd2hpY2ggeW91IGNhbiByZWZlcmVuY2UgYnkgcmUtY29udHJhY3QgY2FsbGluZyBDUlVELlRhYmxlIGNvbnRyYWN0IHVzYWdlIG1ldGhvZHMgY2FuIGJlIGRlc2NyaWJlZCBieSByZWZlcnJpbmcgdG8gdGhlIGFzc2F0IGV4YW1wbGUgaW4gdGhlIGJjb3MgZG9jdW1lbnQgaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8u', 'IyB0YWJsZQoKdGFibGUgbGlicmFyeQoKQkNPUyBDUlVEIHVzZXMgdGhlIGJhc2UgbGlicmFyeSwgd2hpY2ggeW91IGNhbiByZWZlcmVuY2UgYnkgcmUtY29udHJhY3QgY2FsbGluZyBDUlVELlRhYmxlIGNvbnRyYWN0IHVzYWdlIG1ldGhvZHMgY2FuIGJlIGRlc2NyaWJlZCBieSByZWZlcnJpbmcgdG8gdGhlIGFzc2F0IGV4YW1wbGUgaW4gdGhlIGJjb3MgZG9jdW1lbnQgaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8u', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (5, 1, 1, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (5, 1, 1, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); -- evidence -- -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (6, 2, 2, 'Evidence', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YUFCSXsgZnVuY3Rpb24gdmVyaWZ5KGFkZHJlc3MgYWRkcilwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhib29sKXt9CmZ1bmN0aW9uIGdldFNpZ25lcih1aW50IGluZGV4KXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3Mpe30gCmZ1bmN0aW9uIGdldFNpZ25lcnNTaXplKCkgcHVibGljIGNvbnN0YW50IHJldHVybnModWludCl7fQp9Cgpjb250cmFjdCBFdmlkZW5jZXsKICAgIAogICAgc3RyaW5nIGV2aWRlbmNlOwogICAgc3RyaW5nIGV2aWRlbmNlSW5mbzsKICAgIHN0cmluZyBldmlkZW5jZUlkOwogICAgdWludDhbXSBfdjsKICAgIGJ5dGVzMzJbXSBfcjsKICAgIGJ5dGVzMzJbXSBfczsKICAgIGFkZHJlc3NbXSBzaWduZXJzOwogICAgYWRkcmVzcyBwdWJsaWMgc2lnbmVyc0FkZHI7CiAgICAKICAgICAgICBldmVudCBhZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IG5ld1NpZ25hdHVyZXNFdmVudChzdHJpbmcgZXZpLCBzdHJpbmcgaW5mbywgc3RyaW5nIGlkLCB1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcyxhZGRyZXNzIGFkZHIpOwogICAgICAgIGV2ZW50IGVycm9yTmV3U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLGFkZHJlc3MgYWRkcik7CiAgICAgICAgZXZlbnQgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsYWRkcmVzcyBhZGRyKTsKICAgICAgICBldmVudCBhZGRSZXBlYXRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsIGFkZHJlc3MgYWRkcik7CgogICAgZnVuY3Rpb24gQ2FsbFZlcmlmeShhZGRyZXNzIGFkZHIpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpIHsKICAgICAgICByZXR1cm4gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikudmVyaWZ5KGFkZHIpOwogICAgfQoKICAgICAgIGZ1bmN0aW9uIEV2aWRlbmNlKHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLCBhZGRyZXNzIGFkZHIsIGFkZHJlc3Mgc2VuZGVyKSBwdWJsaWMgewogICAgICAgc2lnbmVyc0FkZHIgPSBhZGRyOwogICAgICAgaWYoQ2FsbFZlcmlmeShzZW5kZXIpKQogICAgICAgewogICAgICAgICAgIGV2aWRlbmNlID0gZXZpOwogICAgICAgICAgIGV2aWRlbmNlSW5mbyA9IGluZm87CiAgICAgICAgICAgZXZpZGVuY2VJZCA9IGlkOwogICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgX3IucHVzaChyKTsKICAgICAgICAgICBfcy5wdXNoKHMpOwogICAgICAgICAgIHNpZ25lcnMucHVzaChzZW5kZXIpOwogICAgICAgICAgIG5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgICAgIGVsc2UKICAgICAgIHsKICAgICAgICAgICBlcnJvck5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgIH0KCiAgICAgICAgZnVuY3Rpb24gZ2V0RXZpZGVuY2VJbmZvKCkgcHVibGljIGNvbnN0YW50IHJldHVybnMoc3RyaW5nKXsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlSW5mbzsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRFdmlkZW5jZSgpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKHN0cmluZyxzdHJpbmcsc3RyaW5nLHVpbnQ4W10sYnl0ZXMzMltdLGJ5dGVzMzJbXSxhZGRyZXNzW10pewogICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICByZXR1cm4oZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsX3YsX3IsX3Msc2lnbmVyTGlzdCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkU2lnbmF0dXJlcyh1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcykgcHVibGljIHJldHVybnMoYm9vbCkgewogICAgICAgIGZvcih1aW50IGk9IDAgO2k8c2lnbmVycy5sZW5ndGggO2krKykKICAgICAgICB7CiAgICAgICAgICAgIGlmKG1zZy5zZW5kZXIgPT0gc2lnbmVyc1tpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoIF92W2ldID09IHYgJiYgX3JbaV0gPT0gciAmJiBfc1tpXSA9PSBzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFkZFJlcGVhdFNpZ25hdHVyZXNFdmVudChldmlkZW5jZSxldmlkZW5jZUluZm8sZXZpZGVuY2VJZCx2LHIscyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgIGlmKENhbGxWZXJpZnkobXNnLnNlbmRlcikpCiAgICAgICB7CiAgICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgIF9yLnB1c2gocik7CiAgICAgICAgICAgIF9zLnB1c2gocyk7CiAgICAgICAgICAgIHNpZ25lcnMucHVzaChtc2cuc2VuZGVyKTsKICAgICAgICAgICAgYWRkU2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSW5mbyxldmlkZW5jZUlkLHYscixzKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICB9CiAgICAgICBlbHNlCiAgICAgICB7CiAgICAgICAgICAgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTaWduZXJzKClwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhhZGRyZXNzW10pCiAgICB7CiAgICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHNpZ25lckxpc3Q7CiAgICB9Cn0=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (6, 2, 2, 'Evidence', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YUFCSXsgZnVuY3Rpb24gdmVyaWZ5KGFkZHJlc3MgYWRkcilwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhib29sKXt9CmZ1bmN0aW9uIGdldFNpZ25lcih1aW50IGluZGV4KXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3Mpe30gCmZ1bmN0aW9uIGdldFNpZ25lcnNTaXplKCkgcHVibGljIGNvbnN0YW50IHJldHVybnModWludCl7fQp9Cgpjb250cmFjdCBFdmlkZW5jZXsKICAgIAogICAgc3RyaW5nIGV2aWRlbmNlOwogICAgc3RyaW5nIGV2aWRlbmNlSW5mbzsKICAgIHN0cmluZyBldmlkZW5jZUlkOwogICAgdWludDhbXSBfdjsKICAgIGJ5dGVzMzJbXSBfcjsKICAgIGJ5dGVzMzJbXSBfczsKICAgIGFkZHJlc3NbXSBzaWduZXJzOwogICAgYWRkcmVzcyBwdWJsaWMgc2lnbmVyc0FkZHI7CiAgICAKICAgICAgICBldmVudCBhZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IG5ld1NpZ25hdHVyZXNFdmVudChzdHJpbmcgZXZpLCBzdHJpbmcgaW5mbywgc3RyaW5nIGlkLCB1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcyxhZGRyZXNzIGFkZHIpOwogICAgICAgIGV2ZW50IGVycm9yTmV3U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLGFkZHJlc3MgYWRkcik7CiAgICAgICAgZXZlbnQgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsYWRkcmVzcyBhZGRyKTsKICAgICAgICBldmVudCBhZGRSZXBlYXRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsIGFkZHJlc3MgYWRkcik7CgogICAgZnVuY3Rpb24gQ2FsbFZlcmlmeShhZGRyZXNzIGFkZHIpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpIHsKICAgICAgICByZXR1cm4gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikudmVyaWZ5KGFkZHIpOwogICAgfQoKICAgICAgIGZ1bmN0aW9uIEV2aWRlbmNlKHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLCBhZGRyZXNzIGFkZHIsIGFkZHJlc3Mgc2VuZGVyKSBwdWJsaWMgewogICAgICAgc2lnbmVyc0FkZHIgPSBhZGRyOwogICAgICAgaWYoQ2FsbFZlcmlmeShzZW5kZXIpKQogICAgICAgewogICAgICAgICAgIGV2aWRlbmNlID0gZXZpOwogICAgICAgICAgIGV2aWRlbmNlSW5mbyA9IGluZm87CiAgICAgICAgICAgZXZpZGVuY2VJZCA9IGlkOwogICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgX3IucHVzaChyKTsKICAgICAgICAgICBfcy5wdXNoKHMpOwogICAgICAgICAgIHNpZ25lcnMucHVzaChzZW5kZXIpOwogICAgICAgICAgIG5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgICAgIGVsc2UKICAgICAgIHsKICAgICAgICAgICBlcnJvck5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgIH0KCiAgICAgICAgZnVuY3Rpb24gZ2V0RXZpZGVuY2VJbmZvKCkgcHVibGljIGNvbnN0YW50IHJldHVybnMoc3RyaW5nKXsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlSW5mbzsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRFdmlkZW5jZSgpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKHN0cmluZyxzdHJpbmcsc3RyaW5nLHVpbnQ4W10sYnl0ZXMzMltdLGJ5dGVzMzJbXSxhZGRyZXNzW10pewogICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICByZXR1cm4oZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsX3YsX3IsX3Msc2lnbmVyTGlzdCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkU2lnbmF0dXJlcyh1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcykgcHVibGljIHJldHVybnMoYm9vbCkgewogICAgICAgIGZvcih1aW50IGk9IDAgO2k8c2lnbmVycy5sZW5ndGggO2krKykKICAgICAgICB7CiAgICAgICAgICAgIGlmKG1zZy5zZW5kZXIgPT0gc2lnbmVyc1tpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoIF92W2ldID09IHYgJiYgX3JbaV0gPT0gciAmJiBfc1tpXSA9PSBzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFkZFJlcGVhdFNpZ25hdHVyZXNFdmVudChldmlkZW5jZSxldmlkZW5jZUluZm8sZXZpZGVuY2VJZCx2LHIscyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgIGlmKENhbGxWZXJpZnkobXNnLnNlbmRlcikpCiAgICAgICB7CiAgICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgIF9yLnB1c2gocik7CiAgICAgICAgICAgIF9zLnB1c2gocyk7CiAgICAgICAgICAgIHNpZ25lcnMucHVzaChtc2cuc2VuZGVyKTsKICAgICAgICAgICAgYWRkU2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSW5mbyxldmlkZW5jZUlkLHYscixzKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICB9CiAgICAgICBlbHNlCiAgICAgICB7CiAgICAgICAgICAgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTaWduZXJzKClwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhhZGRyZXNzW10pCiAgICB7CiAgICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHNpZ25lckxpc3Q7CiAgICB9Cn0=', 'IyBFdmlkZW5jZSDlkIjnuqYKCiMjIOeugOS7iwpFdmlkZW5jZSDnpLrkvovlkIjnuqbvvIzkvb/nlKjliIblsYLnmoTmmbrog73lkIjnuqbnu5PmnoTvvJogCjHvvInlt6XljoLlkIjnuqbvvIhFdmlkZW5jZVNpZ25lcnNEYXRhLnNvbO+8ie+8jOeUseWtmOivgeWQhOaWueS6i+WJjee6puWumu+8jOWtmOWCqOWtmOivgeeUn+aViOadoeS7tu+8jOW5tueuoeeQhuWtmOivgeeahOeUn+aIkOOAgiAgCjLvvInlrZjor4HlkIjnuqbvvIhFdmlkZW5jZS5zb2zvvInvvIznlLHlt6XljoLlkIjnuqbnlJ/miJDvvIzlrZjlgqjlrZjor4FpZO+8jGhhc2jlkozlkITmlrnnrb7lkI3vvIjmr4/lvKDlrZjor4HkuIDkuKrlkIjnuqbvvInjgIIgIA==', '', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (7, 2, 2, 'EvidenceSignersData', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKaW1wb3J0ICJFdmlkZW5jZS5zb2wiOwoKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YXsKICAgICAgICBhZGRyZXNzW10gc2lnbmVyczsKCQlldmVudCBuZXdFdmlkZW5jZUV2ZW50KGFkZHJlc3MgYWRkcik7CiAgICAgICAgZnVuY3Rpb24gbmV3RXZpZGVuY2Uoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sc3RyaW5nIGlkLHVpbnQ4IHYsIGJ5dGVzMzIgcixieXRlczMyIHMpcHVibGljIHJldHVybnMoYWRkcmVzcykKICAgICAgICB7CiAgICAgICAgICAgIEV2aWRlbmNlIGV2aWRlbmNlID0gbmV3IEV2aWRlbmNlKGV2aSwgaW5mbywgaWQsIHYsIHIsIHMsIHRoaXMsIG1zZy5zZW5kZXIpOwogICAgICAgICAgICBuZXdFdmlkZW5jZUV2ZW50KGV2aWRlbmNlKTsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gRXZpZGVuY2VTaWduZXJzRGF0YShhZGRyZXNzW10gZXZpZGVuY2VTaWduZXJzKXB1YmxpY3sKICAgICAgICAgICAgZm9yKHVpbnQgaT0wOyBpPGV2aWRlbmNlU2lnbmVycy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBzaWduZXJzLnB1c2goZXZpZGVuY2VTaWduZXJzW2ldKTsKCQkJfQoJCX0KCiAgICBmdW5jdGlvbiB2ZXJpZnkoYWRkcmVzcyBhZGRyKXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpewogICAgZm9yKHVpbnQgaT0wOyBpPHNpZ25lcnMubGVuZ3RoOyArK2kpIHsKICAgICAgICBpZiAoYWRkciA9PSBzaWduZXJzW2ldKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyKHVpbnQgaW5kZXgpcHVibGljIGNvbnN0YW50IHJldHVybnMoYWRkcmVzcyl7CiAgICAgICAgdWludCBsaXN0U2l6ZSA9IHNpZ25lcnMubGVuZ3RoOwogICAgICAgIGlmKGluZGV4IDwgbGlzdFNpemUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc2lnbmVyc1tpbmRleF07CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyc1NpemUoKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyh1aW50KXsKICAgICAgICByZXR1cm4gc2lnbmVycy5sZW5ndGg7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVycygpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3NbXSl7CiAgICAgICAgcmV0dXJuIHNpZ25lcnM7CiAgICB9Cgp9', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (7, 2, 2, 'EvidenceSignersData', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKaW1wb3J0ICJFdmlkZW5jZS5zb2wiOwoKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YXsKICAgICAgICBhZGRyZXNzW10gc2lnbmVyczsKCQlldmVudCBuZXdFdmlkZW5jZUV2ZW50KGFkZHJlc3MgYWRkcik7CiAgICAgICAgZnVuY3Rpb24gbmV3RXZpZGVuY2Uoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sc3RyaW5nIGlkLHVpbnQ4IHYsIGJ5dGVzMzIgcixieXRlczMyIHMpcHVibGljIHJldHVybnMoYWRkcmVzcykKICAgICAgICB7CiAgICAgICAgICAgIEV2aWRlbmNlIGV2aWRlbmNlID0gbmV3IEV2aWRlbmNlKGV2aSwgaW5mbywgaWQsIHYsIHIsIHMsIHRoaXMsIG1zZy5zZW5kZXIpOwogICAgICAgICAgICBuZXdFdmlkZW5jZUV2ZW50KGV2aWRlbmNlKTsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gRXZpZGVuY2VTaWduZXJzRGF0YShhZGRyZXNzW10gZXZpZGVuY2VTaWduZXJzKXB1YmxpY3sKICAgICAgICAgICAgZm9yKHVpbnQgaT0wOyBpPGV2aWRlbmNlU2lnbmVycy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBzaWduZXJzLnB1c2goZXZpZGVuY2VTaWduZXJzW2ldKTsKCQkJfQoJCX0KCiAgICBmdW5jdGlvbiB2ZXJpZnkoYWRkcmVzcyBhZGRyKXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpewogICAgZm9yKHVpbnQgaT0wOyBpPHNpZ25lcnMubGVuZ3RoOyArK2kpIHsKICAgICAgICBpZiAoYWRkciA9PSBzaWduZXJzW2ldKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyKHVpbnQgaW5kZXgpcHVibGljIGNvbnN0YW50IHJldHVybnMoYWRkcmVzcyl7CiAgICAgICAgdWludCBsaXN0U2l6ZSA9IHNpZ25lcnMubGVuZ3RoOwogICAgICAgIGlmKGluZGV4IDwgbGlzdFNpemUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc2lnbmVyc1tpbmRleF07CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyc1NpemUoKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyh1aW50KXsKICAgICAgICByZXR1cm4gc2lnbmVycy5sZW5ndGg7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVycygpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3NbXSl7CiAgICAgICAgcmV0dXJuIHNpZ25lcnM7CiAgICB9Cgp9', 'IyBFdmlkZW5jZSDlkIjnuqYKCiMjIOeugOS7iwpFdmlkZW5jZSDnpLrkvovlkIjnuqbvvIzkvb/nlKjliIblsYLnmoTmmbrog73lkIjnuqbnu5PmnoTvvJogCjHvvInlt6XljoLlkIjnuqbvvIhFdmlkZW5jZVNpZ25lcnNEYXRhLnNvbO+8ie+8jOeUseWtmOivgeWQhOaWueS6i+WJjee6puWumu+8jOWtmOWCqOWtmOivgeeUn+aViOadoeS7tu+8jOW5tueuoeeQhuWtmOivgeeahOeUn+aIkOOAgiAgCjLvvInlrZjor4HlkIjnuqbvvIhFdmlkZW5jZS5zb2zvvInvvIznlLHlt6XljoLlkIjnuqbnlJ/miJDvvIzlrZjlgqjlrZjor4FpZO+8jGhhc2jlkozlkITmlrnnrb7lkI3vvIjmr4/lvKDlrZjor4HkuIDkuKrlkIjnuqbvvInjgIIgIA==', '', now(), now()); -- bac points -- -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (8, 3, 3, 'BAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgppbXBvcnQgIi4vU2FmZU1hdGguc29sIjsKaW1wb3J0ICIuL1JvbGVzLnNvbCI7CmltcG9ydCAiLi9BZGRyZXNzLnNvbCI7Cgpjb250cmFjdCBJc3N1ZXJSb2xlIHsKICAgIHVzaW5nIFJvbGVzIGZvciBSb2xlcy5Sb2xlOwoKICAgIGV2ZW50IElzc3VlckFkZGVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKICAgIGV2ZW50IElzc3VlclJlbW92ZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwoKICAgIFJvbGVzLlJvbGUgcHJpdmF0ZSBfaXNzdWVyczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX2FkZElzc3Vlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBtb2RpZmllciBvbmx5SXNzdWVyKCkgewogICAgICAgIHJlcXVpcmUoaXNJc3N1ZXIobXNnLnNlbmRlciksICJJc3N1ZXJSb2xlOiBjYWxsZXIgZG9lcyBub3QgaGF2ZSB0aGUgSXNzdWVyIHJvbGUiKTsKICAgICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfaXNzdWVycy5oYXMoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIG9ubHlJc3N1ZXIgewogICAgICAgIF9hZGRJc3N1ZXIoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVub3VuY2VJc3N1ZXIoKSBwdWJsaWMgewogICAgICAgIF9yZW1vdmVJc3N1ZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZElzc3VlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfaXNzdWVycy5hZGQoYWNjb3VudCk7CiAgICAgICAgZW1pdCBJc3N1ZXJBZGRlZChhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcmVtb3ZlSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9pc3N1ZXJzLnJlbW92ZShhY2NvdW50KTsKICAgICAgICBlbWl0IElzc3VlclJlbW92ZWQoYWNjb3VudCk7CiAgICB9Cn0KCmNvbnRyYWN0IFN1c3BlbmRlclJvbGUgewogICAgdXNpbmcgUm9sZXMgZm9yIFJvbGVzLlJvbGU7CgogICAgZXZlbnQgU3VzcGVuZGVyQWRkZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwogICAgZXZlbnQgU3VzcGVuZGVyUmVtb3ZlZChhZGRyZXNzIGluZGV4ZWQgYWNjb3VudCk7CgogICAgUm9sZXMuUm9sZSBwcml2YXRlIF9zdXNwZW5kZXJzOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfYWRkU3VzcGVuZGVyKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIG1vZGlmaWVyIG9ubHlTdXNwZW5kZXIoKSB7CiAgICAgICAgcmVxdWlyZShpc1N1c3BlbmRlcihtc2cuc2VuZGVyKSwgIlN1c3BlbmRlclJvbGU6IGNhbGxlciBkb2VzIG5vdCBoYXZlIHRoZSBTdXNwZW5kZXIgcm9sZSIpOwogICAgICAgIF87CiAgICB9CgogICAgZnVuY3Rpb24gaXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZXJzLmhhcyhhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgb25seVN1c3BlbmRlciB7CiAgICAgICAgX2FkZFN1c3BlbmRlcihhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiByZW5vdW5jZVN1c3BlbmRlcigpIHB1YmxpYyB7CiAgICAgICAgX3JlbW92ZVN1c3BlbmRlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBfYWRkU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9zdXNwZW5kZXJzLmFkZChhY2NvdW50KTsKICAgICAgICBlbWl0IFN1c3BlbmRlckFkZGVkKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9yZW1vdmVTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB7CiAgICAgICAgX3N1c3BlbmRlcnMucmVtb3ZlKGFjY291bnQpOwogICAgICAgIGVtaXQgU3VzcGVuZGVyUmVtb3ZlZChhY2NvdW50KTsKICAgIH0KfQoKY29udHJhY3QgU3VzcGVuZGFibGUgaXMgU3VzcGVuZGVyUm9sZSB7CgogICAgZXZlbnQgU3VzcGVuZGVkKGFkZHJlc3MgYWNjb3VudCk7CiAgICBldmVudCBVblN1c3BlbmRlZChhZGRyZXNzIGFjY291bnQpOwoKICAgIGJvb2wgcHJpdmF0ZSBfc3VzcGVuZGVkOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfc3VzcGVuZGVkID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNvbnRyYWN0IGlzIHN1c3BlbmRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBmdW5jdGlvbiBzdXNwZW5kZWQoKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IE1vZGlmaWVyIHRvIG1ha2UgYSBmdW5jdGlvbiBjYWxsYWJsZSBvbmx5IHdoZW4gdGhlIGNvbnRyYWN0IGlzIG5vdCBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5Ob3RTdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZSghX3N1c3BlbmRlZCwgIlN1c3BlbmRhYmxlOiBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNb2RpZmllciB0byBtYWtlIGEgZnVuY3Rpb24gY2FsbGFibGUgb25seSB3aGVuIHRoZSBjb250cmFjdCBpcyBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5TdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZShfc3VzcGVuZGVkLCAiU3VzcGVuZGFibGU6IG5vdCBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gc3VzcGVuZCwgdHJpZ2dlcnMgc3RvcHBlZCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VzcGVuZCgpIHB1YmxpYyBvbmx5U3VzcGVuZGVyIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zdXNwZW5kZWQgPSB0cnVlOwogICAgICAgIGVtaXQgU3VzcGVuZGVkKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gdW5TdXNwZW5kLCByZXR1cm5zIHRvIG5vcm1hbCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gdW5TdXNwZW5kKCkgcHVibGljIG9ubHlTdXNwZW5kZXIgd2hlblN1c3BlbmRlZCB7CiAgICAgICAgX3N1c3BlbmRlZCA9IGZhbHNlOwogICAgICAgIGVtaXQgVW5TdXNwZW5kZWQobXNnLnNlbmRlcik7CiAgICB9Cn0KCmNvbnRyYWN0IElCQUMwMDFSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBub3RpY2UgSGFuZGxlIHRoZSByZWNlaXB0IG9mIGFuIE5GVAogICAgICogQGRldiBUaGUgQkFDMDAxIHNtYXJ0IGNvbnRyYWN0IGNhbGxzIHRoaXMgZnVuY3Rpb24gb24gdGhlIHJlY2lwaWVudAogICAgICovCiAgICBmdW5jdGlvbiBvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3Mgb3BlcmF0b3IsIGFkZHJlc3MgZnJvbSwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkKICAgIHB1YmxpYyByZXR1cm5zIChieXRlczQpOwp9Cgpjb250cmFjdCBCQUMwMDFIb2xkZXIgaXMgSUJBQzAwMVJlY2VpdmVyIHsKICAgIGZ1bmN0aW9uIG9uQkFDMDAxUmVjZWl2ZWQoYWRkcmVzcywgYWRkcmVzcywgdWludDI1NiwgYnl0ZXMpIHB1YmxpYyByZXR1cm5zIChieXRlczQpIHsKICAgICAgICByZXR1cm4gdGhpcy5vbkJBQzAwMVJlY2VpdmVkLnNlbGVjdG9yOwogICAgfQp9CgoKLyoqCiAqIEB0aXRsZSBTdGFuZGFyZCBCQUMwMDEgYXNzZXQKICovCmNvbnRyYWN0IEJBQzAwMSBpcyBJc3N1ZXJSb2xlLCBTdXNwZW5kYWJsZSB7CiAgICB1c2luZyBTYWZlTWF0aCBmb3IgdWludDI1NjsKICAgIHVzaW5nIEFkZHJlc3MgZm9yIGFkZHJlc3M7CgogICAgbWFwcGluZyhhZGRyZXNzID0+IHVpbnQyNTYpIHByaXZhdGUgX2JhbGFuY2VzOwogICAgbWFwcGluZyhhZGRyZXNzID0+IG1hcHBpbmcoYWRkcmVzcyA9PiB1aW50MjU2KSkgcHJpdmF0ZSBfYWxsb3dlZDsKICAgIHVpbnQyNTYgcHJpdmF0ZSBfdG90YWxBbW91bnQ7CiAgICBzdHJpbmcgcHJpdmF0ZSBfZGVzY3JpcHRpb247CiAgICBzdHJpbmcgcHJpdmF0ZSBfc2hvcnROYW1lOwogICAgdWludDggcHJpdmF0ZSAgX21pblVuaXQ7CgogICAgLy8gRXF1YWxzIHRvIGBieXRlczQoa2VjY2FrMjU2KCJvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3MsYWRkcmVzcyx1aW50MjU2LGJ5dGVzKSIpKWAKICAgIGJ5dGVzNCBwcml2YXRlIGNvbnN0YW50IF9CQUMwMDFfUkVDRUlWRUQgPSAweGM3M2QxNmFlOwoKCiAgICBldmVudCBTZW5kKCBhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKTsKICAgIGV2ZW50IEFwcHJvdmFsKCBhZGRyZXNzIGluZGV4ZWQgb3duZXIsIGFkZHJlc3MgaW5kZXhlZCBzcGVuZGVyLCB1aW50MjU2IHZhbHVlKTsKCgogICAgY29uc3RydWN0b3Ioc3RyaW5nIG1lbW9yeSBkZXNjcmlwdGlvbiwgc3RyaW5nIG1lbW9yeSBzaG9ydE5hbWUsIHVpbnQ4IG1pblVuaXQsIHVpbnQyNTYgdG90YWxBbW91bnQpIHB1YmxpYyB7CiAgICAgICAgX2Rlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgX3Nob3J0TmFtZSA9IHNob3J0TmFtZTsKICAgICAgICBfbWluVW5pdCA9IG1pblVuaXQ7CiAgICAgICAgX2lzc3VlKG1zZy5zZW5kZXIsIHRvdGFsQW1vdW50ICogKDEwICoqIHVpbnQyNTYobWluVW5pdCkpLCAiIik7CiAgICB9CgoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJldHVybiBfdG90YWxBbW91bnQ7CiAgICB9CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9iYWxhbmNlc1tvd25lcl07CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEZ1bmN0aW9uIHRvIGNoZWNrIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFsbG93YW5jZShhZGRyZXNzIG93bmVyLCBhZGRyZXNzIHNwZW5kZXIpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2FsbG93ZWRbb3duZXJdW3NwZW5kZXJdOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zZW5kKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7CgogICAgfQoKLy8gICAgZnVuY3Rpb24gc2FmZVNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewovLyAgICAgICAgc2VuZCh0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgLyoqCiAgICAgKiBAZGV2IEFwcHJvdmUgdGhlIHBhc3NlZCBhZGRyZXNzIHRvIHNwZW5kIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIGFzc2V0cyBvbiBiZWhhbGYgb2YgbXNnLnNlbmRlci4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBfYXBwcm92ZShtc2cuc2VuZGVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlbmQgYXNzZXRzIGZyb20gb25lIGFkZHJlc3MgdG8gYW5vdGhlci4KICAgICAqLwogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgX3NlbmQoZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgICAgICBfYXBwcm92ZShmcm9tLCBtc2cuc2VuZGVyLCBfYWxsb3dlZFtmcm9tXVttc2cuc2VuZGVyXS5zdWIodmFsdWUpKTsKICAgICAgICAvL2FkZAogICAgICAgIHJlcXVpcmUoX2NoZWNrT25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpLCAiQkFDMDAxOiBzZW5kIHRvIG5vbiBCQUMwMDFSZWNlaXZlciBpbXBsZW1lbnRlciIpOwoKCiAgICB9CgovLy8vIHNhZmUgdG9kbwovLyAgICBmdW5jdGlvbiBzYWZlU2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7Ci8vICAgICAgICBzZW5kRnJvbShmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKGZyb20sIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgZnVuY3Rpb24gYmF0Y2hTZW5kKGFkZHJlc3NbXSB0bywgdWludDI1NltdIHZhbHVlcywgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewoKICAgICAgICAvLyBNVVNUIFRocm93IG9uIGVycm9ycwoKICAgICAgICByZXF1aXJlKHRvLmxlbmd0aCA9PSB2YWx1ZXMubGVuZ3RoLCAidG8gYW5kIHZhbHVlcyBhcnJheSBsZW5naHQgbXVzdCBtYXRjaC4iKTsKCiAgICAgICAgZm9yICh1aW50MjU2IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVxdWlyZSh0b1tpXSAhPSBhZGRyZXNzKDB4MCksICJkZXN0aW5hdGlvbiBhZGRyZXNzIG11c3QgYmUgbm9uLXplcm8uIik7CgogICAgICAgICAgICBzZW5kKHRvW2ldLCB2YWx1ZXNbaV0sIGRhdGEpOwogICAgICAgIH0KICAgIH0KCgogICAgZnVuY3Rpb24gX2NoZWNrT25CQUMwMDFSZWNlaXZlZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpCiAgICBpbnRlcm5hbCByZXR1cm5zIChib29sKQogICAgewogICAgICAgIGlmICghdG8uaXNDb250cmFjdCgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgYnl0ZXM0IHJldHZhbCA9IElCQUMwMDFSZWNlaXZlcih0bykub25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwogICAgICAgIHJldHVybiAocmV0dmFsID09IF9CQUMwMDFfUkVDRUlWRUQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbmNyZWFzZSB0aGUgYW1vdW50IG9mIGFzc2V0cyB0aGF0IGFuIG93bmVyIGFsbG93ZWQgdG8gYSBzcGVuZGVyLgogICAgICovCiAgICBmdW5jdGlvbiBpbmNyZWFzZUFsbG93YW5jZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYWRkZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLmFkZChhZGRlZFZhbHVlKSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IERlY3JlYXNlIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKiBhcHByb3ZlIHNob3VsZCBiZSBjYWxsZWQgd2hlbiBfYWxsb3dlZFttc2cuc2VuZGVyXVtzcGVuZGVyXSA9PSAwLiBUbyBkZWNyZW1lbnQKICAgICAqLwogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLnN1YihzdWJ0cmFjdGVkVmFsdWUpKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXN0cm95KHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3kobXNnLnNlbmRlciwgdmFsdWUsIGRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBCdXJucyBhIHNwZWNpZmljIGFtb3VudCBvZiBhc3NldHMgZnJvbSB0aGUgdGFyZ2V0IGFkZHJlc3MgYW5kIGRlY3JlbWVudHMgYWxsb3dhbmNlLgogICAgICovCiAgICBmdW5jdGlvbiBkZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3lGcm9tKGZyb20sIHZhbHVlLCBkYXRhKTsKICAgIH0KCgogICAgZnVuY3Rpb24gZGVzY3JpcHRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIF9kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIHNob3J0TmFtZSBvZiB0aGUgYXNzZXQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNob3J0TmFtZSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX3Nob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBtaW5Vbml0IG9mIHRoZSBhc3NldC4KICAgICAqLwogICAgZnVuY3Rpb24gbWluVW5pdCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQ4KSB7CiAgICAgICAgcmV0dXJuIF9taW5Vbml0OwogICAgfQoKCiAgICBmdW5jdGlvbiBpc3N1ZShhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgb25seUlzc3VlciByZXR1cm5zIChib29sKSB7CiAgICAgICAgX2lzc3VlKHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXYgU2VuZCBhc3NldCBmb3IgYSBzcGVjaWZpZWQgYWRkcmVzc2VzLgogICAgICovCiAgICBmdW5jdGlvbiBfc2VuZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKHRvICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IHNlbmQgdG8gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfYmFsYW5jZXNbZnJvbV0gPSBfYmFsYW5jZXNbZnJvbV0uc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbdG9dID0gX2JhbGFuY2VzW3RvXS5hZGQodmFsdWUpOwogICAgICAgIGVtaXQgU2VuZCggZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCBpc3N1ZXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBhbmQgYXNzaWducyBpdCB0bwogICAgICovCiAgICBmdW5jdGlvbiBfaXNzdWUoYWRkcmVzcyBhY2NvdW50LCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShhY2NvdW50ICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IGlzc3VlIHRvIHRoZSB6ZXJvIGFkZHJlc3MiKTsKCiAgICAgICAgX3RvdGFsQW1vdW50ID0gX3RvdGFsQW1vdW50LmFkZCh2YWx1ZSk7CiAgICAgICAgX2JhbGFuY2VzW2FjY291bnRdID0gX2JhbGFuY2VzW2FjY291bnRdLmFkZCh2YWx1ZSk7CiAgICAgICAgZW1pdCBTZW5kKCBhZGRyZXNzKDApLCBhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95KGFkZHJlc3MgYWNjb3VudCwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiQkFDMDAxOiBkZXN0cm95IGZyb20gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfdG90YWxBbW91bnQgPSBfdG90YWxBbW91bnQuc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbYWNjb3VudF0gPSBfYmFsYW5jZXNbYWNjb3VudF0uc3ViKHZhbHVlKTsKICAgICAgICBlbWl0IFNlbmQoIGFjY291bnQsIGFkZHJlc3MoMCksIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZSBhbiBhZGRyZXNzIHRvIHNwZW5kIGFub3RoZXIgYWRkcmVzc2VzJyBhc3NldHMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hcHByb3ZlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiB2YWx1ZSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUob3duZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSBmcm9tIHRoZSB6ZXJvIGFkZHJlc3MiKTsKICAgICAgICByZXF1aXJlKHNwZW5kZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSB0byB0aGUgemVybyBhZGRyZXNzIik7CgogICAgICAgIF9hbGxvd2VkW293bmVyXVtzcGVuZGVyXSA9IHZhbHVlOwogICAgICAgIGVtaXQgQXBwcm92YWwoIG93bmVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95RnJvbShhZGRyZXNzIGFjY291bnQsIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICBfZGVzdHJveShhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgX2FwcHJvdmUoYWNjb3VudCwgbXNnLnNlbmRlciwgX2FsbG93ZWRbYWNjb3VudF1bbXNnLnNlbmRlcl0uc3ViKHZhbHVlKSk7CiAgICB9Cn0KCg==', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (8, 3, 3, 'BAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgppbXBvcnQgIi4vU2FmZU1hdGguc29sIjsKaW1wb3J0ICIuL1JvbGVzLnNvbCI7CmltcG9ydCAiLi9BZGRyZXNzLnNvbCI7Cgpjb250cmFjdCBJc3N1ZXJSb2xlIHsKICAgIHVzaW5nIFJvbGVzIGZvciBSb2xlcy5Sb2xlOwoKICAgIGV2ZW50IElzc3VlckFkZGVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKICAgIGV2ZW50IElzc3VlclJlbW92ZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwoKICAgIFJvbGVzLlJvbGUgcHJpdmF0ZSBfaXNzdWVyczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX2FkZElzc3Vlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBtb2RpZmllciBvbmx5SXNzdWVyKCkgewogICAgICAgIHJlcXVpcmUoaXNJc3N1ZXIobXNnLnNlbmRlciksICJJc3N1ZXJSb2xlOiBjYWxsZXIgZG9lcyBub3QgaGF2ZSB0aGUgSXNzdWVyIHJvbGUiKTsKICAgICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfaXNzdWVycy5oYXMoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIG9ubHlJc3N1ZXIgewogICAgICAgIF9hZGRJc3N1ZXIoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVub3VuY2VJc3N1ZXIoKSBwdWJsaWMgewogICAgICAgIF9yZW1vdmVJc3N1ZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZElzc3VlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfaXNzdWVycy5hZGQoYWNjb3VudCk7CiAgICAgICAgZW1pdCBJc3N1ZXJBZGRlZChhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcmVtb3ZlSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9pc3N1ZXJzLnJlbW92ZShhY2NvdW50KTsKICAgICAgICBlbWl0IElzc3VlclJlbW92ZWQoYWNjb3VudCk7CiAgICB9Cn0KCmNvbnRyYWN0IFN1c3BlbmRlclJvbGUgewogICAgdXNpbmcgUm9sZXMgZm9yIFJvbGVzLlJvbGU7CgogICAgZXZlbnQgU3VzcGVuZGVyQWRkZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwogICAgZXZlbnQgU3VzcGVuZGVyUmVtb3ZlZChhZGRyZXNzIGluZGV4ZWQgYWNjb3VudCk7CgogICAgUm9sZXMuUm9sZSBwcml2YXRlIF9zdXNwZW5kZXJzOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfYWRkU3VzcGVuZGVyKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIG1vZGlmaWVyIG9ubHlTdXNwZW5kZXIoKSB7CiAgICAgICAgcmVxdWlyZShpc1N1c3BlbmRlcihtc2cuc2VuZGVyKSwgIlN1c3BlbmRlclJvbGU6IGNhbGxlciBkb2VzIG5vdCBoYXZlIHRoZSBTdXNwZW5kZXIgcm9sZSIpOwogICAgICAgIF87CiAgICB9CgogICAgZnVuY3Rpb24gaXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZXJzLmhhcyhhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgb25seVN1c3BlbmRlciB7CiAgICAgICAgX2FkZFN1c3BlbmRlcihhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiByZW5vdW5jZVN1c3BlbmRlcigpIHB1YmxpYyB7CiAgICAgICAgX3JlbW92ZVN1c3BlbmRlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBfYWRkU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9zdXNwZW5kZXJzLmFkZChhY2NvdW50KTsKICAgICAgICBlbWl0IFN1c3BlbmRlckFkZGVkKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9yZW1vdmVTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB7CiAgICAgICAgX3N1c3BlbmRlcnMucmVtb3ZlKGFjY291bnQpOwogICAgICAgIGVtaXQgU3VzcGVuZGVyUmVtb3ZlZChhY2NvdW50KTsKICAgIH0KfQoKY29udHJhY3QgU3VzcGVuZGFibGUgaXMgU3VzcGVuZGVyUm9sZSB7CgogICAgZXZlbnQgU3VzcGVuZGVkKGFkZHJlc3MgYWNjb3VudCk7CiAgICBldmVudCBVblN1c3BlbmRlZChhZGRyZXNzIGFjY291bnQpOwoKICAgIGJvb2wgcHJpdmF0ZSBfc3VzcGVuZGVkOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfc3VzcGVuZGVkID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNvbnRyYWN0IGlzIHN1c3BlbmRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBmdW5jdGlvbiBzdXNwZW5kZWQoKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IE1vZGlmaWVyIHRvIG1ha2UgYSBmdW5jdGlvbiBjYWxsYWJsZSBvbmx5IHdoZW4gdGhlIGNvbnRyYWN0IGlzIG5vdCBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5Ob3RTdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZSghX3N1c3BlbmRlZCwgIlN1c3BlbmRhYmxlOiBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNb2RpZmllciB0byBtYWtlIGEgZnVuY3Rpb24gY2FsbGFibGUgb25seSB3aGVuIHRoZSBjb250cmFjdCBpcyBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5TdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZShfc3VzcGVuZGVkLCAiU3VzcGVuZGFibGU6IG5vdCBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gc3VzcGVuZCwgdHJpZ2dlcnMgc3RvcHBlZCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VzcGVuZCgpIHB1YmxpYyBvbmx5U3VzcGVuZGVyIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zdXNwZW5kZWQgPSB0cnVlOwogICAgICAgIGVtaXQgU3VzcGVuZGVkKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gdW5TdXNwZW5kLCByZXR1cm5zIHRvIG5vcm1hbCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gdW5TdXNwZW5kKCkgcHVibGljIG9ubHlTdXNwZW5kZXIgd2hlblN1c3BlbmRlZCB7CiAgICAgICAgX3N1c3BlbmRlZCA9IGZhbHNlOwogICAgICAgIGVtaXQgVW5TdXNwZW5kZWQobXNnLnNlbmRlcik7CiAgICB9Cn0KCmNvbnRyYWN0IElCQUMwMDFSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBub3RpY2UgSGFuZGxlIHRoZSByZWNlaXB0IG9mIGFuIE5GVAogICAgICogQGRldiBUaGUgQkFDMDAxIHNtYXJ0IGNvbnRyYWN0IGNhbGxzIHRoaXMgZnVuY3Rpb24gb24gdGhlIHJlY2lwaWVudAogICAgICovCiAgICBmdW5jdGlvbiBvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3Mgb3BlcmF0b3IsIGFkZHJlc3MgZnJvbSwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkKICAgIHB1YmxpYyByZXR1cm5zIChieXRlczQpOwp9Cgpjb250cmFjdCBCQUMwMDFIb2xkZXIgaXMgSUJBQzAwMVJlY2VpdmVyIHsKICAgIGZ1bmN0aW9uIG9uQkFDMDAxUmVjZWl2ZWQoYWRkcmVzcywgYWRkcmVzcywgdWludDI1NiwgYnl0ZXMpIHB1YmxpYyByZXR1cm5zIChieXRlczQpIHsKICAgICAgICByZXR1cm4gdGhpcy5vbkJBQzAwMVJlY2VpdmVkLnNlbGVjdG9yOwogICAgfQp9CgoKLyoqCiAqIEB0aXRsZSBTdGFuZGFyZCBCQUMwMDEgYXNzZXQKICovCmNvbnRyYWN0IEJBQzAwMSBpcyBJc3N1ZXJSb2xlLCBTdXNwZW5kYWJsZSB7CiAgICB1c2luZyBTYWZlTWF0aCBmb3IgdWludDI1NjsKICAgIHVzaW5nIEFkZHJlc3MgZm9yIGFkZHJlc3M7CgogICAgbWFwcGluZyhhZGRyZXNzID0+IHVpbnQyNTYpIHByaXZhdGUgX2JhbGFuY2VzOwogICAgbWFwcGluZyhhZGRyZXNzID0+IG1hcHBpbmcoYWRkcmVzcyA9PiB1aW50MjU2KSkgcHJpdmF0ZSBfYWxsb3dlZDsKICAgIHVpbnQyNTYgcHJpdmF0ZSBfdG90YWxBbW91bnQ7CiAgICBzdHJpbmcgcHJpdmF0ZSBfZGVzY3JpcHRpb247CiAgICBzdHJpbmcgcHJpdmF0ZSBfc2hvcnROYW1lOwogICAgdWludDggcHJpdmF0ZSAgX21pblVuaXQ7CgogICAgLy8gRXF1YWxzIHRvIGBieXRlczQoa2VjY2FrMjU2KCJvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3MsYWRkcmVzcyx1aW50MjU2LGJ5dGVzKSIpKWAKICAgIGJ5dGVzNCBwcml2YXRlIGNvbnN0YW50IF9CQUMwMDFfUkVDRUlWRUQgPSAweGM3M2QxNmFlOwoKCiAgICBldmVudCBTZW5kKCBhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKTsKICAgIGV2ZW50IEFwcHJvdmFsKCBhZGRyZXNzIGluZGV4ZWQgb3duZXIsIGFkZHJlc3MgaW5kZXhlZCBzcGVuZGVyLCB1aW50MjU2IHZhbHVlKTsKCgogICAgY29uc3RydWN0b3Ioc3RyaW5nIG1lbW9yeSBkZXNjcmlwdGlvbiwgc3RyaW5nIG1lbW9yeSBzaG9ydE5hbWUsIHVpbnQ4IG1pblVuaXQsIHVpbnQyNTYgdG90YWxBbW91bnQpIHB1YmxpYyB7CiAgICAgICAgX2Rlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgX3Nob3J0TmFtZSA9IHNob3J0TmFtZTsKICAgICAgICBfbWluVW5pdCA9IG1pblVuaXQ7CiAgICAgICAgX2lzc3VlKG1zZy5zZW5kZXIsIHRvdGFsQW1vdW50ICogKDEwICoqIHVpbnQyNTYobWluVW5pdCkpLCAiIik7CiAgICB9CgoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJldHVybiBfdG90YWxBbW91bnQ7CiAgICB9CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9iYWxhbmNlc1tvd25lcl07CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEZ1bmN0aW9uIHRvIGNoZWNrIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFsbG93YW5jZShhZGRyZXNzIG93bmVyLCBhZGRyZXNzIHNwZW5kZXIpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2FsbG93ZWRbb3duZXJdW3NwZW5kZXJdOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zZW5kKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7CgogICAgfQoKLy8gICAgZnVuY3Rpb24gc2FmZVNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewovLyAgICAgICAgc2VuZCh0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgLyoqCiAgICAgKiBAZGV2IEFwcHJvdmUgdGhlIHBhc3NlZCBhZGRyZXNzIHRvIHNwZW5kIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIGFzc2V0cyBvbiBiZWhhbGYgb2YgbXNnLnNlbmRlci4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBfYXBwcm92ZShtc2cuc2VuZGVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlbmQgYXNzZXRzIGZyb20gb25lIGFkZHJlc3MgdG8gYW5vdGhlci4KICAgICAqLwogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgX3NlbmQoZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgICAgICBfYXBwcm92ZShmcm9tLCBtc2cuc2VuZGVyLCBfYWxsb3dlZFtmcm9tXVttc2cuc2VuZGVyXS5zdWIodmFsdWUpKTsKICAgICAgICAvL2FkZAogICAgICAgIHJlcXVpcmUoX2NoZWNrT25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpLCAiQkFDMDAxOiBzZW5kIHRvIG5vbiBCQUMwMDFSZWNlaXZlciBpbXBsZW1lbnRlciIpOwoKCiAgICB9CgovLy8vIHNhZmUgdG9kbwovLyAgICBmdW5jdGlvbiBzYWZlU2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7Ci8vICAgICAgICBzZW5kRnJvbShmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKGZyb20sIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgZnVuY3Rpb24gYmF0Y2hTZW5kKGFkZHJlc3NbXSB0bywgdWludDI1NltdIHZhbHVlcywgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewoKICAgICAgICAvLyBNVVNUIFRocm93IG9uIGVycm9ycwoKICAgICAgICByZXF1aXJlKHRvLmxlbmd0aCA9PSB2YWx1ZXMubGVuZ3RoLCAidG8gYW5kIHZhbHVlcyBhcnJheSBsZW5naHQgbXVzdCBtYXRjaC4iKTsKCiAgICAgICAgZm9yICh1aW50MjU2IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVxdWlyZSh0b1tpXSAhPSBhZGRyZXNzKDB4MCksICJkZXN0aW5hdGlvbiBhZGRyZXNzIG11c3QgYmUgbm9uLXplcm8uIik7CgogICAgICAgICAgICBzZW5kKHRvW2ldLCB2YWx1ZXNbaV0sIGRhdGEpOwogICAgICAgIH0KICAgIH0KCgogICAgZnVuY3Rpb24gX2NoZWNrT25CQUMwMDFSZWNlaXZlZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpCiAgICBpbnRlcm5hbCByZXR1cm5zIChib29sKQogICAgewogICAgICAgIGlmICghdG8uaXNDb250cmFjdCgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgYnl0ZXM0IHJldHZhbCA9IElCQUMwMDFSZWNlaXZlcih0bykub25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwogICAgICAgIHJldHVybiAocmV0dmFsID09IF9CQUMwMDFfUkVDRUlWRUQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbmNyZWFzZSB0aGUgYW1vdW50IG9mIGFzc2V0cyB0aGF0IGFuIG93bmVyIGFsbG93ZWQgdG8gYSBzcGVuZGVyLgogICAgICovCiAgICBmdW5jdGlvbiBpbmNyZWFzZUFsbG93YW5jZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYWRkZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLmFkZChhZGRlZFZhbHVlKSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IERlY3JlYXNlIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKiBhcHByb3ZlIHNob3VsZCBiZSBjYWxsZWQgd2hlbiBfYWxsb3dlZFttc2cuc2VuZGVyXVtzcGVuZGVyXSA9PSAwLiBUbyBkZWNyZW1lbnQKICAgICAqLwogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLnN1YihzdWJ0cmFjdGVkVmFsdWUpKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXN0cm95KHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3kobXNnLnNlbmRlciwgdmFsdWUsIGRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBCdXJucyBhIHNwZWNpZmljIGFtb3VudCBvZiBhc3NldHMgZnJvbSB0aGUgdGFyZ2V0IGFkZHJlc3MgYW5kIGRlY3JlbWVudHMgYWxsb3dhbmNlLgogICAgICovCiAgICBmdW5jdGlvbiBkZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3lGcm9tKGZyb20sIHZhbHVlLCBkYXRhKTsKICAgIH0KCgogICAgZnVuY3Rpb24gZGVzY3JpcHRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIF9kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIHNob3J0TmFtZSBvZiB0aGUgYXNzZXQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNob3J0TmFtZSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX3Nob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBtaW5Vbml0IG9mIHRoZSBhc3NldC4KICAgICAqLwogICAgZnVuY3Rpb24gbWluVW5pdCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQ4KSB7CiAgICAgICAgcmV0dXJuIF9taW5Vbml0OwogICAgfQoKCiAgICBmdW5jdGlvbiBpc3N1ZShhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgb25seUlzc3VlciByZXR1cm5zIChib29sKSB7CiAgICAgICAgX2lzc3VlKHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXYgU2VuZCBhc3NldCBmb3IgYSBzcGVjaWZpZWQgYWRkcmVzc2VzLgogICAgICovCiAgICBmdW5jdGlvbiBfc2VuZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKHRvICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IHNlbmQgdG8gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfYmFsYW5jZXNbZnJvbV0gPSBfYmFsYW5jZXNbZnJvbV0uc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbdG9dID0gX2JhbGFuY2VzW3RvXS5hZGQodmFsdWUpOwogICAgICAgIGVtaXQgU2VuZCggZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCBpc3N1ZXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBhbmQgYXNzaWducyBpdCB0bwogICAgICovCiAgICBmdW5jdGlvbiBfaXNzdWUoYWRkcmVzcyBhY2NvdW50LCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShhY2NvdW50ICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IGlzc3VlIHRvIHRoZSB6ZXJvIGFkZHJlc3MiKTsKCiAgICAgICAgX3RvdGFsQW1vdW50ID0gX3RvdGFsQW1vdW50LmFkZCh2YWx1ZSk7CiAgICAgICAgX2JhbGFuY2VzW2FjY291bnRdID0gX2JhbGFuY2VzW2FjY291bnRdLmFkZCh2YWx1ZSk7CiAgICAgICAgZW1pdCBTZW5kKCBhZGRyZXNzKDApLCBhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95KGFkZHJlc3MgYWNjb3VudCwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiQkFDMDAxOiBkZXN0cm95IGZyb20gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfdG90YWxBbW91bnQgPSBfdG90YWxBbW91bnQuc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbYWNjb3VudF0gPSBfYmFsYW5jZXNbYWNjb3VudF0uc3ViKHZhbHVlKTsKICAgICAgICBlbWl0IFNlbmQoIGFjY291bnQsIGFkZHJlc3MoMCksIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZSBhbiBhZGRyZXNzIHRvIHNwZW5kIGFub3RoZXIgYWRkcmVzc2VzJyBhc3NldHMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hcHByb3ZlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiB2YWx1ZSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUob3duZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSBmcm9tIHRoZSB6ZXJvIGFkZHJlc3MiKTsKICAgICAgICByZXF1aXJlKHNwZW5kZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSB0byB0aGUgemVybyBhZGRyZXNzIik7CgogICAgICAgIF9hbGxvd2VkW293bmVyXVtzcGVuZGVyXSA9IHZhbHVlOwogICAgICAgIGVtaXQgQXBwcm92YWwoIG93bmVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95RnJvbShhZGRyZXNzIGFjY291bnQsIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICBfZGVzdHJveShhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgX2FwcHJvdmUoYWNjb3VudCwgbXNnLnNlbmRlciwgX2FsbG93ZWRbYWNjb3VudF1bbXNnLnNlbmRlcl0uc3ViKHZhbHVlKSk7CiAgICB9Cn0KCg==', 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (9, 3, 3, 'IBAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKaW50ZXJmYWNlIElCQUMwMDEgewoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KTsKCiAgICBmdW5jdGlvbiBzZW5kKGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyA7CgogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gYWxsb3dhbmNlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYW1vdW50KSBwdWJsaWMgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVzdHJveSh1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gZGVzdHJveUZyb20oYWRkcmVzcyBmcm9tLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBmdW5jdGlvbiBiYXRjaFNlbmQoYWRkcmVzc1tdIHRvLCB1aW50MjU2W10gdmFsdWVzLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaW5jcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IGFkZGVkVmFsdWUpIHB1YmxpYyAgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBldmVudCBTZW5kKGFkZHJlc3MgaW5kZXhlZCBmcm9tLCBhZGRyZXNzIGluZGV4ZWQgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpOwoKICAgIGV2ZW50IEFwcHJvdmFsKGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpOwoKfQ==', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (9, 3, 3, 'IBAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKaW50ZXJmYWNlIElCQUMwMDEgewoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KTsKCiAgICBmdW5jdGlvbiBzZW5kKGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyA7CgogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gYWxsb3dhbmNlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYW1vdW50KSBwdWJsaWMgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVzdHJveSh1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gZGVzdHJveUZyb20oYWRkcmVzcyBmcm9tLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBmdW5jdGlvbiBiYXRjaFNlbmQoYWRkcmVzc1tdIHRvLCB1aW50MjU2W10gdmFsdWVzLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaW5jcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IGFkZGVkVmFsdWUpIHB1YmxpYyAgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBldmVudCBTZW5kKGFkZHJlc3MgaW5kZXhlZCBmcm9tLCBhZGRyZXNzIGluZGV4ZWQgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpOwoKICAgIGV2ZW50IEFwcHJvdmFsKGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpOwoKfQ==', 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (10, 3, 3, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (10, 3, 3, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (11, 3, 3, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (11, 3, 3, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `ware_house_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (12, 3, 3, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (12, 3, 3, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); From c2de043d2b796180a2a62e42f537b4d98cc6b4cd Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Mon, 26 Apr 2021 15:37:48 +0800 Subject: [PATCH 20/92] add account in copy --- .../node/mgr/contract/ContractController.java | 14 ++++++-- .../node/mgr/contract/ContractService.java | 25 ++++++++++++++- .../mgr/contract/entity/ReqCopyContracts.java | 31 ++++++++++++++++++ ...ntroller.java => WarehouseController.java} | 32 +++++++++---------- ...ouseService.java => WarehouseService.java} | 14 ++++---- .../mapper/TbContractFolderMapper.java | 6 ++-- .../mapper/TbContractItemMapper.java | 3 +- .../warehouse/mapper/TbWarehouseMapper.java | 2 +- ...eHouseMdTest.java => WarehouseMdTest.java} | 0 9 files changed, 96 insertions(+), 31 deletions(-) create mode 100644 src/main/java/com/webank/webase/node/mgr/contract/entity/ReqCopyContracts.java rename src/main/java/com/webank/webase/node/mgr/contract/warehouse/{WareHouseController.java => WarehouseController.java} (77%) rename src/main/java/com/webank/webase/node/mgr/contract/warehouse/{WareHouseService.java => WarehouseService.java} (88%) rename src/test/java/node/mgr/test/contract/warehouse/{WareHouseMdTest.java => WarehouseMdTest.java} (100%) diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java index 2899ea042..26eb20365 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java @@ -28,6 +28,7 @@ import com.webank.webase.node.mgr.contract.entity.QueryByBinParam; import com.webank.webase.node.mgr.contract.entity.QueryCnsParam; import com.webank.webase.node.mgr.contract.entity.QueryContractParam; +import com.webank.webase.node.mgr.contract.entity.ReqCopyContracts; import com.webank.webase.node.mgr.contract.entity.ReqListContract; import com.webank.webase.node.mgr.contract.entity.ReqQueryCns; import com.webank.webase.node.mgr.contract.entity.ReqQueryCnsList; @@ -82,8 +83,7 @@ public BaseResponse saveContract(@RequestBody @Valid Contract contract, BindingR Instant startTime = Instant.now(); log.info("start saveContract startTime:{} contract:{}", startTime.toEpochMilli(), JsonTools.toJSONString(contract)); - - // default path / + // default path "/" if ("".equals(contract.getContractPath())) { contract.setContractPath("/"); } @@ -433,4 +433,14 @@ public BasePageResponse findCnsList(@RequestBody @Valid ReqQueryCnsList inputPar Duration.between(startTime, Instant.now()).toMillis()); return pagesponse; } + + @PostMapping(value = "/copy") + @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN_OR_DEVELOPER) + public BaseResponse copyContracts(@RequestBody @Valid ReqCopyContracts req, + BindingResult result) { + log.info("copyContracts start. req:{}", JsonTools.toJSONString(req)); + checkBindResult(result); + contractService.copyContracts(req); + return new BaseResponse(ConstantCode.SUCCESS, req.getContractItems().size()); + } } diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java index 81de2baaa..5eb2a0a95 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java @@ -31,6 +31,7 @@ import com.webank.webase.node.mgr.contract.entity.ContractParam; import com.webank.webase.node.mgr.contract.entity.ContractPathParam; import com.webank.webase.node.mgr.contract.entity.DeployInputParam; +import com.webank.webase.node.mgr.contract.entity.ReqCopyContracts; import com.webank.webase.node.mgr.contract.entity.ReqListContract; import com.webank.webase.node.mgr.contract.entity.RspContractNoAbi; import com.webank.webase.node.mgr.contract.entity.TbContract; @@ -107,6 +108,7 @@ public class ContractService { private CryptoSuite cryptoSuite; @Autowired private GroupService groupService; + /** * add new contract data. */ @@ -158,7 +160,7 @@ private TbContract newContract(Contract contract) { * save application's contract. * * @param appKey - * @param reqContractSourceSave + * @param reqContractAddressSave */ @Transactional public void appContractSave(String appKey, ReqContractAddressSave reqContractAddressSave) @@ -688,4 +690,25 @@ public List queryContractListMultiPath(ReqListContract param) throws return resultList; } + /** + * copy contracts source from contract warehouse + * @param reqCopyContracts + */ + public void copyContracts(ReqCopyContracts reqCopyContracts) { + log.debug("start saveContractBatch ReqContractList:{}", + JsonTools.toJSONString(reqCopyContracts)); + reqCopyContracts.getContractItems().forEach(c -> { + Contract reqContractSave = new Contract(); + reqContractSave.setContractName(c.getContractName()); + reqContractSave.setContractSource(c.getContractSource()); + // default path "/" + reqContractSave.setContractPath(reqCopyContracts.getContractPath()); + if ("".equals(reqCopyContracts.getContractPath())) { + reqContractSave.setContractPath("/"); + } + reqContractSave.setGroupId(reqCopyContracts.getGroupId()); + this.newContract(reqContractSave); + }); + } + } diff --git a/src/main/java/com/webank/webase/node/mgr/contract/entity/ReqCopyContracts.java b/src/main/java/com/webank/webase/node/mgr/contract/entity/ReqCopyContracts.java new file mode 100644 index 000000000..f95123aa4 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/contract/entity/ReqCopyContracts.java @@ -0,0 +1,31 @@ +package com.webank.webase.node.mgr.contract.entity; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.List; +import lombok.NoArgsConstructor; + +/** + * @author marsli + */ +@Data +@NoArgsConstructor +public class ReqCopyContracts { + @NotBlank + private String account; + @NotNull + private Integer groupId; + private String contractPath; + private List contractItems; + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class RepCopyContractItem { + private String contractName; + private String contractSource; + } +} diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseController.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseController.java similarity index 77% rename from src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseController.java rename to src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseController.java index b876bea8a..7e1fa38df 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseController.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseController.java @@ -35,10 +35,10 @@ @Slf4j @RestController @RequestMapping(value = "/warehouse") -public class WareHouseController extends BaseController { +public class WarehouseController extends BaseController { @Autowired - WareHouseService wareHouseService; + WarehouseService warehouseService; /** * query the list of contract store item @@ -46,7 +46,7 @@ public class WareHouseController extends BaseController { @GetMapping(value = "/list") public BaseResponse getContractStoreList() { - List storeItemList = wareHouseService.getStoreList(); + List storeItemList = warehouseService.getStoreList(); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(storeItemList); return response; @@ -55,10 +55,10 @@ public BaseResponse getContractStoreList() { /** * query a contract store item */ - @GetMapping(value = "/{storeId}") - public BaseResponse getContractStoreById(@PathVariable("storeId") Integer storeId) { - log.info("getContractStoreById start. storeId:{}", storeId); - TbWarehouse storeItem = wareHouseService.getStoreItemById(storeId); + @GetMapping(value = "/{warehouseId}") + public BaseResponse getContractStoreById(@PathVariable("warehouseId") Integer warehouseId) { + log.info("getContractStoreById start. warehouseId:{}", warehouseId); + TbWarehouse storeItem = warehouseService.getStoreItemById(warehouseId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(storeItem); return response; @@ -70,7 +70,7 @@ public BaseResponse getContractStoreById(@PathVariable("storeId") Integer storeI @GetMapping(value = "/folder/{contractFolderId}") public BaseResponse getContractFolderById(@PathVariable("contractFolderId") Integer contractFolderId) { log.info("getContractStoreById start. contractFolderId:{}", contractFolderId); - TbContractFolder contractFolderItem = wareHouseService.getContractFolderById(contractFolderId); + TbContractFolder contractFolderItem = warehouseService.getContractFolderById(contractFolderId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(contractFolderItem); return response; @@ -82,19 +82,19 @@ public BaseResponse getContractFolderById(@PathVariable("contractFolderId") Inte @GetMapping(value = "/item/{contractId}") public BaseResponse getContractItemById(@PathVariable("contractId") Integer contractId) { log.info("getContractStoreById start. contractId:{}", contractId); - TbContractItem contractItem = wareHouseService.getContractItemById(contractId); + TbContractItem contractItem = warehouseService.getContractItemById(contractId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(contractItem); return response; } /** - * get folderItemList by storeId + * get folderItemList by warehouseId */ - @GetMapping(value = "/folder/list/{storeId}") - public BaseResponse getFolderItemListByStoreId(@PathVariable("storeId") Integer storeId) { - log.info("getFolderItemListByStoreId start. storeId:{}", storeId); - List contractFolderItemList = wareHouseService.getFolderItemListByStoreId(storeId); + @GetMapping(value = "/folder/list/{warehouseId}") + public BaseResponse getFolderItemListByStoreId(@PathVariable("warehouseId") Integer warehouseId) { + log.info("getFolderItemListByStoreId start. warehouseId:{}", warehouseId); + List contractFolderItemList = warehouseService.getFolderItemListByStoreId(warehouseId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(contractFolderItemList); return response; @@ -105,8 +105,8 @@ public BaseResponse getFolderItemListByStoreId(@PathVariable("storeId") Integer */ @GetMapping(value = "/item/list/{folderId}") public BaseResponse getContractItemByFolderId(@PathVariable("folderId") Integer folderId) { - log.info("getContractItemByFolderId start. storeId:{}", folderId); - List contractItemList = wareHouseService.getContractItemByFolderId(folderId); + log.info("getContractItemByFolderId start. warehouseId:{}", folderId); + List contractItemList = warehouseService.getContractItemByFolderId(folderId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(contractItemList); return response; diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseService.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseService.java similarity index 88% rename from src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseService.java rename to src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseService.java index 1813191f9..d35f46ffe 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WareHouseService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseService.java @@ -31,27 +31,27 @@ */ @Slf4j @Service -public class WareHouseService { +public class WarehouseService { @Autowired private TbContractItemMapper contractItemMapper; @Autowired private TbContractFolderMapper contractFolderMapper; @Autowired - private TbWarehouseMapper wareHouseMapper; + private TbWarehouseMapper warehouseMapper; /** * */ public List getStoreList() { - List storeItemList = wareHouseMapper.findAll(); + List storeItemList = warehouseMapper.findAll(); return storeItemList; } /** * */ - public TbWarehouse getStoreItemById(Integer wareHouseId) { - TbWarehouse storeItem = wareHouseMapper.selectByPrimaryKey(wareHouseId); + public TbWarehouse getStoreItemById(Integer warehouseId) { + TbWarehouse storeItem = warehouseMapper.selectByPrimaryKey(warehouseId); return storeItem; } @@ -82,8 +82,8 @@ public TbContractFolder getContractFolderById(Integer contractFolderId) { /** * */ - public List getFolderItemListByStoreId(Integer wareHouseId) { - List contractFolderItemList = contractFolderMapper.findByWareHouseId(wareHouseId); + public List getFolderItemListByStoreId(Integer warehouseId) { + List contractFolderItemList = contractFolderMapper.findByWarehouseId(warehouseId); return contractFolderItemList; } diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java index 74792b3eb..ff952ce85 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java @@ -1,7 +1,6 @@ package com.webank.webase.node.mgr.contract.warehouse.mapper; import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractFolder; -import com.webank.webase.node.mgr.contract.warehouse.entity.TbWareHouse; import java.util.List; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; @@ -20,8 +19,9 @@ */ public interface TbContractFolderMapper { - @Select({ "select", TbWarehouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_contract_folder", "where ware_house_id = #{wareHouseId}" }) - List findByWareHouseId(@Param("wareHouseId") Integer wareHouseId); + @Select({ "select", TbContractFolderSqlProvider.ALL_COLUMN_FIELDS, "from tb_contract_folder", + "where warehouse_id = #{warehouseId}" }) + List findByWarehouseId(@Param("warehouseId") Integer warehouseId); /** * This method was generated by MyBatis Generator. diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java index dd5111afb..8d8e703ca 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java @@ -16,7 +16,8 @@ public interface TbContractItemMapper { - @Select({ "select", TbWarehouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_contract_folder", "where contract_folder_id = #{contractFolderId}" }) + @Select({ "select", TbContractItemSqlProvider.ALL_COLUMN_FIELDS, "from tb_contract_item", + "where contract_folder_id = #{contractFolderId}" }) List listByFolderId(@Param("contractFolderId") Integer contractFolderId); /** diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWarehouseMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWarehouseMapper.java index 53b06e309..27f97bb36 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWarehouseMapper.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbWarehouseMapper.java @@ -17,7 +17,7 @@ */ public interface TbWarehouseMapper { - @Select({ "select", TbWarehouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_ware_house" }) + @Select({ "select", TbWarehouseSqlProvider.ALL_COLUMN_FIELDS, "from tb_warehouse" }) List findAll(); /** diff --git a/src/test/java/node/mgr/test/contract/warehouse/WareHouseMdTest.java b/src/test/java/node/mgr/test/contract/warehouse/WarehouseMdTest.java similarity index 100% rename from src/test/java/node/mgr/test/contract/warehouse/WareHouseMdTest.java rename to src/test/java/node/mgr/test/contract/warehouse/WarehouseMdTest.java From 798e903736480f6aa40d46231a81d14545dfb7ac Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Mon, 26 Apr 2021 18:09:54 +0800 Subject: [PATCH 21/92] update copy --- .../node/mgr/contract/ContractService.java | 18 ++++++++---------- .../node/mgr/contract/entity/Contract.java | 10 ++++++++++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java index 5eb2a0a95..f3fdfc85d 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java @@ -697,17 +697,15 @@ public List queryContractListMultiPath(ReqListContract param) throws public void copyContracts(ReqCopyContracts reqCopyContracts) { log.debug("start saveContractBatch ReqContractList:{}", JsonTools.toJSONString(reqCopyContracts)); + if ("".equals(reqCopyContracts.getContractPath())) { + reqCopyContracts.setContractPath("/"); + } reqCopyContracts.getContractItems().forEach(c -> { - Contract reqContractSave = new Contract(); - reqContractSave.setContractName(c.getContractName()); - reqContractSave.setContractSource(c.getContractSource()); - // default path "/" - reqContractSave.setContractPath(reqCopyContracts.getContractPath()); - if ("".equals(reqCopyContracts.getContractPath())) { - reqContractSave.setContractPath("/"); - } - reqContractSave.setGroupId(reqCopyContracts.getGroupId()); - this.newContract(reqContractSave); + Contract reqContractSave = new Contract(reqCopyContracts.getGroupId(), "", + reqCopyContracts.getContractPath(), reqCopyContracts.getAccount()); + reqContractSave.setContractName(c.getContractName()); + reqContractSave.setContractSource(c.getContractSource()); + this.newContract(reqContractSave); }); } diff --git a/src/main/java/com/webank/webase/node/mgr/contract/entity/Contract.java b/src/main/java/com/webank/webase/node/mgr/contract/entity/Contract.java index fb26af46e..9384ed6c7 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/entity/Contract.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/entity/Contract.java @@ -16,11 +16,13 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import lombok.Data; +import lombok.NoArgsConstructor; /** * param to save contract */ @Data +@NoArgsConstructor public class Contract { @NotBlank private String account; @@ -35,4 +37,12 @@ public class Contract { private String contractAbi; private String contractBin; private String bytecodeBin; + + public Contract(Integer groupId, String contractName, String contractPath, + String account) { + this.groupId = groupId; + this.contractName = contractName; + this.contractPath = contractPath; + this.account = account; + } } From ddb5815c17619ff9f06e46c745751960f79587fa Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Mon, 26 Apr 2021 18:10:49 +0800 Subject: [PATCH 22/92] update name --- script/webase-ddl.sql | 5 +++-- .../node/mgr/test/contract/warehouse/WarehouseMdTest.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/script/webase-ddl.sql b/script/webase-ddl.sql index ce4ecc528..96e9252cb 100644 --- a/script/webase-ddl.sql +++ b/script/webase-ddl.sql @@ -544,8 +544,6 @@ CREATE TABLE IF NOT EXISTS tb_contract_store ( UNIQUE KEY uk_version (app_key,contract_name,contract_version) ) ENGINE=InnoDB AUTO_INCREMENT=300001 DEFAULT CHARSET=utf8 COMMENT='应用合约信息'; -SET FOREIGN_KEY_CHECKS = 1; - -- ---------------------------- -- Table structure for tb_contract_store -- ---------------------------- @@ -592,3 +590,6 @@ CREATE TABLE IF NOT EXISTS tb_contract_item ( PRIMARY KEY (id), UNIQUE KEY uk_name(warehouse_id,contract_folder_id,contract_name) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='合约仓库合约信息'; + + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/src/test/java/node/mgr/test/contract/warehouse/WarehouseMdTest.java b/src/test/java/node/mgr/test/contract/warehouse/WarehouseMdTest.java index 2918fb958..36b9ddf15 100644 --- a/src/test/java/node/mgr/test/contract/warehouse/WarehouseMdTest.java +++ b/src/test/java/node/mgr/test/contract/warehouse/WarehouseMdTest.java @@ -17,7 +17,7 @@ import java.util.Base64; import org.junit.Test; -public class WareHouseMdTest { +public class WarehouseMdTest { public static final String ADDRESS_MD = "# Address\n" + "\n" + "Address library\n" + From 77412a39daf7937a182cc8cc1c81196e879233f6 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 27 Apr 2021 16:46:08 +0800 Subject: [PATCH 23/92] update config list api --- script/gm/webase-dml-gm.sql | 2 +- script/webase-dml.sql | 2 +- .../node/mgr/configapi/ConfigController.java | 15 +++--- .../mgr/deploy/service/ConfigService.java | 36 ++----------- .../test/configapi/ConfigControllerTest.java | 54 +++++++++++++++++++ 5 files changed, 65 insertions(+), 44 deletions(-) create mode 100644 src/test/java/node/mgr/test/configapi/ConfigControllerTest.java diff --git a/script/gm/webase-dml-gm.sql b/script/gm/webase-dml-gm.sql index 232c9d8d5..cda8c7475 100644 --- a/script/gm/webase-dml-gm.sql +++ b/script/gm/webase-dml-gm.sql @@ -1,6 +1,6 @@ -- ---------------------------- --- 1、init tb_account_info data admin/Abcd1234 // 国密版 sm3.hash(Abcd123) +-- 1、init tb_account_info data admin/password4 // 国密版 sm3.hash(password) -- ---------------------------- INSERT INTO tb_account_info (account,account_pwd,role_id,create_time,modify_time)values('admin', '$2a$10$F/aEB1iEx/FvVh0fMn6L/uyy.PkpTy8Kd9EdbqLGo7Bw7eCivpq.m',100000,now(),now()); diff --git a/script/webase-dml.sql b/script/webase-dml.sql index 7d50e7c09..d4e7165c5 100644 --- a/script/webase-dml.sql +++ b/script/webase-dml.sql @@ -1,6 +1,6 @@ -- ---------------------------- --- 1、init tb_account_info data admin/Abcd1234 +-- 1、init tb_account_info data admin/password4 -- ---------------------------- INSERT INTO tb_account_info (account,account_pwd,role_id,create_time,modify_time)values('admin', '$2a$10$F/aEB1iEx/FvVh0fMn6L/uyy.PkpTy8Kd9EdbqLGo7Bw7eCivpq.m',100000,now(),now()); diff --git a/src/main/java/com/webank/webase/node/mgr/configapi/ConfigController.java b/src/main/java/com/webank/webase/node/mgr/configapi/ConfigController.java index 8cc58065c..3c3de354a 100644 --- a/src/main/java/com/webank/webase/node/mgr/configapi/ConfigController.java +++ b/src/main/java/com/webank/webase/node/mgr/configapi/ConfigController.java @@ -23,7 +23,9 @@ import com.webank.webase.node.mgr.base.properties.VersionProperties; import com.webank.webase.node.mgr.base.tools.IPUtil; import com.webank.webase.node.mgr.configapi.entity.ServerInfo; +import com.webank.webase.node.mgr.deploy.entity.TbConfig; import com.webank.webase.node.mgr.deploy.service.ConfigService; +import java.util.List; import lombok.extern.log4j.Log4j2; import org.fisco.bcos.sdk.crypto.CryptoSuite; import org.springframework.beans.factory.annotation.Autowired; @@ -97,17 +99,12 @@ public BaseResponse isDeployedModifyEnable() { */ @GetMapping(value = "/list") public BaseResponse listDockerTag( - @RequestParam(value = "type", required = true, defaultValue = "0") int type, - @RequestParam(value = "update", required = false) boolean update) throws Exception { + @RequestParam(value = "type", defaultValue = "0") int type, + @RequestParam(value = "update", required = false) boolean update) { log.info("list config, type: [{}], update: [{}]", type, update); - ConfigTypeEnum configTypeEnum = ConfigTypeEnum.getById(type); - if (configTypeEnum == null) { - throw new NodeMgrException(ConstantCode.UNKNOWN_CONFIG_TYPE_ERROR); - } - - return new BaseResponse(ConstantCode.SUCCESS, - configService.selectConfigList(update, configTypeEnum)); + List configList = configService.selectConfigList(update, type); + return new BaseResponse(ConstantCode.SUCCESS, configList); } } diff --git a/src/main/java/com/webank/webase/node/mgr/deploy/service/ConfigService.java b/src/main/java/com/webank/webase/node/mgr/deploy/service/ConfigService.java index 69d10b564..cf90e00ec 100644 --- a/src/main/java/com/webank/webase/node/mgr/deploy/service/ConfigService.java +++ b/src/main/java/com/webank/webase/node/mgr/deploy/service/ConfigService.java @@ -41,39 +41,9 @@ public class ConfigService { * @param type * @return */ - public List selectConfigList(boolean update, ConfigTypeEnum type) { - if (type == null) { - return Collections.emptyList(); - } - - switch (type) { - case DOCKER_IMAGE_TYPE: - // update tags from docker hub registry -// if (StringUtils.isBlank(constants.getImageTagUpdateUrl())) { -// throw new NodeMgrException(ConstantCode.NO_DOCKER_TAG_UPDATE_URL_ERROR); -// } -// -// log.info("Fetch tag from: [{}]", constants.getImageTagUpdateUrl()); -// ResponseEntity responseEntity = -// this.genericRestTemplate.getForEntity(constants.getImageTagUpdateUrl(), ImageTag[].class); -// if (responseEntity == null -// || ArrayUtils.isEmpty(responseEntity.getBody())) { -// // docker hub api return empty -// throw new NodeMgrException(ConstantCode.UPDATE_DOCKER_TAG_ERROR); -// } - -// -// log.info("Docker image tag update success, new tag count is: [{}].", -// CollectionUtils.size(configList)); - - List configList = tbConfigMapper.selectByType(type.getId()); - // return filterByEncryptType(configList, encryptType.getEncryptType()); - return configList; - default: - break; - } - - return Collections.emptyList(); + public List selectConfigList(boolean update, int type) { + List configList = tbConfigMapper.selectByType(type); + return configList; } diff --git a/src/test/java/node/mgr/test/configapi/ConfigControllerTest.java b/src/test/java/node/mgr/test/configapi/ConfigControllerTest.java new file mode 100644 index 000000000..87bcf19d1 --- /dev/null +++ b/src/test/java/node/mgr/test/configapi/ConfigControllerTest.java @@ -0,0 +1,54 @@ +/** + * Copyright 2014-2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package node.mgr.test.configapi; + +import node.mgr.test.base.TestBase; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +public class ConfigControllerTest extends TestBase { + + private MockMvc mockMvc; + + + @Autowired + private WebApplicationContext webApplicationContext; + + @Before + public void setUp() throws Exception { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); + } + + @Test + public void testListConfig() throws Exception { + ResultActions resultActions = mockMvc + .perform(MockMvcRequestBuilders.get("/config/list?type=1")); + resultActions. + andExpect(MockMvcResultMatchers.status().isOk()). + andDo(MockMvcResultHandlers.print()); + System.out.println("=================================response:"+ + resultActions.andReturn().getResponse().getContentAsString()); + + } + +} From d9328160c48bd87e5c549d16ce30f9d163b1514d Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 27 Apr 2021 16:46:08 +0800 Subject: [PATCH 24/92] update config list api --- .../node/mgr/configapi/ConfigController.java | 15 +++--- .../mgr/deploy/service/ConfigService.java | 36 ++----------- .../test/configapi/ConfigControllerTest.java | 54 +++++++++++++++++++ 3 files changed, 63 insertions(+), 42 deletions(-) create mode 100644 src/test/java/node/mgr/test/configapi/ConfigControllerTest.java diff --git a/src/main/java/com/webank/webase/node/mgr/configapi/ConfigController.java b/src/main/java/com/webank/webase/node/mgr/configapi/ConfigController.java index 8cc58065c..3c3de354a 100644 --- a/src/main/java/com/webank/webase/node/mgr/configapi/ConfigController.java +++ b/src/main/java/com/webank/webase/node/mgr/configapi/ConfigController.java @@ -23,7 +23,9 @@ import com.webank.webase.node.mgr.base.properties.VersionProperties; import com.webank.webase.node.mgr.base.tools.IPUtil; import com.webank.webase.node.mgr.configapi.entity.ServerInfo; +import com.webank.webase.node.mgr.deploy.entity.TbConfig; import com.webank.webase.node.mgr.deploy.service.ConfigService; +import java.util.List; import lombok.extern.log4j.Log4j2; import org.fisco.bcos.sdk.crypto.CryptoSuite; import org.springframework.beans.factory.annotation.Autowired; @@ -97,17 +99,12 @@ public BaseResponse isDeployedModifyEnable() { */ @GetMapping(value = "/list") public BaseResponse listDockerTag( - @RequestParam(value = "type", required = true, defaultValue = "0") int type, - @RequestParam(value = "update", required = false) boolean update) throws Exception { + @RequestParam(value = "type", defaultValue = "0") int type, + @RequestParam(value = "update", required = false) boolean update) { log.info("list config, type: [{}], update: [{}]", type, update); - ConfigTypeEnum configTypeEnum = ConfigTypeEnum.getById(type); - if (configTypeEnum == null) { - throw new NodeMgrException(ConstantCode.UNKNOWN_CONFIG_TYPE_ERROR); - } - - return new BaseResponse(ConstantCode.SUCCESS, - configService.selectConfigList(update, configTypeEnum)); + List configList = configService.selectConfigList(update, type); + return new BaseResponse(ConstantCode.SUCCESS, configList); } } diff --git a/src/main/java/com/webank/webase/node/mgr/deploy/service/ConfigService.java b/src/main/java/com/webank/webase/node/mgr/deploy/service/ConfigService.java index 69d10b564..cf90e00ec 100644 --- a/src/main/java/com/webank/webase/node/mgr/deploy/service/ConfigService.java +++ b/src/main/java/com/webank/webase/node/mgr/deploy/service/ConfigService.java @@ -41,39 +41,9 @@ public class ConfigService { * @param type * @return */ - public List selectConfigList(boolean update, ConfigTypeEnum type) { - if (type == null) { - return Collections.emptyList(); - } - - switch (type) { - case DOCKER_IMAGE_TYPE: - // update tags from docker hub registry -// if (StringUtils.isBlank(constants.getImageTagUpdateUrl())) { -// throw new NodeMgrException(ConstantCode.NO_DOCKER_TAG_UPDATE_URL_ERROR); -// } -// -// log.info("Fetch tag from: [{}]", constants.getImageTagUpdateUrl()); -// ResponseEntity responseEntity = -// this.genericRestTemplate.getForEntity(constants.getImageTagUpdateUrl(), ImageTag[].class); -// if (responseEntity == null -// || ArrayUtils.isEmpty(responseEntity.getBody())) { -// // docker hub api return empty -// throw new NodeMgrException(ConstantCode.UPDATE_DOCKER_TAG_ERROR); -// } - -// -// log.info("Docker image tag update success, new tag count is: [{}].", -// CollectionUtils.size(configList)); - - List configList = tbConfigMapper.selectByType(type.getId()); - // return filterByEncryptType(configList, encryptType.getEncryptType()); - return configList; - default: - break; - } - - return Collections.emptyList(); + public List selectConfigList(boolean update, int type) { + List configList = tbConfigMapper.selectByType(type); + return configList; } diff --git a/src/test/java/node/mgr/test/configapi/ConfigControllerTest.java b/src/test/java/node/mgr/test/configapi/ConfigControllerTest.java new file mode 100644 index 000000000..87bcf19d1 --- /dev/null +++ b/src/test/java/node/mgr/test/configapi/ConfigControllerTest.java @@ -0,0 +1,54 @@ +/** + * Copyright 2014-2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package node.mgr.test.configapi; + +import node.mgr.test.base.TestBase; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +public class ConfigControllerTest extends TestBase { + + private MockMvc mockMvc; + + + @Autowired + private WebApplicationContext webApplicationContext; + + @Before + public void setUp() throws Exception { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); + } + + @Test + public void testListConfig() throws Exception { + ResultActions resultActions = mockMvc + .perform(MockMvcRequestBuilders.get("/config/list?type=1")); + resultActions. + andExpect(MockMvcResultMatchers.status().isOk()). + andDo(MockMvcResultHandlers.print()); + System.out.println("=================================response:"+ + resultActions.andReturn().getResponse().getContentAsString()); + + } + +} From 6dbfb0b12711ed52051f5004b4b1d727ac1ec5da Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Wed, 28 Apr 2021 17:18:02 +0800 Subject: [PATCH 25/92] add channel ip & user list --- .../mgr/deploy/service/ConfigService.java | 2 - .../node/mgr/scaffold/ScaffoldController.java | 5 +++ .../node/mgr/scaffold/ScaffoldService.java | 42 +++++++++++++------ .../node/mgr/scaffold/entity/ReqProject.java | 10 ++++- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/deploy/service/ConfigService.java b/src/main/java/com/webank/webase/node/mgr/deploy/service/ConfigService.java index cf90e00ec..294dc61c5 100644 --- a/src/main/java/com/webank/webase/node/mgr/deploy/service/ConfigService.java +++ b/src/main/java/com/webank/webase/node/mgr/deploy/service/ConfigService.java @@ -15,11 +15,9 @@ package com.webank.webase.node.mgr.deploy.service; import com.webank.webase.node.mgr.base.code.ConstantCode; -import com.webank.webase.node.mgr.base.enums.ConfigTypeEnum; import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.deploy.entity.TbConfig; import com.webank.webase.node.mgr.deploy.mapper.TbConfigMapper; -import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import lombok.extern.log4j.Log4j2; diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java index 8bada00c8..7f16965da 100644 --- a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java @@ -18,6 +18,7 @@ import com.webank.webase.node.mgr.base.controller.BaseController; import com.webank.webase.node.mgr.base.entity.BaseResponse; import com.webank.webase.node.mgr.base.properties.ConstantProperties; +import com.webank.webase.node.mgr.base.tools.IPUtil; import com.webank.webase.node.mgr.base.tools.JsonTools; import com.webank.webase.node.mgr.scaffold.entity.ReqProject; import com.webank.webase.node.mgr.scaffold.entity.RspFile; @@ -25,6 +26,7 @@ import java.time.Instant; import javax.validation.Valid; import lombok.extern.log4j.Log4j2; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PostMapping; @@ -48,6 +50,9 @@ public BaseResponse exportProjectApi(@Valid @RequestBody ReqProject param) { Instant startTime = Instant.now(); log.info("start exportProjectApi param:{} groupId:{}", startTime.toEpochMilli(), param); + if (StringUtils.isBlank(param.getChannelIp())) { + param.setChannelIp(IPUtil.LOCAL_IP_127); + } RspFile rspFile = scaffoldService.exportProject(param); log.info("end exportProjectApi useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), rspFile); diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java index cb335c2c6..07500f342 100644 --- a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java @@ -63,8 +63,7 @@ public class ScaffoldService { @Autowired private FrontInterfaceService frontInterfaceService; - // gradle not in package, skip - private static final String GRADLE_WRAPPER_DIR = ""; + private static final String GRADLE_WRAPPER_DIR = "gradle"; private static final String OUTPUT_DIR = "output"; private static final String ZIP_SUFFIX = ".zip"; @@ -78,8 +77,8 @@ public RspFile exportProject(ReqProject reqProject) { // check dir exist File checkProjectDir = new File(OUTPUT_DIR + File.separator + artifactName); if (checkProjectDir.exists()) { - log.error("exportProject dir exist: {}", artifactName); - throw new NodeMgrException(ConstantCode.PROJECT_NAME_ALREADY_EXIST); + boolean result = checkProjectDir.delete(); + log.warn("exportProject dir exist: {}, now delete it result:{}", artifactName, result); } // get contract info list List contractIdList = reqProject.getContractIdList(); @@ -101,19 +100,21 @@ public RspFile exportProject(ReqProject reqProject) { // get front's p2p ip and channel port FrontNodeConfig frontNodeConfig = frontInterfaceService .getNodeConfigFromSpecificFront(front.getFrontIp(), front.getFrontPort()); + frontNodeConfig.setP2pip(reqProject.getChannelIp()); log.info("exportProject get frontNodeConfig:{}", frontNodeConfig); // get front's sdk key cert Map sdkMap = certService.getFrontSdkContent(front.getFrontId()); log.info("exportProject get sdkMap size:{}", sdkMap.size()); // get user private key if set - String hexPrivateKey = ""; - if (StringUtils.isNotBlank(reqProject.getUserAddress())) { - hexPrivateKey = userService.queryUserDetail(reqProject.getGroupId(), reqProject.getUserAddress()); + List userAddressList = reqProject.getUserAddressList(); + String hexPrivateKeyListStr = ""; + if (userAddressList != null && !userAddressList.isEmpty()) { + // hexPrivateKeyListStr = this.handleUserList(reqProject.getGroupId(), userAddressList); + hexPrivateKeyListStr = userService.queryUserDetail(reqProject.getGroupId(), userAddressList.get(0)); } - log.info("exportProject get hexPrivateKey length:{}", hexPrivateKey.length()); // generate String projectPath = this.generateProject(frontNodeConfig, reqProject.getGroup(), reqProject.getArtifactName(), - tbContractList, reqProject.getGroupId(), hexPrivateKey, sdkMap); + tbContractList, reqProject.getGroupId(), hexPrivateKeyListStr, sdkMap); String zipFileName = artifactName + ZIP_SUFFIX; try { ZipUtils.generateZipFile(projectPath, OUTPUT_ZIP_DIR, "", zipFileName); @@ -138,12 +139,12 @@ public RspFile exportProject(ReqProject reqProject) { * @param artifactName * @param tbContractList * @param groupId - * @param hexPrivateKey + * @param hexPrivateKeyListStr * @param sdkMap * @return path string of project */ public String generateProject(FrontNodeConfig nodeConfig, String projectGroup, String artifactName, - List tbContractList, int groupId, String hexPrivateKey, Map sdkMap) { + List tbContractList, int groupId, String hexPrivateKeyListStr, Map sdkMap) { log.info("generateProject sdkMap size:{}", sdkMap.size()); List contractInfoList = this.handleContractList(tbContractList); String frontChannelIpPort = nodeConfig.getP2pip() + ":" + nodeConfig.getChannelPort(); @@ -153,7 +154,7 @@ public String generateProject(FrontNodeConfig nodeConfig, String projectGroup, S try { projectFactory.buildProjectDir(contractInfoList, projectGroup, artifactName, OUTPUT_DIR, GRADLE_WRAPPER_DIR, - frontChannelIpPort, groupId, hexPrivateKey, sdkMap); + frontChannelIpPort, groupId, hexPrivateKeyListStr, sdkMap); } catch (Exception e) { log.error("generateProject error:[]", e); throw new NodeMgrException(ConstantCode.GENERATE_CONTRACT_PROJECT_FAIL.attach(e.getMessage())); @@ -191,4 +192,21 @@ private List handleContractList(List contractList) { log.info("handleContractList contractList:{}", contractInfoList); return contractInfoList; } + + /** + * userP12PathList + * @return: String of list, e.g. 123,123,123 + */ + private String handleUserList(int groupId, List userAddressList) { + List keyList = new ArrayList<>(); + for (String address : userAddressList) { + String hexPrivateKey = ""; + if (StringUtils.isNotBlank(address)) { + hexPrivateKey = userService.queryUserDetail(groupId, address); + } + log.info("exportProject get hexPrivateKey length:{}", hexPrivateKey.length()); + keyList.add(hexPrivateKey); + } + return StringUtils.join(keyList, ","); + } } diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/entity/ReqProject.java b/src/main/java/com/webank/webase/node/mgr/scaffold/entity/ReqProject.java index be2ec707d..2083b43b6 100644 --- a/src/main/java/com/webank/webase/node/mgr/scaffold/entity/ReqProject.java +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/entity/ReqProject.java @@ -36,5 +36,13 @@ public class ReqProject { private Integer frontId; @NotNull private Integer groupId; - private String userAddress; + /** + * channel ip for exported project to connect node + */ + private String channelIp; + /** + * select multi user to export in project by p12 format + */ + @NotNull + private List userAddressList; } From cbe5e59e953731917a00e0842d61c8bcab59c832 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 29 Apr 2021 11:39:43 +0800 Subject: [PATCH 26/92] fix delete non-empty dir --- .../node/mgr/base/tools/NodeMgrTools.java | 24 +++++++++++++++++-- .../node/mgr/scaffold/ScaffoldService.java | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java b/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java index 926b5023b..3a243cf5e 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java +++ b/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java @@ -638,7 +638,7 @@ public static String writePrivateKeyPem(String rawPrivateKey, String address, St File keystorePath = new File(TEMP_EXPORT_KEYSTORE_PATH); // delete old private key if (keystorePath.exists()) { - keystorePath.delete(); + deleteDir(keystorePath); } keystorePath.mkdir(); // get private key @@ -665,7 +665,7 @@ public static String writePrivateKeyP12(String p12Password, String rawPrivateKey File keystorePath = new File(TEMP_EXPORT_KEYSTORE_PATH); // delete old private key if (keystorePath.exists()) { - keystorePath.delete(); + deleteDir(keystorePath); } keystorePath.mkdir(); // get private key @@ -708,4 +708,24 @@ public static String fileToBase64(String filePath) { } return null; } + + /** + * delete dir or file whatever + * @param dir + * @return + */ + public static boolean deleteDir(File dir) { + if (dir.isDirectory()) { + String[] children = dir.list(); + // recursive delete until dir is emtpy to delete + for (int i=0; i Date: Thu, 29 Apr 2021 15:05:31 +0800 Subject: [PATCH 27/92] add tool contract in sql --- script/webase-dml.sql | 97 +++++++++++++++---- .../contract/warehouse/WarehouseMdTest.java | 14 ++- .../warehouse/WarehouseSmartDevTest.java | 93 ++++++++++++++++++ 3 files changed, 184 insertions(+), 20 deletions(-) create mode 100644 src/test/java/node/mgr/test/contract/warehouse/WarehouseSmartDevTest.java diff --git a/script/webase-dml.sql b/script/webase-dml.sql index 57106a3b2..2d7b64213 100644 --- a/script/webase-dml.sql +++ b/script/webase-dml.sql @@ -153,38 +153,97 @@ INSERT INTO `tb_app_info` (`app_name`, `app_key`, `app_type`, `app_doc_link`, `a -- 9、init contract warehouse data (tb_warehouse, tb_contract_folder, tb_contract_item) -- ---------------------------- -- warehouse -INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES (1, '工具箱', 'Toolbox', 1, 'toolboxId', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); -INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES (2, '存证应用', 'Evidence', 2, 'evidenceId', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', now(), now()); -INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES (3, '积分应用', 'Points', 3, 'pointsId', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); +INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES +(1, '工具箱', 'Toolbox', 1, 'toolboxId', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); +INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES +(2, '存证应用', 'Evidence', 2, 'evidenceId', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', now(), now()); +INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES +(3, '积分应用', 'Points', 3, 'pointsId', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); +INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES +(4, 'SmartDev应用', 'Smart_Dev Template', 4, 'smartDevId', 'Smart-Dev-Contracts仓库中的应用模板', 'Smart-Dev-Contract\'s Contract suite of business_template', 'Smart-Dev-Contracts仓库中的应用模板', 'Smart-Dev-Contract\'s Contract suite of business_template', now(), now()); -- folder -INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (1, 1, 'Tools', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); -INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (2, 2, 'Evidence', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', now(), now()); -INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (3, 3, 'Points', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); --- contract item of contract source & md desc, including tools, evidence, points(BAC) -- +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES +(1, 1, 'Tools', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES +(2, 2, 'Evidence', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES +(3, 3, 'Points', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES +(4, 1, 'Smart_Dev_Basic', 'SmartDev基础合约,包含Table/KVTable/Sha/Crypto/HelloWorld等', 'Smart-Dev-Contract basic contract suite, including Table/KVTable/Sha/Crypto/HelloWorld etc.', 'SmartDev基础合约,包含Table/KVTable/Sha/Crypto/HelloWorld等', 'Smart-Dev-Contract default contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES +(5, 4, 'Smart_Dev_Evidence', 'SmartDev存证合约案例', 'Smart-Dev-Contract Evidence contract suite', 'SmartDev存证合约案例', 'Smart-Dev-Contract Evidence contract suite', now(), now()); + +-- contract item +-- of contract source & md desc, including tools, evidence, points(BAC) -- -- tools -- -INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (1, 1, 1, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(1, 1, 1, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (2, 1, 1, 'LibString', 'Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgXjAuNC4xMTsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gUmV0dXJucyB0aGUgbWVtb3J5IGFkZHJlc3Mgb2YgdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YKICAgIC8vIGBuZWVkbGVgIGluIGBzZWxmYCwgb3IgdGhlIGZpcnN0IGJ5dGUgYWZ0ZXIgYHNlbGZgIGlmIG5vdCBmb3VuZC4KICAgIGZ1bmN0aW9uIGZpbmRQdHIodWludCBzZWxmbGVuLCB1aW50IHNlbGZwdHIsIHVpbnQgbmVlZGxlbGVuLCB1aW50IG5lZWRsZXB0cikgcHJpdmF0ZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgdWludCBwdHI7CiAgICAgICAgdWludCBpZHg7CgogICAgICAgIGlmIChuZWVkbGVsZW4gPD0gc2VsZmxlbikgewogICAgICAgICAgICBpZiAobmVlZGxlbGVuIDw9IDMyKSB7CiAgICAgICAgICAgICAgICAvLyBPcHRpbWl6ZWQgYXNzZW1ibHkgZm9yIDY4IGdhcyBwZXIgYnl0ZSBvbiBzaG9ydCBzdHJpbmdzCiAgICAgICAgICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IG1hc2sgOj0gbm90KHN1YihleHAoMiwgbXVsKDgsIHN1YigzMiwgbmVlZGxlbGVuKSkpLCAxKSkKICAgICAgICAgICAgICAgICAgICBsZXQgbmVlZGxlZGF0YSA6PSBhbmQobWxvYWQobmVlZGxlcHRyKSwgbWFzaykKICAgICAgICAgICAgICAgICAgICBsZXQgZW5kIDo9IGFkZChzZWxmcHRyLCBzdWIoc2VsZmxlbiwgbmVlZGxlbGVuKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gc2VsZnB0cgogICAgICAgICAgICAgICAgICAgIGxvb3A6CiAgICAgICAgICAgICAgICAgICAganVtcGkoZXhpdCwgZXEoYW5kKG1sb2FkKHB0ciksIG1hc2spLCBuZWVkbGVkYXRhKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHB0ciwgMSkKICAgICAgICAgICAgICAgICAgICBqdW1waShsb29wLCBsdChzdWIocHRyLCAxKSwgZW5kKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHNlbGZwdHIsIHNlbGZsZW4pCiAgICAgICAgICAgICAgICAgICAgZXhpdDoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBGb3IgbG9uZyBuZWVkbGVzLCB1c2UgaGFzaGluZwogICAgICAgICAgICAgICAgYnl0ZXMzMiBoYXNoOwogICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBoYXNoIDo9IHNoYTMobmVlZGxlcHRyLCBuZWVkbGVsZW4pIH0KICAgICAgICAgICAgICAgIHB0ciA9IHNlbGZwdHI7CiAgICAgICAgICAgICAgICBmb3IgKGlkeCA9IDA7IGlkeCA8PSBzZWxmbGVuIC0gbmVlZGxlbGVuOyBpZHgrKykgewogICAgICAgICAgICAgICAgICAgIGJ5dGVzMzIgdGVzdEhhc2g7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibHkgeyB0ZXN0SGFzaCA6PSBzaGEzKHB0ciwgbmVlZGxlbGVuKSB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc2ggPT0gdGVzdEhhc2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgICAgICAgICAgcHRyICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGZwdHIgKyBzZWxmbGVuOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9zdHIpIGludGVybmFsIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY29tcGFyZU5vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBieXRlIGNoMSA9IGJ5dGVzKF9zZWxmKVtpXXwweDIwOwogICAgICAgICAgICBieXRlIGNoMiA9IGJ5dGVzKF9zdHIpW2ldfDB4MjA7CiAgICAgICAgICAgIGlmIChjaDEgPj0gJ2EnICYmIGNoMSA8PSd6JyAmJiBjaDIgPj0gJ2EnICYmIGNoMiA8PSd6JykgewogICAgICAgICAgICAgICAgaWYgKGNoMSA+IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaDEgPCBjaDIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFscyhzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgYnl0ZSBjaDEgPSBieXRlcyhfc2VsZilbaV18MHgyMDsKICAgICAgICAgICAgYnl0ZSBjaDIgPSBieXRlcyhfc3RyKVtpXXwweDIwOwogICAgICAgICAgICBpZiAoY2gxID49ICdhJyAmJiBjaDEgPD0neicgJiYgY2gyID49ICdhJyAmJiBjaDIgPD0neicpIHsKICAgICAgICAgICAgICAgIGlmIChjaDEgIT0gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gc3Vic3RyKHN0cmluZyBfc2VsZiwgdWludCBfc3RhcnQsIHVpbnQgX2xlbikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKF9sZW4pOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK19zdGFydCwgX2xlbik7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIG1lbWNweShyZXRwdHIrYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc3RycHRyLCBieXRlcyhfc3RyKS5sZW5ndGgpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb25jYXQoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cjEsIHN0cmluZyBfc3RyMikKICAgICAgICBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyMSwgc3RyaW5nIF9zdHIyLCBzdHJpbmcgX3N0cjMpCiAgICAgICAgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhieXRlcyhfc2VsZikubGVuZ3RoICsgYnl0ZXMoX3N0cjEpLmxlbmd0aCArIGJ5dGVzKF9zdHIyKS5sZW5ndGgKICAgICAgICAgICAgKyBieXRlcyhfc3RyMykubGVuZ3RoKTsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgc3RyMXB0cjsKICAgICAgICB1aW50IHN0cjJwdHI7CiAgICAgICAgdWludCBzdHIzcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgc3RyM3B0ciA6PSBhZGQoX3N0cjMsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMXB0ciwgYnl0ZXMoX3N0cjEpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIxKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjJwdHIsIGJ5dGVzKF9zdHIyKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIzcHRyLCBieXRlcyhfc3RyMykubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjMpLmxlbmd0aDsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgdWludCBpOwogICAgICAgIHVpbnQ4IGNoOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBjaCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgaT4wOyAtLWkpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaS0xXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IGVuZCA9IGk7CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50MTYgajsKICAgICAgICBib29sIG1hdGNoZWQ7CiAgICAgICAgZm9yIChpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgc3RhcnQgPSBpOwogICAgICAgIAogICAgICAgIGZvciAoaT11aW50MTYoYnl0ZXMoX3NlbGYpLmxlbmd0aCk7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpLTFdID09IGJ5dGVzKF9jaGFycylbal0pIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIW1hdGNoZWQpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHVpbnQxNiBlbmQgPSBpOwoKICAgICAgICBpZiAoZW5kIDw9IHN0YXJ0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfZGVsaW0sIHN0cmluZ1tdIHN0b3JhZ2UgX2FycmF5KSBpbnRlcm5hbCB7CiAgICAgICAgLy9XaHkgY2FuIG5vdCB1c2UgZGVsZXRlIF9hcnJheT8KICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPF9hcnJheS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkZWxldGUgX2FycmF5W2ldOwogICAgICAgIH0KICAgICAgICBfYXJyYXkubGVuZ3RoID0gMDsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgZGVsaW1wdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgZGVsaW1wdHIgOj0gYWRkKF9kZWxpbSwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIHVpbnQgcHRyOwogICAgICAgICAgICBib29sIGZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChieXRlcyhfZGVsaW0pLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfZGVsaW0pLmxlbmd0aCwgZGVsaW1wdHIpIC0gc2VsZnB0cjsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKHB0ciA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHB0ciA9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwdHIgPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IGVsZW0gPSBuZXcgc3RyaW5nKHB0ci1wb3MpOwogICAgICAgICAgICB1aW50IGVsZW1wdHI7CiAgICAgICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgICAgIGVsZW1wdHIgOj0gYWRkKGVsZW0sIDB4MjApCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWVtY3B5KGVsZW1wdHIsIHNlbGZwdHIrcG9zLCBwdHItcG9zKTsKICAgICAgICAgICAgcG9zID0gcHRyICsgYnl0ZXMoX2RlbGltKS5sZW5ndGg7CiAgICAgICAgICAgIF9hcnJheS5wdXNoKGVsZW0pOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCFmb3VuZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc2VsZnB0ciwgYnl0ZXMoX3N0cikubGVuZ3RoLCBzdHJwdHIpIC0gc2VsZnB0cjsKICAgICAgICBpZiAocHRyIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICBfcmV0ID0gaW50KHB0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3JldCA9IC0xOwogICAgICAgIH0KICAgIH0KICAgIAogICAgZnVuY3Rpb24gaW5kZXhPZihzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyLCB1aW50IHBvcykgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfc3RyKS5sZW5ndGgsIHN0cnB0cikgLSBzZWxmcHRyOwogICAgICAgIGlmIChwdHIgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgIF9yZXQgPSBpbnQocHRyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBfcmV0ID0gLTE7CiAgICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0ludChzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGludCBfcmV0KSB7CiAgICAgICAgX3JldCA9IDA7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID09ICcrJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9IGVsc2UgaWYoYnl0ZXMoX3NlbGYpW2ldID09ICctJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQoKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA+PSAweDMwICYmIGRpZ2l0IDw9IDB4MzkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGFkZHJlc3MgX3JldCkgewogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aC1pIDwgMikgewogICAgICAgICAgICByZXR1cm4gYWRkcmVzcygwKTsKICAgICAgICB9CgogICAgICAgIC8vbXVzdCBzdGFydCB3aXRoIDB4CiAgICAgICAgaWYgKCEoYnl0ZXMoX3NlbGYpW2ldID09ICcwJyAmJiBieXRlcyhfc2VsZilbaSsxXXwweDIwID09ICd4JykpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICB1aW50IGFkZHIgPSAwOwogICAgICAgIAogICAgICAgIGZvciAoaSs9MjsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSAvLycwJy0nOScKICAgICAgICAgICAgICAgIGRpZ2l0IC09IDB4MzA7CiAgICAgICAgICAgIGVsc2UgaWYgKGRpZ2l0fDB4MjAgPj0gMHg2MSAmJiBkaWdpdHwweDIwIDw9IDB4NjYpIC8vJ2EnLSdmJwogICAgICAgICAgICAgICAgZGlnaXQgPSBkaWdpdC0weDYxKzEwOwogICAgICAgICAgICBlbHNlIAogICAgICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7IAogICAgICAgICAgICAKICAgICAgICAgICAgYWRkciA9IGFkZHIqMTYrZGlnaXQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBhZGRyZXNzKGFkZHIpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0tleVZhbHVlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9rZXkpLmxlbmd0aCArIDUpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IGtleXB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBrZXlwdHIgOj0gYWRkKF9rZXksIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwoKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIGtleXB0ciwgYnl0ZXMoX2tleSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX2tleSkubGVuZ3RoOwogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICAKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnOic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldFN0cmluZ1ZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc3RhcnQgKz0gMTsKICAgICAgICAKICAgICAgICBpbnQgZW5kOwogICAgICAgIGlmIChkb3VibGVRdW90ZXMpIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHN0YXJ0KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiJyIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVuZCA9PSAtMSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZi5zdWJzdHIodWludChzdGFydCksIHVpbnQoZW5kLXN0YXJ0KSk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldEludFZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdWludCBpID0gdWludChwb3MpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEgCiAgICAgICAgICAgIHx8IGRpZ2l0ID09IDB4M0EgLyo6Ki8gfHwgZGlnaXQgPT0gMHgyMiAvKiIqLyB8fCBkaWdpdCA9PSAweDI3IC8qJyovKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gdG9VcHBlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnYScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICd6JykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldICY9IH4weDIwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZjsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9Mb3dlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnQScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICdaJykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldIHw9IDB4MjA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IF9zZWxmOwogICAgfQoJCiAgICBmdW5jdGlvbiBrZXlFeGlzdHMoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFscyhfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogCiAgICBmdW5jdGlvbiBpbkFycmF5Tm9DYXNlKHN0cmluZyBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHNOb0Nhc2UoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgfQ==', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(2, 1, 1, 'LibString', 'Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgXjAuNC4xMTsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gUmV0dXJucyB0aGUgbWVtb3J5IGFkZHJlc3Mgb2YgdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YKICAgIC8vIGBuZWVkbGVgIGluIGBzZWxmYCwgb3IgdGhlIGZpcnN0IGJ5dGUgYWZ0ZXIgYHNlbGZgIGlmIG5vdCBmb3VuZC4KICAgIGZ1bmN0aW9uIGZpbmRQdHIodWludCBzZWxmbGVuLCB1aW50IHNlbGZwdHIsIHVpbnQgbmVlZGxlbGVuLCB1aW50IG5lZWRsZXB0cikgcHJpdmF0ZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgdWludCBwdHI7CiAgICAgICAgdWludCBpZHg7CgogICAgICAgIGlmIChuZWVkbGVsZW4gPD0gc2VsZmxlbikgewogICAgICAgICAgICBpZiAobmVlZGxlbGVuIDw9IDMyKSB7CiAgICAgICAgICAgICAgICAvLyBPcHRpbWl6ZWQgYXNzZW1ibHkgZm9yIDY4IGdhcyBwZXIgYnl0ZSBvbiBzaG9ydCBzdHJpbmdzCiAgICAgICAgICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IG1hc2sgOj0gbm90KHN1YihleHAoMiwgbXVsKDgsIHN1YigzMiwgbmVlZGxlbGVuKSkpLCAxKSkKICAgICAgICAgICAgICAgICAgICBsZXQgbmVlZGxlZGF0YSA6PSBhbmQobWxvYWQobmVlZGxlcHRyKSwgbWFzaykKICAgICAgICAgICAgICAgICAgICBsZXQgZW5kIDo9IGFkZChzZWxmcHRyLCBzdWIoc2VsZmxlbiwgbmVlZGxlbGVuKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gc2VsZnB0cgogICAgICAgICAgICAgICAgICAgIGxvb3A6CiAgICAgICAgICAgICAgICAgICAganVtcGkoZXhpdCwgZXEoYW5kKG1sb2FkKHB0ciksIG1hc2spLCBuZWVkbGVkYXRhKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHB0ciwgMSkKICAgICAgICAgICAgICAgICAgICBqdW1waShsb29wLCBsdChzdWIocHRyLCAxKSwgZW5kKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHNlbGZwdHIsIHNlbGZsZW4pCiAgICAgICAgICAgICAgICAgICAgZXhpdDoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBGb3IgbG9uZyBuZWVkbGVzLCB1c2UgaGFzaGluZwogICAgICAgICAgICAgICAgYnl0ZXMzMiBoYXNoOwogICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBoYXNoIDo9IHNoYTMobmVlZGxlcHRyLCBuZWVkbGVsZW4pIH0KICAgICAgICAgICAgICAgIHB0ciA9IHNlbGZwdHI7CiAgICAgICAgICAgICAgICBmb3IgKGlkeCA9IDA7IGlkeCA8PSBzZWxmbGVuIC0gbmVlZGxlbGVuOyBpZHgrKykgewogICAgICAgICAgICAgICAgICAgIGJ5dGVzMzIgdGVzdEhhc2g7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibHkgeyB0ZXN0SGFzaCA6PSBzaGEzKHB0ciwgbmVlZGxlbGVuKSB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc2ggPT0gdGVzdEhhc2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgICAgICAgICAgcHRyICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGZwdHIgKyBzZWxmbGVuOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9zdHIpIGludGVybmFsIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY29tcGFyZU5vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBieXRlIGNoMSA9IGJ5dGVzKF9zZWxmKVtpXXwweDIwOwogICAgICAgICAgICBieXRlIGNoMiA9IGJ5dGVzKF9zdHIpW2ldfDB4MjA7CiAgICAgICAgICAgIGlmIChjaDEgPj0gJ2EnICYmIGNoMSA8PSd6JyAmJiBjaDIgPj0gJ2EnICYmIGNoMiA8PSd6JykgewogICAgICAgICAgICAgICAgaWYgKGNoMSA+IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaDEgPCBjaDIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFscyhzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgYnl0ZSBjaDEgPSBieXRlcyhfc2VsZilbaV18MHgyMDsKICAgICAgICAgICAgYnl0ZSBjaDIgPSBieXRlcyhfc3RyKVtpXXwweDIwOwogICAgICAgICAgICBpZiAoY2gxID49ICdhJyAmJiBjaDEgPD0neicgJiYgY2gyID49ICdhJyAmJiBjaDIgPD0neicpIHsKICAgICAgICAgICAgICAgIGlmIChjaDEgIT0gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gc3Vic3RyKHN0cmluZyBfc2VsZiwgdWludCBfc3RhcnQsIHVpbnQgX2xlbikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKF9sZW4pOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK19zdGFydCwgX2xlbik7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIG1lbWNweShyZXRwdHIrYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc3RycHRyLCBieXRlcyhfc3RyKS5sZW5ndGgpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb25jYXQoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cjEsIHN0cmluZyBfc3RyMikKICAgICAgICBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyMSwgc3RyaW5nIF9zdHIyLCBzdHJpbmcgX3N0cjMpCiAgICAgICAgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhieXRlcyhfc2VsZikubGVuZ3RoICsgYnl0ZXMoX3N0cjEpLmxlbmd0aCArIGJ5dGVzKF9zdHIyKS5sZW5ndGgKICAgICAgICAgICAgKyBieXRlcyhfc3RyMykubGVuZ3RoKTsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgc3RyMXB0cjsKICAgICAgICB1aW50IHN0cjJwdHI7CiAgICAgICAgdWludCBzdHIzcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgc3RyM3B0ciA6PSBhZGQoX3N0cjMsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMXB0ciwgYnl0ZXMoX3N0cjEpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIxKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjJwdHIsIGJ5dGVzKF9zdHIyKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIzcHRyLCBieXRlcyhfc3RyMykubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjMpLmxlbmd0aDsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgdWludCBpOwogICAgICAgIHVpbnQ4IGNoOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBjaCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgaT4wOyAtLWkpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaS0xXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IGVuZCA9IGk7CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50MTYgajsKICAgICAgICBib29sIG1hdGNoZWQ7CiAgICAgICAgZm9yIChpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgc3RhcnQgPSBpOwogICAgICAgIAogICAgICAgIGZvciAoaT11aW50MTYoYnl0ZXMoX3NlbGYpLmxlbmd0aCk7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpLTFdID09IGJ5dGVzKF9jaGFycylbal0pIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIW1hdGNoZWQpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHVpbnQxNiBlbmQgPSBpOwoKICAgICAgICBpZiAoZW5kIDw9IHN0YXJ0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfZGVsaW0sIHN0cmluZ1tdIHN0b3JhZ2UgX2FycmF5KSBpbnRlcm5hbCB7CiAgICAgICAgLy9XaHkgY2FuIG5vdCB1c2UgZGVsZXRlIF9hcnJheT8KICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPF9hcnJheS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkZWxldGUgX2FycmF5W2ldOwogICAgICAgIH0KICAgICAgICBfYXJyYXkubGVuZ3RoID0gMDsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgZGVsaW1wdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgZGVsaW1wdHIgOj0gYWRkKF9kZWxpbSwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIHVpbnQgcHRyOwogICAgICAgICAgICBib29sIGZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChieXRlcyhfZGVsaW0pLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfZGVsaW0pLmxlbmd0aCwgZGVsaW1wdHIpIC0gc2VsZnB0cjsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKHB0ciA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHB0ciA9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwdHIgPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IGVsZW0gPSBuZXcgc3RyaW5nKHB0ci1wb3MpOwogICAgICAgICAgICB1aW50IGVsZW1wdHI7CiAgICAgICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgICAgIGVsZW1wdHIgOj0gYWRkKGVsZW0sIDB4MjApCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWVtY3B5KGVsZW1wdHIsIHNlbGZwdHIrcG9zLCBwdHItcG9zKTsKICAgICAgICAgICAgcG9zID0gcHRyICsgYnl0ZXMoX2RlbGltKS5sZW5ndGg7CiAgICAgICAgICAgIF9hcnJheS5wdXNoKGVsZW0pOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCFmb3VuZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc2VsZnB0ciwgYnl0ZXMoX3N0cikubGVuZ3RoLCBzdHJwdHIpIC0gc2VsZnB0cjsKICAgICAgICBpZiAocHRyIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICBfcmV0ID0gaW50KHB0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3JldCA9IC0xOwogICAgICAgIH0KICAgIH0KICAgIAogICAgZnVuY3Rpb24gaW5kZXhPZihzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyLCB1aW50IHBvcykgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfc3RyKS5sZW5ndGgsIHN0cnB0cikgLSBzZWxmcHRyOwogICAgICAgIGlmIChwdHIgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgIF9yZXQgPSBpbnQocHRyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBfcmV0ID0gLTE7CiAgICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0ludChzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGludCBfcmV0KSB7CiAgICAgICAgX3JldCA9IDA7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID09ICcrJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9IGVsc2UgaWYoYnl0ZXMoX3NlbGYpW2ldID09ICctJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQoKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA+PSAweDMwICYmIGRpZ2l0IDw9IDB4MzkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGFkZHJlc3MgX3JldCkgewogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aC1pIDwgMikgewogICAgICAgICAgICByZXR1cm4gYWRkcmVzcygwKTsKICAgICAgICB9CgogICAgICAgIC8vbXVzdCBzdGFydCB3aXRoIDB4CiAgICAgICAgaWYgKCEoYnl0ZXMoX3NlbGYpW2ldID09ICcwJyAmJiBieXRlcyhfc2VsZilbaSsxXXwweDIwID09ICd4JykpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICB1aW50IGFkZHIgPSAwOwogICAgICAgIAogICAgICAgIGZvciAoaSs9MjsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSAvLycwJy0nOScKICAgICAgICAgICAgICAgIGRpZ2l0IC09IDB4MzA7CiAgICAgICAgICAgIGVsc2UgaWYgKGRpZ2l0fDB4MjAgPj0gMHg2MSAmJiBkaWdpdHwweDIwIDw9IDB4NjYpIC8vJ2EnLSdmJwogICAgICAgICAgICAgICAgZGlnaXQgPSBkaWdpdC0weDYxKzEwOwogICAgICAgICAgICBlbHNlIAogICAgICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7IAogICAgICAgICAgICAKICAgICAgICAgICAgYWRkciA9IGFkZHIqMTYrZGlnaXQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBhZGRyZXNzKGFkZHIpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0tleVZhbHVlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9rZXkpLmxlbmd0aCArIDUpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IGtleXB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBrZXlwdHIgOj0gYWRkKF9rZXksIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwoKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIGtleXB0ciwgYnl0ZXMoX2tleSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX2tleSkubGVuZ3RoOwogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICAKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnOic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldFN0cmluZ1ZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc3RhcnQgKz0gMTsKICAgICAgICAKICAgICAgICBpbnQgZW5kOwogICAgICAgIGlmIChkb3VibGVRdW90ZXMpIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHN0YXJ0KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiJyIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVuZCA9PSAtMSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZi5zdWJzdHIodWludChzdGFydCksIHVpbnQoZW5kLXN0YXJ0KSk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldEludFZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdWludCBpID0gdWludChwb3MpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEgCiAgICAgICAgICAgIHx8IGRpZ2l0ID09IDB4M0EgLyo6Ki8gfHwgZGlnaXQgPT0gMHgyMiAvKiIqLyB8fCBkaWdpdCA9PSAweDI3IC8qJyovKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gdG9VcHBlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnYScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICd6JykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldICY9IH4weDIwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZjsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9Mb3dlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnQScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICdaJykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldIHw9IDB4MjA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IF9zZWxmOwogICAgfQoJCiAgICBmdW5jdGlvbiBrZXlFeGlzdHMoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFscyhfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogCiAgICBmdW5jdGlvbiBpbkFycmF5Tm9DYXNlKHN0cmluZyBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHNOb0Nhc2UoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgfQ==', 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (3, 1, 1, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(3, 1, 1, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (4, 1, 1, 'Table', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7Cgpjb250cmFjdCBUYWJsZUZhY3RvcnkgewogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoVGFibGUpOyAvL29wZW4gdGFibGUKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOyAvL2NyZWF0ZSB0YWJsZQp9CgovL3NlbGVjdCBjb25kaXRpb24KY29udHJhY3QgQ29uZGl0aW9uIHsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgc3RyaW5nKSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgYWRkcmVzcykgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBpbnQyNTYpIHB1YmxpYyB2aWV3OwogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyB2aWV3OwoKICAgIGZ1bmN0aW9uIEdUKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEdFKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKCiAgICBmdW5jdGlvbiBMVChzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CiAgICBmdW5jdGlvbiBMRShzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gbGltaXQoaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIGxpbWl0KGludDI1NiwgaW50MjU2KSBwdWJsaWMgdmlldzsKfQoKLy9vbmUgcmVjb3JkCmNvbnRyYWN0IEVudHJ5IHsKICAgIGZ1bmN0aW9uIGdldEludChzdHJpbmcpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRVSW50KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRBZGRyZXNzKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcyk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczY0KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMxWzY0XSk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczMyKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMzMik7CiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcpOwoKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcsIGludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgdWludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgc3RyaW5nKSBwdWJsaWM7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBhZGRyZXNzKSBwdWJsaWM7Cn0KCi8vcmVjb3JkIHNldHMKY29udHJhY3QgRW50cmllcyB7CiAgICBmdW5jdGlvbiBnZXQoaW50MjU2KSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBzaXplKCkgcHVibGljIHZpZXcgcmV0dXJucyAoaW50MjU2KTsKfQoKLy9UYWJsZSBtYWluIGNvbnRyYWN0CmNvbnRyYWN0IFRhYmxlIHsKICAgIGZ1bmN0aW9uIHNlbGVjdChzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHZpZXcgcmV0dXJucyAoRW50cmllcyk7CiAgICBmdW5jdGlvbiBpbnNlcnQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiB1cGRhdGUoc3RyaW5nLCBFbnRyeSwgQ29uZGl0aW9uKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KTsKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHJldHVybnMgKGludDI1Nik7CgogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBuZXdDb25kaXRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChDb25kaXRpb24pOwp9Cgpjb250cmFjdCBLVlRhYmxlRmFjdG9yeSB7CiAgICBmdW5jdGlvbiBvcGVuVGFibGUoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChLVlRhYmxlKTsKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOwp9CgovL0tWVGFibGUgcGVyIHBlcm1pYXJ5IGtleSBoYXMgb25seSBvbmUgRW50cnkKY29udHJhY3QgS1ZUYWJsZSB7CiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sLCBFbnRyeSk7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBuZXdFbnRyeSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KTsKfQo=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(4, 1, 1, 'Table', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7Cgpjb250cmFjdCBUYWJsZUZhY3RvcnkgewogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoVGFibGUpOyAvL29wZW4gdGFibGUKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOyAvL2NyZWF0ZSB0YWJsZQp9CgovL3NlbGVjdCBjb25kaXRpb24KY29udHJhY3QgQ29uZGl0aW9uIHsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgc3RyaW5nKSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgYWRkcmVzcykgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBpbnQyNTYpIHB1YmxpYyB2aWV3OwogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyB2aWV3OwoKICAgIGZ1bmN0aW9uIEdUKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEdFKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKCiAgICBmdW5jdGlvbiBMVChzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CiAgICBmdW5jdGlvbiBMRShzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gbGltaXQoaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIGxpbWl0KGludDI1NiwgaW50MjU2KSBwdWJsaWMgdmlldzsKfQoKLy9vbmUgcmVjb3JkCmNvbnRyYWN0IEVudHJ5IHsKICAgIGZ1bmN0aW9uIGdldEludChzdHJpbmcpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRVSW50KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRBZGRyZXNzKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcyk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczY0KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMxWzY0XSk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczMyKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMzMik7CiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcpOwoKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcsIGludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgdWludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgc3RyaW5nKSBwdWJsaWM7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBhZGRyZXNzKSBwdWJsaWM7Cn0KCi8vcmVjb3JkIHNldHMKY29udHJhY3QgRW50cmllcyB7CiAgICBmdW5jdGlvbiBnZXQoaW50MjU2KSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBzaXplKCkgcHVibGljIHZpZXcgcmV0dXJucyAoaW50MjU2KTsKfQoKLy9UYWJsZSBtYWluIGNvbnRyYWN0CmNvbnRyYWN0IFRhYmxlIHsKICAgIGZ1bmN0aW9uIHNlbGVjdChzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHZpZXcgcmV0dXJucyAoRW50cmllcyk7CiAgICBmdW5jdGlvbiBpbnNlcnQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiB1cGRhdGUoc3RyaW5nLCBFbnRyeSwgQ29uZGl0aW9uKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KTsKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHJldHVybnMgKGludDI1Nik7CgogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBuZXdDb25kaXRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChDb25kaXRpb24pOwp9Cgpjb250cmFjdCBLVlRhYmxlRmFjdG9yeSB7CiAgICBmdW5jdGlvbiBvcGVuVGFibGUoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChLVlRhYmxlKTsKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOwp9CgovL0tWVGFibGUgcGVyIHBlcm1pYXJ5IGtleSBoYXMgb25seSBvbmUgRW50cnkKY29udHJhY3QgS1ZUYWJsZSB7CiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sLCBFbnRyeSk7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBuZXdFbnRyeSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KTsKfQo=', 'IyB0YWJsZQoKdGFibGUgbGlicmFyeQoKQkNPUyBDUlVEIHVzZXMgdGhlIGJhc2UgbGlicmFyeSwgd2hpY2ggeW91IGNhbiByZWZlcmVuY2UgYnkgcmUtY29udHJhY3QgY2FsbGluZyBDUlVELlRhYmxlIGNvbnRyYWN0IHVzYWdlIG1ldGhvZHMgY2FuIGJlIGRlc2NyaWJlZCBieSByZWZlcnJpbmcgdG8gdGhlIGFzc2F0IGV4YW1wbGUgaW4gdGhlIGJjb3MgZG9jdW1lbnQgaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8u', 'IyB0YWJsZQoKdGFibGUgbGlicmFyeQoKQkNPUyBDUlVEIHVzZXMgdGhlIGJhc2UgbGlicmFyeSwgd2hpY2ggeW91IGNhbiByZWZlcmVuY2UgYnkgcmUtY29udHJhY3QgY2FsbGluZyBDUlVELlRhYmxlIGNvbnRyYWN0IHVzYWdlIG1ldGhvZHMgY2FuIGJlIGRlc2NyaWJlZCBieSByZWZlcnJpbmcgdG8gdGhlIGFzc2F0IGV4YW1wbGUgaW4gdGhlIGJjb3MgZG9jdW1lbnQgaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8u', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (5, 1, 1, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(5, 1, 1, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); -- evidence -- -INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (6, 2, 2, 'Evidence', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YUFCSXsgZnVuY3Rpb24gdmVyaWZ5KGFkZHJlc3MgYWRkcilwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhib29sKXt9CmZ1bmN0aW9uIGdldFNpZ25lcih1aW50IGluZGV4KXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3Mpe30gCmZ1bmN0aW9uIGdldFNpZ25lcnNTaXplKCkgcHVibGljIGNvbnN0YW50IHJldHVybnModWludCl7fQp9Cgpjb250cmFjdCBFdmlkZW5jZXsKICAgIAogICAgc3RyaW5nIGV2aWRlbmNlOwogICAgc3RyaW5nIGV2aWRlbmNlSW5mbzsKICAgIHN0cmluZyBldmlkZW5jZUlkOwogICAgdWludDhbXSBfdjsKICAgIGJ5dGVzMzJbXSBfcjsKICAgIGJ5dGVzMzJbXSBfczsKICAgIGFkZHJlc3NbXSBzaWduZXJzOwogICAgYWRkcmVzcyBwdWJsaWMgc2lnbmVyc0FkZHI7CiAgICAKICAgICAgICBldmVudCBhZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IG5ld1NpZ25hdHVyZXNFdmVudChzdHJpbmcgZXZpLCBzdHJpbmcgaW5mbywgc3RyaW5nIGlkLCB1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcyxhZGRyZXNzIGFkZHIpOwogICAgICAgIGV2ZW50IGVycm9yTmV3U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLGFkZHJlc3MgYWRkcik7CiAgICAgICAgZXZlbnQgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsYWRkcmVzcyBhZGRyKTsKICAgICAgICBldmVudCBhZGRSZXBlYXRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsIGFkZHJlc3MgYWRkcik7CgogICAgZnVuY3Rpb24gQ2FsbFZlcmlmeShhZGRyZXNzIGFkZHIpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpIHsKICAgICAgICByZXR1cm4gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikudmVyaWZ5KGFkZHIpOwogICAgfQoKICAgICAgIGZ1bmN0aW9uIEV2aWRlbmNlKHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLCBhZGRyZXNzIGFkZHIsIGFkZHJlc3Mgc2VuZGVyKSBwdWJsaWMgewogICAgICAgc2lnbmVyc0FkZHIgPSBhZGRyOwogICAgICAgaWYoQ2FsbFZlcmlmeShzZW5kZXIpKQogICAgICAgewogICAgICAgICAgIGV2aWRlbmNlID0gZXZpOwogICAgICAgICAgIGV2aWRlbmNlSW5mbyA9IGluZm87CiAgICAgICAgICAgZXZpZGVuY2VJZCA9IGlkOwogICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgX3IucHVzaChyKTsKICAgICAgICAgICBfcy5wdXNoKHMpOwogICAgICAgICAgIHNpZ25lcnMucHVzaChzZW5kZXIpOwogICAgICAgICAgIG5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgICAgIGVsc2UKICAgICAgIHsKICAgICAgICAgICBlcnJvck5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgIH0KCiAgICAgICAgZnVuY3Rpb24gZ2V0RXZpZGVuY2VJbmZvKCkgcHVibGljIGNvbnN0YW50IHJldHVybnMoc3RyaW5nKXsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlSW5mbzsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRFdmlkZW5jZSgpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKHN0cmluZyxzdHJpbmcsc3RyaW5nLHVpbnQ4W10sYnl0ZXMzMltdLGJ5dGVzMzJbXSxhZGRyZXNzW10pewogICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICByZXR1cm4oZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsX3YsX3IsX3Msc2lnbmVyTGlzdCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkU2lnbmF0dXJlcyh1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcykgcHVibGljIHJldHVybnMoYm9vbCkgewogICAgICAgIGZvcih1aW50IGk9IDAgO2k8c2lnbmVycy5sZW5ndGggO2krKykKICAgICAgICB7CiAgICAgICAgICAgIGlmKG1zZy5zZW5kZXIgPT0gc2lnbmVyc1tpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoIF92W2ldID09IHYgJiYgX3JbaV0gPT0gciAmJiBfc1tpXSA9PSBzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFkZFJlcGVhdFNpZ25hdHVyZXNFdmVudChldmlkZW5jZSxldmlkZW5jZUluZm8sZXZpZGVuY2VJZCx2LHIscyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgIGlmKENhbGxWZXJpZnkobXNnLnNlbmRlcikpCiAgICAgICB7CiAgICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgIF9yLnB1c2gocik7CiAgICAgICAgICAgIF9zLnB1c2gocyk7CiAgICAgICAgICAgIHNpZ25lcnMucHVzaChtc2cuc2VuZGVyKTsKICAgICAgICAgICAgYWRkU2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSW5mbyxldmlkZW5jZUlkLHYscixzKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICB9CiAgICAgICBlbHNlCiAgICAgICB7CiAgICAgICAgICAgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTaWduZXJzKClwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhhZGRyZXNzW10pCiAgICB7CiAgICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHNpZ25lckxpc3Q7CiAgICB9Cn0=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(6, 2, 2, 'Evidence', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YUFCSXsgZnVuY3Rpb24gdmVyaWZ5KGFkZHJlc3MgYWRkcilwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhib29sKXt9CmZ1bmN0aW9uIGdldFNpZ25lcih1aW50IGluZGV4KXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3Mpe30gCmZ1bmN0aW9uIGdldFNpZ25lcnNTaXplKCkgcHVibGljIGNvbnN0YW50IHJldHVybnModWludCl7fQp9Cgpjb250cmFjdCBFdmlkZW5jZXsKICAgIAogICAgc3RyaW5nIGV2aWRlbmNlOwogICAgc3RyaW5nIGV2aWRlbmNlSW5mbzsKICAgIHN0cmluZyBldmlkZW5jZUlkOwogICAgdWludDhbXSBfdjsKICAgIGJ5dGVzMzJbXSBfcjsKICAgIGJ5dGVzMzJbXSBfczsKICAgIGFkZHJlc3NbXSBzaWduZXJzOwogICAgYWRkcmVzcyBwdWJsaWMgc2lnbmVyc0FkZHI7CiAgICAKICAgICAgICBldmVudCBhZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IG5ld1NpZ25hdHVyZXNFdmVudChzdHJpbmcgZXZpLCBzdHJpbmcgaW5mbywgc3RyaW5nIGlkLCB1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcyxhZGRyZXNzIGFkZHIpOwogICAgICAgIGV2ZW50IGVycm9yTmV3U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLGFkZHJlc3MgYWRkcik7CiAgICAgICAgZXZlbnQgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsYWRkcmVzcyBhZGRyKTsKICAgICAgICBldmVudCBhZGRSZXBlYXRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsIGFkZHJlc3MgYWRkcik7CgogICAgZnVuY3Rpb24gQ2FsbFZlcmlmeShhZGRyZXNzIGFkZHIpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpIHsKICAgICAgICByZXR1cm4gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikudmVyaWZ5KGFkZHIpOwogICAgfQoKICAgICAgIGZ1bmN0aW9uIEV2aWRlbmNlKHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLCBhZGRyZXNzIGFkZHIsIGFkZHJlc3Mgc2VuZGVyKSBwdWJsaWMgewogICAgICAgc2lnbmVyc0FkZHIgPSBhZGRyOwogICAgICAgaWYoQ2FsbFZlcmlmeShzZW5kZXIpKQogICAgICAgewogICAgICAgICAgIGV2aWRlbmNlID0gZXZpOwogICAgICAgICAgIGV2aWRlbmNlSW5mbyA9IGluZm87CiAgICAgICAgICAgZXZpZGVuY2VJZCA9IGlkOwogICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgX3IucHVzaChyKTsKICAgICAgICAgICBfcy5wdXNoKHMpOwogICAgICAgICAgIHNpZ25lcnMucHVzaChzZW5kZXIpOwogICAgICAgICAgIG5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgICAgIGVsc2UKICAgICAgIHsKICAgICAgICAgICBlcnJvck5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgIH0KCiAgICAgICAgZnVuY3Rpb24gZ2V0RXZpZGVuY2VJbmZvKCkgcHVibGljIGNvbnN0YW50IHJldHVybnMoc3RyaW5nKXsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlSW5mbzsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRFdmlkZW5jZSgpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKHN0cmluZyxzdHJpbmcsc3RyaW5nLHVpbnQ4W10sYnl0ZXMzMltdLGJ5dGVzMzJbXSxhZGRyZXNzW10pewogICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICByZXR1cm4oZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsX3YsX3IsX3Msc2lnbmVyTGlzdCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkU2lnbmF0dXJlcyh1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcykgcHVibGljIHJldHVybnMoYm9vbCkgewogICAgICAgIGZvcih1aW50IGk9IDAgO2k8c2lnbmVycy5sZW5ndGggO2krKykKICAgICAgICB7CiAgICAgICAgICAgIGlmKG1zZy5zZW5kZXIgPT0gc2lnbmVyc1tpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoIF92W2ldID09IHYgJiYgX3JbaV0gPT0gciAmJiBfc1tpXSA9PSBzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFkZFJlcGVhdFNpZ25hdHVyZXNFdmVudChldmlkZW5jZSxldmlkZW5jZUluZm8sZXZpZGVuY2VJZCx2LHIscyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgIGlmKENhbGxWZXJpZnkobXNnLnNlbmRlcikpCiAgICAgICB7CiAgICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgIF9yLnB1c2gocik7CiAgICAgICAgICAgIF9zLnB1c2gocyk7CiAgICAgICAgICAgIHNpZ25lcnMucHVzaChtc2cuc2VuZGVyKTsKICAgICAgICAgICAgYWRkU2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSW5mbyxldmlkZW5jZUlkLHYscixzKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICB9CiAgICAgICBlbHNlCiAgICAgICB7CiAgICAgICAgICAgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTaWduZXJzKClwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhhZGRyZXNzW10pCiAgICB7CiAgICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHNpZ25lckxpc3Q7CiAgICB9Cn0=', 'IyBFdmlkZW5jZSDlkIjnuqYKCiMjIOeugOS7iwpFdmlkZW5jZSDnpLrkvovlkIjnuqbvvIzkvb/nlKjliIblsYLnmoTmmbrog73lkIjnuqbnu5PmnoTvvJogCjHvvInlt6XljoLlkIjnuqbvvIhFdmlkZW5jZVNpZ25lcnNEYXRhLnNvbO+8ie+8jOeUseWtmOivgeWQhOaWueS6i+WJjee6puWumu+8jOWtmOWCqOWtmOivgeeUn+aViOadoeS7tu+8jOW5tueuoeeQhuWtmOivgeeahOeUn+aIkOOAgiAgCjLvvInlrZjor4HlkIjnuqbvvIhFdmlkZW5jZS5zb2zvvInvvIznlLHlt6XljoLlkIjnuqbnlJ/miJDvvIzlrZjlgqjlrZjor4FpZO+8jGhhc2jlkozlkITmlrnnrb7lkI3vvIjmr4/lvKDlrZjor4HkuIDkuKrlkIjnuqbvvInjgIIgIA==', '', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (7, 2, 2, 'EvidenceSignersData', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKaW1wb3J0ICJFdmlkZW5jZS5zb2wiOwoKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YXsKICAgICAgICBhZGRyZXNzW10gc2lnbmVyczsKCQlldmVudCBuZXdFdmlkZW5jZUV2ZW50KGFkZHJlc3MgYWRkcik7CiAgICAgICAgZnVuY3Rpb24gbmV3RXZpZGVuY2Uoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sc3RyaW5nIGlkLHVpbnQ4IHYsIGJ5dGVzMzIgcixieXRlczMyIHMpcHVibGljIHJldHVybnMoYWRkcmVzcykKICAgICAgICB7CiAgICAgICAgICAgIEV2aWRlbmNlIGV2aWRlbmNlID0gbmV3IEV2aWRlbmNlKGV2aSwgaW5mbywgaWQsIHYsIHIsIHMsIHRoaXMsIG1zZy5zZW5kZXIpOwogICAgICAgICAgICBuZXdFdmlkZW5jZUV2ZW50KGV2aWRlbmNlKTsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gRXZpZGVuY2VTaWduZXJzRGF0YShhZGRyZXNzW10gZXZpZGVuY2VTaWduZXJzKXB1YmxpY3sKICAgICAgICAgICAgZm9yKHVpbnQgaT0wOyBpPGV2aWRlbmNlU2lnbmVycy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBzaWduZXJzLnB1c2goZXZpZGVuY2VTaWduZXJzW2ldKTsKCQkJfQoJCX0KCiAgICBmdW5jdGlvbiB2ZXJpZnkoYWRkcmVzcyBhZGRyKXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpewogICAgZm9yKHVpbnQgaT0wOyBpPHNpZ25lcnMubGVuZ3RoOyArK2kpIHsKICAgICAgICBpZiAoYWRkciA9PSBzaWduZXJzW2ldKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyKHVpbnQgaW5kZXgpcHVibGljIGNvbnN0YW50IHJldHVybnMoYWRkcmVzcyl7CiAgICAgICAgdWludCBsaXN0U2l6ZSA9IHNpZ25lcnMubGVuZ3RoOwogICAgICAgIGlmKGluZGV4IDwgbGlzdFNpemUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc2lnbmVyc1tpbmRleF07CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyc1NpemUoKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyh1aW50KXsKICAgICAgICByZXR1cm4gc2lnbmVycy5sZW5ndGg7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVycygpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3NbXSl7CiAgICAgICAgcmV0dXJuIHNpZ25lcnM7CiAgICB9Cgp9', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(7, 2, 2, 'EvidenceSignersData', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKaW1wb3J0ICJFdmlkZW5jZS5zb2wiOwoKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YXsKICAgICAgICBhZGRyZXNzW10gc2lnbmVyczsKCQlldmVudCBuZXdFdmlkZW5jZUV2ZW50KGFkZHJlc3MgYWRkcik7CiAgICAgICAgZnVuY3Rpb24gbmV3RXZpZGVuY2Uoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sc3RyaW5nIGlkLHVpbnQ4IHYsIGJ5dGVzMzIgcixieXRlczMyIHMpcHVibGljIHJldHVybnMoYWRkcmVzcykKICAgICAgICB7CiAgICAgICAgICAgIEV2aWRlbmNlIGV2aWRlbmNlID0gbmV3IEV2aWRlbmNlKGV2aSwgaW5mbywgaWQsIHYsIHIsIHMsIHRoaXMsIG1zZy5zZW5kZXIpOwogICAgICAgICAgICBuZXdFdmlkZW5jZUV2ZW50KGV2aWRlbmNlKTsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gRXZpZGVuY2VTaWduZXJzRGF0YShhZGRyZXNzW10gZXZpZGVuY2VTaWduZXJzKXB1YmxpY3sKICAgICAgICAgICAgZm9yKHVpbnQgaT0wOyBpPGV2aWRlbmNlU2lnbmVycy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBzaWduZXJzLnB1c2goZXZpZGVuY2VTaWduZXJzW2ldKTsKCQkJfQoJCX0KCiAgICBmdW5jdGlvbiB2ZXJpZnkoYWRkcmVzcyBhZGRyKXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpewogICAgZm9yKHVpbnQgaT0wOyBpPHNpZ25lcnMubGVuZ3RoOyArK2kpIHsKICAgICAgICBpZiAoYWRkciA9PSBzaWduZXJzW2ldKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyKHVpbnQgaW5kZXgpcHVibGljIGNvbnN0YW50IHJldHVybnMoYWRkcmVzcyl7CiAgICAgICAgdWludCBsaXN0U2l6ZSA9IHNpZ25lcnMubGVuZ3RoOwogICAgICAgIGlmKGluZGV4IDwgbGlzdFNpemUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc2lnbmVyc1tpbmRleF07CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyc1NpemUoKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyh1aW50KXsKICAgICAgICByZXR1cm4gc2lnbmVycy5sZW5ndGg7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVycygpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3NbXSl7CiAgICAgICAgcmV0dXJuIHNpZ25lcnM7CiAgICB9Cgp9', 'IyBFdmlkZW5jZSDlkIjnuqYKCiMjIOeugOS7iwpFdmlkZW5jZSDnpLrkvovlkIjnuqbvvIzkvb/nlKjliIblsYLnmoTmmbrog73lkIjnuqbnu5PmnoTvvJogCjHvvInlt6XljoLlkIjnuqbvvIhFdmlkZW5jZVNpZ25lcnNEYXRhLnNvbO+8ie+8jOeUseWtmOivgeWQhOaWueS6i+WJjee6puWumu+8jOWtmOWCqOWtmOivgeeUn+aViOadoeS7tu+8jOW5tueuoeeQhuWtmOivgeeahOeUn+aIkOOAgiAgCjLvvInlrZjor4HlkIjnuqbvvIhFdmlkZW5jZS5zb2zvvInvvIznlLHlt6XljoLlkIjnuqbnlJ/miJDvvIzlrZjlgqjlrZjor4FpZO+8jGhhc2jlkozlkITmlrnnrb7lkI3vvIjmr4/lvKDlrZjor4HkuIDkuKrlkIjnuqbvvInjgIIgIA==', '', now(), now()); -- bac points -- -INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (8, 3, 3, 'BAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgppbXBvcnQgIi4vU2FmZU1hdGguc29sIjsKaW1wb3J0ICIuL1JvbGVzLnNvbCI7CmltcG9ydCAiLi9BZGRyZXNzLnNvbCI7Cgpjb250cmFjdCBJc3N1ZXJSb2xlIHsKICAgIHVzaW5nIFJvbGVzIGZvciBSb2xlcy5Sb2xlOwoKICAgIGV2ZW50IElzc3VlckFkZGVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKICAgIGV2ZW50IElzc3VlclJlbW92ZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwoKICAgIFJvbGVzLlJvbGUgcHJpdmF0ZSBfaXNzdWVyczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX2FkZElzc3Vlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBtb2RpZmllciBvbmx5SXNzdWVyKCkgewogICAgICAgIHJlcXVpcmUoaXNJc3N1ZXIobXNnLnNlbmRlciksICJJc3N1ZXJSb2xlOiBjYWxsZXIgZG9lcyBub3QgaGF2ZSB0aGUgSXNzdWVyIHJvbGUiKTsKICAgICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfaXNzdWVycy5oYXMoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIG9ubHlJc3N1ZXIgewogICAgICAgIF9hZGRJc3N1ZXIoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVub3VuY2VJc3N1ZXIoKSBwdWJsaWMgewogICAgICAgIF9yZW1vdmVJc3N1ZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZElzc3VlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfaXNzdWVycy5hZGQoYWNjb3VudCk7CiAgICAgICAgZW1pdCBJc3N1ZXJBZGRlZChhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcmVtb3ZlSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9pc3N1ZXJzLnJlbW92ZShhY2NvdW50KTsKICAgICAgICBlbWl0IElzc3VlclJlbW92ZWQoYWNjb3VudCk7CiAgICB9Cn0KCmNvbnRyYWN0IFN1c3BlbmRlclJvbGUgewogICAgdXNpbmcgUm9sZXMgZm9yIFJvbGVzLlJvbGU7CgogICAgZXZlbnQgU3VzcGVuZGVyQWRkZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwogICAgZXZlbnQgU3VzcGVuZGVyUmVtb3ZlZChhZGRyZXNzIGluZGV4ZWQgYWNjb3VudCk7CgogICAgUm9sZXMuUm9sZSBwcml2YXRlIF9zdXNwZW5kZXJzOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfYWRkU3VzcGVuZGVyKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIG1vZGlmaWVyIG9ubHlTdXNwZW5kZXIoKSB7CiAgICAgICAgcmVxdWlyZShpc1N1c3BlbmRlcihtc2cuc2VuZGVyKSwgIlN1c3BlbmRlclJvbGU6IGNhbGxlciBkb2VzIG5vdCBoYXZlIHRoZSBTdXNwZW5kZXIgcm9sZSIpOwogICAgICAgIF87CiAgICB9CgogICAgZnVuY3Rpb24gaXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZXJzLmhhcyhhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgb25seVN1c3BlbmRlciB7CiAgICAgICAgX2FkZFN1c3BlbmRlcihhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiByZW5vdW5jZVN1c3BlbmRlcigpIHB1YmxpYyB7CiAgICAgICAgX3JlbW92ZVN1c3BlbmRlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBfYWRkU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9zdXNwZW5kZXJzLmFkZChhY2NvdW50KTsKICAgICAgICBlbWl0IFN1c3BlbmRlckFkZGVkKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9yZW1vdmVTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB7CiAgICAgICAgX3N1c3BlbmRlcnMucmVtb3ZlKGFjY291bnQpOwogICAgICAgIGVtaXQgU3VzcGVuZGVyUmVtb3ZlZChhY2NvdW50KTsKICAgIH0KfQoKY29udHJhY3QgU3VzcGVuZGFibGUgaXMgU3VzcGVuZGVyUm9sZSB7CgogICAgZXZlbnQgU3VzcGVuZGVkKGFkZHJlc3MgYWNjb3VudCk7CiAgICBldmVudCBVblN1c3BlbmRlZChhZGRyZXNzIGFjY291bnQpOwoKICAgIGJvb2wgcHJpdmF0ZSBfc3VzcGVuZGVkOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfc3VzcGVuZGVkID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNvbnRyYWN0IGlzIHN1c3BlbmRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBmdW5jdGlvbiBzdXNwZW5kZWQoKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IE1vZGlmaWVyIHRvIG1ha2UgYSBmdW5jdGlvbiBjYWxsYWJsZSBvbmx5IHdoZW4gdGhlIGNvbnRyYWN0IGlzIG5vdCBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5Ob3RTdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZSghX3N1c3BlbmRlZCwgIlN1c3BlbmRhYmxlOiBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNb2RpZmllciB0byBtYWtlIGEgZnVuY3Rpb24gY2FsbGFibGUgb25seSB3aGVuIHRoZSBjb250cmFjdCBpcyBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5TdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZShfc3VzcGVuZGVkLCAiU3VzcGVuZGFibGU6IG5vdCBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gc3VzcGVuZCwgdHJpZ2dlcnMgc3RvcHBlZCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VzcGVuZCgpIHB1YmxpYyBvbmx5U3VzcGVuZGVyIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zdXNwZW5kZWQgPSB0cnVlOwogICAgICAgIGVtaXQgU3VzcGVuZGVkKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gdW5TdXNwZW5kLCByZXR1cm5zIHRvIG5vcm1hbCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gdW5TdXNwZW5kKCkgcHVibGljIG9ubHlTdXNwZW5kZXIgd2hlblN1c3BlbmRlZCB7CiAgICAgICAgX3N1c3BlbmRlZCA9IGZhbHNlOwogICAgICAgIGVtaXQgVW5TdXNwZW5kZWQobXNnLnNlbmRlcik7CiAgICB9Cn0KCmNvbnRyYWN0IElCQUMwMDFSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBub3RpY2UgSGFuZGxlIHRoZSByZWNlaXB0IG9mIGFuIE5GVAogICAgICogQGRldiBUaGUgQkFDMDAxIHNtYXJ0IGNvbnRyYWN0IGNhbGxzIHRoaXMgZnVuY3Rpb24gb24gdGhlIHJlY2lwaWVudAogICAgICovCiAgICBmdW5jdGlvbiBvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3Mgb3BlcmF0b3IsIGFkZHJlc3MgZnJvbSwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkKICAgIHB1YmxpYyByZXR1cm5zIChieXRlczQpOwp9Cgpjb250cmFjdCBCQUMwMDFIb2xkZXIgaXMgSUJBQzAwMVJlY2VpdmVyIHsKICAgIGZ1bmN0aW9uIG9uQkFDMDAxUmVjZWl2ZWQoYWRkcmVzcywgYWRkcmVzcywgdWludDI1NiwgYnl0ZXMpIHB1YmxpYyByZXR1cm5zIChieXRlczQpIHsKICAgICAgICByZXR1cm4gdGhpcy5vbkJBQzAwMVJlY2VpdmVkLnNlbGVjdG9yOwogICAgfQp9CgoKLyoqCiAqIEB0aXRsZSBTdGFuZGFyZCBCQUMwMDEgYXNzZXQKICovCmNvbnRyYWN0IEJBQzAwMSBpcyBJc3N1ZXJSb2xlLCBTdXNwZW5kYWJsZSB7CiAgICB1c2luZyBTYWZlTWF0aCBmb3IgdWludDI1NjsKICAgIHVzaW5nIEFkZHJlc3MgZm9yIGFkZHJlc3M7CgogICAgbWFwcGluZyhhZGRyZXNzID0+IHVpbnQyNTYpIHByaXZhdGUgX2JhbGFuY2VzOwogICAgbWFwcGluZyhhZGRyZXNzID0+IG1hcHBpbmcoYWRkcmVzcyA9PiB1aW50MjU2KSkgcHJpdmF0ZSBfYWxsb3dlZDsKICAgIHVpbnQyNTYgcHJpdmF0ZSBfdG90YWxBbW91bnQ7CiAgICBzdHJpbmcgcHJpdmF0ZSBfZGVzY3JpcHRpb247CiAgICBzdHJpbmcgcHJpdmF0ZSBfc2hvcnROYW1lOwogICAgdWludDggcHJpdmF0ZSAgX21pblVuaXQ7CgogICAgLy8gRXF1YWxzIHRvIGBieXRlczQoa2VjY2FrMjU2KCJvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3MsYWRkcmVzcyx1aW50MjU2LGJ5dGVzKSIpKWAKICAgIGJ5dGVzNCBwcml2YXRlIGNvbnN0YW50IF9CQUMwMDFfUkVDRUlWRUQgPSAweGM3M2QxNmFlOwoKCiAgICBldmVudCBTZW5kKCBhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKTsKICAgIGV2ZW50IEFwcHJvdmFsKCBhZGRyZXNzIGluZGV4ZWQgb3duZXIsIGFkZHJlc3MgaW5kZXhlZCBzcGVuZGVyLCB1aW50MjU2IHZhbHVlKTsKCgogICAgY29uc3RydWN0b3Ioc3RyaW5nIG1lbW9yeSBkZXNjcmlwdGlvbiwgc3RyaW5nIG1lbW9yeSBzaG9ydE5hbWUsIHVpbnQ4IG1pblVuaXQsIHVpbnQyNTYgdG90YWxBbW91bnQpIHB1YmxpYyB7CiAgICAgICAgX2Rlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgX3Nob3J0TmFtZSA9IHNob3J0TmFtZTsKICAgICAgICBfbWluVW5pdCA9IG1pblVuaXQ7CiAgICAgICAgX2lzc3VlKG1zZy5zZW5kZXIsIHRvdGFsQW1vdW50ICogKDEwICoqIHVpbnQyNTYobWluVW5pdCkpLCAiIik7CiAgICB9CgoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJldHVybiBfdG90YWxBbW91bnQ7CiAgICB9CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9iYWxhbmNlc1tvd25lcl07CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEZ1bmN0aW9uIHRvIGNoZWNrIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFsbG93YW5jZShhZGRyZXNzIG93bmVyLCBhZGRyZXNzIHNwZW5kZXIpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2FsbG93ZWRbb3duZXJdW3NwZW5kZXJdOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zZW5kKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7CgogICAgfQoKLy8gICAgZnVuY3Rpb24gc2FmZVNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewovLyAgICAgICAgc2VuZCh0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgLyoqCiAgICAgKiBAZGV2IEFwcHJvdmUgdGhlIHBhc3NlZCBhZGRyZXNzIHRvIHNwZW5kIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIGFzc2V0cyBvbiBiZWhhbGYgb2YgbXNnLnNlbmRlci4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBfYXBwcm92ZShtc2cuc2VuZGVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlbmQgYXNzZXRzIGZyb20gb25lIGFkZHJlc3MgdG8gYW5vdGhlci4KICAgICAqLwogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgX3NlbmQoZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgICAgICBfYXBwcm92ZShmcm9tLCBtc2cuc2VuZGVyLCBfYWxsb3dlZFtmcm9tXVttc2cuc2VuZGVyXS5zdWIodmFsdWUpKTsKICAgICAgICAvL2FkZAogICAgICAgIHJlcXVpcmUoX2NoZWNrT25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpLCAiQkFDMDAxOiBzZW5kIHRvIG5vbiBCQUMwMDFSZWNlaXZlciBpbXBsZW1lbnRlciIpOwoKCiAgICB9CgovLy8vIHNhZmUgdG9kbwovLyAgICBmdW5jdGlvbiBzYWZlU2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7Ci8vICAgICAgICBzZW5kRnJvbShmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKGZyb20sIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgZnVuY3Rpb24gYmF0Y2hTZW5kKGFkZHJlc3NbXSB0bywgdWludDI1NltdIHZhbHVlcywgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewoKICAgICAgICAvLyBNVVNUIFRocm93IG9uIGVycm9ycwoKICAgICAgICByZXF1aXJlKHRvLmxlbmd0aCA9PSB2YWx1ZXMubGVuZ3RoLCAidG8gYW5kIHZhbHVlcyBhcnJheSBsZW5naHQgbXVzdCBtYXRjaC4iKTsKCiAgICAgICAgZm9yICh1aW50MjU2IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVxdWlyZSh0b1tpXSAhPSBhZGRyZXNzKDB4MCksICJkZXN0aW5hdGlvbiBhZGRyZXNzIG11c3QgYmUgbm9uLXplcm8uIik7CgogICAgICAgICAgICBzZW5kKHRvW2ldLCB2YWx1ZXNbaV0sIGRhdGEpOwogICAgICAgIH0KICAgIH0KCgogICAgZnVuY3Rpb24gX2NoZWNrT25CQUMwMDFSZWNlaXZlZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpCiAgICBpbnRlcm5hbCByZXR1cm5zIChib29sKQogICAgewogICAgICAgIGlmICghdG8uaXNDb250cmFjdCgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgYnl0ZXM0IHJldHZhbCA9IElCQUMwMDFSZWNlaXZlcih0bykub25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwogICAgICAgIHJldHVybiAocmV0dmFsID09IF9CQUMwMDFfUkVDRUlWRUQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbmNyZWFzZSB0aGUgYW1vdW50IG9mIGFzc2V0cyB0aGF0IGFuIG93bmVyIGFsbG93ZWQgdG8gYSBzcGVuZGVyLgogICAgICovCiAgICBmdW5jdGlvbiBpbmNyZWFzZUFsbG93YW5jZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYWRkZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLmFkZChhZGRlZFZhbHVlKSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IERlY3JlYXNlIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKiBhcHByb3ZlIHNob3VsZCBiZSBjYWxsZWQgd2hlbiBfYWxsb3dlZFttc2cuc2VuZGVyXVtzcGVuZGVyXSA9PSAwLiBUbyBkZWNyZW1lbnQKICAgICAqLwogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLnN1YihzdWJ0cmFjdGVkVmFsdWUpKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXN0cm95KHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3kobXNnLnNlbmRlciwgdmFsdWUsIGRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBCdXJucyBhIHNwZWNpZmljIGFtb3VudCBvZiBhc3NldHMgZnJvbSB0aGUgdGFyZ2V0IGFkZHJlc3MgYW5kIGRlY3JlbWVudHMgYWxsb3dhbmNlLgogICAgICovCiAgICBmdW5jdGlvbiBkZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3lGcm9tKGZyb20sIHZhbHVlLCBkYXRhKTsKICAgIH0KCgogICAgZnVuY3Rpb24gZGVzY3JpcHRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIF9kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIHNob3J0TmFtZSBvZiB0aGUgYXNzZXQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNob3J0TmFtZSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX3Nob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBtaW5Vbml0IG9mIHRoZSBhc3NldC4KICAgICAqLwogICAgZnVuY3Rpb24gbWluVW5pdCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQ4KSB7CiAgICAgICAgcmV0dXJuIF9taW5Vbml0OwogICAgfQoKCiAgICBmdW5jdGlvbiBpc3N1ZShhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgb25seUlzc3VlciByZXR1cm5zIChib29sKSB7CiAgICAgICAgX2lzc3VlKHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXYgU2VuZCBhc3NldCBmb3IgYSBzcGVjaWZpZWQgYWRkcmVzc2VzLgogICAgICovCiAgICBmdW5jdGlvbiBfc2VuZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKHRvICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IHNlbmQgdG8gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfYmFsYW5jZXNbZnJvbV0gPSBfYmFsYW5jZXNbZnJvbV0uc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbdG9dID0gX2JhbGFuY2VzW3RvXS5hZGQodmFsdWUpOwogICAgICAgIGVtaXQgU2VuZCggZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCBpc3N1ZXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBhbmQgYXNzaWducyBpdCB0bwogICAgICovCiAgICBmdW5jdGlvbiBfaXNzdWUoYWRkcmVzcyBhY2NvdW50LCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShhY2NvdW50ICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IGlzc3VlIHRvIHRoZSB6ZXJvIGFkZHJlc3MiKTsKCiAgICAgICAgX3RvdGFsQW1vdW50ID0gX3RvdGFsQW1vdW50LmFkZCh2YWx1ZSk7CiAgICAgICAgX2JhbGFuY2VzW2FjY291bnRdID0gX2JhbGFuY2VzW2FjY291bnRdLmFkZCh2YWx1ZSk7CiAgICAgICAgZW1pdCBTZW5kKCBhZGRyZXNzKDApLCBhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95KGFkZHJlc3MgYWNjb3VudCwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiQkFDMDAxOiBkZXN0cm95IGZyb20gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfdG90YWxBbW91bnQgPSBfdG90YWxBbW91bnQuc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbYWNjb3VudF0gPSBfYmFsYW5jZXNbYWNjb3VudF0uc3ViKHZhbHVlKTsKICAgICAgICBlbWl0IFNlbmQoIGFjY291bnQsIGFkZHJlc3MoMCksIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZSBhbiBhZGRyZXNzIHRvIHNwZW5kIGFub3RoZXIgYWRkcmVzc2VzJyBhc3NldHMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hcHByb3ZlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiB2YWx1ZSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUob3duZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSBmcm9tIHRoZSB6ZXJvIGFkZHJlc3MiKTsKICAgICAgICByZXF1aXJlKHNwZW5kZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSB0byB0aGUgemVybyBhZGRyZXNzIik7CgogICAgICAgIF9hbGxvd2VkW293bmVyXVtzcGVuZGVyXSA9IHZhbHVlOwogICAgICAgIGVtaXQgQXBwcm92YWwoIG93bmVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95RnJvbShhZGRyZXNzIGFjY291bnQsIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICBfZGVzdHJveShhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgX2FwcHJvdmUoYWNjb3VudCwgbXNnLnNlbmRlciwgX2FsbG93ZWRbYWNjb3VudF1bbXNnLnNlbmRlcl0uc3ViKHZhbHVlKSk7CiAgICB9Cn0KCg==', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(8, 3, 3, 'BAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgppbXBvcnQgIi4vU2FmZU1hdGguc29sIjsKaW1wb3J0ICIuL1JvbGVzLnNvbCI7CmltcG9ydCAiLi9BZGRyZXNzLnNvbCI7Cgpjb250cmFjdCBJc3N1ZXJSb2xlIHsKICAgIHVzaW5nIFJvbGVzIGZvciBSb2xlcy5Sb2xlOwoKICAgIGV2ZW50IElzc3VlckFkZGVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKICAgIGV2ZW50IElzc3VlclJlbW92ZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwoKICAgIFJvbGVzLlJvbGUgcHJpdmF0ZSBfaXNzdWVyczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX2FkZElzc3Vlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBtb2RpZmllciBvbmx5SXNzdWVyKCkgewogICAgICAgIHJlcXVpcmUoaXNJc3N1ZXIobXNnLnNlbmRlciksICJJc3N1ZXJSb2xlOiBjYWxsZXIgZG9lcyBub3QgaGF2ZSB0aGUgSXNzdWVyIHJvbGUiKTsKICAgICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfaXNzdWVycy5oYXMoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIG9ubHlJc3N1ZXIgewogICAgICAgIF9hZGRJc3N1ZXIoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVub3VuY2VJc3N1ZXIoKSBwdWJsaWMgewogICAgICAgIF9yZW1vdmVJc3N1ZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZElzc3VlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfaXNzdWVycy5hZGQoYWNjb3VudCk7CiAgICAgICAgZW1pdCBJc3N1ZXJBZGRlZChhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcmVtb3ZlSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9pc3N1ZXJzLnJlbW92ZShhY2NvdW50KTsKICAgICAgICBlbWl0IElzc3VlclJlbW92ZWQoYWNjb3VudCk7CiAgICB9Cn0KCmNvbnRyYWN0IFN1c3BlbmRlclJvbGUgewogICAgdXNpbmcgUm9sZXMgZm9yIFJvbGVzLlJvbGU7CgogICAgZXZlbnQgU3VzcGVuZGVyQWRkZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwogICAgZXZlbnQgU3VzcGVuZGVyUmVtb3ZlZChhZGRyZXNzIGluZGV4ZWQgYWNjb3VudCk7CgogICAgUm9sZXMuUm9sZSBwcml2YXRlIF9zdXNwZW5kZXJzOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfYWRkU3VzcGVuZGVyKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIG1vZGlmaWVyIG9ubHlTdXNwZW5kZXIoKSB7CiAgICAgICAgcmVxdWlyZShpc1N1c3BlbmRlcihtc2cuc2VuZGVyKSwgIlN1c3BlbmRlclJvbGU6IGNhbGxlciBkb2VzIG5vdCBoYXZlIHRoZSBTdXNwZW5kZXIgcm9sZSIpOwogICAgICAgIF87CiAgICB9CgogICAgZnVuY3Rpb24gaXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZXJzLmhhcyhhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgb25seVN1c3BlbmRlciB7CiAgICAgICAgX2FkZFN1c3BlbmRlcihhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiByZW5vdW5jZVN1c3BlbmRlcigpIHB1YmxpYyB7CiAgICAgICAgX3JlbW92ZVN1c3BlbmRlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBfYWRkU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9zdXNwZW5kZXJzLmFkZChhY2NvdW50KTsKICAgICAgICBlbWl0IFN1c3BlbmRlckFkZGVkKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9yZW1vdmVTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB7CiAgICAgICAgX3N1c3BlbmRlcnMucmVtb3ZlKGFjY291bnQpOwogICAgICAgIGVtaXQgU3VzcGVuZGVyUmVtb3ZlZChhY2NvdW50KTsKICAgIH0KfQoKY29udHJhY3QgU3VzcGVuZGFibGUgaXMgU3VzcGVuZGVyUm9sZSB7CgogICAgZXZlbnQgU3VzcGVuZGVkKGFkZHJlc3MgYWNjb3VudCk7CiAgICBldmVudCBVblN1c3BlbmRlZChhZGRyZXNzIGFjY291bnQpOwoKICAgIGJvb2wgcHJpdmF0ZSBfc3VzcGVuZGVkOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfc3VzcGVuZGVkID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNvbnRyYWN0IGlzIHN1c3BlbmRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBmdW5jdGlvbiBzdXNwZW5kZWQoKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IE1vZGlmaWVyIHRvIG1ha2UgYSBmdW5jdGlvbiBjYWxsYWJsZSBvbmx5IHdoZW4gdGhlIGNvbnRyYWN0IGlzIG5vdCBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5Ob3RTdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZSghX3N1c3BlbmRlZCwgIlN1c3BlbmRhYmxlOiBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNb2RpZmllciB0byBtYWtlIGEgZnVuY3Rpb24gY2FsbGFibGUgb25seSB3aGVuIHRoZSBjb250cmFjdCBpcyBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5TdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZShfc3VzcGVuZGVkLCAiU3VzcGVuZGFibGU6IG5vdCBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gc3VzcGVuZCwgdHJpZ2dlcnMgc3RvcHBlZCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VzcGVuZCgpIHB1YmxpYyBvbmx5U3VzcGVuZGVyIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zdXNwZW5kZWQgPSB0cnVlOwogICAgICAgIGVtaXQgU3VzcGVuZGVkKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gdW5TdXNwZW5kLCByZXR1cm5zIHRvIG5vcm1hbCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gdW5TdXNwZW5kKCkgcHVibGljIG9ubHlTdXNwZW5kZXIgd2hlblN1c3BlbmRlZCB7CiAgICAgICAgX3N1c3BlbmRlZCA9IGZhbHNlOwogICAgICAgIGVtaXQgVW5TdXNwZW5kZWQobXNnLnNlbmRlcik7CiAgICB9Cn0KCmNvbnRyYWN0IElCQUMwMDFSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBub3RpY2UgSGFuZGxlIHRoZSByZWNlaXB0IG9mIGFuIE5GVAogICAgICogQGRldiBUaGUgQkFDMDAxIHNtYXJ0IGNvbnRyYWN0IGNhbGxzIHRoaXMgZnVuY3Rpb24gb24gdGhlIHJlY2lwaWVudAogICAgICovCiAgICBmdW5jdGlvbiBvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3Mgb3BlcmF0b3IsIGFkZHJlc3MgZnJvbSwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkKICAgIHB1YmxpYyByZXR1cm5zIChieXRlczQpOwp9Cgpjb250cmFjdCBCQUMwMDFIb2xkZXIgaXMgSUJBQzAwMVJlY2VpdmVyIHsKICAgIGZ1bmN0aW9uIG9uQkFDMDAxUmVjZWl2ZWQoYWRkcmVzcywgYWRkcmVzcywgdWludDI1NiwgYnl0ZXMpIHB1YmxpYyByZXR1cm5zIChieXRlczQpIHsKICAgICAgICByZXR1cm4gdGhpcy5vbkJBQzAwMVJlY2VpdmVkLnNlbGVjdG9yOwogICAgfQp9CgoKLyoqCiAqIEB0aXRsZSBTdGFuZGFyZCBCQUMwMDEgYXNzZXQKICovCmNvbnRyYWN0IEJBQzAwMSBpcyBJc3N1ZXJSb2xlLCBTdXNwZW5kYWJsZSB7CiAgICB1c2luZyBTYWZlTWF0aCBmb3IgdWludDI1NjsKICAgIHVzaW5nIEFkZHJlc3MgZm9yIGFkZHJlc3M7CgogICAgbWFwcGluZyhhZGRyZXNzID0+IHVpbnQyNTYpIHByaXZhdGUgX2JhbGFuY2VzOwogICAgbWFwcGluZyhhZGRyZXNzID0+IG1hcHBpbmcoYWRkcmVzcyA9PiB1aW50MjU2KSkgcHJpdmF0ZSBfYWxsb3dlZDsKICAgIHVpbnQyNTYgcHJpdmF0ZSBfdG90YWxBbW91bnQ7CiAgICBzdHJpbmcgcHJpdmF0ZSBfZGVzY3JpcHRpb247CiAgICBzdHJpbmcgcHJpdmF0ZSBfc2hvcnROYW1lOwogICAgdWludDggcHJpdmF0ZSAgX21pblVuaXQ7CgogICAgLy8gRXF1YWxzIHRvIGBieXRlczQoa2VjY2FrMjU2KCJvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3MsYWRkcmVzcyx1aW50MjU2LGJ5dGVzKSIpKWAKICAgIGJ5dGVzNCBwcml2YXRlIGNvbnN0YW50IF9CQUMwMDFfUkVDRUlWRUQgPSAweGM3M2QxNmFlOwoKCiAgICBldmVudCBTZW5kKCBhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKTsKICAgIGV2ZW50IEFwcHJvdmFsKCBhZGRyZXNzIGluZGV4ZWQgb3duZXIsIGFkZHJlc3MgaW5kZXhlZCBzcGVuZGVyLCB1aW50MjU2IHZhbHVlKTsKCgogICAgY29uc3RydWN0b3Ioc3RyaW5nIG1lbW9yeSBkZXNjcmlwdGlvbiwgc3RyaW5nIG1lbW9yeSBzaG9ydE5hbWUsIHVpbnQ4IG1pblVuaXQsIHVpbnQyNTYgdG90YWxBbW91bnQpIHB1YmxpYyB7CiAgICAgICAgX2Rlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgX3Nob3J0TmFtZSA9IHNob3J0TmFtZTsKICAgICAgICBfbWluVW5pdCA9IG1pblVuaXQ7CiAgICAgICAgX2lzc3VlKG1zZy5zZW5kZXIsIHRvdGFsQW1vdW50ICogKDEwICoqIHVpbnQyNTYobWluVW5pdCkpLCAiIik7CiAgICB9CgoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJldHVybiBfdG90YWxBbW91bnQ7CiAgICB9CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9iYWxhbmNlc1tvd25lcl07CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEZ1bmN0aW9uIHRvIGNoZWNrIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFsbG93YW5jZShhZGRyZXNzIG93bmVyLCBhZGRyZXNzIHNwZW5kZXIpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2FsbG93ZWRbb3duZXJdW3NwZW5kZXJdOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zZW5kKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7CgogICAgfQoKLy8gICAgZnVuY3Rpb24gc2FmZVNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewovLyAgICAgICAgc2VuZCh0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgLyoqCiAgICAgKiBAZGV2IEFwcHJvdmUgdGhlIHBhc3NlZCBhZGRyZXNzIHRvIHNwZW5kIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIGFzc2V0cyBvbiBiZWhhbGYgb2YgbXNnLnNlbmRlci4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBfYXBwcm92ZShtc2cuc2VuZGVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlbmQgYXNzZXRzIGZyb20gb25lIGFkZHJlc3MgdG8gYW5vdGhlci4KICAgICAqLwogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgX3NlbmQoZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgICAgICBfYXBwcm92ZShmcm9tLCBtc2cuc2VuZGVyLCBfYWxsb3dlZFtmcm9tXVttc2cuc2VuZGVyXS5zdWIodmFsdWUpKTsKICAgICAgICAvL2FkZAogICAgICAgIHJlcXVpcmUoX2NoZWNrT25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpLCAiQkFDMDAxOiBzZW5kIHRvIG5vbiBCQUMwMDFSZWNlaXZlciBpbXBsZW1lbnRlciIpOwoKCiAgICB9CgovLy8vIHNhZmUgdG9kbwovLyAgICBmdW5jdGlvbiBzYWZlU2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7Ci8vICAgICAgICBzZW5kRnJvbShmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKGZyb20sIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgZnVuY3Rpb24gYmF0Y2hTZW5kKGFkZHJlc3NbXSB0bywgdWludDI1NltdIHZhbHVlcywgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewoKICAgICAgICAvLyBNVVNUIFRocm93IG9uIGVycm9ycwoKICAgICAgICByZXF1aXJlKHRvLmxlbmd0aCA9PSB2YWx1ZXMubGVuZ3RoLCAidG8gYW5kIHZhbHVlcyBhcnJheSBsZW5naHQgbXVzdCBtYXRjaC4iKTsKCiAgICAgICAgZm9yICh1aW50MjU2IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVxdWlyZSh0b1tpXSAhPSBhZGRyZXNzKDB4MCksICJkZXN0aW5hdGlvbiBhZGRyZXNzIG11c3QgYmUgbm9uLXplcm8uIik7CgogICAgICAgICAgICBzZW5kKHRvW2ldLCB2YWx1ZXNbaV0sIGRhdGEpOwogICAgICAgIH0KICAgIH0KCgogICAgZnVuY3Rpb24gX2NoZWNrT25CQUMwMDFSZWNlaXZlZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpCiAgICBpbnRlcm5hbCByZXR1cm5zIChib29sKQogICAgewogICAgICAgIGlmICghdG8uaXNDb250cmFjdCgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgYnl0ZXM0IHJldHZhbCA9IElCQUMwMDFSZWNlaXZlcih0bykub25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwogICAgICAgIHJldHVybiAocmV0dmFsID09IF9CQUMwMDFfUkVDRUlWRUQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbmNyZWFzZSB0aGUgYW1vdW50IG9mIGFzc2V0cyB0aGF0IGFuIG93bmVyIGFsbG93ZWQgdG8gYSBzcGVuZGVyLgogICAgICovCiAgICBmdW5jdGlvbiBpbmNyZWFzZUFsbG93YW5jZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYWRkZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLmFkZChhZGRlZFZhbHVlKSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IERlY3JlYXNlIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKiBhcHByb3ZlIHNob3VsZCBiZSBjYWxsZWQgd2hlbiBfYWxsb3dlZFttc2cuc2VuZGVyXVtzcGVuZGVyXSA9PSAwLiBUbyBkZWNyZW1lbnQKICAgICAqLwogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLnN1YihzdWJ0cmFjdGVkVmFsdWUpKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXN0cm95KHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3kobXNnLnNlbmRlciwgdmFsdWUsIGRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBCdXJucyBhIHNwZWNpZmljIGFtb3VudCBvZiBhc3NldHMgZnJvbSB0aGUgdGFyZ2V0IGFkZHJlc3MgYW5kIGRlY3JlbWVudHMgYWxsb3dhbmNlLgogICAgICovCiAgICBmdW5jdGlvbiBkZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3lGcm9tKGZyb20sIHZhbHVlLCBkYXRhKTsKICAgIH0KCgogICAgZnVuY3Rpb24gZGVzY3JpcHRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIF9kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIHNob3J0TmFtZSBvZiB0aGUgYXNzZXQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNob3J0TmFtZSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX3Nob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBtaW5Vbml0IG9mIHRoZSBhc3NldC4KICAgICAqLwogICAgZnVuY3Rpb24gbWluVW5pdCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQ4KSB7CiAgICAgICAgcmV0dXJuIF9taW5Vbml0OwogICAgfQoKCiAgICBmdW5jdGlvbiBpc3N1ZShhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgb25seUlzc3VlciByZXR1cm5zIChib29sKSB7CiAgICAgICAgX2lzc3VlKHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXYgU2VuZCBhc3NldCBmb3IgYSBzcGVjaWZpZWQgYWRkcmVzc2VzLgogICAgICovCiAgICBmdW5jdGlvbiBfc2VuZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKHRvICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IHNlbmQgdG8gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfYmFsYW5jZXNbZnJvbV0gPSBfYmFsYW5jZXNbZnJvbV0uc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbdG9dID0gX2JhbGFuY2VzW3RvXS5hZGQodmFsdWUpOwogICAgICAgIGVtaXQgU2VuZCggZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCBpc3N1ZXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBhbmQgYXNzaWducyBpdCB0bwogICAgICovCiAgICBmdW5jdGlvbiBfaXNzdWUoYWRkcmVzcyBhY2NvdW50LCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShhY2NvdW50ICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IGlzc3VlIHRvIHRoZSB6ZXJvIGFkZHJlc3MiKTsKCiAgICAgICAgX3RvdGFsQW1vdW50ID0gX3RvdGFsQW1vdW50LmFkZCh2YWx1ZSk7CiAgICAgICAgX2JhbGFuY2VzW2FjY291bnRdID0gX2JhbGFuY2VzW2FjY291bnRdLmFkZCh2YWx1ZSk7CiAgICAgICAgZW1pdCBTZW5kKCBhZGRyZXNzKDApLCBhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95KGFkZHJlc3MgYWNjb3VudCwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiQkFDMDAxOiBkZXN0cm95IGZyb20gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfdG90YWxBbW91bnQgPSBfdG90YWxBbW91bnQuc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbYWNjb3VudF0gPSBfYmFsYW5jZXNbYWNjb3VudF0uc3ViKHZhbHVlKTsKICAgICAgICBlbWl0IFNlbmQoIGFjY291bnQsIGFkZHJlc3MoMCksIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZSBhbiBhZGRyZXNzIHRvIHNwZW5kIGFub3RoZXIgYWRkcmVzc2VzJyBhc3NldHMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hcHByb3ZlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiB2YWx1ZSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUob3duZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSBmcm9tIHRoZSB6ZXJvIGFkZHJlc3MiKTsKICAgICAgICByZXF1aXJlKHNwZW5kZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSB0byB0aGUgemVybyBhZGRyZXNzIik7CgogICAgICAgIF9hbGxvd2VkW293bmVyXVtzcGVuZGVyXSA9IHZhbHVlOwogICAgICAgIGVtaXQgQXBwcm92YWwoIG93bmVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95RnJvbShhZGRyZXNzIGFjY291bnQsIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICBfZGVzdHJveShhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgX2FwcHJvdmUoYWNjb3VudCwgbXNnLnNlbmRlciwgX2FsbG93ZWRbYWNjb3VudF1bbXNnLnNlbmRlcl0uc3ViKHZhbHVlKSk7CiAgICB9Cn0KCg==', 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (9, 3, 3, 'IBAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKaW50ZXJmYWNlIElCQUMwMDEgewoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KTsKCiAgICBmdW5jdGlvbiBzZW5kKGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyA7CgogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gYWxsb3dhbmNlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYW1vdW50KSBwdWJsaWMgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVzdHJveSh1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gZGVzdHJveUZyb20oYWRkcmVzcyBmcm9tLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBmdW5jdGlvbiBiYXRjaFNlbmQoYWRkcmVzc1tdIHRvLCB1aW50MjU2W10gdmFsdWVzLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaW5jcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IGFkZGVkVmFsdWUpIHB1YmxpYyAgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBldmVudCBTZW5kKGFkZHJlc3MgaW5kZXhlZCBmcm9tLCBhZGRyZXNzIGluZGV4ZWQgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpOwoKICAgIGV2ZW50IEFwcHJvdmFsKGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpOwoKfQ==', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(9, 3, 3, 'IBAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKaW50ZXJmYWNlIElCQUMwMDEgewoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KTsKCiAgICBmdW5jdGlvbiBzZW5kKGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyA7CgogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gYWxsb3dhbmNlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYW1vdW50KSBwdWJsaWMgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVzdHJveSh1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gZGVzdHJveUZyb20oYWRkcmVzcyBmcm9tLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBmdW5jdGlvbiBiYXRjaFNlbmQoYWRkcmVzc1tdIHRvLCB1aW50MjU2W10gdmFsdWVzLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaW5jcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IGFkZGVkVmFsdWUpIHB1YmxpYyAgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBldmVudCBTZW5kKGFkZHJlc3MgaW5kZXhlZCBmcm9tLCBhZGRyZXNzIGluZGV4ZWQgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpOwoKICAgIGV2ZW50IEFwcHJvdmFsKGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpOwoKfQ==', 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (10, 3, 3, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(10, 3, 3, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (11, 3, 3, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(11, 3, 3, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); -INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (12, 3, 3, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(12, 3, 3, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); +-- smart dev contracts +-- tools basic +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(13, 1, 4, 'Crypto', 'Y29udHJhY3QgQ3J5cHRvCnsKICAgIGZ1bmN0aW9uIHNtMyhieXRlcyBtZW1vcnkgZGF0YSkgcHVibGljIHZpZXcgcmV0dXJucyhieXRlczMyKXt9CiAgICBmdW5jdGlvbiBrZWNjYWsyNTZIYXNoKGJ5dGVzIG1lbW9yeSBkYXRhKSBwdWJsaWMgdmlldyByZXR1cm5zKGJ5dGVzMzIpe30KICAgIGZ1bmN0aW9uIHNtMlZlcmlmeShieXRlczMyICBtZXNzYWdlLCBieXRlcyBtZW1vcnkgcHVibGljS2V5LCBieXRlczMyIHIsIGJ5dGVzMzIgcykgcHVibGljIHZpZXcgcmV0dXJucyhib29sLCBhZGRyZXNzKXt9CiAgICBmdW5jdGlvbiBjdXJ2ZTI1NTE5VlJGVmVyaWZ5KHN0cmluZyBtZW1vcnkgaW5wdXQsIHN0cmluZyBtZW1vcnkgdnJmUHVibGljS2V5LCBzdHJpbmcgbWVtb3J5IHZyZlByb29mKSBwdWJsaWMgdmlldyByZXR1cm5zKGJvb2wsdWludDI1Nil7fQp9', + 'IyBDcnlwdG8KCkNyeXB0byBJbnRlcmZhY2UgQ29udHJhY3Q=', 'IyBDcnlwdG8KCkNyeXB0byBJbnRlcmZhY2UgQ29udHJhY3Q=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(14, 1, 4, 'ShaTest', 'cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CgpwcmFnbWEgZXhwZXJpbWVudGFsIEFCSUVuY29kZXJWMjsKCmltcG9ydCAiLi9DcnlwdG8uc29sIjsKCmNvbnRyYWN0IFNoYVRlc3R7CiAgICBieXRlcyBfZGF0YSA9ICJIZWxsbywgU2hhVGVzdCI7CiAgICBDcnlwdG8gY3J5cHRvOwoKICAgIGNvbnN0cnVjdG9yKCkgcHVibGljIHsKICAgICAgICBjcnlwdG8gPSBDcnlwdG8oMHg1MDA2KTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRTaGEyNTYoYnl0ZXMgbWVtb3J5IF9tZW1vcnkpIHB1YmxpYyByZXR1cm5zKGJ5dGVzMzIgcmVzdWx0KQogICAgewogICAgICAgIHJldHVybiBzaGEyNTYoX21lbW9yeSk7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0S2VjY2FrMjU2KGJ5dGVzIG1lbW9yeSBfbWVtb3J5KSBwdWJsaWMgcmV0dXJucyhieXRlczMyIHJlc3VsdCkKICAgIHsKICAgICAgICByZXR1cm4ga2VjY2FrMjU2KF9tZW1vcnkpOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldERhdGEoKSBwdWJsaWMgdmlldyByZXR1cm5zKGJ5dGVzIG1lbW9yeSkKICAgIHsKICAgICAgICByZXR1cm4gX2RhdGE7CiAgICB9Cn0K', +'IyBTaGFUZXN0CgpDcnlwdG8gSW50ZXJmYWNlIENvbnRyYWN0CgpDcnlwdG8gVGVzdCBDb250cmFjdCBbQ3J5cHRvIEFQSV0oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9kZWZhdWx0L0NyeXB0by5odG1sKQo=', 'IyBTaGFUZXN0CgpDcnlwdG8gSW50ZXJmYWNlIENvbnRyYWN0CgpDcnlwdG8gVGVzdCBDb250cmFjdCBbQ3J5cHRvIEFQSV0oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9kZWZhdWx0L0NyeXB0by5odG1sKQo=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(15, 1, 4, 'HelloWorld', 'cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7Cgpjb250cmFjdCBIZWxsb1dvcmxkIHsKICAgIHN0cmluZyBuYW1lOwoKICAgIGNvbnN0cnVjdG9yKCkgcHVibGljIHsKICAgICAgICBuYW1lID0gIkhlbGxvLCBXb3JsZCEiOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gbmFtZTsKICAgIH0KCiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nIG1lbW9yeSBuKSBwdWJsaWMgewogICAgICAgIG5hbWUgPSBuOwogICAgfQp9', + 'IyBIZWxsb1dvcmxkCgpIZWxsb1dvcmxkIENvbnRyYWN0Cg==', 'IyBIZWxsb1dvcmxkCgpIZWxsb1dvcmxkIENvbnRyYWN0Cg==', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(16, 1, 4, 'KVTableTest', 'cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CgppbXBvcnQgIi4vVGFibGUuc29sIjsKCmNvbnRyYWN0IEtWVGFibGVUZXN0IHsKICAgIGV2ZW50IFNldFJlc3VsdChpbnQyNTYgY291bnQpOwoKICAgIEtWVGFibGVGYWN0b3J5IHRhYmxlRmFjdG9yeTsKICAgIHN0cmluZyBjb25zdGFudCBUQUJMRV9OQU1FID0gInRfa3Z0ZXN0IjsKCiAgICBjb25zdHJ1Y3RvcigpIHB1YmxpYyB7CiAgICAgICAgLy9UaGUgZml4ZWQgYWRkcmVzcyBpcyAweDEwMTAgZm9yIEtWVGFibGVGYWN0b3J5CiAgICAgICAgdGFibGVGYWN0b3J5ID0gS1ZUYWJsZUZhY3RvcnkoMHgxMDEwKTsKICAgICAgICAvLyB0aGUgcGFyYW1ldGVycyBvZiBjcmVhdGVUYWJsZSBhcmUgdGFibGVOYW1lLGtleUZpZWxkLCJ2bGF1ZUZpbGVkMSx2bGF1ZUZpbGVkMix2bGF1ZUZpbGVkMywuLi4iCiAgICAgICAgdGFibGVGYWN0b3J5LmNyZWF0ZVRhYmxlKFRBQkxFX05BTUUsICJpZCIsICJpdGVtX3ByaWNlLGl0ZW1fbmFtZSIpOwogICAgfQoKICAgIC8vZ2V0IHJlY29yZAogICAgZnVuY3Rpb24gZ2V0KHN0cmluZyBtZW1vcnkgaWQpIHB1YmxpYyB2aWV3IHJldHVybnMgKGJvb2wsIGludDI1Niwgc3RyaW5nIG1lbW9yeSkgewogICAgICAgIEtWVGFibGUgdGFibGUgPSB0YWJsZUZhY3Rvcnkub3BlblRhYmxlKFRBQkxFX05BTUUpOwogICAgICAgIGJvb2wgb2sgPSBmYWxzZTsKICAgICAgICBFbnRyeSBlbnRyeTsKICAgICAgICAob2ssIGVudHJ5KSA9IHRhYmxlLmdldChpZCk7CiAgICAgICAgaW50MjU2IGl0ZW1fcHJpY2U7CiAgICAgICAgc3RyaW5nIG1lbW9yeSBpdGVtX25hbWU7CiAgICAgICAgaWYgKG9rKSB7CiAgICAgICAgICAgIGl0ZW1fcHJpY2UgPSBlbnRyeS5nZXRJbnQoIml0ZW1fcHJpY2UiKTsKICAgICAgICAgICAgaXRlbV9uYW1lID0gZW50cnkuZ2V0U3RyaW5nKCJpdGVtX25hbWUiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChvaywgaXRlbV9wcmljZSwgaXRlbV9uYW1lKTsKICAgIH0KCiAgICAvL3NldCByZWNvcmQKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcgbWVtb3J5IGlkLCBpbnQyNTYgaXRlbV9wcmljZSwgc3RyaW5nIG1lbW9yeSBpdGVtX25hbWUpCiAgICBwdWJsaWMKICAgIHJldHVybnMgKGludDI1NikKICAgIHsKICAgICAgICBLVlRhYmxlIHRhYmxlID0gdGFibGVGYWN0b3J5Lm9wZW5UYWJsZShUQUJMRV9OQU1FKTsKICAgICAgICBFbnRyeSBlbnRyeSA9IHRhYmxlLm5ld0VudHJ5KCk7CiAgICAgICAgLy8gdGhlIGxlbmd0aCBvZiBlbnRyeSdzIGZpZWxkIHZhbHVlIHNob3VsZCA8IDE2TUIKICAgICAgICBlbnRyeS5zZXQoImlkIiwgaWQpOwogICAgICAgIGVudHJ5LnNldCgiaXRlbV9wcmljZSIsIGl0ZW1fcHJpY2UpOwogICAgICAgIGVudHJ5LnNldCgiaXRlbV9uYW1lIiwgaXRlbV9uYW1lKTsKICAgICAgICAvLyB0aGUgZmlyc3QgcGFyYW1ldGVyIGxlbmd0aCBvZiBzZXQgc2hvdWxkIDw9IDI1NUIKICAgICAgICBpbnQyNTYgY291bnQgPSB0YWJsZS5zZXQoaWQsIGVudHJ5KTsKICAgICAgICBlbWl0IFNldFJlc3VsdChjb3VudCk7CiAgICAgICAgcmV0dXJuIGNvdW50OwogICAgfQp9', + 'IyBLVlRhYmxlVGVzdAoKS1ZUYWJsZSBjb250cmFjdCBmb3IgQ1JVRCAKCkNSVUQgVGVzdCwgW0NSVUQgQVBJXShodHRwczovL2Zpc2NvLWJjb3MtZG9jdW1lbnRhdGlvbi5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9hcnRpY2xlcy8zX2ZlYXR1cmVzLzMzX3N0b3JhZ2UvY3J1ZF9ndWlkYW5jZS5odG1sKQo=', 'IyBLVlRhYmxlVGVzdAoKS1ZUYWJsZSBjb250cmFjdCBmb3IgQ1JVRCAKCkNSVUQgVGVzdCwgW0NSVUQgQVBJXShodHRwczovL2Zpc2NvLWJjb3MtZG9jdW1lbnRhdGlvbi5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9hcnRpY2xlcy8zX2ZlYXR1cmVzLzMzX3N0b3JhZ2UvY3J1ZF9ndWlkYW5jZS5odG1sKQo=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(17, 1, 4, 'Table', 'CmNvbnRyYWN0IFRhYmxlRmFjdG9yeSB7CiAgICBmdW5jdGlvbiBvcGVuVGFibGUoc3RyaW5nIG1lbW9yeSkgcHVibGljIHZpZXcgcmV0dXJucyAoVGFibGUpIHt9IC8vb3BlbiB0YWJsZQogICAgZnVuY3Rpb24gY3JlYXRlVGFibGUoc3RyaW5nIG1lbW9yeSwgc3RyaW5nIG1lbW9yeSwgc3RyaW5nIG1lbW9yeSkgcHVibGljIHJldHVybnMgKGludDI1Nikge30gLy9jcmVhdGUgdGFibGUKfQoKLy9zZWxlY3QgY29uZGl0aW9uCmNvbnRyYWN0IENvbmRpdGlvbiB7CiAgICBmdW5jdGlvbiBFUShzdHJpbmcgbWVtb3J5LCBpbnQyNTYpIHB1YmxpYyB2aWV3e30KICAgIGZ1bmN0aW9uIEVRKHN0cmluZyBtZW1vcnksIHN0cmluZyBtZW1vcnkpIHB1YmxpYyB2aWV3e30KCiAgICBmdW5jdGlvbiBORShzdHJpbmcgbWVtb3J5LCBpbnQyNTYpIHB1YmxpYyB2aWV3e30KICAgIGZ1bmN0aW9uIE5FKHN0cmluZyBtZW1vcnksIHN0cmluZyBtZW1vcnkpIHB1YmxpYyB2aWV3e30KCiAgICBmdW5jdGlvbiBHVChzdHJpbmcgbWVtb3J5LCBpbnQyNTYpIHB1YmxpYyB2aWV3e30KICAgIGZ1bmN0aW9uIEdFKHN0cmluZyBtZW1vcnksIGludDI1NikgcHVibGljIHZpZXd7fQoKICAgIGZ1bmN0aW9uIExUKHN0cmluZyBtZW1vcnksIGludDI1NikgcHVibGljIHZpZXd7fQogICAgZnVuY3Rpb24gTEUoc3RyaW5nIG1lbW9yeSwgaW50MjU2KSBwdWJsaWMgdmlld3t9CgogICAgZnVuY3Rpb24gbGltaXQoaW50MjU2KSBwdWJsaWMgdmlld3t9CiAgICBmdW5jdGlvbiBsaW1pdChpbnQyNTYsIGludDI1NikgcHVibGljIHZpZXd7fQp9CgovL29uZSByZWNvcmQKY29udHJhY3QgRW50cnkgewogICAgZnVuY3Rpb24gZ2V0SW50KHN0cmluZyBtZW1vcnkpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nikge30KICAgIGZ1bmN0aW9uIGdldFVJbnQoc3RyaW5nIG1lbW9yeSkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nikge30KICAgIGZ1bmN0aW9uIGdldEFkZHJlc3Moc3RyaW5nIG1lbW9yeSkgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcykge30KICAgIGZ1bmN0aW9uIGdldEJ5dGVzNjQoc3RyaW5nIG1lbW9yeSkgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMxWzY0XSBtZW1vcnkpIHt9CiAgICBmdW5jdGlvbiBnZXRCeXRlczMyKHN0cmluZyBtZW1vcnkpIHB1YmxpYyB2aWV3IHJldHVybnMgKGJ5dGVzMzIpIHt9CiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nIG1lbW9yeSkgcHVibGljIHZpZXcgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSkge30KCiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nIG1lbW9yeSwgaW50MjU2KSBwdWJsaWMge30KICAgIGZ1bmN0aW9uIHNldChzdHJpbmcgbWVtb3J5LCB1aW50MjU2KSBwdWJsaWMge30KICAgIGZ1bmN0aW9uIHNldChzdHJpbmcgbWVtb3J5LCBzdHJpbmcgbWVtb3J5KSBwdWJsaWMge30KICAgIGZ1bmN0aW9uIHNldChzdHJpbmcgbWVtb3J5LCBhZGRyZXNzKSBwdWJsaWMge30KfQoKLy9yZWNvcmQgc2V0cwpjb250cmFjdCBFbnRyaWVzIHsKICAgIGZ1bmN0aW9uIGdldChpbnQyNTYpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KSB7fQogICAgZnVuY3Rpb24gc2l6ZSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nikge30KfQoKLy9UYWJsZSBtYWluIGNvbnRyYWN0CmNvbnRyYWN0IFRhYmxlIHsKICAgIGZ1bmN0aW9uIHNlbGVjdChzdHJpbmcgbWVtb3J5LCBDb25kaXRpb24pIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJpZXMpIHt9CiAgICBmdW5jdGlvbiBpbnNlcnQoc3RyaW5nIG1lbW9yeSwgRW50cnkpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpIHt9CiAgICBmdW5jdGlvbiB1cGRhdGUoc3RyaW5nIG1lbW9yeSwgRW50cnksIENvbmRpdGlvbikgcHVibGljIHJldHVybnMgKGludDI1Nikge30KICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcgbWVtb3J5LCBDb25kaXRpb24pIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpIHt9CgogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSkge30KICAgIGZ1bmN0aW9uIG5ld0NvbmRpdGlvbigpIHB1YmxpYyB2aWV3IHJldHVybnMgKENvbmRpdGlvbikge30KfQoKY29udHJhY3QgS1ZUYWJsZUZhY3RvcnkgewogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZyBtZW1vcnkpIHB1YmxpYyB2aWV3IHJldHVybnMgKEtWVGFibGUpIHt9CiAgICBmdW5jdGlvbiBjcmVhdGVUYWJsZShzdHJpbmcgbWVtb3J5LCBzdHJpbmcgbWVtb3J5LCBzdHJpbmcgbWVtb3J5KSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KSB7fQp9CgovL0tWVGFibGUgcGVyIHBlcm1pYXJ5IGtleSBoYXMgb25seSBvbmUgRW50cnkKY29udHJhY3QgS1ZUYWJsZSB7CiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nIG1lbW9yeSkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCwgRW50cnkpIHt9CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nIG1lbW9yeSwgRW50cnkpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpIHt9CiAgICBmdW5jdGlvbiBuZXdFbnRyeSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KSB7fQp9Cg==', + 'IyBUYWJsZQoKVGFibGUgY29udHJhY3QgZm9yIENSVUQsIFtDUlVEIEFQSV0oaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8vemhfQ04vbGF0ZXN0L2RvY3MvYXJ0aWNsZXMvM19mZWF0dXJlcy8zM19zdG9yYWdlL2NydWRfZ3VpZGFuY2UuaHRtbCkK', 'IyBUYWJsZQoKVGFibGUgY29udHJhY3QgZm9yIENSVUQsIFtDUlVEIEFQSV0oaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8vemhfQ04vbGF0ZXN0L2RvY3MvYXJ0aWNsZXMvM19mZWF0dXJlcy8zM19zdG9yYWdlL2NydWRfZ3VpZGFuY2UuaHRtbCkK', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(18, 1, 4, 'TableTest', 'cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CnByYWdtYSBleHBlcmltZW50YWwgQUJJRW5jb2RlclYyOwoKaW1wb3J0ICIuL1RhYmxlLnNvbCI7Cgpjb250cmFjdCBUYWJsZVRlc3QgewogICAgZXZlbnQgQ3JlYXRlUmVzdWx0KGludDI1NiBjb3VudCk7CiAgICBldmVudCBJbnNlcnRSZXN1bHQoaW50MjU2IGNvdW50KTsKICAgIGV2ZW50IFVwZGF0ZVJlc3VsdChpbnQyNTYgY291bnQpOwogICAgZXZlbnQgUmVtb3ZlUmVzdWx0KGludDI1NiBjb3VudCk7CgogICAgVGFibGVGYWN0b3J5IHRhYmxlRmFjdG9yeTsKICAgIHN0cmluZyBjb25zdGFudCBUQUJMRV9OQU1FID0gInRfdGVzdCI7CiAgICBjb25zdHJ1Y3RvcigpIHB1YmxpYyB7CiAgICAgICAgdGFibGVGYWN0b3J5ID0gVGFibGVGYWN0b3J5KDB4MTAwMSk7IC8vVGhlIGZpeGVkIGFkZHJlc3MgaXMgMHgxMDAxIGZvciBUYWJsZUZhY3RvcnkKICAgICAgICAvLyB0aGUgcGFyYW1ldGVycyBvZiBjcmVhdGVUYWJsZSBhcmUgdGFibGVOYW1lLGtleUZpZWxkLCJ2bGF1ZUZpbGVkMSx2bGF1ZUZpbGVkMix2bGF1ZUZpbGVkMywuLi4iCiAgICAgICAgdGFibGVGYWN0b3J5LmNyZWF0ZVRhYmxlKFRBQkxFX05BTUUsICJuYW1lIiwgIml0ZW1faWQsaXRlbV9uYW1lIik7CiAgICB9CgogICAgLy9zZWxlY3QgcmVjb3JkcwogICAgZnVuY3Rpb24gc2VsZWN0KHN0cmluZyBtZW1vcnkgbmFtZSkKICAgIHB1YmxpYwogICAgdmlldwogICAgcmV0dXJucyAoc3RyaW5nW10gbWVtb3J5LCBpbnQyNTZbXSBtZW1vcnksIHN0cmluZ1tdIG1lbW9yeSkKICAgIHsKICAgICAgICBUYWJsZSB0YWJsZSA9IHRhYmxlRmFjdG9yeS5vcGVuVGFibGUoVEFCTEVfTkFNRSk7CgogICAgICAgIENvbmRpdGlvbiBjb25kaXRpb24gPSB0YWJsZS5uZXdDb25kaXRpb24oKTsKCiAgICAgICAgRW50cmllcyBlbnRyaWVzID0gdGFibGUuc2VsZWN0KG5hbWUsIGNvbmRpdGlvbik7CiAgICAgICAgc3RyaW5nW10gbWVtb3J5IHVzZXJfbmFtZV9ieXRlc19saXN0ID0gbmV3IHN0cmluZ1tdKAogICAgICAgICAgICB1aW50MjU2KGVudHJpZXMuc2l6ZSgpKQogICAgICAgICk7CiAgICAgICAgaW50MjU2W10gbWVtb3J5IGl0ZW1faWRfbGlzdCA9IG5ldyBpbnQyNTZbXSh1aW50MjU2KGVudHJpZXMuc2l6ZSgpKSk7CiAgICAgICAgc3RyaW5nW10gbWVtb3J5IGl0ZW1fbmFtZV9ieXRlc19saXN0ID0gbmV3IHN0cmluZ1tdKAogICAgICAgICAgICB1aW50MjU2KGVudHJpZXMuc2l6ZSgpKQogICAgICAgICk7CgogICAgICAgIGZvciAoaW50MjU2IGkgPSAwOyBpIDwgZW50cmllcy5zaXplKCk7ICsraSkgewogICAgICAgICAgICBFbnRyeSBlbnRyeSA9IGVudHJpZXMuZ2V0KGkpOwoKICAgICAgICAgICAgdXNlcl9uYW1lX2J5dGVzX2xpc3RbdWludDI1NihpKV0gPSBlbnRyeS5nZXRTdHJpbmcoIm5hbWUiKTsKICAgICAgICAgICAgaXRlbV9pZF9saXN0W3VpbnQyNTYoaSldID0gZW50cnkuZ2V0SW50KCJpdGVtX2lkIik7CiAgICAgICAgICAgIGl0ZW1fbmFtZV9ieXRlc19saXN0W3VpbnQyNTYoaSldID0gZW50cnkuZ2V0U3RyaW5nKCJpdGVtX25hbWUiKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAodXNlcl9uYW1lX2J5dGVzX2xpc3QsIGl0ZW1faWRfbGlzdCwgaXRlbV9uYW1lX2J5dGVzX2xpc3QpOwogICAgfQogICAgLy9pbnNlcnQgcmVjb3JkcwogICAgZnVuY3Rpb24gaW5zZXJ0KHN0cmluZyBtZW1vcnkgbmFtZSwgaW50MjU2IGl0ZW1faWQsIHN0cmluZyBtZW1vcnkgaXRlbV9uYW1lKQogICAgcHVibGljCiAgICByZXR1cm5zIChpbnQyNTYpCiAgICB7CiAgICAgICAgVGFibGUgdGFibGUgPSB0YWJsZUZhY3Rvcnkub3BlblRhYmxlKFRBQkxFX05BTUUpOwoKICAgICAgICBFbnRyeSBlbnRyeSA9IHRhYmxlLm5ld0VudHJ5KCk7CiAgICAgICAgZW50cnkuc2V0KCJuYW1lIiwgbmFtZSk7CiAgICAgICAgZW50cnkuc2V0KCJpdGVtX2lkIiwgaXRlbV9pZCk7CiAgICAgICAgZW50cnkuc2V0KCJpdGVtX25hbWUiLCBpdGVtX25hbWUpOwoKICAgICAgICBpbnQyNTYgY291bnQgPSB0YWJsZS5pbnNlcnQobmFtZSwgZW50cnkpOwogICAgICAgIGVtaXQgSW5zZXJ0UmVzdWx0KGNvdW50KTsKCiAgICAgICAgcmV0dXJuIGNvdW50OwogICAgfQogICAgLy91cGRhdGUgcmVjb3JkcwogICAgZnVuY3Rpb24gdXBkYXRlKHN0cmluZyBtZW1vcnkgbmFtZSwgaW50MjU2IGl0ZW1faWQsIHN0cmluZyBtZW1vcnkgaXRlbV9uYW1lKQogICAgcHVibGljCiAgICByZXR1cm5zIChpbnQyNTYpCiAgICB7CiAgICAgICAgVGFibGUgdGFibGUgPSB0YWJsZUZhY3Rvcnkub3BlblRhYmxlKFRBQkxFX05BTUUpOwoKICAgICAgICBFbnRyeSBlbnRyeSA9IHRhYmxlLm5ld0VudHJ5KCk7CiAgICAgICAgZW50cnkuc2V0KCJpdGVtX25hbWUiLCBpdGVtX25hbWUpOwoKICAgICAgICBDb25kaXRpb24gY29uZGl0aW9uID0gdGFibGUubmV3Q29uZGl0aW9uKCk7CiAgICAgICAgY29uZGl0aW9uLkVRKCJuYW1lIiwgbmFtZSk7CiAgICAgICAgY29uZGl0aW9uLkVRKCJpdGVtX2lkIiwgaXRlbV9pZCk7CgogICAgICAgIGludDI1NiBjb3VudCA9IHRhYmxlLnVwZGF0ZShuYW1lLCBlbnRyeSwgY29uZGl0aW9uKTsKICAgICAgICBlbWl0IFVwZGF0ZVJlc3VsdChjb3VudCk7CgogICAgICAgIHJldHVybiBjb3VudDsKICAgIH0KICAgIC8vcmVtb3ZlIHJlY29yZHMKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcgbWVtb3J5IG5hbWUsIGludDI1NiBpdGVtX2lkKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KSB7CiAgICAgICAgVGFibGUgdGFibGUgPSB0YWJsZUZhY3Rvcnkub3BlblRhYmxlKFRBQkxFX05BTUUpOwoKICAgICAgICBDb25kaXRpb24gY29uZGl0aW9uID0gdGFibGUubmV3Q29uZGl0aW9uKCk7CiAgICAgICAgY29uZGl0aW9uLkVRKCJuYW1lIiwgbmFtZSk7CiAgICAgICAgY29uZGl0aW9uLkVRKCJpdGVtX2lkIiwgaXRlbV9pZCk7CgogICAgICAgIGludDI1NiBjb3VudCA9IHRhYmxlLnJlbW92ZShuYW1lLCBjb25kaXRpb24pOwogICAgICAgIGVtaXQgUmVtb3ZlUmVzdWx0KGNvdW50KTsKCiAgICAgICAgcmV0dXJuIGNvdW50OwogICAgfQp9Cg==', + 'IyBUYWJsZVRlc3QKClRhYmxlIGNvbnRyYWN0IGZvciBDUlVEIAoKQ1JVRCBUZXN0LCBbQ1JVRCBBUEldKGh0dHBzOi8vZmlzY28tYmNvcy1kb2N1bWVudGF0aW9uLnJlYWR0aGVkb2NzLmlvL3poX0NOL2xhdGVzdC9kb2NzL2FydGljbGVzLzNfZmVhdHVyZXMvMzNfc3RvcmFnZS9jcnVkX2d1aWRhbmNlLmh0bWwpCg==', 'IyBUYWJsZVRlc3QKClRhYmxlIGNvbnRyYWN0IGZvciBDUlVEIAoKQ1JVRCBUZXN0LCBbQ1JVRCBBUEldKGh0dHBzOi8vZmlzY28tYmNvcy1kb2N1bWVudGF0aW9uLnJlYWR0aGVkb2NzLmlvL3poX0NOL2xhdGVzdC9kb2NzL2FydGljbGVzLzNfZmVhdHVyZXMvMzNfc3RvcmFnZS9jcnVkX2d1aWRhbmNlLmh0bWwpCg==', now(), now()); +-- evidence +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(19, 4, 5, 'EvidenceController', '', + 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(20, 4, 5, 'EvidenceRepository', '', + 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(21, 4, 5, 'RequestRepository', '', +'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(22, 4, 5, 'Authentication', '', +'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); diff --git a/src/test/java/node/mgr/test/contract/warehouse/WarehouseMdTest.java b/src/test/java/node/mgr/test/contract/warehouse/WarehouseMdTest.java index 36b9ddf15..df0277ad1 100644 --- a/src/test/java/node/mgr/test/contract/warehouse/WarehouseMdTest.java +++ b/src/test/java/node/mgr/test/contract/warehouse/WarehouseMdTest.java @@ -52,17 +52,29 @@ public void testToolMdToBase64() { System.out.println("SAFE_MATH_MD:\n" + Base64.getEncoder().encodeToString(SAFE_MATH_MD.getBytes())); System.out.println("TABLE_MD:\n" + Base64.getEncoder().encodeToString(TABLE_MD.getBytes())); System.out.println("ROLES_MD:\n" + Base64.getEncoder().encodeToString(ROLES_MD.getBytes())); + } + @Test + public void testEvidenceMdToBase64() { System.out.println("EVIDENCE_MD:\n" + Base64.getEncoder().encodeToString(EVIDENCE_MD.getBytes())); - System.out.println("BAC001_MD:\n" + Base64.getEncoder().encodeToString(BAC001_MD.getBytes())); } + public static final String EVIDENCE_MD = "# Evidence 合约\n" + "\n" + "## 简介\n" + "Evidence 示例合约,使用分层的智能合约结构: \n" + "1)工厂合约(EvidenceSignersData.sol),由存证各方事前约定,存储存证生效条件,并管理存证的生成。 \n" + "2)存证合约(Evidence.sol),由工厂合约生成,存储存证id,hash和各方签名(每张存证一个合约)。 "; + + @Test + public void testBACMdToBase64() { + System.out.println("ADDRESS_MD:\n" + Base64.getEncoder().encodeToString(ADDRESS_MD.getBytes())); + System.out.println("SAFE_MATH_MD:\n" + Base64.getEncoder().encodeToString(SAFE_MATH_MD.getBytes())); + System.out.println("ROLES_MD:\n" + Base64.getEncoder().encodeToString(ROLES_MD.getBytes())); + System.out.println("BAC001_MD:\n" + Base64.getEncoder().encodeToString(BAC001_MD.getBytes())); + } + public static final String BAC001_MD = "# 积分合约\n" + "\n" + "## 简介\n" + diff --git a/src/test/java/node/mgr/test/contract/warehouse/WarehouseSmartDevTest.java b/src/test/java/node/mgr/test/contract/warehouse/WarehouseSmartDevTest.java new file mode 100644 index 000000000..e1822dcaa --- /dev/null +++ b/src/test/java/node/mgr/test/contract/warehouse/WarehouseSmartDevTest.java @@ -0,0 +1,93 @@ +/** + * Copyright 2014-2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package node.mgr.test.contract.warehouse; + +import com.webank.scaffold.util.IOUtil; +import com.webank.webase.node.mgr.base.tools.NodeMgrTools; +import java.io.File; +import java.io.IOException; +import java.util.Base64; +import java.util.Objects; +import org.junit.Test; + +public class WarehouseSmartDevTest { + + private final static String readDir = "contracts"; + /** + * get all sol source code in contracts dir + */ + @Test + public void testGetSolSrcBase64() throws IOException { + File contractDir = new File(readDir); + this.printFileContent(contractDir); + } + + private void printFileContent(File file) throws IOException { + for (File subFile : Objects.requireNonNull(file.listFiles())) { + if (subFile.isDirectory()) { + System.out.println("subDir name: " + subFile.getName()); + if(!"base64".equals(subFile.getName())) { + printFileContent(subFile); + } + } else { + System.out.println("subFile name: " + subFile.getName()); + String content = IOUtil.readAsString(subFile); +// System.out.println(solFile.getName() + " content: " + content); + System.out.println(subFile.getName() + " content base64: " + NodeMgrTools + .encodedBase64Str(content)); + IOUtil.writeStringToFile(NodeMgrTools.encodedBase64Str(content), + new File(readDir + "/base64"), + subFile.getName() + ".txt"); + } + } + } + + public final static String HELLO_WORLD = "# HelloWorld\n" + + "\n" + + "HelloWorld Contract\n"; + + public final static String CRUD = "# Table\n" + + "\n" + + "Table contract for CRUD, [CRUD API](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/articles/3_features/33_storage/crud_guidance.html)\n"; + public final static String CRUD_TEST = "# TableTest\n" + + "\n" + + "Table contract for CRUD \n" + + "\n" + + "CRUD Test, [CRUD API](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/articles/3_features/33_storage/crud_guidance.html)\n"; + public final static String KVTABLE_TEST = "# KVTableTest\n" + + "\n" + + "KVTable contract for CRUD \n" + + "\n" + + "CRUD Test, [CRUD API](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/articles/3_features/33_storage/crud_guidance.html)\n"; + public final static String CRYPTO = "# Crypto\n" + + "\n" + + "Crypto Interface Contract"; + public final static String CRYPTO_SHA_TEST = "# ShaTest\n" + + "\n" + + "Crypto Interface Contract\n" + + "\n" + + "Crypto Test Contract [Crypto API](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/default/Crypto.html)\n"; + + @Test + public void testGetMdBase64() { + System.out.println("HELLO_WORLD:\n" + Base64.getEncoder().encodeToString(HELLO_WORLD.getBytes())); + System.out.println("CRUD:\n" + Base64.getEncoder().encodeToString(CRUD.getBytes())); + System.out.println("CRUD_TEST:\n" + Base64.getEncoder().encodeToString(CRUD_TEST.getBytes())); + System.out.println("KVTABLE_TEST:\n" + Base64.getEncoder().encodeToString(KVTABLE_TEST.getBytes())); + System.out.println("CRYPTO:\n" + Base64.getEncoder().encodeToString(CRYPTO.getBytes())); + System.out.println("CRYPTO_SHA_TEST:\n" + Base64.getEncoder().encodeToString(CRYPTO_SHA_TEST.getBytes())); + } + +} \ No newline at end of file From 9770d71926ab59be9cef5bd6da3b60b748bf2c50 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 29 Apr 2021 15:19:17 +0800 Subject: [PATCH 28/92] add evidence in warehouse --- script/webase-dml.sql | 16 ++++++++-------- .../warehouse/WarehouseSmartDevTest.java | 13 +++++++++++++ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/script/webase-dml.sql b/script/webase-dml.sql index 2d7b64213..ef5b4a289 100644 --- a/script/webase-dml.sql +++ b/script/webase-dml.sql @@ -236,14 +236,14 @@ INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `con 'IyBUYWJsZVRlc3QKClRhYmxlIGNvbnRyYWN0IGZvciBDUlVEIAoKQ1JVRCBUZXN0LCBbQ1JVRCBBUEldKGh0dHBzOi8vZmlzY28tYmNvcy1kb2N1bWVudGF0aW9uLnJlYWR0aGVkb2NzLmlvL3poX0NOL2xhdGVzdC9kb2NzL2FydGljbGVzLzNfZmVhdHVyZXMvMzNfc3RvcmFnZS9jcnVkX2d1aWRhbmNlLmh0bWwpCg==', 'IyBUYWJsZVRlc3QKClRhYmxlIGNvbnRyYWN0IGZvciBDUlVEIAoKQ1JVRCBUZXN0LCBbQ1JVRCBBUEldKGh0dHBzOi8vZmlzY28tYmNvcy1kb2N1bWVudGF0aW9uLnJlYWR0aGVkb2NzLmlvL3poX0NOL2xhdGVzdC9kb2NzL2FydGljbGVzLzNfZmVhdHVyZXMvMzNfc3RvcmFnZS9jcnVkX2d1aWRhbmNlLmh0bWwpCg==', now(), now()); -- evidence INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(19, 4, 5, 'EvidenceController', '', - 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +(19, 4, 5, 'EvidenceController', 'Ci8qCiAqIENvcHlyaWdodCAyMDE0LTIwMTkgdGhlIG9yaWdpbmFsIGF1dGhvciBvciBhdXRob3JzLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogKi8KCnByYWdtYSBzb2xpZGl0eSA+PTAuNC4yNCA8MC42LjExOyAKCmltcG9ydCAiLi9SZXF1ZXN0UmVwb3NpdG9yeS5zb2wiOwppbXBvcnQgIi4vRXZpZGVuY2VSZXBvc2l0b3J5LnNvbCI7Cgpjb250cmFjdCBFdmlkZW5jZUNvbnRyb2xsZXJ7CiAgICBSZXF1ZXN0UmVwb3NpdG9yeSBwdWJsaWMgX3JlcXVlc3RSZXBvOwogICAgRXZpZGVuY2VSZXBvc2l0b3J5IHB1YmxpYyBfZXZpZGVuY2VSZXBvOwoKICAgIGV2ZW50IENyZWF0ZVNhdmVSZXF1ZXN0KGJ5dGVzMzIgaW5kZXhlZCBoYXNoLCBhZGRyZXNzIGNyZWF0b3IpOyAgIAogICAgZXZlbnQgVm90ZVNhdmVSZXF1ZXN0KGJ5dGVzMzIgaW5kZXhlZCBoYXNoLCBhZGRyZXNzIHZvdGVyLCBib29sIGNvbXBsZXRlKTsKICAgIGV2ZW50IEV2aWRlbmNlU2F2ZWQoYnl0ZXMzMiBpbmRleGVkIGhhc2gpOwoKICAgIGNvbnN0cnVjdG9yKHVpbnQ4IHRocmVzaG9sZCwgYWRkcmVzc1tdIG1lbW9yeSB2b3RlckFycmF5KSBwdWJsaWN7CiAgICAgICAgX3JlcXVlc3RSZXBvID0gbmV3IFJlcXVlc3RSZXBvc2l0b3J5KHRocmVzaG9sZCwgdm90ZXJBcnJheSk7CiAgICAgICAgX2V2aWRlbmNlUmVwbyA9IG5ldyBFdmlkZW5jZVJlcG9zaXRvcnkoKTsKICAgIH0KCiAgICBtb2RpZmllciB2YWxpZGF0ZUhhc2goYnl0ZXMzMiBoYXNoKXsKICAgICAgcmVxdWlyZShoYXNoICE9IDAsICJOb3QgdmFsaWQgaGFzaCIpOwogICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGNyZWF0ZVNhdmVSZXF1ZXN0KGJ5dGVzMzIgaGFzaCwgYnl0ZXMgbWVtb3J5IGV4dCkgcHVibGljIHZhbGlkYXRlSGFzaChoYXNoKXsKICAgICAgICBfcmVxdWVzdFJlcG8uY3JlYXRlU2F2ZVJlcXVlc3QoaGFzaCwgbXNnLnNlbmRlciwgZXh0KTsKICAgICAgICBlbWl0IENyZWF0ZVNhdmVSZXF1ZXN0KGhhc2gsIG1zZy5zZW5kZXIpOwogICAgfQoKICAgIGZ1bmN0aW9uIHZvdGVTYXZlUmVxdWVzdChieXRlczMyIGhhc2gpIHB1YmxpYyB2YWxpZGF0ZUhhc2goaGFzaCkgcmV0dXJucyhib29sKXsKICAgICAgICBib29sIGIgPSBfcmVxdWVzdFJlcG8udm90ZVNhdmVSZXF1ZXN0KGhhc2gsIG1zZy5zZW5kZXIpOwogICAgICAgIGlmKCFiKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgKGJ5dGVzMzIgaCwgYWRkcmVzcyBjcmVhdG9yLCBieXRlcyBtZW1vcnkgZXh0LCAgdWludDggdm90ZWQsIHVpbnQ4IHRocmVzaG9sZCkgPSAgX3JlcXVlc3RSZXBvLmdldFJlcXVlc3REYXRhKGhhc2gpOwogICAgICAgIGJvb2wgcGFzc2VkID0gdm90ZWQgPj0gdGhyZXNob2xkOwogICAgICAgIGVtaXQgVm90ZVNhdmVSZXF1ZXN0KGhhc2gsIG1zZy5zZW5kZXIsIHBhc3NlZCk7CiAgICAgICAgaWYocGFzc2VkKXsKICAgICAgICAgICAgX2V2aWRlbmNlUmVwby5zZXREYXRhKGhhc2gsIGNyZWF0b3IsIG5vdyk7CiAgICAgICAgICAgIF9yZXF1ZXN0UmVwby5kZWxldGVTYXZlUmVxdWVzdChoYXNoKTsKICAgICAgICAgICAgZW1pdCBFdmlkZW5jZVNhdmVkKGhhc2gpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRSZXF1ZXN0RGF0YShieXRlczMyIGhhc2gpIHB1YmxpYyB2aWV3IAogICAgICByZXR1cm5zKGJ5dGVzMzIsIGFkZHJlc3MgY3JlYXRvciwgYnl0ZXMgbWVtb3J5IGV4dCwgdWludDggdm90ZWQsIHVpbnQ4IHRocmVzaG9sZCl7CiAgICAgICAgcmV0dXJuIF9yZXF1ZXN0UmVwby5nZXRSZXF1ZXN0RGF0YShoYXNoKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRFdmlkZW5jZShieXRlczMyIGhhc2gpIHB1YmxpYyB2aWV3IHJldHVybnMoYnl0ZXMzMiAsIGFkZHJlc3MsIHVpbnQpewogICAgICAgIHJldHVybiBfZXZpZGVuY2VSZXBvLmdldERhdGEoaGFzaCk7CiAgICB9Cn0K', + 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', now(), now()); INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(20, 4, 5, 'EvidenceRepository', '', - 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +(20, 4, 5, 'EvidenceRepository', 'LyoKICogQ29weXJpZ2h0IDIwMTQtMjAxOSB0aGUgb3JpZ2luYWwgYXV0aG9yIG9yIGF1dGhvcnMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiAqLwoKcHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CmltcG9ydCAiLi9BdXRoZW50aWNhdGlvbi5zb2wiOwoKY29udHJhY3QgRXZpZGVuY2VSZXBvc2l0b3J5IGlzIEF1dGhlbnRpY2F0aW9uIHsgICAgCiAgICBzdHJ1Y3QgRXZpZGVuY2VEYXRhewogICAgICAgIGJ5dGVzMzIgaGFzaDsKICAgICAgICBhZGRyZXNzIG93bmVyOwogICAgICAgIHVpbnQgdGltZXN0YW1wOwogICAgfQogICAgbWFwcGluZyhieXRlczMyPT5FdmlkZW5jZURhdGEpIHByaXZhdGUgX2V2aWRlbmNlczsgIAogICAgCiAgICBmdW5jdGlvbiBzZXREYXRhKGJ5dGVzMzIgaGFzaCwgYWRkcmVzcyBvd25lciwgdWludCB0aW1lc3RhbXApIHB1YmxpYyBhdXRoIHsKICAgICAgICBfZXZpZGVuY2VzW2hhc2hdLmhhc2ggPSBoYXNoOwogICAgICAgIF9ldmlkZW5jZXNbaGFzaF0ub3duZXIgPSBvd25lcjsKICAgICAgICBfZXZpZGVuY2VzW2hhc2hdLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gZ2V0RGF0YShieXRlczMyIGhhc2gpIHB1YmxpYyB2aWV3IHJldHVybnMoYnl0ZXMzMiAsIGFkZHJlc3MsIHVpbnQpewogICAgICAgIEV2aWRlbmNlRGF0YSBzdG9yYWdlIGV2aWRlbmNlID0gX2V2aWRlbmNlc1toYXNoXTsKICAgICAgICByZXF1aXJlKGV2aWRlbmNlLmhhc2ggPT0gaGFzaCwgIkV2aWRlbmNlIG5vdCBleGlzdCIpOwogICAgICAgIHJldHVybiAoZXZpZGVuY2UuaGFzaCwgZXZpZGVuY2Uub3duZXIsIGV2aWRlbmNlLnRpbWVzdGFtcCk7CiAgICB9Cn0K', + 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', now(), now()); INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(21, 4, 5, 'RequestRepository', '', -'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +(21, 4, 5, 'RequestRepository', 'LyoKICogQ29weXJpZ2h0IDIwMTQtMjAxOSB0aGUgb3JpZ2luYWwgYXV0aG9yIG9yIGF1dGhvcnMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiAqLwoKcHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CgppbXBvcnQgIi4vQXV0aGVudGljYXRpb24uc29sIjsKCmNvbnRyYWN0IFJlcXVlc3RSZXBvc2l0b3J5IGlzIEF1dGhlbnRpY2F0aW9ueyAgICAKICAgIHN0cnVjdCBTYXZlUmVxdWVzdHsKICAgICAgICBieXRlczMyIGhhc2g7CiAgICAgICAgYWRkcmVzcyBjcmVhdG9yOwogICAgICAgIHVpbnQ4IHZvdGVkOwogICAgICAgIGJ5dGVzIGV4dDsKICAgICAgICBtYXBwaW5nKGFkZHJlc3M9PmJvb2wpIHN0YXR1czsKICAgIH0KICAgIHVpbnQ4IHB1YmxpYyBfdGhyZXNob2xkOwogICAgbWFwcGluZyhieXRlczMyPT5TYXZlUmVxdWVzdCkgcHJpdmF0ZSBfc2F2ZVJlcXVlc3RzOwogICAgbWFwcGluZyhhZGRyZXNzPT5ib29sKSBwcml2YXRlIF92b3RlcnM7CiAgICAKICAgIGNvbnN0cnVjdG9yKHVpbnQ4IHRocmVzaG9sZCwgYWRkcmVzc1tdIG1lbW9yeSB2b3RlckFycmF5KSBwdWJsaWN7CiAgICAgICAgX3RocmVzaG9sZCA9IHRocmVzaG9sZDsKICAgICAgICBmb3IodWludCBpPTA7aTx2b3RlckFycmF5Lmxlbmd0aDtpKyspewogICAgICAgICAgICBfdm90ZXJzW3ZvdGVyQXJyYXlbaV1dID0gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY3JlYXRlU2F2ZVJlcXVlc3QoYnl0ZXMzMiBoYXNoLCBhZGRyZXNzIG93bmVyLCBieXRlcyBtZW1vcnkgZXh0KSBwdWJsaWMgYXV0aHsKICAgICAgICByZXF1aXJlKF9zYXZlUmVxdWVzdHNbaGFzaF0uaGFzaCA9PSAwLCAicmVxdWVzdCBhbHJlYWR5IGV4aXN0ZWQiKTsKICAgICAgICBfc2F2ZVJlcXVlc3RzW2hhc2hdLmhhc2ggPSBoYXNoOwogICAgICAgIF9zYXZlUmVxdWVzdHNbaGFzaF0uY3JlYXRvciA9IG93bmVyOwogICAgICAgIF9zYXZlUmVxdWVzdHNbaGFzaF0uZXh0ID0gZXh0OwogICAgfQoKICAgIGZ1bmN0aW9uIHZvdGVTYXZlUmVxdWVzdChieXRlczMyIGhhc2gsIGFkZHJlc3Mgdm90ZXIpIHB1YmxpYyBhdXRoIHJldHVybnMgKGJvb2wpewogICAgICAgIHJlcXVpcmUoX3ZvdGVyc1t2b3Rlcl0gPT0gdHJ1ZSwgIk5vdCBhbGxvd2VkIHRvIHZvdGUiKTsKICAgICAgICByZXF1aXJlKF9zYXZlUmVxdWVzdHNbaGFzaF0uaGFzaCA9PSBoYXNoLCAicmVxdWVzdCBub3QgZm91bmQiKTsKICAgICAgICBTYXZlUmVxdWVzdCBzdG9yYWdlIHJlcXVlc3QgPSBfc2F2ZVJlcXVlc3RzW2hhc2hdOwogICAgICAgIHJlcXVpcmUocmVxdWVzdC5zdGF0dXNbdm90ZXJdID09IGZhbHNlLCAiVm90ZXIgYWxyZWFkeSB2b3RlZCIpOwogICAgICAgIHJlcXVlc3Quc3RhdHVzW3ZvdGVyXSA9IHRydWU7CiAgICAgICAgcmVxdWVzdC52b3RlZCsrOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRSZXF1ZXN0RGF0YShieXRlczMyIGhhc2gpIHB1YmxpYyB2aWV3IAogICAgICByZXR1cm5zKGJ5dGVzMzIsIGFkZHJlc3MgY3JlYXRvciwgYnl0ZXMgbWVtb3J5IGV4dCwgdWludDggdm90ZWQsIHVpbnQ4IHRocmVzaG9sZCl7CiAgICAgICAgU2F2ZVJlcXVlc3Qgc3RvcmFnZSByZXF1ZXN0ID0gX3NhdmVSZXF1ZXN0c1toYXNoXTsKICAgICAgICByZXF1aXJlKF9zYXZlUmVxdWVzdHNbaGFzaF0uaGFzaCA9PSBoYXNoLCAicmVxdWVzdCBub3QgZm91bmQiKTsKICAgICAgICByZXR1cm4gKGhhc2gsIHJlcXVlc3QuY3JlYXRvciwgcmVxdWVzdC5leHQsIHJlcXVlc3Qudm90ZWQsIF90aHJlc2hvbGQpOwogICAgfQoKICAgIGZ1bmN0aW9uIGRlbGV0ZVNhdmVSZXF1ZXN0KGJ5dGVzMzIgaGFzaCkgcHVibGljIGF1dGggewogICAgICAgIHJlcXVpcmUoX3NhdmVSZXF1ZXN0c1toYXNoXS5oYXNoID09IGhhc2gsICJyZXF1ZXN0IG5vdCBmb3VuZCIpOwogICAgICAgIGRlbGV0ZSBfc2F2ZVJlcXVlc3RzW2hhc2hdOwogICAgfQp9Cg==', +'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', now(), now()); INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(22, 4, 5, 'Authentication', '', -'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +(22, 4, 5, 'Authentication', 'LyoKICogQ29weXJpZ2h0IDIwMTQtMjAxOSB0aGUgb3JpZ2luYWwgYXV0aG9yIG9yIGF1dGhvcnMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiAqLwoKcHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7Cgpjb250cmFjdCBBdXRoZW50aWNhdGlvbnsKICAgIGFkZHJlc3MgcHVibGljIF9vd25lcjsKICAgIG1hcHBpbmcoYWRkcmVzcz0+Ym9vbCkgcHJpdmF0ZSBfYWNsOwoKICAgIGNvbnN0cnVjdG9yKCkgcHVibGljewogICAgICBfb3duZXIgPSBtc2cuc2VuZGVyOwogICAgfSAKCiAgICBtb2RpZmllciBvbmx5T3duZXIoKXsKICAgICAgcmVxdWlyZShtc2cuc2VuZGVyID09IF9vd25lciwgIk5vdCBhZG1pbiIpOwogICAgICBfOwogICAgfQoKICAgIG1vZGlmaWVyIGF1dGgoKXsKICAgICAgcmVxdWlyZShtc2cuc2VuZGVyID09IF9vd25lciB8fCBfYWNsW21zZy5zZW5kZXJdPT10cnVlLCAiTm90IGF1dGhlbnRpY2F0ZWQiKTsKICAgICAgXzsKICAgIH0KCiAgICBmdW5jdGlvbiBhbGxvdyhhZGRyZXNzIGFkZHIpIHB1YmxpYyBvbmx5T3duZXJ7CiAgICAgIF9hY2xbYWRkcl0gPSB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGRlbnkoYWRkcmVzcyBhZGRyKSBwdWJsaWMgb25seU93bmVyewogICAgICBfYWNsW2FkZHJdID0gZmFsc2U7CiAgICB9Cn0K', +'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', now(), now()); diff --git a/src/test/java/node/mgr/test/contract/warehouse/WarehouseSmartDevTest.java b/src/test/java/node/mgr/test/contract/warehouse/WarehouseSmartDevTest.java index e1822dcaa..fd3272099 100644 --- a/src/test/java/node/mgr/test/contract/warehouse/WarehouseSmartDevTest.java +++ b/src/test/java/node/mgr/test/contract/warehouse/WarehouseSmartDevTest.java @@ -80,6 +80,18 @@ private void printFileContent(File file) throws IOException { + "\n" + "Crypto Test Contract [Crypto API](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/default/Crypto.html)\n"; + public final static String EVIDENCE_API = "# Evidence存证\n" + + "\n" + + "## 简介\n" + + "\n" + + "存证操作,上传、审批、修改、删除等,详情查看[Smart-Dev Evidence Doc](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/business_template/Evidence.html)\n" + + "\n" + + "合约:\n" + + "1) EvidenceController 对外服务的唯一接口\n" + + "2) EvidenceRepository 辅助合约,用于数据和逻辑分离\n" + + "3) RequestRepository 辅助合约,用于数据和逻辑分离\n" + + "4) Authentication 辅助合约,用于数据和逻辑分离"; + @Test public void testGetMdBase64() { System.out.println("HELLO_WORLD:\n" + Base64.getEncoder().encodeToString(HELLO_WORLD.getBytes())); @@ -88,6 +100,7 @@ public void testGetMdBase64() { System.out.println("KVTABLE_TEST:\n" + Base64.getEncoder().encodeToString(KVTABLE_TEST.getBytes())); System.out.println("CRYPTO:\n" + Base64.getEncoder().encodeToString(CRYPTO.getBytes())); System.out.println("CRYPTO_SHA_TEST:\n" + Base64.getEncoder().encodeToString(CRYPTO_SHA_TEST.getBytes())); + System.out.println("EVIDENCE_API:\n" + Base64.getEncoder().encodeToString(EVIDENCE_API.getBytes())); } } \ No newline at end of file From e66449b1a179334f930f6d66c821466a294eeaf9 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 30 Apr 2021 09:58:39 +0800 Subject: [PATCH 29/92] update front agency --- .../com/webank/webase/node/mgr/front/FrontService.java | 8 +++++++- src/main/resources/mapper/FrontMapper.xml | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/webank/webase/node/mgr/front/FrontService.java b/src/main/java/com/webank/webase/node/mgr/front/FrontService.java index 8f60d5aae..5db3be3eb 100644 --- a/src/main/java/com/webank/webase/node/mgr/front/FrontService.java +++ b/src/main/java/com/webank/webase/node/mgr/front/FrontService.java @@ -91,6 +91,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.Level; +import org.fisco.bcos.sdk.client.protocol.response.NodeInfo; import org.fisco.bcos.sdk.client.protocol.response.SyncStatus.SyncStatusInfo; import org.fisco.bcos.sdk.crypto.CryptoSuite; import org.fisco.bcos.sdk.model.CryptoType; @@ -197,14 +198,19 @@ public void refreshFront() { log.warn("get version of Front and Sign failed (required front and sign v1.4.0+)."); } // get node config(add in 1.5.0) + // p2p/rpc/channel port etc. FrontNodeConfig nodeConfig = frontInterface.getNodeConfigFromSpecificFront(frontIp, frontPort); + // get agency of node + NodeInfo nodeInfo = frontInterface.getNodeInfoFromSpecificFront(frontIp, frontPort); tbFront.setP2pPort(nodeConfig.getP2pport()); tbFront.setJsonrpcPort(nodeConfig.getRpcport()); tbFront.setChannelPort(nodeConfig.getChannelPort()); - //copy attribute + // copy attribute tbFront.setNodeId(syncStatus.getNodeId()); tbFront.setClientVersion(clientVersion); tbFront.setSupportVersion(supportVersion); + // set agency from chain + tbFront.setAgency(nodeInfo.getNodeInfo().getAgency()); //update front info frontMapper.updateBasicInfo(tbFront); // save group info diff --git a/src/main/resources/mapper/FrontMapper.xml b/src/main/resources/mapper/FrontMapper.xml index d5d639a58..e31a97234 100644 --- a/src/main/resources/mapper/FrontMapper.xml +++ b/src/main/resources/mapper/FrontMapper.xml @@ -68,6 +68,7 @@ p2p_port = #{p2pPort}, jsonrpc_port = #{jsonrpcPort}, channel_port = #{channelPort}, + agency = #{agency}, modify_time = now() where front_id = #{frontId} From 3ce223cc3a650f84d65b17127817a74b6ef6e40c Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 30 Apr 2021 09:58:50 +0800 Subject: [PATCH 30/92] update store as evidence --- script/webase-dml.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/webase-dml.sql b/script/webase-dml.sql index ef5b4a289..f984744a2 100644 --- a/script/webase-dml.sql +++ b/script/webase-dml.sql @@ -160,7 +160,7 @@ INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES (3, '积分应用', 'Points', 3, 'pointsId', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES -(4, 'SmartDev应用', 'Smart_Dev Template', 4, 'smartDevId', 'Smart-Dev-Contracts仓库中的应用模板', 'Smart-Dev-Contract\'s Contract suite of business_template', 'Smart-Dev-Contracts仓库中的应用模板', 'Smart-Dev-Contract\'s Contract suite of business_template', now(), now()); +(4, 'SmartDev存证应用', 'Smart_Dev_Evidence', 4, 'evidenceId', 'Smart-Dev-Contracts仓库中的存证应用模板', 'Smart-Dev-Contract\'s Evidence Contract suite of business_template', 'Smart-Dev-Contracts仓库中的存证应用模板', 'Smart-Dev-Contract\'s Evidence Contract suite of business_template', now(), now()); -- folder INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES (1, 1, 'Tools', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); From ca2d3fd4ca574fa415eb1a59c7d88be28f1c64d4 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 30 Apr 2021 10:11:42 +0800 Subject: [PATCH 31/92] update api using param instead of path --- .../warehouse/WarehouseController.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseController.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseController.java index 7e1fa38df..dc7fc6809 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseController.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseController.java @@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -55,8 +56,8 @@ public BaseResponse getContractStoreList() { /** * query a contract store item */ - @GetMapping(value = "/{warehouseId}") - public BaseResponse getContractStoreById(@PathVariable("warehouseId") Integer warehouseId) { + @GetMapping(value = "") + public BaseResponse getContractStoreById(@RequestParam("warehouseId") Integer warehouseId) { log.info("getContractStoreById start. warehouseId:{}", warehouseId); TbWarehouse storeItem = warehouseService.getStoreItemById(warehouseId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); @@ -67,10 +68,10 @@ public BaseResponse getContractStoreById(@PathVariable("warehouseId") Integer wa /** * query a contract folder item */ - @GetMapping(value = "/folder/{contractFolderId}") - public BaseResponse getContractFolderById(@PathVariable("contractFolderId") Integer contractFolderId) { - log.info("getContractStoreById start. contractFolderId:{}", contractFolderId); - TbContractFolder contractFolderItem = warehouseService.getContractFolderById(contractFolderId); + @GetMapping(value = "/folder") + public BaseResponse getContractFolderById(@RequestParam("folderId") Integer folderId) { + log.info("getContractStoreById start. folderId:{}", folderId); + TbContractFolder contractFolderItem = warehouseService.getContractFolderById(folderId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(contractFolderItem); return response; @@ -79,8 +80,8 @@ public BaseResponse getContractFolderById(@PathVariable("contractFolderId") Inte /** * query a contract item */ - @GetMapping(value = "/item/{contractId}") - public BaseResponse getContractItemById(@PathVariable("contractId") Integer contractId) { + @GetMapping(value = "/item") + public BaseResponse getContractItemById(@RequestParam("contractId") Integer contractId) { log.info("getContractStoreById start. contractId:{}", contractId); TbContractItem contractItem = warehouseService.getContractItemById(contractId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); @@ -91,8 +92,8 @@ public BaseResponse getContractItemById(@PathVariable("contractId") Integer cont /** * get folderItemList by warehouseId */ - @GetMapping(value = "/folder/list/{warehouseId}") - public BaseResponse getFolderItemListByStoreId(@PathVariable("warehouseId") Integer warehouseId) { + @GetMapping(value = "/folder/list") + public BaseResponse getFolderItemListByStoreId(@RequestParam("warehouseId") Integer warehouseId) { log.info("getFolderItemListByStoreId start. warehouseId:{}", warehouseId); List contractFolderItemList = warehouseService.getFolderItemListByStoreId(warehouseId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); @@ -103,8 +104,8 @@ public BaseResponse getFolderItemListByStoreId(@PathVariable("warehouseId") Inte /** * get contractItemList by folderId */ - @GetMapping(value = "/item/list/{folderId}") - public BaseResponse getContractItemByFolderId(@PathVariable("folderId") Integer folderId) { + @GetMapping(value = "/item/list") + public BaseResponse getContractItemByFolderId(@RequestParam("folderId") Integer folderId) { log.info("getContractItemByFolderId start. warehouseId:{}", folderId); List contractItemList = warehouseService.getContractItemByFolderId(folderId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); From 605ccbe289706706e633a6101afb3738b236f0ca Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 30 Apr 2021 10:42:56 +0800 Subject: [PATCH 32/92] add use time --- .../webank/webase/node/mgr/contract/ContractController.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java index 26eb20365..abbb03c65 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java @@ -438,9 +438,13 @@ public BasePageResponse findCnsList(@RequestBody @Valid ReqQueryCnsList inputPar @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN_OR_DEVELOPER) public BaseResponse copyContracts(@RequestBody @Valid ReqCopyContracts req, BindingResult result) { - log.info("copyContracts start. req:{}", JsonTools.toJSONString(req)); + Instant startTime = Instant.now(); + log.info("copyContracts start. startTime:{} req:{}", startTime.toEpochMilli(), + JsonTools.toJSONString(req)); checkBindResult(result); contractService.copyContracts(req); + log.info("end copyContracts. useTime:{}", + Duration.between(startTime, Instant.now()).toMillis()); return new BaseResponse(ConstantCode.SUCCESS, req.getContractItems().size()); } } From d349876aa6eef8a5ab6676c55af55f0b5ecf853a Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 30 Apr 2021 10:53:46 +0800 Subject: [PATCH 33/92] update api use time --- .../node/mgr/contract/ContractController.java | 3 +- .../warehouse/WarehouseController.java | 38 ++++++++++++++----- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java index abbb03c65..79ec77485 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java @@ -443,8 +443,7 @@ public BaseResponse copyContracts(@RequestBody @Valid ReqCopyContracts req, JsonTools.toJSONString(req)); checkBindResult(result); contractService.copyContracts(req); - log.info("end copyContracts. useTime:{}", - Duration.between(startTime, Instant.now()).toMillis()); + log.info("end copyContracts. useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); return new BaseResponse(ConstantCode.SUCCESS, req.getContractItems().size()); } } diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseController.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseController.java index dc7fc6809..3c02cb78a 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseController.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/WarehouseController.java @@ -16,9 +16,12 @@ import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.controller.BaseController; import com.webank.webase.node.mgr.base.entity.BaseResponse; +import com.webank.webase.node.mgr.base.tools.JsonTools; import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractFolder; import com.webank.webase.node.mgr.contract.warehouse.entity.TbContractItem; import com.webank.webase.node.mgr.contract.warehouse.entity.TbWarehouse; +import java.time.Duration; +import java.time.Instant; import java.util.List; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -45,11 +48,13 @@ public class WarehouseController extends BaseController { * query the list of contract store item */ @GetMapping(value = "/list") - public BaseResponse getContractStoreList() { - + public BaseResponse listContractStore() { + Instant startTime = Instant.now(); + log.info("listContractStore start. startTime:{}", startTime.toEpochMilli()); List storeItemList = warehouseService.getStoreList(); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(storeItemList); + log.info("end listContractStore. useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); return response; } @@ -58,10 +63,13 @@ public BaseResponse getContractStoreList() { */ @GetMapping(value = "") public BaseResponse getContractStoreById(@RequestParam("warehouseId") Integer warehouseId) { - log.info("getContractStoreById start. warehouseId:{}", warehouseId); + Instant startTime = Instant.now(); + log.info("getContractStoreById start. startTime:{} warehouseId:{}", startTime.toEpochMilli(), + warehouseId); TbWarehouse storeItem = warehouseService.getStoreItemById(warehouseId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(storeItem); + log.info("end getContractStoreById. useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); return response; } @@ -70,10 +78,13 @@ public BaseResponse getContractStoreById(@RequestParam("warehouseId") Integer wa */ @GetMapping(value = "/folder") public BaseResponse getContractFolderById(@RequestParam("folderId") Integer folderId) { - log.info("getContractStoreById start. folderId:{}", folderId); + Instant startTime = Instant.now(); + log.info("getContractFolderById start. startTime:{} folderId:{}", startTime.toEpochMilli(), + folderId); TbContractFolder contractFolderItem = warehouseService.getContractFolderById(folderId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(contractFolderItem); + log.info("end getContractFolderById. useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); return response; } @@ -82,10 +93,13 @@ public BaseResponse getContractFolderById(@RequestParam("folderId") Integer fold */ @GetMapping(value = "/item") public BaseResponse getContractItemById(@RequestParam("contractId") Integer contractId) { - log.info("getContractStoreById start. contractId:{}", contractId); + Instant startTime = Instant.now(); + log.info("getContractItemById start. startTime:{} contractId:{}", startTime.toEpochMilli(), + contractId); TbContractItem contractItem = warehouseService.getContractItemById(contractId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(contractItem); + log.info("end getContractItemById. useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); return response; } @@ -93,11 +107,14 @@ public BaseResponse getContractItemById(@RequestParam("contractId") Integer cont * get folderItemList by warehouseId */ @GetMapping(value = "/folder/list") - public BaseResponse getFolderItemListByStoreId(@RequestParam("warehouseId") Integer warehouseId) { - log.info("getFolderItemListByStoreId start. warehouseId:{}", warehouseId); + public BaseResponse listFolderItemByStoreId(@RequestParam("warehouseId") Integer warehouseId) { + Instant startTime = Instant.now(); + log.info("listFolderItemByStoreId start. startTime:{} warehouseId:{}", startTime.toEpochMilli(), + warehouseId); List contractFolderItemList = warehouseService.getFolderItemListByStoreId(warehouseId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(contractFolderItemList); + log.info("end listFolderItemByStoreId. useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); return response; } @@ -105,11 +122,14 @@ public BaseResponse getFolderItemListByStoreId(@RequestParam("warehouseId") Inte * get contractItemList by folderId */ @GetMapping(value = "/item/list") - public BaseResponse getContractItemByFolderId(@RequestParam("folderId") Integer folderId) { - log.info("getContractItemByFolderId start. warehouseId:{}", folderId); + public BaseResponse listContractItemByFolderId(@RequestParam("folderId") Integer folderId) { + Instant startTime = Instant.now(); + log.info("listContractItemByFolderId start. startTime:{} folderId:{}", startTime.toEpochMilli(), + folderId); List contractItemList = warehouseService.getContractItemByFolderId(folderId); BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); response.setData(contractItemList); + log.info("end listContractItemByFolderId. useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); return response; } } From ead3e75b6099c4f267767c92b9da8a33c3df2b57 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 30 Apr 2021 12:01:10 +0800 Subject: [PATCH 34/92] default empty of bin --- .../com/webank/webase/node/mgr/scaffold/ScaffoldService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java index 6a15975be..90d5373c3 100644 --- a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java @@ -182,9 +182,11 @@ private List handleContractList(List contractList) { contractInfo.setContractAddress(contractAddress); contractInfo.setAbiStr(contractAbi); if (cryptoSuite.getCryptoTypeConfig() == CryptoType.SM_TYPE) { + contractInfo.setBinStr(""); contractInfo.setSmBinStr(bytecodeBin); } else { contractInfo.setBinStr(bytecodeBin); + contractInfo.setSmBinStr(""); } contractInfoList.add(contractInfo); } From 22e9713299e431446a9326c5795c81e322e91178 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 6 May 2021 09:51:29 +0800 Subject: [PATCH 35/92] update order --- .../mgr/contract/warehouse/mapper/TbContractFolderMapper.java | 2 +- .../mgr/contract/warehouse/mapper/TbContractItemMapper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java index ff952ce85..59a0d8da3 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractFolderMapper.java @@ -20,7 +20,7 @@ public interface TbContractFolderMapper { @Select({ "select", TbContractFolderSqlProvider.ALL_COLUMN_FIELDS, "from tb_contract_folder", - "where warehouse_id = #{warehouseId}" }) + "where warehouse_id = #{warehouseId} order by id asc" }) List findByWarehouseId(@Param("warehouseId") Integer warehouseId); /** diff --git a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java index 8d8e703ca..1e3199242 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/warehouse/mapper/TbContractItemMapper.java @@ -17,7 +17,7 @@ public interface TbContractItemMapper { @Select({ "select", TbContractItemSqlProvider.ALL_COLUMN_FIELDS, "from tb_contract_item", - "where contract_folder_id = #{contractFolderId}" }) + "where contract_folder_id = #{contractFolderId} order by id asc" }) List listByFolderId(@Param("contractFolderId") Integer contractFolderId); /** From a98f16a30ca76a81ac3e942930ca9abedce7255f Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 6 May 2021 10:37:26 +0800 Subject: [PATCH 36/92] fix param & code --- .../com/webank/webase/node/mgr/base/code/ConstantCode.java | 3 +-- .../com/webank/webase/node/mgr/base/tools/NodeMgrTools.java | 3 +++ .../com/webank/webase/node/mgr/scaffold/entity/ReqProject.java | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java index f99510601..aea5f632e 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java +++ b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java @@ -312,9 +312,8 @@ public class ConstantCode { public static final RetCode SIGNATURE_NOT_MATCH = RetCode.mark(202526, "signature not match"); // add in v1.5.1 - public static final RetCode PROJECT_NAME_ALREADY_EXIST = RetCode.mark(202531, "directory of project's artifact name already exist"); + public static final RetCode GENERATE_CONTRACT_PROJECT_FAIL = RetCode.mark(202531, "directory of project's artifact name already exist"); public static final RetCode GET_FRONT_SDK_MAP_FAIL = RetCode.mark(202532, "get sdk cert/key content map failed"); - public static final RetCode GENERATE_CONTRACT_PROJECT_FAIL = RetCode.mark(202533, "generate project of contract failed"); /* auth */ diff --git a/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java b/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java index 3a243cf5e..edaa3dc3e 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java +++ b/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java @@ -717,6 +717,9 @@ public static String fileToBase64(String filePath) { public static boolean deleteDir(File dir) { if (dir.isDirectory()) { String[] children = dir.list(); + if (children == null) { + return dir.delete(); + } // recursive delete until dir is emtpy to delete for (int i=0; i userAddressList; } From 76a6933b30b40ad510e5815e4f4f4b8e1c975a80 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 7 May 2021 10:39:42 +0800 Subject: [PATCH 37/92] update error code --- .../java/com/webank/webase/node/mgr/base/code/ConstantCode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java index aea5f632e..21d5980f1 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java +++ b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java @@ -312,7 +312,7 @@ public class ConstantCode { public static final RetCode SIGNATURE_NOT_MATCH = RetCode.mark(202526, "signature not match"); // add in v1.5.1 - public static final RetCode GENERATE_CONTRACT_PROJECT_FAIL = RetCode.mark(202531, "directory of project's artifact name already exist"); + public static final RetCode GENERATE_CONTRACT_PROJECT_FAIL = RetCode.mark(202531, "generate project failed in scaffold"); public static final RetCode GET_FRONT_SDK_MAP_FAIL = RetCode.mark(202532, "get sdk cert/key content map failed"); From 36bf67f6e01f28342e11c6f8346336f8f9f5fd5f Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 7 May 2021 11:09:51 +0800 Subject: [PATCH 38/92] only localhost or not --- .../node/mgr/base/code/ConstantCode.java | 1 + .../node/mgr/deploy/service/HostService.java | 35 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java index 21d5980f1..05cf0ee76 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java +++ b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java @@ -252,6 +252,7 @@ public class ConstantCode { public static final RetCode IMAGE_NOT_EXISTS_ON_HOST = RetCode.mark(202466, "Image not exists on host."); public static final RetCode NODES_NUM_EXCEED_MAX_ERROR = RetCode.mark(202467, "Max 4 nodes on a same host."); public static final RetCode SAME_HOST_ERROR = RetCode.mark(202468, "Host of WeBASE-Node-Manager's ip is already existed."); + public static final RetCode HOST_ONLY_ALL_LOCALHOST_OR_NOT_LOCALHOST = RetCode.mark(202469, "Host must be all localhost(127.0.0.1) or all non-localhost"); // add in 1.4.3 public static final RetCode EXEC_DOCKER_CHECK_SCRIPT_ERROR = RetCode.mark(202469, "Check docker installed and running of host"); public static final RetCode EXEC_HOST_CHECK_SCRIPT_ERROR_FOR_MEM = RetCode.mark(202470, "Check host memory not enough for nodes(s)"); diff --git a/src/main/java/com/webank/webase/node/mgr/deploy/service/HostService.java b/src/main/java/com/webank/webase/node/mgr/deploy/service/HostService.java index feb5fd75d..7e8510797 100644 --- a/src/main/java/com/webank/webase/node/mgr/deploy/service/HostService.java +++ b/src/main/java/com/webank/webase/node/mgr/deploy/service/HostService.java @@ -108,7 +108,7 @@ public TbHost checkDirAndInsert(String ip, String rootDir, HostStatusEnum hostSt log.info("check host ip accessible:{}", ip); ansibleService.execPing(ip); // check 127.0.0.1 - this.validateHostLocalIp(ip); + this.validateAllLocalhostOrNot(ip); log.info("check host root dir accessible:{}", rootDir); ExecuteResult execResult = ansibleService.execCreateDir(ip, rootDir); @@ -843,6 +843,7 @@ public boolean syncCheckPortHostList(List deployNodeInfoList) { * if 127.0.0.1 was added first, then check * @param ip */ + @Deprecated private void validateHostLocalIp(String ip) { if (IPUtil.isLocal(ip)) { // if ip is 127.0.0.1, check all other host ip @@ -874,4 +875,36 @@ private void validateHostLocalIp(String ip) { } } + /** + * @case: if 127.0.0.1 added, cannot add other ip, only 127.0.0.1 support + * @case: if other ip added, cannot add 127.0.0.1 + */ + private void validateAllLocalhostOrNot(String ip) { + log.info("check validateAllLocalhostOrNot ip:{}",ip); + if (IPUtil.isLocal(ip)) { + // if ip is 127.0.0.1, check all other host ip + List hostList = tbHostMapper.selectAll(); + // 127.0.0.1 is the first host, pass + if (hostList == null || hostList.isEmpty()) { + log.info("host list empty, skip check local"); + return; + } else { + // if already exist others ip, not pass + log.error("validateAllLocalhostOrNot already exist common ip, cannot add 127.0.0.1"); + throw new NodeMgrException(ConstantCode.HOST_ONLY_ALL_LOCALHOST_OR_NOT_LOCALHOST); + } + } else { + // check whether 127.0.0.1 in tb_host + TbHost hostOfLocalIp = tbHostMapper.getByIp(IPUtil.LOCAL_IP_127); + if (hostOfLocalIp == null) { + log.info("host of 127.0.0.1 not in tb_host, skip check local"); + return; + } else { + // if already exist local ip, not pass + log.error("validateAllLocalhostOrNot already exist localhost ip, cannot add common ip"); + throw new NodeMgrException(ConstantCode.HOST_ONLY_ALL_LOCALHOST_OR_NOT_LOCALHOST); + } + + } + } } \ No newline at end of file From c6b112a9bc571fe8843b17f015818424f59d4370 Mon Sep 17 00:00:00 2001 From: marsli Date: Fri, 7 May 2021 20:27:25 +0800 Subject: [PATCH 39/92] Delete script/gm directory --- script/gm/webase-dml-gm.sql | 108 ----------------------------------- script/gm/webase-gm.sh | 32 ----------- script/gm/webase-sql-gm.list | 4 -- 3 files changed, 144 deletions(-) delete mode 100644 script/gm/webase-dml-gm.sql delete mode 100644 script/gm/webase-gm.sh delete mode 100644 script/gm/webase-sql-gm.list diff --git a/script/gm/webase-dml-gm.sql b/script/gm/webase-dml-gm.sql deleted file mode 100644 index 232c9d8d5..000000000 --- a/script/gm/webase-dml-gm.sql +++ /dev/null @@ -1,108 +0,0 @@ - --- ---------------------------- --- 1、init tb_account_info data admin/Abcd1234 // 国密版 sm3.hash(Abcd123) --- ---------------------------- -INSERT INTO tb_account_info (account,account_pwd,role_id,create_time,modify_time)values('admin', '$2a$10$F/aEB1iEx/FvVh0fMn6L/uyy.PkpTy8Kd9EdbqLGo7Bw7eCivpq.m',100000,now(),now()); - - --- ---------------------------- --- 2、init tb_role data --- ---------------------------- -INSERT INTO `tb_role` (role_name,role_name_zh,create_time,modify_time)VALUES ('admin', '管理员', now(), now()); -INSERT INTO `tb_role` (role_name,role_name_zh,create_time,modify_time)VALUES ('visitor', '普通用户', now(), now()); -INSERT INTO `tb_role` (role_name,role_name_zh,create_time,modify_time)VALUES ('developer', '开发者', now(), now()); - - --- ---------------------------- --- 3、init tb_user data 国密版 --- ---------------------------- --- INSERT INTO tb_user(user_name, public_key, user_status, user_type, address, has_pk, create_time, modify_time) VALUES ( 'systemUser', '0xc5d877bff9923af55f248fb48b8907dc7d00cac3ba19b4259aebefe325510af7bd0a75e9a8e8234aa7aa58bc70510ee4bef02201a86006196da4e771c47b71b4', 1, 2, '0xf1585b8d0e08a0a00fff662e24d67ba95a438256', 1, Now(), Now()); - - - --- ---------------------------- --- 4、init tb_user_key_mapping data 国密版 --- ---------------------------- --- INSERT INTO tb_user_key_mapping(user_id, private_key, map_status, create_time, modify_time) VALUES (700001, 'SzK9KCjpyVCW0T9K9r/MSlmcpkeckYKVn/D1X7fzzp18MM7yHhUHQugTxKXVJJY5XWOb4zZ79IXMBu77zmXsr0mCRnATZTUqFfWLX6tUBIw=', 1, now(), now()); - - --- ---------------------------- --- 5、init tb_method (repeated methodId is removed, ex: remove(string)) methodId 国密版 --- ---------------------------- --- (system config info 0x1000) setValueByKey -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x0749b518', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"value\",\"type\":\"string\"}],\"name\":\"setValueByKey\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); --- (table factory 0x1001) createTable openTable -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xc92a7801', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"tableName\",\"type\":\"string\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"valueField\",\"type\":\"string\"}],\"name\":\"createTable\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x59a48b65', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"string\"}],\"name\":\"openTable\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, now(), now()); --- (crud info 0x1002) update select remove insert(same as cns's insert) -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x10bd675b', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"tableName\",\"type\":\"string\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"entry\",\"type\":\"string\"},{\"name\":\"condition\",\"type\":\"string\"},{\"name\":\"optional\",\"type\":\"string\"}],\"name\":\"update\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x7388111f', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"tableName\",\"type\":\"string\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"condition\",\"type\":\"string\"},{\"name\":\"optional\",\"type\":\"string\"}],\"name\":\"select\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x81b81824', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"tableName\",\"type\":\"string\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"condition\",\"type\":\"string\"},{\"name\":\"optional\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xb8eaa08d', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"version\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"string\"},{\"name\":\"abi\",\"type\":\"string\"}],\"name\":\"insert\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-06-17 20:32:30', '2019-06-17 20:32:30'); --- (consensus info node manage 0x1003) addObserver addSealer remove -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x25e85d16', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"nodeID\",\"type\":\"string\"}],\"name\":\"addObserver\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xdf434acc', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"nodeID\",\"type\":\"string\"}],\"name\":\"addSealer\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x86b733f9', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"nodeID\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); --- (cns info 0x1004) selectByName selectByNameAndVersion // insert(ignored, same as crud's insert method: insert(string,string,string,string) -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x078af4af', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"}],\"name\":\"selectByName\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2019-06-17 20:32:30', '2019-06-17 20:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xec72a422', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"version\",\"type\":\"string\"}],\"name\":\"selectByNameAndVersion\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2019-06-17 20:32:30', '2019-06-17 20:32:30'); --- INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xb8eaa08d', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"version\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"string\"},{\"name\":\"abi\",\"type\":\"string\"}],\"name\":\"insert\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-06-17 20:32:30', '2019-06-17 20:32:30'); --- (permission manage 0x1005) insert queryByName remove grantWrite revokeWrite -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xce0a9fb9', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"table_name\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"string\"}],\"name\":\"insert\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xbbec3f91', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"table_name\",\"type\":\"string\"}],\"name\":\"queryByName\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x85d23afc', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"table_name\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"string\"}],\"name\":\"remove\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2019-09-02 16:32:30', '2019-09-02 16:32:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xd010d23c', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"contractAddr\",\"type\":\"address\"},{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"grantWrite\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, now(), now()); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xdf12fe78', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"contractAddr\",\"type\":\"address\"},{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"revokeWrite\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, now(), now()); --- (contract life cycle 0x1007) --- getStatus unfreeze freeze grantManager queryManager revokeManager -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xbca14431', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x61cb24c3', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"unfreeze\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xf12c66df', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"freeze\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x27c46414', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"contractAddr\",\"type\":\"address\"},{\"name\":\"userAddr\",\"type\":\"address\"}],\"name\":\"grantManager\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xa450e730', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryManager\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x00c77684', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"contractAddr\",\"type\":\"address\"},{\"name\":\"userAddr\",\"type\":\"address\"}],\"name\":\"revokeManager\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, now(), now()); --- (chain governance 0x1008) --- listOperators updateCommitteeMemberWeight queryThreshold queryCommitteeMemberWeight grantCommitteeMember -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xb90059a3', 0, '{\"constant\":true,\"inputs\":[],\"name\":\"listOperators\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x95e96f8f', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"},{\"name\":\"weight\",\"type\":\"int256\"}],\"name\":\"updateCommitteeMemberWeight\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x35365efb', 0, '{\"constant\":true,\"inputs\":[],\"name\":\"queryThreshold\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xc784c982', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"queryCommitteeMemberWeight\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"},{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xcbff0346', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"grantCommitteeMember\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); --- unfreezeAccount listCommitteeMembers updateThreshold revokeCommitteeMember grantOperator -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x2312386d', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"account\",\"type\":\"address\"}],\"name\":\"unfreezeAccount\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x77cb0994', 0, '{\"constant\":true,\"inputs\":[],\"name\":\"listCommitteeMembers\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x931af204', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"threshold\",\"type\":\"int256\"}],\"name\":\"updateThreshold\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x681362f3', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"revokeCommitteeMember\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xd1db6540', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"grantOperator\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); --- freezeAccount revokeOperator getAccountStatus -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0x563e46a5', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"account\",\"type\":\"address\"}],\"name\":\"freezeAccount\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xc9ab2069', 0, '{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"}],\"name\":\"revokeOperator\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); -INSERT INTO `tb_method`(`method_id`, `group_id`, `abi_info`, `method_type`, `contract_type`, `create_time`, `modify_time`) VALUES ('0xa41e61cc', 0, '{\"constant\":true,\"inputs\":[{\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}', 'function', 1, '2020-08-03 19:44:30', '2020-08-03 19:44:30'); - - --- ---------------------------- --- 6、init tb_alert_rule --- ---------------------------- --- add node status alert rule template -INSERT INTO `tb_alert_rule`(`rule_name`,`enable`,`alert_type`,`alert_level`,`alert_interval_seconds`,`alert_content`,`content_param_list`,`create_time`,`modify_time`) VALUES ('节点异常告警/Node Exception', 0, 1, 1, 3600, '{nodeId}节点异常,请到“节点管理”页面查看具体信息 / Node: {nodeIdEn} node status exception,please check out in \"Node Management\"', '[\"{nodeId}\", \"{nodeIdEn}\"]', '2019-10-29 20:02:30', '2019-10-29 20:02:30'); --- add audit alert rule template -INSERT INTO `tb_alert_rule`(`rule_name`,`enable`,`alert_type`,`alert_level`,`alert_interval_seconds`,`alert_content`,`content_param_list`,`create_time`,`modify_time`) VALUES ('审计异常告警/Audit Exception', 0, 2, 1, 3600, '审计异常:{auditType},请到“交易审计”页面查看具体信息 / Audit alert: {auditTypeEn},please check out in \"Transaction Audit\"', '[\"{auditType}\", \"{auditTypeEn}\"]', '2019-10-29 20:02:30', '2019-10-29 20:02:30'); --- add cert alert rule template -INSERT INTO `tb_alert_rule`(`rule_name`,`enable`,`alert_type`,`alert_level`,`alert_interval_seconds`,`alert_content`,`content_param_list`,`create_time`,`modify_time`) VALUES ('证书有效期告警/Cert Validity Exception', 0, 3, 1, 3600, '证书将在{time}过期,请到“证书管理”页面查看具体信息 / Cert validity exception:invalid at {timeEn},please check out in \"Cert Management\"', '[\"{time}\", \"{timeEn}\"]', '2019-10-29 20:02:30', '2019-10-29 20:02:30'); - --- ---------------------------- --- 7、init tb_mail_server_config --- ---------------------------- --- add mail_server_config template -INSERT INTO `tb_mail_server_config`(`server_name`,`host`,`port`,`username`,`password`,`protocol`,`default_encoding`,`create_time`,`modify_time`,`authentication`,`starttls_enable`,`starttls_required`,`socket_factory_port`,`socket_factory_class`,`socket_factory_fallback`,`enable`) VALUES ('Default config', 'smtp.qq.com', '25', 'yourmail@qq.com', 'yourpassword','smtp', 'UTF-8','2019-10-29 20:02:30', '2019-10-29 20:02:30', 1, 1, 0, 465, 'javax.net.ssl.SSLSocketFactory', 0, 0); - - --- ---------------------------- --- 8、init tb_config --- ---------------------------- -INSERT INTO `tb_config`(`config_name`, `config_type`, `config_value`, `create_time`, `modify_time`) VALUES ('docker 镜像版本', 1, 'v2.7.2', '2020-07-22 17:14:23', '2020-07-22 17:14:23'); - --- ---------------------------- --- 9、init tb_app_info data (template) --- ---------------------------- -INSERT INTO `tb_app_info` (`app_name`, `app_key`, `app_type`, `app_doc_link`, `app_icon`, `app_desc`, `app_detail`, `create_time`, `modify_time`) VALUES ('WeId-temp', 'app00001', 1, 'https://weidentity.readthedocs.io/zh_CN/latest/docs/deploy-via-web.html', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFGmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDIgNzkuMTY0MzUyLCAyMDIwLzAxLzMwLTE1OjUwOjM4ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjEtMDMtMThUMTY6NTc6MzQrMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTAzLTE4VDE4OjAyOjAxKzA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIxLTAzLTE4VDE4OjAyOjAxKzA4OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg1NDJjNjJlLTZjYTUtNGI2My05ZDg5LWNhMjVmOTU1NTA4OSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4NTQyYzYyZS02Y2E1LTRiNjMtOWQ4OS1jYTI1Zjk1NTUwODkiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo4NTQyYzYyZS02Y2E1LTRiNjMtOWQ4OS1jYTI1Zjk1NTUwODkiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg1NDJjNjJlLTZjYTUtNGI2My05ZDg5LWNhMjVmOTU1NTA4OSIgc3RFdnQ6d2hlbj0iMjAyMS0wMy0xOFQxNjo1NzozNCswODowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+5hbXdAAADNFJREFUeJzt23msXOV5x/Hf877vWWa/q++177VZvG8EMEUyxXIxFBVaCIEEiFJVCS0ohJRIVGoiHFVKlTZVUUvVqE5omlBQiJIoAYKdpTipgZrGtdsa8IIDxtf7vXPX2c+c8y5P/7gusgWWKs4fVdXzlY5mzoxm5ugz533PnNEMMTOyPnjif3sD/q+XAaYsA0xZBpiyDDBlGWDKMsCUZYApywBTlgGmLANMWQaYsgwwZRlgyjLAlGWAKcsAU5YBpiwDTFkGmLIMMGUZYMoywJRlgCnLAFOWAaYsA0xZBpiyDDBlGWDKMsCUZYApU+ev7BscAACQ4z8E+F6AzmilPu6SxOpaDcrzkKuUoZmhmB8F8NsCOGRIPNBRCtfUa4i6MeoAdpVG8ceb/xxOEPIm7hVSfpcFiuToaXJ4go3F5PFZeJVRRHsfATCO4Vv+7ouyOHiN6UZfJNBB9iUmIwbXE3jVMbjxz8Jf4iCW/gDtX2nArwGiC7SuQLGyFkr8CI2DHoZuvBQQDqSMAsMRsSMSSIwFMcMraIzv+DRs504Az2H4lm1QuQEZcR1e3trG/jY6y0eBmTaw+ygABq68BNiwEDgyDd5937tmF+yB1hoYa0DgO4UQ17E1Vw83Gq7cbCIGYJhhnIXHFkS4WwLXGaI1LBREHAFOgwDUAVzZPI3bT7+Ebq4PQnmXQ4qb4XCd82yv6zEwXgI2ANsWQFchXHV3KILcl9jqD1OCAF0Bqx1AH+AXtJ4AyN3DJF8URI8JcujYGKKwACS9e532tlfWvXZL4cqrkVt3Vwjpf4dZv1gIzSaSOSRQ82j/gy4A7NYaiOtNYuZhQQQnxY8Xx13utxYGQCIEClGMdfVmAUyDICBW8meVdhMDtQYiIgAEB6AD4IGjOzEY94C4uNzBQBkfjcWzL1evOo220nANB4gIhBUIeu4YkMW8YKNnRIiDwjOwksEMwAI2tgAIIIJzDCQO0BrQCRADzoQQ2sBpwoxrgVh/VBLfEDu3uJoEmK2fQnPPX0GwfkSEg7+T739hsR7oR7j2viEVhB9n57Z0Dg9MTbV9GIQAM2AZgJ5fDANCAPZCwAuGMJVKUMxLQHS5cw6WxL+9XanAEj08RFjM1o012W07kMuNMHgRSEBq/VrS6SAI/HUn8+GtfkENsDFvuyj67vJoqrkh2o9dvUvWFNsMp2yjPN73TjhRhq4J5IbsQG5B4faem1cvANorTduHyvceiN55LtZtDX/9J5A30yNcoLJclDvWqqrYJha5nKpgUIxC9cagoqA8tB+cHpOyiNzyYpFjsxC+t5xIwMbRW6xxSSBl0m0cnSi55BvKo58kzdzTaMxWKAhvF6EPFlRruZovOnJJ2KdaRDyIvLK4ZOAoSQaX1RC6yQjnaAbAiXfNzv+R+duVChIpb+pKsZOZoVrt/sT3Nsl8/nlhLAQB2tg+Q1jhS7GHGci12wMNqW4LCoUnnbVwAJQgdEkc2Dg1ufnrC1bPPbjlL7+/KKp9jHz7n2bSbuicaiF3VeXWUPrfccZVWAmwTqBjoHcg/Gp1998+bMPVC3vWfXgbktodQkk4ZU5Ep8r3q1DvVP2dL0tWf+ScDBkSUna7znZ+Fkf0US+f+5Jif6tOOgADJCWk9EFEX+F8cZttNX/BNjluJX0+8MLnXBJf6nQMCAmVF0CizjCZbcKpraTsfqvN9dGcRWEw/yKMu8mS23r62d/7yvsO4csaDZTjeLkmgmT+VRD6GzzPe4a1hiaODAAy5pNerFcRCUjr9rHnXxfkwyfJ6rjjzF01nVwmnP3moDXrX63kH/mzbg3FuVOXE4WgUB7pNM+CKV4f+P4LOtIVSPsZ6Zl1MO7nni9Qn2nt0SOfQmnFzS+5ePYO5+zTJokftW0xWrx8ZruefWdYV80yYzhkE00LW//XpKN9oHSHjeKHda1x1MEend89iJntK4xkX7fTebF1trpWslnh4BY1g6QOVT3I1tQgJEA4biJ+xbjkWWvMUGKTPCs5kUwZzO09nddGbzZkSZE9eNE5cF9/P8bDcJ1nLSxAdeU9AaICrH2Iou5niRnsew+50L+PrYURNNb2vDthGZYxFRCuLyvxB4YxFMQNVPMjG6tbHivnw+IyRgNmRu6Tc7+J4orRx2yspVK8tXus+bXJXdVDELIowBCJ+mWp7N1NHK1gxlGAdoH5EGB2mygInF+5Ex73WMso+rUHB/NTv86gZzk2oL7eNVGl5x9trL9AQgEQY2Da7Ky5Vgj3kpTY7GDgecnhYHzx2NSu226DoINCCQB4HLCbRYKH4WiESEB33ctqMIcFNy1cxQ4+O5oulczrF50DBSAUYSUzwMAKjxkW9KqRcpsiGRDRV8G8FMBSx4ATmBbgZc4BDtBSqt8loGwZdUt0tKTEy4NEqxPIihARuh25p0aSFnp8I6yFFfxUtx5BaN0Hhw0msEYPd06G9dJWxw4A50DeYyBVIbY1js3JwuJSDxu7lo3GlN70HxPxCeRp9hJBEuzweqvuID2+qqwYlvh1BYXW3BxcHqiU+tdar4b2W1ccaO3/Naglb5YYvB6OAZb/LkSMaKgNrzG4WloCkuQN6gIoFZeK+e05XGuEpy+6Bw7U60uYeZWjcxOkc6eDSuUjpUUjoGIxZuZvERgMQFgDUSn/knK5cWEtIOkFS2IJQKGQNBpKcc8sgr+oW3WFhAV0Qa/sa78+eu3PfSBW7ASccZcV1veg78ZFq8HkOfAh7WsLiw5IAsB25/QKa5JhNm4jC3UDEncSjFEhvbkW+2Nt3Q0J+JABo2i6+wbDLnyPN1rrAMHHHFnfy+UXdN7aEcTNqTWsywiHq2/037QDg5t2XgNGhR054VyVWfZSnvIkbczMIBJbWGHYQd8COBD4DTC7iwLGYXgFAyPEgCICCXFvrrd3SrdaqI+Po9vp/L2SCsQASQW0u6+Fid4mPQnB/LnA6O+x0V9W1vyDY/e91VMnSz2ms9pAwlIy1WARVZKlCVjuhyAI8reTVttMh7/OwsHv8FhfdRFEaegbpHyA8WlI+hrDfU746m+I6JPO8HKAwMRnh8XLGFHtjSxCH8ygmeLhAoUIfXGZA8COHmDId6hU+OvCpZsGSQXLWDMczR4JShMQjQXDRBIgJ5wnfgqZO+MdqHyIWvZPAYA8+hMqyBPS8qdkcRitsZ1vntlxPy4K2MyFS8tKtrRSk7FOHmo1W6/OHDuG5pkzcNYgjroHusZ82w+8VqzkW6bZrO6Zq+2dTsxH8ky/6Cp1a+J5X4CjDUlsn/inNVc2m8PBQFgM2iL0fjqRAOPdNjO7e8jxM+SDPd970DM9SwOIVryosKua/AumX3n0QFI9cr3I9X9fsLxBKf9+a9jYKP4xCxcTYSZK3A8n20VoCgaIxGkh5Q87SjerEwnaHbdVenIPQJMCNNM15nnuW1lWfukEg3dOT/DxiagHM36w0zl+iki+CSZBQrzSmWqedNo8T8Jd09L4TBLbx0kQXNJCoW/Vgf7Vd18AeMHHmAO5cOiQoNxGYj3p4jNzESABEOYvEwALwtCLlRgdMKZxtpvM7ACwsVDApWGISjdaSACdEmrSRg2zdfG38Wq4cmFZ/yhMcksnuwvWtkvqOEphDc7zYCbcYOS3QwwfYdFe6XVP3HVGjx9MUP0t9Fx9F4rrHkIyN1ZWoc+1I7NNlRCK6ytFtrpQb4npTgw7UHR54Ym8MKIBQ8lEtQMMFLCoQgHrxGcr2haJ0+QCXwQFZtFmR/FMPg+GQblVR9nLVQwnGvA6IvBBVv8GAzOtBMd9a34/zNHjrAonWiRXkMolc8/c+v4HEb8bVw8D+BiAZh6YPQcHzJ/YWCIUnNOtVndsEMAkgADzwz0hwlDUHScAY6USyAfCsTUA+sYbOAaUh4AR9e4ZEgUSetpOtQstYPkeoDMCvDYCYATAKpBqg9kCQGN+A/i/B0wLQIsIoPnx0wHQYQCCBaQUcILAQAwgnn/752eocwtAgGSGAc/fzairqQ5mKEQSuuJQj/c8GJWK52A9D5DFY93xvZ+on92bwDkAFwF0AAoAYjl/nXBhdA6RiKB5/mBC592XCAE6d50YEF4D0EUAOSCUwPnzr2OQB0BJwFbm3yoP82dO0JhfOf/F6b0b9EE7/zTXMoRwmLttPaJiEaLTTcSe459n5+6xgvu8XPxku3HtUzO7t9eAf37PU6n33PL/LHLzO0K0ZRnQV4SYaSZiz7EfWMfTQqCkPPsTZ4Ia0Pv+j8/+L5yu7AvVlGWAKcsAU5YBpiwDTFkGmLIMMGUZYMoywJRlgCnLAFOWAaYsA0xZBpiyDDBlGWDKMsCUZYApywBTlgGmLANMWQaYsgwwZRlgyjLAlGWAKcsAU5YBpiwDTFkGmLIMMGX/BTNpY2P8E+A7AAAAAElFTkSuQmCC', 'WeIdentity是一套分布式多中心的技术解决方案。', 'WeIdentity目前主要包含两大模块:WeIdentity DID以及WeIdentity Credential。 WeIdentity DID模块在FISCO-BCOS区块链底层平台上实现了一套符合W3C DID规范的分布式多中心的身份标识协议,使实体(人或物)的现实身份实现了链上的身份标识;WeIdentity Credential提供了一整套基于W3C VC规范的解决方案,旨在对这一类数据进行标准化、电子化,生成可验证、可交换的「凭证」(Credential),支持对凭证的属性进行选择性披露,及生成链上存证(Evidence)。', now(), now()); diff --git a/script/gm/webase-gm.sh b/script/gm/webase-gm.sh deleted file mode 100644 index 131330a84..000000000 --- a/script/gm/webase-gm.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - - -echo -e "\n init start...." - -IP=${1} -PORT=${2} - -if [[ ! $IP || ! $PORT ]] ; then - echo "Usage: sh ${0} ip port" - echo "eg: sh ${0} 127.0.0.1 8501" - exit 1 -fi - -#dbUser -DBUSER="defaultAccount" -#dbPass -PASSWD="defaultPassword" -#dbName -DBNAME="webasenodemanager" - - -#connect to database then execute init -cat webase-sql-gm.list | mysql --user=$DBUSER --password=$PASSWD --host=$IP --database=$DBNAME --port=$PORT --default-character-set=utf8; - -if [ "$?" == "0" ]; then - echo -e "init success... \n" -else - echo -e "init fail... \n" -fi - -exit diff --git a/script/gm/webase-sql-gm.list b/script/gm/webase-sql-gm.list deleted file mode 100644 index 6f172a3d9..000000000 --- a/script/gm/webase-sql-gm.list +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -source ../webase-ddl.sql; -source webase-dml-gm.sql; \ No newline at end of file From fa46a49b3813c1d459b7043f7bcb38a41e929085 Mon Sep 17 00:00:00 2001 From: Sayou1989 Date: Mon, 10 May 2021 12:13:52 +0800 Subject: [PATCH 40/92] account interfaces for app integration --- build.gradle | 2 +- .../appintegration/AppIntegrationService.java | 12 +- .../{ => api}/AppIntegrationApi.java | 90 +++++++++++-- .../api/DecryptRequestBodyAdvice.java | 112 ++++++++++++++++ .../api/EncryptResponseBodyAdvice.java | 72 ++++++++++ .../entity/UpdatePasswordInfo.java | 30 +++++ .../node/mgr/base/code/ConstantCode.java | 3 + .../webase/node/mgr/base/enums/AppStatus.java | 44 +++++++ .../mgr/base/filter/AppIntegrationFilter.java | 6 +- .../mgr/base/filter/ValidateCodeFilter.java | 2 +- .../base/properties/ConstantProperties.java | 8 ++ .../webase/node/mgr/base/tools/AesUtils.java | 123 ++++++++++++++++++ .../webase/node/mgr/base/tools/JsonTools.java | 52 ++++++-- .../mgr/contract/ContractPathService.java | 9 ++ .../node/mgr/contract/ContractService.java | 19 ++- .../webase/node/mgr/role/RoleController.java | 25 +--- .../webase/node/mgr/role/RoleService.java | 35 ++++- src/main/resources/mapper/AppInfoMapper.xml | 4 +- 18 files changed, 583 insertions(+), 65 deletions(-) rename src/main/java/com/webank/webase/node/mgr/appintegration/{ => api}/AppIntegrationApi.java (88%) create mode 100644 src/main/java/com/webank/webase/node/mgr/appintegration/api/DecryptRequestBodyAdvice.java create mode 100644 src/main/java/com/webank/webase/node/mgr/appintegration/api/EncryptResponseBodyAdvice.java create mode 100644 src/main/java/com/webank/webase/node/mgr/appintegration/entity/UpdatePasswordInfo.java create mode 100644 src/main/java/com/webank/webase/node/mgr/base/enums/AppStatus.java create mode 100644 src/main/java/com/webank/webase/node/mgr/base/tools/AesUtils.java diff --git a/build.gradle b/build.gradle index 54084758b..906cc7dd1 100644 --- a/build.gradle +++ b/build.gradle @@ -80,7 +80,7 @@ List mbg = [ dependencies { compile springboot,spring,jaxb,jackson,log4j - compile "org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.7.2" + compile "org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.8.0-SNAPSHOT" compile "org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.0" compile "org.apache.commons:commons-lang3:3.8.1" compile "mysql:mysql-connector-java:8.0.22" diff --git a/src/main/java/com/webank/webase/node/mgr/appintegration/AppIntegrationService.java b/src/main/java/com/webank/webase/node/mgr/appintegration/AppIntegrationService.java index ec040e8f9..51d16f2ea 100644 --- a/src/main/java/com/webank/webase/node/mgr/appintegration/AppIntegrationService.java +++ b/src/main/java/com/webank/webase/node/mgr/appintegration/AppIntegrationService.java @@ -19,8 +19,8 @@ import com.webank.webase.node.mgr.appintegration.entity.AppRegisterInfo; import com.webank.webase.node.mgr.appintegration.entity.TbAppInfo; import com.webank.webase.node.mgr.base.code.ConstantCode; +import com.webank.webase.node.mgr.base.enums.AppStatus; import com.webank.webase.node.mgr.base.enums.AppType; -import com.webank.webase.node.mgr.base.enums.DataStatus; import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.base.tools.NodeMgrTools; import com.webank.webase.node.mgr.base.tools.ValidateUtil; @@ -84,6 +84,7 @@ public TbAppInfo newApp(AppAddInfo appAddInfo) { BeanUtils.copyProperties(appAddInfo, tbAppInfo); tbAppInfo.setAppKey(appKey); tbAppInfo.setAppSecret(appSecret); + tbAppInfo.setAppStatus(AppStatus.UNREGISTER.getValue()); Integer affectRow = appInfoMapper.addAppInfo(tbAppInfo); if (affectRow == 0) { log.warn("affect 0 rows of tb_app_info"); @@ -133,7 +134,7 @@ public void appRegister(String appKey, AppRegisterInfo appRegisterInfo) { } // update TbAppInfo tbAppInfo = queryAppInfoByAppKey(appKey); - tbAppInfo.setAppStatus(DataStatus.NORMAL.getValue()); + tbAppInfo.setAppStatus(AppStatus.NORMAL.getValue()); BeanUtils.copyProperties(appRegisterInfo, tbAppInfo); updateAppInfo(tbAppInfo); } @@ -147,12 +148,15 @@ public void appStatusCheck() { param.setAppType(AppType.NEW.getValue()); List listOfAppInfo = listOfAppInfo(param); for (TbAppInfo tbAppInfo : listOfAppInfo) { - Integer appStatus = DataStatus.NORMAL.getValue(); + if (tbAppInfo.getAppStatus().intValue() == AppStatus.UNREGISTER.getValue()) { + continue; + } + Integer appStatus = AppStatus.NORMAL.getValue(); try { NodeMgrTools.checkServerConnect(tbAppInfo.getAppIp(), tbAppInfo.getAppPort()); } catch (Exception e) { log.debug("appKey:{} status is invalid", tbAppInfo.getAppKey()); - appStatus = DataStatus.INVALID.getValue(); + appStatus = AppStatus.INVALID.getValue(); } updateAppInfo(new TbAppInfo(tbAppInfo.getId(), appStatus)); } diff --git a/src/main/java/com/webank/webase/node/mgr/appintegration/AppIntegrationApi.java b/src/main/java/com/webank/webase/node/mgr/appintegration/api/AppIntegrationApi.java similarity index 88% rename from src/main/java/com/webank/webase/node/mgr/appintegration/AppIntegrationApi.java rename to src/main/java/com/webank/webase/node/mgr/appintegration/api/AppIntegrationApi.java index a9d272d68..f86f840ac 100644 --- a/src/main/java/com/webank/webase/node/mgr/appintegration/AppIntegrationApi.java +++ b/src/main/java/com/webank/webase/node/mgr/appintegration/api/AppIntegrationApi.java @@ -12,16 +12,19 @@ * the License. */ -package com.webank.webase.node.mgr.appintegration; +package com.webank.webase.node.mgr.appintegration.api; import com.webank.webase.node.mgr.account.AccountService; +import com.webank.webase.node.mgr.account.entity.AccountInfo; import com.webank.webase.node.mgr.account.entity.AccountListParam; import com.webank.webase.node.mgr.account.entity.TbAccountInfo; +import com.webank.webase.node.mgr.appintegration.AppIntegrationService; import com.webank.webase.node.mgr.appintegration.contractstore.ContractStoreService; import com.webank.webase.node.mgr.appintegration.contractstore.entity.ReqContractAddressSave; import com.webank.webase.node.mgr.appintegration.contractstore.entity.ReqContractSourceSave; import com.webank.webase.node.mgr.appintegration.entity.AppRegisterInfo; import com.webank.webase.node.mgr.appintegration.entity.BasicInfo; +import com.webank.webase.node.mgr.appintegration.entity.UpdatePasswordInfo; import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.controller.BaseController; import com.webank.webase.node.mgr.base.entity.BasePageResponse; @@ -46,6 +49,7 @@ import com.webank.webase.node.mgr.node.NodeService; import com.webank.webase.node.mgr.node.entity.NodeParam; import com.webank.webase.node.mgr.node.entity.TbNode; +import com.webank.webase.node.mgr.role.RoleService; import com.webank.webase.node.mgr.table.TableService; import com.webank.webase.node.mgr.user.UserService; import com.webank.webase.node.mgr.user.entity.BindUserInputParam; @@ -87,6 +91,8 @@ public class AppIntegrationApi extends BaseController { @Autowired private AccountService accountService; @Autowired + private RoleService roleService; + @Autowired private GroupService groupService; @Autowired private NodeService nodeService; @@ -108,7 +114,7 @@ public class AppIntegrationApi extends BaseController { private VersionProperties versionProperties; /** - * add new front + * app register. */ @PostMapping("/appRegister") public BaseResponse appRegister(@RequestParam(required = true) String appKey, @@ -155,6 +161,68 @@ public BasePageResponse queryAccountList(@RequestParam(required = true) Integer return pagesponse; } + /** + * query role list. + */ + @GetMapping(value = "/roleList") + public BasePageResponse queryRoleList() throws NodeMgrException { + Instant startTime = Instant.now(); + log.info("start queryRoleList.", startTime.toEpochMilli()); + + // query + BasePageResponse pagesponse = roleService.queryRoleList(null, null, null, null); + + log.info("end queryRoleList useTime:{} result:{}", + Duration.between(startTime, Instant.now()).toMillis(), + JsonTools.toJSONString(pagesponse)); + return pagesponse; + } + + /** + * add account info. + */ + @PostMapping(value = "/accountAdd") + public BaseResponse addAccountInfo(@RequestBody @Valid AccountInfo info, BindingResult result) + throws NodeMgrException { + checkBindResult(result); + BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS); + Instant startTime = Instant.now(); + log.info("start addAccountInfo. startTime:{}", startTime.toEpochMilli()); + + // add account row + accountService.addAccountRow(info); + + // query row + TbAccountInfo tbAccount = accountService.queryByAccount(info.getAccount()); + tbAccount.setAccountPwd(null); + baseResponse.setData(tbAccount); + + log.info("end addAccountInfo useTime:{} result:{}", + Duration.between(startTime, Instant.now()).toMillis(), + JsonTools.toJSONString(baseResponse)); + return baseResponse; + } + + /** + * update password. + */ + @PostMapping(value = "/passwordUpdate") + public BaseResponse updatePassword(@RequestBody @Valid UpdatePasswordInfo info, + BindingResult result) throws NodeMgrException { + checkBindResult(result); + BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS); + Instant startTime = Instant.now(); + + // update account row + accountService.updatePassword(info.getAccount(), info.getOldAccountPwd(), + info.getNewAccountPwd()); + + log.info("end updatePassword useTime:{} result:{}", + Duration.between(startTime, Instant.now()).toMillis(), + JsonTools.toJSONString(baseResponse)); + return baseResponse; + } + /** * get base info. */ @@ -172,6 +240,7 @@ public BaseResponse getBasicInfo() { /** * get encrypt type. */ + @Deprecated @GetMapping("encrypt") public BaseResponse getEncryptType() { int encrypt = cryptoSuite.cryptoTypeConfig; @@ -340,7 +409,7 @@ public BaseResponse newUser(@RequestBody @Valid NewUserInputParam user, BindingR // add user row TbUser userRow = userService.addUserInfo(user.getGroupId(), user.getUserName(), - user.getAccount(), user.getDescription(), user.getUserType(), null, + user.getAccount(), user.getDescription(), user.getUserType(), null, ReturnPrivateKey.TURE.getValue(), CheckUserExist.TURE.getValue()); baseResponse.setData(userRow); @@ -378,18 +447,18 @@ public BasePageResponse userList(@RequestParam(required = true) Integer groupId, @RequestParam(required = true) Integer pageNumber, @RequestParam(required = true) Integer pageSize, @RequestParam(required = false) String account, - @RequestParam(required = false) String commParam, + @RequestParam(required = false) String userParam, @RequestParam(required = false, defaultValue = "") Integer hasPrivateKey) throws NodeMgrException { BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); - log.info("start userList startTime:{} groupId:{} pageNumber:{} pageSize:{} commParam:{}", - startTime.toEpochMilli(), groupId, pageNumber, pageSize, commParam); + log.info("start userList startTime:{} groupId:{} pageNumber:{} pageSize:{} userParam:{}", + startTime.toEpochMilli(), groupId, pageNumber, pageSize, userParam); UserParam param = new UserParam(); param.setGroupId(groupId); param.setAccount(account); - param.setCommParam(commParam); + param.setCommParam(userParam); param.setPageSize(pageSize); param.setHasPk(hasPrivateKey); @@ -442,7 +511,8 @@ public BaseResponse importPrivateKey(@Valid @RequestBody ReqImportPrivateKey req // add user row TbUser userRow = userService.addUserInfo(reqImport.getGroupId(), reqImport.getUserName(), reqImport.getAccount(), reqImport.getDescription(), reqImport.getUserType(), - privateKeyEncoded, ReturnPrivateKey.FALSE.getValue(), CheckUserExist.FALSE.getValue()); + privateKeyEncoded, ReturnPrivateKey.FALSE.getValue(), + CheckUserExist.FALSE.getValue()); baseResponse.setData(userRow); log.info("end importPrivateKey useTime:{} result:{}", @@ -493,7 +563,7 @@ public BaseResponse importP12PrivateKey(@RequestParam MultipartFile p12File, log.info("end importPemPrivateKey useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), JsonTools.toJSONString(baseResponse)); - return new BaseResponse(ConstantCode.SUCCESS); + return baseResponse; } /** @@ -545,7 +615,7 @@ public BaseResponse contractAddressSave(@RequestParam(required = true) String ap */ @GetMapping("dbInfo") public BaseResponse getDbInfo() { - log.info("getDbInfo:{}"); + log.info("getDbInfo."); return new BaseResponse(ConstantCode.SUCCESS, tableService.getDbInfo()); } } diff --git a/src/main/java/com/webank/webase/node/mgr/appintegration/api/DecryptRequestBodyAdvice.java b/src/main/java/com/webank/webase/node/mgr/appintegration/api/DecryptRequestBodyAdvice.java new file mode 100644 index 000000000..a37a86264 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/appintegration/api/DecryptRequestBodyAdvice.java @@ -0,0 +1,112 @@ +package com.webank.webase.node.mgr.appintegration.api; + +import com.webank.webase.node.mgr.appintegration.AppIntegrationService; +import com.webank.webase.node.mgr.appintegration.entity.TbAppInfo; +import com.webank.webase.node.mgr.base.code.ConstantCode; +import com.webank.webase.node.mgr.base.exception.NodeMgrException; +import com.webank.webase.node.mgr.base.properties.ConstantProperties; +import com.webank.webase.node.mgr.base.tools.AesUtils; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Type; +import java.nio.charset.Charset; +import java.util.Objects; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.MethodParameter; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.stereotype.Component; +import org.springframework.util.StreamUtils; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice; + +/** + * DecryptRequestBodyAdvice. + */ +@Slf4j +@Component +@ControllerAdvice(basePackages = "com.webank.webase.node.mgr.appintegration.api") +public class DecryptRequestBodyAdvice implements RequestBodyAdvice { + + @Autowired + private AppIntegrationService appIntegrationService; + @Autowired + private ConstantProperties cp; + + @Override + public boolean supports(MethodParameter methodParameter, Type type, + Class> aClass) { + return true; + } + + @Override + public Object handleEmptyBody(Object body, HttpInputMessage httpInputMessage, + MethodParameter methodParameter, Type type, + Class> aClass) { + return body; + } + + @Override + public Object afterBodyRead(Object body, HttpInputMessage httpInputMessage, + MethodParameter methodParameter, Type type, + Class> aClass) { + return body; + } + + @Override + public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, + MethodParameter methodParameter, Type type, + Class> aClass) throws IOException { + HttpHeaders headers = httpInputMessage.getHeaders(); + String isTransferEncrypt = headers.getFirst(ConstantProperties.PARAM_IS_TRANSFER_ENCRYPT); + log.debug("beforeBodyRead isTransferEncrypt:{}", isTransferEncrypt); + if (StringUtils.isBlank(isTransferEncrypt)) { + return httpInputMessage; + } + if (!isTransferEncrypt.equals(String.valueOf(cp.isTransferEncrypt()))) { + throw new NodeMgrException(ConstantCode.ENCRYPT_NOT_MATCH); + } + if (isTransferEncrypt.equals(ConstantProperties.ENCRYPT_FALSE)) { + return httpInputMessage; + } + String appKey = httpInputMessage.getHeaders().getFirst(ConstantProperties.PARAM_APP_KEY); + if (StringUtils.isBlank(appKey)) { + throw new NodeMgrException(ConstantCode.APPKEY_CANNOT_EMPTY); + } + TbAppInfo tbAppInfo = appIntegrationService.queryAppInfoByAppKey(appKey); + if (Objects.isNull(tbAppInfo)) { + throw new NodeMgrException(ConstantCode.APPKEY_NOT_EXISTS); + } + String bodyStr = + StreamUtils.copyToString(httpInputMessage.getBody(), Charset.forName("utf-8")); + byte[] body = + AesUtils.decrypt(bodyStr, tbAppInfo.getAppSecret().substring(0, 16)).getBytes(); + return new MyHttpInputMessage(headers, body); + } + + /** + * 自定义消息体,因为getBody()只能调一次,所以要重新封装一个可重复读的消息体 + */ + @AllArgsConstructor + public static class MyHttpInputMessage implements HttpInputMessage { + + private HttpHeaders headers; + + private byte[] body; + + @Override + public InputStream getBody() throws IOException { + return new ByteArrayInputStream(body); + } + + @Override + public HttpHeaders getHeaders() { + return headers; + } + } +} diff --git a/src/main/java/com/webank/webase/node/mgr/appintegration/api/EncryptResponseBodyAdvice.java b/src/main/java/com/webank/webase/node/mgr/appintegration/api/EncryptResponseBodyAdvice.java new file mode 100644 index 000000000..1eba8520c --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/appintegration/api/EncryptResponseBodyAdvice.java @@ -0,0 +1,72 @@ +package com.webank.webase.node.mgr.appintegration.api; + +import com.webank.webase.node.mgr.appintegration.AppIntegrationService; +import com.webank.webase.node.mgr.appintegration.entity.TbAppInfo; +import com.webank.webase.node.mgr.base.code.ConstantCode; +import com.webank.webase.node.mgr.base.exception.NodeMgrException; +import com.webank.webase.node.mgr.base.properties.ConstantProperties; +import com.webank.webase.node.mgr.base.tools.AesUtils; +import com.webank.webase.node.mgr.base.tools.JsonTools; +import java.util.Objects; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.MethodParameter; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; + +/** + * EncryptResponseBodyAdvice. + */ +@Slf4j +@Component +@ControllerAdvice(basePackages = "com.webank.webase.node.mgr.appintegration.api") +public class EncryptResponseBodyAdvice implements ResponseBodyAdvice { + + @Autowired + private AppIntegrationService appIntegrationService; + @Autowired + private ConstantProperties cp; + + @Override + public boolean supports(MethodParameter methodParameter, + Class> aClass) { + return true; + } + + @Override + public Object beforeBodyWrite(Object body, MethodParameter mp, MediaType mediaType, + Class> aClass, ServerHttpRequest serverHttpRequest, + ServerHttpResponse serverHttpResponse) { + String isTransferEncrypt = serverHttpRequest.getHeaders() + .getFirst(ConstantProperties.PARAM_IS_TRANSFER_ENCRYPT); + log.debug("beforeBodyWrite isTransferEncrypt:{}", isTransferEncrypt); + if (StringUtils.isBlank(isTransferEncrypt)) { + return body; + } + if (!isTransferEncrypt.equals(String.valueOf(cp.isTransferEncrypt()))) { + throw new NodeMgrException(ConstantCode.ENCRYPT_NOT_MATCH); + } + if (isTransferEncrypt.equals(ConstantProperties.ENCRYPT_FALSE)) { + return body; + } + + // encrypt response body + String appKey = serverHttpRequest.getHeaders().getFirst(ConstantProperties.PARAM_APP_KEY); + if (StringUtils.isBlank(appKey)) { + throw new NodeMgrException(ConstantCode.APPKEY_CANNOT_EMPTY); + } + TbAppInfo tbAppInfo = appIntegrationService.queryAppInfoByAppKey(appKey); + if (Objects.isNull(tbAppInfo)) { + throw new NodeMgrException(ConstantCode.APPKEY_NOT_EXISTS); + } + String content = JsonTools.toJSONString(body); + Object result = AesUtils.encrypt(content, tbAppInfo.getAppSecret().substring(0, 16)); + return result; + } +} diff --git a/src/main/java/com/webank/webase/node/mgr/appintegration/entity/UpdatePasswordInfo.java b/src/main/java/com/webank/webase/node/mgr/appintegration/entity/UpdatePasswordInfo.java new file mode 100644 index 000000000..db5094d16 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/appintegration/entity/UpdatePasswordInfo.java @@ -0,0 +1,30 @@ +/** + * Copyright 2014-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.webank.webase.node.mgr.appintegration.entity; + +import javax.validation.constraints.NotBlank; +import lombok.Data; + +/** + * entity to update password. + */ +@Data +public class UpdatePasswordInfo { + @NotBlank + private String account; + @NotBlank + private String oldAccountPwd; + @NotBlank + private String newAccountPwd; +} diff --git a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java index 05cf0ee76..bf6d907c5 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java +++ b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java @@ -311,6 +311,9 @@ public class ConstantCode { public static final RetCode TIMESTAMP_TIMEOUT = RetCode.mark(202524, "timestamp timeout"); public static final RetCode APPKEY_NOT_EXISTS = RetCode.mark(202525, "app key not exists"); public static final RetCode SIGNATURE_NOT_MATCH = RetCode.mark(202526, "signature not match"); + public static final RetCode REQUEST_ENCRYPT_FAIL = RetCode.mark(202527, "request encrypt fail"); + public static final RetCode REQUEST_DECRYPT_FAIL = RetCode.mark(202528, "request decrypt fail"); + public static final RetCode ENCRYPT_NOT_MATCH = RetCode.mark(202529, "isTransferEncrypt config not match"); // add in v1.5.1 public static final RetCode GENERATE_CONTRACT_PROJECT_FAIL = RetCode.mark(202531, "generate project failed in scaffold"); diff --git a/src/main/java/com/webank/webase/node/mgr/base/enums/AppStatus.java b/src/main/java/com/webank/webase/node/mgr/base/enums/AppStatus.java new file mode 100644 index 000000000..d886f1dd1 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/base/enums/AppStatus.java @@ -0,0 +1,44 @@ +/** + * Copyright 2014-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +/** + * Copyright 2014-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.webank.webase.node.mgr.base.enums; + +/** + * Enumeration of app status. + */ +public enum AppStatus { + UNREGISTER(0), NORMAL(1), INVALID(2); + + private int value; + + AppStatus(Integer dataStatus) { + this.value = dataStatus; + } + + public int getValue() { + return this.value; + } +} diff --git a/src/main/java/com/webank/webase/node/mgr/base/filter/AppIntegrationFilter.java b/src/main/java/com/webank/webase/node/mgr/base/filter/AppIntegrationFilter.java index 34e4148f2..637c23b17 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/filter/AppIntegrationFilter.java +++ b/src/main/java/com/webank/webase/node/mgr/base/filter/AppIntegrationFilter.java @@ -56,9 +56,9 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons * validate app request. */ private void validateAppRequest(HttpServletRequest request) { - String timestamp = request.getParameter("timestamp"); - String appKey = request.getParameter("appKey"); - String signature = request.getParameter("signature"); + String timestamp = request.getParameter(ConstantProperties.PARAM_TIMESTAMP); + String appKey = request.getParameter(ConstantProperties.PARAM_APP_KEY); + String signature = request.getParameter(ConstantProperties.PARAM_SIGNATURE); log.debug("validateAppRequest. timestamp:{} appKey:{} signature:{}", timestamp, appKey, signature); // check param diff --git a/src/main/java/com/webank/webase/node/mgr/base/filter/ValidateCodeFilter.java b/src/main/java/com/webank/webase/node/mgr/base/filter/ValidateCodeFilter.java index fb05d10fb..ad26b45bd 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/filter/ValidateCodeFilter.java +++ b/src/main/java/com/webank/webase/node/mgr/base/filter/ValidateCodeFilter.java @@ -44,7 +44,7 @@ public class ValidateCodeFilter implements Filter { @Autowired private TokenService tokenService; - @Autowired + private static final String LOGIN_URI = "/account/login"; private static final String LOGIN_METHOD = "post"; diff --git a/src/main/java/com/webank/webase/node/mgr/base/properties/ConstantProperties.java b/src/main/java/com/webank/webase/node/mgr/base/properties/ConstantProperties.java index 9478b5a8d..6e818ba31 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/properties/ConstantProperties.java +++ b/src/main/java/com/webank/webase/node/mgr/base/properties/ConstantProperties.java @@ -47,6 +47,13 @@ public class ConstantProperties { public static final int ADDRESS_LENGTH = 42; public static final String HAS_ROLE_ADMIN = "hasRole('admin')"; public static final String HAS_ROLE_ADMIN_OR_DEVELOPER = "hasRole('admin') or hasRole('developer')"; + + public static final String PARAM_APP_KEY = "appKey"; + public static final String PARAM_APP_SECRET = "appSecret"; + public static final String PARAM_TIMESTAMP = "timestamp"; + public static final String PARAM_SIGNATURE = "signature"; + public static final String PARAM_IS_TRANSFER_ENCRYPT = "isTransferEncrypt"; + public static final String ENCRYPT_FALSE = "false"; private boolean developerModeEnable = false; private boolean deployedModifyEnable = true; @@ -114,6 +121,7 @@ public class ConstantProperties { * application integration */ private long appRequestTimeOut = 300000; + private boolean isTransferEncrypt = true; /** * default resetGroupList interval gap, default 15000ms(15s) diff --git a/src/main/java/com/webank/webase/node/mgr/base/tools/AesUtils.java b/src/main/java/com/webank/webase/node/mgr/base/tools/AesUtils.java new file mode 100644 index 000000000..588b95606 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/base/tools/AesUtils.java @@ -0,0 +1,123 @@ +/* + * Copyright 2014-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.webank.webase.node.mgr.base.tools; + +import com.webank.webase.node.mgr.base.code.ConstantCode; +import com.webank.webase.node.mgr.base.exception.NodeMgrException; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import lombok.extern.log4j.Log4j2; + +/** + * Aes加解密工具 + */ +@Log4j2 +public class AesUtils { + + private static final String KEY_ALGORITHM = "AES"; + private static final String DEFAULT_IV = "abcdefgh12345678"; + private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";// 默认的加密算法 + + /** + * AES 加密操作 + * + * @param content 待加密内容 + * @param password 密码 + * @return 加密数据 + */ + public static String encrypt(String content, String aesKey) { + try { + // 创建密码器 + Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); + + // 密码key(超过16字节即128bit的key,需要替换jre中的local_policy.jar和US_export_policy.jar,否则报错:Illegal + // key size) + SecretKeySpec keySpec = + new SecretKeySpec(aesKey.getBytes(StandardCharsets.UTF_8), KEY_ALGORITHM); + + // 向量iv + IvParameterSpec ivParameterSpec = + new IvParameterSpec(DEFAULT_IV.getBytes(StandardCharsets.UTF_8)); + + // 初始化为加密模式的密码器 + cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec); + + // 加密 + byte[] byteContent = content.getBytes(StandardCharsets.UTF_8); + byte[] result = cipher.doFinal(byteContent); + + return Base64.getEncoder().encodeToString(result); + } catch (Exception ex) { + log.error("encrypt fail. content:{}", content, ex); + throw new NodeMgrException(ConstantCode.REQUEST_DECRYPT_FAIL); + } + } + + /** + * AES 解密操作 + * + * @param content 密文 + * @param aesKey 密码 + * @return 明文 + */ + public static String decrypt(String content, String aesKey) { + try { + // 创建密码器 + Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); + + // 密码key + SecretKeySpec keySpec = + new SecretKeySpec(aesKey.getBytes(StandardCharsets.UTF_8), KEY_ALGORITHM); + + // 向量iv + IvParameterSpec ivParameterSpec = + new IvParameterSpec(DEFAULT_IV.getBytes(StandardCharsets.UTF_8)); + + // 初始化为解密模式的密码器 + cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec); + + // 执行操作 + byte[] encrypted1 = Base64.getDecoder().decode(content); + byte[] result = cipher.doFinal(encrypted1); + + return new String(result, StandardCharsets.UTF_8); + } catch (Exception ex) { + log.error("decrypt fail. content:{}", content, ex); + throw new NodeMgrException(ConstantCode.REQUEST_ENCRYPT_FAIL); + } + } + + public static void main(String[] args) throws Exception { + Map map = new HashMap(); + map.put("key", "value"); + map.put("中文", "汉字"); + + String aesKey = "EfdsW23D23d3df43"; + + String content = JsonTools.toJSONString(map); + System.out.println("加密前:" + content); + + String encrypt = encrypt(content, aesKey); + System.out.println("加密后:" + encrypt); + + String decrypt = decrypt(encrypt, aesKey); + System.out.println("解密后:" + decrypt); + } + +} diff --git a/src/main/java/com/webank/webase/node/mgr/base/tools/JsonTools.java b/src/main/java/com/webank/webase/node/mgr/base/tools/JsonTools.java index d9d9fe051..ab163b43c 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/tools/JsonTools.java +++ b/src/main/java/com/webank/webase/node/mgr/base/tools/JsonTools.java @@ -15,15 +15,6 @@ */ package com.webank.webase.node.mgr.base.tools; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; - -import org.apache.commons.lang3.StringUtils; - import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonParser.Feature; import com.fasterxml.jackson.core.JsonProcessingException; @@ -33,8 +24,27 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; - +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; /** * Jackson Util @@ -42,7 +52,9 @@ */ @Slf4j public class JsonTools { - private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss"; + private static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; + private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; + private static final String DEFAULT_TIME_FORMAT = "HH:mm:ss"; /** * 设置一些通用的属性 */ @@ -61,7 +73,23 @@ public class JsonTools { // timestamp objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); // date format - objectMapper.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT)); + objectMapper.setDateFormat(new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT)); + // LocalDate format + JavaTimeModule javaTimeModule = new JavaTimeModule(); + javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer( + DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))); + javaTimeModule.addSerializer(LocalDate.class, + new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))); + javaTimeModule.addSerializer(LocalTime.class, + new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))); + javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer( + DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))); + javaTimeModule.addDeserializer(LocalDate.class, + new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))); + javaTimeModule.addDeserializer(LocalTime.class, + new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))); + objectMapper.registerModule(javaTimeModule).registerModule(new ParameterNamesModule()) + .registerModule(new Jdk8Module()); return objectMapper; }); diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractPathService.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractPathService.java index d27615fe5..6ca0e10fb 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractPathService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractPathService.java @@ -80,4 +80,13 @@ public int removeByPathName(ContractPathParam param) { public void removeByGroupId(Integer groupId) { contractPathMapper.removeByGroupId(groupId); } + + public boolean checkPathExist(Integer groupId, String pathName) { + TbContractPath contractPath = contractPathMapper.findOne(new ContractPathParam(groupId, pathName)); + if (contractPath != null) { + return true; + } else { + return false; + } + } } diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java index f3fdfc85d..fe3646968 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java @@ -173,6 +173,7 @@ public void appContractSave(String appKey, ReqContractAddressSave reqContractAdd reqContractAddressSave.getContractAddress()); String contractName = reqContractAddressSave.getContractName(); String contractVersion = reqContractAddressSave.getContractVersion(); + String contractPath = reqContractAddressSave.getContractPath(); // get contract store ContractStoreParam contractStoreParam = new ContractStoreParam(); contractStoreParam.setAppKey(appKey); @@ -182,10 +183,14 @@ public void appContractSave(String appKey, ReqContractAddressSave reqContractAdd if (CollectionUtils.isEmpty(listOfContractStore)) { throw new NodeMgrException(ConstantCode.CONTRACT_SOURCE_NOT_EXIST); } + boolean pathExist = contractPathService.checkPathExist(groupId, contractPath); for (TbContractStore tbContractStore : listOfContractStore) { - ContractParam param = - new ContractParam(groupId, reqContractAddressSave.getContractPath(), - tbContractStore.getContractName(), tbContractStore.getAccount()); + // check if tbContractStore has been saved + if (pathExist && !tbContractStore.getContractName().equals(contractName)) { + continue; + } + ContractParam param = new ContractParam(groupId, contractPath, + tbContractStore.getContractName(), tbContractStore.getAccount()); TbContract localContract = queryContract(param); // check if deployed contract saved if (Objects.nonNull(localContract) @@ -197,7 +202,7 @@ public void appContractSave(String appKey, ReqContractAddressSave reqContractAdd BeanUtils.copyProperties(tbContractStore, tbContract); tbContract.setGroupId(groupId); tbContract.setContractStatus(ContractStatus.NOTDEPLOYED.getValue()); - tbContract.setContractPath(reqContractAddressSave.getContractPath()); + tbContract.setContractPath(contractPath); tbContract.setContractType(ContractType.APPIMPORT.getValue()); if (tbContractStore.getContractName().equals(contractName)) { tbContract.setContractAddress(reqContractAddressSave.getContractAddress()); @@ -211,12 +216,12 @@ public void appContractSave(String appKey, ReqContractAddressSave reqContractAdd // save and update method NewMethodInputParam newMethodInputParam = new NewMethodInputParam(); newMethodInputParam.setGroupId(groupId); - newMethodInputParam - .setMethodList(Web3Tools.getMethodFromAbi(tbContractStore.getContractAbi(), cryptoSuite)); + newMethodInputParam.setMethodList( + Web3Tools.getMethodFromAbi(tbContractStore.getContractAbi(), cryptoSuite)); methodService.saveMethod(newMethodInputParam, ContractType.APPIMPORT.getValue()); } // if exist, auto not save (ignore) - contractPathService.save(groupId, reqContractAddressSave.getContractPath(), true); + contractPathService.save(groupId, contractPath, true); } /** diff --git a/src/main/java/com/webank/webase/node/mgr/role/RoleController.java b/src/main/java/com/webank/webase/node/mgr/role/RoleController.java index cad262545..419cee7f4 100644 --- a/src/main/java/com/webank/webase/node/mgr/role/RoleController.java +++ b/src/main/java/com/webank/webase/node/mgr/role/RoleController.java @@ -15,17 +15,12 @@ */ package com.webank.webase.node.mgr.role; -import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.entity.BasePageResponse; -import com.webank.webase.node.mgr.base.enums.RoleType; import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.base.properties.ConstantProperties; import com.webank.webase.node.mgr.base.tools.JsonTools; import java.time.Duration; import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; @@ -42,8 +37,6 @@ public class RoleController { @Autowired private RoleService roleService; - @Autowired - private ConstantProperties constantProperties; /** * query role list. @@ -55,30 +48,14 @@ public BasePageResponse queryRoleList( @RequestParam(value = "roleId", required = false) Integer roleId, @RequestParam(value = "roleName", required = false) String roleName) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info( "start queryRoleList. startTime:{} pageNumber:{} pageSize:{} roleId:{} roleName:{}", startTime.toEpochMilli(), pageNumber, pageSize, roleId, roleName); - // param - Integer realPageSize = Optional.ofNullable(pageSize).orElse(5); - Integer start = Optional.ofNullable(pageNumber) - .map(page -> (page - 1) * realPageSize).orElse(0); - List roleIdListNotIn = new ArrayList<>(); - if (!constantProperties.isDeveloperModeEnable()) { - roleIdListNotIn.add(RoleType.DEVELOPER.getValue()); - } - RoleListParam param = new RoleListParam(start, realPageSize, roleId, roleName, roleIdListNotIn); - // query - int count = roleService.countOfRole(param); - if (count > 0) { - List listOfRole = roleService.listOfRole(param); - pagesponse.setData(listOfRole); - pagesponse.setTotalCount(count); - } + BasePageResponse pagesponse = roleService.queryRoleList(pageNumber, pageSize, roleId, roleName); log.info("end queryRoleList useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), diff --git a/src/main/java/com/webank/webase/node/mgr/role/RoleService.java b/src/main/java/com/webank/webase/node/mgr/role/RoleService.java index fabfba7cd..9a9723aa6 100644 --- a/src/main/java/com/webank/webase/node/mgr/role/RoleService.java +++ b/src/main/java/com/webank/webase/node/mgr/role/RoleService.java @@ -15,10 +15,15 @@ */ package com.webank.webase.node.mgr.role; -import com.webank.webase.node.mgr.base.tools.JsonTools; import com.webank.webase.node.mgr.base.code.ConstantCode; +import com.webank.webase.node.mgr.base.entity.BasePageResponse; +import com.webank.webase.node.mgr.base.enums.RoleType; import com.webank.webase.node.mgr.base.exception.NodeMgrException; +import com.webank.webase.node.mgr.base.properties.ConstantProperties; +import com.webank.webase.node.mgr.base.tools.JsonTools; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -32,6 +37,34 @@ public class RoleService { @Autowired private RoleMapper roleMapper; + @Autowired + private ConstantProperties constantProperties; + + public BasePageResponse queryRoleList(Integer pageNumber, Integer pageSize, Integer roleId, + String roleName) throws NodeMgrException { + BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + + // param + Integer realPageSize = Optional.ofNullable(pageSize).orElse(10); + Integer start = + Optional.ofNullable(pageNumber).map(page -> (page - 1) * realPageSize).orElse(0); + List roleIdListNotIn = new ArrayList<>(); + if (!constantProperties.isDeveloperModeEnable()) { + roleIdListNotIn.add(RoleType.DEVELOPER.getValue()); + } + RoleListParam param = + new RoleListParam(start, realPageSize, roleId, roleName, roleIdListNotIn); + + // query + int count = countOfRole(param); + if (count > 0) { + List listOfRole = listOfRole(param); + pagesponse.setData(listOfRole); + pagesponse.setTotalCount(count); + } + + return pagesponse; + } /** * query role count. diff --git a/src/main/resources/mapper/AppInfoMapper.xml b/src/main/resources/mapper/AppInfoMapper.xml index 5af9ba0e3..956beeda6 100644 --- a/src/main/resources/mapper/AppInfoMapper.xml +++ b/src/main/resources/mapper/AppInfoMapper.xml @@ -37,8 +37,8 @@ - INSERT INTO tb_app_info(app_name,app_key,app_secret,app_doc_link,app_icon,app_desc,app_detail,create_time,modify_time) - VALUES (#{appName},#{appKey},#{appSecret},#{appDocLink},#{appIcon},#{appDesc},#{appDetail},now(),now()) + INSERT INTO tb_app_info(app_name,app_key,app_secret,app_doc_link,app_icon,app_desc,app_status,app_detail,create_time,modify_time) + VALUES (#{appName},#{appKey},#{appSecret},#{appDocLink},#{appIcon},#{appDesc},#{appStatus},#{appDetail},now(),now()) SELECT LAST_INSERT_ID() From 59aefdbffa5082c31acbf34a27312503d22bdf9d Mon Sep 17 00:00:00 2001 From: Sayou1989 Date: Mon, 10 May 2021 14:44:55 +0800 Subject: [PATCH 41/92] pagesponse change to pageResponse --- .../node/mgr/account/AccountController.java | 10 ++-- .../AppIntegrationController.java | 8 +-- .../appintegration/api/AppIntegrationApi.java | 56 +++++++++---------- .../node/mgr/contract/ContractController.java | 48 ++++++++-------- .../node/mgr/front/FrontController.java | 10 ++-- .../node/mgr/group/GroupController.java | 32 +++++------ .../node/mgr/monitor/MonitorController.java | 20 +++---- .../webase/node/mgr/node/NodeController.java | 10 ++-- .../webase/node/mgr/role/RoleController.java | 6 +- .../webase/node/mgr/role/RoleService.java | 8 +-- .../webase/node/mgr/user/UserController.java | 10 ++-- 11 files changed, 109 insertions(+), 109 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/account/AccountController.java b/src/main/java/com/webank/webase/node/mgr/account/AccountController.java index df391b39c..96b3ac159 100644 --- a/src/main/java/com/webank/webase/node/mgr/account/AccountController.java +++ b/src/main/java/com/webank/webase/node/mgr/account/AccountController.java @@ -162,7 +162,7 @@ public BaseResponse updateAccountInfo(@RequestBody @Valid AccountInfo info, Http public BasePageResponse queryAccountList(@PathVariable("pageNumber") Integer pageNumber, @PathVariable("pageSize") Integer pageSize, @RequestParam(value = "account", required = false) String account) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start queryAccountList. startTime:{} pageNumber:{} pageSize:{}", startTime.toEpochMilli(), pageNumber, pageSize); @@ -175,13 +175,13 @@ public BasePageResponse queryAccountList(@PathVariable("pageNumber") Integer pag SqlSortType.DESC.getValue()); List listOfAccount = accountService.listOfAccount(param); listOfAccount.stream().forEach(accountData -> accountData.setAccountPwd(null)); - pagesponse.setData(listOfAccount); - pagesponse.setTotalCount(count); + pageResponse.setData(listOfAccount); + pageResponse.setTotalCount(count); } log.info("end queryAccountList useTime:{} result:{}", - Duration.between(startTime, Instant.now()).toMillis(), JsonTools.toJSONString(pagesponse)); - return pagesponse; + Duration.between(startTime, Instant.now()).toMillis(), JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** diff --git a/src/main/java/com/webank/webase/node/mgr/appintegration/AppIntegrationController.java b/src/main/java/com/webank/webase/node/mgr/appintegration/AppIntegrationController.java index 38385b951..ada40c2c3 100644 --- a/src/main/java/com/webank/webase/node/mgr/appintegration/AppIntegrationController.java +++ b/src/main/java/com/webank/webase/node/mgr/appintegration/AppIntegrationController.java @@ -76,7 +76,7 @@ public BaseResponse saveApp(@RequestBody @Valid AppAddInfo appAddInfo, BindingRe public BasePageResponse queryAppList(@RequestParam(required = false) Integer appType, @RequestParam(required = false) String appName, @RequestParam(required = false) String appKey) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start queryAppList startTime:{} appName:{},appKey:{}", startTime.toEpochMilli(), appName, appKey); @@ -92,15 +92,15 @@ public BasePageResponse queryAppList(@RequestParam(required = false) Integer app } // query app info int count = appIntegrationService.countOfAppInfo(param); - pagesponse.setTotalCount(count); + pageResponse.setTotalCount(count); if (count > 0) { List list = appIntegrationService.listOfAppInfo(param); - pagesponse.setData(list); + pageResponse.setData(list); } log.info("end queryAppList useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); - return pagesponse; + return pageResponse; } /** diff --git a/src/main/java/com/webank/webase/node/mgr/appintegration/api/AppIntegrationApi.java b/src/main/java/com/webank/webase/node/mgr/appintegration/api/AppIntegrationApi.java index f86f840ac..5c7add9e3 100644 --- a/src/main/java/com/webank/webase/node/mgr/appintegration/api/AppIntegrationApi.java +++ b/src/main/java/com/webank/webase/node/mgr/appintegration/api/AppIntegrationApi.java @@ -138,7 +138,7 @@ public BaseResponse appRegister(@RequestParam(required = true) String appKey, public BasePageResponse queryAccountList(@RequestParam(required = true) Integer pageNumber, @RequestParam(required = true) Integer pageSize, @RequestParam(required = false) String account) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start queryAccountList. startTime:{} pageNumber:{} pageSize:{}", startTime.toEpochMilli(), pageNumber, pageSize); @@ -151,14 +151,14 @@ public BasePageResponse queryAccountList(@RequestParam(required = true) Integer new AccountListParam(start, pageSize, account, SqlSortType.DESC.getValue()); List listOfAccount = accountService.listOfAccount(param); listOfAccount.stream().forEach(accountData -> accountData.setAccountPwd(null)); - pagesponse.setData(listOfAccount); - pagesponse.setTotalCount(count); + pageResponse.setData(listOfAccount); + pageResponse.setTotalCount(count); } log.info("end queryAccountList useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), - JsonTools.toJSONString(pagesponse)); - return pagesponse; + JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** @@ -170,12 +170,12 @@ public BasePageResponse queryRoleList() throws NodeMgrException { log.info("start queryRoleList.", startTime.toEpochMilli()); // query - BasePageResponse pagesponse = roleService.queryRoleList(null, null, null, null); + BasePageResponse pageResponse = roleService.queryRoleList(null, null, null, null); log.info("end queryRoleList useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), - JsonTools.toJSONString(pagesponse)); - return pagesponse; + JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** @@ -255,7 +255,7 @@ public BaseResponse getEncryptType() { public BasePageResponse getGroupList( @RequestParam(required = false, defaultValue = "1") Integer groupStatus) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start getGroupList startTime:{}", startTime.toEpochMilli()); @@ -268,14 +268,14 @@ public BasePageResponse getGroupList( int count = groupService.countOfGroup(null, groupStatus); if (count > 0) { List groupList = groupService.getGroupList(groupStatus); - pagesponse.setTotalCount(count); - pagesponse.setData(groupList); + pageResponse.setTotalCount(count); + pageResponse.setData(groupList); } log.info("end getGroupList useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), - JsonTools.toJSONString(pagesponse)); - return pagesponse; + JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** @@ -286,7 +286,7 @@ public BasePageResponse queryNodeList(@RequestParam(required = true) Integer pag @RequestParam(required = true) Integer pageSize, @RequestParam(required = false, defaultValue = "") Integer groupId, @RequestParam(required = false) String nodeId) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start queryNodeList startTime:{}", startTime.toEpochMilli()); @@ -309,15 +309,15 @@ public BasePageResponse queryNodeList(@RequestParam(required = true) Integer pag queryParam.setStart(start); List listOfnode = nodeService.queryNodeList(queryParam); - pagesponse.setData(listOfnode); - pagesponse.setTotalCount(count); + pageResponse.setData(listOfnode); + pageResponse.setTotalCount(count); } log.info("end queryNodeList useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), - JsonTools.toJSONString(pagesponse)); - return pagesponse; + JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** @@ -353,7 +353,7 @@ public BaseResponse getNodeInfo(@RequestParam(required = true) Integer groupId, @GetMapping(value = "/frontNodeList") public BasePageResponse queryFrontList(@RequestParam(required = false) Integer groupId, @RequestParam(required = false) String nodeId) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start queryFrontList startTime:{} groupId:{},nodeId:{}", startTime.toEpochMilli(), groupId, nodeId); @@ -365,18 +365,18 @@ public BasePageResponse queryFrontList(@RequestParam(required = false) Integer g // query front info int count = frontService.getFrontCount(param); - pagesponse.setTotalCount(count); + pageResponse.setTotalCount(count); if (count > 0) { List list = frontService.getFrontList(param); list.forEach(front -> front.setGroupList( frontGroupMapService.getGroupIdListByFrontId(front.getFrontId()))); - pagesponse.setData(list); + pageResponse.setData(list); } log.info("end queryFrontList useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), - JsonTools.toJSONString(pagesponse)); - return pagesponse; + JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** @@ -450,7 +450,7 @@ public BasePageResponse userList(@RequestParam(required = true) Integer groupId, @RequestParam(required = false) String userParam, @RequestParam(required = false, defaultValue = "") Integer hasPrivateKey) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start userList startTime:{} groupId:{} pageNumber:{} pageSize:{} userParam:{}", startTime.toEpochMilli(), groupId, pageNumber, pageSize, userParam); @@ -470,14 +470,14 @@ public BasePageResponse userList(@RequestParam(required = true) Integer groupId, param.setPageSize(pageSize); List listOfUser = userService.queryUserList(param); - pagesponse.setData(listOfUser); - pagesponse.setTotalCount(count); + pageResponse.setData(listOfUser); + pageResponse.setTotalCount(count); } log.info("end userList useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), - JsonTools.toJSONString(pagesponse)); - return pagesponse; + JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java index 79ec77485..3d4fccdc9 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java @@ -126,7 +126,7 @@ public BaseResponse deleteContract(@PathVariable("groupId") Integer groupId, @PostMapping(value = "/contractList") public BasePageResponse queryContractList(@RequestBody QueryContractParam inputParam) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start contractList. startTime:{} inputParam:{}", startTime.toEpochMilli(), JsonTools.toJSONString(inputParam)); @@ -144,13 +144,13 @@ public BasePageResponse queryContractList(@RequestBody QueryContractParam inputP // query list List listOfContract = contractService.queryContractList(queryParam); - pagesponse.setData(listOfContract); - pagesponse.setTotalCount(count); + pageResponse.setData(listOfContract); + pageResponse.setTotalCount(count); } log.info("end contractList. useTime:{} result count:{}", Duration.between(startTime, Instant.now()).toMillis(), count); - return pagesponse; + return pageResponse; } /** @@ -259,7 +259,7 @@ public BaseResponse getByPartOfByecodebin(@RequestBody @Valid QueryByBinParam qu @GetMapping(value = "/contractList/all/light") public BasePageResponse queryContractListNoAbi(@RequestParam Integer groupId, @RequestParam Integer contractStatus) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start queryContractListNoAbi. startTime:{} groupId:{}", startTime.toEpochMilli(), groupId); @@ -274,13 +274,13 @@ public BasePageResponse queryContractListNoAbi(@RequestParam Integer groupId, // query list List listOfContract = contractService.queryContractListNoAbi(queryParam); - pagesponse.setData(listOfContract); - pagesponse.setTotalCount(count); + pageResponse.setData(listOfContract); + pageResponse.setTotalCount(count); } log.info("end queryContractListNoAbi. useTime:{} result count:{}", Duration.between(startTime, Instant.now()).toMillis(), count); - return pagesponse; + return pageResponse; } @@ -312,19 +312,19 @@ public BaseResponse addContractPath(@Valid @RequestBody ContractPathParam param) */ @PostMapping(value = "/contractPath/list/{groupId}") public BasePageResponse queryContractPathList(@PathVariable("groupId") Integer groupId) { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start queryContractPathList. startTime:{} groupId:{}", startTime.toEpochMilli(), groupId); List result = contractService.queryContractPathList(groupId); - pagesponse.setData(result); - pagesponse.setTotalCount(result.size()); + pageResponse.setData(result); + pageResponse.setTotalCount(result.size()); log.info("end queryContractPathList. useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), - JsonTools.toJSONString(pagesponse)); - return pagesponse; + JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** @@ -351,16 +351,16 @@ public BaseResponse deleteContractByPath(@Valid @RequestBody ContractPathParam p @PostMapping(value = "/contractList/multiPath") public BasePageResponse listContractByMultiPath(@RequestBody ReqListContract inputParam) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start listContractByMultiPath. startTime:{} inputParam:{}", startTime.toEpochMilli(), JsonTools.toJSONString(inputParam)); List contractList = contractService.queryContractListMultiPath(inputParam); - pagesponse.setTotalCount(contractList.size()); - pagesponse.setData(contractList); + pageResponse.setTotalCount(contractList.size()); + pageResponse.setData(contractList); log.info("end listContractByMultiPath. useTime:{} result count:{}", Duration.between(startTime, Instant.now()).toMillis(), contractList.size()); - return pagesponse; + return pageResponse; } /** @@ -390,15 +390,15 @@ public BaseResponse registerCns(@RequestBody @Valid ReqRegisterCns reqRegisterCn public BaseResponse findCnsByAddress(@RequestBody @Valid ReqQueryCns reqQueryCns, BindingResult result) throws NodeMgrException { checkBindResult(result); - BaseResponse pagesponse = new BaseResponse(ConstantCode.SUCCESS); + BaseResponse pageResponse = new BaseResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start findCnsByAddress startTime:{} reqQueryCns:{}", startTime.toEpochMilli(), JsonTools.toJSONString(reqQueryCns)); TbCns tbCns = cnsService.getCnsByAddress( new QueryCnsParam(reqQueryCns.getGroupId(), reqQueryCns.getContractAddress())); - pagesponse.setData(tbCns); + pageResponse.setData(tbCns); log.info("end findCnsByAddress. useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); - return pagesponse; + return pageResponse; } /** @@ -408,7 +408,7 @@ public BaseResponse findCnsByAddress(@RequestBody @Valid ReqQueryCns reqQueryCns public BasePageResponse findCnsList(@RequestBody @Valid ReqQueryCnsList inputParam, BindingResult result) throws NodeMgrException { checkBindResult(result); - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start findCnsList startTime:{} reqQueryCns:{}", startTime.toEpochMilli(), JsonTools.toJSONString(inputParam)); @@ -425,13 +425,13 @@ public BasePageResponse findCnsList(@RequestBody @Valid ReqQueryCnsList inputPar queryParam.setFlagSortedByTime(SqlSortType.DESC.getValue()); // query list List listOfCns = cnsService.getList(queryParam); - pagesponse.setData(listOfCns); - pagesponse.setTotalCount(count); + pageResponse.setData(listOfCns); + pageResponse.setTotalCount(count); } log.info("end findCnsList. useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); - return pagesponse; + return pageResponse; } @PostMapping(value = "/copy") diff --git a/src/main/java/com/webank/webase/node/mgr/front/FrontController.java b/src/main/java/com/webank/webase/node/mgr/front/FrontController.java index c603b2985..f7fd3dbe6 100644 --- a/src/main/java/com/webank/webase/node/mgr/front/FrontController.java +++ b/src/main/java/com/webank/webase/node/mgr/front/FrontController.java @@ -93,7 +93,7 @@ public BasePageResponse queryFrontList( @RequestParam(value = "groupId", required = false) Integer groupId, @RequestParam(value = "frontStatus", required = false) Integer frontStatus) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start queryFrontList startTime:{} frontId:{} groupId:{},frontStatus:{}", startTime.toEpochMilli(), frontId, groupId, frontStatus); @@ -106,15 +106,15 @@ public BasePageResponse queryFrontList( //query front info int count = frontService.getFrontCount(param); - pagesponse.setTotalCount(count); + pageResponse.setTotalCount(count); if (count > 0) { List list = frontService.getFrontList(param); - pagesponse.setData(list); + pageResponse.setData(list); } log.info("end queryFrontList useTime:{} result:{}", - Duration.between(startTime, Instant.now()).toMillis(), JsonTools.toJSONString(pagesponse)); - return pagesponse; + Duration.between(startTime, Instant.now()).toMillis(), JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** diff --git a/src/main/java/com/webank/webase/node/mgr/group/GroupController.java b/src/main/java/com/webank/webase/node/mgr/group/GroupController.java index b595cc25d..16571b4d2 100644 --- a/src/main/java/com/webank/webase/node/mgr/group/GroupController.java +++ b/src/main/java/com/webank/webase/node/mgr/group/GroupController.java @@ -111,7 +111,7 @@ public BaseResponse getGroupGeneral(@PathVariable("groupId") Integer groupId) */ @GetMapping("/all") public BasePageResponse getAllGroup() throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start getAllGroup startTime:{}", startTime.toEpochMilli()); @@ -119,8 +119,8 @@ public BasePageResponse getAllGroup() throws NodeMgrException { int count = groupService.countOfGroup(null, GroupStatus.NORMAL.getValue()); if (count > 0) { List groupList = groupService.getGroupList(GroupStatus.NORMAL.getValue()); - pagesponse.setTotalCount(count); - pagesponse.setData(groupList); + pageResponse.setTotalCount(count); + pageResponse.setData(groupList); } // reset group @@ -128,8 +128,8 @@ public BasePageResponse getAllGroup() throws NodeMgrException { log.info("end getAllGroup useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), - JsonTools.toJSONString(pagesponse)); - return pagesponse; + JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** @@ -143,7 +143,7 @@ public BasePageResponse getAllGroup() throws NodeMgrException { "/all/invalidIncluded"}) public BasePageResponse getAllGroupIncludeInvalidGroup(@PathVariable(value = "pageNumber",required = false) Integer pageNumber, @PathVariable(value = "pageSize", required = false) Integer pageSize) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start getAllGroupIncludeInvalidGroup startTime:{}", startTime.toEpochMilli()); @@ -152,12 +152,12 @@ public BasePageResponse getAllGroupIncludeInvalidGroup(@PathVariable(value = "pa if (count > 0) { List groupList = groupService.getGroupList(null); if (pageNumber == null && pageSize == null) { - pagesponse.setData(groupList); - pagesponse.setTotalCount(count); + pageResponse.setData(groupList); + pageResponse.setTotalCount(count); } else { List2Page list2Page = new List2Page(groupList, pageSize, pageNumber); - pagesponse.setData(list2Page.getPagedList()); - pagesponse.setTotalCount(count); + pageResponse.setData(list2Page.getPagedList()); + pageResponse.setTotalCount(count); } } // reset group @@ -165,8 +165,8 @@ public BasePageResponse getAllGroupIncludeInvalidGroup(@PathVariable(value = "pa log.info("end getAllGroupIncludeInvalidGroup useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), - JsonTools.toJSONString(pagesponse)); - return pagesponse; + JsonTools.toJSONString(pageResponse)); + return pageResponse; } @GetMapping("/all/{groupStatus}") @@ -200,18 +200,18 @@ public BaseResponse getAllGroupOfStatus(@PathVariable("groupStatus") Integer gro */ @GetMapping("/transDaily/{groupId}") public BaseResponse getTransDaily(@PathVariable("groupId") Integer groupId) throws Exception { - BaseResponse pagesponse = new BaseResponse(ConstantCode.SUCCESS); + BaseResponse pageResponse = new BaseResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start getTransDaily startTime:{} groupId:{}", startTime.toEpochMilli(), groupId); // query trans daily List listTrans = transDailyService.listSeventDayOfTrans(groupId); - pagesponse.setData(listTrans); + pageResponse.setData(listTrans); log.info("end getAllGroup useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), - JsonTools.toJSONString(pagesponse)); - return pagesponse; + JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** diff --git a/src/main/java/com/webank/webase/node/mgr/monitor/MonitorController.java b/src/main/java/com/webank/webase/node/mgr/monitor/MonitorController.java index 00277b325..fe8c07746 100644 --- a/src/main/java/com/webank/webase/node/mgr/monitor/MonitorController.java +++ b/src/main/java/com/webank/webase/node/mgr/monitor/MonitorController.java @@ -115,7 +115,7 @@ public BasePageResponse unusualUserList(@PathVariable("groupId") Integer groupId @PathVariable("pageSize") Integer pageSize, @RequestParam(value = "userName", required = false) String userName) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info( "start unusualUserList startTime:{} groupId:{} pageNumber:{} pageSize:{}" @@ -127,13 +127,13 @@ public BasePageResponse unusualUserList(@PathVariable("groupId") Integer groupId if (count != null && count > 0) { List listOfUnusualUser = monitorService .queryUnusualUserList(groupId, userName, pageNumber, pageSize); - pagesponse.setData(listOfUnusualUser); - pagesponse.setTotalCount(count); + pageResponse.setData(listOfUnusualUser); + pageResponse.setTotalCount(count); } log.info("end unusualUserList useTime:{} result:{}", - Duration.between(startTime, Instant.now()).toMillis(), JsonTools.toJSONString(pagesponse)); - return pagesponse; + Duration.between(startTime, Instant.now()).toMillis(), JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** @@ -145,7 +145,7 @@ public BasePageResponse unusualContractList(@PathVariable("groupId") Integer gro @PathVariable("pageSize") Integer pageSize, @RequestParam(value = "contractAddress", required = false) String contractAddress) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info( "start unusualContractList startTime:{} groupId:{} pageNumber:{}" @@ -157,12 +157,12 @@ public BasePageResponse unusualContractList(@PathVariable("groupId") Integer gro if (count != null && count > 0) { List listOfUnusualContract = monitorService .queryUnusualContractList(groupId, contractAddress, pageNumber, pageSize); - pagesponse.setData(listOfUnusualContract); - pagesponse.setTotalCount(count); + pageResponse.setData(listOfUnusualContract); + pageResponse.setTotalCount(count); } log.info("end unusualContractList useTime:{} result:{}", - Duration.between(startTime, Instant.now()).toMillis(), JsonTools.toJSONString(pagesponse)); - return pagesponse; + Duration.between(startTime, Instant.now()).toMillis(), JsonTools.toJSONString(pageResponse)); + return pageResponse; } } diff --git a/src/main/java/com/webank/webase/node/mgr/node/NodeController.java b/src/main/java/com/webank/webase/node/mgr/node/NodeController.java index 955f4d37d..a664c315c 100644 --- a/src/main/java/com/webank/webase/node/mgr/node/NodeController.java +++ b/src/main/java/com/webank/webase/node/mgr/node/NodeController.java @@ -54,7 +54,7 @@ public BasePageResponse queryNodeList(@PathVariable("groupId") Integer groupId, @PathVariable("pageSize") Integer pageSize, @RequestParam(value = "nodeName", required = false) String nodeName) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info( "start queryNodeList startTime:{} groupId:{} pageNumber:{} pageSize:{} nodeName:{}", @@ -80,14 +80,14 @@ public BasePageResponse queryNodeList(@PathVariable("groupId") Integer groupId, queryParam.setStart(start); List listOfnode = nodeService.queryNodeList(queryParam); - pagesponse.setData(listOfnode); - pagesponse.setTotalCount(count); + pageResponse.setData(listOfnode); + pageResponse.setTotalCount(count); } log.info("end queryNodeList useTime:{} result:{}", - Duration.between(startTime, Instant.now()).toMillis(), JsonTools.toJSONString(pagesponse)); - return pagesponse; + Duration.between(startTime, Instant.now()).toMillis(), JsonTools.toJSONString(pageResponse)); + return pageResponse; } /** diff --git a/src/main/java/com/webank/webase/node/mgr/role/RoleController.java b/src/main/java/com/webank/webase/node/mgr/role/RoleController.java index 419cee7f4..e0fa5ccd6 100644 --- a/src/main/java/com/webank/webase/node/mgr/role/RoleController.java +++ b/src/main/java/com/webank/webase/node/mgr/role/RoleController.java @@ -55,11 +55,11 @@ public BasePageResponse queryRoleList( pageNumber, pageSize, roleId, roleName); // query - BasePageResponse pagesponse = roleService.queryRoleList(pageNumber, pageSize, roleId, roleName); + BasePageResponse pageResponse = roleService.queryRoleList(pageNumber, pageSize, roleId, roleName); log.info("end queryRoleList useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), - JsonTools.toJSONString(pagesponse)); - return pagesponse; + JsonTools.toJSONString(pageResponse)); + return pageResponse; } } diff --git a/src/main/java/com/webank/webase/node/mgr/role/RoleService.java b/src/main/java/com/webank/webase/node/mgr/role/RoleService.java index 9a9723aa6..35119fd75 100644 --- a/src/main/java/com/webank/webase/node/mgr/role/RoleService.java +++ b/src/main/java/com/webank/webase/node/mgr/role/RoleService.java @@ -42,7 +42,7 @@ public class RoleService { public BasePageResponse queryRoleList(Integer pageNumber, Integer pageSize, Integer roleId, String roleName) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); // param Integer realPageSize = Optional.ofNullable(pageSize).orElse(10); @@ -59,11 +59,11 @@ public BasePageResponse queryRoleList(Integer pageNumber, Integer pageSize, Inte int count = countOfRole(param); if (count > 0) { List listOfRole = listOfRole(param); - pagesponse.setData(listOfRole); - pagesponse.setTotalCount(count); + pageResponse.setData(listOfRole); + pageResponse.setTotalCount(count); } - return pagesponse; + return pageResponse; } /** diff --git a/src/main/java/com/webank/webase/node/mgr/user/UserController.java b/src/main/java/com/webank/webase/node/mgr/user/UserController.java index ee5ec8846..7c6b63322 100644 --- a/src/main/java/com/webank/webase/node/mgr/user/UserController.java +++ b/src/main/java/com/webank/webase/node/mgr/user/UserController.java @@ -145,7 +145,7 @@ public BasePageResponse userList(@PathVariable("groupId") Integer groupId, @RequestParam(value = "account", required = false) String account, @RequestParam(value = "userParam", required = false) String commParam) throws NodeMgrException { - BasePageResponse pagesponse = new BasePageResponse(ConstantCode.SUCCESS); + BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start userList startTime:{} groupId:{} pageNumber:{} pageSize:{} commParam:{}", startTime.toEpochMilli(), groupId, pageNumber, pageSize, commParam); @@ -164,14 +164,14 @@ public BasePageResponse userList(@PathVariable("groupId") Integer groupId, param.setPageSize(pageSize); List listOfUser = userService.queryUserList(param); - pagesponse.setData(listOfUser); - pagesponse.setTotalCount(count); + pageResponse.setData(listOfUser); + pageResponse.setTotalCount(count); } log.info("end userList useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), - JsonTools.toJSONString(pagesponse)); - return pagesponse; + JsonTools.toJSONString(pageResponse)); + return pageResponse; } @PostMapping("/import") From 17a0aa1cf8ca9d44ad888ff1f1ece925c32300bc Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Wed, 12 May 2021 11:40:11 +0800 Subject: [PATCH 42/92] fix contract get & updat ecode --- .../com/webank/webase/node/mgr/base/code/ConstantCode.java | 3 +-- .../com/webank/webase/node/mgr/contract/ContractService.java | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java index 05cf0ee76..d2ba6c6c7 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java +++ b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java @@ -244,7 +244,7 @@ public class ConstantCode { public static final RetCode GENERATE_FRONT_YML_ERROR = RetCode.mark(202458, "Generate front application.yml file failed."); public static final RetCode EXEC_HOST_INIT_SCRIPT_ERROR = RetCode.mark(202459, "Exec host init script failed."); public static final RetCode TRANSFER_FILES_ERROR = RetCode.mark(202460, "Transfer files error."); - public static final RetCode DOCKER_OPERATION_ERROR = RetCode.mark(202461, "Docker option error."); + public static final RetCode HOST_ONLY_ALL_LOCALHOST_OR_NOT_LOCALHOST = RetCode.mark(202461, "Host must be all localhost(127.0.0.1) or all non-localhost"); public static final RetCode TWO_NODES_AT_LEAST = RetCode.mark(202462, "Two nodes at least."); public static final RetCode TWO_SEALER_IN_GROUP_AT_LEAST = RetCode.mark(202463, "Group need two sealers at least."); public static final RetCode WEBASE_SIGN_CONFIG_ERROR = RetCode.mark(202464, "Please check webaseSignAddress in application.yml file."); @@ -252,7 +252,6 @@ public class ConstantCode { public static final RetCode IMAGE_NOT_EXISTS_ON_HOST = RetCode.mark(202466, "Image not exists on host."); public static final RetCode NODES_NUM_EXCEED_MAX_ERROR = RetCode.mark(202467, "Max 4 nodes on a same host."); public static final RetCode SAME_HOST_ERROR = RetCode.mark(202468, "Host of WeBASE-Node-Manager's ip is already existed."); - public static final RetCode HOST_ONLY_ALL_LOCALHOST_OR_NOT_LOCALHOST = RetCode.mark(202469, "Host must be all localhost(127.0.0.1) or all non-localhost"); // add in 1.4.3 public static final RetCode EXEC_DOCKER_CHECK_SCRIPT_ERROR = RetCode.mark(202469, "Check docker installed and running of host"); public static final RetCode EXEC_HOST_CHECK_SCRIPT_ERROR_FOR_MEM = RetCode.mark(202470, "Check host memory not enough for nodes(s)"); diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java index f3fdfc85d..5fae16da6 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java @@ -226,7 +226,7 @@ private TbContract updateContract(Contract contract) { // check contract id TbContract tbContract = verifyContractIdExist(contract.getContractId(), contract.getGroupId()); - if (tbContract.getContractType() == ContractStatus.DEPLOYED.getValue() + if (tbContract.getContractStatus() == ContractStatus.DEPLOYED.getValue() && !constantProperties.isDeployedModifyEnable()) { log.info("fail updateContract. deployed contract cannot be modified"); throw new NodeMgrException(ConstantCode.DEPLOYED_CANNOT_MODIFIED); @@ -351,7 +351,7 @@ public TbContract deployContract(DeployInputParam inputParam) throws NodeMgrExce // check contract TbContract contractRecord = verifyContractIdExist(inputParam.getContractId(), inputParam.getGroupId()); - if (contractRecord.getContractType() == ContractStatus.DEPLOYED.getValue() + if (contractRecord.getContractStatus() == ContractStatus.DEPLOYED.getValue() && !constantProperties.isDeployedModifyEnable()) { log.info("fail deployContract. deployed contract cannot be modified"); throw new NodeMgrException(ConstantCode.DEPLOYED_CANNOT_MODIFIED); From f02459a70822e54c69393182df4a014c0a970373 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Wed, 12 May 2021 11:40:24 +0800 Subject: [PATCH 43/92] v1.5.1 --- release_note.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release_note.txt b/release_note.txt index 8f450fca4..c14cbb80e 100644 --- a/release_note.txt +++ b/release_note.txt @@ -1 +1 @@ - v1.5.0 + v1.5.1 From 8a9fd7b640954eb2b092708f6119275189fbb7f5 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Wed, 12 May 2021 15:16:58 +0800 Subject: [PATCH 44/92] add gradle --- build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.gradle b/build.gradle index 54084758b..a5dd239dd 100644 --- a/build.gradle +++ b/build.gradle @@ -100,6 +100,10 @@ dependencies { compile 'org.thymeleaf:thymeleaf:3.0.11.RELEASE' compile 'ognl:ognl:3.2.14' compile 'org.apache.commons:commons-collections4:4.4' + // scaffold + compile ('com.webank.webase:solscaffold:1.0.0-SNAPSHOT') + compile ('com.webank:solc-gradle-plugin:1.0.0-SNAPSHOT') + testCompile test,mbg compileOnly lombok @@ -149,6 +153,10 @@ jar { from file('src/main/resources/') into 'dist/conf_template' } + copy { + from file('gradle') + into 'dist/gradle' + } copy { from file('script/') into 'dist/script' From 3553c72f9ab674ba8ccc5d07adcc2e081a3eda74 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Wed, 12 May 2021 16:08:54 +0800 Subject: [PATCH 45/92] update front agency & add detail in request fail --- .../com/webank/webase/node/mgr/front/FrontController.java | 2 +- .../java/com/webank/webase/node/mgr/front/FrontService.java | 5 ++++- .../com/webank/webase/node/mgr/front/entity/FrontInfo.java | 4 +++- .../webase/node/mgr/frontinterface/FrontRestTools.java | 6 +++--- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/front/FrontController.java b/src/main/java/com/webank/webase/node/mgr/front/FrontController.java index c603b2985..4bf1e0b7d 100644 --- a/src/main/java/com/webank/webase/node/mgr/front/FrontController.java +++ b/src/main/java/com/webank/webase/node/mgr/front/FrontController.java @@ -53,7 +53,7 @@ public class FrontController extends BaseController { private FrontService frontService; /** - * refresh front + * refresh frontn */ @GetMapping("/refresh") public BaseResponse refreshFront() { diff --git a/src/main/java/com/webank/webase/node/mgr/front/FrontService.java b/src/main/java/com/webank/webase/node/mgr/front/FrontService.java index 5db3be3eb..c453a978f 100644 --- a/src/main/java/com/webank/webase/node/mgr/front/FrontService.java +++ b/src/main/java/com/webank/webase/node/mgr/front/FrontService.java @@ -284,7 +284,10 @@ public TbFront newFront(FrontInfo frontInfo) { tbFront.setP2pPort(nodeConfig.getP2pport()); tbFront.setJsonrpcPort(nodeConfig.getRpcport()); tbFront.setChannelPort(nodeConfig.getChannelPort()); - + // get agency of node + NodeInfo nodeInfo = frontInterface.getNodeInfoFromSpecificFront(frontIp, frontPort); + log.info("front's agency is :{}", nodeInfo.getNodeInfo()); + tbFront.setAgency(nodeInfo.getNodeInfo().getAgency()); // get front server version and sign server version try { String frontVersion = frontInterface.getFrontVersionFromSpecificFront(frontIp, frontPort); diff --git a/src/main/java/com/webank/webase/node/mgr/front/entity/FrontInfo.java b/src/main/java/com/webank/webase/node/mgr/front/entity/FrontInfo.java index 5f64fa114..11e44f578 100644 --- a/src/main/java/com/webank/webase/node/mgr/front/entity/FrontInfo.java +++ b/src/main/java/com/webank/webase/node/mgr/front/entity/FrontInfo.java @@ -23,6 +23,8 @@ public class FrontInfo { private String frontIp; @NotNull private Integer frontPort; - @NotBlank + /** + * deprecated in v1.5.1 + */ private String agency; } diff --git a/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontRestTools.java b/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontRestTools.java index 7a00dc816..c1b740da5 100644 --- a/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontRestTools.java +++ b/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontRestTools.java @@ -339,7 +339,7 @@ public T getForEntity(Integer groupId, String uri, Class clazz) { T response = restTemplateExchange(groupId, uri, HttpMethod.GET, null, clazz); if (response == null) { log.error("getForEntity response is null!"); - throw new NodeMgrException(ConstantCode.REQUEST_FRONT_FAIL); + throw new NodeMgrException(ConstantCode.REQUEST_FRONT_FAIL.attach("getForEntity response is null")); } return response; } @@ -351,7 +351,7 @@ public T postForEntity(Integer groupId, String uri, Object params, Class T response = restTemplateExchange(groupId, uri, HttpMethod.POST, params, clazz); if (response == null) { log.error("postForEntity response is null!"); - throw new NodeMgrException(ConstantCode.REQUEST_FRONT_FAIL); + throw new NodeMgrException(ConstantCode.REQUEST_FRONT_FAIL.attach("postForEntity response is null")); } return response; } @@ -363,7 +363,7 @@ public T deleteForEntity(Integer groupId, String uri, Object params, Class Date: Wed, 12 May 2021 16:51:01 +0800 Subject: [PATCH 46/92] add upgrade sql --- script/upgrade/v150_v151.sql | 150 +++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 script/upgrade/v150_v151.sql diff --git a/script/upgrade/v150_v151.sql b/script/upgrade/v150_v151.sql new file mode 100644 index 000000000..0d08f958e --- /dev/null +++ b/script/upgrade/v150_v151.sql @@ -0,0 +1,150 @@ +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; +CREATE TABLE IF NOT EXISTS tb_warehouse ( + id int(11) NOT NULL COMMENT '自增编号', + warehouse_name varchar(255) binary NOT NULL COMMENT '合约仓库名', + warehouse_name_en varchar(255) binary NOT NULL COMMENT '仓库名(英文)', + type int(11) NOT NULL COMMENT '仓库类型', + warehouse_icon mediumtext COMMENT '仓库图标(Base64)', + description mediumtext COMMENT '仓库描述(Base64)', + description_en mediumtext COMMENT '仓库描述(英文)(Base64)', + warehouse_detail mediumtext COMMENT '仓库详情', + warehouse_detail_en mediumtext COMMENT '仓库详情(英文)', + create_time datetime DEFAULT NULL COMMENT '创建时间', + modify_time datetime DEFAULT NULL COMMENT '修改时间', + PRIMARY KEY (id), + UNIQUE KEY uk_name(warehouse_name) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='合约仓库'; + +CREATE TABLE IF NOT EXISTS tb_contract_folder ( + id int(11) NOT NULL COMMENT '自增编号', + folder_name varchar(255) binary NOT NULL COMMENT '合约目录名', + description mediumtext COMMENT '目录描述(Base64)', + description_en mediumtext COMMENT '目录描述(英文)(Base64)', + folder_detail mediumtext COMMENT '目录详情', + folder_detail_en mediumtext COMMENT '目录详情(英文)', + create_time datetime DEFAULT NULL COMMENT '创建时间', + modify_time datetime DEFAULT NULL COMMENT '修改时间', + warehouse_id int(11) NOT NULL COMMENT '合约仓库编号', + PRIMARY KEY (id), + UNIQUE KEY uk_name(warehouse_id,folder_name) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='合约仓库目录'; + +CREATE TABLE IF NOT EXISTS tb_contract_item ( + id int(11) NOT NULL COMMENT '自增编号', + contract_name varchar(255) binary NOT NULL COMMENT '合约名称', + contract_source mediumtext COMMENT '合约源码(Base64)', + description mediumtext COMMENT '合约描述(Base64)', + description_en mediumtext COMMENT '合约描述(英文)(Base64)', + create_time datetime DEFAULT NULL COMMENT '创建时间', + modify_time datetime DEFAULT NULL COMMENT '修改时间', + warehouse_id int(11) NOT NULL COMMENT '合约仓库编号', + contract_folder_id int(11) NOT NULL COMMENT '合约目录编号', + PRIMARY KEY (id), + UNIQUE KEY uk_name(warehouse_id,contract_folder_id,contract_name) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='合约仓库合约信息'; + + +-- 插入默认数据 -- + +-- ---------------------------- +-- 9、init contract warehouse data (tb_warehouse, tb_contract_folder, tb_contract_item) +-- ---------------------------- +-- warehouse +INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES +(1, '工具箱', 'Toolbox', 1, 'toolboxId', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); +INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES +(2, '存证应用', 'Evidence', 2, 'evidenceId', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', now(), now()); +INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES +(3, '积分应用', 'Points', 3, 'pointsId', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); +INSERT INTO `tb_warehouse` (`id`, `warehouse_name`, `warehouse_name_en`, `type`, `warehouse_icon`, `description`, `description_en`, `warehouse_detail`, `warehouse_detail_en`, `create_time`, `modify_time`) VALUES +(4, 'SmartDev存证应用', 'Smart_Dev_Evidence', 4, 'evidenceId', 'Smart-Dev-Contracts仓库中的存证应用模板', 'Smart-Dev-Contract\'s Evidence Contract suite of business_template', 'Smart-Dev-Contracts仓库中的存证应用模板', 'Smart-Dev-Contract\'s Evidence Contract suite of business_template', now(), now()); +-- folder +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES +(1, 1, 'Tools', '工具箱中有常用的工具合约', 'Toolbox Contract suite', '工具箱中有常用的工具合约', 'Toolbox Contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES +(2, 2, 'Evidence', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', '一套区块链存证合约,实现区块链存证、取证', 'Evidence Contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES +(3, 3, 'Points', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', '一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能', 'Points Contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES +(4, 1, 'Smart_Dev_Basic', 'SmartDev基础合约,包含Table/KVTable/Sha/Crypto/HelloWorld等', 'Smart-Dev-Contract basic contract suite, including Table/KVTable/Sha/Crypto/HelloWorld etc.', 'SmartDev基础合约,包含Table/KVTable/Sha/Crypto/HelloWorld等', 'Smart-Dev-Contract default contract suite', now(), now()); +INSERT INTO `tb_contract_folder` (`id`, `warehouse_id`, `folder_name`, `description`, `description_en`, `folder_detail`, `folder_detail_en`, `create_time`, `modify_time`) VALUES +(5, 4, 'Smart_Dev_Evidence', 'SmartDev存证合约案例', 'Smart-Dev-Contract Evidence contract suite', 'SmartDev存证合约案例', 'Smart-Dev-Contract Evidence contract suite', now(), now()); + +-- contract item +-- of contract source & md desc, including tools, evidence, points(BAC) -- +-- tools -- +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(1, 1, 1, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', + 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(2, 1, 1, 'LibString', 'Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgXjAuNC4xMTsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gUmV0dXJucyB0aGUgbWVtb3J5IGFkZHJlc3Mgb2YgdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YKICAgIC8vIGBuZWVkbGVgIGluIGBzZWxmYCwgb3IgdGhlIGZpcnN0IGJ5dGUgYWZ0ZXIgYHNlbGZgIGlmIG5vdCBmb3VuZC4KICAgIGZ1bmN0aW9uIGZpbmRQdHIodWludCBzZWxmbGVuLCB1aW50IHNlbGZwdHIsIHVpbnQgbmVlZGxlbGVuLCB1aW50IG5lZWRsZXB0cikgcHJpdmF0ZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgdWludCBwdHI7CiAgICAgICAgdWludCBpZHg7CgogICAgICAgIGlmIChuZWVkbGVsZW4gPD0gc2VsZmxlbikgewogICAgICAgICAgICBpZiAobmVlZGxlbGVuIDw9IDMyKSB7CiAgICAgICAgICAgICAgICAvLyBPcHRpbWl6ZWQgYXNzZW1ibHkgZm9yIDY4IGdhcyBwZXIgYnl0ZSBvbiBzaG9ydCBzdHJpbmdzCiAgICAgICAgICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IG1hc2sgOj0gbm90KHN1YihleHAoMiwgbXVsKDgsIHN1YigzMiwgbmVlZGxlbGVuKSkpLCAxKSkKICAgICAgICAgICAgICAgICAgICBsZXQgbmVlZGxlZGF0YSA6PSBhbmQobWxvYWQobmVlZGxlcHRyKSwgbWFzaykKICAgICAgICAgICAgICAgICAgICBsZXQgZW5kIDo9IGFkZChzZWxmcHRyLCBzdWIoc2VsZmxlbiwgbmVlZGxlbGVuKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gc2VsZnB0cgogICAgICAgICAgICAgICAgICAgIGxvb3A6CiAgICAgICAgICAgICAgICAgICAganVtcGkoZXhpdCwgZXEoYW5kKG1sb2FkKHB0ciksIG1hc2spLCBuZWVkbGVkYXRhKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHB0ciwgMSkKICAgICAgICAgICAgICAgICAgICBqdW1waShsb29wLCBsdChzdWIocHRyLCAxKSwgZW5kKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHNlbGZwdHIsIHNlbGZsZW4pCiAgICAgICAgICAgICAgICAgICAgZXhpdDoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBGb3IgbG9uZyBuZWVkbGVzLCB1c2UgaGFzaGluZwogICAgICAgICAgICAgICAgYnl0ZXMzMiBoYXNoOwogICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBoYXNoIDo9IHNoYTMobmVlZGxlcHRyLCBuZWVkbGVsZW4pIH0KICAgICAgICAgICAgICAgIHB0ciA9IHNlbGZwdHI7CiAgICAgICAgICAgICAgICBmb3IgKGlkeCA9IDA7IGlkeCA8PSBzZWxmbGVuIC0gbmVlZGxlbGVuOyBpZHgrKykgewogICAgICAgICAgICAgICAgICAgIGJ5dGVzMzIgdGVzdEhhc2g7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibHkgeyB0ZXN0SGFzaCA6PSBzaGEzKHB0ciwgbmVlZGxlbGVuKSB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc2ggPT0gdGVzdEhhc2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgICAgICAgICAgcHRyICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGZwdHIgKyBzZWxmbGVuOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9zdHIpIGludGVybmFsIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY29tcGFyZU5vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBieXRlIGNoMSA9IGJ5dGVzKF9zZWxmKVtpXXwweDIwOwogICAgICAgICAgICBieXRlIGNoMiA9IGJ5dGVzKF9zdHIpW2ldfDB4MjA7CiAgICAgICAgICAgIGlmIChjaDEgPj0gJ2EnICYmIGNoMSA8PSd6JyAmJiBjaDIgPj0gJ2EnICYmIGNoMiA8PSd6JykgewogICAgICAgICAgICAgICAgaWYgKGNoMSA+IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaDEgPCBjaDIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFscyhzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgYnl0ZSBjaDEgPSBieXRlcyhfc2VsZilbaV18MHgyMDsKICAgICAgICAgICAgYnl0ZSBjaDIgPSBieXRlcyhfc3RyKVtpXXwweDIwOwogICAgICAgICAgICBpZiAoY2gxID49ICdhJyAmJiBjaDEgPD0neicgJiYgY2gyID49ICdhJyAmJiBjaDIgPD0neicpIHsKICAgICAgICAgICAgICAgIGlmIChjaDEgIT0gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gc3Vic3RyKHN0cmluZyBfc2VsZiwgdWludCBfc3RhcnQsIHVpbnQgX2xlbikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKF9sZW4pOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK19zdGFydCwgX2xlbik7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIG1lbWNweShyZXRwdHIrYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc3RycHRyLCBieXRlcyhfc3RyKS5sZW5ndGgpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb25jYXQoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cjEsIHN0cmluZyBfc3RyMikKICAgICAgICBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyMSwgc3RyaW5nIF9zdHIyLCBzdHJpbmcgX3N0cjMpCiAgICAgICAgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhieXRlcyhfc2VsZikubGVuZ3RoICsgYnl0ZXMoX3N0cjEpLmxlbmd0aCArIGJ5dGVzKF9zdHIyKS5sZW5ndGgKICAgICAgICAgICAgKyBieXRlcyhfc3RyMykubGVuZ3RoKTsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgc3RyMXB0cjsKICAgICAgICB1aW50IHN0cjJwdHI7CiAgICAgICAgdWludCBzdHIzcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgc3RyM3B0ciA6PSBhZGQoX3N0cjMsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMXB0ciwgYnl0ZXMoX3N0cjEpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIxKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjJwdHIsIGJ5dGVzKF9zdHIyKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIzcHRyLCBieXRlcyhfc3RyMykubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjMpLmxlbmd0aDsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgdWludCBpOwogICAgICAgIHVpbnQ4IGNoOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBjaCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgaT4wOyAtLWkpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaS0xXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IGVuZCA9IGk7CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50MTYgajsKICAgICAgICBib29sIG1hdGNoZWQ7CiAgICAgICAgZm9yIChpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgc3RhcnQgPSBpOwogICAgICAgIAogICAgICAgIGZvciAoaT11aW50MTYoYnl0ZXMoX3NlbGYpLmxlbmd0aCk7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpLTFdID09IGJ5dGVzKF9jaGFycylbal0pIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIW1hdGNoZWQpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHVpbnQxNiBlbmQgPSBpOwoKICAgICAgICBpZiAoZW5kIDw9IHN0YXJ0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfZGVsaW0sIHN0cmluZ1tdIHN0b3JhZ2UgX2FycmF5KSBpbnRlcm5hbCB7CiAgICAgICAgLy9XaHkgY2FuIG5vdCB1c2UgZGVsZXRlIF9hcnJheT8KICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPF9hcnJheS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkZWxldGUgX2FycmF5W2ldOwogICAgICAgIH0KICAgICAgICBfYXJyYXkubGVuZ3RoID0gMDsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgZGVsaW1wdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgZGVsaW1wdHIgOj0gYWRkKF9kZWxpbSwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIHVpbnQgcHRyOwogICAgICAgICAgICBib29sIGZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChieXRlcyhfZGVsaW0pLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfZGVsaW0pLmxlbmd0aCwgZGVsaW1wdHIpIC0gc2VsZnB0cjsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKHB0ciA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHB0ciA9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwdHIgPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IGVsZW0gPSBuZXcgc3RyaW5nKHB0ci1wb3MpOwogICAgICAgICAgICB1aW50IGVsZW1wdHI7CiAgICAgICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgICAgIGVsZW1wdHIgOj0gYWRkKGVsZW0sIDB4MjApCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWVtY3B5KGVsZW1wdHIsIHNlbGZwdHIrcG9zLCBwdHItcG9zKTsKICAgICAgICAgICAgcG9zID0gcHRyICsgYnl0ZXMoX2RlbGltKS5sZW5ndGg7CiAgICAgICAgICAgIF9hcnJheS5wdXNoKGVsZW0pOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCFmb3VuZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc2VsZnB0ciwgYnl0ZXMoX3N0cikubGVuZ3RoLCBzdHJwdHIpIC0gc2VsZnB0cjsKICAgICAgICBpZiAocHRyIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICBfcmV0ID0gaW50KHB0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3JldCA9IC0xOwogICAgICAgIH0KICAgIH0KICAgIAogICAgZnVuY3Rpb24gaW5kZXhPZihzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyLCB1aW50IHBvcykgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfc3RyKS5sZW5ndGgsIHN0cnB0cikgLSBzZWxmcHRyOwogICAgICAgIGlmIChwdHIgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgIF9yZXQgPSBpbnQocHRyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBfcmV0ID0gLTE7CiAgICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0ludChzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGludCBfcmV0KSB7CiAgICAgICAgX3JldCA9IDA7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID09ICcrJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9IGVsc2UgaWYoYnl0ZXMoX3NlbGYpW2ldID09ICctJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQoKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA+PSAweDMwICYmIGRpZ2l0IDw9IDB4MzkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGFkZHJlc3MgX3JldCkgewogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aC1pIDwgMikgewogICAgICAgICAgICByZXR1cm4gYWRkcmVzcygwKTsKICAgICAgICB9CgogICAgICAgIC8vbXVzdCBzdGFydCB3aXRoIDB4CiAgICAgICAgaWYgKCEoYnl0ZXMoX3NlbGYpW2ldID09ICcwJyAmJiBieXRlcyhfc2VsZilbaSsxXXwweDIwID09ICd4JykpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICB1aW50IGFkZHIgPSAwOwogICAgICAgIAogICAgICAgIGZvciAoaSs9MjsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSAvLycwJy0nOScKICAgICAgICAgICAgICAgIGRpZ2l0IC09IDB4MzA7CiAgICAgICAgICAgIGVsc2UgaWYgKGRpZ2l0fDB4MjAgPj0gMHg2MSAmJiBkaWdpdHwweDIwIDw9IDB4NjYpIC8vJ2EnLSdmJwogICAgICAgICAgICAgICAgZGlnaXQgPSBkaWdpdC0weDYxKzEwOwogICAgICAgICAgICBlbHNlIAogICAgICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7IAogICAgICAgICAgICAKICAgICAgICAgICAgYWRkciA9IGFkZHIqMTYrZGlnaXQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBhZGRyZXNzKGFkZHIpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0tleVZhbHVlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9rZXkpLmxlbmd0aCArIDUpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IGtleXB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBrZXlwdHIgOj0gYWRkKF9rZXksIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwoKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIGtleXB0ciwgYnl0ZXMoX2tleSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX2tleSkubGVuZ3RoOwogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICAKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnOic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldFN0cmluZ1ZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc3RhcnQgKz0gMTsKICAgICAgICAKICAgICAgICBpbnQgZW5kOwogICAgICAgIGlmIChkb3VibGVRdW90ZXMpIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHN0YXJ0KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiJyIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVuZCA9PSAtMSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZi5zdWJzdHIodWludChzdGFydCksIHVpbnQoZW5kLXN0YXJ0KSk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldEludFZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdWludCBpID0gdWludChwb3MpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEgCiAgICAgICAgICAgIHx8IGRpZ2l0ID09IDB4M0EgLyo6Ki8gfHwgZGlnaXQgPT0gMHgyMiAvKiIqLyB8fCBkaWdpdCA9PSAweDI3IC8qJyovKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gdG9VcHBlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnYScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICd6JykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldICY9IH4weDIwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZjsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9Mb3dlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnQScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICdaJykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldIHw9IDB4MjA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IF9zZWxmOwogICAgfQoJCiAgICBmdW5jdGlvbiBrZXlFeGlzdHMoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFscyhfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogCiAgICBmdW5jdGlvbiBpbkFycmF5Tm9DYXNlKHN0cmluZyBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHNOb0Nhc2UoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgfQ==', + 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(3, 1, 1, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', + 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(4, 1, 1, 'Table', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7Cgpjb250cmFjdCBUYWJsZUZhY3RvcnkgewogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoVGFibGUpOyAvL29wZW4gdGFibGUKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOyAvL2NyZWF0ZSB0YWJsZQp9CgovL3NlbGVjdCBjb25kaXRpb24KY29udHJhY3QgQ29uZGl0aW9uIHsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgc3RyaW5nKSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgYWRkcmVzcykgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBpbnQyNTYpIHB1YmxpYyB2aWV3OwogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyB2aWV3OwoKICAgIGZ1bmN0aW9uIEdUKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEdFKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKCiAgICBmdW5jdGlvbiBMVChzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CiAgICBmdW5jdGlvbiBMRShzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gbGltaXQoaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIGxpbWl0KGludDI1NiwgaW50MjU2KSBwdWJsaWMgdmlldzsKfQoKLy9vbmUgcmVjb3JkCmNvbnRyYWN0IEVudHJ5IHsKICAgIGZ1bmN0aW9uIGdldEludChzdHJpbmcpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRVSW50KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRBZGRyZXNzKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcyk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczY0KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMxWzY0XSk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczMyKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMzMik7CiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcpOwoKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcsIGludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgdWludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgc3RyaW5nKSBwdWJsaWM7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBhZGRyZXNzKSBwdWJsaWM7Cn0KCi8vcmVjb3JkIHNldHMKY29udHJhY3QgRW50cmllcyB7CiAgICBmdW5jdGlvbiBnZXQoaW50MjU2KSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBzaXplKCkgcHVibGljIHZpZXcgcmV0dXJucyAoaW50MjU2KTsKfQoKLy9UYWJsZSBtYWluIGNvbnRyYWN0CmNvbnRyYWN0IFRhYmxlIHsKICAgIGZ1bmN0aW9uIHNlbGVjdChzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHZpZXcgcmV0dXJucyAoRW50cmllcyk7CiAgICBmdW5jdGlvbiBpbnNlcnQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiB1cGRhdGUoc3RyaW5nLCBFbnRyeSwgQ29uZGl0aW9uKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KTsKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHJldHVybnMgKGludDI1Nik7CgogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBuZXdDb25kaXRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChDb25kaXRpb24pOwp9Cgpjb250cmFjdCBLVlRhYmxlRmFjdG9yeSB7CiAgICBmdW5jdGlvbiBvcGVuVGFibGUoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChLVlRhYmxlKTsKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOwp9CgovL0tWVGFibGUgcGVyIHBlcm1pYXJ5IGtleSBoYXMgb25seSBvbmUgRW50cnkKY29udHJhY3QgS1ZUYWJsZSB7CiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sLCBFbnRyeSk7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBuZXdFbnRyeSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KTsKfQo=', + 'IyB0YWJsZQoKdGFibGUgbGlicmFyeQoKQkNPUyBDUlVEIHVzZXMgdGhlIGJhc2UgbGlicmFyeSwgd2hpY2ggeW91IGNhbiByZWZlcmVuY2UgYnkgcmUtY29udHJhY3QgY2FsbGluZyBDUlVELlRhYmxlIGNvbnRyYWN0IHVzYWdlIG1ldGhvZHMgY2FuIGJlIGRlc2NyaWJlZCBieSByZWZlcnJpbmcgdG8gdGhlIGFzc2F0IGV4YW1wbGUgaW4gdGhlIGJjb3MgZG9jdW1lbnQgaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8u', 'IyB0YWJsZQoKdGFibGUgbGlicmFyeQoKQkNPUyBDUlVEIHVzZXMgdGhlIGJhc2UgbGlicmFyeSwgd2hpY2ggeW91IGNhbiByZWZlcmVuY2UgYnkgcmUtY29udHJhY3QgY2FsbGluZyBDUlVELlRhYmxlIGNvbnRyYWN0IHVzYWdlIG1ldGhvZHMgY2FuIGJlIGRlc2NyaWJlZCBieSByZWZlcnJpbmcgdG8gdGhlIGFzc2F0IGV4YW1wbGUgaW4gdGhlIGJjb3MgZG9jdW1lbnQgaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8u', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(5, 1, 1, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', + 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +-- evidence -- +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(6, 2, 2, 'Evidence', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YUFCSXsgZnVuY3Rpb24gdmVyaWZ5KGFkZHJlc3MgYWRkcilwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhib29sKXt9CmZ1bmN0aW9uIGdldFNpZ25lcih1aW50IGluZGV4KXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3Mpe30gCmZ1bmN0aW9uIGdldFNpZ25lcnNTaXplKCkgcHVibGljIGNvbnN0YW50IHJldHVybnModWludCl7fQp9Cgpjb250cmFjdCBFdmlkZW5jZXsKICAgIAogICAgc3RyaW5nIGV2aWRlbmNlOwogICAgc3RyaW5nIGV2aWRlbmNlSW5mbzsKICAgIHN0cmluZyBldmlkZW5jZUlkOwogICAgdWludDhbXSBfdjsKICAgIGJ5dGVzMzJbXSBfcjsKICAgIGJ5dGVzMzJbXSBfczsKICAgIGFkZHJlc3NbXSBzaWduZXJzOwogICAgYWRkcmVzcyBwdWJsaWMgc2lnbmVyc0FkZHI7CiAgICAKICAgICAgICBldmVudCBhZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IG5ld1NpZ25hdHVyZXNFdmVudChzdHJpbmcgZXZpLCBzdHJpbmcgaW5mbywgc3RyaW5nIGlkLCB1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcyxhZGRyZXNzIGFkZHIpOwogICAgICAgIGV2ZW50IGVycm9yTmV3U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLGFkZHJlc3MgYWRkcik7CiAgICAgICAgZXZlbnQgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsYWRkcmVzcyBhZGRyKTsKICAgICAgICBldmVudCBhZGRSZXBlYXRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsIGFkZHJlc3MgYWRkcik7CgogICAgZnVuY3Rpb24gQ2FsbFZlcmlmeShhZGRyZXNzIGFkZHIpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpIHsKICAgICAgICByZXR1cm4gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikudmVyaWZ5KGFkZHIpOwogICAgfQoKICAgICAgIGZ1bmN0aW9uIEV2aWRlbmNlKHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLCBhZGRyZXNzIGFkZHIsIGFkZHJlc3Mgc2VuZGVyKSBwdWJsaWMgewogICAgICAgc2lnbmVyc0FkZHIgPSBhZGRyOwogICAgICAgaWYoQ2FsbFZlcmlmeShzZW5kZXIpKQogICAgICAgewogICAgICAgICAgIGV2aWRlbmNlID0gZXZpOwogICAgICAgICAgIGV2aWRlbmNlSW5mbyA9IGluZm87CiAgICAgICAgICAgZXZpZGVuY2VJZCA9IGlkOwogICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgX3IucHVzaChyKTsKICAgICAgICAgICBfcy5wdXNoKHMpOwogICAgICAgICAgIHNpZ25lcnMucHVzaChzZW5kZXIpOwogICAgICAgICAgIG5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgICAgIGVsc2UKICAgICAgIHsKICAgICAgICAgICBlcnJvck5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgIH0KCiAgICAgICAgZnVuY3Rpb24gZ2V0RXZpZGVuY2VJbmZvKCkgcHVibGljIGNvbnN0YW50IHJldHVybnMoc3RyaW5nKXsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlSW5mbzsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRFdmlkZW5jZSgpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKHN0cmluZyxzdHJpbmcsc3RyaW5nLHVpbnQ4W10sYnl0ZXMzMltdLGJ5dGVzMzJbXSxhZGRyZXNzW10pewogICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICByZXR1cm4oZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsX3YsX3IsX3Msc2lnbmVyTGlzdCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkU2lnbmF0dXJlcyh1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcykgcHVibGljIHJldHVybnMoYm9vbCkgewogICAgICAgIGZvcih1aW50IGk9IDAgO2k8c2lnbmVycy5sZW5ndGggO2krKykKICAgICAgICB7CiAgICAgICAgICAgIGlmKG1zZy5zZW5kZXIgPT0gc2lnbmVyc1tpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoIF92W2ldID09IHYgJiYgX3JbaV0gPT0gciAmJiBfc1tpXSA9PSBzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFkZFJlcGVhdFNpZ25hdHVyZXNFdmVudChldmlkZW5jZSxldmlkZW5jZUluZm8sZXZpZGVuY2VJZCx2LHIscyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgIGlmKENhbGxWZXJpZnkobXNnLnNlbmRlcikpCiAgICAgICB7CiAgICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgIF9yLnB1c2gocik7CiAgICAgICAgICAgIF9zLnB1c2gocyk7CiAgICAgICAgICAgIHNpZ25lcnMucHVzaChtc2cuc2VuZGVyKTsKICAgICAgICAgICAgYWRkU2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSW5mbyxldmlkZW5jZUlkLHYscixzKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICB9CiAgICAgICBlbHNlCiAgICAgICB7CiAgICAgICAgICAgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTaWduZXJzKClwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhhZGRyZXNzW10pCiAgICB7CiAgICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHNpZ25lckxpc3Q7CiAgICB9Cn0=', + 'IyBFdmlkZW5jZSDlkIjnuqYKCiMjIOeugOS7iwpFdmlkZW5jZSDnpLrkvovlkIjnuqbvvIzkvb/nlKjliIblsYLnmoTmmbrog73lkIjnuqbnu5PmnoTvvJogCjHvvInlt6XljoLlkIjnuqbvvIhFdmlkZW5jZVNpZ25lcnNEYXRhLnNvbO+8ie+8jOeUseWtmOivgeWQhOaWueS6i+WJjee6puWumu+8jOWtmOWCqOWtmOivgeeUn+aViOadoeS7tu+8jOW5tueuoeeQhuWtmOivgeeahOeUn+aIkOOAgiAgCjLvvInlrZjor4HlkIjnuqbvvIhFdmlkZW5jZS5zb2zvvInvvIznlLHlt6XljoLlkIjnuqbnlJ/miJDvvIzlrZjlgqjlrZjor4FpZO+8jGhhc2jlkozlkITmlrnnrb7lkI3vvIjmr4/lvKDlrZjor4HkuIDkuKrlkIjnuqbvvInjgIIgIA==', '', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(7, 2, 2, 'EvidenceSignersData', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKaW1wb3J0ICJFdmlkZW5jZS5zb2wiOwoKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YXsKICAgICAgICBhZGRyZXNzW10gc2lnbmVyczsKCQlldmVudCBuZXdFdmlkZW5jZUV2ZW50KGFkZHJlc3MgYWRkcik7CiAgICAgICAgZnVuY3Rpb24gbmV3RXZpZGVuY2Uoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sc3RyaW5nIGlkLHVpbnQ4IHYsIGJ5dGVzMzIgcixieXRlczMyIHMpcHVibGljIHJldHVybnMoYWRkcmVzcykKICAgICAgICB7CiAgICAgICAgICAgIEV2aWRlbmNlIGV2aWRlbmNlID0gbmV3IEV2aWRlbmNlKGV2aSwgaW5mbywgaWQsIHYsIHIsIHMsIHRoaXMsIG1zZy5zZW5kZXIpOwogICAgICAgICAgICBuZXdFdmlkZW5jZUV2ZW50KGV2aWRlbmNlKTsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gRXZpZGVuY2VTaWduZXJzRGF0YShhZGRyZXNzW10gZXZpZGVuY2VTaWduZXJzKXB1YmxpY3sKICAgICAgICAgICAgZm9yKHVpbnQgaT0wOyBpPGV2aWRlbmNlU2lnbmVycy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBzaWduZXJzLnB1c2goZXZpZGVuY2VTaWduZXJzW2ldKTsKCQkJfQoJCX0KCiAgICBmdW5jdGlvbiB2ZXJpZnkoYWRkcmVzcyBhZGRyKXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpewogICAgZm9yKHVpbnQgaT0wOyBpPHNpZ25lcnMubGVuZ3RoOyArK2kpIHsKICAgICAgICBpZiAoYWRkciA9PSBzaWduZXJzW2ldKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyKHVpbnQgaW5kZXgpcHVibGljIGNvbnN0YW50IHJldHVybnMoYWRkcmVzcyl7CiAgICAgICAgdWludCBsaXN0U2l6ZSA9IHNpZ25lcnMubGVuZ3RoOwogICAgICAgIGlmKGluZGV4IDwgbGlzdFNpemUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc2lnbmVyc1tpbmRleF07CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyc1NpemUoKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyh1aW50KXsKICAgICAgICByZXR1cm4gc2lnbmVycy5sZW5ndGg7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVycygpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3NbXSl7CiAgICAgICAgcmV0dXJuIHNpZ25lcnM7CiAgICB9Cgp9', + 'IyBFdmlkZW5jZSDlkIjnuqYKCiMjIOeugOS7iwpFdmlkZW5jZSDnpLrkvovlkIjnuqbvvIzkvb/nlKjliIblsYLnmoTmmbrog73lkIjnuqbnu5PmnoTvvJogCjHvvInlt6XljoLlkIjnuqbvvIhFdmlkZW5jZVNpZ25lcnNEYXRhLnNvbO+8ie+8jOeUseWtmOivgeWQhOaWueS6i+WJjee6puWumu+8jOWtmOWCqOWtmOivgeeUn+aViOadoeS7tu+8jOW5tueuoeeQhuWtmOivgeeahOeUn+aIkOOAgiAgCjLvvInlrZjor4HlkIjnuqbvvIhFdmlkZW5jZS5zb2zvvInvvIznlLHlt6XljoLlkIjnuqbnlJ/miJDvvIzlrZjlgqjlrZjor4FpZO+8jGhhc2jlkozlkITmlrnnrb7lkI3vvIjmr4/lvKDlrZjor4HkuIDkuKrlkIjnuqbvvInjgIIgIA==', '', now(), now()); +-- bac points -- +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(8, 3, 3, 'BAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgppbXBvcnQgIi4vU2FmZU1hdGguc29sIjsKaW1wb3J0ICIuL1JvbGVzLnNvbCI7CmltcG9ydCAiLi9BZGRyZXNzLnNvbCI7Cgpjb250cmFjdCBJc3N1ZXJSb2xlIHsKICAgIHVzaW5nIFJvbGVzIGZvciBSb2xlcy5Sb2xlOwoKICAgIGV2ZW50IElzc3VlckFkZGVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKICAgIGV2ZW50IElzc3VlclJlbW92ZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwoKICAgIFJvbGVzLlJvbGUgcHJpdmF0ZSBfaXNzdWVyczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX2FkZElzc3Vlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBtb2RpZmllciBvbmx5SXNzdWVyKCkgewogICAgICAgIHJlcXVpcmUoaXNJc3N1ZXIobXNnLnNlbmRlciksICJJc3N1ZXJSb2xlOiBjYWxsZXIgZG9lcyBub3QgaGF2ZSB0aGUgSXNzdWVyIHJvbGUiKTsKICAgICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfaXNzdWVycy5oYXMoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIG9ubHlJc3N1ZXIgewogICAgICAgIF9hZGRJc3N1ZXIoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVub3VuY2VJc3N1ZXIoKSBwdWJsaWMgewogICAgICAgIF9yZW1vdmVJc3N1ZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZElzc3VlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfaXNzdWVycy5hZGQoYWNjb3VudCk7CiAgICAgICAgZW1pdCBJc3N1ZXJBZGRlZChhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcmVtb3ZlSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9pc3N1ZXJzLnJlbW92ZShhY2NvdW50KTsKICAgICAgICBlbWl0IElzc3VlclJlbW92ZWQoYWNjb3VudCk7CiAgICB9Cn0KCmNvbnRyYWN0IFN1c3BlbmRlclJvbGUgewogICAgdXNpbmcgUm9sZXMgZm9yIFJvbGVzLlJvbGU7CgogICAgZXZlbnQgU3VzcGVuZGVyQWRkZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwogICAgZXZlbnQgU3VzcGVuZGVyUmVtb3ZlZChhZGRyZXNzIGluZGV4ZWQgYWNjb3VudCk7CgogICAgUm9sZXMuUm9sZSBwcml2YXRlIF9zdXNwZW5kZXJzOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfYWRkU3VzcGVuZGVyKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIG1vZGlmaWVyIG9ubHlTdXNwZW5kZXIoKSB7CiAgICAgICAgcmVxdWlyZShpc1N1c3BlbmRlcihtc2cuc2VuZGVyKSwgIlN1c3BlbmRlclJvbGU6IGNhbGxlciBkb2VzIG5vdCBoYXZlIHRoZSBTdXNwZW5kZXIgcm9sZSIpOwogICAgICAgIF87CiAgICB9CgogICAgZnVuY3Rpb24gaXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZXJzLmhhcyhhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgb25seVN1c3BlbmRlciB7CiAgICAgICAgX2FkZFN1c3BlbmRlcihhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiByZW5vdW5jZVN1c3BlbmRlcigpIHB1YmxpYyB7CiAgICAgICAgX3JlbW92ZVN1c3BlbmRlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBfYWRkU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9zdXNwZW5kZXJzLmFkZChhY2NvdW50KTsKICAgICAgICBlbWl0IFN1c3BlbmRlckFkZGVkKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9yZW1vdmVTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB7CiAgICAgICAgX3N1c3BlbmRlcnMucmVtb3ZlKGFjY291bnQpOwogICAgICAgIGVtaXQgU3VzcGVuZGVyUmVtb3ZlZChhY2NvdW50KTsKICAgIH0KfQoKY29udHJhY3QgU3VzcGVuZGFibGUgaXMgU3VzcGVuZGVyUm9sZSB7CgogICAgZXZlbnQgU3VzcGVuZGVkKGFkZHJlc3MgYWNjb3VudCk7CiAgICBldmVudCBVblN1c3BlbmRlZChhZGRyZXNzIGFjY291bnQpOwoKICAgIGJvb2wgcHJpdmF0ZSBfc3VzcGVuZGVkOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfc3VzcGVuZGVkID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNvbnRyYWN0IGlzIHN1c3BlbmRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBmdW5jdGlvbiBzdXNwZW5kZWQoKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IE1vZGlmaWVyIHRvIG1ha2UgYSBmdW5jdGlvbiBjYWxsYWJsZSBvbmx5IHdoZW4gdGhlIGNvbnRyYWN0IGlzIG5vdCBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5Ob3RTdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZSghX3N1c3BlbmRlZCwgIlN1c3BlbmRhYmxlOiBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNb2RpZmllciB0byBtYWtlIGEgZnVuY3Rpb24gY2FsbGFibGUgb25seSB3aGVuIHRoZSBjb250cmFjdCBpcyBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5TdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZShfc3VzcGVuZGVkLCAiU3VzcGVuZGFibGU6IG5vdCBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gc3VzcGVuZCwgdHJpZ2dlcnMgc3RvcHBlZCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VzcGVuZCgpIHB1YmxpYyBvbmx5U3VzcGVuZGVyIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zdXNwZW5kZWQgPSB0cnVlOwogICAgICAgIGVtaXQgU3VzcGVuZGVkKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gdW5TdXNwZW5kLCByZXR1cm5zIHRvIG5vcm1hbCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gdW5TdXNwZW5kKCkgcHVibGljIG9ubHlTdXNwZW5kZXIgd2hlblN1c3BlbmRlZCB7CiAgICAgICAgX3N1c3BlbmRlZCA9IGZhbHNlOwogICAgICAgIGVtaXQgVW5TdXNwZW5kZWQobXNnLnNlbmRlcik7CiAgICB9Cn0KCmNvbnRyYWN0IElCQUMwMDFSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBub3RpY2UgSGFuZGxlIHRoZSByZWNlaXB0IG9mIGFuIE5GVAogICAgICogQGRldiBUaGUgQkFDMDAxIHNtYXJ0IGNvbnRyYWN0IGNhbGxzIHRoaXMgZnVuY3Rpb24gb24gdGhlIHJlY2lwaWVudAogICAgICovCiAgICBmdW5jdGlvbiBvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3Mgb3BlcmF0b3IsIGFkZHJlc3MgZnJvbSwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkKICAgIHB1YmxpYyByZXR1cm5zIChieXRlczQpOwp9Cgpjb250cmFjdCBCQUMwMDFIb2xkZXIgaXMgSUJBQzAwMVJlY2VpdmVyIHsKICAgIGZ1bmN0aW9uIG9uQkFDMDAxUmVjZWl2ZWQoYWRkcmVzcywgYWRkcmVzcywgdWludDI1NiwgYnl0ZXMpIHB1YmxpYyByZXR1cm5zIChieXRlczQpIHsKICAgICAgICByZXR1cm4gdGhpcy5vbkJBQzAwMVJlY2VpdmVkLnNlbGVjdG9yOwogICAgfQp9CgoKLyoqCiAqIEB0aXRsZSBTdGFuZGFyZCBCQUMwMDEgYXNzZXQKICovCmNvbnRyYWN0IEJBQzAwMSBpcyBJc3N1ZXJSb2xlLCBTdXNwZW5kYWJsZSB7CiAgICB1c2luZyBTYWZlTWF0aCBmb3IgdWludDI1NjsKICAgIHVzaW5nIEFkZHJlc3MgZm9yIGFkZHJlc3M7CgogICAgbWFwcGluZyhhZGRyZXNzID0+IHVpbnQyNTYpIHByaXZhdGUgX2JhbGFuY2VzOwogICAgbWFwcGluZyhhZGRyZXNzID0+IG1hcHBpbmcoYWRkcmVzcyA9PiB1aW50MjU2KSkgcHJpdmF0ZSBfYWxsb3dlZDsKICAgIHVpbnQyNTYgcHJpdmF0ZSBfdG90YWxBbW91bnQ7CiAgICBzdHJpbmcgcHJpdmF0ZSBfZGVzY3JpcHRpb247CiAgICBzdHJpbmcgcHJpdmF0ZSBfc2hvcnROYW1lOwogICAgdWludDggcHJpdmF0ZSAgX21pblVuaXQ7CgogICAgLy8gRXF1YWxzIHRvIGBieXRlczQoa2VjY2FrMjU2KCJvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3MsYWRkcmVzcyx1aW50MjU2LGJ5dGVzKSIpKWAKICAgIGJ5dGVzNCBwcml2YXRlIGNvbnN0YW50IF9CQUMwMDFfUkVDRUlWRUQgPSAweGM3M2QxNmFlOwoKCiAgICBldmVudCBTZW5kKCBhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKTsKICAgIGV2ZW50IEFwcHJvdmFsKCBhZGRyZXNzIGluZGV4ZWQgb3duZXIsIGFkZHJlc3MgaW5kZXhlZCBzcGVuZGVyLCB1aW50MjU2IHZhbHVlKTsKCgogICAgY29uc3RydWN0b3Ioc3RyaW5nIG1lbW9yeSBkZXNjcmlwdGlvbiwgc3RyaW5nIG1lbW9yeSBzaG9ydE5hbWUsIHVpbnQ4IG1pblVuaXQsIHVpbnQyNTYgdG90YWxBbW91bnQpIHB1YmxpYyB7CiAgICAgICAgX2Rlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgX3Nob3J0TmFtZSA9IHNob3J0TmFtZTsKICAgICAgICBfbWluVW5pdCA9IG1pblVuaXQ7CiAgICAgICAgX2lzc3VlKG1zZy5zZW5kZXIsIHRvdGFsQW1vdW50ICogKDEwICoqIHVpbnQyNTYobWluVW5pdCkpLCAiIik7CiAgICB9CgoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJldHVybiBfdG90YWxBbW91bnQ7CiAgICB9CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9iYWxhbmNlc1tvd25lcl07CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEZ1bmN0aW9uIHRvIGNoZWNrIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFsbG93YW5jZShhZGRyZXNzIG93bmVyLCBhZGRyZXNzIHNwZW5kZXIpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2FsbG93ZWRbb3duZXJdW3NwZW5kZXJdOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zZW5kKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7CgogICAgfQoKLy8gICAgZnVuY3Rpb24gc2FmZVNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewovLyAgICAgICAgc2VuZCh0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgLyoqCiAgICAgKiBAZGV2IEFwcHJvdmUgdGhlIHBhc3NlZCBhZGRyZXNzIHRvIHNwZW5kIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIGFzc2V0cyBvbiBiZWhhbGYgb2YgbXNnLnNlbmRlci4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBfYXBwcm92ZShtc2cuc2VuZGVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlbmQgYXNzZXRzIGZyb20gb25lIGFkZHJlc3MgdG8gYW5vdGhlci4KICAgICAqLwogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgX3NlbmQoZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgICAgICBfYXBwcm92ZShmcm9tLCBtc2cuc2VuZGVyLCBfYWxsb3dlZFtmcm9tXVttc2cuc2VuZGVyXS5zdWIodmFsdWUpKTsKICAgICAgICAvL2FkZAogICAgICAgIHJlcXVpcmUoX2NoZWNrT25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpLCAiQkFDMDAxOiBzZW5kIHRvIG5vbiBCQUMwMDFSZWNlaXZlciBpbXBsZW1lbnRlciIpOwoKCiAgICB9CgovLy8vIHNhZmUgdG9kbwovLyAgICBmdW5jdGlvbiBzYWZlU2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7Ci8vICAgICAgICBzZW5kRnJvbShmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKGZyb20sIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgZnVuY3Rpb24gYmF0Y2hTZW5kKGFkZHJlc3NbXSB0bywgdWludDI1NltdIHZhbHVlcywgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewoKICAgICAgICAvLyBNVVNUIFRocm93IG9uIGVycm9ycwoKICAgICAgICByZXF1aXJlKHRvLmxlbmd0aCA9PSB2YWx1ZXMubGVuZ3RoLCAidG8gYW5kIHZhbHVlcyBhcnJheSBsZW5naHQgbXVzdCBtYXRjaC4iKTsKCiAgICAgICAgZm9yICh1aW50MjU2IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVxdWlyZSh0b1tpXSAhPSBhZGRyZXNzKDB4MCksICJkZXN0aW5hdGlvbiBhZGRyZXNzIG11c3QgYmUgbm9uLXplcm8uIik7CgogICAgICAgICAgICBzZW5kKHRvW2ldLCB2YWx1ZXNbaV0sIGRhdGEpOwogICAgICAgIH0KICAgIH0KCgogICAgZnVuY3Rpb24gX2NoZWNrT25CQUMwMDFSZWNlaXZlZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpCiAgICBpbnRlcm5hbCByZXR1cm5zIChib29sKQogICAgewogICAgICAgIGlmICghdG8uaXNDb250cmFjdCgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgYnl0ZXM0IHJldHZhbCA9IElCQUMwMDFSZWNlaXZlcih0bykub25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwogICAgICAgIHJldHVybiAocmV0dmFsID09IF9CQUMwMDFfUkVDRUlWRUQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbmNyZWFzZSB0aGUgYW1vdW50IG9mIGFzc2V0cyB0aGF0IGFuIG93bmVyIGFsbG93ZWQgdG8gYSBzcGVuZGVyLgogICAgICovCiAgICBmdW5jdGlvbiBpbmNyZWFzZUFsbG93YW5jZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYWRkZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLmFkZChhZGRlZFZhbHVlKSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IERlY3JlYXNlIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKiBhcHByb3ZlIHNob3VsZCBiZSBjYWxsZWQgd2hlbiBfYWxsb3dlZFttc2cuc2VuZGVyXVtzcGVuZGVyXSA9PSAwLiBUbyBkZWNyZW1lbnQKICAgICAqLwogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLnN1YihzdWJ0cmFjdGVkVmFsdWUpKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXN0cm95KHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3kobXNnLnNlbmRlciwgdmFsdWUsIGRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBCdXJucyBhIHNwZWNpZmljIGFtb3VudCBvZiBhc3NldHMgZnJvbSB0aGUgdGFyZ2V0IGFkZHJlc3MgYW5kIGRlY3JlbWVudHMgYWxsb3dhbmNlLgogICAgICovCiAgICBmdW5jdGlvbiBkZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3lGcm9tKGZyb20sIHZhbHVlLCBkYXRhKTsKICAgIH0KCgogICAgZnVuY3Rpb24gZGVzY3JpcHRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIF9kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIHNob3J0TmFtZSBvZiB0aGUgYXNzZXQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNob3J0TmFtZSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX3Nob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBtaW5Vbml0IG9mIHRoZSBhc3NldC4KICAgICAqLwogICAgZnVuY3Rpb24gbWluVW5pdCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQ4KSB7CiAgICAgICAgcmV0dXJuIF9taW5Vbml0OwogICAgfQoKCiAgICBmdW5jdGlvbiBpc3N1ZShhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgb25seUlzc3VlciByZXR1cm5zIChib29sKSB7CiAgICAgICAgX2lzc3VlKHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXYgU2VuZCBhc3NldCBmb3IgYSBzcGVjaWZpZWQgYWRkcmVzc2VzLgogICAgICovCiAgICBmdW5jdGlvbiBfc2VuZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKHRvICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IHNlbmQgdG8gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfYmFsYW5jZXNbZnJvbV0gPSBfYmFsYW5jZXNbZnJvbV0uc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbdG9dID0gX2JhbGFuY2VzW3RvXS5hZGQodmFsdWUpOwogICAgICAgIGVtaXQgU2VuZCggZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCBpc3N1ZXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBhbmQgYXNzaWducyBpdCB0bwogICAgICovCiAgICBmdW5jdGlvbiBfaXNzdWUoYWRkcmVzcyBhY2NvdW50LCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShhY2NvdW50ICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IGlzc3VlIHRvIHRoZSB6ZXJvIGFkZHJlc3MiKTsKCiAgICAgICAgX3RvdGFsQW1vdW50ID0gX3RvdGFsQW1vdW50LmFkZCh2YWx1ZSk7CiAgICAgICAgX2JhbGFuY2VzW2FjY291bnRdID0gX2JhbGFuY2VzW2FjY291bnRdLmFkZCh2YWx1ZSk7CiAgICAgICAgZW1pdCBTZW5kKCBhZGRyZXNzKDApLCBhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95KGFkZHJlc3MgYWNjb3VudCwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiQkFDMDAxOiBkZXN0cm95IGZyb20gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfdG90YWxBbW91bnQgPSBfdG90YWxBbW91bnQuc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbYWNjb3VudF0gPSBfYmFsYW5jZXNbYWNjb3VudF0uc3ViKHZhbHVlKTsKICAgICAgICBlbWl0IFNlbmQoIGFjY291bnQsIGFkZHJlc3MoMCksIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZSBhbiBhZGRyZXNzIHRvIHNwZW5kIGFub3RoZXIgYWRkcmVzc2VzJyBhc3NldHMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hcHByb3ZlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiB2YWx1ZSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUob3duZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSBmcm9tIHRoZSB6ZXJvIGFkZHJlc3MiKTsKICAgICAgICByZXF1aXJlKHNwZW5kZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSB0byB0aGUgemVybyBhZGRyZXNzIik7CgogICAgICAgIF9hbGxvd2VkW293bmVyXVtzcGVuZGVyXSA9IHZhbHVlOwogICAgICAgIGVtaXQgQXBwcm92YWwoIG93bmVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95RnJvbShhZGRyZXNzIGFjY291bnQsIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICBfZGVzdHJveShhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgX2FwcHJvdmUoYWNjb3VudCwgbXNnLnNlbmRlciwgX2FsbG93ZWRbYWNjb3VudF1bbXNnLnNlbmRlcl0uc3ViKHZhbHVlKSk7CiAgICB9Cn0KCg==', + 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(9, 3, 3, 'IBAC001', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKaW50ZXJmYWNlIElCQUMwMDEgewoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KTsKCiAgICBmdW5jdGlvbiBzZW5kKGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyA7CgogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gYWxsb3dhbmNlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYW1vdW50KSBwdWJsaWMgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVzdHJveSh1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gZGVzdHJveUZyb20oYWRkcmVzcyBmcm9tLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBmdW5jdGlvbiBiYXRjaFNlbmQoYWRkcmVzc1tdIHRvLCB1aW50MjU2W10gdmFsdWVzLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaW5jcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IGFkZGVkVmFsdWUpIHB1YmxpYyAgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBldmVudCBTZW5kKGFkZHJlc3MgaW5kZXhlZCBmcm9tLCBhZGRyZXNzIGluZGV4ZWQgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpOwoKICAgIGV2ZW50IEFwcHJvdmFsKGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpOwoKfQ==', + 'IyDnp6/liIblkIjnuqYKCiMjIOeugOS7iwogQkFDMDAxIOaYr+S4gOWll+WMuuWdl+mTvuenr+WIhuWQiOe6pu+8jOWFt+acieenr+WIhuebuOWFs+eahOWinuWPke+8jOmUgOavge+8jOaaguWBnOWQiOe6pu+8jOm7keeZveWQjeWNleetieadg+mZkOaOp+WItuetieWKn+iDveOAggoKIyMg5Zub5Liq5Z+65pys5YWD57SgCgotIGRlc2NyaXB0aW9uIAoKICDmraTnp6/liIbnmoTlhbfkvZPmj4/ov7AKCi0gc2hvcnROYW1lIAoKICDnp6/liIbnroDnp7AKCi0gbWluVW5pdCAKCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIHRvdGFsQW1vdW50IAoKICDnp6/liIbmgLvmlbDph48KCiMjIOS6lOS4quWfuuacrOihjOS4ujogCgotIOWPkeihjAoKICDosIPnlKjlkIjnuqbnmoQgZGVwbG95IOaWueazle+8jOS8oOWFpeS9oOWIneWni+WMlueahOWbm+S4quWFg+e0oOWNs+WPr++8jOWNs+WcqOWMuuWdl+mTvuS4iuWPkeihjOS6huS9oOaMh+WumuaAu+mHj+WSjOWQjeensOeahOenr+WIhuOAggoKICAtIOWFtuS4rSBtaW5Vbml0IOWSjCB0b3RhbEFtb3VudCDkuI3og73kuLrotJ/mlbDmiJblsI/mlbAKCi0g6L2s6LSmCgogIOiwg+eUqCBzZW5kIOaWueazleWNs+WPr+WunueOsOi9rOi0pu+8jOS5i+WQjuiwg+eUqCBiYWxhbmNlIOaWueazleWPr+S7peafpeeci+iHquW3seeahOenr+WIhuS9meminQoKLSDlop7lj5EKCiAg6LCD55SoIGlzc3VlIOaWueazleeJueWumuWcsOWdgOWinuWPkeenr+WIhu+8jCDlubblj6/ku6XpgJrov4cgYWRkSXNzdWVyIOWinuWKoOacieadg+mZkOWinuWPkeenr+WIhueahOS6uu+8jOS5n+WPr+S7pemAmui/h3Jlbm91bmNlSXNzdWVyIOaWueazleenu+mZpOWinuWPkeadg+mZkAoKLSDplIDmr4EKCiAg6LCD55SoIGRlc3Rvcnkg5Lul5Y+KIGRlc3RvcnlGcm9tIOmUgOavgeiHquW3seWcsOWdgOS4i+enr+WIhuWSjOeJueWumuWcsOWdgOS4i+eahOenr+WIhgoKLSDmmoLlgZwKCiAg6YGH5Yiw57Sn5oCl54q25Ya177yM5L2g5Y+v5Lul6LCD55SoIHN1c3BlbmQg5pa55rOV77yM5pqC5YGc5ZCI57qm77yM6L+Z5qC35Lu75L2V5Lq66YO95LiN6IO96LCD55SoIHNlbmQg5Ye95pWw44CC5pWF6Zqc5L+u5aSN5ZCO77yM5Y+v5Lul6LCD55SoIHVuU3VzcGVuZCDmlrnms5Xop6PpmaTmmoLlgZzjgILkuZ/lj6/ku6XpgJrov4cgYWRkU3VzcGVuZGVyIOWSjCByZW5vdW5jZVN1c3BlbmRlciDnm7jlupTlop7liqDlkoznp7vpmaTmmoLlgZzogIXmnYPpmZAKCgojIyDmjqXlj6Por7TmmI4KCi0gPGI+dG90YWxBbW91bnQoKTwvYj4KCiAg6L+U5Zue56ev5YiG5oC76YePCgogIC0g6L+Z6YeM55qE56ev5YiG5oC76YeP6ZyA6KaB6K6h566X5pyA5bCP6L2s6LSm5Y2V5L2N77yM5omA5Lul5a6e6ZmF6L+U5Zue5YC85Li6ICAgdG90YWxBbW91bnQgKiAxMDxzdXA+bWluVW5pdDwvc3VwPiAKCi0gPGI+YmFsYW5jZShhZGRyZXNzIG93bmVyKTwvYj4KCiAg6L+U5Zueb3duZXLnmoTluJDmiLfnmoTnp6/liIbkvZnpop0KCi0gPGI+c2VuZChhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlICwgc3RyaW5nIGRhdGEpPC9iPgoKICDlsIbmlbDph4/kuLp2YWx1ZeeahOenr+WIhui9rOWFpeWcsOWdgCB0byDlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu2LCBkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV6L+b6KGM5q2k5pON5L2cCiAgLSDor7fpgb/lhY0gdG8g5Li66Ieq6Lqr6L+b6KGM5pON5L2cCgotIDxiPnNlbmRGcm9tKGFkZHJlc3MgZnJvbSxhZGRyZXNzIHRvLHVpbnQyNTYgdmFsdWXvvIxzdHJpbmcgIGRhdGEpKTwvYj4KCiAg5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byDvvIzlubbop6blj5EgdHJhbnNmZXIg5LqL5Lu277yMZGF0YSDmmK/ovazotKblpIfms6jjgIIKCiAgLSDmlrnms5XnmoTosIPnlKjogIXlj6/ku6XkuI3kuLogZnJvbe+8jCDmraTml7bpnIDopoHpooTlhYjov5vooYwgYXBwcm92ZSDmjojmnYMKCiAgLSBmcm9tIOS4jeiDveS4uuiwg+eUqOiAheiHqui6q+WcsOWdgO+8jOWQpuWImeS8muaKpemUmQogIC0gc3VzcGVuZCDnirbmgIHkuIvml6Dms5XmiafooYzmraTmk43kvZwKCi0gPGI+c2FmZVNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgIHN0cmluZyBkYXRhKTwvYj4KCiAg5a6J5YWo55qE5bCG5Zyw5Z2AIGZyb20g5Lit55qEIHZhbHVlIOaVsOmHj+eahOenr+WIhui9rOWFpeWcsOWdgCB0byAoIHRv5aaC5p6c5piv5ZCI57qm5Zyw5Z2A77yM5b+F6aG75a6e546w5o6l5pS25o6l5Y+jIEJBQzAwMUhvbGRlciDmiY3lj6/ku6XmjqXmlLbovazotKYpIO+8jOW5tuinpuWPkSB0cmFuc2ZlciDkuovku7bvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIHN1c3BlbmQg54q25oCB5LiL5peg5rOV5omn6KGM5q2k5pON5L2cCgotIDxiPnNhZmVCYXRjaFNlbmQoIGFkZHJlc3NbXSB0bywgdWludDI1NltdICB2YWx1ZXMsIHN0cmluZyAgZGF0YSk8L2I+CgogIOaJuemHj+WwhuiHquW3sei0puaIt+S4i+eahOenr+WIhui9rOe7mSB0byDmlbDnu4TnmoTlnLDlnYDvvIwgdG8g5ZKMIHZhbHVlcyDnmoTkuKrmlbDopoHkuIDoh7QKCiAgLSBzdXNwZW5kIOeKtuaAgeS4i+aXoOazleaJp+ihjOatpOaTjeS9nAoKLSA8Yj5hcHByb3ZlKGFkZHJlc3Mgc3BlbmRlcix1aW50MjU2IHZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5LuO6Ieq5bex6LSm5oi35o+Q5Y+W6ZmQ6aKdIHZhbHVlIOeahOenr+WIhgoKICAtIOatpOaWueazlemFjeWQiCBzZW5kZnJvbSAvIHNhZmVzZW5kZnJvbSDkuIDotbfkvb/nlKgKICAtIOmHjeWkjeaOiOadg+aXtu+8jOacgOe7iOaOiOadg+mineW6puS4uuacgOWQjuS4gOasoeaOiOadg+eahOWAvAoKLSA8Yj5hbGxvd2FuY2UoYWRkcmVzcyBvd25lcixhZGRyZXNzIHNwZW5kZXIpPC9iPgoKICDov5Tlm54gc3BlbmRlciDlj6/ku44gb3duZXIg5o+Q5Y+W55qE56ev5YiG5pWw6YeP5LiK6ZmQCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5LiA6LW35L2/55SoCgotIDxiPmluY3JlYXNlQWxsb3dhbmNlKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiBhZGRlZFZhbHVlKTwvYj4KCiAg5YWB6K64IHNwZW5kZXIg5o+Q5Y+W55qE56ev5YiG5LiK6ZmQ5Zyo5Y6f5pyJ5Z+656GA5LiK5aKe5YqgIGFkZGVkVmFsdWUKCiAgLSDmraTmlrnms5XphY3lkIggYXBwcm92ZSDkvb/nlKgKCi0gPGI+ZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSk8L2I+CgogIOWFgeiuuCBzcGVuZGVyICDmj5Dlj5bnmoTnp6/liIbkuIrpmZDlnKjljp/mnInln7rnoYDkuIrlh4/lsJEgc3VidHJhY3RlZFZhbHVlCgogIC0g5q2k5pa55rOV6YWN5ZCIIGFwcHJvdmUg5L2/55SoCgotIDxiPm1pblVuaXQoKTwvYj4KCiAg56ev5YiG5pyA5bCP5Y2V5L2NCgotIDxiPnNob3J0TmFtZSgpPC9iPgoKICDnp6/liIbnroDnp7AKCi0gPGI+ZGVzY3JpcHRpb24oKTwvYj4KCiAg56ev5YiG5o+P6L+wCgotIDxiPmRlc3RvcnkodWludDI1NiB2YWx1Ze+8jCBzdHJpbmcgIGRhdGEpPC9iPgoKICDlh4/lsJHoh6rlt7HnmoTnp6/liIbvvIxkYXRhIOaYr+i9rOi0puWkh+azqAoKICAtIOiwg+eUqOaXtu+8jHZhbHVlIOWAvOmcgOimgeWwj+S6juetieS6juebruWJjeiHquW3seeahOenr+WIhuaAu+mHjwoKLSA8Yj5kZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWXvvIwgc3RyaW5nICBkYXRhKTwvYj4KCiAg5YeP5bCR5Zyw5Z2AIGZyb20g56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCiAgLSDosIPnlKjmraTmlrnms5Xml7bvvIzpnIDopoHphY3lkIggYXBwcm92ZSDov5vooYzkvb/nlKgKCi0gPGI+aXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1Ze+8jHN0cmluZyAgZGF0YSk8L2I+CgogIOe7meWcsOWdgCB0byDlop7liqDmlbDph4/kuLogdmFsdWUg55qE56ev5YiG77yMZGF0YSDmmK/ovazotKblpIfms6gKCi0gPGI+aXNJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5qOA5p+lIGFjY291bnQg5piv5ZCm5pyJ5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPmFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDkvb/lnLDlnYAgYWNjb3VudCDmi6XmnInlop7liqDnp6/liIbnmoTmnYPpmZAKCi0gPGI+cmVub3VuY2VJc3N1ZXIoKTwvYj4KCiAg56e76Zmk5aKe5Yqg56ev5YiG55qE5p2D6ZmQCgotIDxiPnN1c3BlbmQoKTwvYj4KCiAg5pqC5YGc5ZCI57qmCgogIC0gc3VzcGVuZCDlkI7ml6Dms5Xov5vooYwgc2VuZCAvIHNhZmVzZW5kZnJvbSAvIHNlbmRmcm9tIC8gc2FmZUJhdGNoU2VuZCAvIGFwcHJvdmVzIOaTjeS9nAoKLSA8Yj51blN1c3BlbmQoKTwvYj4KCiAg6YeN5ZCv5ZCI57qmCiAgCi0gPGI+c3VzcGVuZGVkPC9iPgoKICDliKTmlq3lkIjnuqbmmK/lkKblpITkuo7mmoLlgZznirbmgIEKCi0gPGI+aXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KTwvYj4KCiAg5piv5ZCm5pyJ5pqC5YGc5ZCI57qm5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQg5pa55rOV5LiA6LW35L2/55SoCgotIDxiPmFkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpPC9iPgoKICDlop7liqDmmoLlgZzmnYPpmZDogIUKCiAgLSDphY3lkIggc3VzcGVuZCDmlrnms5XkuIDotbfkvb/nlKgKCi0gPGI+cmVub3VuY2VTdXNwZW5kZXIoKTwvYj4KCiAg56e76Zmk5pqC5YGc5p2D6ZmQCgogIC0g6YWN5ZCIIHN1c3BlbmQgLyBhZGRTdXNwZW5kZXIg5pa55rOV5L2/55SoCgoK', '', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(10, 3, 3, 'Roles', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=', + 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', 'IyBSb2xlcwoKUm9sZSBwZXJtaXNzaW9ucyBjb250cm9sIGNvbnRyYWN0cwo=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(11, 3, 3, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', + 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', 'IyBTYWZlTWF0aAoKU2FmZU1hdGggbGlicmFyeQoKQSBzZWN1cmUgbWF0aGVtYXRpY2FsIGxpYnJhcnkgdGhhdCBwcm92aWRlcyBhIHNhZmUgYWRkaXRpb24sIHN1YnRyYWN0LCBhbmQgZGl2aWRl44CCVGhlIHVzZSBvZiBzZWN1cmUgbWF0aGVtYXRpY2FsIGNvbnRyYWN0cyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgII=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(12, 3, 3, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', + 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); +-- smart dev contracts +-- tools basic +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(13, 1, 4, 'Crypto', 'Y29udHJhY3QgQ3J5cHRvCnsKICAgIGZ1bmN0aW9uIHNtMyhieXRlcyBtZW1vcnkgZGF0YSkgcHVibGljIHZpZXcgcmV0dXJucyhieXRlczMyKXt9CiAgICBmdW5jdGlvbiBrZWNjYWsyNTZIYXNoKGJ5dGVzIG1lbW9yeSBkYXRhKSBwdWJsaWMgdmlldyByZXR1cm5zKGJ5dGVzMzIpe30KICAgIGZ1bmN0aW9uIHNtMlZlcmlmeShieXRlczMyICBtZXNzYWdlLCBieXRlcyBtZW1vcnkgcHVibGljS2V5LCBieXRlczMyIHIsIGJ5dGVzMzIgcykgcHVibGljIHZpZXcgcmV0dXJucyhib29sLCBhZGRyZXNzKXt9CiAgICBmdW5jdGlvbiBjdXJ2ZTI1NTE5VlJGVmVyaWZ5KHN0cmluZyBtZW1vcnkgaW5wdXQsIHN0cmluZyBtZW1vcnkgdnJmUHVibGljS2V5LCBzdHJpbmcgbWVtb3J5IHZyZlByb29mKSBwdWJsaWMgdmlldyByZXR1cm5zKGJvb2wsdWludDI1Nil7fQp9', + 'IyBDcnlwdG8KCkNyeXB0byBJbnRlcmZhY2UgQ29udHJhY3Q=', 'IyBDcnlwdG8KCkNyeXB0byBJbnRlcmZhY2UgQ29udHJhY3Q=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(14, 1, 4, 'ShaTest', 'cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CgpwcmFnbWEgZXhwZXJpbWVudGFsIEFCSUVuY29kZXJWMjsKCmltcG9ydCAiLi9DcnlwdG8uc29sIjsKCmNvbnRyYWN0IFNoYVRlc3R7CiAgICBieXRlcyBfZGF0YSA9ICJIZWxsbywgU2hhVGVzdCI7CiAgICBDcnlwdG8gY3J5cHRvOwoKICAgIGNvbnN0cnVjdG9yKCkgcHVibGljIHsKICAgICAgICBjcnlwdG8gPSBDcnlwdG8oMHg1MDA2KTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRTaGEyNTYoYnl0ZXMgbWVtb3J5IF9tZW1vcnkpIHB1YmxpYyByZXR1cm5zKGJ5dGVzMzIgcmVzdWx0KQogICAgewogICAgICAgIHJldHVybiBzaGEyNTYoX21lbW9yeSk7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0S2VjY2FrMjU2KGJ5dGVzIG1lbW9yeSBfbWVtb3J5KSBwdWJsaWMgcmV0dXJucyhieXRlczMyIHJlc3VsdCkKICAgIHsKICAgICAgICByZXR1cm4ga2VjY2FrMjU2KF9tZW1vcnkpOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldERhdGEoKSBwdWJsaWMgdmlldyByZXR1cm5zKGJ5dGVzIG1lbW9yeSkKICAgIHsKICAgICAgICByZXR1cm4gX2RhdGE7CiAgICB9Cn0K', +'IyBTaGFUZXN0CgpDcnlwdG8gSW50ZXJmYWNlIENvbnRyYWN0CgpDcnlwdG8gVGVzdCBDb250cmFjdCBbQ3J5cHRvIEFQSV0oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9kZWZhdWx0L0NyeXB0by5odG1sKQo=', 'IyBTaGFUZXN0CgpDcnlwdG8gSW50ZXJmYWNlIENvbnRyYWN0CgpDcnlwdG8gVGVzdCBDb250cmFjdCBbQ3J5cHRvIEFQSV0oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9kZWZhdWx0L0NyeXB0by5odG1sKQo=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(15, 1, 4, 'HelloWorld', 'cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7Cgpjb250cmFjdCBIZWxsb1dvcmxkIHsKICAgIHN0cmluZyBuYW1lOwoKICAgIGNvbnN0cnVjdG9yKCkgcHVibGljIHsKICAgICAgICBuYW1lID0gIkhlbGxvLCBXb3JsZCEiOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gbmFtZTsKICAgIH0KCiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nIG1lbW9yeSBuKSBwdWJsaWMgewogICAgICAgIG5hbWUgPSBuOwogICAgfQp9', + 'IyBIZWxsb1dvcmxkCgpIZWxsb1dvcmxkIENvbnRyYWN0Cg==', 'IyBIZWxsb1dvcmxkCgpIZWxsb1dvcmxkIENvbnRyYWN0Cg==', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(16, 1, 4, 'KVTableTest', 'cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CgppbXBvcnQgIi4vVGFibGUuc29sIjsKCmNvbnRyYWN0IEtWVGFibGVUZXN0IHsKICAgIGV2ZW50IFNldFJlc3VsdChpbnQyNTYgY291bnQpOwoKICAgIEtWVGFibGVGYWN0b3J5IHRhYmxlRmFjdG9yeTsKICAgIHN0cmluZyBjb25zdGFudCBUQUJMRV9OQU1FID0gInRfa3Z0ZXN0IjsKCiAgICBjb25zdHJ1Y3RvcigpIHB1YmxpYyB7CiAgICAgICAgLy9UaGUgZml4ZWQgYWRkcmVzcyBpcyAweDEwMTAgZm9yIEtWVGFibGVGYWN0b3J5CiAgICAgICAgdGFibGVGYWN0b3J5ID0gS1ZUYWJsZUZhY3RvcnkoMHgxMDEwKTsKICAgICAgICAvLyB0aGUgcGFyYW1ldGVycyBvZiBjcmVhdGVUYWJsZSBhcmUgdGFibGVOYW1lLGtleUZpZWxkLCJ2bGF1ZUZpbGVkMSx2bGF1ZUZpbGVkMix2bGF1ZUZpbGVkMywuLi4iCiAgICAgICAgdGFibGVGYWN0b3J5LmNyZWF0ZVRhYmxlKFRBQkxFX05BTUUsICJpZCIsICJpdGVtX3ByaWNlLGl0ZW1fbmFtZSIpOwogICAgfQoKICAgIC8vZ2V0IHJlY29yZAogICAgZnVuY3Rpb24gZ2V0KHN0cmluZyBtZW1vcnkgaWQpIHB1YmxpYyB2aWV3IHJldHVybnMgKGJvb2wsIGludDI1Niwgc3RyaW5nIG1lbW9yeSkgewogICAgICAgIEtWVGFibGUgdGFibGUgPSB0YWJsZUZhY3Rvcnkub3BlblRhYmxlKFRBQkxFX05BTUUpOwogICAgICAgIGJvb2wgb2sgPSBmYWxzZTsKICAgICAgICBFbnRyeSBlbnRyeTsKICAgICAgICAob2ssIGVudHJ5KSA9IHRhYmxlLmdldChpZCk7CiAgICAgICAgaW50MjU2IGl0ZW1fcHJpY2U7CiAgICAgICAgc3RyaW5nIG1lbW9yeSBpdGVtX25hbWU7CiAgICAgICAgaWYgKG9rKSB7CiAgICAgICAgICAgIGl0ZW1fcHJpY2UgPSBlbnRyeS5nZXRJbnQoIml0ZW1fcHJpY2UiKTsKICAgICAgICAgICAgaXRlbV9uYW1lID0gZW50cnkuZ2V0U3RyaW5nKCJpdGVtX25hbWUiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChvaywgaXRlbV9wcmljZSwgaXRlbV9uYW1lKTsKICAgIH0KCiAgICAvL3NldCByZWNvcmQKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcgbWVtb3J5IGlkLCBpbnQyNTYgaXRlbV9wcmljZSwgc3RyaW5nIG1lbW9yeSBpdGVtX25hbWUpCiAgICBwdWJsaWMKICAgIHJldHVybnMgKGludDI1NikKICAgIHsKICAgICAgICBLVlRhYmxlIHRhYmxlID0gdGFibGVGYWN0b3J5Lm9wZW5UYWJsZShUQUJMRV9OQU1FKTsKICAgICAgICBFbnRyeSBlbnRyeSA9IHRhYmxlLm5ld0VudHJ5KCk7CiAgICAgICAgLy8gdGhlIGxlbmd0aCBvZiBlbnRyeSdzIGZpZWxkIHZhbHVlIHNob3VsZCA8IDE2TUIKICAgICAgICBlbnRyeS5zZXQoImlkIiwgaWQpOwogICAgICAgIGVudHJ5LnNldCgiaXRlbV9wcmljZSIsIGl0ZW1fcHJpY2UpOwogICAgICAgIGVudHJ5LnNldCgiaXRlbV9uYW1lIiwgaXRlbV9uYW1lKTsKICAgICAgICAvLyB0aGUgZmlyc3QgcGFyYW1ldGVyIGxlbmd0aCBvZiBzZXQgc2hvdWxkIDw9IDI1NUIKICAgICAgICBpbnQyNTYgY291bnQgPSB0YWJsZS5zZXQoaWQsIGVudHJ5KTsKICAgICAgICBlbWl0IFNldFJlc3VsdChjb3VudCk7CiAgICAgICAgcmV0dXJuIGNvdW50OwogICAgfQp9', + 'IyBLVlRhYmxlVGVzdAoKS1ZUYWJsZSBjb250cmFjdCBmb3IgQ1JVRCAKCkNSVUQgVGVzdCwgW0NSVUQgQVBJXShodHRwczovL2Zpc2NvLWJjb3MtZG9jdW1lbnRhdGlvbi5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9hcnRpY2xlcy8zX2ZlYXR1cmVzLzMzX3N0b3JhZ2UvY3J1ZF9ndWlkYW5jZS5odG1sKQo=', 'IyBLVlRhYmxlVGVzdAoKS1ZUYWJsZSBjb250cmFjdCBmb3IgQ1JVRCAKCkNSVUQgVGVzdCwgW0NSVUQgQVBJXShodHRwczovL2Zpc2NvLWJjb3MtZG9jdW1lbnRhdGlvbi5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9hcnRpY2xlcy8zX2ZlYXR1cmVzLzMzX3N0b3JhZ2UvY3J1ZF9ndWlkYW5jZS5odG1sKQo=', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(17, 1, 4, 'Table', 'CmNvbnRyYWN0IFRhYmxlRmFjdG9yeSB7CiAgICBmdW5jdGlvbiBvcGVuVGFibGUoc3RyaW5nIG1lbW9yeSkgcHVibGljIHZpZXcgcmV0dXJucyAoVGFibGUpIHt9IC8vb3BlbiB0YWJsZQogICAgZnVuY3Rpb24gY3JlYXRlVGFibGUoc3RyaW5nIG1lbW9yeSwgc3RyaW5nIG1lbW9yeSwgc3RyaW5nIG1lbW9yeSkgcHVibGljIHJldHVybnMgKGludDI1Nikge30gLy9jcmVhdGUgdGFibGUKfQoKLy9zZWxlY3QgY29uZGl0aW9uCmNvbnRyYWN0IENvbmRpdGlvbiB7CiAgICBmdW5jdGlvbiBFUShzdHJpbmcgbWVtb3J5LCBpbnQyNTYpIHB1YmxpYyB2aWV3e30KICAgIGZ1bmN0aW9uIEVRKHN0cmluZyBtZW1vcnksIHN0cmluZyBtZW1vcnkpIHB1YmxpYyB2aWV3e30KCiAgICBmdW5jdGlvbiBORShzdHJpbmcgbWVtb3J5LCBpbnQyNTYpIHB1YmxpYyB2aWV3e30KICAgIGZ1bmN0aW9uIE5FKHN0cmluZyBtZW1vcnksIHN0cmluZyBtZW1vcnkpIHB1YmxpYyB2aWV3e30KCiAgICBmdW5jdGlvbiBHVChzdHJpbmcgbWVtb3J5LCBpbnQyNTYpIHB1YmxpYyB2aWV3e30KICAgIGZ1bmN0aW9uIEdFKHN0cmluZyBtZW1vcnksIGludDI1NikgcHVibGljIHZpZXd7fQoKICAgIGZ1bmN0aW9uIExUKHN0cmluZyBtZW1vcnksIGludDI1NikgcHVibGljIHZpZXd7fQogICAgZnVuY3Rpb24gTEUoc3RyaW5nIG1lbW9yeSwgaW50MjU2KSBwdWJsaWMgdmlld3t9CgogICAgZnVuY3Rpb24gbGltaXQoaW50MjU2KSBwdWJsaWMgdmlld3t9CiAgICBmdW5jdGlvbiBsaW1pdChpbnQyNTYsIGludDI1NikgcHVibGljIHZpZXd7fQp9CgovL29uZSByZWNvcmQKY29udHJhY3QgRW50cnkgewogICAgZnVuY3Rpb24gZ2V0SW50KHN0cmluZyBtZW1vcnkpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nikge30KICAgIGZ1bmN0aW9uIGdldFVJbnQoc3RyaW5nIG1lbW9yeSkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nikge30KICAgIGZ1bmN0aW9uIGdldEFkZHJlc3Moc3RyaW5nIG1lbW9yeSkgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcykge30KICAgIGZ1bmN0aW9uIGdldEJ5dGVzNjQoc3RyaW5nIG1lbW9yeSkgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMxWzY0XSBtZW1vcnkpIHt9CiAgICBmdW5jdGlvbiBnZXRCeXRlczMyKHN0cmluZyBtZW1vcnkpIHB1YmxpYyB2aWV3IHJldHVybnMgKGJ5dGVzMzIpIHt9CiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nIG1lbW9yeSkgcHVibGljIHZpZXcgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSkge30KCiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nIG1lbW9yeSwgaW50MjU2KSBwdWJsaWMge30KICAgIGZ1bmN0aW9uIHNldChzdHJpbmcgbWVtb3J5LCB1aW50MjU2KSBwdWJsaWMge30KICAgIGZ1bmN0aW9uIHNldChzdHJpbmcgbWVtb3J5LCBzdHJpbmcgbWVtb3J5KSBwdWJsaWMge30KICAgIGZ1bmN0aW9uIHNldChzdHJpbmcgbWVtb3J5LCBhZGRyZXNzKSBwdWJsaWMge30KfQoKLy9yZWNvcmQgc2V0cwpjb250cmFjdCBFbnRyaWVzIHsKICAgIGZ1bmN0aW9uIGdldChpbnQyNTYpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KSB7fQogICAgZnVuY3Rpb24gc2l6ZSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nikge30KfQoKLy9UYWJsZSBtYWluIGNvbnRyYWN0CmNvbnRyYWN0IFRhYmxlIHsKICAgIGZ1bmN0aW9uIHNlbGVjdChzdHJpbmcgbWVtb3J5LCBDb25kaXRpb24pIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJpZXMpIHt9CiAgICBmdW5jdGlvbiBpbnNlcnQoc3RyaW5nIG1lbW9yeSwgRW50cnkpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpIHt9CiAgICBmdW5jdGlvbiB1cGRhdGUoc3RyaW5nIG1lbW9yeSwgRW50cnksIENvbmRpdGlvbikgcHVibGljIHJldHVybnMgKGludDI1Nikge30KICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcgbWVtb3J5LCBDb25kaXRpb24pIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpIHt9CgogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSkge30KICAgIGZ1bmN0aW9uIG5ld0NvbmRpdGlvbigpIHB1YmxpYyB2aWV3IHJldHVybnMgKENvbmRpdGlvbikge30KfQoKY29udHJhY3QgS1ZUYWJsZUZhY3RvcnkgewogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZyBtZW1vcnkpIHB1YmxpYyB2aWV3IHJldHVybnMgKEtWVGFibGUpIHt9CiAgICBmdW5jdGlvbiBjcmVhdGVUYWJsZShzdHJpbmcgbWVtb3J5LCBzdHJpbmcgbWVtb3J5LCBzdHJpbmcgbWVtb3J5KSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KSB7fQp9CgovL0tWVGFibGUgcGVyIHBlcm1pYXJ5IGtleSBoYXMgb25seSBvbmUgRW50cnkKY29udHJhY3QgS1ZUYWJsZSB7CiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nIG1lbW9yeSkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCwgRW50cnkpIHt9CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nIG1lbW9yeSwgRW50cnkpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpIHt9CiAgICBmdW5jdGlvbiBuZXdFbnRyeSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KSB7fQp9Cg==', + 'IyBUYWJsZQoKVGFibGUgY29udHJhY3QgZm9yIENSVUQsIFtDUlVEIEFQSV0oaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8vemhfQ04vbGF0ZXN0L2RvY3MvYXJ0aWNsZXMvM19mZWF0dXJlcy8zM19zdG9yYWdlL2NydWRfZ3VpZGFuY2UuaHRtbCkK', 'IyBUYWJsZQoKVGFibGUgY29udHJhY3QgZm9yIENSVUQsIFtDUlVEIEFQSV0oaHR0cHM6Ly9maXNjby1iY29zLWRvY3VtZW50YXRpb24ucmVhZHRoZWRvY3MuaW8vemhfQ04vbGF0ZXN0L2RvY3MvYXJ0aWNsZXMvM19mZWF0dXJlcy8zM19zdG9yYWdlL2NydWRfZ3VpZGFuY2UuaHRtbCkK', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(18, 1, 4, 'TableTest', 'cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CnByYWdtYSBleHBlcmltZW50YWwgQUJJRW5jb2RlclYyOwoKaW1wb3J0ICIuL1RhYmxlLnNvbCI7Cgpjb250cmFjdCBUYWJsZVRlc3QgewogICAgZXZlbnQgQ3JlYXRlUmVzdWx0KGludDI1NiBjb3VudCk7CiAgICBldmVudCBJbnNlcnRSZXN1bHQoaW50MjU2IGNvdW50KTsKICAgIGV2ZW50IFVwZGF0ZVJlc3VsdChpbnQyNTYgY291bnQpOwogICAgZXZlbnQgUmVtb3ZlUmVzdWx0KGludDI1NiBjb3VudCk7CgogICAgVGFibGVGYWN0b3J5IHRhYmxlRmFjdG9yeTsKICAgIHN0cmluZyBjb25zdGFudCBUQUJMRV9OQU1FID0gInRfdGVzdCI7CiAgICBjb25zdHJ1Y3RvcigpIHB1YmxpYyB7CiAgICAgICAgdGFibGVGYWN0b3J5ID0gVGFibGVGYWN0b3J5KDB4MTAwMSk7IC8vVGhlIGZpeGVkIGFkZHJlc3MgaXMgMHgxMDAxIGZvciBUYWJsZUZhY3RvcnkKICAgICAgICAvLyB0aGUgcGFyYW1ldGVycyBvZiBjcmVhdGVUYWJsZSBhcmUgdGFibGVOYW1lLGtleUZpZWxkLCJ2bGF1ZUZpbGVkMSx2bGF1ZUZpbGVkMix2bGF1ZUZpbGVkMywuLi4iCiAgICAgICAgdGFibGVGYWN0b3J5LmNyZWF0ZVRhYmxlKFRBQkxFX05BTUUsICJuYW1lIiwgIml0ZW1faWQsaXRlbV9uYW1lIik7CiAgICB9CgogICAgLy9zZWxlY3QgcmVjb3JkcwogICAgZnVuY3Rpb24gc2VsZWN0KHN0cmluZyBtZW1vcnkgbmFtZSkKICAgIHB1YmxpYwogICAgdmlldwogICAgcmV0dXJucyAoc3RyaW5nW10gbWVtb3J5LCBpbnQyNTZbXSBtZW1vcnksIHN0cmluZ1tdIG1lbW9yeSkKICAgIHsKICAgICAgICBUYWJsZSB0YWJsZSA9IHRhYmxlRmFjdG9yeS5vcGVuVGFibGUoVEFCTEVfTkFNRSk7CgogICAgICAgIENvbmRpdGlvbiBjb25kaXRpb24gPSB0YWJsZS5uZXdDb25kaXRpb24oKTsKCiAgICAgICAgRW50cmllcyBlbnRyaWVzID0gdGFibGUuc2VsZWN0KG5hbWUsIGNvbmRpdGlvbik7CiAgICAgICAgc3RyaW5nW10gbWVtb3J5IHVzZXJfbmFtZV9ieXRlc19saXN0ID0gbmV3IHN0cmluZ1tdKAogICAgICAgICAgICB1aW50MjU2KGVudHJpZXMuc2l6ZSgpKQogICAgICAgICk7CiAgICAgICAgaW50MjU2W10gbWVtb3J5IGl0ZW1faWRfbGlzdCA9IG5ldyBpbnQyNTZbXSh1aW50MjU2KGVudHJpZXMuc2l6ZSgpKSk7CiAgICAgICAgc3RyaW5nW10gbWVtb3J5IGl0ZW1fbmFtZV9ieXRlc19saXN0ID0gbmV3IHN0cmluZ1tdKAogICAgICAgICAgICB1aW50MjU2KGVudHJpZXMuc2l6ZSgpKQogICAgICAgICk7CgogICAgICAgIGZvciAoaW50MjU2IGkgPSAwOyBpIDwgZW50cmllcy5zaXplKCk7ICsraSkgewogICAgICAgICAgICBFbnRyeSBlbnRyeSA9IGVudHJpZXMuZ2V0KGkpOwoKICAgICAgICAgICAgdXNlcl9uYW1lX2J5dGVzX2xpc3RbdWludDI1NihpKV0gPSBlbnRyeS5nZXRTdHJpbmcoIm5hbWUiKTsKICAgICAgICAgICAgaXRlbV9pZF9saXN0W3VpbnQyNTYoaSldID0gZW50cnkuZ2V0SW50KCJpdGVtX2lkIik7CiAgICAgICAgICAgIGl0ZW1fbmFtZV9ieXRlc19saXN0W3VpbnQyNTYoaSldID0gZW50cnkuZ2V0U3RyaW5nKCJpdGVtX25hbWUiKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAodXNlcl9uYW1lX2J5dGVzX2xpc3QsIGl0ZW1faWRfbGlzdCwgaXRlbV9uYW1lX2J5dGVzX2xpc3QpOwogICAgfQogICAgLy9pbnNlcnQgcmVjb3JkcwogICAgZnVuY3Rpb24gaW5zZXJ0KHN0cmluZyBtZW1vcnkgbmFtZSwgaW50MjU2IGl0ZW1faWQsIHN0cmluZyBtZW1vcnkgaXRlbV9uYW1lKQogICAgcHVibGljCiAgICByZXR1cm5zIChpbnQyNTYpCiAgICB7CiAgICAgICAgVGFibGUgdGFibGUgPSB0YWJsZUZhY3Rvcnkub3BlblRhYmxlKFRBQkxFX05BTUUpOwoKICAgICAgICBFbnRyeSBlbnRyeSA9IHRhYmxlLm5ld0VudHJ5KCk7CiAgICAgICAgZW50cnkuc2V0KCJuYW1lIiwgbmFtZSk7CiAgICAgICAgZW50cnkuc2V0KCJpdGVtX2lkIiwgaXRlbV9pZCk7CiAgICAgICAgZW50cnkuc2V0KCJpdGVtX25hbWUiLCBpdGVtX25hbWUpOwoKICAgICAgICBpbnQyNTYgY291bnQgPSB0YWJsZS5pbnNlcnQobmFtZSwgZW50cnkpOwogICAgICAgIGVtaXQgSW5zZXJ0UmVzdWx0KGNvdW50KTsKCiAgICAgICAgcmV0dXJuIGNvdW50OwogICAgfQogICAgLy91cGRhdGUgcmVjb3JkcwogICAgZnVuY3Rpb24gdXBkYXRlKHN0cmluZyBtZW1vcnkgbmFtZSwgaW50MjU2IGl0ZW1faWQsIHN0cmluZyBtZW1vcnkgaXRlbV9uYW1lKQogICAgcHVibGljCiAgICByZXR1cm5zIChpbnQyNTYpCiAgICB7CiAgICAgICAgVGFibGUgdGFibGUgPSB0YWJsZUZhY3Rvcnkub3BlblRhYmxlKFRBQkxFX05BTUUpOwoKICAgICAgICBFbnRyeSBlbnRyeSA9IHRhYmxlLm5ld0VudHJ5KCk7CiAgICAgICAgZW50cnkuc2V0KCJpdGVtX25hbWUiLCBpdGVtX25hbWUpOwoKICAgICAgICBDb25kaXRpb24gY29uZGl0aW9uID0gdGFibGUubmV3Q29uZGl0aW9uKCk7CiAgICAgICAgY29uZGl0aW9uLkVRKCJuYW1lIiwgbmFtZSk7CiAgICAgICAgY29uZGl0aW9uLkVRKCJpdGVtX2lkIiwgaXRlbV9pZCk7CgogICAgICAgIGludDI1NiBjb3VudCA9IHRhYmxlLnVwZGF0ZShuYW1lLCBlbnRyeSwgY29uZGl0aW9uKTsKICAgICAgICBlbWl0IFVwZGF0ZVJlc3VsdChjb3VudCk7CgogICAgICAgIHJldHVybiBjb3VudDsKICAgIH0KICAgIC8vcmVtb3ZlIHJlY29yZHMKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcgbWVtb3J5IG5hbWUsIGludDI1NiBpdGVtX2lkKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KSB7CiAgICAgICAgVGFibGUgdGFibGUgPSB0YWJsZUZhY3Rvcnkub3BlblRhYmxlKFRBQkxFX05BTUUpOwoKICAgICAgICBDb25kaXRpb24gY29uZGl0aW9uID0gdGFibGUubmV3Q29uZGl0aW9uKCk7CiAgICAgICAgY29uZGl0aW9uLkVRKCJuYW1lIiwgbmFtZSk7CiAgICAgICAgY29uZGl0aW9uLkVRKCJpdGVtX2lkIiwgaXRlbV9pZCk7CgogICAgICAgIGludDI1NiBjb3VudCA9IHRhYmxlLnJlbW92ZShuYW1lLCBjb25kaXRpb24pOwogICAgICAgIGVtaXQgUmVtb3ZlUmVzdWx0KGNvdW50KTsKCiAgICAgICAgcmV0dXJuIGNvdW50OwogICAgfQp9Cg==', + 'IyBUYWJsZVRlc3QKClRhYmxlIGNvbnRyYWN0IGZvciBDUlVEIAoKQ1JVRCBUZXN0LCBbQ1JVRCBBUEldKGh0dHBzOi8vZmlzY28tYmNvcy1kb2N1bWVudGF0aW9uLnJlYWR0aGVkb2NzLmlvL3poX0NOL2xhdGVzdC9kb2NzL2FydGljbGVzLzNfZmVhdHVyZXMvMzNfc3RvcmFnZS9jcnVkX2d1aWRhbmNlLmh0bWwpCg==', 'IyBUYWJsZVRlc3QKClRhYmxlIGNvbnRyYWN0IGZvciBDUlVEIAoKQ1JVRCBUZXN0LCBbQ1JVRCBBUEldKGh0dHBzOi8vZmlzY28tYmNvcy1kb2N1bWVudGF0aW9uLnJlYWR0aGVkb2NzLmlvL3poX0NOL2xhdGVzdC9kb2NzL2FydGljbGVzLzNfZmVhdHVyZXMvMzNfc3RvcmFnZS9jcnVkX2d1aWRhbmNlLmh0bWwpCg==', now(), now()); +-- evidence +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(19, 4, 5, 'EvidenceController', 'Ci8qCiAqIENvcHlyaWdodCAyMDE0LTIwMTkgdGhlIG9yaWdpbmFsIGF1dGhvciBvciBhdXRob3JzLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogKi8KCnByYWdtYSBzb2xpZGl0eSA+PTAuNC4yNCA8MC42LjExOyAKCmltcG9ydCAiLi9SZXF1ZXN0UmVwb3NpdG9yeS5zb2wiOwppbXBvcnQgIi4vRXZpZGVuY2VSZXBvc2l0b3J5LnNvbCI7Cgpjb250cmFjdCBFdmlkZW5jZUNvbnRyb2xsZXJ7CiAgICBSZXF1ZXN0UmVwb3NpdG9yeSBwdWJsaWMgX3JlcXVlc3RSZXBvOwogICAgRXZpZGVuY2VSZXBvc2l0b3J5IHB1YmxpYyBfZXZpZGVuY2VSZXBvOwoKICAgIGV2ZW50IENyZWF0ZVNhdmVSZXF1ZXN0KGJ5dGVzMzIgaW5kZXhlZCBoYXNoLCBhZGRyZXNzIGNyZWF0b3IpOyAgIAogICAgZXZlbnQgVm90ZVNhdmVSZXF1ZXN0KGJ5dGVzMzIgaW5kZXhlZCBoYXNoLCBhZGRyZXNzIHZvdGVyLCBib29sIGNvbXBsZXRlKTsKICAgIGV2ZW50IEV2aWRlbmNlU2F2ZWQoYnl0ZXMzMiBpbmRleGVkIGhhc2gpOwoKICAgIGNvbnN0cnVjdG9yKHVpbnQ4IHRocmVzaG9sZCwgYWRkcmVzc1tdIG1lbW9yeSB2b3RlckFycmF5KSBwdWJsaWN7CiAgICAgICAgX3JlcXVlc3RSZXBvID0gbmV3IFJlcXVlc3RSZXBvc2l0b3J5KHRocmVzaG9sZCwgdm90ZXJBcnJheSk7CiAgICAgICAgX2V2aWRlbmNlUmVwbyA9IG5ldyBFdmlkZW5jZVJlcG9zaXRvcnkoKTsKICAgIH0KCiAgICBtb2RpZmllciB2YWxpZGF0ZUhhc2goYnl0ZXMzMiBoYXNoKXsKICAgICAgcmVxdWlyZShoYXNoICE9IDAsICJOb3QgdmFsaWQgaGFzaCIpOwogICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGNyZWF0ZVNhdmVSZXF1ZXN0KGJ5dGVzMzIgaGFzaCwgYnl0ZXMgbWVtb3J5IGV4dCkgcHVibGljIHZhbGlkYXRlSGFzaChoYXNoKXsKICAgICAgICBfcmVxdWVzdFJlcG8uY3JlYXRlU2F2ZVJlcXVlc3QoaGFzaCwgbXNnLnNlbmRlciwgZXh0KTsKICAgICAgICBlbWl0IENyZWF0ZVNhdmVSZXF1ZXN0KGhhc2gsIG1zZy5zZW5kZXIpOwogICAgfQoKICAgIGZ1bmN0aW9uIHZvdGVTYXZlUmVxdWVzdChieXRlczMyIGhhc2gpIHB1YmxpYyB2YWxpZGF0ZUhhc2goaGFzaCkgcmV0dXJucyhib29sKXsKICAgICAgICBib29sIGIgPSBfcmVxdWVzdFJlcG8udm90ZVNhdmVSZXF1ZXN0KGhhc2gsIG1zZy5zZW5kZXIpOwogICAgICAgIGlmKCFiKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgKGJ5dGVzMzIgaCwgYWRkcmVzcyBjcmVhdG9yLCBieXRlcyBtZW1vcnkgZXh0LCAgdWludDggdm90ZWQsIHVpbnQ4IHRocmVzaG9sZCkgPSAgX3JlcXVlc3RSZXBvLmdldFJlcXVlc3REYXRhKGhhc2gpOwogICAgICAgIGJvb2wgcGFzc2VkID0gdm90ZWQgPj0gdGhyZXNob2xkOwogICAgICAgIGVtaXQgVm90ZVNhdmVSZXF1ZXN0KGhhc2gsIG1zZy5zZW5kZXIsIHBhc3NlZCk7CiAgICAgICAgaWYocGFzc2VkKXsKICAgICAgICAgICAgX2V2aWRlbmNlUmVwby5zZXREYXRhKGhhc2gsIGNyZWF0b3IsIG5vdyk7CiAgICAgICAgICAgIF9yZXF1ZXN0UmVwby5kZWxldGVTYXZlUmVxdWVzdChoYXNoKTsKICAgICAgICAgICAgZW1pdCBFdmlkZW5jZVNhdmVkKGhhc2gpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRSZXF1ZXN0RGF0YShieXRlczMyIGhhc2gpIHB1YmxpYyB2aWV3IAogICAgICByZXR1cm5zKGJ5dGVzMzIsIGFkZHJlc3MgY3JlYXRvciwgYnl0ZXMgbWVtb3J5IGV4dCwgdWludDggdm90ZWQsIHVpbnQ4IHRocmVzaG9sZCl7CiAgICAgICAgcmV0dXJuIF9yZXF1ZXN0UmVwby5nZXRSZXF1ZXN0RGF0YShoYXNoKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRFdmlkZW5jZShieXRlczMyIGhhc2gpIHB1YmxpYyB2aWV3IHJldHVybnMoYnl0ZXMzMiAsIGFkZHJlc3MsIHVpbnQpewogICAgICAgIHJldHVybiBfZXZpZGVuY2VSZXBvLmdldERhdGEoaGFzaCk7CiAgICB9Cn0K', + 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(20, 4, 5, 'EvidenceRepository', 'LyoKICogQ29weXJpZ2h0IDIwMTQtMjAxOSB0aGUgb3JpZ2luYWwgYXV0aG9yIG9yIGF1dGhvcnMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiAqLwoKcHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CmltcG9ydCAiLi9BdXRoZW50aWNhdGlvbi5zb2wiOwoKY29udHJhY3QgRXZpZGVuY2VSZXBvc2l0b3J5IGlzIEF1dGhlbnRpY2F0aW9uIHsgICAgCiAgICBzdHJ1Y3QgRXZpZGVuY2VEYXRhewogICAgICAgIGJ5dGVzMzIgaGFzaDsKICAgICAgICBhZGRyZXNzIG93bmVyOwogICAgICAgIHVpbnQgdGltZXN0YW1wOwogICAgfQogICAgbWFwcGluZyhieXRlczMyPT5FdmlkZW5jZURhdGEpIHByaXZhdGUgX2V2aWRlbmNlczsgIAogICAgCiAgICBmdW5jdGlvbiBzZXREYXRhKGJ5dGVzMzIgaGFzaCwgYWRkcmVzcyBvd25lciwgdWludCB0aW1lc3RhbXApIHB1YmxpYyBhdXRoIHsKICAgICAgICBfZXZpZGVuY2VzW2hhc2hdLmhhc2ggPSBoYXNoOwogICAgICAgIF9ldmlkZW5jZXNbaGFzaF0ub3duZXIgPSBvd25lcjsKICAgICAgICBfZXZpZGVuY2VzW2hhc2hdLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gZ2V0RGF0YShieXRlczMyIGhhc2gpIHB1YmxpYyB2aWV3IHJldHVybnMoYnl0ZXMzMiAsIGFkZHJlc3MsIHVpbnQpewogICAgICAgIEV2aWRlbmNlRGF0YSBzdG9yYWdlIGV2aWRlbmNlID0gX2V2aWRlbmNlc1toYXNoXTsKICAgICAgICByZXF1aXJlKGV2aWRlbmNlLmhhc2ggPT0gaGFzaCwgIkV2aWRlbmNlIG5vdCBleGlzdCIpOwogICAgICAgIHJldHVybiAoZXZpZGVuY2UuaGFzaCwgZXZpZGVuY2Uub3duZXIsIGV2aWRlbmNlLnRpbWVzdGFtcCk7CiAgICB9Cn0K', + 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(21, 4, 5, 'RequestRepository', 'LyoKICogQ29weXJpZ2h0IDIwMTQtMjAxOSB0aGUgb3JpZ2luYWwgYXV0aG9yIG9yIGF1dGhvcnMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiAqLwoKcHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CgppbXBvcnQgIi4vQXV0aGVudGljYXRpb24uc29sIjsKCmNvbnRyYWN0IFJlcXVlc3RSZXBvc2l0b3J5IGlzIEF1dGhlbnRpY2F0aW9ueyAgICAKICAgIHN0cnVjdCBTYXZlUmVxdWVzdHsKICAgICAgICBieXRlczMyIGhhc2g7CiAgICAgICAgYWRkcmVzcyBjcmVhdG9yOwogICAgICAgIHVpbnQ4IHZvdGVkOwogICAgICAgIGJ5dGVzIGV4dDsKICAgICAgICBtYXBwaW5nKGFkZHJlc3M9PmJvb2wpIHN0YXR1czsKICAgIH0KICAgIHVpbnQ4IHB1YmxpYyBfdGhyZXNob2xkOwogICAgbWFwcGluZyhieXRlczMyPT5TYXZlUmVxdWVzdCkgcHJpdmF0ZSBfc2F2ZVJlcXVlc3RzOwogICAgbWFwcGluZyhhZGRyZXNzPT5ib29sKSBwcml2YXRlIF92b3RlcnM7CiAgICAKICAgIGNvbnN0cnVjdG9yKHVpbnQ4IHRocmVzaG9sZCwgYWRkcmVzc1tdIG1lbW9yeSB2b3RlckFycmF5KSBwdWJsaWN7CiAgICAgICAgX3RocmVzaG9sZCA9IHRocmVzaG9sZDsKICAgICAgICBmb3IodWludCBpPTA7aTx2b3RlckFycmF5Lmxlbmd0aDtpKyspewogICAgICAgICAgICBfdm90ZXJzW3ZvdGVyQXJyYXlbaV1dID0gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY3JlYXRlU2F2ZVJlcXVlc3QoYnl0ZXMzMiBoYXNoLCBhZGRyZXNzIG93bmVyLCBieXRlcyBtZW1vcnkgZXh0KSBwdWJsaWMgYXV0aHsKICAgICAgICByZXF1aXJlKF9zYXZlUmVxdWVzdHNbaGFzaF0uaGFzaCA9PSAwLCAicmVxdWVzdCBhbHJlYWR5IGV4aXN0ZWQiKTsKICAgICAgICBfc2F2ZVJlcXVlc3RzW2hhc2hdLmhhc2ggPSBoYXNoOwogICAgICAgIF9zYXZlUmVxdWVzdHNbaGFzaF0uY3JlYXRvciA9IG93bmVyOwogICAgICAgIF9zYXZlUmVxdWVzdHNbaGFzaF0uZXh0ID0gZXh0OwogICAgfQoKICAgIGZ1bmN0aW9uIHZvdGVTYXZlUmVxdWVzdChieXRlczMyIGhhc2gsIGFkZHJlc3Mgdm90ZXIpIHB1YmxpYyBhdXRoIHJldHVybnMgKGJvb2wpewogICAgICAgIHJlcXVpcmUoX3ZvdGVyc1t2b3Rlcl0gPT0gdHJ1ZSwgIk5vdCBhbGxvd2VkIHRvIHZvdGUiKTsKICAgICAgICByZXF1aXJlKF9zYXZlUmVxdWVzdHNbaGFzaF0uaGFzaCA9PSBoYXNoLCAicmVxdWVzdCBub3QgZm91bmQiKTsKICAgICAgICBTYXZlUmVxdWVzdCBzdG9yYWdlIHJlcXVlc3QgPSBfc2F2ZVJlcXVlc3RzW2hhc2hdOwogICAgICAgIHJlcXVpcmUocmVxdWVzdC5zdGF0dXNbdm90ZXJdID09IGZhbHNlLCAiVm90ZXIgYWxyZWFkeSB2b3RlZCIpOwogICAgICAgIHJlcXVlc3Quc3RhdHVzW3ZvdGVyXSA9IHRydWU7CiAgICAgICAgcmVxdWVzdC52b3RlZCsrOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRSZXF1ZXN0RGF0YShieXRlczMyIGhhc2gpIHB1YmxpYyB2aWV3IAogICAgICByZXR1cm5zKGJ5dGVzMzIsIGFkZHJlc3MgY3JlYXRvciwgYnl0ZXMgbWVtb3J5IGV4dCwgdWludDggdm90ZWQsIHVpbnQ4IHRocmVzaG9sZCl7CiAgICAgICAgU2F2ZVJlcXVlc3Qgc3RvcmFnZSByZXF1ZXN0ID0gX3NhdmVSZXF1ZXN0c1toYXNoXTsKICAgICAgICByZXF1aXJlKF9zYXZlUmVxdWVzdHNbaGFzaF0uaGFzaCA9PSBoYXNoLCAicmVxdWVzdCBub3QgZm91bmQiKTsKICAgICAgICByZXR1cm4gKGhhc2gsIHJlcXVlc3QuY3JlYXRvciwgcmVxdWVzdC5leHQsIHJlcXVlc3Qudm90ZWQsIF90aHJlc2hvbGQpOwogICAgfQoKICAgIGZ1bmN0aW9uIGRlbGV0ZVNhdmVSZXF1ZXN0KGJ5dGVzMzIgaGFzaCkgcHVibGljIGF1dGggewogICAgICAgIHJlcXVpcmUoX3NhdmVSZXF1ZXN0c1toYXNoXS5oYXNoID09IGhhc2gsICJyZXF1ZXN0IG5vdCBmb3VuZCIpOwogICAgICAgIGRlbGV0ZSBfc2F2ZVJlcXVlc3RzW2hhc2hdOwogICAgfQp9Cg==', +'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', now(), now()); +INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES +(22, 4, 5, 'Authentication', 'LyoKICogQ29weXJpZ2h0IDIwMTQtMjAxOSB0aGUgb3JpZ2luYWwgYXV0aG9yIG9yIGF1dGhvcnMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiAqLwoKcHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7Cgpjb250cmFjdCBBdXRoZW50aWNhdGlvbnsKICAgIGFkZHJlc3MgcHVibGljIF9vd25lcjsKICAgIG1hcHBpbmcoYWRkcmVzcz0+Ym9vbCkgcHJpdmF0ZSBfYWNsOwoKICAgIGNvbnN0cnVjdG9yKCkgcHVibGljewogICAgICBfb3duZXIgPSBtc2cuc2VuZGVyOwogICAgfSAKCiAgICBtb2RpZmllciBvbmx5T3duZXIoKXsKICAgICAgcmVxdWlyZShtc2cuc2VuZGVyID09IF9vd25lciwgIk5vdCBhZG1pbiIpOwogICAgICBfOwogICAgfQoKICAgIG1vZGlmaWVyIGF1dGgoKXsKICAgICAgcmVxdWlyZShtc2cuc2VuZGVyID09IF9vd25lciB8fCBfYWNsW21zZy5zZW5kZXJdPT10cnVlLCAiTm90IGF1dGhlbnRpY2F0ZWQiKTsKICAgICAgXzsKICAgIH0KCiAgICBmdW5jdGlvbiBhbGxvdyhhZGRyZXNzIGFkZHIpIHB1YmxpYyBvbmx5T3duZXJ7CiAgICAgIF9hY2xbYWRkcl0gPSB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGRlbnkoYWRkcmVzcyBhZGRyKSBwdWJsaWMgb25seU93bmVyewogICAgICBfYWNsW2FkZHJdID0gZmFsc2U7CiAgICB9Cn0K', +'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', now(), now()); + + +SET FOREIGN_KEY_CHECKS = 1; From 4ddaef5bc4007e897904ab9f24b67de366a76199 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Wed, 12 May 2021 16:59:14 +0800 Subject: [PATCH 47/92] add front default normal --- .../java/com/webank/webase/node/mgr/front/FrontService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/webank/webase/node/mgr/front/FrontService.java b/src/main/java/com/webank/webase/node/mgr/front/FrontService.java index c453a978f..8e9531392 100644 --- a/src/main/java/com/webank/webase/node/mgr/front/FrontService.java +++ b/src/main/java/com/webank/webase/node/mgr/front/FrontService.java @@ -235,6 +235,8 @@ public TbFront newFront(FrontInfo frontInfo) { // set default chainId tbFront.setChainId(0); tbFront.setChainName("default"); + // default normal front + tbFront.setStatus(DataStatus.NORMAL.getValue()); String frontIp = frontInfo.getFrontIp(); Integer frontPort = frontInfo.getFrontPort(); From e4896730e648810c0d9688c8592cd0675509277c Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 13 May 2021 10:51:57 +0800 Subject: [PATCH 48/92] add default channelPort 20200 --- .../com/webank/webase/node/mgr/scaffold/ScaffoldService.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java index 90d5373c3..e0359e3d0 100644 --- a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java @@ -100,6 +100,11 @@ public RspFile exportProject(ReqProject reqProject) { // get front's p2p ip and channel port FrontNodeConfig frontNodeConfig = frontInterfaceService .getNodeConfigFromSpecificFront(front.getFrontIp(), front.getFrontPort()); + if (frontNodeConfig.getChannelPort() == null) { + log.warn("getNodeConfig channelPort return null of {}," + + " for front's nodePath not configured! frontId:{}", frontNodeConfig, front.getFrontId()); + frontNodeConfig.setChannelPort(20200); + } frontNodeConfig.setP2pip(reqProject.getChannelIp()); log.info("exportProject get frontNodeConfig:{}", frontNodeConfig); // get front's sdk key cert From 702f7e8bade8c8f813f7584cae28feb982bff3d6 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 13 May 2021 11:13:19 +0800 Subject: [PATCH 49/92] update log --- .../webase/node/mgr/frontinterface/FrontRestTools.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontRestTools.java b/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontRestTools.java index c1b740da5..d45856685 100644 --- a/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontRestTools.java +++ b/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontRestTools.java @@ -403,8 +403,8 @@ private T restTemplateExchange(int groupId, String uri, HttpMethod method, HttpEntity entity = buildHttpEntity(param);// build entity if (null == restTemplate) { log.error("fail restTemplateExchange, rest is null. groupId:{} uri:{}", - groupId,uri); - throw new NodeMgrException(ConstantCode.SYSTEM_EXCEPTION); + groupId,uri); + throw new NodeMgrException(ConstantCode.SYSTEM_EXCEPTION.attach("restTemplate is null")); } ResponseEntity response = restTemplate.exchange(url, method, entity, clazz); frontService.updateFrontWithInternal(frontUrlInfo.getFrontId(), DataStatus.NORMAL.getValue()); @@ -417,7 +417,7 @@ private T restTemplateExchange(int groupId, String uri, HttpMethod method, frontService.updateFrontWithInternal(frontUrlInfo.getFrontId(), DataStatus.INVALID.getValue()); throw new NodeMgrException(ConstantCode.REQUEST_FRONT_FAIL, ex); } - log.info("continue next front", ex); + log.info("continue next front"); continue; } catch (HttpStatusCodeException ex) { // case2: request front success but return fail From add2c2791507a95b6e0e6770fca2f75d47600137 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 13 May 2021 11:17:16 +0800 Subject: [PATCH 50/92] update stat interval 10s --- .../com/webank/webase/node/mgr/statistic/StatService.java | 2 +- src/main/resources/application.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/statistic/StatService.java b/src/main/java/com/webank/webase/node/mgr/statistic/StatService.java index dd59cdf3d..df6621d02 100644 --- a/src/main/java/com/webank/webase/node/mgr/statistic/StatService.java +++ b/src/main/java/com/webank/webase/node/mgr/statistic/StatService.java @@ -83,7 +83,7 @@ public void pullBlockStatistic(CountDownLatch latch, Integer groupId) { localBlockNum = latestStat.getBlockNumber(); lastBlockTimestamp = Long.parseLong(latestStat.getStatTimestamp()); } else { - log.info("local block is null, start pull from zero groupId:{}", groupId); + log.info("groupId:{} local block is null, start pull from zero", groupId); // if no stat data local, pull from zero localBlockNum = 0; RspStatBlock zeroBlock = frontInterfaceService.getBlockStatisticByNumber(groupId, BigInteger.ZERO); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index f71de8a42..5e905694d 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -96,8 +96,8 @@ constant: resetGroupListInterval: 15000 ###interval block statistic, unit: ms statBlockRetainMax: 100000 - statBlockFixedDelay: 5000 - statBlockPageSize: 10 # block stat data to pull in one time + statBlockFixedDelay: 10000 + statBlockPageSize: 20 # block stat data to pull in one time enableExternalFromBlock: true # enable record account and contract from block #### 1.4.0 visual deploy From 41490b1b9500243dc68d95fcd3b6a35855d6b62d Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 14 May 2021 10:40:55 +0800 Subject: [PATCH 51/92] add node config in front api --- .../webase/node/mgr/front/FrontController.java | 17 ++++++++++++++++- .../webase/node/mgr/front/FrontService.java | 12 ++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/webank/webase/node/mgr/front/FrontController.java b/src/main/java/com/webank/webase/node/mgr/front/FrontController.java index 4bf1e0b7d..02d25eb9c 100644 --- a/src/main/java/com/webank/webase/node/mgr/front/FrontController.java +++ b/src/main/java/com/webank/webase/node/mgr/front/FrontController.java @@ -14,14 +14,15 @@ package com.webank.webase.node.mgr.front; -import com.webank.webase.node.mgr.base.tools.JsonTools; import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.controller.BaseController; import com.webank.webase.node.mgr.base.entity.BasePageResponse; import com.webank.webase.node.mgr.base.entity.BaseResponse; import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.base.properties.ConstantProperties; +import com.webank.webase.node.mgr.base.tools.JsonTools; import com.webank.webase.node.mgr.front.entity.FrontInfo; +import com.webank.webase.node.mgr.front.entity.FrontNodeConfig; import com.webank.webase.node.mgr.front.entity.FrontParam; import com.webank.webase.node.mgr.front.entity.TbFront; import java.time.Duration; @@ -150,4 +151,18 @@ public BaseResponse refreshFrontStatus() throws NodeMgrException { return new BaseResponse(ConstantCode.SUCCESS); } + /** + * get front's node config + */ + @GetMapping(value = "/nodeConfig") + @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN_OR_DEVELOPER) + public BaseResponse getFrontNodeConfig(@RequestParam("frontId") int frontId) { + Instant startTime = Instant.now(); + log.info("start getFrontNodeConfig startTime:{} ", startTime.toEpochMilli()); + FrontNodeConfig nodeConfig = frontService.getFrontNodeConfig(frontId); + + log.info("end getFrontNodeConfig useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); + return new BaseResponse(ConstantCode.SUCCESS, nodeConfig); + } + } diff --git a/src/main/java/com/webank/webase/node/mgr/front/FrontService.java b/src/main/java/com/webank/webase/node/mgr/front/FrontService.java index 8e9531392..7a8aa2887 100644 --- a/src/main/java/com/webank/webase/node/mgr/front/FrontService.java +++ b/src/main/java/com/webank/webase/node/mgr/front/FrontService.java @@ -1294,4 +1294,16 @@ private void validateSupportVersion(String supportVersion) { throw new NodeMgrException(ConstantCode.WEBASE_VERSION_NOT_MATCH_FISCO_SUPPORT_VERSION); } } + + public FrontNodeConfig getFrontNodeConfig(int frontId) { + TbFront front = this.getById(frontId); + if (front == null) { + log.error(""); + throw new NodeMgrException(ConstantCode.INVALID_FRONT_ID); + } + String frontIp = front.getFrontIp(); + int frontPort = front.getFrontPort(); + FrontNodeConfig nodeConfig = frontInterface.getNodeConfigFromSpecificFront(frontIp, frontPort); + return nodeConfig; + } } From 7e3ca76c389320e99aad9151ea312c14edabe69f Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 14 May 2021 11:27:47 +0800 Subject: [PATCH 52/92] add scaffold jar --- build.gradle | 11 +++++++---- .../webase/node/mgr/scaffold/ScaffoldService.java | 6 +++--- .../node/mgr/test/scaffold/ScaffoldBuildTest.java | 8 ++++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index a5dd239dd..1bb07b48c 100644 --- a/build.gradle +++ b/build.gradle @@ -78,8 +78,14 @@ List mbg = [ 'com.github.yuanmomo:mybatis-generator-plugin:1.0.9' ] +List scaffold = [ + compile ('com.webank.webase:solscaffold:1.0.0-SNAPSHOT'), + compile ('com.webank:SmartDev-Scaffold:1.0.0-SNAPSHOT'), + compile ('com.webank:solc-gradle-plugin:1.0.0-SNAPSHOT') +] + dependencies { - compile springboot,spring,jaxb,jackson,log4j + compile springboot,spring,jaxb,jackson,log4j,scaffold compile "org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.7.2" compile "org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.0" compile "org.apache.commons:commons-lang3:3.8.1" @@ -100,9 +106,6 @@ dependencies { compile 'org.thymeleaf:thymeleaf:3.0.11.RELEASE' compile 'ognl:ognl:3.2.14' compile 'org.apache.commons:commons-collections4:4.4' - // scaffold - compile ('com.webank.webase:solscaffold:1.0.0-SNAPSHOT') - compile ('com.webank:solc-gradle-plugin:1.0.0-SNAPSHOT') testCompile test,mbg diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java index e0359e3d0..2e6496b6a 100644 --- a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldService.java @@ -14,8 +14,8 @@ package com.webank.webase.node.mgr.scaffold; -import com.webank.scaffold.artifact.webase.NewMainResourceDir.ContractInfo; -import com.webank.scaffold.factory.ProjectFactory; +import com.webank.scaffold.artifact.NewMainResourceDir.ContractInfo; +import com.webank.scaffold.factory.WebaseProjectFactory; import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.base.tools.NodeMgrTools; @@ -153,7 +153,7 @@ public String generateProject(FrontNodeConfig nodeConfig, String projectGroup, S log.info("generateProject sdkMap size:{}", sdkMap.size()); List contractInfoList = this.handleContractList(tbContractList); String frontChannelIpPort = nodeConfig.getP2pip() + ":" + nodeConfig.getChannelPort(); - ProjectFactory projectFactory = new ProjectFactory(); + WebaseProjectFactory projectFactory = new WebaseProjectFactory(); log.info("generateProject projectGroup:{},artifactName:{},OUTPUT_DIR:{},frontChannelIpPort:{},groupId:{}", projectGroup, artifactName, OUTPUT_DIR, frontChannelIpPort, groupId); try { diff --git a/src/test/java/node/mgr/test/scaffold/ScaffoldBuildTest.java b/src/test/java/node/mgr/test/scaffold/ScaffoldBuildTest.java index eed5d2145..afdcfab7f 100644 --- a/src/test/java/node/mgr/test/scaffold/ScaffoldBuildTest.java +++ b/src/test/java/node/mgr/test/scaffold/ScaffoldBuildTest.java @@ -14,11 +14,11 @@ package node.mgr.test.scaffold; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.webank.scaffold.artifact.NewMainResourceDir.ContractInfo; import com.webank.scaffold.artifact.ProjectArtifact; -import com.webank.scaffold.artifact.webase.NewMainResourceDir.ContractInfo; import com.webank.scaffold.factory.ProjectFactory; +import com.webank.scaffold.factory.WebaseProjectFactory; import com.webank.scaffold.util.IOUtil; import com.webank.webase.node.mgr.base.tools.CleanPathUtil; import java.io.BufferedWriter; @@ -110,7 +110,7 @@ public void testBuildByParam() throws Exception { System.out.println("sdkMap: "); System.out.println(sdkMap); - ProjectFactory projectFactory = new ProjectFactory(); + WebaseProjectFactory projectFactory = new WebaseProjectFactory(); ProjectArtifact result = projectFactory.buildProjectDir( Collections.singletonList(contractInfo), group, artifactName, outputDir, "gradle", @@ -143,7 +143,7 @@ public void testBuildMultiSol() throws Exception { ObjectMapper mapper = new ObjectMapper(); Map sdkMap = mapper.readValue(sdkMapStr, Map.class); - ProjectFactory projectFactory = new ProjectFactory(); + WebaseProjectFactory projectFactory = new WebaseProjectFactory(); // ProjectArtifact result = projectFactory.buildProjectDir(Collections.singletonList(contractInfo), ProjectArtifact result = projectFactory.buildProjectDir(Arrays.asList(contractInfo, creditContract), group, artifactName, outputDir, "gradle", From 346e58d12cd174633a9c5d636f1d7c52aef6b5a7 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 14 May 2021 14:38:08 +0800 Subject: [PATCH 53/92] update --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 1bb07b48c..c24f52641 100644 --- a/build.gradle +++ b/build.gradle @@ -79,9 +79,9 @@ List mbg = [ ] List scaffold = [ - compile ('com.webank.webase:solscaffold:1.0.0-SNAPSHOT'), - compile ('com.webank:SmartDev-Scaffold:1.0.0-SNAPSHOT'), - compile ('com.webank:solc-gradle-plugin:1.0.0-SNAPSHOT') + 'com.webank.webase:solscaffold:1.0.0-SNAPSHOT', + 'com.webank:SmartDev-Scaffold:1.0.0-SNAPSHOT', + 'com.webank:solc-gradle-plugin:1.0.0-SNAPSHOT' ] dependencies { From e2df6118c20d432adab3838b15004158da0878e2 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 14 May 2021 14:54:28 +0800 Subject: [PATCH 54/92] distinct unusual contract --- src/main/resources/mapper/UserTransMonitorMapper.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/mapper/UserTransMonitorMapper.xml b/src/main/resources/mapper/UserTransMonitorMapper.xml index f090c810f..8698d3c9e 100644 --- a/src/main/resources/mapper/UserTransMonitorMapper.xml +++ b/src/main/resources/mapper/UserTransMonitorMapper.xml @@ -171,7 +171,7 @@ - select user_name as userName,sum(trans_count) as transCount, max(trans_hashs) as hashs, max(modify_time) as time + select distinct(user_name) as userName,sum(trans_count) as transCount, max(trans_hashs) as hashs, max(modify_time) as time from ${tableName} where user_type=1 and user_name like CONCAT(CONCAT('%',#{userName}),'%') From c6d231a35708629ea657cb9aa08c408a314182b8 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 14 May 2021 15:18:55 +0800 Subject: [PATCH 56/92] fix test --- .../mgr/test/contract/warehouse/WarehouseSmartDevTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/node/mgr/test/contract/warehouse/WarehouseSmartDevTest.java b/src/test/java/node/mgr/test/contract/warehouse/WarehouseSmartDevTest.java index fd3272099..a804446b5 100644 --- a/src/test/java/node/mgr/test/contract/warehouse/WarehouseSmartDevTest.java +++ b/src/test/java/node/mgr/test/contract/warehouse/WarehouseSmartDevTest.java @@ -14,6 +14,7 @@ package node.mgr.test.contract.warehouse; +import com.webank.scaffold.util.FileUtils; import com.webank.scaffold.util.IOUtil; import com.webank.webase.node.mgr.base.tools.NodeMgrTools; import java.io.File; @@ -47,7 +48,7 @@ private void printFileContent(File file) throws IOException { // System.out.println(solFile.getName() + " content: " + content); System.out.println(subFile.getName() + " content base64: " + NodeMgrTools .encodedBase64Str(content)); - IOUtil.writeStringToFile(NodeMgrTools.encodedBase64Str(content), + FileUtils.writeStringToFile(NodeMgrTools.encodedBase64Str(content), new File(readDir + "/base64"), subFile.getName() + ".txt"); } From 3d698f6d2c1e3342a425d6b8611e44d64663fc56 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 15:04:39 +0800 Subject: [PATCH 57/92] update node info return --- .../webank/webase/node/mgr/front/FrontService.java | 11 ++++++----- .../mgr/frontinterface/FrontInterfaceService.java | 7 ++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/front/FrontService.java b/src/main/java/com/webank/webase/node/mgr/front/FrontService.java index 7a8aa2887..15b3cc51a 100644 --- a/src/main/java/com/webank/webase/node/mgr/front/FrontService.java +++ b/src/main/java/com/webank/webase/node/mgr/front/FrontService.java @@ -92,6 +92,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.Level; import org.fisco.bcos.sdk.client.protocol.response.NodeInfo; +import org.fisco.bcos.sdk.client.protocol.response.NodeInfo.NodeInformation; import org.fisco.bcos.sdk.client.protocol.response.SyncStatus.SyncStatusInfo; import org.fisco.bcos.sdk.crypto.CryptoSuite; import org.fisco.bcos.sdk.model.CryptoType; @@ -201,7 +202,7 @@ public void refreshFront() { // p2p/rpc/channel port etc. FrontNodeConfig nodeConfig = frontInterface.getNodeConfigFromSpecificFront(frontIp, frontPort); // get agency of node - NodeInfo nodeInfo = frontInterface.getNodeInfoFromSpecificFront(frontIp, frontPort); + NodeInformation nodeInfo = frontInterface.getNodeInfoFromSpecificFront(frontIp, frontPort); tbFront.setP2pPort(nodeConfig.getP2pport()); tbFront.setJsonrpcPort(nodeConfig.getRpcport()); tbFront.setChannelPort(nodeConfig.getChannelPort()); @@ -210,7 +211,7 @@ public void refreshFront() { tbFront.setClientVersion(clientVersion); tbFront.setSupportVersion(supportVersion); // set agency from chain - tbFront.setAgency(nodeInfo.getNodeInfo().getAgency()); + tbFront.setAgency(nodeInfo.getAgency()); //update front info frontMapper.updateBasicInfo(tbFront); // save group info @@ -287,9 +288,9 @@ public TbFront newFront(FrontInfo frontInfo) { tbFront.setJsonrpcPort(nodeConfig.getRpcport()); tbFront.setChannelPort(nodeConfig.getChannelPort()); // get agency of node - NodeInfo nodeInfo = frontInterface.getNodeInfoFromSpecificFront(frontIp, frontPort); - log.info("front's agency is :{}", nodeInfo.getNodeInfo()); - tbFront.setAgency(nodeInfo.getNodeInfo().getAgency()); + NodeInformation nodeInfo = frontInterface.getNodeInfoFromSpecificFront(frontIp, frontPort); + log.info("front's agency is :{}", nodeInfo); + tbFront.setAgency(nodeInfo.getAgency()); // get front server version and sign server version try { String frontVersion = frontInterface.getFrontVersionFromSpecificFront(frontIp, frontPort); diff --git a/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontInterfaceService.java b/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontInterfaceService.java index 6490ef369..d9669c8b7 100644 --- a/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontInterfaceService.java +++ b/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontInterfaceService.java @@ -50,6 +50,7 @@ import org.fisco.bcos.sdk.client.protocol.response.BcosBlockHeader; import org.fisco.bcos.sdk.client.protocol.response.ConsensusStatus.ConsensusInfo; import org.fisco.bcos.sdk.client.protocol.response.NodeInfo; +import org.fisco.bcos.sdk.client.protocol.response.NodeInfo.NodeInformation; import org.fisco.bcos.sdk.client.protocol.response.SyncStatus.SyncStatusInfo; import org.fisco.bcos.sdk.model.NodeVersion.ClientVersion; import org.fisco.bcos.sdk.model.TransactionReceipt; @@ -522,10 +523,10 @@ public FrontNodeConfig getNodeConfigFromSpecificFront(String frontIp, Integer fr return nodeConfig; } - public NodeInfo getNodeInfoFromSpecificFront(String frontIp, Integer frontPort) { + public NodeInformation getNodeInfoFromSpecificFront(String frontIp, Integer frontPort) { Integer groupId = Integer.MAX_VALUE; - NodeInfo nodeInfo = getFromSpecificFront(groupId, frontIp, frontPort, - FrontRestTools.URI_NODE_INFO, NodeInfo.class); + NodeInformation nodeInfo = getFromSpecificFront(groupId, frontIp, frontPort, + FrontRestTools.URI_NODE_INFO, NodeInformation.class); return nodeInfo; } From d88254eb6234931a087dedb73e0d999282078aa8 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 15:07:33 +0800 Subject: [PATCH 58/92] update code --- .../node/mgr/base/filter/AbstractAuthenticationFilter.java | 3 ++- .../com/webank/webase/node/mgr/base/filter/FrontFilter.java | 2 +- .../webank/webase/node/mgr/base/filter/UriFormatFilter.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/base/filter/AbstractAuthenticationFilter.java b/src/main/java/com/webank/webase/node/mgr/base/filter/AbstractAuthenticationFilter.java index 8ff58a56e..0c4e2d46e 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/filter/AbstractAuthenticationFilter.java +++ b/src/main/java/com/webank/webase/node/mgr/base/filter/AbstractAuthenticationFilter.java @@ -45,7 +45,8 @@ public AbstractAuthenticationFilter(AuthenticationManager authenticationManager) } @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException { final String header = request.getHeader(TOKEN_HEADER_NAME); if (header == null || !header.startsWith(getHeaderPrefix())) { diff --git a/src/main/java/com/webank/webase/node/mgr/base/filter/FrontFilter.java b/src/main/java/com/webank/webase/node/mgr/base/filter/FrontFilter.java index dd6a7509f..52076215c 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/filter/FrontFilter.java +++ b/src/main/java/com/webank/webase/node/mgr/base/filter/FrontFilter.java @@ -84,7 +84,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha * check path is ignore. */ private boolean isIgnore(String uri) { - long count = ignorePath.stream().filter(path -> uri.startsWith(path)).count(); + long count = ignorePath.stream().filter(uri::startsWith).count(); return count > 0; } diff --git a/src/main/java/com/webank/webase/node/mgr/base/filter/UriFormatFilter.java b/src/main/java/com/webank/webase/node/mgr/base/filter/UriFormatFilter.java index c3d75e303..d89be9b80 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/filter/UriFormatFilter.java +++ b/src/main/java/com/webank/webase/node/mgr/base/filter/UriFormatFilter.java @@ -42,7 +42,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; - String requestUri = httpRequest.getRequestURI().toString(); + String requestUri = httpRequest.getRequestURI(); log.debug("request url:{}", requestUri); request = new HttpServletRequestWrapper(httpRequest) { From 23b03f0392fd7e85a584914f9ccc3eb6156d44a1 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 16:53:45 +0800 Subject: [PATCH 59/92] add method when insert tb_abi --- .../webase/node/mgr/base/tools/Web3Tools.java | 1 + .../node/mgr/contract/abi/AbiService.java | 9 ++++ .../webase/node/mgr/method/MethodService.java | 54 +++++++++++++++++-- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/base/tools/Web3Tools.java b/src/main/java/com/webank/webase/node/mgr/base/tools/Web3Tools.java index 2f857b54a..231e77844 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/tools/Web3Tools.java +++ b/src/main/java/com/webank/webase/node/mgr/base/tools/Web3Tools.java @@ -15,6 +15,7 @@ */ package com.webank.webase.node.mgr.base.tools; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.exception.NodeMgrException; diff --git a/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiService.java b/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiService.java index e78f4ae00..55c552c02 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiService.java @@ -17,6 +17,7 @@ package com.webank.webase.node.mgr.contract.abi; import com.webank.webase.node.mgr.base.code.ConstantCode; +import com.webank.webase.node.mgr.base.enums.ContractType; import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.base.tools.JsonTools; import com.webank.webase.node.mgr.base.tools.NodeMgrTools; @@ -28,6 +29,7 @@ import com.webank.webase.node.mgr.contract.entity.RspContractNoAbi; import com.webank.webase.node.mgr.contract.entity.TbContract; import com.webank.webase.node.mgr.frontinterface.FrontInterfaceService; +import com.webank.webase.node.mgr.method.MethodService; import java.math.BigInteger; import java.time.LocalDateTime; import java.util.ArrayList; @@ -50,6 +52,8 @@ public class AbiService { FrontInterfaceService frontInterfaceService; @Autowired ContractService contractService; + @Autowired + MethodService methodService; public List getListByGroupId(ReqAbiListParam param) { List abiList = abiMapper.listOfAbi(param); @@ -83,6 +87,8 @@ public void insertAbiInfo(ReqImportAbi param) { checkAbiExist(groupId, account, contractAddress); // add addAbiToDb(groupId, param.getContractName(), account, contractAddress, contractAbiStr, contractBin); + // save and update method + methodService.saveMethod(groupId, contractAbiStr, ContractType.GENERALCONTRACT.getValue()); } @Transactional @@ -106,6 +112,9 @@ public void updateAbiInfo(ReqImportAbi param) { updateAbi.setContractBin(contractBin); updateAbi.setModifyTime(LocalDateTime.now()); abiMapper.update(updateAbi); + // update method + methodService.saveMethod(param.getGroupId(), contractAbiStr, ContractType.GENERALCONTRACT.getValue()); + } public void delete(Integer id) { diff --git a/src/main/java/com/webank/webase/node/mgr/method/MethodService.java b/src/main/java/com/webank/webase/node/mgr/method/MethodService.java index 297ec607e..a750c8a1a 100644 --- a/src/main/java/com/webank/webase/node/mgr/method/MethodService.java +++ b/src/main/java/com/webank/webase/node/mgr/method/MethodService.java @@ -13,17 +13,24 @@ */ package com.webank.webase.node.mgr.method; +import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.enums.ContractType; +import com.webank.webase.node.mgr.base.exception.NodeMgrException; +import com.webank.webase.node.mgr.base.tools.Web3Tools; import com.webank.webase.node.mgr.method.entity.Method; import com.webank.webase.node.mgr.method.entity.NewMethodInputParam; import com.webank.webase.node.mgr.method.entity.TbMethod; +import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import lombok.extern.log4j.Log4j2; +import org.fisco.bcos.sdk.crypto.CryptoSuite; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; @Log4j2 @Service @@ -31,22 +38,63 @@ public class MethodService { @Autowired private MethodMapper methodMapper; + @Autowired + private CryptoSuite cryptoSuite; + + /** + * save method by abi string + * @param groupId + * @param abiStr + * @param type + */ + public void saveMethod(int groupId, String abiStr, int type) { + List methodList; + try { + methodList = new ArrayList<>(Web3Tools.getMethodFromAbi(abiStr, cryptoSuite)); + } catch (IOException e) { + log.error("saveMethod failed:[]", e); + throw new NodeMgrException(ConstantCode.PARAM_FAIL_ABI_INVALID); + } + NewMethodInputParam newMethodInputParam = new NewMethodInputParam(); + newMethodInputParam.setGroupId(groupId); + newMethodInputParam.setMethodList(methodList); + this.saveMethod(newMethodInputParam, type); + } /** - * save method info. + * save method info */ public void saveMethod(NewMethodInputParam newMethodInputParam, Integer type) { + int groupId = newMethodInputParam.getGroupId(); List methodList = newMethodInputParam.getMethodList(); TbMethod tbMethod = new TbMethod(); - tbMethod.setGroupId(newMethodInputParam.getGroupId()); + tbMethod.setGroupId(groupId); tbMethod.setContractType(type); //save each method for (Method method : methodList) { + if (checkMethodExist(method.getMethodId(), groupId)) { + log.info("methodId of [{}] in group [{}] exist, jump over", method.getMethodId(), groupId); + continue; + } BeanUtils.copyProperties(method, tbMethod); methodMapper.add(tbMethod); } } + /** + * checkMethod whether exist + * @param methodId + * @param groupId + * @return + */ + private boolean checkMethodExist(String methodId, int groupId) { + TbMethod check = methodMapper.getMethodById(methodId, groupId); + if (Objects.nonNull(check)) { + return true; + } + return false; + } + /** * query by methodId. */ @@ -66,7 +114,7 @@ public TbMethod getByMethodId(String methodId, Integer groupId) { * delete by groupId. */ public void deleteByGroupId(int groupId){ - if(groupId==0){ + if (groupId == 0) { return; } methodMapper.removeByGroupId(groupId); From 3d8b4f7ad69b8b525d7c8ebbe7a4f775ffa44e68 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 16:54:55 +0800 Subject: [PATCH 60/92] update distinct & not support abnormal --- .../webank/webase/node/mgr/external/ExternalController.java | 5 ++--- .../mgr/external/mapper/TbExternalAccountSqlProvider.java | 4 +--- .../mgr/external/mapper/TbExternalContractSqlProvider.java | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/external/ExternalController.java b/src/main/java/com/webank/webase/node/mgr/external/ExternalController.java index 0d90f028f..30e127901 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/ExternalController.java +++ b/src/main/java/com/webank/webase/node/mgr/external/ExternalController.java @@ -136,7 +136,7 @@ public BasePageResponse listExtUserListJoin(@PathVariable("groupId") Integer gro param.setGroupId(groupId); param.setPageSize(pageSize); param.setAccount(account); - // type: 1-all, 2-normal, 3-abnormal + // type: 1-all, 2-normal param.setCommParam(type.toString()); int count = extAccountService.countExtAccount(param); @@ -180,10 +180,9 @@ public BasePageResponse listExtContractListJoin(@PathVariable("groupId") Integer param.setAccount(account); param.setContractAddress(contractAddress); param.setContractName(contractName); - // type: 1-all, 2-normal, 3-abnormal + // type: 1-all, 2-normal param.setContractType(type); int count = extContractService.countExtContract(param); - if (count > 0) { Integer start = Optional.ofNullable(pageNumber).map(page -> (page - 1) * pageSize).orElse(null); diff --git a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java index 4f4a0f628..ad3137df4 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java +++ b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java @@ -19,7 +19,7 @@ public String listJoin(UserParam param) { "FROM tb_user " + ") b on ext.address=b.address and ext.group_id=b.group_id " + "LEFT JOIN " + - "( SELECT user_name,sum(trans_count) transCount, max(trans_hashs) hashs " + + "( SELECT distinct(user_name),sum(trans_count) transCount, max(trans_hashs) hashs " + "FROM tb_user_transaction_monitor_${groupId} WHERE user_type=1 group by user_name" + // if external address equal to monitor user's username, it means user not imported ") c on ext.address=c.user_name"; @@ -76,8 +76,6 @@ public String getList(UserParam param) { sql.ORDER_BY("create_time "); if (param.getStart() != null && param.getPageSize() != null) { sql.LIMIT(param.getStart() + "," +param.getPageSize()); -// sql.LIMIT(param.getStart()); -// sql.LIMIT(param.getPageSize()); } return sql.toString(); } diff --git a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java index 802916685..3a07ed347 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java +++ b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java @@ -20,7 +20,7 @@ public String listJoin(ContractParam param) { "FROM tb_abi " + ") b on ext.contract_address=b.contract_address and ext.group_id=b.group_id " + "LEFT JOIN " + - "( SELECT contract_address,sum(trans_count) transCount,max(trans_hashs) hashs " + + "( SELECT distinct(contract_address),sum(trans_count) transCount,max(trans_hashs) hashs " + "FROM tb_user_transaction_monitor_${groupId} WHERE trans_unusual_type=1 group by contract_address" + // if external address equal to monitor user's username, it means user not imported ") c on ext.contract_address=c.contract_address"; From 7bd1d5a5874b3240d00cbc114aeb34a43a12006c Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 17:52:49 +0800 Subject: [PATCH 61/92] update unusual contract --- .../node/mgr/contract/abi/AbiMapper.java | 8 +++++ .../node/mgr/contract/abi/AbiService.java | 19 +++++++++++- .../contract/abi/entity/ReqAbiListParam.java | 1 + .../mgr/contract/entity/ContractParam.java | 2 +- .../node/mgr/monitor/MonitorService.java | 29 ++++++++++++++++--- src/main/resources/mapper/AbiMapper.xml | 22 ++++++++++++++ 6 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiMapper.java index 9891d9847..fb952d942 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiMapper.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiMapper.java @@ -50,4 +50,12 @@ AbiInfo queryByGroupIdAndContractName(@Param("groupId") int groupId, void deleteByGroupId(@Param("groupId") int groupId); List listAllContract(ReqAbiListParam param); + + /** + * support query by bin + * @param param + * @return + */ + AbiInfo getAbiByBin(ReqAbiListParam param); + } diff --git a/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiService.java b/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiService.java index 55c552c02..efdd71068 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiService.java @@ -30,6 +30,7 @@ import com.webank.webase.node.mgr.contract.entity.TbContract; import com.webank.webase.node.mgr.frontinterface.FrontInterfaceService; import com.webank.webase.node.mgr.method.MethodService; +import com.webank.webase.node.mgr.monitor.MonitorService; import java.math.BigInteger; import java.time.LocalDateTime; import java.util.ArrayList; @@ -54,6 +55,8 @@ public class AbiService { ContractService contractService; @Autowired MethodService methodService; + @Autowired + MonitorService monitorService; public List getListByGroupId(ReqAbiListParam param) { List abiList = abiMapper.listOfAbi(param); @@ -89,6 +92,10 @@ public void insertAbiInfo(ReqImportAbi param) { addAbiToDb(groupId, param.getContractName(), account, contractAddress, contractAbiStr, contractBin); // save and update method methodService.saveMethod(groupId, contractAbiStr, ContractType.GENERALCONTRACT.getValue()); + if (StringUtils.isNotBlank(contractBin)) { + // update monitor unusual deployInputParam's info + monitorService.updateUnusualContract(groupId, param.getContractName(), contractBin); + } } @Transactional @@ -114,7 +121,10 @@ public void updateAbiInfo(ReqImportAbi param) { abiMapper.update(updateAbi); // update method methodService.saveMethod(param.getGroupId(), contractAbiStr, ContractType.GENERALCONTRACT.getValue()); - + if (StringUtils.isNotBlank(contractBin)) { + // update monitor unusual deployInputParam's info + monitorService.updateUnusualContract(param.getGroupId(), param.getContractName(), contractBin); + } } public void delete(Integer id) { @@ -291,4 +301,11 @@ private void addAbiToDb(int groupId, String contractName, String account, String abiMapper.add(saveAbi); } + public AbiInfo getAbiInfoByBin(ReqAbiListParam param) { + log.debug("start getAbiInfoByBin. queryParam:{}", JsonTools.toJSONString(param)); + AbiInfo abiInfo = abiMapper.getAbiByBin(param); + log.debug("end getAbiInfoByBin. queryParam:{} tbContract:{}", JsonTools.toJSONString(param), + JsonTools.toJSONString(abiInfo)); + return abiInfo; + } } diff --git a/src/main/java/com/webank/webase/node/mgr/contract/abi/entity/ReqAbiListParam.java b/src/main/java/com/webank/webase/node/mgr/contract/abi/entity/ReqAbiListParam.java index 42b9363c4..ae3f11699 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/abi/entity/ReqAbiListParam.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/abi/entity/ReqAbiListParam.java @@ -35,6 +35,7 @@ public class ReqAbiListParam extends BaseQueryParam { private String account; private String contractName; private String contractAddress; + private String partOfContractBin; public ReqAbiListParam(Integer start, Integer pageSize, String flagSortedByTime) { super(start, pageSize, flagSortedByTime); diff --git a/src/main/java/com/webank/webase/node/mgr/contract/entity/ContractParam.java b/src/main/java/com/webank/webase/node/mgr/contract/entity/ContractParam.java index c54d161ad..a4993765f 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/entity/ContractParam.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/entity/ContractParam.java @@ -44,7 +44,7 @@ public class ContractParam extends BaseQueryParam { /** * init by contractId. */ - public ContractParam(int contractId,int groupId) { + public ContractParam(int contractId, int groupId) { super(); this.contractId = contractId; this.groupId = groupId; diff --git a/src/main/java/com/webank/webase/node/mgr/monitor/MonitorService.java b/src/main/java/com/webank/webase/node/mgr/monitor/MonitorService.java index a91dd24ae..1a1b436af 100644 --- a/src/main/java/com/webank/webase/node/mgr/monitor/MonitorService.java +++ b/src/main/java/com/webank/webase/node/mgr/monitor/MonitorService.java @@ -25,6 +25,9 @@ import com.webank.webase.node.mgr.base.tools.NodeMgrTools; import com.webank.webase.node.mgr.base.tools.Web3Tools; import com.webank.webase.node.mgr.contract.ContractService; +import com.webank.webase.node.mgr.contract.abi.AbiService; +import com.webank.webase.node.mgr.contract.abi.entity.AbiInfo; +import com.webank.webase.node.mgr.contract.abi.entity.ReqAbiListParam; import com.webank.webase.node.mgr.contract.entity.ContractParam; import com.webank.webase.node.mgr.contract.entity.TbContract; import com.webank.webase.node.mgr.frontinterface.FrontInterfaceService; @@ -86,7 +89,10 @@ public class MonitorService { private MethodService methodService; @Autowired private ConstantProperties cProperties; - @Autowired private CryptoSuite cryptoSuite; + @Autowired + private CryptoSuite cryptoSuite; + @Autowired + private AbiService abiService; /** @@ -380,7 +386,7 @@ private ContractMonitorResult monitorContract(int groupId, String transHash, Str String contractAddress, contractName, interfaceName = "", contractBin; int transType = TransType.DEPLOY.getValue(); int transUnusualType = TransUnusualType.NORMAL.getValue(); - + // deploy contract tx if (isDeploy(transTo)) { contractAddress = frontInterfacee.getAddressByHash(groupId, transHash); if (ConstantProperties.ADDRESS_DEPLOY.equals(contractAddress)) { @@ -390,9 +396,15 @@ private ContractMonitorResult monitorContract(int groupId, String transHash, Str param.setGroupId(groupId); param.setPartOfBytecodeBin(contractBin); TbContract tbContract = contractService.queryContract(param); - + // add abi query + ReqAbiListParam paramTbAbi = new ReqAbiListParam(); + paramTbAbi.setGroupId(groupId); + paramTbAbi.setPartOfContractBin(contractBin); + AbiInfo abiInfo = abiService.getAbiInfoByBin(paramTbAbi); if (Objects.nonNull(tbContract)) { contractName = tbContract.getContractName(); + } else if (Objects.nonNull(abiInfo)) { + contractName = abiInfo.getContractName(); } else { contractName = getNameFromContractBin(groupId, contractBin); transUnusualType = TransUnusualType.CONTRACT.getValue(); @@ -400,10 +412,17 @@ private ContractMonitorResult monitorContract(int groupId, String transHash, Str } else { contractBin = frontInterfacee.getCodeFromFront(groupId, contractAddress, blockNumber); contractBin = removeBinFirstAndLast(contractBin); - + List contractRow = contractService.queryContractByBin(groupId, contractBin); + // add abi query + ReqAbiListParam paramTbAbi = new ReqAbiListParam(); + paramTbAbi.setGroupId(groupId); + paramTbAbi.setPartOfContractBin(contractBin); + AbiInfo abiInfo = abiService.getAbiInfoByBin(paramTbAbi); if (contractRow != null && contractRow.size() > 0) { contractName = contractRow.get(0).getContractName(); + } else if (Objects.nonNull(abiInfo)) { + contractName = abiInfo.getContractName(); } else { contractName = getNameFromContractBin(groupId, contractBin); transUnusualType = TransUnusualType.CONTRACT.getValue(); @@ -426,12 +445,14 @@ private ContractMonitorResult monitorContract(int groupId, String transHash, Str transUnusualType = TransUnusualType.FUNCTION.getValue(); } } else { + // no contract name, use bin as contract name contractName = getNameFromContractBin(groupId, contractBin); TbMethod tbMethod = methodService.getByMethodId(methodId, groupId); if (Objects.nonNull(tbMethod)) { interfaceName = getInterfaceName(methodId, "[" + tbMethod.getAbiInfo() + "]"); log.info("monitor methodId:{} interfaceName:{}", methodId, interfaceName); } + // no method id, deploy tx if (StringUtils.isBlank(interfaceName)) { interfaceName = transInput.substring(0, 10); transUnusualType = TransUnusualType.CONTRACT.getValue(); diff --git a/src/main/resources/mapper/AbiMapper.xml b/src/main/resources/mapper/AbiMapper.xml index a4dde09ba..07766beaa 100644 --- a/src/main/resources/mapper/AbiMapper.xml +++ b/src/main/resources/mapper/AbiMapper.xml @@ -144,4 +144,26 @@ limit #{start},#{pageSize} + + \ No newline at end of file From d668aeafa19609ec5086fa7c12af8638be81d52a Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 18:19:26 +0800 Subject: [PATCH 62/92] add all contract in external --- .../node/mgr/external/ExtContractService.java | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java b/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java index 58e5132a8..090797201 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java @@ -16,8 +16,12 @@ import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.exception.NodeMgrException; +import com.webank.webase.node.mgr.base.properties.ConstantProperties; import com.webank.webase.node.mgr.base.tools.NodeMgrTools; import com.webank.webase.node.mgr.contract.ContractService; +import com.webank.webase.node.mgr.contract.abi.AbiService; +import com.webank.webase.node.mgr.contract.abi.entity.AbiInfo; +import com.webank.webase.node.mgr.contract.abi.entity.ReqAbiListParam; import com.webank.webase.node.mgr.contract.entity.ContractParam; import com.webank.webase.node.mgr.contract.entity.TbContract; import com.webank.webase.node.mgr.external.entity.RspAllExtContract; @@ -45,6 +49,8 @@ public class ExtContractService { @Autowired private ContractService contractService; @Autowired + private AbiService abiService; + @Autowired private FrontInterfaceService frontInterfaceService; /** @@ -60,11 +66,15 @@ public void asyncSaveContract(int groupId, String txHash, String timestampStr) { groupId, txHash, timestampStr); TransactionReceipt txReceipt = frontInterfaceService.getTransReceipt(groupId, txHash); - if (!Address.DEFAULT.getValue().equals(txReceipt.getTo())) { - return; + // if send transaction to call contract, receipt's contract address is all zero, + // receipt's to is contract address + String contractAddress = txReceipt.getTo(); + // if receipt's to is all zero, deploy transaction + if (ConstantProperties.ADDRESS_DEPLOY.equals(txReceipt.getTo())) { + contractAddress = txReceipt.getContractAddress(); } - // save - saveContractOnChain(groupId, txReceipt.getContractAddress(), txHash, + // save ext contract + saveContractOnChain(groupId, contractAddress, txHash, txReceipt.getFrom(), timestampStr); } @@ -91,6 +101,15 @@ public int saveContractOnChain(int groupId, String contractAddress, String txHas tbContract.setContractName(existedContract.getContractName()); tbContract.setContractAbi(existedContract.getContractAbi()); } + // check tb_abi's address + AbiInfo existedTbAbi = abiService.getAbiByGroupIdAndAddress(groupId, contractAddress); + if (Objects.nonNull(existedTbAbi)) { + log.debug("saveContractOnChain exist tb_contract " + + "contractAddress:{} address:{}", groupId, contractAddress); + // set related contract name + tbContract.setContractName(existedTbAbi.getContractName()); + tbContract.setContractAbi(existedTbAbi.getContractAbi()); + } tbContract.setGroupId(groupId); tbContract.setContractAddress(contractAddress); tbContract.setDeployTxHash(txHash); From 62d1a8e57c3e6dd3e1880d87d240eedf0972487f Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 18:53:56 +0800 Subject: [PATCH 63/92] fix count with abnormal --- .../node/mgr/external/ExtContractService.java | 2 +- .../mapper/TbExternalAccountSqlProvider.java | 14 ++++++++++---- .../mapper/TbExternalContractSqlProvider.java | 14 ++++++++++---- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java b/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java index 090797201..050fa5206 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java @@ -102,7 +102,7 @@ public int saveContractOnChain(int groupId, String contractAddress, String txHas tbContract.setContractAbi(existedContract.getContractAbi()); } // check tb_abi's address - AbiInfo existedTbAbi = abiService.getAbiByGroupIdAndAddress(groupId, contractAddress); + AbiInfo existedTbAbi = abiService.getAbi(groupId, contractAddress); if (Objects.nonNull(existedTbAbi)) { log.debug("saveContractOnChain exist tb_contract " + "contractAddress:{} address:{}", groupId, contractAddress); diff --git a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java index ad3137df4..dd923eccc 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java +++ b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java @@ -45,16 +45,22 @@ public String listJoin(UserParam param) { public String count(UserParam param) { SQL sql = new SQL(); - sql.FROM("tb_external_account"); - sql.SELECT("count(1)"); + sql.SELECT("count(1),b.userId from tb_external_account ext " + + "left join " + + "(select user_id userId,group_id,address from tb_user) b " + + "on ext.address=b.address and ext.group_id=b.group_id "); if (param.getGroupId() != null) { sql.WHERE("group_id = #{groupId}"); } if (param.getUserName() != null) { sql.WHERE("user_name = #{userName}"); } - if (param.getUserId() != null) { - sql.WHERE("id = #{userId}"); + // get all or some + // 1-all(default), 2-normal, 3-abnormal + if (Integer.parseInt(param.getCommParam()) == ExternalInfoType.NORMAL.getValue()) { + sql.WHERE("b.userId is not NULL"); + } else if (Integer.parseInt(param.getCommParam()) == ExternalInfoType.ABNORMAL.getValue()) { + sql.WHERE("b.userId is NULL"); } return sql.toString(); } diff --git a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java index 3a07ed347..4a2813a0d 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java +++ b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java @@ -52,8 +52,10 @@ public String listJoin(ContractParam param) { public String count(ContractParam param) { SQL sql = new SQL(); - sql.FROM("tb_external_contract"); - sql.SELECT("count(1)"); + sql.SELECT("count(1),b.abiId from tb_external_contract ext " + + "left join " + + "(select abi_id abiId,contract_address,group_id from tb_abi) b " + + "on ext.contract_address=b.contract_address and ext.group_id=b.group_id "); if (param.getGroupId() != null) { sql.WHERE("group_id = #{groupId}"); } @@ -63,8 +65,12 @@ public String count(ContractParam param) { if (param.getDeployAddress() != null) { sql.WHERE("deploy_address = #{deployAddress}"); } - if (param.getContractId() != null) { - sql.WHERE("id = #{contractId}"); + // get all or some + // 1-all(default), 2-normal, 3-abnormal + if (param.getContractType() == ExternalInfoType.NORMAL.getValue()) { + sql.WHERE("b.abiId is not NULL"); + } else if (param.getContractType() == ExternalInfoType.ABNORMAL.getValue()) { + sql.WHERE("b.abiId is NULL"); } return sql.toString(); } From 9358434567371d3ae232355d1c034859dd85ce2c Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 18:54:35 +0800 Subject: [PATCH 64/92] add get abi info --- .../com/webank/webase/node/mgr/contract/abi/AbiService.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiService.java b/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiService.java index efdd71068..caf71493b 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/abi/AbiService.java @@ -158,13 +158,17 @@ private void checkAbiIdExist(Integer abiId) { } public AbiInfo getAbiByGroupIdAndAddress(Integer groupId, String contractAddress) { - AbiInfo abiInfo = abiMapper.queryByGroupIdAndAddress(groupId, null, contractAddress); + AbiInfo abiInfo = this.getAbi(groupId, contractAddress); if (Objects.isNull(abiInfo)) { throw new NodeMgrException(ConstantCode.ABI_INFO_NOT_EXISTS); } return abiInfo; } + public AbiInfo getAbi(Integer groupId, String contractAddress) { + return abiMapper.queryByGroupIdAndAddress(groupId, null, contractAddress); + } + /** * check address is valid. * @return address's runtime bin From ca8911202d067c2c5440bc69b5ccc0caae237550 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 18:55:06 +0800 Subject: [PATCH 65/92] fix refresh front's default agency --- .../java/com/webank/webase/node/mgr/front/FrontService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/webank/webase/node/mgr/front/FrontService.java b/src/main/java/com/webank/webase/node/mgr/front/FrontService.java index 15b3cc51a..bfa17176c 100644 --- a/src/main/java/com/webank/webase/node/mgr/front/FrontService.java +++ b/src/main/java/com/webank/webase/node/mgr/front/FrontService.java @@ -211,7 +211,7 @@ public void refreshFront() { tbFront.setClientVersion(clientVersion); tbFront.setSupportVersion(supportVersion); // set agency from chain - tbFront.setAgency(nodeInfo.getAgency()); + tbFront.setAgency(nodeInfo.getAgency() == null ? "fisco" : nodeInfo.getAgency()); //update front info frontMapper.updateBasicInfo(tbFront); // save group info From b0ea2764e07743613a53b4c916db7ac107a1f3f7 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 18:55:24 +0800 Subject: [PATCH 66/92] update all zero address --- .../com/webank/webase/node/mgr/block/BlockService.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/block/BlockService.java b/src/main/java/com/webank/webase/node/mgr/block/BlockService.java index e4175d2aa..6b7d79f33 100644 --- a/src/main/java/com/webank/webase/node/mgr/block/BlockService.java +++ b/src/main/java/com/webank/webase/node/mgr/block/BlockService.java @@ -376,16 +376,15 @@ public Object searchByBlockNumOrTxHash(int groupId, String input) { } private void saveExternalInfo(int groupId, JsonTransactionResponse trans, String timestamp) { + log.info("saveExternalInfo trans block number:{}", trans.getBlockNumber()); if (!cProperties.getEnableExternalFromBlock()) { return; } // try to save external account extAccountService.saveAccountOnChain(groupId, trans.getFrom()); // try to save external contract - String toAddress = trans.getTo(); - if (Address.DEFAULT.getValue().equals(toAddress)) { - log.debug("saveExternalInfo contract from block:{}", trans.getHash()); - extContractService.asyncSaveContract(groupId, trans.getHash(), timestamp); - } + log.debug("saveExternalInfo contract from block:{}", trans.getHash()); + extContractService.asyncSaveContract(groupId, trans.getHash(), timestamp); + } } From dfb2ffa1df84417cfd9a0907309c5cab0feace56 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 20:28:41 +0800 Subject: [PATCH 67/92] fix sql in external & ignore precompiled address --- .../base/properties/ConstantProperties.java | 1 + .../node/mgr/external/ExtContractService.java | 3 +++ .../mapper/TbExternalAccountSqlProvider.java | 14 +++++++------ .../mapper/TbExternalContractSqlProvider.java | 20 ++++++++++++------- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/base/properties/ConstantProperties.java b/src/main/java/com/webank/webase/node/mgr/base/properties/ConstantProperties.java index 6e818ba31..d03235993 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/properties/ConstantProperties.java +++ b/src/main/java/com/webank/webase/node/mgr/base/properties/ConstantProperties.java @@ -43,6 +43,7 @@ public class ConstantProperties { public static final String CONSTANT_PREFIX = "constant"; public static final String CONTRACT_NAME_ZERO = "0x00000000"; public static final String ADDRESS_DEPLOY = "0x0000000000000000000000000000000000000000"; + public static final String ADDRESS_PRECOMPILED = "0x000000000000000000000000000000000000"; public static final int PUBLICKEY_LENGTH = 130; public static final int ADDRESS_LENGTH = 42; public static final String HAS_ROLE_ADMIN = "hasRole('admin')"; diff --git a/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java b/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java index 050fa5206..50d3bd914 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java @@ -69,6 +69,9 @@ public void asyncSaveContract(int groupId, String txHash, String timestampStr) { // if send transaction to call contract, receipt's contract address is all zero, // receipt's to is contract address String contractAddress = txReceipt.getTo(); + if (contractAddress.startsWith(ConstantProperties.ADDRESS_PRECOMPILED)) { + return; + } // if receipt's to is all zero, deploy transaction if (ConstantProperties.ADDRESS_DEPLOY.equals(txReceipt.getTo())) { contractAddress = txReceipt.getContractAddress(); diff --git a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java index dd923eccc..ecf8812fe 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java +++ b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java @@ -24,7 +24,9 @@ public String listJoin(UserParam param) { // if external address equal to monitor user's username, it means user not imported ") c on ext.address=c.user_name"; sql.SELECT(sqlStr); - sql.WHERE("ext.group_id= #{groupId}"); + if (param.getGroupId() != null) { + sql.WHERE("ext.group_id = #{groupId}"); + } if (param.getAccount() != null) { sql.WHERE("b.account = #{account}"); } @@ -45,15 +47,15 @@ public String listJoin(UserParam param) { public String count(UserParam param) { SQL sql = new SQL(); - sql.SELECT("count(1),b.userId from tb_external_account ext " + sql.SELECT("count(1),ext.group_id,ext.address,b.userId,b.account from tb_external_account ext " + "left join " - + "(select user_id userId,group_id,address from tb_user) b " + + "(select user_id userId,group_id,address,account from tb_user) b " + "on ext.address=b.address and ext.group_id=b.group_id "); if (param.getGroupId() != null) { - sql.WHERE("group_id = #{groupId}"); + sql.WHERE("ext.group_id = #{groupId}"); } - if (param.getUserName() != null) { - sql.WHERE("user_name = #{userName}"); + if (param.getAccount() != null) { + sql.WHERE("b.account = #{account}"); } // get all or some // 1-all(default), 2-normal, 3-abnormal diff --git a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java index 4a2813a0d..4043441cb 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java +++ b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java @@ -25,7 +25,9 @@ public String listJoin(ContractParam param) { // if external address equal to monitor user's username, it means user not imported ") c on ext.contract_address=c.contract_address"; sql.SELECT(columnsWithJoin); - sql.WHERE("ext.group_id= #{groupId}"); + if (param.getGroupId() != null) { + sql.WHERE("ext.group_id = #{groupId}"); + } if (param.getAccount() != null) { sql.WHERE("b.account = #{account}"); } @@ -52,18 +54,22 @@ public String listJoin(ContractParam param) { public String count(ContractParam param) { SQL sql = new SQL(); - sql.SELECT("count(1),b.abiId from tb_external_contract ext " + sql.SELECT("count(1),ext.group_id,ext.contract_address,b.abiId,b.account,b.contract_name" + + " from tb_external_contract ext " + "left join " - + "(select abi_id abiId,contract_address,group_id from tb_abi) b " + + "(select abi_id abiId,contract_address,group_id,account,contract_name from tb_abi) b " + "on ext.contract_address=b.contract_address and ext.group_id=b.group_id "); if (param.getGroupId() != null) { - sql.WHERE("group_id = #{groupId}"); + sql.WHERE("ext.group_id = #{groupId}"); } if (param.getContractAddress() != null) { - sql.WHERE("contract_address = #{contractAddress}"); + sql.WHERE("ext.contract_address = #{contractAddress}"); } - if (param.getDeployAddress() != null) { - sql.WHERE("deploy_address = #{deployAddress}"); + if (param.getAccount() != null) { + sql.WHERE("b.account = #{account}"); + } + if (param.getContractName() != null) { + sql.WHERE("b.contract_name = #{contractName}"); } // get all or some // 1-all(default), 2-normal, 3-abnormal From 24be3c9f9afdb7709bf1f9385e1ad60a9c014bf7 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 20:43:49 +0800 Subject: [PATCH 68/92] add export package name valid --- .../node/mgr/base/code/ConstantCode.java | 1 + .../node/mgr/base/tools/NodeMgrTools.java | 27 +++++++++++++++++ .../node/mgr/external/ExtContractService.java | 1 + .../node/mgr/scaffold/ScaffoldController.java | 29 +++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java index 32a97c8e9..2a6e2fdd9 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java +++ b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java @@ -317,6 +317,7 @@ public class ConstantCode { // add in v1.5.1 public static final RetCode GENERATE_CONTRACT_PROJECT_FAIL = RetCode.mark(202531, "generate project failed in scaffold"); public static final RetCode GET_FRONT_SDK_MAP_FAIL = RetCode.mark(202532, "get sdk cert/key content map failed"); + public static final RetCode PARAM_INVALID_LETTER_DIGIT = RetCode.mark(202533, "Only support letter and digit, please check your params"); /* auth */ diff --git a/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java b/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java index edaa3dc3e..c487a6f3f 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java +++ b/src/main/java/com/webank/webase/node/mgr/base/tools/NodeMgrTools.java @@ -731,4 +731,31 @@ public static boolean deleteDir(File dir) { // delete empty dir return dir.delete(); } + + /** + * 支持数字,字母与下划线"_" + * + * @param input + * @return + */ + public static boolean isLetterDigit(String input) { + String regex = "^[a-z0-9A-Z_]+$"; + return input.matches(regex); + } + + /** + * 字母开头 + * @param input + * @return + */ + public static boolean startWithLetter(String input) { + if (StringUtils.isBlank(input)) { + return false; + } + if (!isLetterDigit(input)) { + return false; + } + String regex = "^[a-zA-Z]+$"; + return (input.charAt(0)+"").matches(regex); + } } diff --git a/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java b/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java index 50d3bd914..60db60daf 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java @@ -69,6 +69,7 @@ public void asyncSaveContract(int groupId, String txHash, String timestampStr) { // if send transaction to call contract, receipt's contract address is all zero, // receipt's to is contract address String contractAddress = txReceipt.getTo(); + // ignore precompiled contract address if (contractAddress.startsWith(ConstantProperties.ADDRESS_PRECOMPILED)) { return; } diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java index 7f16965da..65654ab98 100644 --- a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java @@ -17,9 +17,11 @@ import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.controller.BaseController; import com.webank.webase.node.mgr.base.entity.BaseResponse; +import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.base.properties.ConstantProperties; import com.webank.webase.node.mgr.base.tools.IPUtil; import com.webank.webase.node.mgr.base.tools.JsonTools; +import com.webank.webase.node.mgr.base.tools.NodeMgrTools; import com.webank.webase.node.mgr.scaffold.entity.ReqProject; import com.webank.webase.node.mgr.scaffold.entity.RspFile; import java.time.Duration; @@ -53,6 +55,33 @@ public BaseResponse exportProjectApi(@Valid @RequestBody ReqProject param) { if (StringUtils.isBlank(param.getChannelIp())) { param.setChannelIp(IPUtil.LOCAL_IP_127); } + // check artifact name and group name + if (!NodeMgrTools.startWithLetter(param.getArtifactName())) { + log.error("must start with letter"); + throw new NodeMgrException(ConstantCode.PARAM_INVALID_LETTER_DIGIT); + } + // validate group name, ex: org.example + if (!param.getGroup().contains("\\.")) { + // only org + if (!NodeMgrTools.startWithLetter(param.getGroup())) { + log.error("must start with letter"); + throw new NodeMgrException(ConstantCode.PARAM_INVALID_LETTER_DIGIT); + } + } else { + // include org.xxx + String[] groupNameArray = param.getGroup().split("\\."); + for (String group: groupNameArray) { + // not start or end with dot "." + if (StringUtils.isBlank(group)) { + log.error("group cannot start or end with dot"); + throw new NodeMgrException(ConstantCode.PARAM_INVALID_LETTER_DIGIT); + } + if (!NodeMgrTools.startWithLetter(group)) { + log.error("package name must start with letter"); + throw new NodeMgrException(ConstantCode.PARAM_INVALID_LETTER_DIGIT); + } + } + } RspFile rspFile = scaffoldService.exportProject(param); log.info("end exportProjectApi useTime:{} result:{}", Duration.between(startTime, Instant.now()).toMillis(), rspFile); From 4f9f511c191e253877b28f336897eb1b951e6a24 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 20:44:02 +0800 Subject: [PATCH 69/92] exclude key jar --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 358aa043f..61207af28 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ group = 'com.webank.webase.node.mgr' -version = '0.0.1-SNAPSHOT' +version = '1.0.0-SNAPSHOT' apply plugin: 'maven' apply plugin: 'java' @@ -124,6 +124,7 @@ configurations { all*.exclude group: 'jline', module: 'jline' all*.exclude group: 'com.google.protobuf', module: 'protobuf-java' all*.exclude group: 'javax.annotation', module: 'javax.annotation-api' + all*.exclude group: 'com.webank', module: 'key-mini-toolkit' } sourceSets { From 84f0a6af9afc8fc54d43ab8530a10c85e5137d85 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 20:44:20 +0800 Subject: [PATCH 70/92] update comment --- script/webase-ddl.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/webase-ddl.sql b/script/webase-ddl.sql index 96e9252cb..1fc3f67f9 100644 --- a/script/webase-ddl.sql +++ b/script/webase-ddl.sql @@ -489,7 +489,7 @@ CREATE TABLE IF NOT EXISTS tb_external_contract ( deploy_time datetime NOT NULL COMMENT '部署时间', contract_bin mediumtext DEFAULT NULL COMMENT '合约链上binary', contract_status int(1) DEFAULT '1' COMMENT '部署状态(1:未部署,2:部署成功,3:部署失败)', - contract_type tinyint(4) DEFAULT '0' COMMENT '合约类型(0-普通合约,1-系统合约)', + contract_type tinyint(4) DEFAULT '0' COMMENT '合约类型(0-普通合约,1-系统合约,2-APP合约)', contract_name varchar(120) binary DEFAULT NULL COMMENT '合约名称', contract_version varchar(120) DEFAULT NULL COMMENT '合约版本', contract_abi mediumtext COMMENT '编译合约生成的abi文件内容', From 74e3cffab185f270bdccf14742c0036d4df930a8 Mon Sep 17 00:00:00 2001 From: Sayou1989 Date: Tue, 18 May 2021 20:46:39 +0800 Subject: [PATCH 71/92] get account from token --- script/upgrade/v150_v151.sql | 2 + script/webase-ddl.sql | 1 + .../node/mgr/account/AccountController.java | 11 +---- .../node/mgr/account/AccountService.java | 13 +++++ .../appintegration/api/AppIntegrationApi.java | 2 +- .../mgr/base/annotation/CurrentAccount.java | 30 ++++++++++++ .../CurrentAccountMethodArgumentResolver.java | 47 ++++++++++++++++++ .../annotation/entity/CurrentAccountInfo.java | 25 ++++++++++ .../node/mgr/base/config/WebMvcConfig.java | 27 ++++++++++- .../node/mgr/base/filter/AccountFilter.java | 48 +++++++++++++++++++ .../node/mgr/contract/ContractController.java | 36 +++++++++----- .../node/mgr/contract/ContractPathMapper.java | 2 +- .../mgr/contract/ContractPathService.java | 7 +-- .../node/mgr/contract/ContractService.java | 8 ++-- .../node/mgr/contract/entity/Contract.java | 1 - .../contract/entity/QueryContractParam.java | 1 + .../mgr/contract/entity/TbContractPath.java | 1 + .../node/mgr/external/ExternalController.java | 17 +++++-- .../webase/node/mgr/user/UserController.java | 33 +++++++------ .../webase/node/mgr/user/UserService.java | 10 ++-- .../mgr/user/entity/BindUserInputParam.java | 2 - .../mgr/user/entity/NewUserInputParam.java | 2 - .../resources/mapper/ContractPathMapper.xml | 9 +++- 23 files changed, 274 insertions(+), 61 deletions(-) create mode 100644 src/main/java/com/webank/webase/node/mgr/base/annotation/CurrentAccount.java create mode 100644 src/main/java/com/webank/webase/node/mgr/base/annotation/CurrentAccountMethodArgumentResolver.java create mode 100644 src/main/java/com/webank/webase/node/mgr/base/annotation/entity/CurrentAccountInfo.java create mode 100644 src/main/java/com/webank/webase/node/mgr/base/filter/AccountFilter.java diff --git a/script/upgrade/v150_v151.sql b/script/upgrade/v150_v151.sql index 0d08f958e..f789607de 100644 --- a/script/upgrade/v150_v151.sql +++ b/script/upgrade/v150_v151.sql @@ -146,5 +146,7 @@ INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `con (22, 4, 5, 'Authentication', 'LyoKICogQ29weXJpZ2h0IDIwMTQtMjAxOSB0aGUgb3JpZ2luYWwgYXV0aG9yIG9yIGF1dGhvcnMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiAqLwoKcHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7Cgpjb250cmFjdCBBdXRoZW50aWNhdGlvbnsKICAgIGFkZHJlc3MgcHVibGljIF9vd25lcjsKICAgIG1hcHBpbmcoYWRkcmVzcz0+Ym9vbCkgcHJpdmF0ZSBfYWNsOwoKICAgIGNvbnN0cnVjdG9yKCkgcHVibGljewogICAgICBfb3duZXIgPSBtc2cuc2VuZGVyOwogICAgfSAKCiAgICBtb2RpZmllciBvbmx5T3duZXIoKXsKICAgICAgcmVxdWlyZShtc2cuc2VuZGVyID09IF9vd25lciwgIk5vdCBhZG1pbiIpOwogICAgICBfOwogICAgfQoKICAgIG1vZGlmaWVyIGF1dGgoKXsKICAgICAgcmVxdWlyZShtc2cuc2VuZGVyID09IF9vd25lciB8fCBfYWNsW21zZy5zZW5kZXJdPT10cnVlLCAiTm90IGF1dGhlbnRpY2F0ZWQiKTsKICAgICAgXzsKICAgIH0KCiAgICBmdW5jdGlvbiBhbGxvdyhhZGRyZXNzIGFkZHIpIHB1YmxpYyBvbmx5T3duZXJ7CiAgICAgIF9hY2xbYWRkcl0gPSB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGRlbnkoYWRkcmVzcyBhZGRyKSBwdWJsaWMgb25seU93bmVyewogICAgICBfYWNsW2FkZHJdID0gZmFsc2U7CiAgICB9Cn0K', 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', 'IyBFdmlkZW5jZeWtmOivgQoKIyMg566A5LuLCgrlrZjor4Hmk43kvZzvvIzkuIrkvKDjgIHlrqHmibnjgIHkv67mlLnjgIHliKDpmaTnrYnvvIzor6bmg4Xmn6XnnItbU21hcnQtRGV2IEV2aWRlbmNlIERvY10oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9idXNpbmVzc190ZW1wbGF0ZS9FdmlkZW5jZS5odG1sKQoK5ZCI57qm77yaCjEpIEV2aWRlbmNlQ29udHJvbGxlciDlr7nlpJbmnI3liqHnmoTllK/kuIDmjqXlj6MKMikgRXZpZGVuY2VSZXBvc2l0b3J5IOi+heWKqeWQiOe6pu+8jOeUqOS6juaVsOaNruWSjOmAu+i+keWIhuemuwozKSBSZXF1ZXN0UmVwb3NpdG9yeSDovoXliqnlkIjnuqbvvIznlKjkuo7mlbDmja7lkozpgLvovpHliIbnprsKNCkgQXV0aGVudGljYXRpb24g6L6F5Yqp5ZCI57qm77yM55So5LqO5pWw5o2u5ZKM6YC76L6R5YiG56a7', now(), now()); +-- 修改表 -- +ALTER TABLE tb_contract_path ADD COLUMN account varchar(50) binary DEFAULT 'admin' COMMENT '关联账号' after group_id; SET FOREIGN_KEY_CHECKS = 1; diff --git a/script/webase-ddl.sql b/script/webase-ddl.sql index 96e9252cb..8dca366c0 100644 --- a/script/webase-ddl.sql +++ b/script/webase-ddl.sql @@ -416,6 +416,7 @@ CREATE TABLE IF NOT EXISTS tb_contract_path ( id int(11) NOT NULL AUTO_INCREMENT COMMENT '合约路径编号', contract_path varchar(128) binary NOT NULL COMMENT '合约所在目录', group_id int(11) NOT NULL COMMENT '所属群组编号', + account varchar(50) binary DEFAULT 'admin' COMMENT '关联账号', create_time datetime DEFAULT NULL COMMENT '创建时间', modify_time datetime DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (id), diff --git a/src/main/java/com/webank/webase/node/mgr/account/AccountController.java b/src/main/java/com/webank/webase/node/mgr/account/AccountController.java index 96b3ac159..527ee3bb1 100644 --- a/src/main/java/com/webank/webase/node/mgr/account/AccountController.java +++ b/src/main/java/com/webank/webase/node/mgr/account/AccountController.java @@ -138,7 +138,7 @@ public BaseResponse updateAccountInfo(@RequestBody @Valid AccountInfo info, Http log.info("start updateAccountInfo startTime:{}", startTime.toEpochMilli()); // current - String currentAccount = getCurrentAccount(request); + String currentAccount = accountService.getCurrentAccount(request); // update account row accountService.updateAccountRow(currentAccount, info); @@ -211,7 +211,7 @@ public BaseResponse updatePassword(@RequestBody @Valid PasswordInfo info, HttpSe BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); - String targetAccount = getCurrentAccount(request); + String targetAccount = accountService.getCurrentAccount(request); // update account row accountService @@ -222,11 +222,4 @@ public BaseResponse updatePassword(@RequestBody @Valid PasswordInfo info, HttpSe return baseResponse; } - /** - * get current account. - */ - private String getCurrentAccount(HttpServletRequest request) { - String token = NodeMgrTools.getToken(request); - return tokenService.getValueFromToken(token); - } } diff --git a/src/main/java/com/webank/webase/node/mgr/account/AccountService.java b/src/main/java/com/webank/webase/node/mgr/account/AccountService.java index 25d1ec1a1..047f5f4bd 100644 --- a/src/main/java/com/webank/webase/node/mgr/account/AccountService.java +++ b/src/main/java/com/webank/webase/node/mgr/account/AccountService.java @@ -16,6 +16,7 @@ package com.webank.webase.node.mgr.account; import com.webank.webase.node.mgr.base.tools.JsonTools; +import com.webank.webase.node.mgr.base.tools.NodeMgrTools; import com.webank.webase.node.mgr.account.entity.AccountInfo; import com.webank.webase.node.mgr.account.entity.AccountListParam; import com.webank.webase.node.mgr.account.entity.LoginInfo; @@ -24,7 +25,9 @@ import com.webank.webase.node.mgr.base.enums.AccountStatus; import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.role.RoleService; +import com.webank.webase.node.mgr.token.TokenService; import java.util.List; +import javax.servlet.http.HttpServletRequest; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -46,6 +49,8 @@ public class AccountService { @Qualifier(value = "bCryptPasswordEncoder") @Autowired private PasswordEncoder passwordEncoder; + @Autowired + private TokenService tokenService; /** * login. @@ -253,5 +258,13 @@ private void checkDbAffectRow(Integer affectRow) throws NodeMgrException { throw new NodeMgrException(ConstantCode.DB_EXCEPTION); } } + + /** + * get current account. + */ + public String getCurrentAccount(HttpServletRequest request) { + String token = NodeMgrTools.getToken(request); + return tokenService.getValueFromToken(token); + } } diff --git a/src/main/java/com/webank/webase/node/mgr/appintegration/api/AppIntegrationApi.java b/src/main/java/com/webank/webase/node/mgr/appintegration/api/AppIntegrationApi.java index 5c7add9e3..c9c9cf769 100644 --- a/src/main/java/com/webank/webase/node/mgr/appintegration/api/AppIntegrationApi.java +++ b/src/main/java/com/webank/webase/node/mgr/appintegration/api/AppIntegrationApi.java @@ -430,7 +430,7 @@ public BaseResponse importPublicKey(@RequestBody @Valid BindUserInputParam user, Instant startTime = Instant.now(); // query user row - TbUser userRow = userService.bindUserInfo(user, CheckUserExist.FALSE.getValue()); + TbUser userRow = userService.bindUserInfo(user, user.getAccount(), CheckUserExist.FALSE.getValue()); baseResponse.setData(userRow); log.info("end importPublicKey useTime:{} result:{}", diff --git a/src/main/java/com/webank/webase/node/mgr/base/annotation/CurrentAccount.java b/src/main/java/com/webank/webase/node/mgr/base/annotation/CurrentAccount.java new file mode 100644 index 000000000..d047c59b0 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/base/annotation/CurrentAccount.java @@ -0,0 +1,30 @@ +/** + * Copyright 2014-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.webank.webase.node.mgr.base.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 在Controller的方法参数使用此注解,该方法在映射时会注入当前登录的Account对象 + */ +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface CurrentAccount { + +} diff --git a/src/main/java/com/webank/webase/node/mgr/base/annotation/CurrentAccountMethodArgumentResolver.java b/src/main/java/com/webank/webase/node/mgr/base/annotation/CurrentAccountMethodArgumentResolver.java new file mode 100644 index 000000000..ccc1f78c9 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/base/annotation/CurrentAccountMethodArgumentResolver.java @@ -0,0 +1,47 @@ +/** + * Copyright 2014-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.webank.webase.node.mgr.base.annotation; + +import com.webank.webase.node.mgr.base.annotation.entity.CurrentAccountInfo; +import com.webank.webase.node.mgr.base.code.ConstantCode; +import com.webank.webase.node.mgr.base.exception.NodeMgrException; +import org.springframework.core.MethodParameter; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +public class CurrentAccountMethodArgumentResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter methodParameter) { + return methodParameter.getParameterType().isAssignableFrom(CurrentAccountInfo.class) + && methodParameter.hasParameterAnnotation(CurrentAccount.class); + } + + @Override + public Object resolveArgument(MethodParameter methodParameter, + ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, + WebDataBinderFactory webDataBinderFactory) throws Exception { + // 从拦截器中获取的当前账户信息 + CurrentAccountInfo currentAccountInfo = (CurrentAccountInfo) nativeWebRequest + .getAttribute("currentAccountInfo", RequestAttributes.SCOPE_REQUEST); + if (currentAccountInfo != null) { + return currentAccountInfo; + } + // 如果当前账户信息为null,则抛出异常 + throw new NodeMgrException(ConstantCode.ACCOUNT_NOT_EXISTS); + } +} diff --git a/src/main/java/com/webank/webase/node/mgr/base/annotation/entity/CurrentAccountInfo.java b/src/main/java/com/webank/webase/node/mgr/base/annotation/entity/CurrentAccountInfo.java new file mode 100644 index 000000000..7e4c4346b --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/base/annotation/entity/CurrentAccountInfo.java @@ -0,0 +1,25 @@ +/** + * Copyright 2014-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.webank.webase.node.mgr.base.annotation.entity; + +import lombok.Data; + +/** + * Entity class of account info. + */ +@Data +public class CurrentAccountInfo { + String account; + Integer roleId; +} diff --git a/src/main/java/com/webank/webase/node/mgr/base/config/WebMvcConfig.java b/src/main/java/com/webank/webase/node/mgr/base/config/WebMvcConfig.java index 9bb81a3e5..96e287aba 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/config/WebMvcConfig.java +++ b/src/main/java/com/webank/webase/node/mgr/base/config/WebMvcConfig.java @@ -1,10 +1,16 @@ package com.webank.webase.node.mgr.base.config; +import com.webank.webase.node.mgr.base.annotation.CurrentAccountMethodArgumentResolver; +import com.webank.webase.node.mgr.base.filter.AccountFilter; import com.webank.webase.node.mgr.base.filter.AppIntegrationFilter; +import com.webank.webase.node.mgr.base.properties.ConstantProperties; +import java.util.List; import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -15,12 +21,19 @@ @Data @Configuration public class WebMvcConfig implements WebMvcConfigurer { - + @Value("${server.port}") private int port; @Autowired private AppIntegrationFilter appIntegrationFilter; + @Autowired + private ConstantProperties constants; + + @Bean + public AccountFilter setAccountFilter() { + return new AccountFilter(); + } /** * 注册拦截器 @@ -28,5 +41,17 @@ public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(appIntegrationFilter).addPathPatterns("/api/**");// 自定义拦截的url路径 + registry.addInterceptor(setAccountFilter()).addPathPatterns("/**") + .excludePathPatterns(constants.getPermitUrlArray()); + } + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(currentAccountMethodArgumentResolver()); + } + + @Bean + public CurrentAccountMethodArgumentResolver currentAccountMethodArgumentResolver() { + return new CurrentAccountMethodArgumentResolver(); } } diff --git a/src/main/java/com/webank/webase/node/mgr/base/filter/AccountFilter.java b/src/main/java/com/webank/webase/node/mgr/base/filter/AccountFilter.java new file mode 100644 index 000000000..8613994e4 --- /dev/null +++ b/src/main/java/com/webank/webase/node/mgr/base/filter/AccountFilter.java @@ -0,0 +1,48 @@ +/** + * Copyright 2014-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.webank.webase.node.mgr.base.filter; + +import com.webank.webase.node.mgr.account.AccountService; +import com.webank.webase.node.mgr.account.entity.TbAccountInfo; +import com.webank.webase.node.mgr.base.annotation.entity.CurrentAccountInfo; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +/** + * validate accoutn info. + */ +@Component +public class AccountFilter implements HandlerInterceptor { + + @Autowired + private AccountService accountService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, + Object handler) throws Exception { + // 获取账户信息 + String account = accountService.getCurrentAccount(request); + TbAccountInfo accountRow = accountService.queryByAccount(account); + // 设置账户信息 + CurrentAccountInfo currentAccountInfo = new CurrentAccountInfo(); + currentAccountInfo.setAccount(account); + currentAccountInfo.setRoleId(accountRow.getRoleId()); + request.setAttribute("currentAccountInfo", currentAccountInfo); + return true; + } + +} diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java index 3d4fccdc9..f3102410b 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java @@ -13,10 +13,13 @@ */ package com.webank.webase.node.mgr.contract; +import com.webank.webase.node.mgr.base.annotation.CurrentAccount; +import com.webank.webase.node.mgr.base.annotation.entity.CurrentAccountInfo; import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.controller.BaseController; import com.webank.webase.node.mgr.base.entity.BasePageResponse; import com.webank.webase.node.mgr.base.entity.BaseResponse; +import com.webank.webase.node.mgr.base.enums.RoleType; import com.webank.webase.node.mgr.base.enums.SqlSortType; import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.base.properties.ConstantProperties; @@ -76,8 +79,8 @@ public class ContractController extends BaseController { */ @PostMapping(value = "/save") @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN_OR_DEVELOPER) - public BaseResponse saveContract(@RequestBody @Valid Contract contract, BindingResult result) - throws NodeMgrException { + public BaseResponse saveContract(@RequestBody @Valid Contract contract, + @CurrentAccount CurrentAccountInfo currentAccountInfo, BindingResult result) throws NodeMgrException { checkBindResult(result); BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); @@ -88,6 +91,7 @@ public BaseResponse saveContract(@RequestBody @Valid Contract contract, BindingR contract.setContractPath("/"); } // add contract row + contract.setAccount(currentAccountInfo.getAccount()); TbContract tbContract = contractService.saveContract(contract); baseResponse.setData(tbContract); @@ -124,8 +128,8 @@ public BaseResponse deleteContract(@PathVariable("groupId") Integer groupId, * query contract info list. */ @PostMapping(value = "/contractList") - public BasePageResponse queryContractList(@RequestBody QueryContractParam inputParam) - throws NodeMgrException { + public BasePageResponse queryContractList(@RequestBody QueryContractParam inputParam, + @CurrentAccount CurrentAccountInfo currentAccountInfo) throws NodeMgrException { BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start contractList. startTime:{} inputParam:{}", startTime.toEpochMilli(), @@ -134,6 +138,9 @@ public BasePageResponse queryContractList(@RequestBody QueryContractParam inputP // param ContractParam queryParam = new ContractParam(); BeanUtils.copyProperties(inputParam, queryParam); + String account = RoleType.DEVELOPER.getValue().intValue() == currentAccountInfo.getRoleId().intValue() + ? currentAccountInfo.getAccount() : null; + queryParam.setAccount(account); int count = contractService.countOfContract(queryParam); if (count > 0) { @@ -289,7 +296,8 @@ public BasePageResponse queryContractListNoAbi(@RequestParam Integer groupId, */ @PostMapping(value = "/contractPath") @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN_OR_DEVELOPER) - public BaseResponse addContractPath(@Valid @RequestBody ContractPathParam param) { + public BaseResponse addContractPath(@Valid @RequestBody ContractPathParam param, + @CurrentAccount CurrentAccountInfo currentAccountInfo) { BaseResponse response = new BaseResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start addContractPath. startTime:{} param:{}", startTime.toEpochMilli(), param); @@ -298,7 +306,7 @@ public BaseResponse addContractPath(@Valid @RequestBody ContractPathParam param) if ("".equals(contractPath)) { contractPath = "/"; } - int result = contractPathService.save(param.getGroupId(), contractPath, false); + int result = contractPathService.save(param.getGroupId(), contractPath, currentAccountInfo.getAccount(), false); response.setData(result); log.info("end addContractPath. useTime:{} add result:{}", @@ -311,13 +319,15 @@ public BaseResponse addContractPath(@Valid @RequestBody ContractPathParam param) * query contract info list. */ @PostMapping(value = "/contractPath/list/{groupId}") - public BasePageResponse queryContractPathList(@PathVariable("groupId") Integer groupId) { + public BasePageResponse queryContractPathList(@PathVariable("groupId") Integer groupId, + @CurrentAccount CurrentAccountInfo currentAccountInfo) { BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start queryContractPathList. startTime:{} groupId:{}", startTime.toEpochMilli(), groupId); - - List result = contractService.queryContractPathList(groupId); + String account = RoleType.DEVELOPER.getValue().intValue() == currentAccountInfo.getRoleId().intValue() + ? currentAccountInfo.getAccount() : null; + List result = contractService.queryContractPathList(groupId, account); pageResponse.setData(result); pageResponse.setTotalCount(result.size()); @@ -349,12 +359,16 @@ public BaseResponse deleteContractByPath(@Valid @RequestBody ContractPathParam p * query contract info list by multi path */ @PostMapping(value = "/contractList/multiPath") - public BasePageResponse listContractByMultiPath(@RequestBody ReqListContract inputParam) - throws NodeMgrException { + public BasePageResponse listContractByMultiPath(@RequestBody ReqListContract inputParam, + @CurrentAccount CurrentAccountInfo currentAccountInfo) throws NodeMgrException { BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start listContractByMultiPath. startTime:{} inputParam:{}", startTime.toEpochMilli(), JsonTools.toJSONString(inputParam)); + + String account = RoleType.DEVELOPER.getValue().intValue() == currentAccountInfo.getRoleId().intValue() + ? currentAccountInfo.getAccount() : null; + inputParam.setAccount(account); List contractList = contractService.queryContractListMultiPath(inputParam); pageResponse.setTotalCount(contractList.size()); pageResponse.setData(contractList); diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractPathMapper.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractPathMapper.java index 7a3b3484d..5fd18ed62 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractPathMapper.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractPathMapper.java @@ -32,7 +32,7 @@ public interface ContractPathMapper { TbContractPath findOne(ContractPathParam param); - List listOfContractPath(@Param("groupId") Integer groupId); + List listOfContractPath(@Param("groupId") Integer groupId, @Param("account") String account); void removeByGroupId(@Param("groupId") Integer groupId); diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractPathService.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractPathService.java index 6ca0e10fb..74c9d2cb6 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractPathService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractPathService.java @@ -32,8 +32,8 @@ public class ContractPathService { @Autowired private ContractPathMapper contractPathMapper; - public List listContractPath(Integer groupId) { - return contractPathMapper.listOfContractPath(groupId); + public List listContractPath(Integer groupId, String account) { + return contractPathMapper.listOfContractPath(groupId, account); } /** @@ -42,7 +42,7 @@ public List listContractPath(Integer groupId) { * @param pathName * @return */ - public int save(Integer groupId, String pathName, boolean ignoreRepeat) { + public int save(Integer groupId, String pathName, String account, boolean ignoreRepeat) { TbContractPath check = contractPathMapper.findOne(new ContractPathParam(groupId, pathName)); if (check != null) { if (ignoreRepeat) { @@ -55,6 +55,7 @@ public int save(Integer groupId, String pathName, boolean ignoreRepeat) { TbContractPath contractPath = new TbContractPath(); contractPath.setContractPath(pathName); contractPath.setGroupId(groupId); + contractPath.setAccount(account); return contractPathMapper.add(contractPath); } diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java index abec9ebe6..fe11627ea 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java @@ -152,7 +152,7 @@ private TbContract newContract(Contract contract) { // save contract path log.debug("newContract save contract path"); // if exist, auto not save (ignore) - contractPathService.save(contract.getGroupId(), contract.getContractPath(), true); + contractPathService.save(contract.getGroupId(), contract.getContractPath(), contract.getAccount(), true); return tbContract; } @@ -221,7 +221,7 @@ public void appContractSave(String appKey, ReqContractAddressSave reqContractAdd methodService.saveMethod(newMethodInputParam, ContractType.APPIMPORT.getValue()); } // if exist, auto not save (ignore) - contractPathService.save(groupId, contractPath, true); + contractPathService.save(groupId, contractPath, listOfContractStore.get(0).getAccount(), true); } /** @@ -632,8 +632,8 @@ private void checkDeployPermission(int groupId, String userAddress) { /** * get contract path list */ - public List queryContractPathList(Integer groupId) { - List pathList = contractPathService.listContractPath(groupId); + public List queryContractPathList(Integer groupId, String account) { + List pathList = contractPathService.listContractPath(groupId, account); // not return null, but return empty list List resultList = new ArrayList<>(); if (pathList != null) { diff --git a/src/main/java/com/webank/webase/node/mgr/contract/entity/Contract.java b/src/main/java/com/webank/webase/node/mgr/contract/entity/Contract.java index 9384ed6c7..a7fc80b6f 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/entity/Contract.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/entity/Contract.java @@ -24,7 +24,6 @@ @Data @NoArgsConstructor public class Contract { - @NotBlank private String account; @NotNull private Integer groupId; diff --git a/src/main/java/com/webank/webase/node/mgr/contract/entity/QueryContractParam.java b/src/main/java/com/webank/webase/node/mgr/contract/entity/QueryContractParam.java index c345d6508..d80ff94dc 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/entity/QueryContractParam.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/entity/QueryContractParam.java @@ -20,6 +20,7 @@ public class QueryContractParam { private Integer groupId; private String contractName; + @Deprecated private String account; private String contractAddress; private Integer contractStatus; diff --git a/src/main/java/com/webank/webase/node/mgr/contract/entity/TbContractPath.java b/src/main/java/com/webank/webase/node/mgr/contract/entity/TbContractPath.java index 15f84df6c..078103a8b 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/entity/TbContractPath.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/entity/TbContractPath.java @@ -27,6 +27,7 @@ public class TbContractPath { private Integer id; private Integer groupId; private String contractPath; + private String account; private LocalDateTime createTime; private LocalDateTime modifyTime; } diff --git a/src/main/java/com/webank/webase/node/mgr/external/ExternalController.java b/src/main/java/com/webank/webase/node/mgr/external/ExternalController.java index 0d90f028f..3d98deb87 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/ExternalController.java +++ b/src/main/java/com/webank/webase/node/mgr/external/ExternalController.java @@ -14,9 +14,12 @@ package com.webank.webase.node.mgr.external; +import com.webank.webase.node.mgr.base.annotation.CurrentAccount; +import com.webank.webase.node.mgr.base.annotation.entity.CurrentAccountInfo; import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.controller.BaseController; import com.webank.webase.node.mgr.base.entity.BasePageResponse; +import com.webank.webase.node.mgr.base.enums.RoleType; import com.webank.webase.node.mgr.base.enums.SqlSortType; import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.base.tools.JsonTools; @@ -124,14 +127,15 @@ public BasePageResponse extContractList(@PathVariable("groupId") Integer groupId public BasePageResponse listExtUserListJoin(@PathVariable("groupId") Integer groupId, @PathVariable("pageNumber") Integer pageNumber, @PathVariable("pageSize") Integer pageSize, - @RequestParam(value = "account", required = false) String account, - @RequestParam(value = "type", defaultValue = "1") Integer type) - throws NodeMgrException { + @RequestParam(value = "type", defaultValue = "1") Integer type, + @CurrentAccount CurrentAccountInfo currentAccountInfo) throws NodeMgrException { BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start listExtUserListJoin startTime:{} groupId:{} pageNumber:{} pageSize:{}", startTime.toEpochMilli(), groupId, pageNumber, pageSize); + String account = RoleType.DEVELOPER.getValue().intValue() == currentAccountInfo.getRoleId().intValue() + ? currentAccountInfo.getAccount() : null; UserParam param = new UserParam(); param.setGroupId(groupId); param.setPageSize(pageSize); @@ -165,15 +169,18 @@ public BasePageResponse listExtUserListJoin(@PathVariable("groupId") Integer gro public BasePageResponse listExtContractListJoin(@PathVariable("groupId") Integer groupId, @PathVariable("pageNumber") Integer pageNumber, @PathVariable("pageSize") Integer pageSize, - @RequestParam(value = "account", required = false) String account, @RequestParam(value = "type", defaultValue = "1") Integer type, @RequestParam(value = "contractAddress", required = false) String contractAddress, @RequestParam(value = "contractName", required = false) String contractName, - @RequestParam(value = "requiredBin", defaultValue = "true", required = false) Boolean requiredBin) throws NodeMgrException { + @RequestParam(value = "requiredBin", defaultValue = "true", required = false) Boolean requiredBin, + @CurrentAccount CurrentAccountInfo currentAccountInfo) throws NodeMgrException { BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start listExtContractListJoin. startTime:{} groupId:{}", startTime.toEpochMilli(), groupId); + + String account = RoleType.DEVELOPER.getValue().intValue() == currentAccountInfo.getRoleId().intValue() + ? currentAccountInfo.getAccount() : null; ContractParam param = new ContractParam(); param.setGroupId(groupId); param.setPageSize(pageSize); diff --git a/src/main/java/com/webank/webase/node/mgr/user/UserController.java b/src/main/java/com/webank/webase/node/mgr/user/UserController.java index 7c6b63322..423a3b595 100644 --- a/src/main/java/com/webank/webase/node/mgr/user/UserController.java +++ b/src/main/java/com/webank/webase/node/mgr/user/UserController.java @@ -13,12 +13,14 @@ */ package com.webank.webase.node.mgr.user; +import com.webank.webase.node.mgr.base.annotation.CurrentAccount; +import com.webank.webase.node.mgr.base.annotation.entity.CurrentAccountInfo; import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.controller.BaseController; import com.webank.webase.node.mgr.base.entity.BasePageResponse; import com.webank.webase.node.mgr.base.entity.BaseResponse; import com.webank.webase.node.mgr.base.enums.CheckUserExist; -import com.webank.webase.node.mgr.base.enums.ReturnPrivateKey; +import com.webank.webase.node.mgr.base.enums.RoleType; import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.base.properties.ConstantProperties; import com.webank.webase.node.mgr.base.tools.HttpRequestTools; @@ -36,7 +38,6 @@ import com.webank.webase.node.mgr.user.entity.UserParam; import java.time.Duration; import java.time.Instant; -import java.util.Base64; import java.util.List; import java.util.Optional; import javax.validation.Valid; @@ -72,15 +73,15 @@ public class UserController extends BaseController { */ @PostMapping(value = "/userInfo") @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN_OR_DEVELOPER) - public BaseResponse addUserInfo(@RequestBody @Valid NewUserInputParam user, - BindingResult result) throws NodeMgrException { + public BaseResponse addUserInfo(@RequestBody @Valid NewUserInputParam user, + @CurrentAccount CurrentAccountInfo currentAccountInfo, BindingResult result) throws NodeMgrException { checkBindResult(result); BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); // add user row TbUser userRow = userService.addUserInfoLocal(user.getGroupId(), user.getUserName(), - user.getAccount(), user.getDescription(), user.getUserType(), null); + currentAccountInfo.getAccount(), user.getDescription(), user.getUserType(), null); baseResponse.setData(userRow); log.info("end addUserInfo useTime:{} result:{}", @@ -95,13 +96,13 @@ public BaseResponse addUserInfo(@RequestBody @Valid NewUserInputParam user, @PostMapping(value = "/bind") @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN_OR_DEVELOPER) public BaseResponse bindUserInfo(@RequestBody @Valid BindUserInputParam user, - BindingResult result) throws NodeMgrException { + @CurrentAccount CurrentAccountInfo currentAccountInfo, BindingResult result) throws NodeMgrException { checkBindResult(result); BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); // query user row - TbUser userRow = userService.bindUserInfo(user, CheckUserExist.TURE.getValue()); + TbUser userRow = userService.bindUserInfo(user, currentAccountInfo.getAccount(), CheckUserExist.TURE.getValue()); baseResponse.setData(userRow); log.info("end bindUserInfo useTime:{} result:{}", @@ -142,14 +143,16 @@ public BaseResponse updateUserInfo(@RequestBody @Valid UpdateUserInputParam user public BasePageResponse userList(@PathVariable("groupId") Integer groupId, @PathVariable("pageNumber") Integer pageNumber, @PathVariable("pageSize") Integer pageSize, - @RequestParam(value = "account", required = false) String account, - @RequestParam(value = "userParam", required = false) String commParam) + @RequestParam(value = "userParam", required = false) String commParam, + @CurrentAccount CurrentAccountInfo currentAccountInfo) throws NodeMgrException { BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start userList startTime:{} groupId:{} pageNumber:{} pageSize:{} commParam:{}", startTime.toEpochMilli(), groupId, pageNumber, pageSize, commParam); + String account = RoleType.DEVELOPER.getValue().intValue() == currentAccountInfo.getRoleId().intValue() + ? currentAccountInfo.getAccount() : null; UserParam param = new UserParam(); param.setGroupId(groupId); param.setAccount(account); @@ -177,7 +180,7 @@ public BasePageResponse userList(@PathVariable("groupId") Integer groupId, @PostMapping("/import") @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN_OR_DEVELOPER) public BaseResponse importPrivateKey(@Valid @RequestBody ReqImportPrivateKey reqImport, - BindingResult result) { + @CurrentAccount CurrentAccountInfo currentAccountInfo, BindingResult result) { checkBindResult(result); BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); @@ -186,7 +189,7 @@ public BaseResponse importPrivateKey(@Valid @RequestBody ReqImportPrivateKey req String privateKeyEncoded = reqImport.getPrivateKey(); // add user row TbUser userRow = userService.addUserInfoLocal(reqImport.getGroupId(), reqImport.getUserName(), - reqImport.getAccount(), reqImport.getDescription(), reqImport.getUserType(), + currentAccountInfo.getAccount(), reqImport.getDescription(), reqImport.getUserType(), privateKeyEncoded); baseResponse.setData(userRow); @@ -199,7 +202,7 @@ public BaseResponse importPrivateKey(@Valid @RequestBody ReqImportPrivateKey req @PostMapping("/importPem") @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN_OR_DEVELOPER) public BaseResponse importPemPrivateKey(@Valid @RequestBody ReqImportPem reqImportPem, - BindingResult result) { + @CurrentAccount CurrentAccountInfo currentAccountInfo, BindingResult result) { checkBindResult(result); BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); @@ -209,6 +212,7 @@ public BaseResponse importPemPrivateKey(@Valid @RequestBody ReqImportPem reqImpo throw new NodeMgrException(ConstantCode.PEM_FORMAT_ERROR); } // import + reqImportPem.setAccount(currentAccountInfo.getAccount()); TbUser userRow = userService.importPem(reqImportPem, CheckUserExist.TURE.getValue()); baseResponse.setData(userRow); @@ -223,7 +227,8 @@ public BaseResponse importPemPrivateKey(@Valid @RequestBody ReqImportPem reqImpo public BaseResponse importP12PrivateKey(@RequestParam MultipartFile p12File, @RequestParam(required = false, defaultValue = "") String p12Password, @RequestParam Integer groupId, @RequestParam String userName, - @RequestParam String account, @RequestParam(required = false) String description) { + @RequestParam(required = false) String description, + @CurrentAccount CurrentAccountInfo currentAccountInfo) { BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); @@ -234,7 +239,7 @@ public BaseResponse importP12PrivateKey(@RequestParam MultipartFile p12File, throw new NodeMgrException(ConstantCode.P12_FILE_ERROR); } TbUser userRow = userService.importKeyStoreFromP12(p12File, p12Password, groupId, userName, - account, description, CheckUserExist.TURE.getValue()); + currentAccountInfo.getAccount(), description, CheckUserExist.TURE.getValue()); baseResponse.setData(userRow); log.info("end importPemPrivateKey useTime:{} result:{}", diff --git a/src/main/java/com/webank/webase/node/mgr/user/UserService.java b/src/main/java/com/webank/webase/node/mgr/user/UserService.java index a36b2d039..195924518 100644 --- a/src/main/java/com/webank/webase/node/mgr/user/UserService.java +++ b/src/main/java/com/webank/webase/node/mgr/user/UserService.java @@ -212,7 +212,7 @@ public TbUser addUserInfo(Integer groupId, String userName, String account, Stri * bind user info. */ @Transactional - public TbUser bindUserInfo(BindUserInputParam user, boolean isCheckExist) throws NodeMgrException { + public TbUser bindUserInfo(BindUserInputParam user, String account, boolean isCheckExist) throws NodeMgrException { log.debug("start bindUserInfo User:{}", JsonTools.toJSONString(user)); String publicKey = user.getPublicKey(); @@ -230,10 +230,10 @@ public TbUser bindUserInfo(BindUserInputParam user, boolean isCheckExist) throws // check group id groupService.checkGroupId(user.getGroupId()); // check account - accountService.accountExist(user.getAccount()); + accountService.accountExist(account); // check userName - TbUser userRow = queryByName(user.getGroupId(), user.getUserName(), user.getAccount()); + TbUser userRow = queryByName(user.getGroupId(), user.getUserName(), account); if (Objects.nonNull(userRow)) { if (!isCheckExist) { return userRow; @@ -247,7 +247,7 @@ public TbUser bindUserInfo(BindUserInputParam user, boolean isCheckExist) throws } // check address - TbUser addressRow = queryUser(null, user.getGroupId(), null, address, user.getAccount()); + TbUser addressRow = queryUser(null, user.getGroupId(), null, address, account); if (Objects.nonNull(addressRow)) { if (!isCheckExist) { return addressRow; @@ -258,7 +258,7 @@ public TbUser bindUserInfo(BindUserInputParam user, boolean isCheckExist) throws // add row TbUser newUserRow = new TbUser(HasPk.NONE.getValue(), user.getUserType(), - user.getUserName(), user.getAccount(), user.getGroupId(), address, publicKey, + user.getUserName(), account, user.getGroupId(), address, publicKey, user.getDescription()); Integer affectRow = userMapper.addUserRow(newUserRow); if (affectRow == 0) { diff --git a/src/main/java/com/webank/webase/node/mgr/user/entity/BindUserInputParam.java b/src/main/java/com/webank/webase/node/mgr/user/entity/BindUserInputParam.java index 601de5425..0f61a043e 100644 --- a/src/main/java/com/webank/webase/node/mgr/user/entity/BindUserInputParam.java +++ b/src/main/java/com/webank/webase/node/mgr/user/entity/BindUserInputParam.java @@ -31,8 +31,6 @@ public class BindUserInputParam { @NotBlank @Length(max=64) private String userName; - @NotBlank - @Length(max=50) private String account; @NotBlank private String publicKey; diff --git a/src/main/java/com/webank/webase/node/mgr/user/entity/NewUserInputParam.java b/src/main/java/com/webank/webase/node/mgr/user/entity/NewUserInputParam.java index ef5d0e578..c02cf726c 100644 --- a/src/main/java/com/webank/webase/node/mgr/user/entity/NewUserInputParam.java +++ b/src/main/java/com/webank/webase/node/mgr/user/entity/NewUserInputParam.java @@ -32,8 +32,6 @@ public class NewUserInputParam { @NotBlank @Length(max=64) private String userName; - @NotBlank - @Length(max=50) private String account; @NotNull private Integer groupId; diff --git a/src/main/resources/mapper/ContractPathMapper.xml b/src/main/resources/mapper/ContractPathMapper.xml index d2fdb659d..ebd95e934 100644 --- a/src/main/resources/mapper/ContractPathMapper.xml +++ b/src/main/resources/mapper/ContractPathMapper.xml @@ -10,6 +10,8 @@ property="groupId" /> + - REPLACE INTO tb_contract_path(group_id,contract_path,create_time,modify_time) - VALUES (#{groupId},#{contractPath}, now(), now()) + REPLACE INTO tb_contract_path(group_id,contract_path,account,create_time,modify_time) + VALUES (#{groupId},#{contractPath},#{account}, now(), now()) @@ -49,6 +51,9 @@ resultMap="pathMap"> select * from tb_contract_path where group_id = #{groupId} + + and account = #{account} + order by modify_time desc From 2e0b36a9b1a0c39ece2913b21f54eb277db8e7dc Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 18 May 2021 20:55:11 +0800 Subject: [PATCH 72/92] update log --- .../webase/node/mgr/frontinterface/FrontInterfaceService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontInterfaceService.java b/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontInterfaceService.java index d9669c8b7..5cf68b78e 100644 --- a/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontInterfaceService.java +++ b/src/main/java/com/webank/webase/node/mgr/frontinterface/FrontInterfaceService.java @@ -387,7 +387,7 @@ public List getObserverList(Integer groupId) { log.debug("start getObserverList. groupId:{}", groupId); List observers = frontRestTools.getForEntity(groupId, FrontRestTools.URI_GET_OBSERVER_LIST, List.class); - log.info("end getObserverList. observers:{}", JsonTools.toJSONString(observers)); + log.debug("end getObserverList. observers:{}", JsonTools.toJSONString(observers)); return observers; } From 972e63e17071b7f8cd1e4bafe1f932a90fe4affb Mon Sep 17 00:00:00 2001 From: Sayou1989 Date: Wed, 19 May 2021 10:02:08 +0800 Subject: [PATCH 73/92] fix mointorInfo to monitorInfo --- .../java/com/webank/webase/node/mgr/chain/ChainController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/webank/webase/node/mgr/chain/ChainController.java b/src/main/java/com/webank/webase/node/mgr/chain/ChainController.java index 0aedbf08c..f52e4a0ae 100644 --- a/src/main/java/com/webank/webase/node/mgr/chain/ChainController.java +++ b/src/main/java/com/webank/webase/node/mgr/chain/ChainController.java @@ -43,7 +43,7 @@ public class ChainController { @Autowired private ChainService chainService; - @GetMapping(value = "/mointorInfo/{frontId}") + @GetMapping(value = "/monitorInfo/{frontId}") public BaseResponse getChainMoinntorInfo(@PathVariable("frontId") Integer frontId, @RequestParam(required = false) @DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime beginDate, @RequestParam(required = false) @DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime endDate, From 8c9fddb5b3c45784b6dc39b49ee1f5357bc4c0e6 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Wed, 19 May 2021 14:42:56 +0800 Subject: [PATCH 74/92] rm exclude key mini jar --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 61207af28..8914ad80f 100644 --- a/build.gradle +++ b/build.gradle @@ -124,7 +124,7 @@ configurations { all*.exclude group: 'jline', module: 'jline' all*.exclude group: 'com.google.protobuf', module: 'protobuf-java' all*.exclude group: 'javax.annotation', module: 'javax.annotation-api' - all*.exclude group: 'com.webank', module: 'key-mini-toolkit' + //all*.exclude group: 'com.webank', module: 'key-mini-toolkit' } sourceSets { From bdab28db73eff5bbe05efb8c1a570b96e6e6ec31 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Wed, 19 May 2021 15:27:00 +0800 Subject: [PATCH 75/92] rm old java sdk --- build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 8914ad80f..7c7d3913c 100644 --- a/build.gradle +++ b/build.gradle @@ -81,7 +81,7 @@ List mbg = [ List scaffold = [ 'com.webank.webase:solscaffold:1.0.0-SNAPSHOT', 'com.webank:SmartDev-Scaffold:1.0.0-SNAPSHOT', - 'com.webank:solc-gradle-plugin:1.0.0-SNAPSHOT' + 'com.webank:solc-gradle-plugin:1.0.1-SNAPSHOT' ] dependencies { @@ -124,7 +124,6 @@ configurations { all*.exclude group: 'jline', module: 'jline' all*.exclude group: 'com.google.protobuf', module: 'protobuf-java' all*.exclude group: 'javax.annotation', module: 'javax.annotation-api' - //all*.exclude group: 'com.webank', module: 'key-mini-toolkit' } sourceSets { From 45fc6f01468b476c8b884e96fea40246911bca5c Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 20 May 2021 15:24:26 +0800 Subject: [PATCH 76/92] fix precompiled contract --- .../node/mgr/external/ExtContractService.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java b/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java index 60db60daf..ca81d41d9 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java @@ -69,14 +69,16 @@ public void asyncSaveContract(int groupId, String txHash, String timestampStr) { // if send transaction to call contract, receipt's contract address is all zero, // receipt's to is contract address String contractAddress = txReceipt.getTo(); - // ignore precompiled contract address - if (contractAddress.startsWith(ConstantProperties.ADDRESS_PRECOMPILED)) { - return; - } + // if receipt's to is all zero, deploy transaction - if (ConstantProperties.ADDRESS_DEPLOY.equals(txReceipt.getTo())) { + if (ConstantProperties.ADDRESS_DEPLOY.equalsIgnoreCase(txReceipt.getTo())) { + log.info("deploy contract tx :{}", txReceipt.getContractAddress()); contractAddress = txReceipt.getContractAddress(); } + // ignore precompiled contract address + if (txReceipt.getTo().startsWith(ConstantProperties.ADDRESS_PRECOMPILED)) { + return; + } // save ext contract saveContractOnChain(groupId, contractAddress, txHash, txReceipt.getFrom(), timestampStr); @@ -88,7 +90,7 @@ public void asyncSaveContract(int groupId, String txHash, String timestampStr) { @Transactional public int saveContractOnChain(int groupId, String contractAddress, String txHash, String deployAddress, String timestamp) { - //log.info("saveContractOnChain groupId:{} contractAddress:{}", groupId, contractAddress); + log.info("saveContractOnChain groupId:{} contractAddress:{}", groupId, contractAddress); if (checkAddressExist(groupId, contractAddress)) { return 0; } @@ -131,7 +133,7 @@ public int saveContractOnChain(int groupId, String contractAddress, String txHas private boolean checkAddressExist(int groupId, String contractAddress) { int count = extContractMapper.countOfExtContract(groupId, contractAddress); if (count > 0) { - log.debug("saveContractOnChain exists tb_external_contract" + log.info("saveContractOnChain exists tb_external_contract" + " groupId:{} address:{}", groupId, contractAddress); return true; } From bfa190d3e577fd3ae75dc21297dbb6cf6a34fdb6 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 20 May 2021 15:24:36 +0800 Subject: [PATCH 77/92] fix contract address search --- .../node/mgr/external/mapper/TbExternalContractSqlProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java index 4043441cb..257fd7ce1 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java +++ b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java @@ -35,7 +35,7 @@ public String listJoin(ContractParam param) { sql.WHERE("b.contractName = #{contractName}"); } if (param.getContractAddress() != null) { - sql.WHERE("ext.contractAddress = #{contractAddress}"); + sql.WHERE("ext.contract_address = #{contractAddress}"); } // get all or some // 1-all(default), 2-normal, 3-abnormal From 16dd0c8ca1f992debb9849c863891f0ad14dfed6 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 20 May 2021 16:01:38 +0800 Subject: [PATCH 78/92] fix contract 0x0 --- .../webase/node/mgr/external/ExtContractService.java | 8 +++++--- .../webase/node/mgr/monitor/MonitorService.java | 12 ++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java b/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java index ca81d41d9..0b3650d6b 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/external/ExtContractService.java @@ -72,11 +72,12 @@ public void asyncSaveContract(int groupId, String txHash, String timestampStr) { // if receipt's to is all zero, deploy transaction if (ConstantProperties.ADDRESS_DEPLOY.equalsIgnoreCase(txReceipt.getTo())) { - log.info("deploy contract tx :{}", txReceipt.getContractAddress()); + log.debug("deploy contract tx :{}", txReceipt.getContractAddress()); contractAddress = txReceipt.getContractAddress(); } // ignore precompiled contract address - if (txReceipt.getTo().startsWith(ConstantProperties.ADDRESS_PRECOMPILED)) { + if (contractAddress.startsWith(ConstantProperties.ADDRESS_PRECOMPILED)) { + log.debug("ignore precompiled contract:{}", contractAddress); return; } // save ext contract @@ -90,8 +91,9 @@ public void asyncSaveContract(int groupId, String txHash, String timestampStr) { @Transactional public int saveContractOnChain(int groupId, String contractAddress, String txHash, String deployAddress, String timestamp) { - log.info("saveContractOnChain groupId:{} contractAddress:{}", groupId, contractAddress); + log.debug("saveContractOnChain groupId:{} contractAddress:{}", groupId, contractAddress); if (checkAddressExist(groupId, contractAddress)) { + log.info("checkAddressExist groupId:{} contractAddress:{}", groupId, contractAddress); return 0; } TbExternalContract tbContract = new TbExternalContract(); diff --git a/src/main/java/com/webank/webase/node/mgr/monitor/MonitorService.java b/src/main/java/com/webank/webase/node/mgr/monitor/MonitorService.java index 1a1b436af..3168be2a6 100644 --- a/src/main/java/com/webank/webase/node/mgr/monitor/MonitorService.java +++ b/src/main/java/com/webank/webase/node/mgr/monitor/MonitorService.java @@ -82,7 +82,7 @@ public class MonitorService { @Autowired private TransHashService transHashService; @Autowired - private FrontInterfaceService frontInterfacee; + private FrontInterfaceService frontInterface; @Autowired private MonitorTransactionService monitorTransactionService; @Autowired @@ -198,7 +198,7 @@ public void updateUnusualContract(Integer groupId, String contractName, String c if (StringUtils.isBlank(txHash)) { return; } - ChainTransInfo trans = frontInterfacee.getTransInfoByHash(groupId, txHash); + ChainTransInfo trans = frontInterface.getTransInfoByHash(groupId, txHash); if (trans == null) { return; } @@ -340,7 +340,7 @@ public List queryUnusualContractList(Integer groupId, public void monitorTransHash(int groupId, TbTransHash trans, LocalDateTime createTime) { try { - ChainTransInfo chanTrans = frontInterfacee + ChainTransInfo chanTrans = frontInterface .getTransInfoByHash(groupId, trans.getTransHash()); if (Objects.isNull(chanTrans)) { log.error("monitor jump over,invalid hash. groupId:{} hash:{}", groupId, @@ -388,7 +388,7 @@ private ContractMonitorResult monitorContract(int groupId, String transHash, Str int transUnusualType = TransUnusualType.NORMAL.getValue(); // deploy contract tx if (isDeploy(transTo)) { - contractAddress = frontInterfacee.getAddressByHash(groupId, transHash); + contractAddress = frontInterface.getAddressByHash(groupId, transHash); if (ConstantProperties.ADDRESS_DEPLOY.equals(contractAddress)) { contractBin = StringUtils.removeStart(transInput, "0x"); @@ -410,7 +410,7 @@ private ContractMonitorResult monitorContract(int groupId, String transHash, Str transUnusualType = TransUnusualType.CONTRACT.getValue(); } } else { - contractBin = frontInterfacee.getCodeFromFront(groupId, contractAddress, blockNumber); + contractBin = frontInterface.getCodeFromFront(groupId, contractAddress, blockNumber); contractBin = removeBinFirstAndLast(contractBin); List contractRow = contractService.queryContractByBin(groupId, contractBin); @@ -433,7 +433,7 @@ private ContractMonitorResult monitorContract(int groupId, String transHash, Str transType = TransType.CALL.getValue(); String methodId = transInput.substring(0, 10); contractAddress = transTo; - contractBin = frontInterfacee.getCodeFromFront(groupId, contractAddress, blockNumber); + contractBin = frontInterface.getCodeFromFront(groupId, contractAddress, blockNumber); contractBin = removeBinFirstAndLast(contractBin); List contractRow = contractService.queryContractByBin(groupId, contractBin); From 2c32d4c59fc8e72c19591930f12e7a1f56ecf32c Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 20 May 2021 16:53:27 +0800 Subject: [PATCH 79/92] fix dot --- .../webase/node/mgr/scaffold/ScaffoldController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java index 65654ab98..335de996e 100644 --- a/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java +++ b/src/main/java/com/webank/webase/node/mgr/scaffold/ScaffoldController.java @@ -61,10 +61,10 @@ public BaseResponse exportProjectApi(@Valid @RequestBody ReqProject param) { throw new NodeMgrException(ConstantCode.PARAM_INVALID_LETTER_DIGIT); } // validate group name, ex: org.example - if (!param.getGroup().contains("\\.")) { + if (!param.getGroup().contains(".")) { // only org if (!NodeMgrTools.startWithLetter(param.getGroup())) { - log.error("must start with letter"); + log.error("group must start with letter"); throw new NodeMgrException(ConstantCode.PARAM_INVALID_LETTER_DIGIT); } } else { @@ -73,11 +73,11 @@ public BaseResponse exportProjectApi(@Valid @RequestBody ReqProject param) { for (String group: groupNameArray) { // not start or end with dot "." if (StringUtils.isBlank(group)) { - log.error("group cannot start or end with dot"); + log.error("group must start with letter, and not end with dot"); throw new NodeMgrException(ConstantCode.PARAM_INVALID_LETTER_DIGIT); } if (!NodeMgrTools.startWithLetter(group)) { - log.error("package name must start with letter"); + log.error("group name must start with letter"); throw new NodeMgrException(ConstantCode.PARAM_INVALID_LETTER_DIGIT); } } From 945f1dbaea564fbdc3f7823583049fdf854443ec Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 20 May 2021 16:53:43 +0800 Subject: [PATCH 80/92] add user name address search --- .../node/mgr/external/ExternalController.java | 4 ++++ .../mapper/TbExternalAccountSqlProvider.java | 16 ++++++++++++++-- .../mapper/TbExternalContractSqlProvider.java | 1 - .../webase/node/mgr/user/entity/UserParam.java | 1 + 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/external/ExternalController.java b/src/main/java/com/webank/webase/node/mgr/external/ExternalController.java index e92f3f88f..0f63b2c8a 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/ExternalController.java +++ b/src/main/java/com/webank/webase/node/mgr/external/ExternalController.java @@ -128,6 +128,8 @@ public BasePageResponse listExtUserListJoin(@PathVariable("groupId") Integer gro @PathVariable("pageNumber") Integer pageNumber, @PathVariable("pageSize") Integer pageSize, @RequestParam(value = "type", defaultValue = "1") Integer type, + @RequestParam(value = "userName", required = false) String userName, + @RequestParam(value = "address", required = false) String address, @CurrentAccount CurrentAccountInfo currentAccountInfo) throws NodeMgrException { BasePageResponse pageResponse = new BasePageResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); @@ -140,6 +142,8 @@ public BasePageResponse listExtUserListJoin(@PathVariable("groupId") Integer gro param.setGroupId(groupId); param.setPageSize(pageSize); param.setAccount(account); + param.setUserName(userName); + param.setAddress(address); // type: 1-all, 2-normal param.setCommParam(type.toString()); diff --git a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java index ecf8812fe..a180f343d 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java +++ b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalAccountSqlProvider.java @@ -30,6 +30,12 @@ public String listJoin(UserParam param) { if (param.getAccount() != null) { sql.WHERE("b.account = #{account}"); } + if (param.getUserName() != null) { + sql.WHERE("b.userName = #{userName}"); + } + if (param.getAddress() != null) { + sql.WHERE("ext.address = #{address}"); + } // get all or some // 1-all(default), 2-normal, 3-abnormal if (Integer.parseInt(param.getCommParam()) == ExternalInfoType.NORMAL.getValue()) { @@ -47,9 +53,9 @@ public String listJoin(UserParam param) { public String count(UserParam param) { SQL sql = new SQL(); - sql.SELECT("count(1),ext.group_id,ext.address,b.userId,b.account from tb_external_account ext " + sql.SELECT("count(1),ext.group_id,ext.address,b.userId,b.account,b.userName from tb_external_account ext " + "left join " - + "(select user_id userId,group_id,address,account from tb_user) b " + + "(select user_id userId,group_id,address,account,user_name userName from tb_user) b " + "on ext.address=b.address and ext.group_id=b.group_id "); if (param.getGroupId() != null) { sql.WHERE("ext.group_id = #{groupId}"); @@ -57,6 +63,12 @@ public String count(UserParam param) { if (param.getAccount() != null) { sql.WHERE("b.account = #{account}"); } + if (param.getUserName() != null) { + sql.WHERE("b.userName = #{userName}"); + } + if (param.getAddress() != null) { + sql.WHERE("ext.address = #{address}"); + } // get all or some // 1-all(default), 2-normal, 3-abnormal if (Integer.parseInt(param.getCommParam()) == ExternalInfoType.NORMAL.getValue()) { diff --git a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java index 257fd7ce1..e3b2e130c 100644 --- a/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java +++ b/src/main/java/com/webank/webase/node/mgr/external/mapper/TbExternalContractSqlProvider.java @@ -22,7 +22,6 @@ public String listJoin(ContractParam param) { "LEFT JOIN " + "( SELECT distinct(contract_address),sum(trans_count) transCount,max(trans_hashs) hashs " + "FROM tb_user_transaction_monitor_${groupId} WHERE trans_unusual_type=1 group by contract_address" + - // if external address equal to monitor user's username, it means user not imported ") c on ext.contract_address=c.contract_address"; sql.SELECT(columnsWithJoin); if (param.getGroupId() != null) { diff --git a/src/main/java/com/webank/webase/node/mgr/user/entity/UserParam.java b/src/main/java/com/webank/webase/node/mgr/user/entity/UserParam.java index 2c53911f6..a8c7c5b06 100644 --- a/src/main/java/com/webank/webase/node/mgr/user/entity/UserParam.java +++ b/src/main/java/com/webank/webase/node/mgr/user/entity/UserParam.java @@ -32,4 +32,5 @@ public class UserParam extends BaseQueryParam { private String account; private String commParam; private Integer hasPk; + private String address; } \ No newline at end of file From b8050e6c15128a0959272b604a0f29ec2a8e1960 Mon Sep 17 00:00:00 2001 From: Sayou1989 Date: Thu, 20 May 2021 17:38:44 +0800 Subject: [PATCH 81/92] developer can delete their own contract path --- .../node/mgr/base/code/ConstantCode.java | 2 +- .../node/mgr/contract/ContractController.java | 29 ++++++++++--------- .../mgr/contract/ContractPathService.java | 11 ++++--- .../node/mgr/contract/ContractService.java | 15 ++++++++-- .../contract/entity/ContractPathParam.java | 1 + .../resources/mapper/ContractPathMapper.xml | 3 ++ 6 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java index 2a6e2fdd9..20b1da75f 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java +++ b/src/main/java/com/webank/webase/node/mgr/base/code/ConstantCode.java @@ -318,7 +318,7 @@ public class ConstantCode { public static final RetCode GENERATE_CONTRACT_PROJECT_FAIL = RetCode.mark(202531, "generate project failed in scaffold"); public static final RetCode GET_FRONT_SDK_MAP_FAIL = RetCode.mark(202532, "get sdk cert/key content map failed"); public static final RetCode PARAM_INVALID_LETTER_DIGIT = RetCode.mark(202533, "Only support letter and digit, please check your params"); - + public static final RetCode CONTRACT_PATH_NOT_EXISTS = RetCode.mark(202534, "contract path not exists."); /* auth */ public static final RetCode USER_NOT_LOGGED_IN = RetCode.mark(302000, "user not logged in"); diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java index f3102410b..b4e10ac1b 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractController.java @@ -341,14 +341,15 @@ public BasePageResponse queryContractPathList(@PathVariable("groupId") Integer g * delete contract by id. only admin batch delete contract */ @DeleteMapping(value = "/batch/path") - @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN) - public BaseResponse deleteContractByPath(@Valid @RequestBody ContractPathParam param) { + @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN_OR_DEVELOPER) + public BaseResponse deleteContractByPath(@Valid @RequestBody ContractPathParam param, + @CurrentAccount CurrentAccountInfo currentAccountInfo) { BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); log.info("start deleteContractByPath startTime:{} ContractPathParam:{}", startTime.toEpochMilli(), param); - - contractService.deleteByContractPath(param); + + contractService.deleteByContractPath(param, currentAccountInfo); log.info("end deleteContractByPath useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); @@ -365,9 +366,9 @@ public BasePageResponse listContractByMultiPath(@RequestBody ReqListContract inp Instant startTime = Instant.now(); log.info("start listContractByMultiPath. startTime:{} inputParam:{}", startTime.toEpochMilli(), JsonTools.toJSONString(inputParam)); - - String account = RoleType.DEVELOPER.getValue().intValue() == currentAccountInfo.getRoleId().intValue() - ? currentAccountInfo.getAccount() : null; + + String account = RoleType.DEVELOPER.getValue().intValue() == currentAccountInfo.getRoleId() + .intValue() ? currentAccountInfo.getAccount() : null; inputParam.setAccount(account); List contractList = contractService.queryContractListMultiPath(inputParam); pageResponse.setTotalCount(contractList.size()); @@ -401,8 +402,8 @@ public BaseResponse registerCns(@RequestBody @Valid ReqRegisterCns reqRegisterCn * query cns info */ @PostMapping(value = "/findCns") - public BaseResponse findCnsByAddress(@RequestBody @Valid ReqQueryCns reqQueryCns, BindingResult result) - throws NodeMgrException { + public BaseResponse findCnsByAddress(@RequestBody @Valid ReqQueryCns reqQueryCns, + BindingResult result) throws NodeMgrException { checkBindResult(result); BaseResponse pageResponse = new BaseResponse(ConstantCode.SUCCESS); Instant startTime = Instant.now(); @@ -411,7 +412,8 @@ public BaseResponse findCnsByAddress(@RequestBody @Valid ReqQueryCns reqQueryCns TbCns tbCns = cnsService.getCnsByAddress( new QueryCnsParam(reqQueryCns.getGroupId(), reqQueryCns.getContractAddress())); pageResponse.setData(tbCns); - log.info("end findCnsByAddress. useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); + log.info("end findCnsByAddress. useTime:{}", + Duration.between(startTime, Instant.now()).toMillis()); return pageResponse; } @@ -451,13 +453,14 @@ public BasePageResponse findCnsList(@RequestBody @Valid ReqQueryCnsList inputPar @PostMapping(value = "/copy") @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN_OR_DEVELOPER) public BaseResponse copyContracts(@RequestBody @Valid ReqCopyContracts req, - BindingResult result) { + BindingResult result) { Instant startTime = Instant.now(); log.info("copyContracts start. startTime:{} req:{}", startTime.toEpochMilli(), - JsonTools.toJSONString(req)); + JsonTools.toJSONString(req)); checkBindResult(result); contractService.copyContracts(req); - log.info("end copyContracts. useTime:{}", Duration.between(startTime, Instant.now()).toMillis()); + log.info("end copyContracts. useTime:{}", + Duration.between(startTime, Instant.now()).toMillis()); return new BaseResponse(ConstantCode.SUCCESS, req.getContractItems().size()); } } diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractPathService.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractPathService.java index 74c9d2cb6..52fe2865c 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractPathService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractPathService.java @@ -38,12 +38,14 @@ public List listContractPath(Integer groupId, String account) { /** * save not exist path + * * @param groupId * @param pathName * @return */ public int save(Integer groupId, String pathName, String account, boolean ignoreRepeat) { - TbContractPath check = contractPathMapper.findOne(new ContractPathParam(groupId, pathName)); + TbContractPath check = + contractPathMapper.findOne(new ContractPathParam(groupId, pathName, null)); if (check != null) { if (ignoreRepeat) { return 0; @@ -81,9 +83,10 @@ public int removeByPathName(ContractPathParam param) { public void removeByGroupId(Integer groupId) { contractPathMapper.removeByGroupId(groupId); } - - public boolean checkPathExist(Integer groupId, String pathName) { - TbContractPath contractPath = contractPathMapper.findOne(new ContractPathParam(groupId, pathName)); + + public boolean checkPathExist(Integer groupId, String pathName, String account) { + TbContractPath contractPath = + contractPathMapper.findOne(new ContractPathParam(groupId, pathName, account)); if (contractPath != null) { return true; } else { diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java index fe11627ea..66ebcffa9 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java @@ -17,10 +17,12 @@ import com.webank.webase.node.mgr.appintegration.contractstore.entity.ContractStoreParam; import com.webank.webase.node.mgr.appintegration.contractstore.entity.ReqContractAddressSave; import com.webank.webase.node.mgr.appintegration.contractstore.entity.TbContractStore; +import com.webank.webase.node.mgr.base.annotation.entity.CurrentAccountInfo; import com.webank.webase.node.mgr.base.code.ConstantCode; import com.webank.webase.node.mgr.base.entity.BasePageResponse; import com.webank.webase.node.mgr.base.enums.ContractStatus; import com.webank.webase.node.mgr.base.enums.ContractType; +import com.webank.webase.node.mgr.base.enums.RoleType; import com.webank.webase.node.mgr.base.exception.NodeMgrException; import com.webank.webase.node.mgr.base.properties.ConstantProperties; import com.webank.webase.node.mgr.base.tools.JsonTools; @@ -183,7 +185,8 @@ public void appContractSave(String appKey, ReqContractAddressSave reqContractAdd if (CollectionUtils.isEmpty(listOfContractStore)) { throw new NodeMgrException(ConstantCode.CONTRACT_SOURCE_NOT_EXIST); } - boolean pathExist = contractPathService.checkPathExist(groupId, contractPath); + boolean pathExist = contractPathService.checkPathExist(groupId, contractPath, + listOfContractStore.get(0).getAccount()); for (TbContractStore tbContractStore : listOfContractStore) { // check if tbContractStore has been saved if (pathExist && !tbContractStore.getContractName().equals(contractName)) { @@ -642,8 +645,16 @@ public List queryContractPathList(Integer groupId, String accoun return resultList; } - public void deleteByContractPath(ContractPathParam param) { + public void deleteByContractPath(ContractPathParam param, CurrentAccountInfo currentAccountInfo) { log.debug("start deleteByContractPath ContractPathParam:{}", JsonTools.toJSONString(param)); + // check developer + if (RoleType.DEVELOPER.getValue().intValue() == currentAccountInfo.getRoleId().intValue() + && !contractPathService.checkPathExist(param.getGroupId(), param.getContractPath(), + currentAccountInfo.getAccount())) { + log.error("end deleteByContractPath. contract path not exists."); + throw new NodeMgrException(ConstantCode.CONTRACT_PATH_NOT_EXISTS); + } + ContractParam listParam = new ContractParam(); BeanUtils.copyProperties(param, listParam); List contractList = contractMapper.listOfContract(listParam); diff --git a/src/main/java/com/webank/webase/node/mgr/contract/entity/ContractPathParam.java b/src/main/java/com/webank/webase/node/mgr/contract/entity/ContractPathParam.java index 8c34f26f8..2ae99b17f 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/entity/ContractPathParam.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/entity/ContractPathParam.java @@ -24,4 +24,5 @@ public class ContractPathParam { private Integer groupId; private String contractPath; + private String account; } diff --git a/src/main/resources/mapper/ContractPathMapper.xml b/src/main/resources/mapper/ContractPathMapper.xml index ebd95e934..e64aa76e9 100644 --- a/src/main/resources/mapper/ContractPathMapper.xml +++ b/src/main/resources/mapper/ContractPathMapper.xml @@ -62,6 +62,9 @@ select * from tb_contract_path where group_id = #{groupId} and contract_path = #{contractPath} + + and account = #{account} + \ No newline at end of file From 104887474827c2f295f7dd1506a7723a54d89568 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Mon, 24 May 2021 15:46:29 +0800 Subject: [PATCH 82/92] update lib string --- script/webase-dml.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/webase-dml.sql b/script/webase-dml.sql index 8c3dfe086..31942ea4a 100644 --- a/script/webase-dml.sql +++ b/script/webase-dml.sql @@ -180,7 +180,7 @@ INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `con (1, 1, 1, 'Address', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', 'IyBBZGRyZXNzCgpBZGRyZXNzIGxpYnJhcnkKCkFkZHJlc3MgY29udHJhY3QgdXNhZ2UgbWV0aG9kcyBjYW4gcmVmZXIgdG8gdGhlIFBvaW50cyBjb250cmFjdCB3YXJlaG91c2XjgIIKCjEuIERldGVjdCB3aGV0aGVyIHRoZSBhZGRyZXNzIGlzIGEgY29udHJhY3QKMi4gRGV0ZWN0IGlmIHRoZSBhZGRyZXNzIGlzIDB4MA==', now(), now()); INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(2, 1, 1, 'LibString', 'Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgXjAuNC4xMTsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gUmV0dXJucyB0aGUgbWVtb3J5IGFkZHJlc3Mgb2YgdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YKICAgIC8vIGBuZWVkbGVgIGluIGBzZWxmYCwgb3IgdGhlIGZpcnN0IGJ5dGUgYWZ0ZXIgYHNlbGZgIGlmIG5vdCBmb3VuZC4KICAgIGZ1bmN0aW9uIGZpbmRQdHIodWludCBzZWxmbGVuLCB1aW50IHNlbGZwdHIsIHVpbnQgbmVlZGxlbGVuLCB1aW50IG5lZWRsZXB0cikgcHJpdmF0ZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgdWludCBwdHI7CiAgICAgICAgdWludCBpZHg7CgogICAgICAgIGlmIChuZWVkbGVsZW4gPD0gc2VsZmxlbikgewogICAgICAgICAgICBpZiAobmVlZGxlbGVuIDw9IDMyKSB7CiAgICAgICAgICAgICAgICAvLyBPcHRpbWl6ZWQgYXNzZW1ibHkgZm9yIDY4IGdhcyBwZXIgYnl0ZSBvbiBzaG9ydCBzdHJpbmdzCiAgICAgICAgICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IG1hc2sgOj0gbm90KHN1YihleHAoMiwgbXVsKDgsIHN1YigzMiwgbmVlZGxlbGVuKSkpLCAxKSkKICAgICAgICAgICAgICAgICAgICBsZXQgbmVlZGxlZGF0YSA6PSBhbmQobWxvYWQobmVlZGxlcHRyKSwgbWFzaykKICAgICAgICAgICAgICAgICAgICBsZXQgZW5kIDo9IGFkZChzZWxmcHRyLCBzdWIoc2VsZmxlbiwgbmVlZGxlbGVuKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gc2VsZnB0cgogICAgICAgICAgICAgICAgICAgIGxvb3A6CiAgICAgICAgICAgICAgICAgICAganVtcGkoZXhpdCwgZXEoYW5kKG1sb2FkKHB0ciksIG1hc2spLCBuZWVkbGVkYXRhKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHB0ciwgMSkKICAgICAgICAgICAgICAgICAgICBqdW1waShsb29wLCBsdChzdWIocHRyLCAxKSwgZW5kKSkKICAgICAgICAgICAgICAgICAgICBwdHIgOj0gYWRkKHNlbGZwdHIsIHNlbGZsZW4pCiAgICAgICAgICAgICAgICAgICAgZXhpdDoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBGb3IgbG9uZyBuZWVkbGVzLCB1c2UgaGFzaGluZwogICAgICAgICAgICAgICAgYnl0ZXMzMiBoYXNoOwogICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBoYXNoIDo9IHNoYTMobmVlZGxlcHRyLCBuZWVkbGVsZW4pIH0KICAgICAgICAgICAgICAgIHB0ciA9IHNlbGZwdHI7CiAgICAgICAgICAgICAgICBmb3IgKGlkeCA9IDA7IGlkeCA8PSBzZWxmbGVuIC0gbmVlZGxlbGVuOyBpZHgrKykgewogICAgICAgICAgICAgICAgICAgIGJ5dGVzMzIgdGVzdEhhc2g7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibHkgeyB0ZXN0SGFzaCA6PSBzaGEzKHB0ciwgbmVlZGxlbGVuKSB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc2ggPT0gdGVzdEhhc2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgICAgICAgICAgICAgcHRyICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGZwdHIgKyBzZWxmbGVuOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9zdHIpIGludGVybmFsIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY29tcGFyZU5vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBieXRlIGNoMSA9IGJ5dGVzKF9zZWxmKVtpXXwweDIwOwogICAgICAgICAgICBieXRlIGNoMiA9IGJ5dGVzKF9zdHIpW2ldfDB4MjA7CiAgICAgICAgICAgIGlmIChjaDEgPj0gJ2EnICYmIGNoMSA8PSd6JyAmJiBjaDIgPj0gJ2EnICYmIGNoMiA8PSd6JykgewogICAgICAgICAgICAgICAgaWYgKGNoMSA+IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaDEgPCBjaDIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW2ldIDwgYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFscyhzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgYnl0ZSBjaDEgPSBieXRlcyhfc2VsZilbaV18MHgyMDsKICAgICAgICAgICAgYnl0ZSBjaDIgPSBieXRlcyhfc3RyKVtpXXwweDIwOwogICAgICAgICAgICBpZiAoY2gxID49ICdhJyAmJiBjaDEgPD0neicgJiYgY2gyID49ICdhJyAmJiBjaDIgPD0neicpIHsKICAgICAgICAgICAgICAgIGlmIChjaDEgIT0gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gc3Vic3RyKHN0cmluZyBfc2VsZiwgdWludCBfc3RhcnQsIHVpbnQgX2xlbikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKF9sZW4pOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK19zdGFydCwgX2xlbik7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIG1lbWNweShyZXRwdHIrYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc3RycHRyLCBieXRlcyhfc3RyKS5sZW5ndGgpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBjb25jYXQoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cjEsIHN0cmluZyBfc3RyMikKICAgICAgICBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyMSwgc3RyaW5nIF9zdHIyLCBzdHJpbmcgX3N0cjMpCiAgICAgICAgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhieXRlcyhfc2VsZikubGVuZ3RoICsgYnl0ZXMoX3N0cjEpLmxlbmd0aCArIGJ5dGVzKF9zdHIyKS5sZW5ndGgKICAgICAgICAgICAgKyBieXRlcyhfc3RyMykubGVuZ3RoKTsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgc3RyMXB0cjsKICAgICAgICB1aW50IHN0cjJwdHI7CiAgICAgICAgdWludCBzdHIzcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgc3RyM3B0ciA6PSBhZGQoX3N0cjMsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMXB0ciwgYnl0ZXMoX3N0cjEpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIxKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjJwdHIsIGJ5dGVzKF9zdHIyKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIzcHRyLCBieXRlcyhfc3RyMykubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjMpLmxlbmd0aDsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgdWludCBpOwogICAgICAgIHVpbnQ4IGNoOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBjaCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgaT4wOyAtLWkpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaS0xXSk7CiAgICAgICAgICAgIGlmICghKGNoID09IDB4MjAgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEIHx8IGNoID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50IGVuZCA9IGk7CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50MTYgajsKICAgICAgICBib29sIG1hdGNoZWQ7CiAgICAgICAgZm9yIChpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgc3RhcnQgPSBpOwogICAgICAgIAogICAgICAgIGZvciAoaT11aW50MTYoYnl0ZXMoX3NlbGYpLmxlbmd0aCk7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8Ynl0ZXMoX2NoYXJzKS5sZW5ndGg7ICsraikgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpLTFdID09IGJ5dGVzKF9jaGFycylbal0pIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIW1hdGNoZWQpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHVpbnQxNiBlbmQgPSBpOwoKICAgICAgICBpZiAoZW5kIDw9IHN0YXJ0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoZW5kLXN0YXJ0KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICBtZW1jcHkocmV0cHRyLCBzZWxmcHRyK3N0YXJ0LCBlbmQtc3RhcnQpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgX3NlbGYsIHN0cmluZyBfZGVsaW0sIHN0cmluZ1tdIHN0b3JhZ2UgX2FycmF5KSBpbnRlcm5hbCB7CiAgICAgICAgLy9XaHkgY2FuIG5vdCB1c2UgZGVsZXRlIF9hcnJheT8KICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPF9hcnJheS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkZWxldGUgX2FycmF5W2ldOwogICAgICAgIH0KICAgICAgICBfYXJyYXkubGVuZ3RoID0gMDsKCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgZGVsaW1wdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgZGVsaW1wdHIgOj0gYWRkKF9kZWxpbSwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIHVpbnQgcHRyOwogICAgICAgICAgICBib29sIGZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChieXRlcyhfZGVsaW0pLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfZGVsaW0pLmxlbmd0aCwgZGVsaW1wdHIpIC0gc2VsZnB0cjsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKHB0ciA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHB0ciA9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwdHIgPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IGVsZW0gPSBuZXcgc3RyaW5nKHB0ci1wb3MpOwogICAgICAgICAgICB1aW50IGVsZW1wdHI7CiAgICAgICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgICAgIGVsZW1wdHIgOj0gYWRkKGVsZW0sIDB4MjApCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWVtY3B5KGVsZW1wdHIsIHNlbGZwdHIrcG9zLCBwdHItcG9zKTsKICAgICAgICAgICAgcG9zID0gcHRyICsgYnl0ZXMoX2RlbGltKS5sZW5ndGg7CiAgICAgICAgICAgIF9hcnJheS5wdXNoKGVsZW0pOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCFmb3VuZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aCwgc2VsZnB0ciwgYnl0ZXMoX3N0cikubGVuZ3RoLCBzdHJwdHIpIC0gc2VsZnB0cjsKICAgICAgICBpZiAocHRyIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICBfcmV0ID0gaW50KHB0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3JldCA9IC0xOwogICAgICAgIH0KICAgIH0KICAgIAogICAgZnVuY3Rpb24gaW5kZXhPZihzdHJpbmcgX3NlbGYsIHN0cmluZyBfc3RyLCB1aW50IHBvcykgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHJwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RycHRyIDo9IGFkZChfc3RyLCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoYnl0ZXMoX3NlbGYpLmxlbmd0aC1wb3MsIHNlbGZwdHIrcG9zLCBieXRlcyhfc3RyKS5sZW5ndGgsIHN0cnB0cikgLSBzZWxmcHRyOwogICAgICAgIGlmIChwdHIgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgIF9yZXQgPSBpbnQocHRyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBfcmV0ID0gLTE7CiAgICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0ludChzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGludCBfcmV0KSB7CiAgICAgICAgX3JldCA9IDA7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID09ICcrJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9IGVsc2UgaWYoYnl0ZXMoX3NlbGYpW2ldID09ICctJykgewogICAgICAgICAgICBwb3NpdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQoKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA+PSAweDMwICYmIGRpZ2l0IDw9IDB4MzkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKGFkZHJlc3MgX3JldCkgewogICAgICAgIHVpbnQxNiBpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aC1pIDwgMikgewogICAgICAgICAgICByZXR1cm4gYWRkcmVzcygwKTsKICAgICAgICB9CgogICAgICAgIC8vbXVzdCBzdGFydCB3aXRoIDB4CiAgICAgICAgaWYgKCEoYnl0ZXMoX3NlbGYpW2ldID09ICcwJyAmJiBieXRlcyhfc2VsZilbaSsxXXwweDIwID09ICd4JykpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICB1aW50IGFkZHIgPSAwOwogICAgICAgIAogICAgICAgIGZvciAoaSs9MjsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSAvLycwJy0nOScKICAgICAgICAgICAgICAgIGRpZ2l0IC09IDB4MzA7CiAgICAgICAgICAgIGVsc2UgaWYgKGRpZ2l0fDB4MjAgPj0gMHg2MSAmJiBkaWdpdHwweDIwIDw9IDB4NjYpIC8vJ2EnLSdmJwogICAgICAgICAgICAgICAgZGlnaXQgPSBkaWdpdC0weDYxKzEwOwogICAgICAgICAgICBlbHNlIAogICAgICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7IAogICAgICAgICAgICAKICAgICAgICAgICAgYWRkciA9IGFkZHIqMTYrZGlnaXQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBhZGRyZXNzKGFkZHIpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0tleVZhbHVlKHN0cmluZyBfc2VsZiwgc3RyaW5nIF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9rZXkpLmxlbmd0aCArIDUpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IGtleXB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBrZXlwdHIgOj0gYWRkKF9rZXksIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdWludCBwb3MgPSAwOwoKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIGtleXB0ciwgYnl0ZXMoX2tleSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX2tleSkubGVuZ3RoOwogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICAKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnOic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzZWxmcHRyLCBieXRlcyhfc2VsZikubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3NlbGYpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldFN0cmluZ1ZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIF9yZXQpIHsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc3RhcnQgKz0gMTsKICAgICAgICAKICAgICAgICBpbnQgZW5kOwogICAgICAgIGlmIChkb3VibGVRdW90ZXMpIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHN0YXJ0KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5kID0gX3NlbGYuaW5kZXhPZigiJyIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVuZCA9PSAtMSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZi5zdWJzdHIodWludChzdGFydCksIHVpbnQoZW5kLXN0YXJ0KSk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldEludFZhbHVlQnlLZXkoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcG9zICs9IGludChieXRlcyhfa2V5KS5sZW5ndGgrMik7CgogICAgICAgICAgICBib29sIGNvbG9uID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICh1aW50KHBvcykgPCBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJyAnIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcdCcgCiAgICAgICAgICAgICAgICAgICAgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xyJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICc6JykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGNvbG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHVpbnQocG9zKSA9PSBieXRlcyhfc2VsZikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdWludCBpID0gdWludChwb3MpOwogICAgICAgIHVpbnQ4IGRpZ2l0OwogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID09IDB4MjAgfHwgZGlnaXQgPT0gMHgwOSB8fCBkaWdpdCA9PSAweDBEIHx8IGRpZ2l0ID09IDB4MEEgCiAgICAgICAgICAgIHx8IGRpZ2l0ID09IDB4M0EgLyo6Ki8gfHwgZGlnaXQgPT0gMHgyMiAvKiIqLyB8fCBkaWdpdCA9PSAweDI3IC8qJyovKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gdG9VcHBlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnYScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICd6JykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldICY9IH4weDIwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIF9yZXQgPSBfc2VsZjsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9Mb3dlcihzdHJpbmcgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA+PSAnQScgJiYgYnl0ZXMoX3NlbGYpW2ldIDw9ICdaJykgewogICAgICAgICAgICAgICAgYnl0ZXMoX3NlbGYpW2ldIHw9IDB4MjA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IF9zZWxmOwogICAgfQoJCiAgICBmdW5jdGlvbiBrZXlFeGlzdHMoc3RyaW5nIF9zZWxmLCBzdHJpbmcgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFscyhfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogCiAgICBmdW5jdGlvbiBpbkFycmF5Tm9DYXNlKHN0cmluZyBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHNOb0Nhc2UoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgfQ==', +(2, 1, 1, 'LibString', 'Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgPj0wLjQuMjQgPDAuNi4xMDsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBieXRlc1RvU3RyaW5nKGJ5dGVzIG1lbW9yeSBfYnl0ZXMpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSl7CiAgICAgICAgYnl0ZXMgbWVtb3J5IGJ5dGVzQXJyYXkgPSBuZXcgYnl0ZXMoX2J5dGVzLmxlbmd0aCk7CiAgICAgICAgZm9yICh1aW50MjU2IGk7IGkgPCBfYnl0ZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgYnl0ZXNBcnJheVtpXSA9IF9ieXRlc1tpXTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZyhfYnl0ZXMpOwogICAgfQoKICAgIGZ1bmN0aW9uIHN0cmluZ1RvQnl0ZXMoc3RyaW5nIG1lbW9yeSBfc3RyaW5nKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGJ5dGVzIG1lbW9yeSl7CiAgICAgICAgYnl0ZXMgbWVtb3J5IF9ieXRlcyA9IGJ5dGVzKF9zdHJpbmcpOwogICAgICAgIHJldHVybiBfYnl0ZXM7CiAgICB9CiAgICAKIAogICAgZnVuY3Rpb24gYnl0ZXMzMlRvU3RyaW5nKGJ5dGVzMzIgX2J5dGVzMzIpIGludGVybmFsIHB1cmUgcmV0dXJucyhzdHJpbmcgbWVtb3J5KXsKICAgICAgICBieXRlcyBtZW1vcnkgYnl0ZXNTdHJpbmcgPSBuZXcgYnl0ZXMoMzIpOwogICAgICAgIHVpbnQgY2hhckNvdW50ID0gMCA7CiAgICAgICAgZm9yKHVpbnQgaSA9IDAgOyBpPDMyO2krKyl7CiAgICAgICAgICAgIGJ5dGUgY2hhciA9IGJ5dGUoYnl0ZXMzMih1aW50KF9ieXRlczMyKSAqMiAqKig4KmkpKSk7CiAgICAgICAgICAgIGlmKGNoYXIgIT0wKXsKICAgICAgICAgICAgICAgIGJ5dGVzU3RyaW5nW2NoYXJDb3VudF0gPSBjaGFyOwogICAgICAgICAgICAgICAgY2hhckNvdW50Kys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnl0ZXMgbWVtb3J5IGJ5dGVzU3RyaW5nVHJpbW1lZCA9IG5ldyBieXRlcyhjaGFyQ291bnQpOwogICAgICAgIGZvcih1aW50IGo9MDtqPGNoYXJDb3VudDtqKyspewogICAgICAgICAgICBieXRlc1N0cmluZ1RyaW1tZWRbal09Ynl0ZXNTdHJpbmdbal07CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmcoYnl0ZXNTdHJpbmdUcmltbWVkKTsKICAgIH0KCgogICAgZnVuY3Rpb24gc3RyaW5nVG9CeXRlczMyKHN0cmluZyBtZW1vcnkgc291cmNlKSBpbnRlcm5hbCBwdXJlIHJldHVybnMoYnl0ZXMzMiByZXN1bHQpewogICAgICAgIGFzc2VtYmx5ewogICAgICAgICAgICByZXN1bHQgOj0gbWxvYWQoYWRkKHNvdXJjZSwzMikpCiAgICAgICAgfQogICAgfQoKCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX3N0cikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVtpXSA8IGJ5dGVzKF9zdHIpW2ldKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGNvbXBhcmVOb0Nhc2Uoc3RyaW5nIG1lbW9yeSBfc2VsZiwgc3RyaW5nIG1lbW9yeSBfc3RyKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGJ5dGUgY2gxID0gYnl0ZXMoX3NlbGYpW2ldfDB4MjA7CiAgICAgICAgICAgIGJ5dGUgY2gyID0gYnl0ZXMoX3N0cilbaV18MHgyMDsKICAgICAgICAgICAgaWYgKGNoMSA+PSAnYScgJiYgY2gxIDw9J3onICYmIGNoMiA+PSAnYScgJiYgY2gyIDw9J3onKSB7CiAgICAgICAgICAgICAgICBpZiAoY2gxID4gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoMSA8IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChieXRlcyhfc2VsZilbaV0gPCBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZXF1YWxzKHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX3N0cikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9zdHIpIGludGVybmFsIHB1cmUgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggIT0gYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGJ5dGUgY2gxID0gYnl0ZXMoX3NlbGYpW2ldfDB4MjA7CiAgICAgICAgICAgIGJ5dGUgY2gyID0gYnl0ZXMoX3N0cilbaV18MHgyMDsKICAgICAgICAgICAgaWYgKGNoMSA+PSAnYScgJiYgY2gxIDw9J3onICYmIGNoMiA+PSAnYScgJiYgY2gyIDw9J3onKSB7CiAgICAgICAgICAgICAgICBpZiAoY2gxICE9IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gIT0gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIHN1YnN0cihzdHJpbmcgbWVtb3J5IF9zZWxmLCB1aW50IF9zdGFydCwgdWludCBfbGVuKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgbWVtb3J5IF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm4gX3JldDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoX2xlbik7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIrX3N0YXJ0LCBfbGVuKTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gY29uY2F0KHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9zdHIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cnB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBzdHJwdHIgOj0gYWRkKF9zdHIsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgbWVtY3B5KHJldHB0ciwgc2VsZnB0ciwgYnl0ZXMoX3NlbGYpLmxlbmd0aCk7CiAgICAgICAgbWVtY3B5KHJldHB0citieXRlcyhfc2VsZikubGVuZ3RoLCBzdHJwdHIsIGJ5dGVzKF9zdHIpLmxlbmd0aCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9zdHIxLCBzdHJpbmcgbWVtb3J5IF9zdHIyKQogICAgICAgIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9zdHIxLCBzdHJpbmcgbWVtb3J5IF9zdHIyLCBzdHJpbmcgbWVtb3J5IF9zdHIzKQogICAgICAgIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aAogICAgICAgICAgICArIGJ5dGVzKF9zdHIzKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHIxcHRyOwogICAgICAgIHVpbnQgc3RyMnB0cjsKICAgICAgICB1aW50IHN0cjNwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RyMXB0ciA6PSBhZGQoX3N0cjEsIDB4MjApCiAgICAgICAgICAgIHN0cjJwdHIgOj0gYWRkKF9zdHIyLCAweDIwKQogICAgICAgICAgICBzdHIzcHRyIDo9IGFkZChfc3RyMywgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjNwdHIsIGJ5dGVzKF9zdHIzKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMykubGVuZ3RoOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBtZW1vcnkgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIHVpbnQgaTsKICAgICAgICB1aW50OCBjaDsKICAgICAgICBmb3IgKGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShjaCA9PSAweDIwIHx8IGNoID09IDB4MDkgfHwgY2ggPT0gMHgwRCB8fCBjaCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdWludCBzdGFydCA9IGk7CiAgICAgICAgCiAgICAgICAgZm9yIChpPWJ5dGVzKF9zZWxmKS5sZW5ndGg7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIGNoID0gdWludDgoYnl0ZXMoX3NlbGYpW2ktMV0pOwogICAgICAgICAgICBpZiAoIShjaCA9PSAweDIwIHx8IGNoID09IDB4MDkgfHwgY2ggPT0gMHgwRCB8fCBjaCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdWludCBlbmQgPSBpOwogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGVuZC1zdGFydCk7CiAgICAgICAgCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgbWVtY3B5KHJldHB0ciwgc2VsZnB0citzdGFydCwgZW5kLXN0YXJ0KTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSBfcmV0KSB7CiAgICAgICAgdWludDE2IGk7CiAgICAgICAgdWludDE2IGo7CiAgICAgICAgYm9vbCBtYXRjaGVkOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBtYXRjaGVkID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAoaj0wOyBqPGJ5dGVzKF9jaGFycykubGVuZ3RoOyArK2opIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPT0gYnl0ZXMoX2NoYXJzKVtqXSkgewogICAgICAgICAgICAgICAgICAgIG1hdGNoZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghbWF0Y2hlZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdWludDE2IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9dWludDE2KGJ5dGVzKF9zZWxmKS5sZW5ndGgpOyBpPjA7IC0taSkgewogICAgICAgICAgICBtYXRjaGVkID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAoaj0wOyBqPGJ5dGVzKF9jaGFycykubGVuZ3RoOyArK2opIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaS0xXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgZW5kID0gaTsKCiAgICAgICAgaWYgKGVuZCA8PSBzdGFydCkgewoJCSAgICBfcmV0ID0gIiI7CiAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhlbmQtc3RhcnQpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIrc3RhcnQsIGVuZC1zdGFydCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIG1lbW9yeSBzcmMsIHN0cmluZyBtZW1vcnkgdmFsdWUpCiAgICAgICAgaW50ZXJuYWwKICAgICAgICBwdXJlCiAgICAgICAgcmV0dXJucyAoaW50KSB7CiAgICAgICAgcmV0dXJuIGluZGV4T2Yoc3JjLCB2YWx1ZSwgMCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nICBtZW1vcnkgc3JjLCBzdHJpbmcgbWVtb3J5IHZhbHVlLCB1aW50IG9mZnNldCkKICAgICAgICBpbnRlcm5hbAogICAgICAgIHB1cmUKICAgICAgICByZXR1cm5zIChpbnQpIHsKICAgICAgICBieXRlcyBtZW1vcnkgc3JjQnl0ZXMgPSBieXRlcyhzcmMpOwogICAgICAgIGJ5dGVzIG1lbW9yeSB2YWx1ZUJ5dGVzID0gYnl0ZXModmFsdWUpOwoKICAgICAgICBhc3NlcnQodmFsdWVCeXRlcy5sZW5ndGggPT0gMSk7CgogICAgICAgIGZvciAodWludCBpID0gb2Zmc2V0OyBpIDwgc3JjQnl0ZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgaWYgKHNyY0J5dGVzW2ldID09IHZhbHVlQnl0ZXNbMF0pIHsKICAgICAgICAgICAgICAgIHJldHVybiBpbnQoaSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgbWVtb3J5IHNyYywgc3RyaW5nIG1lbW9yeSBzZXBhcmF0b3IpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc3RyaW5nW10gbWVtb3J5IHNwbGl0QXJyKSB7CiAgICAgICAgYnl0ZXMgbWVtb3J5IHNyY0J5dGVzID0gYnl0ZXMoc3JjKTsKCiAgICAgICAgdWludCBvZmZzZXQgPSAwOwogICAgICAgIHVpbnQgc3BsaXRzQ291bnQgPSAxOwogICAgICAgIGludCBsaW1pdCA9IC0xOwogICAgICAgIHdoaWxlIChvZmZzZXQgPCBzcmNCeXRlcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICAgIGxpbWl0ID0gaW5kZXhPZihzcmMsIHNlcGFyYXRvciwgb2Zmc2V0KTsKICAgICAgICAgICAgaWYgKGxpbWl0ID09IC0xKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgc3BsaXRzQ291bnQrKzsKICAgICAgICAgICAgICAgIG9mZnNldCA9IHVpbnQobGltaXQpICsgMTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc3BsaXRBcnIgPSBuZXcgc3RyaW5nW10oc3BsaXRzQ291bnQpOwoKICAgICAgICBvZmZzZXQgPSAwOwogICAgICAgIHNwbGl0c0NvdW50ID0gMDsKICAgICAgICB3aGlsZSAob2Zmc2V0IDwgc3JjQnl0ZXMubGVuZ3RoIC0gMSkgewoKICAgICAgICAgICAgbGltaXQgPSBpbmRleE9mKHNyYywgc2VwYXJhdG9yLCBvZmZzZXQpOwogICAgICAgICAgICBpZiAobGltaXQgPT0gLSAxKSB7CiAgICAgICAgICAgICAgICBsaW1pdCA9IGludChzcmNCeXRlcy5sZW5ndGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IHRtcCA9IG5ldyBzdHJpbmcodWludChsaW1pdCkgLSBvZmZzZXQpOwogICAgICAgICAgICBieXRlcyBtZW1vcnkgdG1wQnl0ZXMgPSBieXRlcyh0bXApOwoKICAgICAgICAgICAgdWludCBqID0gMDsKICAgICAgICAgICAgZm9yICh1aW50IGkgPSBvZmZzZXQ7IGkgPCB1aW50KGxpbWl0KTsgaSsrKSB7CiAgICAgICAgICAgICAgICB0bXBCeXRlc1tqKytdID0gc3JjQnl0ZXNbaV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb2Zmc2V0ID0gdWludChsaW1pdCkgKyAxOwogICAgICAgICAgICBzcGxpdEFycltzcGxpdHNDb3VudCsrXSA9IHN0cmluZyh0bXBCeXRlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzcGxpdEFycjsKICAgIH0KICAgIAoKICAgIAogICAgZnVuY3Rpb24gdG9JbnQoc3RyaW5nIG1lbW9yeSBfc2VsZikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50OCBkaWdpdDsKICAgICAgICBmb3IgKGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA9PSAweDIwIHx8IGRpZ2l0ID09IDB4MDkgfHwgZGlnaXQgPT0gMHgwRCB8fCBkaWdpdCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIF9yZXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgbWVtb3J5IF9zZWxmKSBpbnRlcm5hbCByZXR1cm5zIChhZGRyZXNzIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50OCBkaWdpdDsKICAgICAgICBmb3IgKGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA9PSAweDIwIHx8IGRpZ2l0ID09IDB4MDkgfHwgZGlnaXQgPT0gMHgwRCB8fCBkaWdpdCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGgtaSA8IDIpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICAvL211c3Qgc3RhcnQgd2l0aCAweAogICAgICAgIGlmICghKGJ5dGVzKF9zZWxmKVtpXSA9PSAnMCcgJiYgYnl0ZXMoX3NlbGYpW2krMV18MHgyMCA9PSAneCcpKSB7CiAgICAgICAgICAgIHJldHVybiBhZGRyZXNzKDApOwogICAgICAgIH0KCiAgICAgICAgdWludCBhZGRyID0gMDsKICAgICAgICAKICAgICAgICBmb3IgKGkrPTI7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKGRpZ2l0ID49IDB4MzAgJiYgZGlnaXQgPD0gMHgzOSkgLy8nMCctJzknCiAgICAgICAgICAgICAgICBkaWdpdCAtPSAweDMwOwogICAgICAgICAgICBlbHNlIGlmIChkaWdpdHwweDIwID49IDB4NjEgJiYgZGlnaXR8MHgyMCA8PSAweDY2KSAvLydhJy0nZicKICAgICAgICAgICAgICAgIGRpZ2l0ID0gZGlnaXQtMHg2MSsxMDsKICAgICAgICAgICAgZWxzZSAKICAgICAgICAgICAgICAgIHJldHVybiBhZGRyZXNzKDApOyAKICAgICAgICAgICAgCiAgICAgICAgICAgIGFkZHIgPSBhZGRyKjE2K2RpZ2l0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gYWRkcmVzcyhhZGRyKTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9LZXlWYWx1ZShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfa2V5KS5sZW5ndGggKyA1KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBrZXlwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAga2V5cHRyIDo9IGFkZChfa2V5LCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQgcG9zID0gMDsKCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBrZXlwdHIsIGJ5dGVzKF9rZXkpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9rZXkpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJzonOwogICAgICAgIAogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc2VsZnB0ciwgYnl0ZXMoX3NlbGYpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTdHJpbmdWYWx1ZUJ5S2V5KHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSBfcmV0KSB7CgkJX3JldCA9ICIiOwogICAgICAgIGludCBwb3MgPSAtMTsKICAgICAgICB1aW50IHNlYXJjaFN0YXJ0ID0gMDsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCJcIiIuY29uY2F0KF9rZXksICJcIiIpLCBzZWFyY2hTdGFydCk7CiAgICAgICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgICAgIHBvcyA9IF9zZWxmLmluZGV4T2YoIiciLmNvbmNhdChfa2V5LCAiJyIpLCBzZWFyY2hTdGFydCk7CiAgICAgICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9yZXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHBvcyArPSBpbnQoYnl0ZXMoX2tleSkubGVuZ3RoKzIpOwoKICAgICAgICAgICAgYm9vbCBjb2xvbiA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAodWludChwb3MpIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICcgJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXHQnIAogICAgICAgICAgICAgICAgICAgIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdccicgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xuJykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnOicpIHsKICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgICAgICBjb2xvbiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZih1aW50KHBvcykgPT0gYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICAgICAgcmV0dXJuIF9yZXQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3JldDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzdGFydCArPSAxOwogICAgICAgIAogICAgICAgIGludCBlbmQ7CiAgICAgICAgaWYgKGRvdWJsZVF1b3RlcykgewogICAgICAgICAgICBlbmQgPSBfc2VsZi5pbmRleE9mKCJcIiIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbmQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChzdGFydCkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW5kID09IC0xKSB7CiAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICBfcmV0ID0gX3NlbGYuc3Vic3RyKHVpbnQoc3RhcnQpLCB1aW50KGVuZC1zdGFydCkpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRJbnRWYWx1ZUJ5S2V5KHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwb3MgKz0gaW50KGJ5dGVzKF9rZXkpLmxlbmd0aCsyKTsKCiAgICAgICAgICAgIGJvb2wgY29sb24gPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKHVpbnQocG9zKSA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnICcgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1x0JyAKICAgICAgICAgICAgICAgICAgICB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXHInIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcbicpIHsKICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJzonKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICAgICAgY29sb24gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYodWludChwb3MpID09IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29sb24pIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2VhcmNoU3RhcnQgPSB1aW50KHBvcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHVpbnQgaSA9IHVpbnQocG9zKTsKICAgICAgICB1aW50OCBkaWdpdDsKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA9PSAweDIwIHx8IGRpZ2l0ID09IDB4MDkgfHwgZGlnaXQgPT0gMHgwRCB8fCBkaWdpdCA9PSAweDBBIAogICAgICAgICAgICB8fCBkaWdpdCA9PSAweDNBIC8qOiovIHx8IGRpZ2l0ID09IDB4MjIgLyoiKi8gfHwgZGlnaXQgPT0gMHgyNyAvKicqLykpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGJvb2wgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPT0gJysnKSB7CiAgICAgICAgICAgIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0gZWxzZSBpZihieXRlcyhfc2VsZilbaV0gPT0gJy0nKSB7CiAgICAgICAgICAgIHBvc2l0aXZlID0gZmFsc2U7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9CgogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID49IDB4MzAgJiYgZGlnaXQgPD0gMHgzOSkpIHsKICAgICAgICAgICAgICAgIGlmICghcG9zaXRpdmUpIHsKICAgICAgICAgICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX3JldDsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIHRvVXBwZXJjYXNlKHN0cmluZyBtZW1vcnkgc3JjKSBpbnRlcm5hbCBwdXJlIHJldHVybnMoc3RyaW5nIG1lbW9yeSl7CiAgICAgICAgYnl0ZXMgbWVtb3J5IHNyY2IgPSBieXRlcyhzcmMpOwogICAgICAgIGZvcih1aW50IGk9MDtpPHNyY2IubGVuZ3RoO2krKyl7CiAgICAgICAgICAgIGJ5dGUgYiA9IHNyY2JbaV07CiAgICAgICAgICAgIGlmKGIgPj0gJ2EnICYmIGIgPD0gJ3onKXsKICAgICAgICAgICAgICAgIGIgJj0gYnl0ZSgweERGKTsvLyAtMzIKICAgICAgICAgICAgICAgIHNyY2JbaV0gPSBiIDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc3JjOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0xvd2VyY2FzZShzdHJpbmcgbWVtb3J5IHNyYykgaW50ZXJuYWwgcHVyZSByZXR1cm5zKHN0cmluZyBtZW1vcnkpewogICAgICAgIGJ5dGVzIG1lbW9yeSBzcmNiID0gYnl0ZXMoc3JjKTsKICAgICAgICBmb3IodWludCBpPTA7aTxzcmNiLmxlbmd0aDtpKyspewogICAgICAgICAgICBieXRlIGIgPSBzcmNiW2ldOwogICAgICAgICAgICBpZihiID49ICdBJyAmJiBiIDw9ICdaJyl7CiAgICAgICAgICAgICAgICBiIHw9IDB4MjA7CiAgICAgICAgICAgICAgICBzcmNiW2ldID0gYjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc3JjOwogICAgfQoKCQogICAgZnVuY3Rpb24ga2V5RXhpc3RzKHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIG1lbW9yeSBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHMoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KIAogICAgZnVuY3Rpb24gaW5BcnJheU5vQ2FzZShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFsc05vQ2FzZShfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICB9', 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', 'IyBTdHJpbmcgbGlicmFyeQoKU3RyaW5nIGxpYnJhcnkKClByb3ZpZGVzIGNvbW1vbiBzdHJpbmctcmVsYXRlZCBvcGVyYXRpb25zLCBpbmNsdWRpbmcgY29weWluZywgZmluZGluZywgcmVwbGFjaW5nLCBhbmQgc28gb27jgII=', now(), now()); INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (3, 1, 1, 'SafeMath', 'cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=', From 8cea2807d37f8b4072f3270c76325b8a084e60f3 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Tue, 25 May 2021 11:54:36 +0800 Subject: [PATCH 83/92] update crypto above v2.8.0 --- script/upgrade/v150_v151.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script/upgrade/v150_v151.sql b/script/upgrade/v150_v151.sql index f789607de..da0378b81 100644 --- a/script/upgrade/v150_v151.sql +++ b/script/upgrade/v150_v151.sql @@ -115,10 +115,10 @@ INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `con -- smart dev contracts -- tools basic INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(13, 1, 4, 'Crypto', 'Y29udHJhY3QgQ3J5cHRvCnsKICAgIGZ1bmN0aW9uIHNtMyhieXRlcyBtZW1vcnkgZGF0YSkgcHVibGljIHZpZXcgcmV0dXJucyhieXRlczMyKXt9CiAgICBmdW5jdGlvbiBrZWNjYWsyNTZIYXNoKGJ5dGVzIG1lbW9yeSBkYXRhKSBwdWJsaWMgdmlldyByZXR1cm5zKGJ5dGVzMzIpe30KICAgIGZ1bmN0aW9uIHNtMlZlcmlmeShieXRlczMyICBtZXNzYWdlLCBieXRlcyBtZW1vcnkgcHVibGljS2V5LCBieXRlczMyIHIsIGJ5dGVzMzIgcykgcHVibGljIHZpZXcgcmV0dXJucyhib29sLCBhZGRyZXNzKXt9CiAgICBmdW5jdGlvbiBjdXJ2ZTI1NTE5VlJGVmVyaWZ5KHN0cmluZyBtZW1vcnkgaW5wdXQsIHN0cmluZyBtZW1vcnkgdnJmUHVibGljS2V5LCBzdHJpbmcgbWVtb3J5IHZyZlByb29mKSBwdWJsaWMgdmlldyByZXR1cm5zKGJvb2wsdWludDI1Nil7fQp9', +(13, 1, 4, 'Crypto', 'LyoqCiAqIG9ubHkgc3VwcG9ydGVkIGluIEZJU0NPLUJDT1MgdjIuOC4wKyAKICovCmNvbnRyYWN0IENyeXB0bwp7CiAgICBmdW5jdGlvbiBzbTMoYnl0ZXMgbWVtb3J5IGRhdGEpIHB1YmxpYyB2aWV3IHJldHVybnMoYnl0ZXMzMil7fQogICAgZnVuY3Rpb24ga2VjY2FrMjU2SGFzaChieXRlcyBtZW1vcnkgZGF0YSkgcHVibGljIHZpZXcgcmV0dXJucyhieXRlczMyKXt9CiAgICBmdW5jdGlvbiBzbTJWZXJpZnkoYnl0ZXMzMiAgbWVzc2FnZSwgYnl0ZXMgbWVtb3J5IHB1YmxpY0tleSwgYnl0ZXMzMiByLCBieXRlczMyIHMpIHB1YmxpYyB2aWV3IHJldHVybnMoYm9vbCwgYWRkcmVzcyl7fQogICAgZnVuY3Rpb24gY3VydmUyNTUxOVZSRlZlcmlmeShzdHJpbmcgbWVtb3J5IGlucHV0LCBzdHJpbmcgbWVtb3J5IHZyZlB1YmxpY0tleSwgc3RyaW5nIG1lbW9yeSB2cmZQcm9vZikgcHVibGljIHZpZXcgcmV0dXJucyhib29sLHVpbnQyNTYpe30KfQ==', 'IyBDcnlwdG8KCkNyeXB0byBJbnRlcmZhY2UgQ29udHJhY3Q=', 'IyBDcnlwdG8KCkNyeXB0byBJbnRlcmZhY2UgQ29udHJhY3Q=', now(), now()); INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES -(14, 1, 4, 'ShaTest', 'cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CgpwcmFnbWEgZXhwZXJpbWVudGFsIEFCSUVuY29kZXJWMjsKCmltcG9ydCAiLi9DcnlwdG8uc29sIjsKCmNvbnRyYWN0IFNoYVRlc3R7CiAgICBieXRlcyBfZGF0YSA9ICJIZWxsbywgU2hhVGVzdCI7CiAgICBDcnlwdG8gY3J5cHRvOwoKICAgIGNvbnN0cnVjdG9yKCkgcHVibGljIHsKICAgICAgICBjcnlwdG8gPSBDcnlwdG8oMHg1MDA2KTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRTaGEyNTYoYnl0ZXMgbWVtb3J5IF9tZW1vcnkpIHB1YmxpYyByZXR1cm5zKGJ5dGVzMzIgcmVzdWx0KQogICAgewogICAgICAgIHJldHVybiBzaGEyNTYoX21lbW9yeSk7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0S2VjY2FrMjU2KGJ5dGVzIG1lbW9yeSBfbWVtb3J5KSBwdWJsaWMgcmV0dXJucyhieXRlczMyIHJlc3VsdCkKICAgIHsKICAgICAgICByZXR1cm4ga2VjY2FrMjU2KF9tZW1vcnkpOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldERhdGEoKSBwdWJsaWMgdmlldyByZXR1cm5zKGJ5dGVzIG1lbW9yeSkKICAgIHsKICAgICAgICByZXR1cm4gX2RhdGE7CiAgICB9Cn0K', +(14, 1, 4, 'ShaTest', 'cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CgpwcmFnbWEgZXhwZXJpbWVudGFsIEFCSUVuY29kZXJWMjsKCmltcG9ydCAiLi9DcnlwdG8uc29sIjsKCi8qKgogKiBvbmx5IHN1cHBvcnRlZCBpbiBGSVNDTy1CQ09TIHYyLjguMCsgCiAqLwpjb250cmFjdCBTaGFUZXN0ewogICAgYnl0ZXMgX2RhdGEgPSAiSGVsbG8sIFNoYVRlc3QiOwogICAgQ3J5cHRvIGNyeXB0bzsKCiAgICBjb25zdHJ1Y3RvcigpIHB1YmxpYyB7CiAgICAgICAgY3J5cHRvID0gQ3J5cHRvKDB4NTAwNik7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2hhMjU2KGJ5dGVzIG1lbW9yeSBfbWVtb3J5KSBwdWJsaWMgcmV0dXJucyhieXRlczMyIHJlc3VsdCkKICAgIHsKICAgICAgICByZXR1cm4gc2hhMjU2KF9tZW1vcnkpOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldEtlY2NhazI1NihieXRlcyBtZW1vcnkgX21lbW9yeSkgcHVibGljIHJldHVybnMoYnl0ZXMzMiByZXN1bHQpCiAgICB7CiAgICAgICAgcmV0dXJuIGtlY2NhazI1NihfbWVtb3J5KTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXREYXRhKCkgcHVibGljIHZpZXcgcmV0dXJucyhieXRlcyBtZW1vcnkpCiAgICB7CiAgICAgICAgcmV0dXJuIF9kYXRhOwogICAgfQp9Cg==', 'IyBTaGFUZXN0CgpDcnlwdG8gSW50ZXJmYWNlIENvbnRyYWN0CgpDcnlwdG8gVGVzdCBDb250cmFjdCBbQ3J5cHRvIEFQSV0oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9kZWZhdWx0L0NyeXB0by5odG1sKQo=', 'IyBTaGFUZXN0CgpDcnlwdG8gSW50ZXJmYWNlIENvbnRyYWN0CgpDcnlwdG8gVGVzdCBDb250cmFjdCBbQ3J5cHRvIEFQSV0oaHR0cHM6Ly90b29sa2l0LWRvYy5yZWFkdGhlZG9jcy5pby96aF9DTi9sYXRlc3QvZG9jcy9XZUJhbmtCbG9ja2NoYWluLVNtYXJ0RGV2LUNvbnRyYWN0L2FwaS9kZWZhdWx0L0NyeXB0by5odG1sKQo=', now(), now()); INSERT INTO `tb_contract_item` (`id`, `warehouse_id`, `contract_folder_id`, `contract_name`, `contract_source`, `description`, `description_en`, `create_time`, `modify_time`) VALUES (15, 1, 4, 'HelloWorld', 'cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7Cgpjb250cmFjdCBIZWxsb1dvcmxkIHsKICAgIHN0cmluZyBuYW1lOwoKICAgIGNvbnN0cnVjdG9yKCkgcHVibGljIHsKICAgICAgICBuYW1lID0gIkhlbGxvLCBXb3JsZCEiOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gbmFtZTsKICAgIH0KCiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nIG1lbW9yeSBuKSBwdWJsaWMgewogICAgICAgIG5hbWUgPSBuOwogICAgfQp9', From 1cf2c60616502f363b78d7781f662e4cab803814 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Wed, 26 May 2021 16:10:20 +0800 Subject: [PATCH 84/92] fix sdk zip download --- .../webase/node/mgr/cert/CertService.java | 232 ++++-------------- 1 file changed, 47 insertions(+), 185 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/cert/CertService.java b/src/main/java/com/webank/webase/node/mgr/cert/CertService.java index ad48bd49d..3fe4a7a31 100644 --- a/src/main/java/com/webank/webase/node/mgr/cert/CertService.java +++ b/src/main/java/com/webank/webase/node/mgr/cert/CertService.java @@ -479,25 +479,19 @@ public Map getFrontSdkContent(int frontId) { * @return */ public synchronized FileContentHandle getFrontSdkZipFile(int frontId) { + File tempZipFile = new File(TEMP_ZIP_FILE_PATH); + if (tempZipFile.exists()) { + boolean result = NodeMgrTools.deleteDir(tempZipFile); + log.info("getFrontSdkZipFile delete old zip file[{}] before create new, result:{}", tempZipFile, result); + } // get sdk cert content Map sdkContentMap = this.getFrontSdkContent(frontId); if (sdkContentMap.isEmpty()) { throw new NodeMgrException(ConstantCode.SDK_CRT_KEY_FILE_NOT_FOUND); } - // get if guomi sdk - String key = sdkContentMap.keySet().iterator().next(); - boolean useGm = key.contains("gm"); - - // if guomi, create conf/gm, else create conf/ - File sdkDir; - if (useGm) { - sdkDir = new File(TEMP_SDK_DIR + File.separator + "gm"); - } else { - sdkDir = new File(TEMP_SDK_DIR); - } - log.info("writeSdkAsFile sdkDir:{}", sdkDir); + // create dir and zip - writeSdkFilesAndZip(sdkContentMap, sdkDir, useGm); + writeSdkFilesAndZip(sdkContentMap); try { // FileInputStream would be closed by web return new FileContentHandle(TEMP_ZIP_FILE_NAME, new FileInputStream(TEMP_ZIP_FILE_PATH)); @@ -507,44 +501,65 @@ public synchronized FileContentHandle getFrontSdkZipFile(int frontId) { } } - private void writeSdkFilesAndZip(Map sdkContentMap, File sdkDir, boolean useGm) { - this.writeSdkAsFile(sdkContentMap, sdkDir); - // zip the directory of conf(guomi: conf/gm) - String gmDirInZip = useGm ? "gm" : ""; + + private void writeSdkFilesAndZip(Map sdkContentMap) { + this.writeSdkAsFile(sdkContentMap); + // zip the directory of sdk of TEMP_SDK_DIR + //sdk + //├── ca.crt + //├── gm + //│   ├── gmca.crt + //│   ├── gmensdk.crt + //│   ├── gmensdk.key + //│   ├── gmsdk.crt + //│   └── gmsdk.key + //├── sdk.crt + //└── sdk.key try { - ZipUtils.generateZipFile(sdkDir.getPath(), TEMP_ZIP_DIR, gmDirInZip, TEMP_ZIP_FILE_NAME); + ZipUtils.generateZipFile(TEMP_SDK_DIR, TEMP_ZIP_DIR, "", TEMP_ZIP_FILE_NAME); } catch (Exception e) { log.error("writeSdkAsFile generateZipFile fail:[]", e); throw new NodeMgrException(ConstantCode.WRITE_SDK_CRT_KEY_FILE_FAIL); } - // rm conf dir - boolean resultDel = sdkDir.delete(); - log.info("delete for temp sdk file, result:{}", resultDel); + // after zip, delete sdk dir + File sdkDir = new File(TEMP_SDK_DIR); + boolean resultDel = NodeMgrTools.deleteDir(sdkDir); + log.info("delete for temp sdk dir[{}], result:{}", sdkDir, resultDel); } /** * write sdk file of ca.crt, sdk.crt, sdk.key * @param sdkContentMap - * @param sdkDir sdk file output directory * @return */ - public void writeSdkAsFile(Map sdkContentMap, File sdkDir) { + public void writeSdkAsFile(Map sdkContentMap) { - // create sdk dir + // write each content to each file in sdk/ or sdk/gm/ + // gm: gmca.crt, gmsdk.crt, gmsdk.key + // else: ca.crt, sdk.crt, sdk.key + File sdkDir = new File(TEMP_SDK_DIR); + File gmSdkDir = new File(TEMP_SDK_DIR + File.separator + "gm"); if (sdkDir.exists()) { - boolean result = sdkDir.delete(); - log.info("delete existed gm dir, result:{}", result); + boolean result = NodeMgrTools.deleteDir(sdkDir); + log.info("writeSdkAsFile delete sdk dir[{}], result:{}", sdkDir, result); } - boolean result = sdkDir.mkdirs(); - log.info("mkdir for temp sdk file, result:{}", result); + boolean sdkDirRes = sdkDir.mkdirs(); + log.info("writeSdkAsFile re-create sdk dir result:{}", sdkDirRes); - // write each content to each file in conf/ or conf/gm/ - // gm: gmca.crt, gmsdk.crt, gmsdk.key - // else: ca.crt, sdk.crt, sdk.key for (String fileName : sdkContentMap.keySet()) { + // if sdk.key, save in sdk/sdk.key Path sdkFilePath = Paths - .get(CleanPathUtil.cleanString(sdkDir.getPath() + File.separator + fileName)); + .get(CleanPathUtil.cleanString(TEMP_SDK_DIR + File.separator + fileName)); + // if gmsdk.key, save in sdk/gm/gmsdk.key + if (fileName.contains("gm")) { + sdkFilePath = Paths.get(CleanPathUtil.cleanString(TEMP_SDK_DIR + File.separator + + "gm" + File.separator + fileName)); + if (!gmSdkDir.exists()) { + boolean gmSdkDirRes = gmSdkDir.mkdirs(); + log.info("writeSdkAsFile create gmSdkDir[{}] result:{}", sdkFilePath, gmSdkDirRes); + } + } String fileContent = sdkContentMap.get(fileName); log.info("writeSdkAsFile sdkPath:{}, content:{}", sdkFilePath, fileContent); try (BufferedWriter writer = Files @@ -558,157 +573,4 @@ public void writeSdkAsFile(Map sdkContentMap, File sdkDir) { } } -// -// public synchronized FileContentHandle getFrontSdkFiles(int frontId) { -// Map sdkContentMap = this.getFrontSdkContent(frontId); -// if (sdkContentMap.isEmpty()) { -// throw new NodeMgrException(ConstantCode.SDK_CRT_KEY_FILE_NOT_FOUND); -// } -// // get if guomi sdk -// String key = sdkContentMap.keySet().iterator().next(); -// boolean useGm = key.contains("gm"); -// // create dir and zip -// writeSdkAsFile(sdkContentMap, useGm); -// try { -// return new FileContentHandle(TEMP_ZIP_FILE_NAME, new FileInputStream(TEMP_ZIP_FILE_PATH)); -// } catch (IOException e) { -// log.error("getFrontSdkFiles fail:[]", e); -// throw new NodeMgrException(ConstantCode.WRITE_SDK_CRT_KEY_FILE_FAIL); -// } -// } -// -// private void writeSdkAsFile(Map sdkContentMap, boolean useGm) { -// // if guomi, create conf/gm, else create conf/ -// File sdkDir; -// if (useGm) { -// sdkDir = new File(TEMP_SDK_DIR + File.separator + "gm"); -// } else { -// sdkDir = new File(TEMP_SDK_DIR); -// } -// log.info("writeSdkAsFile sdkDir:{}", sdkDir); -// -// // create sdk dir -// if (sdkDir.exists()) { -// boolean result = sdkDir.delete(); -// log.info("delete existed gm dir, result:{}", result); -// } -// boolean result = sdkDir.mkdirs(); -// log.info("mkdir for temp sdk file, result:{}", result); -// -// // write each content to each file in conf/ or conf/gm/ -// // gm: gmca.crt, gmsdk.crt, gmsdk.key -// // else: ca.crt, sdk.crt, sdk.key -// for (String fileName : sdkContentMap.keySet()) { -// Path sdkFilePath = Paths.get(sdkDir.getPath() + File.separator + CleanPathUtil.cleanString(fileName)); -// String fileContent = sdkContentMap.get(fileName); -// log.info("writeSdkAsFile sdkPath:{}, content:{}", sdkFilePath, fileContent); -// try (BufferedWriter writer = Files.newBufferedWriter(sdkFilePath, StandardCharsets.UTF_8)) { -// // write to relative path -// writer.write(fileContent); -// } catch (IOException e) { -// log.error("writeSdkAsFile fail:[]", e); -// throw new NodeMgrException(ConstantCode.WRITE_SDK_CRT_KEY_FILE_FAIL); -// } -// } -// // zip the directory of conf(guomi: conf/gm) -// try { -// generateZipFile(sdkDir.getPath(), TEMP_ZIP_DIR, useGm); -// } catch (Exception e) { -// log.error("writeSdkAsFile generateZipFile fail:[]", e); -// throw new NodeMgrException(ConstantCode.WRITE_SDK_CRT_KEY_FILE_FAIL); -// } -// -// // rm conf dir -// boolean resultDel = sdkDir.delete(); -// log.info("delete for temp sdk file, result:{}", resultDel); -// } -// -// /** -// * @param path 要压缩的文件路径 -// * @param outputDir zip包的生成目录,默认为tempZip -// * @param useGm if use gm, there is gm dir in zip -// */ -// public static void generateZipFile(String path, String outputDir, boolean useGm) throws Exception { -// -// File file2Zip = new File(CleanPathUtil.cleanString(path)); -// // 压缩文件的路径不存在 -// if (!file2Zip.exists()) { -// log.error("file not exist:{}", path); -// throw new Exception("file not exist: " + path); -// } -// // 用于存放压缩文件的文件夹 -// File compress = new File(outputDir); -// // 如果文件夹不存在,进行创建 -// if (!compress.exists() ){ -// compress.mkdirs(); -// } -// // 目的压缩文件,已存在则先删除 -// // tempZip/conf.zip -// String generateFileName = compress.getAbsolutePath() + File.separator + CleanPathUtil.cleanString(TEMP_ZIP_FILE_NAME); -// File confZip = new File(generateFileName); -// if (confZip.exists() ) { -// log.info("confZip exist, now delete:{}", confZip); -// confZip.delete(); -// } -// // 输出流 -// FileOutputStream outputStream = new FileOutputStream(CleanPathUtil.cleanString(generateFileName)); -// // 压缩输出流 -// ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(outputStream)); -// // 传入输出流,传入需要压缩的file路径 -// String gmDir = useGm ? "gm" : ""; -// generateFile(zipOutputStream, file2Zip, gmDir); -// -// log.info("file2Zip:{} and outputFile:{}" ,file2Zip.getAbsolutePath(), generateFileName); -// // 关闭 输出流 -// zipOutputStream.close(); -// outputStream.close(); -// } -// -// -// /** -// * @param out 输出流 -// * @param file 目标文件 -// * @param dir 在压缩包中的文件夹 -// * @throws Exception -// */ -// private static void generateFile(ZipOutputStream out, File file, String dir) throws Exception { -// -// // 当前的是文件夹,则进行一步处理 -// if (file.isDirectory()) { -// //得到文件列表信息 -// File[] files = file.listFiles(); -// -// //将文件夹添加到下一级打包目录 -// out.putNextEntry(new ZipEntry(dir + "/")); -// -// dir = dir.length() == 0 ? "" : dir + "/"; -// -// //循环将文件夹中的文件打包 -// for (int i = 0; i < files.length; i++) { -// generateFile(out, files[i], dir + files[i].getName()); -// } -// -// } else { // 当前是文件 -// FileInputStream inputStream = null; -// try { -// inputStream = new FileInputStream(file); -// // 标记要打包的条目 -// out.putNextEntry(new ZipEntry(dir)); -// // 进行写操作 -// int len = 0; -// byte[] bytes = new byte[1024]; -// while ((len = inputStream.read(bytes)) > 0) { -// out.write(bytes, 0, len); -// } -// } catch (IOException e) { -// log.error("base64ToFile IOException:[{}]", e.toString()); -// } finally { -// if (inputStream != null) { -// inputStream.close(); -// } -// } -// } -// -// } - } From 82d241aaab2383eb94dbc599aa44648960260491 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Wed, 26 May 2021 16:11:08 +0800 Subject: [PATCH 85/92] update comment --- .../java/com/webank/webase/node/mgr/chain/ChainService.java | 5 +++-- .../com/webank/webase/node/mgr/deploy/entity/ReqAddNode.java | 1 + .../webank/webase/node/mgr/deploy/entity/ReqConfigChain.java | 2 -- .../webank/webase/node/mgr/deploy/service/AgencyService.java | 2 +- .../webank/webase/node/mgr/deploy/service/DeployService.java | 2 -- .../webase/node/mgr/deploy/service/DockerCommandService.java | 1 - 6 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/chain/ChainService.java b/src/main/java/com/webank/webase/node/mgr/chain/ChainService.java index 7c2658688..19d464ab8 100644 --- a/src/main/java/com/webank/webase/node/mgr/chain/ChainService.java +++ b/src/main/java/com/webank/webase/node/mgr/chain/ChainService.java @@ -331,7 +331,8 @@ public boolean generateConfigLocalAndInitDb(String chainName, List deployNodeIn // insert front group mapping this.frontGroupMapService.newFrontGroup(front.getFrontId(), groupId, GroupStatus.MAINTAINING); - // update node count of goup + // update node count of group TbGroup group = this.groupService.getGroupById(groupId); this.groupService.updateGroupNodeCount(groupId, group.getNodeCount() + 1 ); diff --git a/src/main/java/com/webank/webase/node/mgr/deploy/entity/ReqAddNode.java b/src/main/java/com/webank/webase/node/mgr/deploy/entity/ReqAddNode.java index 2ae3eaa78..5f06f657c 100644 --- a/src/main/java/com/webank/webase/node/mgr/deploy/entity/ReqAddNode.java +++ b/src/main/java/com/webank/webase/node/mgr/deploy/entity/ReqAddNode.java @@ -44,6 +44,7 @@ public class ReqAddNode { /** * 0, 1 */ + @Deprecated private int encryptType; } diff --git a/src/main/java/com/webank/webase/node/mgr/deploy/entity/ReqConfigChain.java b/src/main/java/com/webank/webase/node/mgr/deploy/entity/ReqConfigChain.java index 4583aac0a..4606a2490 100644 --- a/src/main/java/com/webank/webase/node/mgr/deploy/entity/ReqConfigChain.java +++ b/src/main/java/com/webank/webase/node/mgr/deploy/entity/ReqConfigChain.java @@ -32,8 +32,6 @@ public class ReqConfigChain { @NotNull private String[] ipconf; -// @Positive -// private int tagId; /** * ex: v2.7.0, v2.7.1 etc. */ diff --git a/src/main/java/com/webank/webase/node/mgr/deploy/service/AgencyService.java b/src/main/java/com/webank/webase/node/mgr/deploy/service/AgencyService.java index 3f30da6c8..6a36e8d01 100644 --- a/src/main/java/com/webank/webase/node/mgr/deploy/service/AgencyService.java +++ b/src/main/java/com/webank/webase/node/mgr/deploy/service/AgencyService.java @@ -95,7 +95,7 @@ public TbAgency initAgencyIfNew( return agency; } - if(! ValidateUtil.validateAgencyName(agencyName)){ + if(!ValidateUtil.validateAgencyName(agencyName)){ throw new NodeMgrException(AGENCY_NAME_CONFIG_ERROR); } diff --git a/src/main/java/com/webank/webase/node/mgr/deploy/service/DeployService.java b/src/main/java/com/webank/webase/node/mgr/deploy/service/DeployService.java index 0608fd452..f64f17542 100644 --- a/src/main/java/com/webank/webase/node/mgr/deploy/service/DeployService.java +++ b/src/main/java/com/webank/webase/node/mgr/deploy/service/DeployService.java @@ -503,8 +503,6 @@ public Pair batchAddNode(ReqAddNode addNode) throw new NodeMgrException(ConstantCode.CHAIN_NAME_NOT_EXISTS_ERROR); } - - log.info("batchAddNode chainName:{},deployNodeInfoList:{},tagId:{},encrtypType:{}," + "webaseSignAddr:{},agencyName:{}", chainName, deployNodeInfoList, chain.getVersion(), chain.getEncryptType(), chain.getWebaseSignAddr(), agencyName); diff --git a/src/main/java/com/webank/webase/node/mgr/deploy/service/DockerCommandService.java b/src/main/java/com/webank/webase/node/mgr/deploy/service/DockerCommandService.java index a538b7858..665d5006f 100644 --- a/src/main/java/com/webank/webase/node/mgr/deploy/service/DockerCommandService.java +++ b/src/main/java/com/webank/webase/node/mgr/deploy/service/DockerCommandService.java @@ -100,7 +100,6 @@ public void pullImage(String ip, String imageTag, int imagePullType, String down log.info("pullImage from docker hub"); String dockerPullCommand = String.format("docker pull %s", imageFullName); // kill exists docker pull process -// SshTools.killCommand(ip, dockerPullCommand, sshUser, sshPort, constant.getPrivateKey()); ExecuteResult result = ansibleService.execDocker(ip, dockerPullCommand); if (result.failed()) { throw new NodeMgrException(ConstantCode.ANSIBLE_PULL_DOCKER_HUB_ERROR.attach(result.getExecuteOut())); From 6a83d1265890b84e94e36ed17eb71a0b453670d1 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 27 May 2021 11:20:19 +0800 Subject: [PATCH 86/92] update cns name --- .../java/com/webank/webase/node/mgr/contract/CnsService.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/contract/CnsService.java b/src/main/java/com/webank/webase/node/mgr/contract/CnsService.java index 271894c33..01ec58d62 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/CnsService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/CnsService.java @@ -58,7 +58,7 @@ public void registerCns(ReqRegisterCns inputParam) throws NodeMgrException { log.error("fail registerCns. abi is empty"); throw new NodeMgrException(ConstantCode.CONTRACT_ABI_EMPTY); } - // check version + // check version locally QueryCnsParam queryParam = new QueryCnsParam(inputParam.getGroupId(), inputParam.getCnsName(), inputParam.getVersion()); int count = countOfCns(queryParam); @@ -74,7 +74,8 @@ public void registerCns(ReqRegisterCns inputParam) throws NodeMgrException { params.put("groupId", groupId); params.put("signUserId", signUserId); params.put("contractName", contractName); - params.put("cnsName", contractName); + // depend on cnsName + params.put("cnsName", inputParam.getCnsName()); params.put("version", inputParam.getVersion()); params.put("contractAddress", inputParam.getContractAddress()); params.put("abiInfo", abiArray); From dcb121f3ef2cb84f5dd508acb503e6ed88ea9443 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 27 May 2021 15:10:42 +0800 Subject: [PATCH 87/92] add valid of ip --- .../node/mgr/deploy/controller/HostController.java | 10 +++++++--- .../webase/node/mgr/deploy/service/HostService.java | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/deploy/controller/HostController.java b/src/main/java/com/webank/webase/node/mgr/deploy/controller/HostController.java index 8e296d98a..b92396dc6 100644 --- a/src/main/java/com/webank/webase/node/mgr/deploy/controller/HostController.java +++ b/src/main/java/com/webank/webase/node/mgr/deploy/controller/HostController.java @@ -81,9 +81,8 @@ public BaseResponse addHost(@RequestBody @Valid ReqAddHost reqAddHost, BindingRe checkBindResult(result); if(!ValidateUtil.ipv4Valid(reqAddHost.getSshIp())) { - throw new ParamException( - ConstantCode.IP_FORMAT_ERROR.getCode(), ConstantCode.IP_FORMAT_ERROR.getMessage() - ); + log.error("not valid ip!:{}", reqAddHost.getSshIp()); + throw new NodeMgrException(ConstantCode.IP_FORMAT_ERROR); } Instant startTime = Instant.now(); @@ -121,6 +120,11 @@ public BaseResponse deleteHostWithout(@PathVariable("hostId") Integer hostId) th @PreAuthorize(ConstantProperties.HAS_ROLE_ADMIN) public BaseResponse pingHost(@RequestBody @Valid ReqAddHost reqAddHost, BindingResult result) throws NodeMgrException { checkBindResult(result); + + if(!ValidateUtil.ipv4Valid(reqAddHost.getSshIp())) { + log.error("not valid ip!:{}", reqAddHost.getSshIp()); + throw new NodeMgrException(ConstantCode.IP_FORMAT_ERROR); + } Instant startTime = Instant.now(); log.info("Start ping:[{}], start:[{}]", JsonTools.toJSONString(reqAddHost), startTime); try { diff --git a/src/main/java/com/webank/webase/node/mgr/deploy/service/HostService.java b/src/main/java/com/webank/webase/node/mgr/deploy/service/HostService.java index 7e8510797..8e044d846 100644 --- a/src/main/java/com/webank/webase/node/mgr/deploy/service/HostService.java +++ b/src/main/java/com/webank/webase/node/mgr/deploy/service/HostService.java @@ -19,6 +19,7 @@ import com.webank.webase.node.mgr.base.enums.HostStatusEnum; import com.webank.webase.node.mgr.base.enums.ScpTypeEnum; import com.webank.webase.node.mgr.base.exception.NodeMgrException; +import com.webank.webase.node.mgr.base.exception.ParamException; import com.webank.webase.node.mgr.base.properties.ConstantProperties; import com.webank.webase.node.mgr.base.tools.IPUtil; import com.webank.webase.node.mgr.base.tools.NumberUtil; @@ -109,7 +110,6 @@ public TbHost checkDirAndInsert(String ip, String rootDir, HostStatusEnum hostSt ansibleService.execPing(ip); // check 127.0.0.1 this.validateAllLocalhostOrNot(ip); - log.info("check host root dir accessible:{}", rootDir); ExecuteResult execResult = ansibleService.execCreateDir(ip, rootDir); if (execResult.failed()) { From 0870e10e114217759d57df6478682829c8697c21 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Thu, 27 May 2021 17:37:19 +0800 Subject: [PATCH 88/92] update error log --- .../node/mgr/base/exception/ExceptionsHandler.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/webank/webase/node/mgr/base/exception/ExceptionsHandler.java b/src/main/java/com/webank/webase/node/mgr/base/exception/ExceptionsHandler.java index a75137c3d..dd60f13d7 100644 --- a/src/main/java/com/webank/webase/node/mgr/base/exception/ExceptionsHandler.java +++ b/src/main/java/com/webank/webase/node/mgr/base/exception/ExceptionsHandler.java @@ -41,7 +41,7 @@ public class ExceptionsHandler { @ExceptionHandler(value = NodeMgrException.class) @ResponseStatus(value = HttpStatus.BAD_REQUEST) public BaseResponse myExceptionHandler(NodeMgrException nodeMgrException) { - log.warn("catch business exception", nodeMgrException); + log.error("catch business exception:[]", nodeMgrException); RetCode retCode = Optional.ofNullable(nodeMgrException).map(NodeMgrException::getRetCode) .orElse(ConstantCode.SYSTEM_EXCEPTION); @@ -57,7 +57,7 @@ public BaseResponse myExceptionHandler(NodeMgrException nodeMgrException) { @ExceptionHandler(value = ParamException.class) @ResponseStatus(value = HttpStatus.BAD_REQUEST) public BaseResponse paramExceptionHandler(ParamException paramException) { - log.warn("catch param exception", paramException); + log.error("catch param exception:[]", paramException); RetCode retCode = Optional.ofNullable(paramException).map(ParamException::getRetCode) .orElse(ConstantCode.SYSTEM_EXCEPTION); @@ -73,7 +73,7 @@ public BaseResponse paramExceptionHandler(ParamException paramException) { @ExceptionHandler(value = TypeMismatchException.class) @ResponseStatus(value = HttpStatus.BAD_REQUEST) public BaseResponse typeMismatchExceptionHandler(TypeMismatchException ex) { - log.warn("catch typeMismatchException", ex); + log.error("catch typeMismatchException:[]", ex); RetCode retCode = new RetCode(ConstantCode.PARAM_EXCEPTION.getCode(), ex.getMessage()); BaseResponse bre = new BaseResponse(retCode); @@ -90,7 +90,7 @@ public BaseResponse typeMismatchExceptionHandler(TypeMismatchException ex) { @ResponseStatus(value = HttpStatus.UNAUTHORIZED) public BaseResponse accessDeniedExceptionHandler(AccessDeniedException exception) throws Exception { - log.warn("catch accessDenied exception", exception); + log.error("catch accessDenied exception:[]", exception); BaseResponse bre = new BaseResponse(ConstantCode.ACCESS_DENIED); log.warn("accessDenied exception return:{}", JsonTools.toJSONString(bre)); return bre; @@ -103,7 +103,7 @@ public BaseResponse accessDeniedExceptionHandler(AccessDeniedException exception @ExceptionHandler(value = RuntimeException.class) @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) public BaseResponse exceptionHandler(RuntimeException exc) { - log.warn("catch RuntimeException", exc); + log.error("catch RuntimeException:[]", exc); // 默认系统异常 RetCode retCode = ConstantCode.SYSTEM_EXCEPTION; // v1.3.1 增加异常细节 From aecc9b7d502a882a533f4d364ddbab3319ad36e6 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 28 May 2021 11:28:34 +0800 Subject: [PATCH 89/92] update solc scaffold 1.0.0 --- build.gradle | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 7c7d3913c..9468620d4 100644 --- a/build.gradle +++ b/build.gradle @@ -15,12 +15,10 @@ targetCompatibility = 1.8 // In this section you declare where to find the dependencies of your project repositories { maven {url "http://maven.aliyun.com/nexus/content/groups/public/"} - - maven { url 'https://dl.bintray.com/ethereum/maven/' } + mavenCentral() maven { url "https://oss.sonatype.org/content/repositories/snapshots" } - + maven { url 'https://dl.bintray.com/ethereum/maven/' } mavenLocal() - mavenCentral() } def springboot_version="2.1.15.RELEASE" @@ -79,7 +77,7 @@ List mbg = [ ] List scaffold = [ - 'com.webank.webase:solscaffold:1.0.0-SNAPSHOT', + 'com.webank.webase:solscaffold:1.0.0', 'com.webank:SmartDev-Scaffold:1.0.0-SNAPSHOT', 'com.webank:solc-gradle-plugin:1.0.1-SNAPSHOT' ] From f1716096f51cc76eb0e8686133496d51bddff5ab Mon Sep 17 00:00:00 2001 From: marsli Date: Fri, 28 May 2021 14:34:13 +0800 Subject: [PATCH 90/92] v1.5.1 --- Changelog.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Changelog.md b/Changelog.md index e30000982..f4cc11b53 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,4 +1,24 @@ +### v1.5.1(2021-05-28) + +**Add** +- 支持导出合约的Java工程脚手架 +- 新增合约仓库接口 +- 新增全量用户/合约通过地址搜索功能 + +**Fix** +- 优化开发者模式下鉴权,修复开发者模式下删除合约目录问题 +- 优化应用管理中合约同步速度过慢问题 +- 修复交易审计中异常数据总数错误问题 +- 修复导出SDK证书目录问题 + +**兼容性** +- 支持FISCO-BCOS v2.4.x 及以上版本 +- WeBASE-Web v1.5.1+ +- WeBASE-Front v1.5.1+ +- WeBASE-Sign v1.5.0+ +详细了解,请阅读[**技术文档**](https://webasedoc.readthedocs.io/zh_CN/latest/)。 + ### v1.5.0(2021-04-06) **Add** From 16bb40d2f6d8ef706b76badf21a0530e41674ac7 Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 28 May 2021 17:18:52 +0800 Subject: [PATCH 91/92] use sdk 2.7.2 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9468620d4..0ca1777cb 100644 --- a/build.gradle +++ b/build.gradle @@ -84,7 +84,7 @@ List scaffold = [ dependencies { compile springboot,spring,jaxb,jackson,log4j,scaffold - compile "org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.8.0-SNAPSHOT" + compile "org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.7.2" compile "org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.0" compile "org.apache.commons:commons-lang3:3.8.1" compile "mysql:mysql-connector-java:8.0.22" From 577c9eebbb951cbda0996427cd10c9db72a9eccf Mon Sep 17 00:00:00 2001 From: CodingCattwo <847701726@qq.com> Date: Fri, 28 May 2021 17:31:59 +0800 Subject: [PATCH 92/92] fix fallback --- .../com/webank/webase/node/mgr/contract/ContractService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java index 66ebcffa9..b7104c35c 100644 --- a/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java +++ b/src/main/java/com/webank/webase/node/mgr/contract/ContractService.java @@ -368,7 +368,8 @@ public TbContract deployContract(DeployInputParam inputParam) throws NodeMgrExce verifyContractNameNotExist(inputParam.getGroupId(), inputParam.getContractPath(), inputParam.getContractName(), inputParam.getAccount(), inputParam.getContractId()); - List abiArray = JsonTools.toJavaObjectList(inputParam.getContractAbi(), ABIDefinition.class); +// List abiArray = JsonTools.toJavaObjectList(inputParam.getContractAbi(), ABIDefinition.class); + List abiArray = JsonTools.toJavaObjectList(inputParam.getContractAbi(), Object.class); if (abiArray == null || abiArray.isEmpty()) { log.info("fail deployContract. abi is empty"); throw new NodeMgrException(ConstantCode.CONTRACT_ABI_EMPTY);