feat: add YiSaiQi studio project for CONTRACT_CREATE on other machines

This commit is contained in:
34BFF76918A9449ABAB323149DDCEA73 2026-08-31 10:22:10 +08:00
parent 5824279fd5
commit 94db441de0
12 changed files with 1871 additions and 76 deletions

View File

@ -0,0 +1,358 @@
# coding=utf-8
"""
构建合同建单 Main.seq —— 按业务段换行,画布上能直接读出步骤。
艺赛旗「插入代码块」的标题固定为「插入代码块#1」,「业务流程描述」节点
打开后再保存标题会被清空。画布上真正能看见的是代码块的备注(NOTE)。
因此本脚本:
1. 不再插入空的业务流程描述节点
2. 把「S06 填写签约方」写进 NOTE,作为画布副标题
3. 按 准备 / 进入起草 / 填写表单 / 提交回写 四段换行
关闭 Studio 后运行本脚本,再重新打开项目编译。
"""
from __future__ import annotations
import base64
import json
from pathlib import Path
HERE = Path(__file__).resolve().parent
OUT = HERE / "studio" / "Main.seq"
COL_W = 280
ROW_H = 200
ORIGIN_X = 360
ORIGIN_Y = 220
BEGIN_TAG = "202608141000000001"
def b64_apa(val):
# 艺赛旗 EP_CONTROL / EP_Gen 字段值末尾带换行,缺失会导致字段解析失败
return json.dumps({"val": base64.b64encode(str(val).encode()).decode()}, indent=4) + "\n"
def b64_raw(val):
return base64.b64encode(str(val).encode()).decode()
STEP_INIT = '''import sys, os, json
from pathlib import Path
_REPO_ROOT = next(
p for p in Path(__file__).resolve().parents
if (p / "rpa_yisaiqi" / "__init__.py").exists()
)
if str(_REPO_ROOT) not in sys.path:
sys.path.insert(0, str(_REPO_ROOT))
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_create_node import ContractCreateError, load_input_data, build_spec_from_data
from rpa_yisaiqi.callback_client import StateCenterClient
from rpa_yisaiqi.apa_browser_adapter import ApaBrowserAdapter
def _first(*values):
for value in values:
if value is not None and str(value).strip():
return str(value).strip()
return ""
raw = (self.input_arg or "").strip()
if not raw:
raw = os.getenv("CONTRACT_INPUT_JSON", "").strip()
if not raw:
raw = str(_REPO_ROOT / "rpa_yisaiqi" / "examples" / "contract_create_input_dry_run.json")
print("未传入 -i/--input,使用默认联调入参:", raw)
if not raw:
raise ContractCreateError("缺少业务入参:请通过 -i/--input 传入 JSON 字符串或文件路径")
data = load_input_data(raw)
state_center_url = _first(
data.get("stateCenterUrl"), data.get("stateCenterURL"),
os.getenv("STATE_CENTER_URL"), "http://192.168.105.69:8000",
)
agent_token = _first(data.get("agentToken"), os.getenv("AGENT_TOKEN"), "dev-agent-token")
_st.spec = build_spec_from_data(data)
_st.client = StateCenterClient(state_center_url, agent_token)
_st.ctx = _st.spec.flow_context
_st.browser = ApaBrowserAdapter(url=_st.ctx.contract_url, flow="CONTRACT_CREATE")
_st.is_dry_run = (_st.spec.submit_mode == "dry_run")
if not _st.is_dry_run:
print("回调状态中心 start", _st.spec.job_id)
_st.client.start_node(_st.spec.job_id, "CONTRACT_CREATE")'''
STEP_OPEN = '''import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import open_contract_system
open_contract_system(_st.browser, _st.ctx)'''
STEP_LOGIN = '''import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import login_contract_system
login_contract_system(_st.browser, _st.ctx)'''
STEP_ENTER = '''import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import enter_contract_create
enter_contract_create(_st.browser)'''
STEP_TEMPLATE = '''import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import select_contract_template
select_contract_template(_st.browser, _st.ctx)'''
STEP_SIGNATORY = '''import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import fill_contract_signatory_info
fill_contract_signatory_info(_st.browser, _st.ctx)'''
STEP_BASIC = '''import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import fill_contract_basic_info
fill_contract_basic_info(_st.browser, _st.ctx)'''
STEP_AMOUNT = '''import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import fill_contract_amount_and_dates
fill_contract_amount_and_dates(_st.browser, _st.ctx)'''
STEP_GOODS = '''import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import fill_contract_goods_lines
fill_contract_goods_lines(_st.browser, _st.ctx)'''
STEP_PAYMENT = '''import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import fill_contract_payment_info
fill_contract_payment_info(_st.browser, _st.ctx)'''
STEP_UPLOAD = '''import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import upload_contract_document_if_needed
upload_contract_document_if_needed(_st.browser, _st.ctx)'''
STEP_SUBMIT = '''import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import submit_contract_for_approval
_st.submitted = submit_contract_for_approval(_st.browser, _st.ctx)'''
STEP_READ_NO = '''import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import read_contract_number
if _st.submitted:
_st.contract_no = read_contract_number(_st.browser, _st.ctx)'''
STEP_COMPLETE = '''import json
import rpa_yisaiqi._flow_state as _st
if not _st.is_dry_run and _st.contract_no:
print("回调状态中心 complete", _st.spec.job_id, _st.contract_no)
_st.client.complete_node(_st.spec.job_id, "CONTRACT_CREATE", {
"businessRefs": {"contractSystemNo": _st.contract_no},
})
print(json.dumps({"status": "done", "contractSystemNo": _st.contract_no}, ensure_ascii=False))'''
# 每段一行。NOTE 会显示在画布「插入代码块#1」下方,务必写短步骤名。
PHASES = [
(
"准备",
[
("S01 初始化并回调 start", STEP_INIT),
("S02 打开合同系统", STEP_OPEN),
("S03 登录合同系统", STEP_LOGIN),
],
),
(
"进入起草",
[
("S04 进入合同起草", STEP_ENTER),
("S05 选择模板", STEP_TEMPLATE),
],
),
(
"填写表单",
[
("S06 填写签约方", STEP_SIGNATORY),
("S07 填写基础信息", STEP_BASIC),
("S08 填写金额日期", STEP_AMOUNT),
("S09 填写货品明细", STEP_GOODS),
("S10 填写付款信息", STEP_PAYMENT),
],
),
(
"提交回写",
[
("S11 上传合同PDF", STEP_UPLOAD),
("S12 提交送审", STEP_SUBMIT),
("S13 读取合同编号", STEP_READ_NO),
("S14 回调 complete", STEP_COMPLETE),
],
),
]
def code_tag(i: int) -> str:
return f"202608143{i:02d}0000000"
def line_tag(i: int) -> str:
return f"202608149{i:02d}0000000"
def _iter_steps():
index = 1
for phase_name, items in PHASES:
for title, code in items:
yield index, phase_name, title, code
index += 1
def build_begin_node(px: int, py: int) -> dict:
return {
"NodePanelData": {
"ExpandedGroups": [],
"InputProperty": {"mouse_x": 0, "mouse_y": 0},
"PubProperty": "",
"RetPins": [],
},
"NodeProperty": "",
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": False,
"NodePx": str(px),
"NodePy": str(py),
"NodeSubType": "EnumWidget_Begin",
"NodeTag": BEGIN_TAG,
"NodeTitle": "开始",
},
}
def build_code_node(tag: str, title: str, code: str, px: int, py: int) -> dict:
body = f'print("[{title}]")\n' + code
return {
"NodePanelData": {
"ExpandedGroups": [],
"InputProperty": {"mouse_x": 0, "mouse_y": 0},
"PubProperty": "",
"RetPins": [],
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": json.dumps(
{"PImport": "", "PBCode": b64_raw(body)}, indent=4
) + "\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": b64_apa("0"),
"EP_Gen_BEFOREDELAY": b64_apa("0"),
"EP_Gen_NOTE": b64_apa(title),
},
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": False,
"NodePx": str(px),
"NodePy": str(py),
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": tag,
"NodeTitle": title,
},
}
def build_nodes():
nodes = []
placed = [] # (tag, x, y)
begin_x, begin_y = ORIGIN_X, ORIGIN_Y
nodes.append(build_begin_node(begin_x, begin_y))
placed.append((BEGIN_TAG, begin_x, begin_y))
# 第一段从「开始」右侧接着排;后续每段单独一行
col = 1
row = 0
current_phase = None
for index, phase_name, title, code in _iter_steps():
if current_phase is None:
current_phase = phase_name
elif phase_name != current_phase:
current_phase = phase_name
row += 1
col = 0
x = ORIGIN_X + col * COL_W
y = ORIGIN_Y + row * ROW_H
tag = code_tag(index)
nodes.append(build_code_node(tag, title, code, x, y))
placed.append((tag, x, y))
col += 1
return nodes, placed
def build_lines(placed: list) -> list:
lines = []
for k in range(len(placed) - 1):
prev_tag, prev_x, prev_y = placed[k]
next_tag, next_x, next_y = placed[k + 1]
same_row = prev_y == next_y
if same_row:
start_x, start_y = prev_x + 150, prev_y + 40
end_x, end_y = next_x - 4, next_y + 40
else:
start_x, start_y = prev_x + 70, prev_y + 90
end_x, end_y = next_x + 70, next_y - 8
lines.append({
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": f"{next_tag}/EPin_Flow_In",
"Px": str(end_x),
"Py": str(end_y),
},
"LineNote": "",
"LineSplit": {"Px": "", "Py": ""},
"LineStart": {
"Pidx": f"{prev_tag}/EPin_Flow_Out",
"Px": str(start_x),
"Py": str(start_y),
},
"LineTag": line_tag(k + 1),
"LineType": 0,
})
return lines
def main() -> None:
nodes, placed = build_nodes()
xs = [x for _, x, _ in placed]
ys = [y for _, _, y in placed]
main_seq = {
"LineList": build_lines(placed),
"NodeList": nodes,
"SeqTag": "Main",
"ViewCenterPx": str((min(xs) + max(xs)) // 2),
"ViewCenterPy": str((min(ys) + max(ys)) // 2),
"ViewScaling": "0.7",
}
OUT.write_text(json.dumps(main_seq, ensure_ascii=False, indent=4), encoding="utf-8")
print(f"多节点 Main.seq 已生成:{OUT}")
print(f"节点数:{len(nodes)}(1 开始 + {len(placed) - 1} 代码块,已去掉空业务标识)")
print(f"连线数:{len(main_seq['LineList'])}")
current_phase = None
for index, phase_name, title, _ in _iter_steps():
if phase_name != current_phase:
current_phase = phase_name
print(f" [{phase_name}]")
print(f" {title}")
if __name__ == "__main__":
main()

View File

@ -4,9 +4,9 @@
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "20260813200000/EPin_Flow_In",
"Px": "512",
"Py": "300"
"Pidx": "202608143010000000/EPin_Flow_In",
"Px": "697",
"Py": "314.931"
},
"LineNote": "",
"LineSplit": {
@ -14,71 +14,777 @@
"Py": ""
},
"LineStart": {
"Pidx": "20260813100000/EPin_Flow_Out",
"Px": "457",
"Py": "246"
"Pidx": "202608141000000001/EPin_Flow_Out",
"Px": "547",
"Py": "296"
},
"LineTag": "20260813300000",
"LineTag": "202608149010000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143020000000/EPin_Flow_In",
"Px": "977",
"Py": "314.931"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143010000000/EPin_Flow_Out",
"Px": "827",
"Py": "314.931"
},
"LineTag": "202608149020000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143030000000/EPin_Flow_In",
"Px": "1257",
"Py": "320"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143020000000/EPin_Flow_Out",
"Px": "1107",
"Py": "314.931"
},
"LineTag": "202608149030000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143040000000/EPin_Flow_In",
"Px": "417",
"Py": "520"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143030000000/EPin_Flow_Out",
"Px": "1387",
"Py": "320"
},
"LineTag": "202608149040000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143050000000/EPin_Flow_In",
"Px": "697",
"Py": "520"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143040000000/EPin_Flow_Out",
"Px": "547",
"Py": "520"
},
"LineTag": "202608149050000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143060000000/EPin_Flow_In",
"Px": "417",
"Py": "720"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143050000000/EPin_Flow_Out",
"Px": "827",
"Py": "520"
},
"LineTag": "202608149060000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143070000000/EPin_Flow_In",
"Px": "697",
"Py": "720"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143060000000/EPin_Flow_Out",
"Px": "547",
"Py": "720"
},
"LineTag": "202608149070000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143080000000/EPin_Flow_In",
"Px": "977",
"Py": "720"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143070000000/EPin_Flow_Out",
"Px": "827",
"Py": "720"
},
"LineTag": "202608149080000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143090000000/EPin_Flow_In",
"Px": "1257",
"Py": "720"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143080000000/EPin_Flow_Out",
"Px": "1107",
"Py": "720"
},
"LineTag": "202608149090000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143100000000/EPin_Flow_In",
"Px": "1537",
"Py": "720"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143090000000/EPin_Flow_Out",
"Px": "1387",
"Py": "720"
},
"LineTag": "202608149100000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143110000000/EPin_Flow_In",
"Px": "417",
"Py": "920"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143100000000/EPin_Flow_Out",
"Px": "1667",
"Py": "720"
},
"LineTag": "202608149110000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143120000000/EPin_Flow_In",
"Px": "697",
"Py": "920"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143110000000/EPin_Flow_Out",
"Px": "547",
"Py": "920"
},
"LineTag": "202608149120000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143130000000/EPin_Flow_In",
"Px": "977",
"Py": "920"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143120000000/EPin_Flow_Out",
"Px": "827",
"Py": "920"
},
"LineTag": "202608149130000000",
"LineType": 0
},
{
"LineColor": "255, 255, 255",
"LineCommented": 0,
"LineEnd": {
"Pidx": "202608143140000000/EPin_Flow_In",
"Px": "1257",
"Py": "920"
},
"LineNote": "",
"LineSplit": {
"Px": "",
"Py": ""
},
"LineStart": {
"Pidx": "202608143130000000/EPin_Flow_Out",
"Px": "1107",
"Py": "920"
},
"LineTag": "202608149140000000",
"LineType": 0
}
],
"NodeList": [
{
"NodePanelData": {
"ExpandedGroups": [],
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": []
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"aW1wb3J0IHN5cywgb3MsIGpzb24KZnJvbSBwYXRobGliIGltcG9ydCBQYXRoCgpfUkVQT19ST09UID0gbmV4dCgKICAgIHAgZm9yIHAgaW4gUGF0aChfX2ZpbGVfXykucmVzb2x2ZSgpLnBhcmVudHMKICAgIGlmIChwIC8gInJwYV95aXNhaXFpIiAvICJfX2luaXRfXy5weSIpLmV4aXN0cygpCikKaWYgc3RyKF9SRVBPX1JPT1QpIG5vdCBpbiBzeXMucGF0aDoKICAgIHN5cy5wYXRoLmluc2VydCgwLCBzdHIoX1JFUE9fUk9PVCkpCgpmcm9tIHJwYV95aXNhaXFpLmNvbnRyYWN0X2NyZWF0ZV9ub2RlIGltcG9ydCAoCiAgICBDb250cmFjdENyZWF0ZUVycm9yLCBsb2FkX2lucHV0X2RhdGEsIHJ1bl9jb250cmFjdF9jcmVhdGUsCikKCmRlZiBfZmlyc3QoKnZhbHVlcyk6CiAgICBmb3IgdmFsdWUgaW4gdmFsdWVzOgogICAgICAgIGlmIHZhbHVlIGlzIG5vdCBOb25lIGFuZCBzdHIodmFsdWUpLnN0cmlwKCk6CiAgICAgICAgICAgIHJldHVybiBzdHIodmFsdWUpLnN0cmlwKCkKICAgIHJldHVybiAiIgoKcmF3ID0gKHNlbGYuaW5wdXRfYXJnIG9yICIiKS5zdHJpcCgpCmlmIG5vdCByYXc6CiAgICByYWlzZSBDb250cmFjdENyZWF0ZUVycm9yKCLnvLrlsJHkuJrliqHlhaXlj4LvvJror7fpgJrov4cgLWkvLS1pbnB1dCDkvKDlhaUgSlNPTiDlrZfnrKbkuLLmiJbmlofku7bot6/lvoQiKQoKZGF0YSA9IGxvYWRfaW5wdXRfZGF0YShyYXcpCgpzdGF0ZV9jZW50ZXJfdXJsID0gX2ZpcnN0KAogICAgZGF0YS5nZXQoInN0YXRlQ2VudGVyVXJsIiksIGRhdGEuZ2V0KCJzdGF0ZUNlbnRlclVSTCIpLAogICAgb3MuZ2V0ZW52KCJTVEFURV9DRU5URVJfVVJMIiksICJodHRwOi8vMTI3LjAuMC4xOjgwMDAiLAopCmFnZW50X3Rva2VuID0gX2ZpcnN0KAogICAgZGF0YS5nZXQoImFnZW50VG9rZW4iKSwgb3MuZ2V0ZW52KCJBR0VOVF9UT0tFTiIpLCAiZGV2LWFnZW50LXRva2VuIiwKKQoKcHJpbnQoIj0iICogNjApCnByaW50KCLlkIjlkIzlu7rljZUgQ09OVFJBQ1RfQ1JFQVRFIC0g5byA5aeLIikKcHJpbnQoImpvYklkPSVzIHNvdXJjZVR5cGU9JXMgc3VibWl0TW9kZT0lcyIgJSAoCiAgICBkYXRhLmdldCgiam9iSWQiKSwgZGF0YS5nZXQoInNvdXJjZVR5cGUiKSwgZGF0YS5nZXQoInN1Ym1pdE1vZGUiKSkpCnByaW50KCI9IiAqIDYwKQoKcmVzdWx0ID0gcnVuX2NvbnRyYWN0X2NyZWF0ZSgKICAgIGRhdGEsCiAgICBzdGF0ZV9jZW50ZXJfdXJsPXN0YXRlX2NlbnRlcl91cmwsCiAgICBhZ2VudF90b2tlbj1hZ2VudF90b2tlbiwKKQpwcmludChqc29uLmR1bXBzKHJlc3VsdCwgZW5zdXJlX2FzY2lpPUZhbHNlKSkK\"\n}"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}",
"EP_Gen_NOTE": "{\n \"val\": \"6K+75Y+W5YWl5Y+C5bm25omn6KGMIENPTlRSQUNUX0NSRUFURe+8iOWQq+eKtuaAgeS4reW/g+Wbnuiwg++8iQ==\"\n}"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "515",
"NodePy": "270",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "20260813200000",
"NodeTitle": "读取入参并执行合同建单"
}
},
{
"NodePanelData": {
"ExpandedGroups": [],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": []
"RetPins": [
]
},
"NodeProperty": "",
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "330",
"NodePy": "230",
"NodePx": "420",
"NodePy": "280",
"NodeSubType": "EnumWidget_Begin",
"NodeTag": "20260813100000",
"NodeTag": "202608141000000001",
"NodeTitle": "开始"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PBCode\": \"cHJpbnQoIltTMDEg5Yid5aeL5YyW5bm25Zue6LCDIHN0YXJ0XSIpCmltcG9ydCBzeXMsIG9zLCBqc29uCmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aAoKX1JFUE9fUk9PVCA9IG5leHQoCiAgICBwIGZvciBwIGluIFBhdGgoX19maWxlX18pLnJlc29sdmUoKS5wYXJlbnRzCiAgICBpZiAocCAvICJycGFfeWlzYWlxaSIgLyAiX19pbml0X18ucHkiKS5leGlzdHMoKQopCmlmIHN0cihfUkVQT19ST09UKSBub3QgaW4gc3lzLnBhdGg6CiAgICBzeXMucGF0aC5pbnNlcnQoMCwgc3RyKF9SRVBPX1JPT1QpKQoKaW1wb3J0IHJwYV95aXNhaXFpLl9mbG93X3N0YXRlIGFzIF9zdApmcm9tIHJwYV95aXNhaXFpLmNvbnRyYWN0X2NyZWF0ZV9ub2RlIGltcG9ydCBDb250cmFjdENyZWF0ZUVycm9yLCBsb2FkX2lucHV0X2RhdGEsIGJ1aWxkX3NwZWNfZnJvbV9kYXRhCmZyb20gcnBhX3lpc2FpcWkuY2FsbGJhY2tfY2xpZW50IGltcG9ydCBTdGF0ZUNlbnRlckNsaWVudApmcm9tIHJwYV95aXNhaXFpLmFwYV9icm93c2VyX2FkYXB0ZXIgaW1wb3J0IEFwYUJyb3dzZXJBZGFwdGVyCgoKZGVmIF9maXJzdCgqdmFsdWVzKToKICAgIGZvciB2YWx1ZSBpbiB2YWx1ZXM6CiAgICAgICAgaWYgdmFsdWUgaXMgbm90IE5vbmUgYW5kIHN0cih2YWx1ZSkuc3RyaXAoKToKICAgICAgICAgICAgcmV0dXJuIHN0cih2YWx1ZSkuc3RyaXAoKQogICAgcmV0dXJuICIiCgoKcmF3ID0gKHNlbGYuaW5wdXRfYXJnIG9yICIiKS5zdHJpcCgpCmlmIG5vdCByYXc6CiAgICByYXcgPSBvcy5nZXRlbnYoIkNPTlRSQUNUX0lOUFVUX0pTT04iLCAiIikuc3RyaXAoKQppZiBub3QgcmF3OgogICAgcmF3ID0gc3RyKF9SRVBPX1JPT1QgLyAicnBhX3lpc2FpcWkiIC8gImV4YW1wbGVzIiAvICJjb250cmFjdF9jcmVhdGVfaW5wdXRfZHJ5X3J1bi5qc29uIikKICAgIHByaW50KCLmnKrkvKDlhaUgLWkvLS1pbnB1dO+8jOS9v+eUqOm7mOiupOiBlOiwg+WFpeWPgu+8miIsIHJhdykKaWYgbm90IHJhdzoKICAgIHJhaXNlIENvbnRyYWN0Q3JlYXRlRXJyb3IoIue8uuWwkeS4muWKoeWFpeWPgu+8muivt+mAmui/hyAtaS8tLWlucHV0IOS8oOWFpSBKU09OIOWtl+espuS4suaIluaWh+S7tui3r+W+hCIpCgpkYXRhID0gbG9hZF9pbnB1dF9kYXRhKHJhdykKc3RhdGVfY2VudGVyX3VybCA9IF9maXJzdCgKICAgIGRhdGEuZ2V0KCJzdGF0ZUNlbnRlclVybCIpLCBkYXRhLmdldCgic3RhdGVDZW50ZXJVUkwiKSwKICAgIG9zLmdldGVudigiU1RBVEVfQ0VOVEVSX1VSTCIpLCAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwKKQphZ2VudF90b2tlbiA9IF9maXJzdChkYXRhLmdldCgiYWdlbnRUb2tlbiIpLCBvcy5nZXRlbnYoIkFHRU5UX1RPS0VOIiksICJkZXYtYWdlbnQtdG9rZW4iKQoKX3N0LnNwZWMgPSBidWlsZF9zcGVjX2Zyb21fZGF0YShkYXRhKQpfc3QuY2xpZW50ID0gU3RhdGVDZW50ZXJDbGllbnQoc3RhdGVfY2VudGVyX3VybCwgYWdlbnRfdG9rZW4pCl9zdC5jdHggPSBfc3Quc3BlYy5mbG93X2NvbnRleHQKX3N0LmJyb3dzZXIgPSBBcGFCcm93c2VyQWRhcHRlcih1cmw9X3N0LmN0eC5jb250cmFjdF91cmwpCl9zdC5pc19kcnlfcnVuID0gKF9zdC5zcGVjLnN1Ym1pdF9tb2RlID09ICJkcnlfcnVuIikKCmlmIG5vdCBfc3QuaXNfZHJ5X3J1biBhbmQgb3MuZ2V0ZW52KCJSUEFfQ0FMTEJBQ0tfU1RBVEVfQ0VOVEVSIikgPT0gIjEiOgogICAgX3N0LmNsaWVudC5zdGFydF9ub2RlKF9zdC5zcGVjLmpvYl9pZCwgIkNPTlRSQUNUX0NSRUFURSIp\",\n \"PImport\": \"\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzAxIOWIneWni+WMluW5tuWbnuiwgyBzdGFydA==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "700",
"NodePy": "280",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143010000000",
"NodeTitle": "插入代码块#1-13"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PBCode\": \"cHJpbnQoIltTMDIg5omT5byA5ZCI5ZCM57O757ufXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBvcGVuX2NvbnRyYWN0X3N5c3RlbQoKb3Blbl9jb250cmFjdF9zeXN0ZW0oX3N0LmJyb3dzZXIsIF9zdC5jdHgp\",\n \"PImport\": \"\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzAyIOaJk+W8gOWQiOWQjOezu+e7nw==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "980",
"NodePy": "280",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143020000000",
"NodeTitle": "插入代码块#1-12"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDMg55m75b2V5ZCI5ZCM57O757ufXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBsb2dpbl9jb250cmFjdF9zeXN0ZW0KCmxvZ2luX2NvbnRyYWN0X3N5c3RlbShfc3QuYnJvd3NlciwgX3N0LmN0eCk=\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzAzIOeZu+W9leWQiOWQjOezu+e7nw==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "1260",
"NodePy": "280",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143030000000",
"NodeTitle": "插入代码块#1-11"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDQg6L+b5YWl5ZCI5ZCM6LW36I2JXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBlbnRlcl9jb250cmFjdF9jcmVhdGUKCmVudGVyX2NvbnRyYWN0X2NyZWF0ZShfc3QuYnJvd3Nlcik=\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzA0IOi/m+WFpeWQiOWQjOi1t+iNiQ==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "420",
"NodePy": "480",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143040000000",
"NodeTitle": "插入代码块#1-10"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDUg6YCJ5oup5qih5p2/XSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBzZWxlY3RfY29udHJhY3RfdGVtcGxhdGUKCnNlbGVjdF9jb250cmFjdF90ZW1wbGF0ZShfc3QuYnJvd3NlciwgX3N0LmN0eCk=\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzA1IOmAieaLqeaooeadvw==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "700",
"NodePy": "480",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143050000000",
"NodeTitle": "插入代码块#1-9"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDYg5aGr5YaZ562+57qm5pa5XSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBmaWxsX2NvbnRyYWN0X3NpZ25hdG9yeV9pbmZvCgpmaWxsX2NvbnRyYWN0X3NpZ25hdG9yeV9pbmZvKF9zdC5icm93c2VyLCBfc3QuY3R4KQ==\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzA2IOWhq+WGmeetvue6puaWuQ==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "420",
"NodePy": "680",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143060000000",
"NodeTitle": "插入代码块#1-8"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDcg5aGr5YaZ5Z+656GA5L+h5oGvXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBmaWxsX2NvbnRyYWN0X2Jhc2ljX2luZm8KCmZpbGxfY29udHJhY3RfYmFzaWNfaW5mbyhfc3QuYnJvd3NlciwgX3N0LmN0eCk=\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzA3IOWhq+WGmeWfuuehgOS/oeaBrw==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "700",
"NodePy": "680",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143070000000",
"NodeTitle": "插入代码块#1-7"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDgg5aGr5YaZ6YeR6aKd5pel5pyfXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBmaWxsX2NvbnRyYWN0X2Ftb3VudF9hbmRfZGF0ZXMKCmZpbGxfY29udHJhY3RfYW1vdW50X2FuZF9kYXRlcyhfc3QuYnJvd3NlciwgX3N0LmN0eCk=\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzA4IOWhq+WGmemHkemineaXpeacnw==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "980",
"NodePy": "680",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143080000000",
"NodeTitle": "插入代码块#1-6"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDkg5aGr5YaZ6LSn5ZOB5piO57uGXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBmaWxsX2NvbnRyYWN0X2dvb2RzX2xpbmVzCgpmaWxsX2NvbnRyYWN0X2dvb2RzX2xpbmVzKF9zdC5icm93c2VyLCBfc3QuY3R4KQ==\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzA5IOWhq+WGmei0p+WTgeaYjue7hg==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "1260",
"NodePy": "680",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143090000000",
"NodeTitle": "插入代码块#1-5"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMTAg5aGr5YaZ5LuY5qy+5L+h5oGvXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBmaWxsX2NvbnRyYWN0X3BheW1lbnRfaW5mbwoKZmlsbF9jb250cmFjdF9wYXltZW50X2luZm8oX3N0LmJyb3dzZXIsIF9zdC5jdHgp\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzEwIOWhq+WGmeS7mOasvuS/oeaBrw==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "1540",
"NodePy": "680",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143100000000",
"NodeTitle": "插入代码块#1-4"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMTEg5LiK5Lyg5ZCI5ZCMUERGXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCB1cGxvYWRfY29udHJhY3RfZG9jdW1lbnRfaWZfbmVlZGVkCgp1cGxvYWRfY29udHJhY3RfZG9jdW1lbnRfaWZfbmVlZGVkKF9zdC5icm93c2VyLCBfc3QuY3R4KQ==\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzExIOS4iuS8oOWQiOWQjFBERg==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "420",
"NodePy": "880",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143110000000",
"NodeTitle": "插入代码块#1-3"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMTIg5o+Q5Lqk6YCB5a6hXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBzdWJtaXRfY29udHJhY3RfZm9yX2FwcHJvdmFsCgpfc3Quc3VibWl0dGVkID0gc3VibWl0X2NvbnRyYWN0X2Zvcl9hcHByb3ZhbChfc3QuYnJvd3NlciwgX3N0LmN0eCk=\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzEyIOaPkOS6pOmAgeWuoQ==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "700",
"NodePy": "880",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143120000000",
"NodeTitle": "插入代码块#1-2"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMTMg6K+75Y+W5ZCI5ZCM57yW5Y+3XSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCByZWFkX2NvbnRyYWN0X251bWJlcgoKaWYgX3N0LnN1Ym1pdHRlZDoKICAgIF9zdC5jb250cmFjdF9ubyA9IHJlYWRfY29udHJhY3RfbnVtYmVyKF9zdC5icm93c2VyKQ==\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzEzIOivu+WPluWQiOWQjOe8luWPtw==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "980",
"NodePy": "880",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143130000000",
"NodeTitle": "插入代码块#1-1"
}
},
{
"NodePanelData": {
"ExpandedGroups": [
],
"InputProperty": {
"mouse_x": 0,
"mouse_y": 0
},
"PubProperty": "",
"RetPins": [
]
},
"NodeProperty": {
"EP_CONTROL": {
"EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMTQg5Zue6LCDIGNvbXBsZXRlXSIpCmltcG9ydCBqc29uCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKCmlmIG5vdCBfc3QuaXNfZHJ5X3J1biBhbmQgX3N0LmNvbnRyYWN0X25vIGFuZCBvcy5nZXRlbnYoIlJQQV9DQUxMQkFDS19TVEFURV9DRU5URVIiKSA9PSAiMSI6CiAgICBfc3QuY2xpZW50LmNvbXBsZXRlX25vZGUoX3N0LnNwZWMuam9iX2lkLCAiQ09OVFJBQ1RfQ1JFQVRFIiwgewogICAgICAgICJidXNpbmVzc1JlZnMiOiB7ImNvbnRyYWN0U3lzdGVtTm8iOiBfc3QuY29udHJhY3Rfbm99LAogICAgfSkKcHJpbnQoanNvbi5kdW1wcyh7InN0YXR1cyI6ICJkb25lIiwgImNvbnRyYWN0U3lzdGVtTm8iOiBfc3QuY29udHJhY3Rfbm99LCBlbnN1cmVfYXNjaWk9RmFsc2UpKQ==\"\n}\n"
},
"EP_Gen": {
"EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n",
"EP_Gen_NOTE": "{\n \"val\": \"UzE0IOWbnuiwgyBjb21wbGV0ZQ==\"\n}\n"
}
},
"NodeUI": {
"NodeElementID": "",
"NodeModel": "2",
"NodePropErr": false,
"NodePx": "1260",
"NodePy": "880",
"NodeSubType": "EnumWidget_Code_Custom",
"NodeTag": "202608143140000000",
"NodeTitle": "插入代码块#1"
}
}
],
"SeqTag": "Main",
"ViewCenterPx": "600",
"ViewCenterPy": "300",
"ViewScaling": "1"
}
"ViewCenterPx": "1357.02",
"ViewCenterPy": "547.412",
"ViewScaling": "0.564474"
}

View File

@ -0,0 +1,46 @@
{
"GlobalVar": [
],
"OpenFlow": "[\n {\n \"current-tab\": \"true\",\n \"seq\": \"Main\",\n \"tag\": \"2026081210133309518\",\n \"title\": \"Main\",\n \"type\": \"bp\"\n }\n]\n",
"ProInfo": {
"CodeCustomCount": "0",
"ProAbsolutePath": "D:/work/AutoRpa/rpa_yisaiqi/studio",
"ProChange": "2026/08/18 13:12:33",
"ProColorRef": "4",
"ProCreate": "2026/08/12 10:13:31",
"ProDesc": "",
"ProDocVersion": "1.0.0.4",
"ProImports": "",
"ProIsAdminRun": "0",
"ProIsNewReturn": "1",
"ProName": "AutoRpa",
"ProStudio": "2026.1.0.36",
"ProTag": "2026081210133159316",
"ProTheme": "light",
"ProUIADeepMatch": "1",
"ProUserID": "34BFF76918A9449ABAB323149DDCEA73",
"ProUserName": "Administrator",
"ProVersion": "1.0.0.0",
"operatingSystem": 0,
"releaseUserName": "qm01"
},
"SeqGroupList": [
],
"SeqPythonModuleList": [
],
"SeqTextFileList": [
],
"SequenceList": [
{
"sdc": "",
"seq": "Main",
"seqptag": "",
"seqret": "1",
"seqtag": "2026081210133309518",
"spr": [
],
"spv": [
]
}
]
}

View File

@ -0,0 +1,22 @@
# coding=utf-8
# 编译日期:2026-08-12 10:13:31
# 版权所有:www.i-search.com.cn
# 测试运行或调试以上全局函数入口
if __name__ == '__main__':
pass

View File

@ -1,5 +1,5 @@
# coding=utf-8
# 编译日期:2026-08-13 14:30:00
# 编译日期:2026-08-17 16:28:48
# 版权所有:www.i-search.com.cn
import ubpa.init_input as iinput
from ubpa.base_util import StdOutHook, ExceptionHandler
@ -40,56 +40,132 @@ class AutoRpa:
self.input_arg = iinput.load_init(__file__)
if self.input_arg is None:
sys.exit(0)
def Main(self):
#插入代码块#1-13
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143010000000,Title:插入代码块#1-13,Note:S01 初始化并回调 start')
print("[S01 初始化并回调 start]")
import sys, os, json
from pathlib import Path
_REPO_ROOT = next(
p for p in Path(__file__).resolve().parents
if (p / "rpa_yisaiqi" / "__init__.py").exists()
)
if str(_REPO_ROOT) not in sys.path:
sys.path.insert(0, str(_REPO_ROOT))
from rpa_yisaiqi.contract_create_node import (
ContractCreateError, load_input_data, run_contract_create,
)
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_create_node import ContractCreateError, load_input_data, build_spec_from_data
from rpa_yisaiqi.callback_client import StateCenterClient
from rpa_yisaiqi.apa_browser_adapter import ApaBrowserAdapter
def _first(*values):
for value in values:
if value is not None and str(value).strip():
return str(value).strip()
return ""
raw = (self.input_arg or "").strip()
if not raw:
raw = os.getenv("CONTRACT_INPUT_JSON", "").strip()
if not raw:
raw = str(_REPO_ROOT / "rpa_yisaiqi" / "examples" / "contract_create_input_dry_run.json")
print("未传入 -i/--input,使用默认联调入参:", raw)
if not raw:
raise ContractCreateError("缺少业务入参:请通过 -i/--input 传入 JSON 字符串或文件路径")
data = load_input_data(raw)
state_center_url = _first(
data.get("stateCenterUrl"), data.get("stateCenterURL"),
os.getenv("STATE_CENTER_URL"), "http://127.0.0.1:8000",
)
agent_token = _first(
data.get("agentToken"), os.getenv("AGENT_TOKEN"), "dev-agent-token",
)
print("=" * 60)
print("合同建单 CONTRACT_CREATE - 开始")
print("jobId=%s sourceType=%s submitMode=%s" % (
data.get("jobId"), data.get("sourceType"), data.get("submitMode")))
print("=" * 60)
result = run_contract_create(
data,
state_center_url=state_center_url,
agent_token=agent_token,
)
print(json.dumps(result, ensure_ascii=False))
return result
agent_token = _first(data.get("agentToken"), os.getenv("AGENT_TOKEN"), "dev-agent-token")
_st.spec = build_spec_from_data(data)
_st.client = StateCenterClient(state_center_url, agent_token)
_st.ctx = _st.spec.flow_context
_st.browser = ApaBrowserAdapter(url=_st.ctx.contract_url)
_st.is_dry_run = (_st.spec.submit_mode == "dry_run")
if not _st.is_dry_run and os.getenv("RPA_CALLBACK_STATE_CENTER") == "1":
_st.client.start_node(_st.spec.job_id, "CONTRACT_CREATE")
#插入代码块#1-12
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143020000000,Title:插入代码块#1-12,Note:S02 打开合同系统')
print("[S02 打开合同系统]")
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import open_contract_system
open_contract_system(_st.browser, _st.ctx)
#插入代码块#1-11
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143030000000,Title:插入代码块#1-11,Note:S03 登录合同系统')
print("[S03 登录合同系统]")
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import login_contract_system
login_contract_system(_st.browser, _st.ctx)
#插入代码块#1-10
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143040000000,Title:插入代码块#1-10,Note:S04 进入合同起草')
print("[S04 进入合同起草]")
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import enter_contract_create
enter_contract_create(_st.browser)
#插入代码块#1-9
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143050000000,Title:插入代码块#1-9,Note:S05 选择模板')
print("[S05 选择模板]")
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import select_contract_template
select_contract_template(_st.browser, _st.ctx)
#插入代码块#1-8
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143060000000,Title:插入代码块#1-8,Note:S06 填写签约方')
print("[S06 填写签约方]")
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import fill_contract_signatory_info
fill_contract_signatory_info(_st.browser, _st.ctx)
#插入代码块#1-7
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143070000000,Title:插入代码块#1-7,Note:S07 填写基础信息')
print("[S07 填写基础信息]")
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import fill_contract_basic_info
fill_contract_basic_info(_st.browser, _st.ctx)
#插入代码块#1-6
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143080000000,Title:插入代码块#1-6,Note:S08 填写金额日期')
print("[S08 填写金额日期]")
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import fill_contract_amount_and_dates
fill_contract_amount_and_dates(_st.browser, _st.ctx)
#插入代码块#1-5
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143090000000,Title:插入代码块#1-5,Note:S09 填写货品明细')
print("[S09 填写货品明细]")
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import fill_contract_goods_lines
fill_contract_goods_lines(_st.browser, _st.ctx)
#插入代码块#1-4
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143100000000,Title:插入代码块#1-4,Note:S10 填写付款信息')
print("[S10 填写付款信息]")
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import fill_contract_payment_info
fill_contract_payment_info(_st.browser, _st.ctx)
#插入代码块#1-3
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143110000000,Title:插入代码块#1-3,Note:S11 上传合同PDF')
print("[S11 上传合同PDF]")
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import upload_contract_document_if_needed
upload_contract_document_if_needed(_st.browser, _st.ctx)
#插入代码块#1-2
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143120000000,Title:插入代码块#1-2,Note:S12 提交送审')
print("[S12 提交送审]")
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import submit_contract_for_approval
_st.submitted = submit_contract_for_approval(_st.browser, _st.ctx)
#插入代码块#1-1
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143130000000,Title:插入代码块#1-1,Note:S13 读取合同编号')
print("[S13 读取合同编号]")
import rpa_yisaiqi._flow_state as _st
from rpa_yisaiqi.contract_flow_steps import read_contract_number
if _st.submitted:
_st.contract_no = read_contract_number(_st.browser)
#插入代码块#1
self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143140000000,Title:插入代码块#1,Note:S14 回调 complete')
print("[S14 回调 complete]")
import json
import rpa_yisaiqi._flow_state as _st
if not _st.is_dry_run and _st.contract_no and os.getenv("RPA_CALLBACK_STATE_CENTER") == "1":
_st.client.complete_node(_st.spec.job_id, "CONTRACT_CREATE", {
"businessRefs": {"contractSystemNo": _st.contract_no},
})
print(json.dumps({"status": "done", "contractSystemNo": _st.contract_no}, ensure_ascii=False))
if __name__ == '__main__':
ILog.begin_init()

View File

@ -0,0 +1,12 @@
# coding: utf8
"""
Python模块脚本
"""
import os
# 项目路径、资源库元素文件(建议其他元素库文件路径在此处声明)
ProjectPath = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
CodePath = os.path.join(ProjectPath, "codes")
ModulePath = os.path.join(CodePath, "modules")
ElementFile = os.path.join(ModulePath, "resources", "elements.json")

View File

@ -0,0 +1,86 @@
# 更多示例代码 http://support.i-search.com.cn:8088/showdoc/web/#/page/11923
## 导入资源库
'''
from iresource import iSResource
is_resource: iSResource = iSResource(__file__)
或者手动指定其他工程元素库文件(当前项目或其他项目)
ElementFile = r"~/NewProject1/codes/modules/resources/elements.json"
is_resource: iSResource = iSResource(json_file=ElementFile)
'''
## 全部资源
'''
all_resource = is_resource.all()
'''
## 获取全局变量、流程变量(参数)
'''
gv1 = is_resource.get_global_var("gv_1")
lv1 = is_resource.get_flow_var("lv_1")
'''
## 设置全局变量、流程变量(参数)
'''
gv1 = is_resource.set_global_var("gv_1", "gv_1新值")
lv1 = is_resource.set_flow_var("lv_1", "lv_1新值")
'''
## 获取元素对象(这段代码可从【元素库】中右击元素,点击【复制代码】直接获得)
'''
element1 = is_resource.get_element("元素ID")
element1.show() # 打印显示元素信息
all_element = is_resource.elements() # 全部元素
'''
## 支持 By.ID,By.CODE,By.NAME 获取元素对象
'''
is_resource.get_element(By.ID, "元素ID")
is_resource.get_element(By.CODE, "元素Code")
is_resource.get_element(By.NAME, "元素Name")
## 也支持具体方法获取元素对象
'''
is_resource.get_element_by_id("元素id")
is_resource.get_element_by_id("元素Code")
is_resource.get_element_by_id("元素Name")
'''
## 元素对象的 方法 和 属性
'''
element1.actions() # 所有方法
element1.properties() # 所有属性
element1.path # 元素路径
element1.snapshot # 元素快照
element1.help("click") # 查看方法使用文档
element1.click(wait_seconds=5)
is_resource.set_action_wait_seconds(5) # 全局调整动作方法执行的等待时间秒数
element1.set_text(value="测试一下")
'''
## 对象化使用
'''
# 使用对象库,通过iSObject对象可以调用子对象(如:键盘、窗口、Excel等)
iSObject.Keyboard(element1.window_title).keypress_input("abc") # 模拟按键
iSObject.Server().set_var("abc", "123") # 设置服务器变量
'''

View File

@ -0,0 +1,3 @@
{
"version": "2.0"
}

View File

@ -0,0 +1,148 @@
# coding=utf-8
"""合同起草真实入口。Studio 编译不会改这个文件。"""
from __future__ import annotations
import json
import os
import sys
from pathlib import Path
def _repo_root() -> Path:
for parent in Path(__file__).resolve().parents:
if (parent / "rpa_yisaiqi" / "__init__.py").exists():
return parent
raise RuntimeError("找不到仓库根目录(缺少 rpa_yisaiqi/__init__.py)")
_REPO_ROOT = _repo_root()
if str(_REPO_ROOT) not in sys.path:
sys.path.insert(0, str(_REPO_ROOT))
from rpa_yisaiqi.apa_browser_adapter import ApaBrowserAdapter # noqa: E402
from rpa_yisaiqi.callback_client import StateCenterClient # noqa: E402
from rpa_yisaiqi.contract_create_node import ( # noqa: E402
ContractCreateError,
build_spec_from_data,
load_input_data,
)
from rpa_yisaiqi.contract_flow_steps import ( # noqa: E402
enter_contract_create,
fill_contract_amount_and_dates,
fill_contract_basic_info,
fill_contract_goods_lines,
fill_contract_payment_info,
fill_contract_signatory_info,
login_contract_system,
open_contract_system,
read_contract_number,
select_contract_template,
submit_contract_for_approval,
upload_contract_document_if_needed,
)
def _first(*values) -> str:
for value in values:
if value is not None and str(value).strip():
return str(value).strip()
return ""
def _parse_input_arg(argv: list[str]) -> str:
i = 0
while i < len(argv):
arg = argv[i]
if arg in ("-i", "--input", "--input-json") and i + 1 < len(argv):
return argv[i + 1]
if arg.startswith("--input=") or arg.startswith("--input-json="):
return arg.split("=", 1)[1]
i += 1
return ""
def main() -> int:
print("合同起草流程启动", flush=True)
raw = _parse_input_arg(sys.argv[1:])
if not raw:
raw = os.getenv("CONTRACT_INPUT_JSON", "").strip()
if not raw:
raw = str(_REPO_ROOT / "rpa_yisaiqi" / "examples" / "contract_create_input_dry_run.json")
print("未传入 -i/--input,使用默认联调入参:", raw, flush=True)
print("[S01 初始化]", flush=True)
data = load_input_data(raw)
state_center_url = _first(
data.get("stateCenterUrl"),
data.get("stateCenterURL"),
os.getenv("STATE_CENTER_URL"),
"http://192.168.105.69:8000",
)
agent_token = _first(data.get("agentToken"), os.getenv("AGENT_TOKEN"), "dev-agent-token")
spec = build_spec_from_data(data)
ctx = spec.flow_context
if ctx is None:
raise ContractCreateError("初始化失败:flow_context 为空")
client = StateCenterClient(state_center_url, agent_token)
browser = ApaBrowserAdapter(url=ctx.contract_url, flow="CONTRACT_CREATE")
is_dry_run = spec.submit_mode == "dry_run"
print(" jobId=", spec.job_id, " submitMode=", spec.submit_mode, flush=True)
print(" contractDocumentPath=", ctx.contract_document_path or ctx.merged_pdf_path, flush=True)
if not is_dry_run:
print("回调状态中心 start", spec.job_id, flush=True)
client.start_node(spec.job_id, "CONTRACT_CREATE")
print("[S02 打开合同系统]", flush=True)
open_contract_system(browser, ctx)
print("[S03 登录合同系统]", flush=True)
login_contract_system(browser, ctx)
print("[S04 进入合同起草]", flush=True)
enter_contract_create(browser)
print("[S05 选择模板]", flush=True)
select_contract_template(browser, ctx)
print("[S06 填写签约方]", flush=True)
fill_contract_signatory_info(browser, ctx)
print("[S07 填写基础信息]", flush=True)
fill_contract_basic_info(browser, ctx)
print("[S08 填写金额日期]", flush=True)
fill_contract_amount_and_dates(browser, ctx)
print("[S09 填写货品明细]", flush=True)
fill_contract_goods_lines(browser, ctx)
print("[S10 填写付款信息]", flush=True)
fill_contract_payment_info(browser, ctx)
print("[S11 上传合同PDF]", flush=True)
upload_contract_document_if_needed(browser, ctx)
print("[S12 提交送审]", flush=True)
submitted = submit_contract_for_approval(browser, ctx)
contract_no = ""
if submitted:
print("[S13 读取合同编号]", flush=True)
contract_no = read_contract_number(browser, ctx)
print("[S14 结束]", flush=True)
if not is_dry_run and contract_no:
print("回调状态中心 complete", spec.job_id, contract_no, flush=True)
client.complete_node(
spec.job_id,
"CONTRACT_CREATE",
{"businessRefs": {"contractSystemNo": contract_no}},
)
print(json.dumps({"status": "done", "contractSystemNo": contract_no}, ensure_ascii=False), flush=True)
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@ -0,0 +1,64 @@
# coding=utf-8
"""APA 启动 Main.py 前会加载本文件。Studio 重新编译不会改这里。
Studio 点运行只带 -p,不带 -i。这里自动补上默认联调 JSON,
避免 S01 因 input_arg 为空直接报「缺少业务入参」。
账号过期把 Main.py 覆盖成空注释时,改走 run_contract.py。
"""
from __future__ import annotations
import os
import sys
def _codes_dir() -> str:
return os.path.dirname(os.path.abspath(__file__))
def _default_input_path() -> str:
repo = os.path.abspath(os.path.join(_codes_dir(), "..", "..", ".."))
return os.path.join(repo, "rpa_yisaiqi", "examples", "contract_create_input_dry_run.json")
def _is_apa_main() -> bool:
if not sys.argv:
return False
return os.path.basename(str(sys.argv[0])).lower() == "main.py"
def _argv_has_input(argv: list) -> bool:
for i, arg in enumerate(argv):
if arg in ("-i", "--input") and i + 1 < len(argv) and str(argv[i + 1]).strip():
return True
if str(arg).startswith("--input=") and str(arg).split("=", 1)[1].strip():
return True
return False
def _main_is_expired_stub(path: str) -> bool:
try:
text = open(path, encoding="utf-8").read()
except Exception:
return False
return "账号过期" in text
# Windows 虚拟机只回调 Mac 状态中心,不在本机起库。
os.environ.setdefault("STATE_CENTER_URL", "http://192.168.105.69:8000")
os.environ.setdefault("AGENT_TOKEN", "dev-agent-token")
os.environ.setdefault("RPA_CALLBACK_STATE_CENTER", "1")
if _is_apa_main():
if _main_is_expired_stub(sys.argv[0]):
print("检测到 Main.py 被艺赛旗覆盖(账号过期),改走独立入口", flush=True)
if _codes_dir() not in sys.path:
sys.path.insert(0, _codes_dir())
from run_contract import main
raise SystemExit(main())
if not _argv_has_input(sys.argv):
default_input = _default_input_path()
if os.path.isfile(default_input):
sys.argv.extend(["-i", default_input])
print("未传入 -i,自动使用默认联调入参:", default_input, flush=True)

View File

@ -0,0 +1 @@
[]

File diff suppressed because one or more lines are too long