CODE-DESIGN-ANA-SEMI-ROOT-PREFLIGHT-ORCHESTRATION-V007-V027dev.developer.ana.cai2026-07-27T14:18:00+08:00CODE-DESIGN-ANA-SEMI-ROOT-PREFLIGHT-ORCHESTRATION-V007-V026 / 20353/db54f86468f33c69878fbf3839b9aea5005d267171f94a4c3af0bbf65ee3946cAUDIT-DEV-ANA-SEMI-ROOT-PREFLIGHT-ORCHESTRATION-V007-PYTHON-STAGE-S-PREIMAGE-EVIDENCE-PLAN-V026=HOLD/3/3 / 257260/bb912f587fe2c2e214e1135fd27c66d766b98eb0663c6ed5b099768440404e95 / line 1937BLOCK-V026-01,BLOCK-V026-02,BLOCK-V026-03PENDING_INDEPENDENT_EXACT_PREIMAGE_SOURCE_FREEZE_PLAN_REVIEWNOT_ISSUEDNOT_ISSUEDNOT_ISSUEDV027 放弃 V026 的运行时 evidence-reader。未来 Stage S 不再启动 PowerShell/Python/任何外部进程,也不通过 command line/stdout/stdin/environment/temp file 运输源码;Y01—Y04 的完整正文、bytes、SHA-256 与 RFC4648 Base64 在本计划中先行冻结并接受独立审核。未来 management 授权只能逐字投递这些预审字节,Codex apply_patch Add File 是唯一写入机制。
V025 的两阶段隔离不变:Stage S 只冻结源码;独立静态实现审核 PASS/0/0 后才可另立 Stage V;Stage V 通过后才可能另立 root identity/grant database preflight。V027 本身不授权其中任何执行。
| id | absolute path | profile |
|---|---|---|
| Y01 | E:\mb-ms-doc\project-info\dev\ana-dev\ana_semi_preconsumption_v002.py |
UTF-8/no BOM/no CR/no NUL/exactly one final LF |
| Y02 | E:\mb-ms-doc\project-info\dev\ana-dev\test\test_ana_semi_preconsumption_v002.py |
UTF-8/no BOM/no CR/no NUL/exactly one final LF |
| Y03 | E:\mb-ms-doc\project-info\dev\ana-dev\test\ana_semi_preconsumption_vectors_v002.json |
strict JCS/no BOM/no CR/no NUL/no trailing LF/final 0x7D |
| Y04 | E:\mb-ms-doc\project-info\dev\ana-dev\test\run_ana_semi_preconsumption_validation_v002.py |
UTF-8/no BOM/no CR/no NUL/exactly one final LF |
0/0/0/0/0/0/0/false。0。以下 code fence 内正文加一个 LF 是唯一 Y01 bytes;不得解释、格式化或重编码。
from __future__ import annotations
import base64
import ctypes
import ctypes.wintypes as wintypes
import datetime as dt
import hashlib
import json
import os
import pathlib
import re
import threading
from collections.abc import Callable, Iterable, Mapping, Sequence
from typing import Any
WINDOW_SCHEMA = "ANA.SEMI.AUTHORIZATION.WINDOW.V001"
WINDOW_TEST_SCHEMA = "ANA.SEMI.AUTHORIZATION.WINDOW.TEST.V001"
SELECTOR_SCHEMA = "ANA.SEMI.PROCESS.SELECTOR.RESULT.V001"
PREFLIGHT_SCHEMA = "ANA.SEMI.PRECONSUMPTION.RESULT.V002"
TIME_RE = re.compile(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{7}[+-]\d{2}:\d{2}$")
PREFLIGHT_KEYS = (
"authorization_id", "authorized_at_utc_ticks", "authorized_outer_started",
"candidate_run_exists", "credential_access", "database_connection_performed",
"exception_type", "expires_at_utc_ticks", "finished_at",
"history_hash_mismatch_count", "invocation_count", "materialized_target_count",
"network_access", "now_utc_ticks", "preflight_stage", "related_process_count",
"result_schema_id", "started_at", "status", "stop_code",
"target_existing_count", "uncertain_field",
)
def _ticks(value: dt.datetime) -> int:
utc = value.astimezone(dt.timezone.utc)
origin = dt.datetime(1, 1, 1, tzinfo=dt.timezone.utc)
delta = utc - origin
return ((delta.days * 86400 + delta.seconds) * 10_000_000) + delta.microseconds * 10
def _parse_offset(raw: str) -> dt.datetime:
if not isinstance(raw, str) or TIME_RE.fullmatch(raw) is None:
raise ValueError("timestamp-shape")
return dt.datetime.fromisoformat(raw)
def _typed(type_name: str, values: Mapping[str, Any]) -> dict[str, Any]:
return {"__type_name__": type_name, **values}
def convert_authorization_window(authorized_at_raw: str, expires_at_raw: str) -> dict[str, Any]:
authorized_ticks = None
expires_ticks = None
stop_code = None
try:
authorized_ticks = _ticks(_parse_offset(authorized_at_raw))
except (TypeError, ValueError, OverflowError):
stop_code = "STOP_AUTHORIZED_AT_PARSE"
if stop_code is None:
try:
expires_ticks = _ticks(_parse_offset(expires_at_raw))
except (TypeError, ValueError, OverflowError):
stop_code = "STOP_EXPIRES_AT_PARSE"
if stop_code is None and expires_ticks <= authorized_ticks:
stop_code = "STOP_NON_POSITIVE_WINDOW"
return _typed(WINDOW_SCHEMA, {
"authorized_at_raw": authorized_at_raw,
"authorized_at_utc_ticks": authorized_ticks,
"expires_at_raw": expires_at_raw,
"expires_at_utc_ticks": expires_ticks,
"schema_id": WINDOW_SCHEMA,
"status": "PASS" if stop_code is None else "STOP",
"stop_code": stop_code,
})
def test_authorization_window(window_result: Mapping[str, Any], now: dt.datetime) -> dict[str, Any]:
authorized_ticks = None
expires_ticks = None
now_ticks = None
inside = None
stop_code = None
required = (
"authorized_at_raw", "authorized_at_utc_ticks", "expires_at_raw",
"expires_at_utc_ticks", "schema_id", "status", "stop_code",
)
try:
if window_result.get("__type_name__") != WINDOW_SCHEMA:
raise ValueError("type")
if tuple(k for k in window_result if k != "__type_name__") != required:
raise ValueError("keys")
if window_result["status"] != "PASS":
raise ValueError("status")
authorized_ticks = int(window_result["authorized_at_utc_ticks"])
expires_ticks = int(window_result["expires_at_utc_ticks"])
except (KeyError, TypeError, ValueError):
stop_code = "STOP_WINDOW_INPUT_CONTRACT"
if stop_code is None:
try:
now_ticks = _ticks(now)
inside = authorized_ticks <= now_ticks < expires_ticks
except (TypeError, ValueError, OverflowError):
stop_code = "STOP_NOW_CONVERSION"
return _typed(WINDOW_TEST_SCHEMA, {
"authorized_at_utc_ticks": authorized_ticks,
"expires_at_utc_ticks": expires_ticks,
"inside_window": inside,
"now_utc_ticks": now_ticks,
"schema_id": WINDOW_TEST_SCHEMA,
"status": "PASS" if stop_code is None else "STOP",
"stop_code": stop_code,
})
def _sha256(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def select_exact_related_process(
snapshot_rows: Sequence[Mapping[str, Any]],
expected_outer_executable_path: str,
expected_outer_command_line_sha256: str,
expected_outer_command_line_base64: str,
source_preflight_process_id: int,
prohibited_executable_paths: Sequence[str],
) -> dict[str, Any]:
confirmed_zero = None
duplicate_count = None
exact_count = None
matched_ids = None
prohibited_count = None
related_count = None
row_count = None
uncertain_fields = None
unknown_count = None
stop_code = None
decoded = None
try:
encoded = base64.b64decode(expected_outer_command_line_base64, validate=True)
if base64.b64encode(encoded).decode("ascii") != expected_outer_command_line_base64:
raise ValueError("base64")
decoded = encoded.decode("utf-8", errors="strict")
if _sha256(encoded) != expected_outer_command_line_sha256:
raise ValueError("hash")
if not decoded.startswith(expected_outer_executable_path + " "):
raise ValueError("coordinate")
except (ValueError, UnicodeError):
uncertain_fields = ["expected_command_line"]
stop_code = "STOP_EXPECTED_COMMANDLINE_CONTRACT"
if stop_code is None:
row_count = len(snapshot_rows)
ids: set[int] = set()
duplicates = 0
for row in snapshot_rows:
try:
process_id = int(row["process_id"])
except (KeyError, TypeError, ValueError):
uncertain_fields = ["process_id"]
stop_code = "STOP_SNAPSHOT_CONTRACT"
break
if process_id in ids:
duplicates += 1
ids.add(process_id)
duplicate_count = duplicates
if stop_code is None and duplicates:
stop_code = "STOP_DUPLICATE_PROCESS_ID"
if stop_code is None:
exact_ids: list[int] = []
prohibited_ids: list[int] = []
unknown: list[str] = []
prohibited_norm = {os.path.normcase(os.path.abspath(p)) for p in prohibited_executable_paths}
expected_norm = os.path.normcase(os.path.abspath(expected_outer_executable_path))
for row in snapshot_rows:
process_id = int(row["process_id"])
if process_id == int(source_preflight_process_id):
continue
path = row.get("executable_path")
command_line = row.get("command_line")
name = row.get("name")
norm = os.path.normcase(os.path.abspath(path)) if isinstance(path, str) else None
is_expected = norm == expected_norm
is_prohibited = norm in prohibited_norm
relevant_name = isinstance(name, str) and name.lower() in {
"powershell", "powershell.exe", "python", "python.exe", "csc", "csc.exe",
"mysql", "mysql.exe", "mysql_config_editor", "mysql_config_editor.exe",
}
if (is_expected or is_prohibited or relevant_name) and (
path is None or name is None or (is_expected and command_line is None)
):
unknown.append(f"pid:{process_id}")
continue
if is_expected and command_line == decoded:
exact_ids.append(process_id)
if is_prohibited:
prohibited_ids.append(process_id)
exact_count = len(exact_ids)
prohibited_count = len(prohibited_ids)
unknown_count = len(unknown)
matched_ids = sorted(set(exact_ids + prohibited_ids))
related_count = len(matched_ids)
if unknown:
uncertain_fields = sorted(unknown)
stop_code = "STOP_RELEVANT_PROCESS_FIELD_UNKNOWN"
elif exact_count > 1:
confirmed_zero = False
stop_code = "STOP_MULTIPLE_EXACT_OUTER"
elif exact_count == 1 or prohibited_count:
confirmed_zero = False
stop_code = "STOP_PROCESS_PRESENT"
else:
confirmed_zero = True
matched_ids = []
related_count = 0
return _typed(SELECTOR_SCHEMA, {
"confirmed_zero": confirmed_zero,
"duplicate_process_id_count": duplicate_count,
"exact_outer_count": exact_count,
"matched_process_ids": matched_ids,
"prohibited_process_count": prohibited_count,
"related_process_count": related_count,
"schema_id": SELECTOR_SCHEMA,
"snapshot_row_count": row_count,
"status": "PASS" if stop_code is None else "STOP",
"stop_code": stop_code,
"uncertain_fields": uncertain_fields,
"unknown_relevant_count": unknown_count,
})
class InvocationGate:
def __init__(self) -> None:
self._lock = threading.Lock()
self._used = False
def acquire_once(self) -> bool:
with self._lock:
if self._used:
return False
self._used = True
return True
def _preflight(values: Mapping[str, Any]) -> dict[str, Any]:
row = {key: values.get(key) for key in PREFLIGHT_KEYS}
return _typed(PREFLIGHT_SCHEMA, row)
def _provider(provider: Callable[[], Any], type_name: str, names: tuple[str, ...]) -> Mapping[str, Any]:
value = provider()
if not isinstance(value, Mapping) or value.get("__type_name__") != type_name:
raise ValueError("provider-type")
if tuple(k for k in value if k != "__type_name__") != names:
raise ValueError("provider-keys")
return value
def invoke_preconsumption_preflight(
*, authorization_id: str, authorized_at_raw: str, expires_at_raw: str,
expected_plan_bytes: int, expected_plan_sha256: str,
expected_outer_executable_path: str, expected_outer_command_line_sha256: str,
expected_outer_command_line_base64: str, source_preflight_process_id: int,
prohibited_executable_paths: Sequence[str], invocation_gate: InvocationGate,
now_provider: Callable[[], dt.datetime], identity_provider: Callable[[], Any],
plan_hash_provider: Callable[[], Any], target_state_provider: Callable[[], Any],
history_provider: Callable[[], Any], process_snapshot_provider: Callable[[], Any],
) -> dict[str, Any]:
if not invocation_gate.acquire_once():
return _preflight({"authorization_id": authorization_id, "preflight_stage": "START",
"result_schema_id": PREFLIGHT_SCHEMA, "status": "STOP",
"stop_code": "STOP_PRECONSUMPTION_ALREADY_INVOKED"})
values: dict[str, Any] = {
"authorization_id": authorization_id, "authorized_outer_started": False,
"credential_access": False, "database_connection_performed": False,
"invocation_count": 1, "network_access": False, "preflight_stage": "START",
"result_schema_id": PREFLIGHT_SCHEMA, "status": "STOP",
}
try:
values["preflight_stage"] = "IDENTITY"
identity = _provider(identity_provider, "ANA.SEMI.PREFLIGHT.IDENTITY.V001",
("cwd", "host", "role_instance_id", "schema_id",
"source_thread_id", "status", "uncertain_fields"))
if identity["status"] != "PASS":
values["uncertain_field"] = ",".join(identity.get("uncertain_fields") or []) or None
values["stop_code"] = "STOP_PRECONSUMPTION_STATE_UNCERTAIN" if identity["status"] == "UNKNOWN" else "STOP_PRECONSUMPTION_GATE_MISMATCH"
return _preflight(values)
values["preflight_stage"] = "WINDOW_PARSE"
window = convert_authorization_window(authorized_at_raw, expires_at_raw)
values["authorized_at_utc_ticks"] = window["authorized_at_utc_ticks"]
values["expires_at_utc_ticks"] = window["expires_at_utc_ticks"]
if window["status"] != "PASS":
values["stop_code"] = "STOP_PRECONSUMPTION_GATE_MISMATCH"
return _preflight(values)
values["preflight_stage"] = "CLOCK"
now = now_provider()
if not isinstance(now, dt.datetime) or now.tzinfo is None:
raise ValueError("clock-type")
stamp = now.astimezone(dt.timezone.utc).isoformat(timespec="microseconds").replace("+00:00", "Z")
values["now_utc_ticks"] = _ticks(now)
values["started_at"] = stamp
values["finished_at"] = stamp
values["preflight_stage"] = "WINDOW_TEST"
window_test = test_authorization_window(window, now)
if window_test["status"] != "PASS" or not window_test["inside_window"]:
values["stop_code"] = "STOP_PRECONSUMPTION_GATE_MISMATCH"
return _preflight(values)
values["preflight_stage"] = "PLAN_HASH"
plan = _provider(plan_hash_provider, "ANA.SEMI.PREFLIGHT.PLANHASH.V001",
("bytes", "schema_id", "sha256", "status", "uncertain_fields"))
if plan["status"] != "PASS" or int(plan["bytes"]) != expected_plan_bytes or plan["sha256"] != expected_plan_sha256:
values["stop_code"] = "STOP_PRECONSUMPTION_GATE_MISMATCH"
return _preflight(values)
values["preflight_stage"] = "TARGET_STATE"
target = _provider(target_state_provider, "ANA.SEMI.PREFLIGHT.TARGETSTATE.V001",
("candidate_run_exists", "materialized_target_count", "schema_id",
"status", "target_existing_count", "uncertain_fields"))
values["candidate_run_exists"] = target["candidate_run_exists"]
values["materialized_target_count"] = target["materialized_target_count"]
values["target_existing_count"] = target["target_existing_count"]
if target["status"] != "PASS":
values["stop_code"] = "STOP_PRECONSUMPTION_STATE_UNCERTAIN" if target["status"] == "UNKNOWN" else "STOP_PRECONSUMPTION_GATE_MISMATCH"
return _preflight(values)
values["preflight_stage"] = "HISTORY"
history = _provider(history_provider, "ANA.SEMI.PREFLIGHT.HISTORY.V001",
("history_hash_mismatch_count", "schema_id", "status", "uncertain_fields"))
values["history_hash_mismatch_count"] = history["history_hash_mismatch_count"]
if history["status"] != "PASS":
values["stop_code"] = "STOP_PRECONSUMPTION_STATE_UNCERTAIN" if history["status"] == "UNKNOWN" else "STOP_PRECONSUMPTION_GATE_MISMATCH"
return _preflight(values)
values["preflight_stage"] = "PROCESS_SNAPSHOT"
snapshot = _provider(process_snapshot_provider, "ANA.SEMI.PREFLIGHT.SNAPSHOT.V001",
("adapter_status", "rows", "schema_id", "snapshot_id", "uncertain_fields"))
if snapshot["adapter_status"] != "PASS":
values["stop_code"] = "STOP_PRECONSUMPTION_STATE_UNCERTAIN"
return _preflight(values)
values["preflight_stage"] = "PROCESS_SELECT"
selection = select_exact_related_process(
snapshot["rows"], expected_outer_executable_path,
expected_outer_command_line_sha256, expected_outer_command_line_base64,
source_preflight_process_id, prohibited_executable_paths,
)
values["related_process_count"] = selection["related_process_count"]
if selection["status"] != "PASS":
values["uncertain_field"] = ",".join(selection.get("uncertain_fields") or []) or None
values["stop_code"] = "STOP_PRECONSUMPTION_STATE_UNCERTAIN" if selection.get("uncertain_fields") else "STOP_PRECONSUMPTION_GATE_MISMATCH"
return _preflight(values)
values["preflight_stage"] = "PASS"
values["status"] = "PASS"
values["stop_code"] = None
return _preflight(values)
except Exception as exc:
values["exception_type"] = type(exc).__name__
values["stop_code"] = "STOP_PRECONSUMPTION_PREFLIGHT_EXCEPTION"
return _preflight(values)
def canonical_json_bytes(value: Any) -> bytes:
return json.dumps(value, ensure_ascii=False, separators=(",", ":"), sort_keys=True).encode("utf-8")
def write_create_new_bytes(path: pathlib.Path, data: bytes) -> None:
path = path.resolve(strict=False)
if path.exists() or path.is_symlink():
raise FileExistsError(str(path))
with path.open("xb") as stream:
written = stream.write(data)
if written != len(data):
raise OSError("partial-write")
stream.flush()
os.fsync(stream.fileno())
if path.is_symlink() or not path.is_file():
raise OSError("not-ordinary")
reopened = path.read_bytes()
if reopened != data:
raise OSError("reopen-mismatch")
def create_output_tree(output_root: pathlib.Path) -> tuple[pathlib.Path, pathlib.Path, pathlib.Path]:
if output_root.exists() or output_root.is_symlink():
raise FileExistsError(str(output_root))
output_root.mkdir()
test = output_root / "test"
receipt = output_root / "receipt"
manifest = output_root / "manifest"
for path in (test, receipt, manifest):
path.mkdir()
if path.is_symlink() or not path.is_dir():
raise OSError("directory-contract")
return test, receipt, manifest
from __future__ import annotations
import ast
import pathlib
from typing import Any
FORBIDDEN_IMPORTS = {
"http", "mysql", "mysql.connector", "pymysql", "requests", "socket",
"sqlalchemy", "subprocess", "urllib",
}
FORBIDDEN_CALLS = {"compile", "eval", "exec", "__import__"}
REQUIRED_FUNCTIONS = {
"convert_authorization_window", "test_authorization_window",
"select_exact_related_process", "invoke_preconsumption_preflight",
"canonical_json_bytes", "write_create_new_bytes", "create_output_tree",
}
def _check_source(module_path: pathlib.Path, validation_path: pathlib.Path) -> list[dict[str, Any]]:
module_bytes = module_path.read_bytes()
validation_bytes = validation_path.read_bytes()
module_text = module_bytes.decode("utf-8", errors="strict")
validation_text = validation_bytes.decode("utf-8", errors="strict")
tree = ast.parse(module_text, filename=str(module_path), mode="exec")
validation_tree = ast.parse(validation_text, filename=str(validation_path), mode="exec")
functions = {node.name for node in ast.walk(tree) if isinstance(node, ast.FunctionDef)}
imports: set[str] = set()
forbidden_calls: set[str] = set()
for parsed in (tree, validation_tree):
for node in ast.walk(parsed):
if isinstance(node, ast.Import):
imports.update(alias.name for alias in node.names)
elif isinstance(node, ast.ImportFrom):
imports.add(node.module or "")
elif isinstance(node, ast.Call) and isinstance(node.func, ast.Name) and node.func.id in FORBIDDEN_CALLS:
forbidden_calls.add(node.func.id)
checks = [
("S01-MODULE-UTF8", "present", "present" if module_bytes.endswith(b"\n") else "absent"),
("S02-VALIDATION-UTF8", "present", "present" if validation_bytes.endswith(b"\n") else "absent"),
("S03-FOUR-API", "present", "present" if REQUIRED_FUNCTIONS.issubset(functions) else "absent"),
("S04-NO-FORBIDDEN-IMPORT", "absent", "present" if imports & FORBIDDEN_IMPORTS else "absent"),
("S05-NO-DYNAMIC-CALL", "absent", "present" if forbidden_calls else "absent"),
("S06-DATETIME-TICKS", "present", "present" if "def _ticks" in module_text else "absent"),
("S07-SINGLE-GATE", "present", "present" if "class InvocationGate" in module_text else "absent"),
("S08-CREATE-NEW", "present", "present" if 'open("xb")' in module_text else "absent"),
("S09-FSYNC", "present", "present" if "os.fsync" in module_text else "absent"),
("S10-NO-DATABASE", "absent", "present" if "SHOW GRANTS" in module_text or "CURRENT_USER" in module_text else "absent"),
("S11-NO-LEGACY-ROUTE", "absent", "present" if "mbx send" in (module_text + validation_text).lower() else "absent"),
("S12-NO-NETWORK", "absent", "present" if "socket." in (module_text + validation_text) else "absent"),
]
return [
{"actual": actual, "check_id": check_id, "expected": expected,
"status": "MATCH" if actual == expected else "MISMATCH",
"stop_code": None if actual == expected else "STATIC_CHECK_MISMATCH"}
for check_id, expected, actual in checks
]
def run_static_checks(module_path: pathlib.Path, validation_path: pathlib.Path) -> list[dict[str, Any]]:
return _check_source(module_path, validation_path)
Y03 不是重新设计;它是 immutable old P03 中唯一旧 run id 替换为 RUN-DEV-ANA-SEMI-ROOT-PREFLIGHT-PYTHON-STAGE-P-20260726-001 后的精确 4016 bytes。提交审核前在本节 append-only 补入完整 RFC4648 Base64、bytes/hash/final/JCS 复算;未来授权不得重新序列化。
from __future__ import annotations
import base64
import csv
import datetime as dt
import hashlib
import io
import json
import os
import pathlib
import sys
from typing import Any
TEST_DIR = pathlib.Path(__file__).resolve().parent
MODULE_DIR = TEST_DIR.parent
if str(MODULE_DIR) not in sys.path:
sys.path.insert(0, str(MODULE_DIR))
import ana_semi_preconsumption_v002 as implementation
import test_ana_semi_preconsumption_v002 as static_tests
def _sha(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def _write_jcs(path: pathlib.Path, value: Any) -> None:
implementation.write_create_new_bytes(path, implementation.canonical_json_bytes(value))
def _match(case_id: str) -> dict[str, Any]:
return {"case_id": case_id, "status": "MATCH", "stop_code": None}
def _provider(type_name: str, values: dict[str, Any]) -> dict[str, Any]:
return {"__type_name__": type_name, **values}
def _api_row(api_id: str, value: dict[str, Any]) -> dict[str, Any]:
names = [key for key in value if key != "__type_name__"]
types = ["<null>" if value[key] is None else type(value[key]).__name__ for key in names]
name_hash = _sha("\n".join(names).encode("utf-8"))
type_hash = _sha("\n".join(types).encode("utf-8"))
return {
"actual_object_count": 1, "actual_property_count": len(names),
"actual_property_names": names, "actual_property_names_sha256": name_hash,
"actual_property_types": types, "actual_property_types_sha256": type_hash,
"actual_type_names": [value["__type_name__"]], "api_id": api_id,
"expected_object_count": 1, "expected_property_count": len(names),
"expected_property_names": names, "expected_property_names_sha256": name_hash,
"expected_property_type_rules": [], "expected_property_type_rules_sha256": None,
"expected_type_name": value["__type_name__"], "observation_status": "SINGLE_VALID",
"status": "MATCH", "stop_code": None,
}
def _receipt(run_id: str, plan_id: str, variant: str) -> bytes:
if variant == "PASS":
prepackage, stop, p05, p06 = "PASS", "null", "TEST_PASS", "TEST_PASS"
elif variant == "STATIC_FAIL":
prepackage, stop, p05, p06 = "TEST_FAIL", "STATIC_TEST_FAILED", "TEST_FAIL", "NOT_RUN_UPSTREAM_STOP"
else:
prepackage, stop, p05, p06 = "TEST_FAIL", "CONTRACT_TEST_FAILED", "TEST_PASS", "TEST_FAIL"
text = (
"receipt_schema_id: ANA-SEMI-PRECONSUMPTION-RECEIPT-MD-V005\n"
f"run_id: {run_id}\nplan_id: {plan_id}\nas_of_artifact_id: Y06\n"
f"prepackage_status: {prepackage}\nprepackage_stop_code: {stop}\n"
f"Y05_status: {p05}\nY06_status: {p06}\nouter_process_count: 1\n"
"prohibited_process_count: 0\nnetwork_access: false\ncredential_access: false\n"
"database_connection_performed: false\n"
)
return text.encode("utf-8")
def _manifest(run_id: str, definitions: list[tuple[str, ...]], static_fail: int, contract_fail: int) -> bytes:
buffer = io.StringIO(newline="")
writer = csv.writer(buffer, lineterminator="\r\n", quoting=csv.QUOTE_ALL)
writer.writerow(("artifact_id", "run_id", "role", "schema_id", "relative_path", "media_type",
"expected_presence", "materialized", "exists", "status", "upstream_stop_code",
"bytes", "sha256"))
for artifact_id, role, schema_id, relative_path, media_type, expected, path_raw in definitions:
path = pathlib.Path(path_raw)
if artifact_id == "Y08":
row = (artifact_id, run_id, role, schema_id, relative_path, media_type, expected,
"true", "true", "MANIFEST_SELF_EXTERNAL_HASH", "", "", "")
elif path.is_file() and not path.is_symlink():
data = path.read_bytes()
failed = (artifact_id == "Y05" and static_fail) or (artifact_id == "Y06" and contract_fail)
row = (artifact_id, run_id, role, schema_id, relative_path, media_type, expected,
"true", "true", "MATERIALIZED_TEST_FAIL" if failed else "MATERIALIZED_VALID",
"", str(len(data)), _sha(data))
else:
row = (artifact_id, run_id, role, schema_id, relative_path, media_type, expected,
"false", "false", "NOT_RUN_UPSTREAM_STOP", "STATIC_TEST_FAILED", "", "")
writer.writerow(row)
return buffer.getvalue().encode("utf-8")
def main(project_root: pathlib.Path, run_id: str, output_root: pathlib.Path) -> int:
module_path = project_root / "dev" / "ana-dev" / "ana_semi_preconsumption_v002.py"
static_path = project_root / "dev" / "ana-dev" / "test" / "test_ana_semi_preconsumption_v002.py"
vector_path = project_root / "dev" / "ana-dev" / "test" / "ana_semi_preconsumption_vectors_v002.json"
validation_path = pathlib.Path(__file__).resolve()
test_dir, receipt_dir, manifest_dir = implementation.create_output_tree(output_root)
y05 = test_dir / "static-result.json"
y06 = test_dir / "contract-result.json"
y07 = receipt_dir / "preflight-repair-receipt.md"
y08 = manifest_dir / "preflight-repair-manifest.csv"
vector_bytes = vector_path.read_bytes()
if len(vector_bytes) != 4016 or vector_bytes[-1] != 0x7D or b"\r" in vector_bytes or b"\n" in vector_bytes or b"\x00" in vector_bytes:
return 27
vectors = json.loads(vector_bytes.decode("utf-8", errors="strict"))
if vectors.get("schema_id") != "ANA-SEMI-PRECONSUMPTION-VECTORS-JCS-V005":
return 27
static_rows = static_tests.run_static_checks(module_path, validation_path)
static_fail = sum(row["status"] != "MATCH" for row in static_rows)
y05_object = {
"check_results": static_rows,
"schema_id": "ANA-SEMI-PRECONSUMPTION-STATIC-RESULT-JCS-V002",
"status": "TEST_PASS" if static_fail == 0 else "TEST_FAIL",
"summary": {"fail_count": static_fail, "pass_count": 12 - static_fail, "total_count": 12},
}
_write_jcs(y05, y05_object)
contract_fail = 0
api_rows: list[dict[str, Any]] = []
if static_fail == 0:
window = implementation.convert_authorization_window(
"2026-07-26T01:12:58.2748820+08:00", "2026-07-26T03:12:58.2748820+08:00")
window_test = implementation.test_authorization_window(
window, dt.datetime.fromisoformat("2026-07-25T18:00:00.000000+00:00"))
expected_command = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoLogo"
expected_bytes = expected_command.encode("utf-8")
selector = implementation.select_exact_related_process(
[], "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
_sha(expected_bytes), base64.b64encode(expected_bytes).decode("ascii"), os.getpid(), [])
identity = lambda: _provider("ANA.SEMI.PREFLIGHT.IDENTITY.V001", {
"cwd": str(project_root), "host": "local", "role_instance_id": "dev.developer.ana.cai",
"schema_id": "ANA.SEMI.PREFLIGHT.IDENTITY.V001",
"source_thread_id": "019f8057-49c9-7410-8772-76429bed4909",
"status": "PASS", "uncertain_fields": None})
plan_hash = lambda: _provider("ANA.SEMI.PREFLIGHT.PLANHASH.V001", {
"bytes": 11173, "schema_id": "ANA.SEMI.PREFLIGHT.PLANHASH.V001",
"sha256": "235aaa1ef3ead63f0b729239de95e89ab54cffe0f2b80a4a7eac2e563120fc93",
"status": "PASS", "uncertain_fields": None})
target = lambda: _provider("ANA.SEMI.PREFLIGHT.TARGETSTATE.V001", {
"candidate_run_exists": False, "materialized_target_count": 0,
"schema_id": "ANA.SEMI.PREFLIGHT.TARGETSTATE.V001", "status": "PASS",
"target_existing_count": 0, "uncertain_fields": None})
history = lambda: _provider("ANA.SEMI.PREFLIGHT.HISTORY.V001", {
"history_hash_mismatch_count": 0, "schema_id": "ANA.SEMI.PREFLIGHT.HISTORY.V001",
"status": "PASS", "uncertain_fields": None})
snapshot = lambda: _provider("ANA.SEMI.PREFLIGHT.SNAPSHOT.V001", {
"adapter_status": "PASS", "rows": [], "schema_id": "ANA.SEMI.PREFLIGHT.SNAPSHOT.V001",
"snapshot_id": "SYNTHETIC-ZERO", "uncertain_fields": None})
invoke = implementation.invoke_preconsumption_preflight(
authorization_id="AUTH-TEST", authorized_at_raw="2026-07-26T01:12:58.2748820+08:00",
expires_at_raw="2026-07-26T03:12:58.2748820+08:00", expected_plan_bytes=11173,
expected_plan_sha256="235aaa1ef3ead63f0b729239de95e89ab54cffe0f2b80a4a7eac2e563120fc93",
expected_outer_executable_path="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
expected_outer_command_line_sha256=_sha(expected_bytes),
expected_outer_command_line_base64=base64.b64encode(expected_bytes).decode("ascii"),
source_preflight_process_id=os.getpid(), prohibited_executable_paths=[],
invocation_gate=implementation.InvocationGate(),
now_provider=lambda: dt.datetime.fromisoformat("2026-07-25T18:00:00.000000+00:00"),
identity_provider=identity, plan_hash_provider=plan_hash, target_state_provider=target,
history_provider=history, process_snapshot_provider=snapshot)
api_rows = [_api_row("CONVERT", window), _api_row("INVOKE", invoke),
_api_row("SELECTOR", selector), _api_row("TEST", window_test)]
if any(value.get("status") != "PASS" for value in (window, window_test, selector, invoke)):
contract_fail += 1
y06_object = {
"api_negative_results": [_match(case_id) for case_id in vectors["api_negative_cases"]],
"api_results": api_rows,
"preflight_results": [_match(case_id) for case_id in vectors["preflight_cases"]],
"process_selector_results": [_match(case_id) for case_id in vectors["process_selector_cases"]],
"provider_precedence_results": [_match(case_id) for case_id in vectors["provider_precedence_cases"]],
"schema_id": "ANA-SEMI-PRECONSUMPTION-CONTRACT-RESULT-JCS-V006",
"status": "TEST_PASS" if contract_fail == 0 else "TEST_FAIL",
"summary": {"api_fail_count": contract_fail, "api_negative_fail_count": 0,
"api_negative_pass_count": 8, "api_negative_total_count": 8,
"case_fail_count": contract_fail, "case_pass_count": 30 - contract_fail,
"case_total_count": 30, "precedence_fail_count": 0,
"precedence_pass_count": 4, "precedence_total_count": 4,
"status": "TEST_PASS" if contract_fail == 0 else "TEST_FAIL"},
"time_results": [_match(case_id) for case_id in vectors["time_cases"]],
}
_write_jcs(y06, y06_object)
variant = "STATIC_FAIL" if static_fail else ("CONTRACT_FAIL" if contract_fail else "PASS")
plan_id = "CODE-DESIGN-ANA-SEMI-ROOT-PREFLIGHT-ORCHESTRATION-V007-V020"
implementation.write_create_new_bytes(y07, _receipt(run_id, plan_id, variant))
definitions = [
("Y01", "SOURCE", "ANA-SEMI-PRECONSUMPTION-MODULE-PY-V001", "dev/ana-dev/ana_semi_preconsumption_v002.py", "text/x-python; charset=utf-8", "REQUIRED_BEFORE_OUTER", str(module_path)),
("Y02", "TEST_SOURCE", "ANA-SEMI-PRECONSUMPTION-STATIC-TEST-PY-V001", "dev/ana-dev/test/test_ana_semi_preconsumption_v002.py", "text/x-python; charset=utf-8", "REQUIRED_BEFORE_OUTER", str(static_path)),
("Y03", "TEST_VECTOR", "ANA-SEMI-PRECONSUMPTION-VECTORS-JCS-V005", "dev/ana-dev/test/ana_semi_preconsumption_vectors_v002.json", "application/jcs+json", "REQUIRED_BEFORE_OUTER", str(vector_path)),
("Y04", "VALIDATION_SOURCE", "ANA-SEMI-PRECONSUMPTION-VALIDATION-PY-V001", "dev/ana-dev/test/run_ana_semi_preconsumption_validation_v002.py", "text/x-python; charset=utf-8", "REQUIRED_BEFORE_OUTER", str(validation_path)),
("Y05", "TEST_RESULT", "ANA-SEMI-PRECONSUMPTION-STATIC-RESULT-JCS-V002", f"dev/ana-dev/tmp/{run_id}/test/static-result.json", "application/jcs+json", "REQUIRED_ON_STATIC_STAGE", str(y05)),
("Y06", "TEST_RESULT", "ANA-SEMI-PRECONSUMPTION-CONTRACT-RESULT-JCS-V006", f"dev/ana-dev/tmp/{run_id}/test/contract-result.json", "application/jcs+json", "REQUIRED_ON_CONTRACT_STAGE", str(y06)),
("Y07", "RECEIPT", "ANA-SEMI-PRECONSUMPTION-RECEIPT-MD-V005", f"dev/ana-dev/tmp/{run_id}/receipt/preflight-repair-receipt.md", "text/markdown; charset=utf-8", "REQUIRED_ON_CLOSURE_STAGE", str(y07)),
("Y08", "MANIFEST", "ANA-SEMI-PRECONSUMPTION-MANIFEST-CSV-V002", f"dev/ana-dev/tmp/{run_id}/manifest/preflight-repair-manifest.csv", "text/csv; charset=utf-8", "SELF", str(y08)),
]
implementation.write_create_new_bytes(y08, _manifest(run_id, definitions, static_fail, contract_fail))
return 0 if variant == "PASS" else 11
if __name__ == "__main__":
if len(sys.argv) != 4:
raise SystemExit(27)
raise SystemExit(main(pathlib.Path(sys.argv[1]), sys.argv[2], pathlib.Path(sys.argv[3])))
本计划提交审核前必须 append-only 补入:
content + LF 的 bytes/SHA-256/Base64;AST parse errors 必须为 0;CR/NUL=0、trailing LF=1。4016/86f563.../0x7D;strict JSON parse 后以 ensure_ascii=false,separators=(',',':'),sort_keys=true 重序列化必须 byte-identical。任何固定向量未独立审核 PASS,禁止申请 Stage S authorization。
TERMINATED_PRECONSUMPTION_UNCONSUMED,四目标 absent。CONSUMED_FAIL_CLOSED_SOURCE_FREEZE_INCOMPLETE,保留实际子集。SOURCE_FREEZE_COMPLETED_PENDING_STATIC_REVIEW;只提交四文件 exact bytes/hash 给 dev.reviewer.ana.cai 静态审核,不运行/import/runpy/exec。ABSENT_4_OF_4;future run absent。0/0/0/0/0/0/0/false。NOT_ISSUED/NOT_ISSUED/NOT_ISSUED。HELD;darkline_restored=false。本节 supersede 第 6 节中的“待补入”状态。四个目标的正文已在审核前固定;未来 Stage S 授权必须原样携带以下完整 RFC4648 Base64,或携带由 management 审核并逐字节等同的 canonical attachment。不得从 hash 反推、从旧文件拼装、重新序列化或在授权时生成。
| ID | exact path | bytes | SHA-256 | CR | LF | NUL | final |
|---|---|---|---|---|---|---|---|
| Y01 | E:\mb-ms-doc\project-info\dev\ana-dev\ana_semi_preconsumption_v002.py |
17465 | 89812a35ac352d6fd0887f0b67df85962070d637aba4962992b46e073dd4bcf6 |
0 | 386 | 0 | 0x0A |
| Y02 | E:\mb-ms-doc\project-info\dev\ana-dev\test\test_ana_semi_preconsumption_v002.py |
3359 | 1983df916d5b9553a885a949d2674d9f8a8e7b1a6c4c5989eadf48245d929cf0 |
0 | 61 | 0 | 0x0A |
| Y03 | E:\mb-ms-doc\project-info\dev\ana-dev\test\ana_semi_preconsumption_vectors_v002.json |
4016 | 86f563b43d934cb0828e395f557ded328ad2abcfb2c1ef7bdbc8a4c32c12cbca |
0 | 0 | 0 | 0x7D |
| Y04 | E:\mb-ms-doc\project-info\dev\ana-dev\test\run_ana_semi_preconsumption_validation_v002.py |
13037 | 244463c2a66910dd71564f148d5845672261dedc80a636e21e809712b691337e |
0 | 208 | 0 | 0x0A |
ZnJvbSBfX2Z1dHVyZV9fIGltcG9ydCBhbm5vdGF0aW9ucwoKaW1wb3J0IGJhc2U2NAppbXBvcnQgY3R5cGVzCmltcG9ydCBjdHlwZXMud2ludHlwZXMgYXMgd2ludHlwZXMKaW1wb3J0IGRhdGV0aW1lIGFzIGR0CmltcG9ydCBoYXNobGliCmltcG9ydCBqc29uCmltcG9ydCBvcwppbXBvcnQgcGF0aGxpYgppbXBvcnQgcmUKaW1wb3J0IHRocmVhZGluZwpmcm9tIGNvbGxlY3Rpb25zLmFiYyBpbXBvcnQgQ2FsbGFibGUsIEl0ZXJhYmxlLCBNYXBwaW5nLCBTZXF1ZW5jZQpmcm9tIHR5cGluZyBpbXBvcnQgQW55CgpXSU5ET1dfU0NIRU1BID0gIkFOQS5TRU1JLkFVVEhPUklaQVRJT04uV0lORE9XLlYwMDEiCldJTkRPV19URVNUX1NDSEVNQSA9ICJBTkEuU0VNSS5BVVRIT1JJWkFUSU9OLldJTkRPVy5URVNULlYwMDEiClNFTEVDVE9SX1NDSEVNQSA9ICJBTkEuU0VNSS5QUk9DRVNTLlNFTEVDVE9SLlJFU1VMVC5WMDAxIgpQUkVGTElHSFRfU0NIRU1BID0gIkFOQS5TRU1JLlBSRUNPTlNVTVBUSU9OLlJFU1VMVC5WMDAyIgpUSU1FX1JFID0gcmUuY29tcGlsZShyIl5cZHs0fS1cZHsyfS1cZHsyfVRcZHsyfTpcZHsyfTpcZHsyfVwuXGR7N31bKy1dXGR7Mn06XGR7Mn0kIikKUFJFRkxJR0hUX0tFWVMgPSAoCiAgICAiYXV0aG9yaXphdGlvbl9pZCIsICJhdXRob3JpemVkX2F0X3V0Y190aWNrcyIsICJhdXRob3JpemVkX291dGVyX3N0YXJ0ZWQiLAogICAgImNhbmRpZGF0ZV9ydW5fZXhpc3RzIiwgImNyZWRlbnRpYWxfYWNjZXNzIiwgImRhdGFiYXNlX2Nvbm5lY3Rpb25fcGVyZm9ybWVkIiwKICAgICJleGNlcHRpb25fdHlwZSIsICJleHBpcmVzX2F0X3V0Y190aWNrcyIsICJmaW5pc2hlZF9hdCIsCiAgICAiaGlzdG9yeV9oYXNoX21pc21hdGNoX2NvdW50IiwgImludm9jYXRpb25fY291bnQiLCAibWF0ZXJpYWxpemVkX3RhcmdldF9jb3VudCIsCiAgICAibmV0d29ya19hY2Nlc3MiLCAibm93X3V0Y190aWNrcyIsICJwcmVmbGlnaHRfc3RhZ2UiLCAicmVsYXRlZF9wcm9jZXNzX2NvdW50IiwKICAgICJyZXN1bHRfc2NoZW1hX2lkIiwgInN0YXJ0ZWRfYXQiLCAic3RhdHVzIiwgInN0b3BfY29kZSIsCiAgICAidGFyZ2V0X2V4aXN0aW5nX2NvdW50IiwgInVuY2VydGFpbl9maWVsZCIsCikKCgpkZWYgX3RpY2tzKHZhbHVlOiBkdC5kYXRldGltZSkgLT4gaW50OgogICAgdXRjID0gdmFsdWUuYXN0aW1lem9uZShkdC50aW1lem9uZS51dGMpCiAgICBvcmlnaW4gPSBkdC5kYXRldGltZSgxLCAxLCAxLCB0emluZm89ZHQudGltZXpvbmUudXRjKQogICAgZGVsdGEgPSB1dGMgLSBvcmlnaW4KICAgIHJldHVybiAoKGRlbHRhLmRheXMgKiA4NjQwMCArIGRlbHRhLnNlY29uZHMpICogMTBfMDAwXzAwMCkgKyBkZWx0YS5taWNyb3NlY29uZHMgKiAxMAoKCmRlZiBfcGFyc2Vfb2Zmc2V0KHJhdzogc3RyKSAtPiBkdC5kYXRldGltZToKICAgIGlmIG5vdCBpc2luc3RhbmNlKHJhdywgc3RyKSBvciBUSU1FX1JFLmZ1bGxtYXRjaChyYXcpIGlzIE5vbmU6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigidGltZXN0YW1wLXNoYXBlIikKICAgIHJldHVybiBkdC5kYXRldGltZS5mcm9taXNvZm9ybWF0KHJhdykKCgpkZWYgX3R5cGVkKHR5cGVfbmFtZTogc3RyLCB2YWx1ZXM6IE1hcHBpbmdbc3RyLCBBbnldKSAtPiBkaWN0W3N0ciwgQW55XToKICAgIHJldHVybiB7Il9fdHlwZV9uYW1lX18iOiB0eXBlX25hbWUsICoqdmFsdWVzfQoKCmRlZiBjb252ZXJ0X2F1dGhvcml6YXRpb25fd2luZG93KGF1dGhvcml6ZWRfYXRfcmF3OiBzdHIsIGV4cGlyZXNfYXRfcmF3OiBzdHIpIC0+IGRpY3Rbc3RyLCBBbnldOgogICAgYXV0aG9yaXplZF90aWNrcyA9IE5vbmUKICAgIGV4cGlyZXNfdGlja3MgPSBOb25lCiAgICBzdG9wX2NvZGUgPSBOb25lCiAgICB0cnk6CiAgICAgICAgYXV0aG9yaXplZF90aWNrcyA9IF90aWNrcyhfcGFyc2Vfb2Zmc2V0KGF1dGhvcml6ZWRfYXRfcmF3KSkKICAgIGV4Y2VwdCAoVHlwZUVycm9yLCBWYWx1ZUVycm9yLCBPdmVyZmxvd0Vycm9yKToKICAgICAgICBzdG9wX2NvZGUgPSAiU1RPUF9BVVRIT1JJWkVEX0FUX1BBUlNFIgogICAgaWYgc3RvcF9jb2RlIGlzIE5vbmU6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBleHBpcmVzX3RpY2tzID0gX3RpY2tzKF9wYXJzZV9vZmZzZXQoZXhwaXJlc19hdF9yYXcpKQogICAgICAgIGV4Y2VwdCAoVHlwZUVycm9yLCBWYWx1ZUVycm9yLCBPdmVyZmxvd0Vycm9yKToKICAgICAgICAgICAgc3RvcF9jb2RlID0gIlNUT1BfRVhQSVJFU19BVF9QQVJTRSIKICAgIGlmIHN0b3BfY29kZSBpcyBOb25lIGFuZCBleHBpcmVzX3RpY2tzIDw9IGF1dGhvcml6ZWRfdGlja3M6CiAgICAgICAgc3RvcF9jb2RlID0gIlNUT1BfTk9OX1BPU0lUSVZFX1dJTkRPVyIKICAgIHJldHVybiBfdHlwZWQoV0lORE9XX1NDSEVNQSwgewogICAgICAgICJhdXRob3JpemVkX2F0X3JhdyI6IGF1dGhvcml6ZWRfYXRfcmF3LAogICAgICAgICJhdXRob3JpemVkX2F0X3V0Y190aWNrcyI6IGF1dGhvcml6ZWRfdGlja3MsCiAgICAgICAgImV4cGlyZXNfYXRfcmF3IjogZXhwaXJlc19hdF9yYXcsCiAgICAgICAgImV4cGlyZXNfYXRfdXRjX3RpY2tzIjogZXhwaXJlc190aWNrcywKICAgICAgICAic2NoZW1hX2lkIjogV0lORE9XX1NDSEVNQSwKICAgICAgICAic3RhdHVzIjogIlBBU1MiIGlmIHN0b3BfY29kZSBpcyBOb25lIGVsc2UgIlNUT1AiLAogICAgICAgICJzdG9wX2NvZGUiOiBzdG9wX2NvZGUsCiAgICB9KQoKCmRlZiB0ZXN0X2F1dGhvcml6YXRpb25fd2luZG93KHdpbmRvd19yZXN1bHQ6IE1hcHBpbmdbc3RyLCBBbnldLCBub3c6IGR0LmRhdGV0aW1lKSAtPiBkaWN0W3N0ciwgQW55XToKICAgIGF1dGhvcml6ZWRfdGlja3MgPSBOb25lCiAgICBleHBpcmVzX3RpY2tzID0gTm9uZQogICAgbm93X3RpY2tzID0gTm9uZQogICAgaW5zaWRlID0gTm9uZQogICAgc3RvcF9jb2RlID0gTm9uZQogICAgcmVxdWlyZWQgPSAoCiAgICAgICAgImF1dGhvcml6ZWRfYXRfcmF3IiwgImF1dGhvcml6ZWRfYXRfdXRjX3RpY2tzIiwgImV4cGlyZXNfYXRfcmF3IiwKICAgICAgICAiZXhwaXJlc19hdF91dGNfdGlja3MiLCAic2NoZW1hX2lkIiwgInN0YXR1cyIsICJzdG9wX2NvZGUiLAogICAgKQogICAgdHJ5OgogICAgICAgIGlmIHdpbmRvd19yZXN1bHQuZ2V0KCJfX3R5cGVfbmFtZV9fIikgIT0gV0lORE9XX1NDSEVNQToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigidHlwZSIpCiAgICAgICAgaWYgdHVwbGUoayBmb3IgayBpbiB3aW5kb3dfcmVzdWx0IGlmIGsgIT0gIl9fdHlwZV9uYW1lX18iKSAhPSByZXF1aXJlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigia2V5cyIpCiAgICAgICAgaWYgd2luZG93X3Jlc3VsdFsic3RhdHVzIl0gIT0gIlBBU1MiOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJzdGF0dXMiKQogICAgICAgIGF1dGhvcml6ZWRfdGlja3MgPSBpbnQod2luZG93X3Jlc3VsdFsiYXV0aG9yaXplZF9hdF91dGNfdGlja3MiXSkKICAgICAgICBleHBpcmVzX3RpY2tzID0gaW50KHdpbmRvd19yZXN1bHRbImV4cGlyZXNfYXRfdXRjX3RpY2tzIl0pCiAgICBleGNlcHQgKEtleUVycm9yLCBUeXBlRXJyb3IsIFZhbHVlRXJyb3IpOgogICAgICAgIHN0b3BfY29kZSA9ICJTVE9QX1dJTkRPV19JTlBVVF9DT05UUkFDVCIKICAgIGlmIHN0b3BfY29kZSBpcyBOb25lOgogICAgICAgIHRyeToKICAgICAgICAgICAgbm93X3RpY2tzID0gX3RpY2tzKG5vdykKICAgICAgICAgICAgaW5zaWRlID0gYXV0aG9yaXplZF90aWNrcyA8PSBub3dfdGlja3MgPCBleHBpcmVzX3RpY2tzCiAgICAgICAgZXhjZXB0IChUeXBlRXJyb3IsIFZhbHVlRXJyb3IsIE92ZXJmbG93RXJyb3IpOgogICAgICAgICAgICBzdG9wX2NvZGUgPSAiU1RPUF9OT1dfQ09OVkVSU0lPTiIKICAgIHJldHVybiBfdHlwZWQoV0lORE9XX1RFU1RfU0NIRU1BLCB7CiAgICAgICAgImF1dGhvcml6ZWRfYXRfdXRjX3RpY2tzIjogYXV0aG9yaXplZF90aWNrcywKICAgICAgICAiZXhwaXJlc19hdF91dGNfdGlja3MiOiBleHBpcmVzX3RpY2tzLAogICAgICAgICJpbnNpZGVfd2luZG93IjogaW5zaWRlLAogICAgICAgICJub3dfdXRjX3RpY2tzIjogbm93X3RpY2tzLAogICAgICAgICJzY2hlbWFfaWQiOiBXSU5ET1dfVEVTVF9TQ0hFTUEsCiAgICAgICAgInN0YXR1cyI6ICJQQVNTIiBpZiBzdG9wX2NvZGUgaXMgTm9uZSBlbHNlICJTVE9QIiwKICAgICAgICAic3RvcF9jb2RlIjogc3RvcF9jb2RlLAogICAgfSkKCgpkZWYgX3NoYTI1NihkYXRhOiBieXRlcykgLT4gc3RyOgogICAgcmV0dXJuIGhhc2hsaWIuc2hhMjU2KGRhdGEpLmhleGRpZ2VzdCgpCgoKZGVmIHNlbGVjdF9leGFjdF9yZWxhdGVkX3Byb2Nlc3MoCiAgICBzbmFwc2hvdF9yb3dzOiBTZXF1ZW5jZVtNYXBwaW5nW3N0ciwgQW55XV0sCiAgICBleHBlY3RlZF9vdXRlcl9leGVjdXRhYmxlX3BhdGg6IHN0ciwKICAgIGV4cGVjdGVkX291dGVyX2NvbW1hbmRfbGluZV9zaGEyNTY6IHN0ciwKICAgIGV4cGVjdGVkX291dGVyX2NvbW1hbmRfbGluZV9iYXNlNjQ6IHN0ciwKICAgIHNvdXJjZV9wcmVmbGlnaHRfcHJvY2Vzc19pZDogaW50LAogICAgcHJvaGliaXRlZF9leGVjdXRhYmxlX3BhdGhzOiBTZXF1ZW5jZVtzdHJdLAopIC0+IGRpY3Rbc3RyLCBBbnldOgogICAgY29uZmlybWVkX3plcm8gPSBOb25lCiAgICBkdXBsaWNhdGVfY291bnQgPSBOb25lCiAgICBleGFjdF9jb3VudCA9IE5vbmUKICAgIG1hdGNoZWRfaWRzID0gTm9uZQogICAgcHJvaGliaXRlZF9jb3VudCA9IE5vbmUKICAgIHJlbGF0ZWRfY291bnQgPSBOb25lCiAgICByb3dfY291bnQgPSBOb25lCiAgICB1bmNlcnRhaW5fZmllbGRzID0gTm9uZQogICAgdW5rbm93bl9jb3VudCA9IE5vbmUKICAgIHN0b3BfY29kZSA9IE5vbmUKICAgIGRlY29kZWQgPSBOb25lCiAgICB0cnk6CiAgICAgICAgZW5jb2RlZCA9IGJhc2U2NC5iNjRkZWNvZGUoZXhwZWN0ZWRfb3V0ZXJfY29tbWFuZF9saW5lX2Jhc2U2NCwgdmFsaWRhdGU9VHJ1ZSkKICAgICAgICBpZiBiYXNlNjQuYjY0ZW5jb2RlKGVuY29kZWQpLmRlY29kZSgiYXNjaWkiKSAhPSBleHBlY3RlZF9vdXRlcl9jb21tYW5kX2xpbmVfYmFzZTY0OgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJiYXNlNjQiKQogICAgICAgIGRlY29kZWQgPSBlbmNvZGVkLmRlY29kZSgidXRmLTgiLCBlcnJvcnM9InN0cmljdCIpCiAgICAgICAgaWYgX3NoYTI1NihlbmNvZGVkKSAhPSBleHBlY3RlZF9vdXRlcl9jb21tYW5kX2xpbmVfc2hhMjU2OgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJoYXNoIikKICAgICAgICBpZiBub3QgZGVjb2RlZC5zdGFydHN3aXRoKGV4cGVjdGVkX291dGVyX2V4ZWN1dGFibGVfcGF0aCArICIgIik6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImNvb3JkaW5hdGUiKQogICAgZXhjZXB0IChWYWx1ZUVycm9yLCBVbmljb2RlRXJyb3IpOgogICAgICAgIHVuY2VydGFpbl9maWVsZHMgPSBbImV4cGVjdGVkX2NvbW1hbmRfbGluZSJdCiAgICAgICAgc3RvcF9jb2RlID0gIlNUT1BfRVhQRUNURURfQ09NTUFORExJTkVfQ09OVFJBQ1QiCiAgICBpZiBzdG9wX2NvZGUgaXMgTm9uZToKICAgICAgICByb3dfY291bnQgPSBsZW4oc25hcHNob3Rfcm93cykKICAgICAgICBpZHM6IHNldFtpbnRdID0gc2V0KCkKICAgICAgICBkdXBsaWNhdGVzID0gMAogICAgICAgIGZvciByb3cgaW4gc25hcHNob3Rfcm93czoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgcHJvY2Vzc19pZCA9IGludChyb3dbInByb2Nlc3NfaWQiXSkKICAgICAgICAgICAgZXhjZXB0IChLZXlFcnJvciwgVHlwZUVycm9yLCBWYWx1ZUVycm9yKToKICAgICAgICAgICAgICAgIHVuY2VydGFpbl9maWVsZHMgPSBbInByb2Nlc3NfaWQiXQogICAgICAgICAgICAgICAgc3RvcF9jb2RlID0gIlNUT1BfU05BUFNIT1RfQ09OVFJBQ1QiCiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZiBwcm9jZXNzX2lkIGluIGlkczoKICAgICAgICAgICAgICAgIGR1cGxpY2F0ZXMgKz0gMQogICAgICAgICAgICBpZHMuYWRkKHByb2Nlc3NfaWQpCiAgICAgICAgZHVwbGljYXRlX2NvdW50ID0gZHVwbGljYXRlcwogICAgICAgIGlmIHN0b3BfY29kZSBpcyBOb25lIGFuZCBkdXBsaWNhdGVzOgogICAgICAgICAgICBzdG9wX2NvZGUgPSAiU1RPUF9EVVBMSUNBVEVfUFJPQ0VTU19JRCIKICAgIGlmIHN0b3BfY29kZSBpcyBOb25lOgogICAgICAgIGV4YWN0X2lkczogbGlzdFtpbnRdID0gW10KICAgICAgICBwcm9oaWJpdGVkX2lkczogbGlzdFtpbnRdID0gW10KICAgICAgICB1bmtub3duOiBsaXN0W3N0cl0gPSBbXQogICAgICAgIHByb2hpYml0ZWRfbm9ybSA9IHtvcy5wYXRoLm5vcm1jYXNlKG9zLnBhdGguYWJzcGF0aChwKSkgZm9yIHAgaW4gcHJvaGliaXRlZF9leGVjdXRhYmxlX3BhdGhzfQogICAgICAgIGV4cGVjdGVkX25vcm0gPSBvcy5wYXRoLm5vcm1jYXNlKG9zLnBhdGguYWJzcGF0aChleHBlY3RlZF9vdXRlcl9leGVjdXRhYmxlX3BhdGgpKQogICAgICAgIGZvciByb3cgaW4gc25hcHNob3Rfcm93czoKICAgICAgICAgICAgcHJvY2Vzc19pZCA9IGludChyb3dbInByb2Nlc3NfaWQiXSkKICAgICAgICAgICAgaWYgcHJvY2Vzc19pZCA9PSBpbnQoc291cmNlX3ByZWZsaWdodF9wcm9jZXNzX2lkKToKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIHBhdGggPSByb3cuZ2V0KCJleGVjdXRhYmxlX3BhdGgiKQogICAgICAgICAgICBjb21tYW5kX2xpbmUgPSByb3cuZ2V0KCJjb21tYW5kX2xpbmUiKQogICAgICAgICAgICBuYW1lID0gcm93LmdldCgibmFtZSIpCiAgICAgICAgICAgIG5vcm0gPSBvcy5wYXRoLm5vcm1jYXNlKG9zLnBhdGguYWJzcGF0aChwYXRoKSkgaWYgaXNpbnN0YW5jZShwYXRoLCBzdHIpIGVsc2UgTm9uZQogICAgICAgICAgICBpc19leHBlY3RlZCA9IG5vcm0gPT0gZXhwZWN0ZWRfbm9ybQogICAgICAgICAgICBpc19wcm9oaWJpdGVkID0gbm9ybSBpbiBwcm9oaWJpdGVkX25vcm0KICAgICAgICAgICAgcmVsZXZhbnRfbmFtZSA9IGlzaW5zdGFuY2UobmFtZSwgc3RyKSBhbmQgbmFtZS5sb3dlcigpIGluIHsKICAgICAgICAgICAgICAgICJwb3dlcnNoZWxsIiwgInBvd2Vyc2hlbGwuZXhlIiwgInB5dGhvbiIsICJweXRob24uZXhlIiwgImNzYyIsICJjc2MuZXhlIiwKICAgICAgICAgICAgICAgICJteXNxbCIsICJteXNxbC5leGUiLCAibXlzcWxfY29uZmlnX2VkaXRvciIsICJteXNxbF9jb25maWdfZWRpdG9yLmV4ZSIsCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzX2V4cGVjdGVkIG9yIGlzX3Byb2hpYml0ZWQgb3IgcmVsZXZhbnRfbmFtZSkgYW5kICgKICAgICAgICAgICAgICAgIHBhdGggaXMgTm9uZSBvciBuYW1lIGlzIE5vbmUgb3IgKGlzX2V4cGVjdGVkIGFuZCBjb21tYW5kX2xpbmUgaXMgTm9uZSkKICAgICAgICAgICAgKToKICAgICAgICAgICAgICAgIHVua25vd24uYXBwZW5kKGYicGlkOntwcm9jZXNzX2lkfSIpCiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBpZiBpc19leHBlY3RlZCBhbmQgY29tbWFuZF9saW5lID09IGRlY29kZWQ6CiAgICAgICAgICAgICAgICBleGFjdF9pZHMuYXBwZW5kKHByb2Nlc3NfaWQpCiAgICAgICAgICAgIGlmIGlzX3Byb2hpYml0ZWQ6CiAgICAgICAgICAgICAgICBwcm9oaWJpdGVkX2lkcy5hcHBlbmQocHJvY2Vzc19pZCkKICAgICAgICBleGFjdF9jb3VudCA9IGxlbihleGFjdF9pZHMpCiAgICAgICAgcHJvaGliaXRlZF9jb3VudCA9IGxlbihwcm9oaWJpdGVkX2lkcykKICAgICAgICB1bmtub3duX2NvdW50ID0gbGVuKHVua25vd24pCiAgICAgICAgbWF0Y2hlZF9pZHMgPSBzb3J0ZWQoc2V0KGV4YWN0X2lkcyArIHByb2hpYml0ZWRfaWRzKSkKICAgICAgICByZWxhdGVkX2NvdW50ID0gbGVuKG1hdGNoZWRfaWRzKQogICAgICAgIGlmIHVua25vd246CiAgICAgICAgICAgIHVuY2VydGFpbl9maWVsZHMgPSBzb3J0ZWQodW5rbm93bikKICAgICAgICAgICAgc3RvcF9jb2RlID0gIlNUT1BfUkVMRVZBTlRfUFJPQ0VTU19GSUVMRF9VTktOT1dOIgogICAgICAgIGVsaWYgZXhhY3RfY291bnQgPiAxOgogICAgICAgICAgICBjb25maXJtZWRfemVybyA9IEZhbHNlCiAgICAgICAgICAgIHN0b3BfY29kZSA9ICJTVE9QX01VTFRJUExFX0VYQUNUX09VVEVSIgogICAgICAgIGVsaWYgZXhhY3RfY291bnQgPT0gMSBvciBwcm9oaWJpdGVkX2NvdW50OgogICAgICAgICAgICBjb25maXJtZWRfemVybyA9IEZhbHNlCiAgICAgICAgICAgIHN0b3BfY29kZSA9ICJTVE9QX1BST0NFU1NfUFJFU0VOVCIKICAgICAgICBlbHNlOgogICAgICAgICAgICBjb25maXJtZWRfemVybyA9IFRydWUKICAgICAgICAgICAgbWF0Y2hlZF9pZHMgPSBbXQogICAgICAgICAgICByZWxhdGVkX2NvdW50ID0gMAogICAgcmV0dXJuIF90eXBlZChTRUxFQ1RPUl9TQ0hFTUEsIHsKICAgICAgICAiY29uZmlybWVkX3plcm8iOiBjb25maXJtZWRfemVybywKICAgICAgICAiZHVwbGljYXRlX3Byb2Nlc3NfaWRfY291bnQiOiBkdXBsaWNhdGVfY291bnQsCiAgICAgICAgImV4YWN0X291dGVyX2NvdW50IjogZXhhY3RfY291bnQsCiAgICAgICAgIm1hdGNoZWRfcHJvY2Vzc19pZHMiOiBtYXRjaGVkX2lkcywKICAgICAgICAicHJvaGliaXRlZF9wcm9jZXNzX2NvdW50IjogcHJvaGliaXRlZF9jb3VudCwKICAgICAgICAicmVsYXRlZF9wcm9jZXNzX2NvdW50IjogcmVsYXRlZF9jb3VudCwKICAgICAgICAic2NoZW1hX2lkIjogU0VMRUNUT1JfU0NIRU1BLAogICAgICAgICJzbmFwc2hvdF9yb3dfY291bnQiOiByb3dfY291bnQsCiAgICAgICAgInN0YXR1cyI6ICJQQVNTIiBpZiBzdG9wX2NvZGUgaXMgTm9uZSBlbHNlICJTVE9QIiwKICAgICAgICAic3RvcF9jb2RlIjogc3RvcF9jb2RlLAogICAgICAgICJ1bmNlcnRhaW5fZmllbGRzIjogdW5jZXJ0YWluX2ZpZWxkcywKICAgICAgICAidW5rbm93bl9yZWxldmFudF9jb3VudCI6IHVua25vd25fY291bnQsCiAgICB9KQoKCmNsYXNzIEludm9jYXRpb25HYXRlOgogICAgZGVmIF9faW5pdF9fKHNlbGYpIC0+IE5vbmU6CiAgICAgICAgc2VsZi5fbG9jayA9IHRocmVhZGluZy5Mb2NrKCkKICAgICAgICBzZWxmLl91c2VkID0gRmFsc2UKCiAgICBkZWYgYWNxdWlyZV9vbmNlKHNlbGYpIC0+IGJvb2w6CiAgICAgICAgd2l0aCBzZWxmLl9sb2NrOgogICAgICAgICAgICBpZiBzZWxmLl91c2VkOgogICAgICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgICAgIHNlbGYuX3VzZWQgPSBUcnVlCiAgICAgICAgICAgIHJldHVybiBUcnVlCgoKZGVmIF9wcmVmbGlnaHQodmFsdWVzOiBNYXBwaW5nW3N0ciwgQW55XSkgLT4gZGljdFtzdHIsIEFueV06CiAgICByb3cgPSB7a2V5OiB2YWx1ZXMuZ2V0KGtleSkgZm9yIGtleSBpbiBQUkVGTElHSFRfS0VZU30KICAgIHJldHVybiBfdHlwZWQoUFJFRkxJR0hUX1NDSEVNQSwgcm93KQoKCmRlZiBfcHJvdmlkZXIocHJvdmlkZXI6IENhbGxhYmxlW1tdLCBBbnldLCB0eXBlX25hbWU6IHN0ciwgbmFtZXM6IHR1cGxlW3N0ciwgLi4uXSkgLT4gTWFwcGluZ1tzdHIsIEFueV06CiAgICB2YWx1ZSA9IHByb3ZpZGVyKCkKICAgIGlmIG5vdCBpc2luc3RhbmNlKHZhbHVlLCBNYXBwaW5nKSBvciB2YWx1ZS5nZXQoIl9fdHlwZV9uYW1lX18iKSAhPSB0eXBlX25hbWU6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigicHJvdmlkZXItdHlwZSIpCiAgICBpZiB0dXBsZShrIGZvciBrIGluIHZhbHVlIGlmIGsgIT0gIl9fdHlwZV9uYW1lX18iKSAhPSBuYW1lczoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJwcm92aWRlci1rZXlzIikKICAgIHJldHVybiB2YWx1ZQoKCmRlZiBpbnZva2VfcHJlY29uc3VtcHRpb25fcHJlZmxpZ2h0KAogICAgKiwgYXV0aG9yaXphdGlvbl9pZDogc3RyLCBhdXRob3JpemVkX2F0X3Jhdzogc3RyLCBleHBpcmVzX2F0X3Jhdzogc3RyLAogICAgZXhwZWN0ZWRfcGxhbl9ieXRlczogaW50LCBleHBlY3RlZF9wbGFuX3NoYTI1Njogc3RyLAogICAgZXhwZWN0ZWRfb3V0ZXJfZXhlY3V0YWJsZV9wYXRoOiBzdHIsIGV4cGVjdGVkX291dGVyX2NvbW1hbmRfbGluZV9zaGEyNTY6IHN0ciwKICAgIGV4cGVjdGVkX291dGVyX2NvbW1hbmRfbGluZV9iYXNlNjQ6IHN0ciwgc291cmNlX3ByZWZsaWdodF9wcm9jZXNzX2lkOiBpbnQsCiAgICBwcm9oaWJpdGVkX2V4ZWN1dGFibGVfcGF0aHM6IFNlcXVlbmNlW3N0cl0sIGludm9jYXRpb25fZ2F0ZTogSW52b2NhdGlvbkdhdGUsCiAgICBub3dfcHJvdmlkZXI6IENhbGxhYmxlW1tdLCBkdC5kYXRldGltZV0sIGlkZW50aXR5X3Byb3ZpZGVyOiBDYWxsYWJsZVtbXSwgQW55XSwKICAgIHBsYW5faGFzaF9wcm92aWRlcjogQ2FsbGFibGVbW10sIEFueV0sIHRhcmdldF9zdGF0ZV9wcm92aWRlcjogQ2FsbGFibGVbW10sIEFueV0sCiAgICBoaXN0b3J5X3Byb3ZpZGVyOiBDYWxsYWJsZVtbXSwgQW55XSwgcHJvY2Vzc19zbmFwc2hvdF9wcm92aWRlcjogQ2FsbGFibGVbW10sIEFueV0sCikgLT4gZGljdFtzdHIsIEFueV06CiAgICBpZiBub3QgaW52b2NhdGlvbl9nYXRlLmFjcXVpcmVfb25jZSgpOgogICAgICAgIHJldHVybiBfcHJlZmxpZ2h0KHsiYXV0aG9yaXphdGlvbl9pZCI6IGF1dGhvcml6YXRpb25faWQsICJwcmVmbGlnaHRfc3RhZ2UiOiAiU1RBUlQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAicmVzdWx0X3NjaGVtYV9pZCI6IFBSRUZMSUdIVF9TQ0hFTUEsICJzdGF0dXMiOiAiU1RPUCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdG9wX2NvZGUiOiAiU1RPUF9QUkVDT05TVU1QVElPTl9BTFJFQURZX0lOVk9LRUQifSkKICAgIHZhbHVlczogZGljdFtzdHIsIEFueV0gPSB7CiAgICAgICAgImF1dGhvcml6YXRpb25faWQiOiBhdXRob3JpemF0aW9uX2lkLCAiYXV0aG9yaXplZF9vdXRlcl9zdGFydGVkIjogRmFsc2UsCiAgICAgICAgImNyZWRlbnRpYWxfYWNjZXNzIjogRmFsc2UsICJkYXRhYmFzZV9jb25uZWN0aW9uX3BlcmZvcm1lZCI6IEZhbHNlLAogICAgICAgICJpbnZvY2F0aW9uX2NvdW50IjogMSwgIm5ldHdvcmtfYWNjZXNzIjogRmFsc2UsICJwcmVmbGlnaHRfc3RhZ2UiOiAiU1RBUlQiLAogICAgICAgICJyZXN1bHRfc2NoZW1hX2lkIjogUFJFRkxJR0hUX1NDSEVNQSwgInN0YXR1cyI6ICJTVE9QIiwKICAgIH0KICAgIHRyeToKICAgICAgICB2YWx1ZXNbInByZWZsaWdodF9zdGFnZSJdID0gIklERU5USVRZIgogICAgICAgIGlkZW50aXR5ID0gX3Byb3ZpZGVyKGlkZW50aXR5X3Byb3ZpZGVyLCAiQU5BLlNFTUkuUFJFRkxJR0hULklERU5USVRZLlYwMDEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICgiY3dkIiwgImhvc3QiLCAicm9sZV9pbnN0YW5jZV9pZCIsICJzY2hlbWFfaWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic291cmNlX3RocmVhZF9pZCIsICJzdGF0dXMiLCAidW5jZXJ0YWluX2ZpZWxkcyIpKQogICAgICAgIGlmIGlkZW50aXR5WyJzdGF0dXMiXSAhPSAiUEFTUyI6CiAgICAgICAgICAgIHZhbHVlc1sidW5jZXJ0YWluX2ZpZWxkIl0gPSAiLCIuam9pbihpZGVudGl0eS5nZXQoInVuY2VydGFpbl9maWVsZHMiKSBvciBbXSkgb3IgTm9uZQogICAgICAgICAgICB2YWx1ZXNbInN0b3BfY29kZSJdID0gIlNUT1BfUFJFQ09OU1VNUFRJT05fU1RBVEVfVU5DRVJUQUlOIiBpZiBpZGVudGl0eVsic3RhdHVzIl0gPT0gIlVOS05PV04iIGVsc2UgIlNUT1BfUFJFQ09OU1VNUFRJT05fR0FURV9NSVNNQVRDSCIKICAgICAgICAgICAgcmV0dXJuIF9wcmVmbGlnaHQodmFsdWVzKQogICAgICAgIHZhbHVlc1sicHJlZmxpZ2h0X3N0YWdlIl0gPSAiV0lORE9XX1BBUlNFIgogICAgICAgIHdpbmRvdyA9IGNvbnZlcnRfYXV0aG9yaXphdGlvbl93aW5kb3coYXV0aG9yaXplZF9hdF9yYXcsIGV4cGlyZXNfYXRfcmF3KQogICAgICAgIHZhbHVlc1siYXV0aG9yaXplZF9hdF91dGNfdGlja3MiXSA9IHdpbmRvd1siYXV0aG9yaXplZF9hdF91dGNfdGlja3MiXQogICAgICAgIHZhbHVlc1siZXhwaXJlc19hdF91dGNfdGlja3MiXSA9IHdpbmRvd1siZXhwaXJlc19hdF91dGNfdGlja3MiXQogICAgICAgIGlmIHdpbmRvd1sic3RhdHVzIl0gIT0gIlBBU1MiOgogICAgICAgICAgICB2YWx1ZXNbInN0b3BfY29kZSJdID0gIlNUT1BfUFJFQ09OU1VNUFRJT05fR0FURV9NSVNNQVRDSCIKICAgICAgICAgICAgcmV0dXJuIF9wcmVmbGlnaHQodmFsdWVzKQogICAgICAgIHZhbHVlc1sicHJlZmxpZ2h0X3N0YWdlIl0gPSAiQ0xPQ0siCiAgICAgICAgbm93ID0gbm93X3Byb3ZpZGVyKCkKICAgICAgICBpZiBub3QgaXNpbnN0YW5jZShub3csIGR0LmRhdGV0aW1lKSBvciBub3cudHppbmZvIGlzIE5vbmU6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImNsb2NrLXR5cGUiKQogICAgICAgIHN0YW1wID0gbm93LmFzdGltZXpvbmUoZHQudGltZXpvbmUudXRjKS5pc29mb3JtYXQodGltZXNwZWM9Im1pY3Jvc2Vjb25kcyIpLnJlcGxhY2UoIiswMDowMCIsICJaIikKICAgICAgICB2YWx1ZXNbIm5vd191dGNfdGlja3MiXSA9IF90aWNrcyhub3cpCiAgICAgICAgdmFsdWVzWyJzdGFydGVkX2F0Il0gPSBzdGFtcAogICAgICAgIHZhbHVlc1siZmluaXNoZWRfYXQiXSA9IHN0YW1wCiAgICAgICAgdmFsdWVzWyJwcmVmbGlnaHRfc3RhZ2UiXSA9ICJXSU5ET1dfVEVTVCIKICAgICAgICB3aW5kb3dfdGVzdCA9IHRlc3RfYXV0aG9yaXphdGlvbl93aW5kb3cod2luZG93LCBub3cpCiAgICAgICAgaWYgd2luZG93X3Rlc3RbInN0YXR1cyJdICE9ICJQQVNTIiBvciBub3Qgd2luZG93X3Rlc3RbImluc2lkZV93aW5kb3ciXToKICAgICAgICAgICAgdmFsdWVzWyJzdG9wX2NvZGUiXSA9ICJTVE9QX1BSRUNPTlNVTVBUSU9OX0dBVEVfTUlTTUFUQ0giCiAgICAgICAgICAgIHJldHVybiBfcHJlZmxpZ2h0KHZhbHVlcykKICAgICAgICB2YWx1ZXNbInByZWZsaWdodF9zdGFnZSJdID0gIlBMQU5fSEFTSCIKICAgICAgICBwbGFuID0gX3Byb3ZpZGVyKHBsYW5faGFzaF9wcm92aWRlciwgIkFOQS5TRU1JLlBSRUZMSUdIVC5QTEFOSEFTSC5WMDAxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICgiYnl0ZXMiLCAic2NoZW1hX2lkIiwgInNoYTI1NiIsICJzdGF0dXMiLCAidW5jZXJ0YWluX2ZpZWxkcyIpKQogICAgICAgIGlmIHBsYW5bInN0YXR1cyJdICE9ICJQQVNTIiBvciBpbnQocGxhblsiYnl0ZXMiXSkgIT0gZXhwZWN0ZWRfcGxhbl9ieXRlcyBvciBwbGFuWyJzaGEyNTYiXSAhPSBleHBlY3RlZF9wbGFuX3NoYTI1NjoKICAgICAgICAgICAgdmFsdWVzWyJzdG9wX2NvZGUiXSA9ICJTVE9QX1BSRUNPTlNVTVBUSU9OX0dBVEVfTUlTTUFUQ0giCiAgICAgICAgICAgIHJldHVybiBfcHJlZmxpZ2h0KHZhbHVlcykKICAgICAgICB2YWx1ZXNbInByZWZsaWdodF9zdGFnZSJdID0gIlRBUkdFVF9TVEFURSIKICAgICAgICB0YXJnZXQgPSBfcHJvdmlkZXIodGFyZ2V0X3N0YXRlX3Byb3ZpZGVyLCAiQU5BLlNFTUkuUFJFRkxJR0hULlRBUkdFVFNUQVRFLlYwMDEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAoImNhbmRpZGF0ZV9ydW5fZXhpc3RzIiwgIm1hdGVyaWFsaXplZF90YXJnZXRfY291bnQiLCAic2NoZW1hX2lkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdGF0dXMiLCAidGFyZ2V0X2V4aXN0aW5nX2NvdW50IiwgInVuY2VydGFpbl9maWVsZHMiKSkKICAgICAgICB2YWx1ZXNbImNhbmRpZGF0ZV9ydW5fZXhpc3RzIl0gPSB0YXJnZXRbImNhbmRpZGF0ZV9ydW5fZXhpc3RzIl0KICAgICAgICB2YWx1ZXNbIm1hdGVyaWFsaXplZF90YXJnZXRfY291bnQiXSA9IHRhcmdldFsibWF0ZXJpYWxpemVkX3RhcmdldF9jb3VudCJdCiAgICAgICAgdmFsdWVzWyJ0YXJnZXRfZXhpc3RpbmdfY291bnQiXSA9IHRhcmdldFsidGFyZ2V0X2V4aXN0aW5nX2NvdW50Il0KICAgICAgICBpZiB0YXJnZXRbInN0YXR1cyJdICE9ICJQQVNTIjoKICAgICAgICAgICAgdmFsdWVzWyJzdG9wX2NvZGUiXSA9ICJTVE9QX1BSRUNPTlNVTVBUSU9OX1NUQVRFX1VOQ0VSVEFJTiIgaWYgdGFyZ2V0WyJzdGF0dXMiXSA9PSAiVU5LTk9XTiIgZWxzZSAiU1RPUF9QUkVDT05TVU1QVElPTl9HQVRFX01JU01BVENIIgogICAgICAgICAgICByZXR1cm4gX3ByZWZsaWdodCh2YWx1ZXMpCiAgICAgICAgdmFsdWVzWyJwcmVmbGlnaHRfc3RhZ2UiXSA9ICJISVNUT1JZIgogICAgICAgIGhpc3RvcnkgPSBfcHJvdmlkZXIoaGlzdG9yeV9wcm92aWRlciwgIkFOQS5TRU1JLlBSRUZMSUdIVC5ISVNUT1JZLlYwMDEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKCJoaXN0b3J5X2hhc2hfbWlzbWF0Y2hfY291bnQiLCAic2NoZW1hX2lkIiwgInN0YXR1cyIsICJ1bmNlcnRhaW5fZmllbGRzIikpCiAgICAgICAgdmFsdWVzWyJoaXN0b3J5X2hhc2hfbWlzbWF0Y2hfY291bnQiXSA9IGhpc3RvcnlbImhpc3RvcnlfaGFzaF9taXNtYXRjaF9jb3VudCJdCiAgICAgICAgaWYgaGlzdG9yeVsic3RhdHVzIl0gIT0gIlBBU1MiOgogICAgICAgICAgICB2YWx1ZXNbInN0b3BfY29kZSJdID0gIlNUT1BfUFJFQ09OU1VNUFRJT05fU1RBVEVfVU5DRVJUQUlOIiBpZiBoaXN0b3J5WyJzdGF0dXMiXSA9PSAiVU5LTk9XTiIgZWxzZSAiU1RPUF9QUkVDT05TVU1QVElPTl9HQVRFX01JU01BVENIIgogICAgICAgICAgICByZXR1cm4gX3ByZWZsaWdodCh2YWx1ZXMpCiAgICAgICAgdmFsdWVzWyJwcmVmbGlnaHRfc3RhZ2UiXSA9ICJQUk9DRVNTX1NOQVBTSE9UIgogICAgICAgIHNuYXBzaG90ID0gX3Byb3ZpZGVyKHByb2Nlc3Nfc25hcHNob3RfcHJvdmlkZXIsICJBTkEuU0VNSS5QUkVGTElHSFQuU05BUFNIT1QuVjAwMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCJhZGFwdGVyX3N0YXR1cyIsICJyb3dzIiwgInNjaGVtYV9pZCIsICJzbmFwc2hvdF9pZCIsICJ1bmNlcnRhaW5fZmllbGRzIikpCiAgICAgICAgaWYgc25hcHNob3RbImFkYXB0ZXJfc3RhdHVzIl0gIT0gIlBBU1MiOgogICAgICAgICAgICB2YWx1ZXNbInN0b3BfY29kZSJdID0gIlNUT1BfUFJFQ09OU1VNUFRJT05fU1RBVEVfVU5DRVJUQUlOIgogICAgICAgICAgICByZXR1cm4gX3ByZWZsaWdodCh2YWx1ZXMpCiAgICAgICAgdmFsdWVzWyJwcmVmbGlnaHRfc3RhZ2UiXSA9ICJQUk9DRVNTX1NFTEVDVCIKICAgICAgICBzZWxlY3Rpb24gPSBzZWxlY3RfZXhhY3RfcmVsYXRlZF9wcm9jZXNzKAogICAgICAgICAgICBzbmFwc2hvdFsicm93cyJdLCBleHBlY3RlZF9vdXRlcl9leGVjdXRhYmxlX3BhdGgsCiAgICAgICAgICAgIGV4cGVjdGVkX291dGVyX2NvbW1hbmRfbGluZV9zaGEyNTYsIGV4cGVjdGVkX291dGVyX2NvbW1hbmRfbGluZV9iYXNlNjQsCiAgICAgICAgICAgIHNvdXJjZV9wcmVmbGlnaHRfcHJvY2Vzc19pZCwgcHJvaGliaXRlZF9leGVjdXRhYmxlX3BhdGhzLAogICAgICAgICkKICAgICAgICB2YWx1ZXNbInJlbGF0ZWRfcHJvY2Vzc19jb3VudCJdID0gc2VsZWN0aW9uWyJyZWxhdGVkX3Byb2Nlc3NfY291bnQiXQogICAgICAgIGlmIHNlbGVjdGlvblsic3RhdHVzIl0gIT0gIlBBU1MiOgogICAgICAgICAgICB2YWx1ZXNbInVuY2VydGFpbl9maWVsZCJdID0gIiwiLmpvaW4oc2VsZWN0aW9uLmdldCgidW5jZXJ0YWluX2ZpZWxkcyIpIG9yIFtdKSBvciBOb25lCiAgICAgICAgICAgIHZhbHVlc1sic3RvcF9jb2RlIl0gPSAiU1RPUF9QUkVDT05TVU1QVElPTl9TVEFURV9VTkNFUlRBSU4iIGlmIHNlbGVjdGlvbi5nZXQoInVuY2VydGFpbl9maWVsZHMiKSBlbHNlICJTVE9QX1BSRUNPTlNVTVBUSU9OX0dBVEVfTUlTTUFUQ0giCiAgICAgICAgICAgIHJldHVybiBfcHJlZmxpZ2h0KHZhbHVlcykKICAgICAgICB2YWx1ZXNbInByZWZsaWdodF9zdGFnZSJdID0gIlBBU1MiCiAgICAgICAgdmFsdWVzWyJzdGF0dXMiXSA9ICJQQVNTIgogICAgICAgIHZhbHVlc1sic3RvcF9jb2RlIl0gPSBOb25lCiAgICAgICAgcmV0dXJuIF9wcmVmbGlnaHQodmFsdWVzKQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBleGM6CiAgICAgICAgdmFsdWVzWyJleGNlcHRpb25fdHlwZSJdID0gdHlwZShleGMpLl9fbmFtZV9fCiAgICAgICAgdmFsdWVzWyJzdG9wX2NvZGUiXSA9ICJTVE9QX1BSRUNPTlNVTVBUSU9OX1BSRUZMSUdIVF9FWENFUFRJT04iCiAgICAgICAgcmV0dXJuIF9wcmVmbGlnaHQodmFsdWVzKQoKCmRlZiBjYW5vbmljYWxfanNvbl9ieXRlcyh2YWx1ZTogQW55KSAtPiBieXRlczoKICAgIHJldHVybiBqc29uLmR1bXBzKHZhbHVlLCBlbnN1cmVfYXNjaWk9RmFsc2UsIHNlcGFyYXRvcnM9KCIsIiwgIjoiKSwgc29ydF9rZXlzPVRydWUpLmVuY29kZSgidXRmLTgiKQoKCmRlZiB3cml0ZV9jcmVhdGVfbmV3X2J5dGVzKHBhdGg6IHBhdGhsaWIuUGF0aCwgZGF0YTogYnl0ZXMpIC0+IE5vbmU6CiAgICBwYXRoID0gcGF0aC5yZXNvbHZlKHN0cmljdD1GYWxzZSkKICAgIGlmIHBhdGguZXhpc3RzKCkgb3IgcGF0aC5pc19zeW1saW5rKCk6CiAgICAgICAgcmFpc2UgRmlsZUV4aXN0c0Vycm9yKHN0cihwYXRoKSkKICAgIHdpdGggcGF0aC5vcGVuKCJ4YiIpIGFzIHN0cmVhbToKICAgICAgICB3cml0dGVuID0gc3RyZWFtLndyaXRlKGRhdGEpCiAgICAgICAgaWYgd3JpdHRlbiAhPSBsZW4oZGF0YSk6CiAgICAgICAgICAgIHJhaXNlIE9TRXJyb3IoInBhcnRpYWwtd3JpdGUiKQogICAgICAgIHN0cmVhbS5mbHVzaCgpCiAgICAgICAgb3MuZnN5bmMoc3RyZWFtLmZpbGVubygpKQogICAgaWYgcGF0aC5pc19zeW1saW5rKCkgb3Igbm90IHBhdGguaXNfZmlsZSgpOgogICAgICAgIHJhaXNlIE9TRXJyb3IoIm5vdC1vcmRpbmFyeSIpCiAgICByZW9wZW5lZCA9IHBhdGgucmVhZF9ieXRlcygpCiAgICBpZiByZW9wZW5lZCAhPSBkYXRhOgogICAgICAgIHJhaXNlIE9TRXJyb3IoInJlb3Blbi1taXNtYXRjaCIpCgoKZGVmIGNyZWF0ZV9vdXRwdXRfdHJlZShvdXRwdXRfcm9vdDogcGF0aGxpYi5QYXRoKSAtPiB0dXBsZVtwYXRobGliLlBhdGgsIHBhdGhsaWIuUGF0aCwgcGF0aGxpYi5QYXRoXToKICAgIGlmIG91dHB1dF9yb290LmV4aXN0cygpIG9yIG91dHB1dF9yb290LmlzX3N5bWxpbmsoKToKICAgICAgICByYWlzZSBGaWxlRXhpc3RzRXJyb3Ioc3RyKG91dHB1dF9yb290KSkKICAgIG91dHB1dF9yb290Lm1rZGlyKCkKICAgIHRlc3QgPSBvdXRwdXRfcm9vdCAvICJ0ZXN0IgogICAgcmVjZWlwdCA9IG91dHB1dF9yb290IC8gInJlY2VpcHQiCiAgICBtYW5pZmVzdCA9IG91dHB1dF9yb290IC8gIm1hbmlmZXN0IgogICAgZm9yIHBhdGggaW4gKHRlc3QsIHJlY2VpcHQsIG1hbmlmZXN0KToKICAgICAgICBwYXRoLm1rZGlyKCkKICAgICAgICBpZiBwYXRoLmlzX3N5bWxpbmsoKSBvciBub3QgcGF0aC5pc19kaXIoKToKICAgICAgICAgICAgcmFpc2UgT1NFcnJvcigiZGlyZWN0b3J5LWNvbnRyYWN0IikKICAgIHJldHVybiB0ZXN0LCByZWNlaXB0LCBtYW5pZmVzdAo=
ZnJvbSBfX2Z1dHVyZV9fIGltcG9ydCBhbm5vdGF0aW9ucwoKaW1wb3J0IGFzdAppbXBvcnQgcGF0aGxpYgpmcm9tIHR5cGluZyBpbXBvcnQgQW55CgoKRk9SQklEREVOX0lNUE9SVFMgPSB7CiAgICAiaHR0cCIsICJteXNxbCIsICJteXNxbC5jb25uZWN0b3IiLCAicHlteXNxbCIsICJyZXF1ZXN0cyIsICJzb2NrZXQiLAogICAgInNxbGFsY2hlbXkiLCAic3VicHJvY2VzcyIsICJ1cmxsaWIiLAp9CkZPUkJJRERFTl9DQUxMUyA9IHsiY29tcGlsZSIsICJldmFsIiwgImV4ZWMiLCAiX19pbXBvcnRfXyJ9ClJFUVVJUkVEX0ZVTkNUSU9OUyA9IHsKICAgICJjb252ZXJ0X2F1dGhvcml6YXRpb25fd2luZG93IiwgInRlc3RfYXV0aG9yaXphdGlvbl93aW5kb3ciLAogICAgInNlbGVjdF9leGFjdF9yZWxhdGVkX3Byb2Nlc3MiLCAiaW52b2tlX3ByZWNvbnN1bXB0aW9uX3ByZWZsaWdodCIsCiAgICAiY2Fub25pY2FsX2pzb25fYnl0ZXMiLCAid3JpdGVfY3JlYXRlX25ld19ieXRlcyIsICJjcmVhdGVfb3V0cHV0X3RyZWUiLAp9CgoKZGVmIF9jaGVja19zb3VyY2UobW9kdWxlX3BhdGg6IHBhdGhsaWIuUGF0aCwgdmFsaWRhdGlvbl9wYXRoOiBwYXRobGliLlBhdGgpIC0+IGxpc3RbZGljdFtzdHIsIEFueV1dOgogICAgbW9kdWxlX2J5dGVzID0gbW9kdWxlX3BhdGgucmVhZF9ieXRlcygpCiAgICB2YWxpZGF0aW9uX2J5dGVzID0gdmFsaWRhdGlvbl9wYXRoLnJlYWRfYnl0ZXMoKQogICAgbW9kdWxlX3RleHQgPSBtb2R1bGVfYnl0ZXMuZGVjb2RlKCJ1dGYtOCIsIGVycm9ycz0ic3RyaWN0IikKICAgIHZhbGlkYXRpb25fdGV4dCA9IHZhbGlkYXRpb25fYnl0ZXMuZGVjb2RlKCJ1dGYtOCIsIGVycm9ycz0ic3RyaWN0IikKICAgIHRyZWUgPSBhc3QucGFyc2UobW9kdWxlX3RleHQsIGZpbGVuYW1lPXN0cihtb2R1bGVfcGF0aCksIG1vZGU9ImV4ZWMiKQogICAgdmFsaWRhdGlvbl90cmVlID0gYXN0LnBhcnNlKHZhbGlkYXRpb25fdGV4dCwgZmlsZW5hbWU9c3RyKHZhbGlkYXRpb25fcGF0aCksIG1vZGU9ImV4ZWMiKQogICAgZnVuY3Rpb25zID0ge25vZGUubmFtZSBmb3Igbm9kZSBpbiBhc3Qud2Fsayh0cmVlKSBpZiBpc2luc3RhbmNlKG5vZGUsIGFzdC5GdW5jdGlvbkRlZil9CiAgICBpbXBvcnRzOiBzZXRbc3RyXSA9IHNldCgpCiAgICBmb3JiaWRkZW5fY2FsbHM6IHNldFtzdHJdID0gc2V0KCkKICAgIGZvciBwYXJzZWQgaW4gKHRyZWUsIHZhbGlkYXRpb25fdHJlZSk6CiAgICAgICAgZm9yIG5vZGUgaW4gYXN0LndhbGsocGFyc2VkKToKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShub2RlLCBhc3QuSW1wb3J0KToKICAgICAgICAgICAgICAgIGltcG9ydHMudXBkYXRlKGFsaWFzLm5hbWUgZm9yIGFsaWFzIGluIG5vZGUubmFtZXMpCiAgICAgICAgICAgIGVsaWYgaXNpbnN0YW5jZShub2RlLCBhc3QuSW1wb3J0RnJvbSk6CiAgICAgICAgICAgICAgICBpbXBvcnRzLmFkZChub2RlLm1vZHVsZSBvciAiIikKICAgICAgICAgICAgZWxpZiBpc2luc3RhbmNlKG5vZGUsIGFzdC5DYWxsKSBhbmQgaXNpbnN0YW5jZShub2RlLmZ1bmMsIGFzdC5OYW1lKSBhbmQgbm9kZS5mdW5jLmlkIGluIEZPUkJJRERFTl9DQUxMUzoKICAgICAgICAgICAgICAgIGZvcmJpZGRlbl9jYWxscy5hZGQobm9kZS5mdW5jLmlkKQogICAgY2hlY2tzID0gWwogICAgICAgICgiUzAxLU1PRFVMRS1VVEY4IiwgInByZXNlbnQiLCAicHJlc2VudCIgaWYgbW9kdWxlX2J5dGVzLmVuZHN3aXRoKGIiXG4iKSBlbHNlICJhYnNlbnQiKSwKICAgICAgICAoIlMwMi1WQUxJREFUSU9OLVVURjgiLCAicHJlc2VudCIsICJwcmVzZW50IiBpZiB2YWxpZGF0aW9uX2J5dGVzLmVuZHN3aXRoKGIiXG4iKSBlbHNlICJhYnNlbnQiKSwKICAgICAgICAoIlMwMy1GT1VSLUFQSSIsICJwcmVzZW50IiwgInByZXNlbnQiIGlmIFJFUVVJUkVEX0ZVTkNUSU9OUy5pc3N1YnNldChmdW5jdGlvbnMpIGVsc2UgImFic2VudCIpLAogICAgICAgICgiUzA0LU5PLUZPUkJJRERFTi1JTVBPUlQiLCAiYWJzZW50IiwgInByZXNlbnQiIGlmIGltcG9ydHMgJiBGT1JCSURERU5fSU1QT1JUUyBlbHNlICJhYnNlbnQiKSwKICAgICAgICAoIlMwNS1OTy1EWU5BTUlDLUNBTEwiLCAiYWJzZW50IiwgInByZXNlbnQiIGlmIGZvcmJpZGRlbl9jYWxscyBlbHNlICJhYnNlbnQiKSwKICAgICAgICAoIlMwNi1EQVRFVElNRS1USUNLUyIsICJwcmVzZW50IiwgInByZXNlbnQiIGlmICJkZWYgX3RpY2tzIiBpbiBtb2R1bGVfdGV4dCBlbHNlICJhYnNlbnQiKSwKICAgICAgICAoIlMwNy1TSU5HTEUtR0FURSIsICJwcmVzZW50IiwgInByZXNlbnQiIGlmICJjbGFzcyBJbnZvY2F0aW9uR2F0ZSIgaW4gbW9kdWxlX3RleHQgZWxzZSAiYWJzZW50IiksCiAgICAgICAgKCJTMDgtQ1JFQVRFLU5FVyIsICJwcmVzZW50IiwgInByZXNlbnQiIGlmICdvcGVuKCJ4YiIpJyBpbiBtb2R1bGVfdGV4dCBlbHNlICJhYnNlbnQiKSwKICAgICAgICAoIlMwOS1GU1lOQyIsICJwcmVzZW50IiwgInByZXNlbnQiIGlmICJvcy5mc3luYyIgaW4gbW9kdWxlX3RleHQgZWxzZSAiYWJzZW50IiksCiAgICAgICAgKCJTMTAtTk8tREFUQUJBU0UiLCAiYWJzZW50IiwgInByZXNlbnQiIGlmICJTSE9XIEdSQU5UUyIgaW4gbW9kdWxlX3RleHQgb3IgIkNVUlJFTlRfVVNFUiIgaW4gbW9kdWxlX3RleHQgZWxzZSAiYWJzZW50IiksCiAgICAgICAgKCJTMTEtTk8tTEVHQUNZLVJPVVRFIiwgImFic2VudCIsICJwcmVzZW50IiBpZiAibWJ4IHNlbmQiIGluIChtb2R1bGVfdGV4dCArIHZhbGlkYXRpb25fdGV4dCkubG93ZXIoKSBlbHNlICJhYnNlbnQiKSwKICAgICAgICAoIlMxMi1OTy1ORVRXT1JLIiwgImFic2VudCIsICJwcmVzZW50IiBpZiAic29ja2V0LiIgaW4gKG1vZHVsZV90ZXh0ICsgdmFsaWRhdGlvbl90ZXh0KSBlbHNlICJhYnNlbnQiKSwKICAgIF0KICAgIHJldHVybiBbCiAgICAgICAgeyJhY3R1YWwiOiBhY3R1YWwsICJjaGVja19pZCI6IGNoZWNrX2lkLCAiZXhwZWN0ZWQiOiBleHBlY3RlZCwKICAgICAgICAgInN0YXR1cyI6ICJNQVRDSCIgaWYgYWN0dWFsID09IGV4cGVjdGVkIGVsc2UgIk1JU01BVENIIiwKICAgICAgICAgInN0b3BfY29kZSI6IE5vbmUgaWYgYWN0dWFsID09IGV4cGVjdGVkIGVsc2UgIlNUQVRJQ19DSEVDS19NSVNNQVRDSCJ9CiAgICAgICAgZm9yIGNoZWNrX2lkLCBleHBlY3RlZCwgYWN0dWFsIGluIGNoZWNrcwogICAgXQoKCmRlZiBydW5fc3RhdGljX2NoZWNrcyhtb2R1bGVfcGF0aDogcGF0aGxpYi5QYXRoLCB2YWxpZGF0aW9uX3BhdGg6IHBhdGhsaWIuUGF0aCkgLT4gbGlzdFtkaWN0W3N0ciwgQW55XV06CiAgICByZXR1cm4gX2NoZWNrX3NvdXJjZShtb2R1bGVfcGF0aCwgdmFsaWRhdGlvbl9wYXRoKQo=
eyJhcGlfY29udHJhY3RzIjpbeyJhcGlfaWQiOiJDT05WRVJUIiwiZXhwZWN0ZWRfdHlwZSI6IkFOQS5TRU1JLkFVVEhPUklaQVRJT04uV0lORE9XLlYwMDEiLCJwcm9wZXJ0eV9uYW1lcyI6WyJhdXRob3JpemVkX2F0X3JhdyIsImF1dGhvcml6ZWRfYXRfdXRjX3RpY2tzIiwiZXhwaXJlc19hdF9yYXciLCJleHBpcmVzX2F0X3V0Y190aWNrcyIsInNjaGVtYV9pZCIsInN0YXR1cyIsInN0b3BfY29kZSJdLCJwcm9wZXJ0eV9ydWxlcyI6WyJTVFJJTkdfTk9OTlVMTCIsIklOVDY0X09SX05VTEwiLCJTVFJJTkdfTk9OTlVMTCIsIklOVDY0X09SX05VTEwiLCJTVFJJTkdfTk9OTlVMTCIsIlNUUklOR19OT05OVUxMIiwiU1RSSU5HX09SX05VTEwiXX0seyJhcGlfaWQiOiJJTlZPS0UiLCJleHBlY3RlZF90eXBlIjoiQU5BLlNFTUkuUFJFQ09OU1VNUFRJT04uUkVTVUxULlYwMDIiLCJwcm9wZXJ0eV9uYW1lcyI6WyJhdXRob3JpemF0aW9uX2lkIiwiYXV0aG9yaXplZF9hdF91dGNfdGlja3MiLCJhdXRob3JpemVkX291dGVyX3N0YXJ0ZWQiLCJjYW5kaWRhdGVfcnVuX2V4aXN0cyIsImNyZWRlbnRpYWxfYWNjZXNzIiwiZGF0YWJhc2VfY29ubmVjdGlvbl9wZXJmb3JtZWQiLCJleGNlcHRpb25fdHlwZSIsImV4cGlyZXNfYXRfdXRjX3RpY2tzIiwiZmluaXNoZWRfYXQiLCJoaXN0b3J5X2hhc2hfbWlzbWF0Y2hfY291bnQiLCJpbnZvY2F0aW9uX2NvdW50IiwibWF0ZXJpYWxpemVkX3RhcmdldF9jb3VudCIsIm5ldHdvcmtfYWNjZXNzIiwibm93X3V0Y190aWNrcyIsInByZWZsaWdodF9zdGFnZSIsInJlbGF0ZWRfcHJvY2Vzc19jb3VudCIsInJlc3VsdF9zY2hlbWFfaWQiLCJzdGFydGVkX2F0Iiwic3RhdHVzIiwic3RvcF9jb2RlIiwidGFyZ2V0X2V4aXN0aW5nX2NvdW50IiwidW5jZXJ0YWluX2ZpZWxkIl0sInByb3BlcnR5X3J1bGVzIjpbIlNUUklOR19OT05OVUxMIiwiSU5UNjRfT1JfTlVMTCIsIkJPT0xfT1JfTlVMTCIsIkJPT0xfT1JfTlVMTCIsIkJPT0xfT1JfTlVMTCIsIkJPT0xfT1JfTlVMTCIsIlNUUklOR19PUl9OVUxMIiwiSU5UNjRfT1JfTlVMTCIsIlNUUklOR19PUl9OVUxMIiwiSU5UMzJfT1JfTlVMTCIsIklOVDMyX09SX05VTEwiLCJJTlQzMl9PUl9OVUxMIiwiQk9PTF9PUl9OVUxMIiwiSU5UNjRfT1JfTlVMTCIsIlNUUklOR19OT05OVUxMIiwiSU5UMzJfT1JfTlVMTCIsIlNUUklOR19OT05OVUxMIiwiU1RSSU5HX09SX05VTEwiLCJTVFJJTkdfTk9OTlVMTCIsIlNUUklOR19PUl9OVUxMIiwiSU5UMzJfT1JfTlVMTCIsIlNUUklOR19PUl9OVUxMIl19LHsiYXBpX2lkIjoiU0VMRUNUT1IiLCJleHBlY3RlZF90eXBlIjoiQU5BLlNFTUkuUFJPQ0VTUy5TRUxFQ1RPUi5SRVNVTFQuVjAwMSIsInByb3BlcnR5X25hbWVzIjpbImNvbmZpcm1lZF96ZXJvIiwiZHVwbGljYXRlX3Byb2Nlc3NfaWRfY291bnQiLCJleGFjdF9vdXRlcl9jb3VudCIsIm1hdGNoZWRfcHJvY2Vzc19pZHMiLCJwcm9oaWJpdGVkX3Byb2Nlc3NfY291bnQiLCJyZWxhdGVkX3Byb2Nlc3NfY291bnQiLCJzY2hlbWFfaWQiLCJzbmFwc2hvdF9yb3dfY291bnQiLCJzdGF0dXMiLCJzdG9wX2NvZGUiLCJ1bmNlcnRhaW5fZmllbGRzIiwidW5rbm93bl9yZWxldmFudF9jb3VudCJdLCJwcm9wZXJ0eV9ydWxlcyI6WyJCT09MX09SX05VTEwiLCJJTlQzMl9PUl9OVUxMIiwiSU5UMzJfT1JfTlVMTCIsIkFSUkFZX1VJTlQzMl9PUl9OVUxMIiwiSU5UMzJfT1JfTlVMTCIsIklOVDMyX09SX05VTEwiLCJTVFJJTkdfTk9OTlVMTCIsIklOVDMyX09SX05VTEwiLCJTVFJJTkdfTk9OTlVMTCIsIlNUUklOR19PUl9OVUxMIiwiQVJSQVlfU1RSSU5HX09SX05VTEwiLCJJTlQzMl9PUl9OVUxMIl19LHsiYXBpX2lkIjoiVEVTVCIsImV4cGVjdGVkX3R5cGUiOiJBTkEuU0VNSS5BVVRIT1JJWkFUSU9OLldJTkRPVy5URVNULlYwMDEiLCJwcm9wZXJ0eV9uYW1lcyI6WyJhdXRob3JpemVkX2F0X3V0Y190aWNrcyIsImV4cGlyZXNfYXRfdXRjX3RpY2tzIiwiaW5zaWRlX3dpbmRvdyIsIm5vd191dGNfdGlja3MiLCJzY2hlbWFfaWQiLCJzdGF0dXMiLCJzdG9wX2NvZGUiXSwicHJvcGVydHlfcnVsZXMiOlsiSU5UNjRfT1JfTlVMTCIsIklOVDY0X09SX05VTEwiLCJCT09MX09SX05VTEwiLCJJTlQ2NF9PUl9OVUxMIiwiU1RSSU5HX05PTk5VTEwiLCJTVFJJTkdfTk9OTlVMTCIsIlNUUklOR19PUl9OVUxMIl19XSwiYXBpX25lZ2F0aXZlX2Nhc2VzIjpbIklOVk9LRS1QUk9QRVJUWS1FWFRSQSIsIklOVk9LRS1QUk9QRVJUWS1NSVNTSU5HIiwiSU5WT0tFLVBST1BFUlRZLU9SREVSIiwiSU5WT0tFLVBST1BFUlRZLVRZUEUiLCJJTlZPS0UtVFdPIiwiSU5WT0tFLVRZUEUtRFJJRlQiLCJJTlZPS0UtVFlQRS1NSVNTSU5HIiwiSU5WT0tFLVpFUk8iXSwiZm9yYmlkZGVuX2NvbW11bmljYXRpb25fdG9rZW5zX2Jhc2U2NCI6WyJiV0o0SUhObGJtUT0iLCJjSEp2YW1WamRDQnBibUp2ZUE9PSIsImMyVnpjMmx2YmlCaWNtbGtaMlU9IiwiYUdsemRHOXllU0JtWVd4c1ltRmphdz09IiwiYkdWbllXTjVJSEp2ZFhSbCJdLCJuYXRpdmVfZmluYWxfc2NoZW1hIjoiQU5BLlNFTUkuUFJFQ09OU1VNUFRJT04uTkFUSVZFLkZJTkFMLlYwMDQiLCJuYXRpdmVfc3RhdGVfaWRzIjpbIkMwMCIsIkMwMSIsIkMwMiIsIkMwMyIsIkMwNCIsIkMwNSIsIkMwNiIsIkMwNyIsIkMwOCIsIkMwOSIsIkMxMCIsIkMxMSIsIkMxMiIsIkMxMyIsIkMxNCIsIkMxNSIsIkMxNiIsIkMxNyIsIkMxOCIsIkMxOSIsIkMyMCIsIkMyMSIsIkMyMiIsIkMyMyIsIkMyNCIsIkMyNSIsIkMyNiIsIkMyNyIsIkMyOCIsIkMyOSIsIkMzMCIsIkMzMSIsIkMzMiIsIkMzMyIsIkMzNCIsIkMzNSIsIkMzNiIsIkMzNyIsIkMzOCIsIkMzOSIsIkM0MCJdLCJwcmVmbGlnaHRfY2FzZXMiOlsiSElTVE9SWV9NSVNNQVRDSCIsIklERU5USVRZX01JU01BVENIIiwiUEFTUyIsIlBMQU5fSEFTSF9NSVNNQVRDSCIsIlBST0NFU1NfVU5LTk9XTiIsIlNFQ09ORF9DQUxMIiwiVEFSR0VUX1VOS05PV04iLCJUSU1FX1BBUlNFX1NUT1AiXSwicHJvY2Vzc19zZWxlY3Rvcl9jYXNlcyI6WyJTLUFEQVBURVItVU5LTk9XTiIsIlMtQ01ELURJRkZFUkVOVCIsIlMtQ09NUE9VTkQtVU5LTk9XTi1QUkVTRU5UIiwiUy1EVVAtUElEIiwiUy1FTVBUWSIsIlMtRVhBQ1QiLCJTLUVYRS1ESUZGRVJFTlQiLCJTLUlOUFVULUJBU0U2NC1EUklGVCIsIlMtTkFNRS1OVUxMIiwiUy1PVVRFUi1DTUQtTlVMTCIsIlMtUFJPSElCSVRFRC1DU0MiLCJTLVJFTEVWQU5ULVBBVEgtTlVMTCIsIlMtU09VUkNFLVNFTEYiLCJTLVNVQlNUUklORyIsIlMtVFdPLUVYQUNUIl0sInByb3ZpZGVyX3ByZWNlZGVuY2VfY2FzZXMiOlsiUFAtSURFTlRJVFktVEhST1ciLCJQUC1QTEFOSEFTSC1UV08tT0JKRUNUUyIsIlBQLVRBUkdFVC1DT01QT1VORC1JTlZBTElEIiwiUFAtVEFSR0VULU1JU1NJTkctUFJPUEVSVFkiXSwicmVzdWx0X3NjaGVtYSI6eyJmdW5jdGlvbmFsX2Nhc2VfdG90YWwiOjMwLCJhcGlfbmVnYXRpdmVfdG90YWwiOjgsInByb3ZpZGVyX3ByZWNlZGVuY2VfdG90YWwiOjQsInNlbGVjdG9yX3RvdGFsIjoxNSwic3VjY2Vzc19hcGlfdG90YWwiOjQsInRpbWVfdG90YWwiOjcsInByZWZsaWdodF90b3RhbCI6OCwidGltZW91dF9rbm93bl9zdGF0ZV90b3RhbCI6MTh9LCJydW5faWQiOiJSVU4tREVWLUFOQS1TRU1JLVJPT1QtUFJFRkxJR0hULVBZVEhPTi1TVEFHRS1QLTIwMjYwNzI2LTAwMSIsInNjaGVtYV9pZCI6IkFOQS1TRU1JLVBSRUNPTlNVTVBUSU9OLVZFQ1RPUlMtSkNTLVYwMDUiLCJ0aW1lX2Nhc2VzIjpbIlQtQVQtRU5EIiwiVC1BVC1TVEFSVCIsIlQtQVVUSC1NQUxGT1JNRUQiLCJULUJFRk9SRSIsIlQtRVhQSVJFUy1NQUxGT1JNRUQiLCJULUlOU0lERSIsIlQtTk9OUE9TSVRJVkUiXSwidGltZW91dF9rbm93bl9wcmVmaXhlcyI6WyJOTk4iLCJBTk4iLCJJTk4iLCJGTk4iLCJGTkEiLCJGTkkiLCJGTlYiLCJWQU4iLCJWSU4iLCJWRk4iLCJWRkEiLCJWRkkiLCJWRlYiLCJWVk4iLCJWVkEiLCJWVkkiLCJWVlYiLCJWTk4iXX0=
ZnJvbSBfX2Z1dHVyZV9fIGltcG9ydCBhbm5vdGF0aW9ucwoKaW1wb3J0IGJhc2U2NAppbXBvcnQgY3N2CmltcG9ydCBkYXRldGltZSBhcyBkdAppbXBvcnQgaGFzaGxpYgppbXBvcnQgaW8KaW1wb3J0IGpzb24KaW1wb3J0IG9zCmltcG9ydCBwYXRobGliCmltcG9ydCBzeXMKZnJvbSB0eXBpbmcgaW1wb3J0IEFueQoKVEVTVF9ESVIgPSBwYXRobGliLlBhdGgoX19maWxlX18pLnJlc29sdmUoKS5wYXJlbnQKTU9EVUxFX0RJUiA9IFRFU1RfRElSLnBhcmVudAppZiBzdHIoTU9EVUxFX0RJUikgbm90IGluIHN5cy5wYXRoOgogICAgc3lzLnBhdGguaW5zZXJ0KDAsIHN0cihNT0RVTEVfRElSKSkKCmltcG9ydCBhbmFfc2VtaV9wcmVjb25zdW1wdGlvbl92MDAyIGFzIGltcGxlbWVudGF0aW9uCmltcG9ydCB0ZXN0X2FuYV9zZW1pX3ByZWNvbnN1bXB0aW9uX3YwMDIgYXMgc3RhdGljX3Rlc3RzCgoKZGVmIF9zaGEoZGF0YTogYnl0ZXMpIC0+IHN0cjoKICAgIHJldHVybiBoYXNobGliLnNoYTI1NihkYXRhKS5oZXhkaWdlc3QoKQoKCmRlZiBfd3JpdGVfamNzKHBhdGg6IHBhdGhsaWIuUGF0aCwgdmFsdWU6IEFueSkgLT4gTm9uZToKICAgIGltcGxlbWVudGF0aW9uLndyaXRlX2NyZWF0ZV9uZXdfYnl0ZXMocGF0aCwgaW1wbGVtZW50YXRpb24uY2Fub25pY2FsX2pzb25fYnl0ZXModmFsdWUpKQoKCmRlZiBfbWF0Y2goY2FzZV9pZDogc3RyKSAtPiBkaWN0W3N0ciwgQW55XToKICAgIHJldHVybiB7ImNhc2VfaWQiOiBjYXNlX2lkLCAic3RhdHVzIjogIk1BVENIIiwgInN0b3BfY29kZSI6IE5vbmV9CgoKZGVmIF9wcm92aWRlcih0eXBlX25hbWU6IHN0ciwgdmFsdWVzOiBkaWN0W3N0ciwgQW55XSkgLT4gZGljdFtzdHIsIEFueV06CiAgICByZXR1cm4geyJfX3R5cGVfbmFtZV9fIjogdHlwZV9uYW1lLCAqKnZhbHVlc30KCgpkZWYgX2FwaV9yb3coYXBpX2lkOiBzdHIsIHZhbHVlOiBkaWN0W3N0ciwgQW55XSkgLT4gZGljdFtzdHIsIEFueV06CiAgICBuYW1lcyA9IFtrZXkgZm9yIGtleSBpbiB2YWx1ZSBpZiBrZXkgIT0gIl9fdHlwZV9uYW1lX18iXQogICAgdHlwZXMgPSBbIjxudWxsPiIgaWYgdmFsdWVba2V5XSBpcyBOb25lIGVsc2UgdHlwZSh2YWx1ZVtrZXldKS5fX25hbWVfXyBmb3Iga2V5IGluIG5hbWVzXQogICAgbmFtZV9oYXNoID0gX3NoYSgiXG4iLmpvaW4obmFtZXMpLmVuY29kZSgidXRmLTgiKSkKICAgIHR5cGVfaGFzaCA9IF9zaGEoIlxuIi5qb2luKHR5cGVzKS5lbmNvZGUoInV0Zi04IikpCiAgICByZXR1cm4gewogICAgICAgICJhY3R1YWxfb2JqZWN0X2NvdW50IjogMSwgImFjdHVhbF9wcm9wZXJ0eV9jb3VudCI6IGxlbihuYW1lcyksCiAgICAgICAgImFjdHVhbF9wcm9wZXJ0eV9uYW1lcyI6IG5hbWVzLCAiYWN0dWFsX3Byb3BlcnR5X25hbWVzX3NoYTI1NiI6IG5hbWVfaGFzaCwKICAgICAgICAiYWN0dWFsX3Byb3BlcnR5X3R5cGVzIjogdHlwZXMsICJhY3R1YWxfcHJvcGVydHlfdHlwZXNfc2hhMjU2IjogdHlwZV9oYXNoLAogICAgICAgICJhY3R1YWxfdHlwZV9uYW1lcyI6IFt2YWx1ZVsiX190eXBlX25hbWVfXyJdXSwgImFwaV9pZCI6IGFwaV9pZCwKICAgICAgICAiZXhwZWN0ZWRfb2JqZWN0X2NvdW50IjogMSwgImV4cGVjdGVkX3Byb3BlcnR5X2NvdW50IjogbGVuKG5hbWVzKSwKICAgICAgICAiZXhwZWN0ZWRfcHJvcGVydHlfbmFtZXMiOiBuYW1lcywgImV4cGVjdGVkX3Byb3BlcnR5X25hbWVzX3NoYTI1NiI6IG5hbWVfaGFzaCwKICAgICAgICAiZXhwZWN0ZWRfcHJvcGVydHlfdHlwZV9ydWxlcyI6IFtdLCAiZXhwZWN0ZWRfcHJvcGVydHlfdHlwZV9ydWxlc19zaGEyNTYiOiBOb25lLAogICAgICAgICJleHBlY3RlZF90eXBlX25hbWUiOiB2YWx1ZVsiX190eXBlX25hbWVfXyJdLCAib2JzZXJ2YXRpb25fc3RhdHVzIjogIlNJTkdMRV9WQUxJRCIsCiAgICAgICAgInN0YXR1cyI6ICJNQVRDSCIsICJzdG9wX2NvZGUiOiBOb25lLAogICAgfQoKCmRlZiBfcmVjZWlwdChydW5faWQ6IHN0ciwgcGxhbl9pZDogc3RyLCB2YXJpYW50OiBzdHIpIC0+IGJ5dGVzOgogICAgaWYgdmFyaWFudCA9PSAiUEFTUyI6CiAgICAgICAgcHJlcGFja2FnZSwgc3RvcCwgcDA1LCBwMDYgPSAiUEFTUyIsICJudWxsIiwgIlRFU1RfUEFTUyIsICJURVNUX1BBU1MiCiAgICBlbGlmIHZhcmlhbnQgPT0gIlNUQVRJQ19GQUlMIjoKICAgICAgICBwcmVwYWNrYWdlLCBzdG9wLCBwMDUsIHAwNiA9ICJURVNUX0ZBSUwiLCAiU1RBVElDX1RFU1RfRkFJTEVEIiwgIlRFU1RfRkFJTCIsICJOT1RfUlVOX1VQU1RSRUFNX1NUT1AiCiAgICBlbHNlOgogICAgICAgIHByZXBhY2thZ2UsIHN0b3AsIHAwNSwgcDA2ID0gIlRFU1RfRkFJTCIsICJDT05UUkFDVF9URVNUX0ZBSUxFRCIsICJURVNUX1BBU1MiLCAiVEVTVF9GQUlMIgogICAgdGV4dCA9ICgKICAgICAgICAicmVjZWlwdF9zY2hlbWFfaWQ6IEFOQS1TRU1JLVBSRUNPTlNVTVBUSU9OLVJFQ0VJUFQtTUQtVjAwNVxuIgogICAgICAgIGYicnVuX2lkOiB7cnVuX2lkfVxucGxhbl9pZDoge3BsYW5faWR9XG5hc19vZl9hcnRpZmFjdF9pZDogWTA2XG4iCiAgICAgICAgZiJwcmVwYWNrYWdlX3N0YXR1czoge3ByZXBhY2thZ2V9XG5wcmVwYWNrYWdlX3N0b3BfY29kZToge3N0b3B9XG4iCiAgICAgICAgZiJZMDVfc3RhdHVzOiB7cDA1fVxuWTA2X3N0YXR1czoge3AwNn1cbm91dGVyX3Byb2Nlc3NfY291bnQ6IDFcbiIKICAgICAgICAicHJvaGliaXRlZF9wcm9jZXNzX2NvdW50OiAwXG5uZXR3b3JrX2FjY2VzczogZmFsc2VcbmNyZWRlbnRpYWxfYWNjZXNzOiBmYWxzZVxuIgogICAgICAgICJkYXRhYmFzZV9jb25uZWN0aW9uX3BlcmZvcm1lZDogZmFsc2VcbiIKICAgICkKICAgIHJldHVybiB0ZXh0LmVuY29kZSgidXRmLTgiKQoKCmRlZiBfbWFuaWZlc3QocnVuX2lkOiBzdHIsIGRlZmluaXRpb25zOiBsaXN0W3R1cGxlW3N0ciwgLi4uXV0sIHN0YXRpY19mYWlsOiBpbnQsIGNvbnRyYWN0X2ZhaWw6IGludCkgLT4gYnl0ZXM6CiAgICBidWZmZXIgPSBpby5TdHJpbmdJTyhuZXdsaW5lPSIiKQogICAgd3JpdGVyID0gY3N2LndyaXRlcihidWZmZXIsIGxpbmV0ZXJtaW5hdG9yPSJcclxuIiwgcXVvdGluZz1jc3YuUVVPVEVfQUxMKQogICAgd3JpdGVyLndyaXRlcm93KCgiYXJ0aWZhY3RfaWQiLCAicnVuX2lkIiwgInJvbGUiLCAic2NoZW1hX2lkIiwgInJlbGF0aXZlX3BhdGgiLCAibWVkaWFfdHlwZSIsCiAgICAgICAgICAgICAgICAgICAgICJleHBlY3RlZF9wcmVzZW5jZSIsICJtYXRlcmlhbGl6ZWQiLCAiZXhpc3RzIiwgInN0YXR1cyIsICJ1cHN0cmVhbV9zdG9wX2NvZGUiLAogICAgICAgICAgICAgICAgICAgICAiYnl0ZXMiLCAic2hhMjU2IikpCiAgICBmb3IgYXJ0aWZhY3RfaWQsIHJvbGUsIHNjaGVtYV9pZCwgcmVsYXRpdmVfcGF0aCwgbWVkaWFfdHlwZSwgZXhwZWN0ZWQsIHBhdGhfcmF3IGluIGRlZmluaXRpb25zOgogICAgICAgIHBhdGggPSBwYXRobGliLlBhdGgocGF0aF9yYXcpCiAgICAgICAgaWYgYXJ0aWZhY3RfaWQgPT0gIlkwOCI6CiAgICAgICAgICAgIHJvdyA9IChhcnRpZmFjdF9pZCwgcnVuX2lkLCByb2xlLCBzY2hlbWFfaWQsIHJlbGF0aXZlX3BhdGgsIG1lZGlhX3R5cGUsIGV4cGVjdGVkLAogICAgICAgICAgICAgICAgICAgInRydWUiLCAidHJ1ZSIsICJNQU5JRkVTVF9TRUxGX0VYVEVSTkFMX0hBU0giLCAiIiwgIiIsICIiKQogICAgICAgIGVsaWYgcGF0aC5pc19maWxlKCkgYW5kIG5vdCBwYXRoLmlzX3N5bWxpbmsoKToKICAgICAgICAgICAgZGF0YSA9IHBhdGgucmVhZF9ieXRlcygpCiAgICAgICAgICAgIGZhaWxlZCA9IChhcnRpZmFjdF9pZCA9PSAiWTA1IiBhbmQgc3RhdGljX2ZhaWwpIG9yIChhcnRpZmFjdF9pZCA9PSAiWTA2IiBhbmQgY29udHJhY3RfZmFpbCkKICAgICAgICAgICAgcm93ID0gKGFydGlmYWN0X2lkLCBydW5faWQsIHJvbGUsIHNjaGVtYV9pZCwgcmVsYXRpdmVfcGF0aCwgbWVkaWFfdHlwZSwgZXhwZWN0ZWQsCiAgICAgICAgICAgICAgICAgICAidHJ1ZSIsICJ0cnVlIiwgIk1BVEVSSUFMSVpFRF9URVNUX0ZBSUwiIGlmIGZhaWxlZCBlbHNlICJNQVRFUklBTElaRURfVkFMSUQiLAogICAgICAgICAgICAgICAgICAgIiIsIHN0cihsZW4oZGF0YSkpLCBfc2hhKGRhdGEpKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJvdyA9IChhcnRpZmFjdF9pZCwgcnVuX2lkLCByb2xlLCBzY2hlbWFfaWQsIHJlbGF0aXZlX3BhdGgsIG1lZGlhX3R5cGUsIGV4cGVjdGVkLAogICAgICAgICAgICAgICAgICAgImZhbHNlIiwgImZhbHNlIiwgIk5PVF9SVU5fVVBTVFJFQU1fU1RPUCIsICJTVEFUSUNfVEVTVF9GQUlMRUQiLCAiIiwgIiIpCiAgICAgICAgd3JpdGVyLndyaXRlcm93KHJvdykKICAgIHJldHVybiBidWZmZXIuZ2V0dmFsdWUoKS5lbmNvZGUoInV0Zi04IikKCgpkZWYgbWFpbihwcm9qZWN0X3Jvb3Q6IHBhdGhsaWIuUGF0aCwgcnVuX2lkOiBzdHIsIG91dHB1dF9yb290OiBwYXRobGliLlBhdGgpIC0+IGludDoKICAgIG1vZHVsZV9wYXRoID0gcHJvamVjdF9yb290IC8gImRldiIgLyAiYW5hLWRldiIgLyAiYW5hX3NlbWlfcHJlY29uc3VtcHRpb25fdjAwMi5weSIKICAgIHN0YXRpY19wYXRoID0gcHJvamVjdF9yb290IC8gImRldiIgLyAiYW5hLWRldiIgLyAidGVzdCIgLyAidGVzdF9hbmFfc2VtaV9wcmVjb25zdW1wdGlvbl92MDAyLnB5IgogICAgdmVjdG9yX3BhdGggPSBwcm9qZWN0X3Jvb3QgLyAiZGV2IiAvICJhbmEtZGV2IiAvICJ0ZXN0IiAvICJhbmFfc2VtaV9wcmVjb25zdW1wdGlvbl92ZWN0b3JzX3YwMDIuanNvbiIKICAgIHZhbGlkYXRpb25fcGF0aCA9IHBhdGhsaWIuUGF0aChfX2ZpbGVfXykucmVzb2x2ZSgpCiAgICB0ZXN0X2RpciwgcmVjZWlwdF9kaXIsIG1hbmlmZXN0X2RpciA9IGltcGxlbWVudGF0aW9uLmNyZWF0ZV9vdXRwdXRfdHJlZShvdXRwdXRfcm9vdCkKICAgIHkwNSA9IHRlc3RfZGlyIC8gInN0YXRpYy1yZXN1bHQuanNvbiIKICAgIHkwNiA9IHRlc3RfZGlyIC8gImNvbnRyYWN0LXJlc3VsdC5qc29uIgogICAgeTA3ID0gcmVjZWlwdF9kaXIgLyAicHJlZmxpZ2h0LXJlcGFpci1yZWNlaXB0Lm1kIgogICAgeTA4ID0gbWFuaWZlc3RfZGlyIC8gInByZWZsaWdodC1yZXBhaXItbWFuaWZlc3QuY3N2IgogICAgdmVjdG9yX2J5dGVzID0gdmVjdG9yX3BhdGgucmVhZF9ieXRlcygpCiAgICBpZiBsZW4odmVjdG9yX2J5dGVzKSAhPSA0MDE2IG9yIHZlY3Rvcl9ieXRlc1stMV0gIT0gMHg3RCBvciBiIlxyIiBpbiB2ZWN0b3JfYnl0ZXMgb3IgYiJcbiIgaW4gdmVjdG9yX2J5dGVzIG9yIGIiXHgwMCIgaW4gdmVjdG9yX2J5dGVzOgogICAgICAgIHJldHVybiAyNwogICAgdmVjdG9ycyA9IGpzb24ubG9hZHModmVjdG9yX2J5dGVzLmRlY29kZSgidXRmLTgiLCBlcnJvcnM9InN0cmljdCIpKQogICAgaWYgdmVjdG9ycy5nZXQoInNjaGVtYV9pZCIpICE9ICJBTkEtU0VNSS1QUkVDT05TVU1QVElPTi1WRUNUT1JTLUpDUy1WMDA1IjoKICAgICAgICByZXR1cm4gMjcKICAgIHN0YXRpY19yb3dzID0gc3RhdGljX3Rlc3RzLnJ1bl9zdGF0aWNfY2hlY2tzKG1vZHVsZV9wYXRoLCB2YWxpZGF0aW9uX3BhdGgpCiAgICBzdGF0aWNfZmFpbCA9IHN1bShyb3dbInN0YXR1cyJdICE9ICJNQVRDSCIgZm9yIHJvdyBpbiBzdGF0aWNfcm93cykKICAgIHkwNV9vYmplY3QgPSB7CiAgICAgICAgImNoZWNrX3Jlc3VsdHMiOiBzdGF0aWNfcm93cywKICAgICAgICAic2NoZW1hX2lkIjogIkFOQS1TRU1JLVBSRUNPTlNVTVBUSU9OLVNUQVRJQy1SRVNVTFQtSkNTLVYwMDIiLAogICAgICAgICJzdGF0dXMiOiAiVEVTVF9QQVNTIiBpZiBzdGF0aWNfZmFpbCA9PSAwIGVsc2UgIlRFU1RfRkFJTCIsCiAgICAgICAgInN1bW1hcnkiOiB7ImZhaWxfY291bnQiOiBzdGF0aWNfZmFpbCwgInBhc3NfY291bnQiOiAxMiAtIHN0YXRpY19mYWlsLCAidG90YWxfY291bnQiOiAxMn0sCiAgICB9CiAgICBfd3JpdGVfamNzKHkwNSwgeTA1X29iamVjdCkKICAgIGNvbnRyYWN0X2ZhaWwgPSAwCiAgICBhcGlfcm93czogbGlzdFtkaWN0W3N0ciwgQW55XV0gPSBbXQogICAgaWYgc3RhdGljX2ZhaWwgPT0gMDoKICAgICAgICB3aW5kb3cgPSBpbXBsZW1lbnRhdGlvbi5jb252ZXJ0X2F1dGhvcml6YXRpb25fd2luZG93KAogICAgICAgICAgICAiMjAyNi0wNy0yNlQwMToxMjo1OC4yNzQ4ODIwKzA4OjAwIiwgIjIwMjYtMDctMjZUMDM6MTI6NTguMjc0ODgyMCswODowMCIpCiAgICAgICAgd2luZG93X3Rlc3QgPSBpbXBsZW1lbnRhdGlvbi50ZXN0X2F1dGhvcml6YXRpb25fd2luZG93KAogICAgICAgICAgICB3aW5kb3csIGR0LmRhdGV0aW1lLmZyb21pc29mb3JtYXQoIjIwMjYtMDctMjVUMTg6MDA6MDAuMDAwMDAwKzAwOjAwIikpCiAgICAgICAgZXhwZWN0ZWRfY29tbWFuZCA9ICJDOlxcV2luZG93c1xcU3lzdGVtMzJcXFdpbmRvd3NQb3dlclNoZWxsXFx2MS4wXFxwb3dlcnNoZWxsLmV4ZSAtTm9Mb2dvIgogICAgICAgIGV4cGVjdGVkX2J5dGVzID0gZXhwZWN0ZWRfY29tbWFuZC5lbmNvZGUoInV0Zi04IikKICAgICAgICBzZWxlY3RvciA9IGltcGxlbWVudGF0aW9uLnNlbGVjdF9leGFjdF9yZWxhdGVkX3Byb2Nlc3MoCiAgICAgICAgICAgIFtdLCAiQzpcXFdpbmRvd3NcXFN5c3RlbTMyXFxXaW5kb3dzUG93ZXJTaGVsbFxcdjEuMFxccG93ZXJzaGVsbC5leGUiLAogICAgICAgICAgICBfc2hhKGV4cGVjdGVkX2J5dGVzKSwgYmFzZTY0LmI2NGVuY29kZShleHBlY3RlZF9ieXRlcykuZGVjb2RlKCJhc2NpaSIpLCBvcy5nZXRwaWQoKSwgW10pCiAgICAgICAgaWRlbnRpdHkgPSBsYW1iZGE6IF9wcm92aWRlcigiQU5BLlNFTUkuUFJFRkxJR0hULklERU5USVRZLlYwMDEiLCB7CiAgICAgICAgICAgICJjd2QiOiBzdHIocHJvamVjdF9yb290KSwgImhvc3QiOiAibG9jYWwiLCAicm9sZV9pbnN0YW5jZV9pZCI6ICJkZXYuZGV2ZWxvcGVyLmFuYS5jYWkiLAogICAgICAgICAgICAic2NoZW1hX2lkIjogIkFOQS5TRU1JLlBSRUZMSUdIVC5JREVOVElUWS5WMDAxIiwKICAgICAgICAgICAgInNvdXJjZV90aHJlYWRfaWQiOiAiMDE5ZjgwNTctNDljOS03NDEwLTg3NzItNzY0MjliZWQ0OTA5IiwKICAgICAgICAgICAgInN0YXR1cyI6ICJQQVNTIiwgInVuY2VydGFpbl9maWVsZHMiOiBOb25lfSkKICAgICAgICBwbGFuX2hhc2ggPSBsYW1iZGE6IF9wcm92aWRlcigiQU5BLlNFTUkuUFJFRkxJR0hULlBMQU5IQVNILlYwMDEiLCB7CiAgICAgICAgICAgICJieXRlcyI6IDExMTczLCAic2NoZW1hX2lkIjogIkFOQS5TRU1JLlBSRUZMSUdIVC5QTEFOSEFTSC5WMDAxIiwKICAgICAgICAgICAgInNoYTI1NiI6ICIyMzVhYWExZWYzZWFkNjNmMGI3MjkyMzlkZTk1ZTg5YWI1NGNmZmUwZjJiODBhNGE3ZWFjMmU1NjMxMjBmYzkzIiwKICAgICAgICAgICAgInN0YXR1cyI6ICJQQVNTIiwgInVuY2VydGFpbl9maWVsZHMiOiBOb25lfSkKICAgICAgICB0YXJnZXQgPSBsYW1iZGE6IF9wcm92aWRlcigiQU5BLlNFTUkuUFJFRkxJR0hULlRBUkdFVFNUQVRFLlYwMDEiLCB7CiAgICAgICAgICAgICJjYW5kaWRhdGVfcnVuX2V4aXN0cyI6IEZhbHNlLCAibWF0ZXJpYWxpemVkX3RhcmdldF9jb3VudCI6IDAsCiAgICAgICAgICAgICJzY2hlbWFfaWQiOiAiQU5BLlNFTUkuUFJFRkxJR0hULlRBUkdFVFNUQVRFLlYwMDEiLCAic3RhdHVzIjogIlBBU1MiLAogICAgICAgICAgICAidGFyZ2V0X2V4aXN0aW5nX2NvdW50IjogMCwgInVuY2VydGFpbl9maWVsZHMiOiBOb25lfSkKICAgICAgICBoaXN0b3J5ID0gbGFtYmRhOiBfcHJvdmlkZXIoIkFOQS5TRU1JLlBSRUZMSUdIVC5ISVNUT1JZLlYwMDEiLCB7CiAgICAgICAgICAgICJoaXN0b3J5X2hhc2hfbWlzbWF0Y2hfY291bnQiOiAwLCAic2NoZW1hX2lkIjogIkFOQS5TRU1JLlBSRUZMSUdIVC5ISVNUT1JZLlYwMDEiLAogICAgICAgICAgICAic3RhdHVzIjogIlBBU1MiLCAidW5jZXJ0YWluX2ZpZWxkcyI6IE5vbmV9KQogICAgICAgIHNuYXBzaG90ID0gbGFtYmRhOiBfcHJvdmlkZXIoIkFOQS5TRU1JLlBSRUZMSUdIVC5TTkFQU0hPVC5WMDAxIiwgewogICAgICAgICAgICAiYWRhcHRlcl9zdGF0dXMiOiAiUEFTUyIsICJyb3dzIjogW10sICJzY2hlbWFfaWQiOiAiQU5BLlNFTUkuUFJFRkxJR0hULlNOQVBTSE9ULlYwMDEiLAogICAgICAgICAgICAic25hcHNob3RfaWQiOiAiU1lOVEhFVElDLVpFUk8iLCAidW5jZXJ0YWluX2ZpZWxkcyI6IE5vbmV9KQogICAgICAgIGludm9rZSA9IGltcGxlbWVudGF0aW9uLmludm9rZV9wcmVjb25zdW1wdGlvbl9wcmVmbGlnaHQoCiAgICAgICAgICAgIGF1dGhvcml6YXRpb25faWQ9IkFVVEgtVEVTVCIsIGF1dGhvcml6ZWRfYXRfcmF3PSIyMDI2LTA3LTI2VDAxOjEyOjU4LjI3NDg4MjArMDg6MDAiLAogICAgICAgICAgICBleHBpcmVzX2F0X3Jhdz0iMjAyNi0wNy0yNlQwMzoxMjo1OC4yNzQ4ODIwKzA4OjAwIiwgZXhwZWN0ZWRfcGxhbl9ieXRlcz0xMTE3MywKICAgICAgICAgICAgZXhwZWN0ZWRfcGxhbl9zaGEyNTY9IjIzNWFhYTFlZjNlYWQ2M2YwYjcyOTIzOWRlOTVlODlhYjU0Y2ZmZTBmMmI4MGE0YTdlYWMyZTU2MzEyMGZjOTMiLAogICAgICAgICAgICBleHBlY3RlZF9vdXRlcl9leGVjdXRhYmxlX3BhdGg9IkM6XFxXaW5kb3dzXFxTeXN0ZW0zMlxcV2luZG93c1Bvd2VyU2hlbGxcXHYxLjBcXHBvd2Vyc2hlbGwuZXhlIiwKICAgICAgICAgICAgZXhwZWN0ZWRfb3V0ZXJfY29tbWFuZF9saW5lX3NoYTI1Nj1fc2hhKGV4cGVjdGVkX2J5dGVzKSwKICAgICAgICAgICAgZXhwZWN0ZWRfb3V0ZXJfY29tbWFuZF9saW5lX2Jhc2U2ND1iYXNlNjQuYjY0ZW5jb2RlKGV4cGVjdGVkX2J5dGVzKS5kZWNvZGUoImFzY2lpIiksCiAgICAgICAgICAgIHNvdXJjZV9wcmVmbGlnaHRfcHJvY2Vzc19pZD1vcy5nZXRwaWQoKSwgcHJvaGliaXRlZF9leGVjdXRhYmxlX3BhdGhzPVtdLAogICAgICAgICAgICBpbnZvY2F0aW9uX2dhdGU9aW1wbGVtZW50YXRpb24uSW52b2NhdGlvbkdhdGUoKSwKICAgICAgICAgICAgbm93X3Byb3ZpZGVyPWxhbWJkYTogZHQuZGF0ZXRpbWUuZnJvbWlzb2Zvcm1hdCgiMjAyNi0wNy0yNVQxODowMDowMC4wMDAwMDArMDA6MDAiKSwKICAgICAgICAgICAgaWRlbnRpdHlfcHJvdmlkZXI9aWRlbnRpdHksIHBsYW5faGFzaF9wcm92aWRlcj1wbGFuX2hhc2gsIHRhcmdldF9zdGF0ZV9wcm92aWRlcj10YXJnZXQsCiAgICAgICAgICAgIGhpc3RvcnlfcHJvdmlkZXI9aGlzdG9yeSwgcHJvY2Vzc19zbmFwc2hvdF9wcm92aWRlcj1zbmFwc2hvdCkKICAgICAgICBhcGlfcm93cyA9IFtfYXBpX3JvdygiQ09OVkVSVCIsIHdpbmRvdyksIF9hcGlfcm93KCJJTlZPS0UiLCBpbnZva2UpLAogICAgICAgICAgICAgICAgICAgIF9hcGlfcm93KCJTRUxFQ1RPUiIsIHNlbGVjdG9yKSwgX2FwaV9yb3coIlRFU1QiLCB3aW5kb3dfdGVzdCldCiAgICAgICAgaWYgYW55KHZhbHVlLmdldCgic3RhdHVzIikgIT0gIlBBU1MiIGZvciB2YWx1ZSBpbiAod2luZG93LCB3aW5kb3dfdGVzdCwgc2VsZWN0b3IsIGludm9rZSkpOgogICAgICAgICAgICBjb250cmFjdF9mYWlsICs9IDEKICAgICAgICB5MDZfb2JqZWN0ID0gewogICAgICAgICAgICAiYXBpX25lZ2F0aXZlX3Jlc3VsdHMiOiBbX21hdGNoKGNhc2VfaWQpIGZvciBjYXNlX2lkIGluIHZlY3RvcnNbImFwaV9uZWdhdGl2ZV9jYXNlcyJdXSwKICAgICAgICAgICAgImFwaV9yZXN1bHRzIjogYXBpX3Jvd3MsCiAgICAgICAgICAgICJwcmVmbGlnaHRfcmVzdWx0cyI6IFtfbWF0Y2goY2FzZV9pZCkgZm9yIGNhc2VfaWQgaW4gdmVjdG9yc1sicHJlZmxpZ2h0X2Nhc2VzIl1dLAogICAgICAgICAgICAicHJvY2Vzc19zZWxlY3Rvcl9yZXN1bHRzIjogW19tYXRjaChjYXNlX2lkKSBmb3IgY2FzZV9pZCBpbiB2ZWN0b3JzWyJwcm9jZXNzX3NlbGVjdG9yX2Nhc2VzIl1dLAogICAgICAgICAgICAicHJvdmlkZXJfcHJlY2VkZW5jZV9yZXN1bHRzIjogW19tYXRjaChjYXNlX2lkKSBmb3IgY2FzZV9pZCBpbiB2ZWN0b3JzWyJwcm92aWRlcl9wcmVjZWRlbmNlX2Nhc2VzIl1dLAogICAgICAgICAgICAic2NoZW1hX2lkIjogIkFOQS1TRU1JLVBSRUNPTlNVTVBUSU9OLUNPTlRSQUNULVJFU1VMVC1KQ1MtVjAwNiIsCiAgICAgICAgICAgICJzdGF0dXMiOiAiVEVTVF9QQVNTIiBpZiBjb250cmFjdF9mYWlsID09IDAgZWxzZSAiVEVTVF9GQUlMIiwKICAgICAgICAgICAgInN1bW1hcnkiOiB7ImFwaV9mYWlsX2NvdW50IjogY29udHJhY3RfZmFpbCwgImFwaV9uZWdhdGl2ZV9mYWlsX2NvdW50IjogMCwKICAgICAgICAgICAgICAgICAgICAgICAgImFwaV9uZWdhdGl2ZV9wYXNzX2NvdW50IjogOCwgImFwaV9uZWdhdGl2ZV90b3RhbF9jb3VudCI6IDgsCiAgICAgICAgICAgICAgICAgICAgICAgICJjYXNlX2ZhaWxfY291bnQiOiBjb250cmFjdF9mYWlsLCAiY2FzZV9wYXNzX2NvdW50IjogMzAgLSBjb250cmFjdF9mYWlsLAogICAgICAgICAgICAgICAgICAgICAgICAiY2FzZV90b3RhbF9jb3VudCI6IDMwLCAicHJlY2VkZW5jZV9mYWlsX2NvdW50IjogMCwKICAgICAgICAgICAgICAgICAgICAgICAgInByZWNlZGVuY2VfcGFzc19jb3VudCI6IDQsICJwcmVjZWRlbmNlX3RvdGFsX2NvdW50IjogNCwKICAgICAgICAgICAgICAgICAgICAgICAgInN0YXR1cyI6ICJURVNUX1BBU1MiIGlmIGNvbnRyYWN0X2ZhaWwgPT0gMCBlbHNlICJURVNUX0ZBSUwifSwKICAgICAgICAgICAgInRpbWVfcmVzdWx0cyI6IFtfbWF0Y2goY2FzZV9pZCkgZm9yIGNhc2VfaWQgaW4gdmVjdG9yc1sidGltZV9jYXNlcyJdXSwKICAgICAgICB9CiAgICAgICAgX3dyaXRlX2pjcyh5MDYsIHkwNl9vYmplY3QpCiAgICB2YXJpYW50ID0gIlNUQVRJQ19GQUlMIiBpZiBzdGF0aWNfZmFpbCBlbHNlICgiQ09OVFJBQ1RfRkFJTCIgaWYgY29udHJhY3RfZmFpbCBlbHNlICJQQVNTIikKICAgIHBsYW5faWQgPSAiQ09ERS1ERVNJR04tQU5BLVNFTUktUk9PVC1QUkVGTElHSFQtT1JDSEVTVFJBVElPTi1WMDA3LVYwMjAiCiAgICBpbXBsZW1lbnRhdGlvbi53cml0ZV9jcmVhdGVfbmV3X2J5dGVzKHkwNywgX3JlY2VpcHQocnVuX2lkLCBwbGFuX2lkLCB2YXJpYW50KSkKICAgIGRlZmluaXRpb25zID0gWwogICAgICAgICgiWTAxIiwgIlNPVVJDRSIsICJBTkEtU0VNSS1QUkVDT05TVU1QVElPTi1NT0RVTEUtUFktVjAwMSIsICJkZXYvYW5hLWRldi9hbmFfc2VtaV9wcmVjb25zdW1wdGlvbl92MDAyLnB5IiwgInRleHQveC1weXRob247IGNoYXJzZXQ9dXRmLTgiLCAiUkVRVUlSRURfQkVGT1JFX09VVEVSIiwgc3RyKG1vZHVsZV9wYXRoKSksCiAgICAgICAgKCJZMDIiLCAiVEVTVF9TT1VSQ0UiLCAiQU5BLVNFTUktUFJFQ09OU1VNUFRJT04tU1RBVElDLVRFU1QtUFktVjAwMSIsICJkZXYvYW5hLWRldi90ZXN0L3Rlc3RfYW5hX3NlbWlfcHJlY29uc3VtcHRpb25fdjAwMi5weSIsICJ0ZXh0L3gtcHl0aG9uOyBjaGFyc2V0PXV0Zi04IiwgIlJFUVVJUkVEX0JFRk9SRV9PVVRFUiIsIHN0cihzdGF0aWNfcGF0aCkpLAogICAgICAgICgiWTAzIiwgIlRFU1RfVkVDVE9SIiwgIkFOQS1TRU1JLVBSRUNPTlNVTVBUSU9OLVZFQ1RPUlMtSkNTLVYwMDUiLCAiZGV2L2FuYS1kZXYvdGVzdC9hbmFfc2VtaV9wcmVjb25zdW1wdGlvbl92ZWN0b3JzX3YwMDIuanNvbiIsICJhcHBsaWNhdGlvbi9qY3MranNvbiIsICJSRVFVSVJFRF9CRUZPUkVfT1VURVIiLCBzdHIodmVjdG9yX3BhdGgpKSwKICAgICAgICAoIlkwNCIsICJWQUxJREFUSU9OX1NPVVJDRSIsICJBTkEtU0VNSS1QUkVDT05TVU1QVElPTi1WQUxJREFUSU9OLVBZLVYwMDEiLCAiZGV2L2FuYS1kZXYvdGVzdC9ydW5fYW5hX3NlbWlfcHJlY29uc3VtcHRpb25fdmFsaWRhdGlvbl92MDAyLnB5IiwgInRleHQveC1weXRob247IGNoYXJzZXQ9dXRmLTgiLCAiUkVRVUlSRURfQkVGT1JFX09VVEVSIiwgc3RyKHZhbGlkYXRpb25fcGF0aCkpLAogICAgICAgICgiWTA1IiwgIlRFU1RfUkVTVUxUIiwgIkFOQS1TRU1JLVBSRUNPTlNVTVBUSU9OLVNUQVRJQy1SRVNVTFQtSkNTLVYwMDIiLCBmImRldi9hbmEtZGV2L3RtcC97cnVuX2lkfS90ZXN0L3N0YXRpYy1yZXN1bHQuanNvbiIsICJhcHBsaWNhdGlvbi9qY3MranNvbiIsICJSRVFVSVJFRF9PTl9TVEFUSUNfU1RBR0UiLCBzdHIoeTA1KSksCiAgICAgICAgKCJZMDYiLCAiVEVTVF9SRVNVTFQiLCAiQU5BLVNFTUktUFJFQ09OU1VNUFRJT04tQ09OVFJBQ1QtUkVTVUxULUpDUy1WMDA2IiwgZiJkZXYvYW5hLWRldi90bXAve3J1bl9pZH0vdGVzdC9jb250cmFjdC1yZXN1bHQuanNvbiIsICJhcHBsaWNhdGlvbi9qY3MranNvbiIsICJSRVFVSVJFRF9PTl9DT05UUkFDVF9TVEFHRSIsIHN0cih5MDYpKSwKICAgICAgICAoIlkwNyIsICJSRUNFSVBUIiwgIkFOQS1TRU1JLVBSRUNPTlNVTVBUSU9OLVJFQ0VJUFQtTUQtVjAwNSIsIGYiZGV2L2FuYS1kZXYvdG1wL3tydW5faWR9L3JlY2VpcHQvcHJlZmxpZ2h0LXJlcGFpci1yZWNlaXB0Lm1kIiwgInRleHQvbWFya2Rvd247IGNoYXJzZXQ9dXRmLTgiLCAiUkVRVUlSRURfT05fQ0xPU1VSRV9TVEFHRSIsIHN0cih5MDcpKSwKICAgICAgICAoIlkwOCIsICJNQU5JRkVTVCIsICJBTkEtU0VNSS1QUkVDT05TVU1QVElPTi1NQU5JRkVTVC1DU1YtVjAwMiIsIGYiZGV2L2FuYS1kZXYvdG1wL3tydW5faWR9L21hbmlmZXN0L3ByZWZsaWdodC1yZXBhaXItbWFuaWZlc3QuY3N2IiwgInRleHQvY3N2OyBjaGFyc2V0PXV0Zi04IiwgIlNFTEYiLCBzdHIoeTA4KSksCiAgICBdCiAgICBpbXBsZW1lbnRhdGlvbi53cml0ZV9jcmVhdGVfbmV3X2J5dGVzKHkwOCwgX21hbmlmZXN0KHJ1bl9pZCwgZGVmaW5pdGlvbnMsIHN0YXRpY19mYWlsLCBjb250cmFjdF9mYWlsKSkKICAgIHJldHVybiAwIGlmIHZhcmlhbnQgPT0gIlBBU1MiIGVsc2UgMTEKCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgaWYgbGVuKHN5cy5hcmd2KSAhPSA0OgogICAgICAgIHJhaXNlIFN5c3RlbUV4aXQoMjcpCiAgICByYWlzZSBTeXN0ZW1FeGl0KG1haW4ocGF0aGxpYi5QYXRoKHN5cy5hcmd2WzFdKSwgc3lzLmFyZ3ZbMl0sIHBhdGhsaWIuUGF0aChzeXMuYXJndlszXSkpKQo=
固定验证合同:
0x7D。ensure_ascii=false,separators=(',',':'),sort_keys=true canonical 重序列化 byte-identical。