paiban/.codex/sessions/2025/09/22/rollout-2025-09-22T21-56-08-019971b5-dcee-7370-80b5-8fa3660a03ab.jsonl
Developer 7c80f73079 1111
2025-09-23 08:33:50 +08:00

35 lines
189 KiB
JSON
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"timestamp":"2025-09-22T13:56:13.064Z","type":"session_meta","payload":{"id":"019971b5-dcee-7370-80b5-8fa3660a03ab","timestamp":"2025-09-22T13:56:08.046Z","cwd":"c:\\GitCode\\paiban","originator":"codex_vscode","cli_version":"0.39.0","instructions":"## 开发规则\r\n\r\n你是一名经验丰富的[专业领域,例如:软件开发工程师 / 系统设计师 / 代码架构师],专注于构建[核心特长,例如:高性能 / 可维护 / 健壮 / 领域驱动]的解决方案。\r\n\r\n你的任务是**审查、理解并迭代式地改进/推进一个[项目类型,例如:现有代码库 / 软件项目 / 技术流程]。**\r\n\r\n在整个工作流程中你必须内化并严格遵循以下核心编程原则确保你的每次输出和建议都体现这些理念\r\n\r\n- **简单至上 (KISS):** 追求代码和设计的极致简洁与直观,避免不必要的复杂性。\r\n- **精益求精 (YAGNI):** 仅实现当前明确所需的功能,抵制过度设计和不必要的未来特性预留。\r\n- **坚实基础 (SOLID):**\r\n - **S (单一职责):** 各组件、类、函数只承担一项明确职责。\r\n - **O (开放/封闭):** 功能扩展无需修改现有代码。\r\n - **L (里氏替换):** 子类型可无缝替换其基类型。\r\n - **I (接口隔离):** 接口应专一,避免“胖接口”。\r\n - **D (依赖倒置):** 依赖抽象而非具体实现。\r\n- **杜绝重复 (DRY):** 识别并消除代码或逻辑中的重复模式,提升复用性。\r\n\r\n**请严格遵循以下工作流程和输出要求:**\r\n\r\n1. **深入理解与初步分析(理解阶段):**\r\n\r\n - 详细审阅提供的[资料/代码/项目描述],全面掌握其当前架构、核心组件、业务逻辑及痛点。\r\n - 在理解的基础上,初步识别项目中潜在的**KISS, YAGNI, DRY, SOLID**原则应用点或违背现象。\r\n\r\n2. **明确目标与迭代规划(规划阶段):**\r\n\r\n - 基于用户需求和对现有项目的理解,清晰定义本次迭代的具体任务范围和可衡量的预期成果。\r\n - 在规划解决方案时,优先考虑如何通过应用上述原则,实现更简洁、高效和可扩展的改进,而非盲目增加功能。\r\n\r\n3. **分步实施与具体改进(执行阶段):**\r\n\r\n - 详细说明你的改进方案,并将其拆解为逻辑清晰、可操作的步骤。\r\n - 针对每个步骤,具体阐述你将如何操作,以及这些操作如何体现**KISS, YAGNI, DRY, SOLID**原则。例如:\r\n - “将此模块拆分为更小的服务,以遵循 SRP 和 OCP。”\r\n - “为避免 DRY将重复的 XXX 逻辑抽象为通用函数。”\r\n - “简化了 Y 功能的用户流,体现 KISS 原则。”\r\n - “移除了 Z 冗余设计,遵循 YAGNI 原则。”\r\n - 重点关注[项目类型,例如:代码质量优化 / 架构重构 / 功能增强 / 用户体验提升 / 性能调优 / 可维护性改善 / Bug 修复]的具体实现细节。\r\n\r\n4. **总结、反思与展望(汇报阶段):**\r\n - 提供一个清晰、结构化且包含**实际代码/设计变动建议(如果适用)**的总结报告。\r\n - 报告中必须包含:\r\n - **本次迭代已完成的核心任务**及其具体成果。\r\n - **本次迭代中,你如何具体应用了** **KISS, YAGNI, DRY, SOLID** **原则**,并简要说明其带来的好处(例如,代码量减少、可读性提高、扩展性增强)。\r\n - **遇到的挑战**以及如何克服。\r\n - **下一步的明确计划和建议。**\r\n\r\n---\r\n\r\n# MCP 服务调用规则\r\n\r\n## 核心策略\r\n\r\n- **审慎单选**:优先离线工具,确需外呼时每轮最多 1 个 MCP 服务\r\n- **序贯调用**:多服务需求时必须串行,明确说明每步理由和产出预期\r\n- **最小范围**:精确限定查询参数,避免过度抓取和噪声\r\n- **可追溯性**:答复末尾统一附加\"工具调用简报\"\r\n\r\n## 服务选择优先级\r\n\r\n### 1. Serena本地代码分析优先\r\n\r\n**工具能力**find_symbol, find_referencing_symbols, get_symbols_overview, search_for_pattern, read_file, replace_symbol_body, create_text_file, execute_shell_command\r\n**触发场景**:代码检索、架构分析、跨文件引用、项目理解\r\n**调用策略**\r\n\r\n- 先用 get_symbols_overview 快速了解文件结构\r\n- find_symbol 精确定位(支持 name_path 模式匹配)\r\n- search_for_pattern 用于复杂正则搜索\r\n- 限制 relative_path 到相关目录,避免全项目扫描\r\n\r\n### 2. Context7官方文档查询\r\n\r\n**流程**resolve-library-id → get-library-docs\r\n**触发场景**:框架 API、配置文档、版本差异、迁移指南\r\n**限制参数**tokens≤5000, topic 指定聚焦范围\r\n\r\n### 3. Sequential Thinking复杂规划\r\n\r\n**触发场景**:多步骤任务分解、架构设计、问题诊断流程\r\n**输出要求**6-10 步可执行计划,不暴露推理过程\r\n**参数控制**total_thoughts≤10, 每步一句话描述\r\n\r\n### 4. DuckDuckGo外部信息\r\n\r\n**触发场景**最新信息、官方公告、breaking changes\r\n**查询优化**≤12 关键词 + 限定词site:, after:, filetype:\r\n**结果控制**≤35 条,优先官方域名,过滤内容农场\r\n\r\n### 5. Playwright浏览器自动化\r\n\r\n**触发场景**网页截图、表单测试、SPA 交互验证\r\n**安全限制**:仅开发测试用途\r\n\r\n## 错误处理和降级\r\n\r\n### 失败策略\r\n\r\n- **429 限流**:退避 20s降低参数范围\r\n- **5xx/超时**:单次重试,退避 2s\r\n- **无结果**:缩小范围或请求澄清\r\n\r\n### 降级链路\r\n\r\n1. Context7 → DuckDuckGo(site:官方域名)\r\n2. DuckDuckGo → 请求用户提供线索\r\n3. Serena → 使用 Claude Code 本地工具\r\n4. 最终降级 → 保守离线答案 + 标注不确定性\r\n\r\n## 实际调用约束\r\n\r\n### 禁用场景\r\n\r\n- 网络受限且未明确授权\r\n- 查询包含敏感代码/密钥\r\n- 本地工具可充分完成任务\r\n\r\n### 并发控制\r\n\r\n- **严格串行**:禁止同轮并发调用多个 MCP 服务\r\n- **意图分解**:多服务需求时拆分为多轮对话\r\n- **明确预期**:每次调用前说明预期产出和后续步骤\r\n\r\n## 工具调用简报格式\r\n\r\n【MCP调用简报】\r\n服务: <serena|context7|sequential-thinking|ddg-search|playwright>\r\n触发: <具体原因>\r\n参数: <关键参数摘要>\r\n结果: <命中数/主要来源>\r\n状态: <成功|重试|降级>\r\n## 典型调用模式\r\n\r\n### 代码分析模式\r\n\r\n1. serena.get_symbols_overview → 了解文件结构\r\n2. serena.find_symbol → 定位具体实现\r\n3. serena.find_referencing_symbols → 分析调用关系\r\n\r\n### 文档查询模式\r\n\r\n1. context7.resolve-library-id → 确定库标识\r\n2. context7.get-library-docs → 获取相关文档段落\r\n\r\n### 规划执行模式\r\n\r\n1. sequential-thinking → 生成执行计划\r\n2. serena 工具链 → 逐步实施代码修改\r\n3. 验证测试 → 确保修改正确性\r\n\r\n\r\n### 编码输出/语言偏好###\r\n## Communication & Language\r\n- Default language: Simplified Chinese for issues, PRs, and assistant replies, unless a thread explicitly requests English.\r\n- Keep code identifiers, CLI commands, logs, and error messages in their original language; add concise Chinese explanations when helpful.\r\n- To switch languages, state it clearly in the conversation or PR description.\r\n\r\n## File Encoding\r\nWhen modifying or adding any code files, the following coding requirements must be adhered to:\r\n- Encoding should be unified to UTF-8 (without BOM). It is strictly prohibited to use other local encodings such as GBK/ANSI, and it is strictly prohibited to submit content containing unreadable characters.\r\n- When modifying or adding files, be sure to save them in UTF-8 format; if you find any files that are not in UTF-8 format before submitting, please convert them to UTF-8 before submitting.\n\n--- project-doc ---\n\n# Repository Guidelines\r\n\r\n## Project Structure & Module Organization\r\nSource lives under the solution `NPP.SmartSchedue.sln`. `NPP.SmartSchedue.Host` hosts the ASP.NET Core app, with environment settings in `appsettings*.json`, seed scripts in `ConfigCenter` and `InitData`, and static assets in `wwwroot`. Domain services sit in `NPP.SmartSchedue.Api`, organized into `Core` (attributes, constants), `Services` (business logic), and `Repositories` (data access). Shared contracts, DTOs, and interfaces reside in `NPP.SmartSchedue.Api.Contracts`; keep cross-project types there. Tests are in `NPP.SmartSchedue.Tests`, with reusable fixtures in `BaseTest` and service-focused integration suites under `Services`.\r\n\r\n## Build, Test, and Development Commands\r\n- `dotnet restore NPP.SmartSchedue.sln` restores all project dependencies.\r\n- `dotnet build NPP.SmartSchedue.sln -c Release` validates compilation; use `-c Debug` during local iteration.\r\n- `dotnet run --project NPP.SmartSchedue.Host` boots the API with the default profile; add `--launch-profile Development` when you need local CAP setups.\r\n- `dotnet test NPP.SmartSchedue.Tests/NPP.SmartSchedue.Tests.csproj --logger \"trx;LogFileName=test-results.trx\"` exercises the xUnit suites and saves artifacts for PR review.\r\n\r\n## Coding Style & Naming Conventions\r\nTarget .NET 9 defaults: four-space indentation, braces on new lines, and explicit namespaces. Use `PascalCase` for classes, public members, and DTOs, `camelCase` for locals and private fields, and prefix interfaces with `I` as seen in `Api.Contracts`. Suffix asynchronous methods with `Async`, and keep request/response models in the Contracts project. Run `dotnet format` before committing to enforce spacing and using-order consistency.\r\n\r\n## Testing Guidelines\r\nWrite xUnit tests alongside existing patterns such as `EquipmentMaintenanceIntegrationTest`. Name new files `{Feature}Test.cs` or `{Feature}IntegrationTest.cs`, group helper logic in `BaseTest`, and rely on `Microsoft.AspNetCore.Mvc.Testing` for host bootstrapping. Aim to cover new service paths and repository edge cases; add mocks via Moq where external systems (CAP, RabbitMQ, MySQL) would otherwise be required.\r\n\r\n## Commit & Pull Request Guidelines\r\nPrefer descriptive commits (`feat(scheduling): add notification workflow`) instead of numeric placeholders seen in recent history. Bundle related changes, include migration or config adjustments in the same commit, and reference tracking IDs where relevant. Pull requests should outline the change, list manual or automated test evidence, mention configuration impacts (CAP, FreeSql, message queues), and supply screenshots for any UI updates under `wwwroot`.\r\n\r\n## Configuration & Environment Notes\r\nKeep secrets out of `appsettings.json`; use user secrets or environment variables for connection strings and CAP brokers. Document any required RabbitMQ or MySQL endpoints in the PR. When adding assets or scripts, mirror the structure under `ConfigCenter`, `InitData`, and `wwwroot` so the publish targets continue copying them correctly.\r\n"}}
{"timestamp":"2025-09-22T13:56:13.065Z","type":"response_item","payload":{"type":"message","role":"user","content":[{"type":"input_text","text":"<user_instructions>\n\n## 开发规则\r\n\r\n你是一名经验丰富的[专业领域,例如:软件开发工程师 / 系统设计师 / 代码架构师],专注于构建[核心特长,例如:高性能 / 可维护 / 健壮 / 领域驱动]的解决方案。\r\n\r\n你的任务是**审查、理解并迭代式地改进/推进一个[项目类型,例如:现有代码库 / 软件项目 / 技术流程]。**\r\n\r\n在整个工作流程中你必须内化并严格遵循以下核心编程原则确保你的每次输出和建议都体现这些理念\r\n\r\n- **简单至上 (KISS):** 追求代码和设计的极致简洁与直观,避免不必要的复杂性。\r\n- **精益求精 (YAGNI):** 仅实现当前明确所需的功能,抵制过度设计和不必要的未来特性预留。\r\n- **坚实基础 (SOLID):**\r\n - **S (单一职责):** 各组件、类、函数只承担一项明确职责。\r\n - **O (开放/封闭):** 功能扩展无需修改现有代码。\r\n - **L (里氏替换):** 子类型可无缝替换其基类型。\r\n - **I (接口隔离):** 接口应专一,避免“胖接口”。\r\n - **D (依赖倒置):** 依赖抽象而非具体实现。\r\n- **杜绝重复 (DRY):** 识别并消除代码或逻辑中的重复模式,提升复用性。\r\n\r\n**请严格遵循以下工作流程和输出要求:**\r\n\r\n1. **深入理解与初步分析(理解阶段):**\r\n\r\n - 详细审阅提供的[资料/代码/项目描述],全面掌握其当前架构、核心组件、业务逻辑及痛点。\r\n - 在理解的基础上,初步识别项目中潜在的**KISS, YAGNI, DRY, SOLID**原则应用点或违背现象。\r\n\r\n2. **明确目标与迭代规划(规划阶段):**\r\n\r\n - 基于用户需求和对现有项目的理解,清晰定义本次迭代的具体任务范围和可衡量的预期成果。\r\n - 在规划解决方案时,优先考虑如何通过应用上述原则,实现更简洁、高效和可扩展的改进,而非盲目增加功能。\r\n\r\n3. **分步实施与具体改进(执行阶段):**\r\n\r\n - 详细说明你的改进方案,并将其拆解为逻辑清晰、可操作的步骤。\r\n - 针对每个步骤,具体阐述你将如何操作,以及这些操作如何体现**KISS, YAGNI, DRY, SOLID**原则。例如:\r\n - “将此模块拆分为更小的服务,以遵循 SRP 和 OCP。”\r\n - “为避免 DRY将重复的 XXX 逻辑抽象为通用函数。”\r\n - “简化了 Y 功能的用户流,体现 KISS 原则。”\r\n - “移除了 Z 冗余设计,遵循 YAGNI 原则。”\r\n - 重点关注[项目类型,例如:代码质量优化 / 架构重构 / 功能增强 / 用户体验提升 / 性能调优 / 可维护性改善 / Bug 修复]的具体实现细节。\r\n\r\n4. **总结、反思与展望(汇报阶段):**\r\n - 提供一个清晰、结构化且包含**实际代码/设计变动建议(如果适用)**的总结报告。\r\n - 报告中必须包含:\r\n - **本次迭代已完成的核心任务**及其具体成果。\r\n - **本次迭代中,你如何具体应用了** **KISS, YAGNI, DRY, SOLID** **原则**,并简要说明其带来的好处(例如,代码量减少、可读性提高、扩展性增强)。\r\n - **遇到的挑战**以及如何克服。\r\n - **下一步的明确计划和建议。**\r\n\r\n---\r\n\r\n# MCP 服务调用规则\r\n\r\n## 核心策略\r\n\r\n- **审慎单选**:优先离线工具,确需外呼时每轮最多 1 个 MCP 服务\r\n- **序贯调用**:多服务需求时必须串行,明确说明每步理由和产出预期\r\n- **最小范围**:精确限定查询参数,避免过度抓取和噪声\r\n- **可追溯性**:答复末尾统一附加\"工具调用简报\"\r\n\r\n## 服务选择优先级\r\n\r\n### 1. Serena本地代码分析优先\r\n\r\n**工具能力**find_symbol, find_referencing_symbols, get_symbols_overview, search_for_pattern, read_file, replace_symbol_body, create_text_file, execute_shell_command\r\n**触发场景**:代码检索、架构分析、跨文件引用、项目理解\r\n**调用策略**\r\n\r\n- 先用 get_symbols_overview 快速了解文件结构\r\n- find_symbol 精确定位(支持 name_path 模式匹配)\r\n- search_for_pattern 用于复杂正则搜索\r\n- 限制 relative_path 到相关目录,避免全项目扫描\r\n\r\n### 2. Context7官方文档查询\r\n\r\n**流程**resolve-library-id → get-library-docs\r\n**触发场景**:框架 API、配置文档、版本差异、迁移指南\r\n**限制参数**tokens≤5000, topic 指定聚焦范围\r\n\r\n### 3. Sequential Thinking复杂规划\r\n\r\n**触发场景**:多步骤任务分解、架构设计、问题诊断流程\r\n**输出要求**6-10 步可执行计划,不暴露推理过程\r\n**参数控制**total_thoughts≤10, 每步一句话描述\r\n\r\n### 4. DuckDuckGo外部信息\r\n\r\n**触发场景**最新信息、官方公告、breaking changes\r\n**查询优化**≤12 关键词 + 限定词site:, after:, filetype:\r\n**结果控制**≤35 条,优先官方域名,过滤内容农场\r\n\r\n### 5. Playwright浏览器自动化\r\n\r\n**触发场景**网页截图、表单测试、SPA 交互验证\r\n**安全限制**:仅开发测试用途\r\n\r\n## 错误处理和降级\r\n\r\n### 失败策略\r\n\r\n- **429 限流**:退避 20s降低参数范围\r\n- **5xx/超时**:单次重试,退避 2s\r\n- **无结果**:缩小范围或请求澄清\r\n\r\n### 降级链路\r\n\r\n1. Context7 → DuckDuckGo(site:官方域名)\r\n2. DuckDuckGo → 请求用户提供线索\r\n3. Serena → 使用 Claude Code 本地工具\r\n4. 最终降级 → 保守离线答案 + 标注不确定性\r\n\r\n## 实际调用约束\r\n\r\n### 禁用场景\r\n\r\n- 网络受限且未明确授权\r\n- 查询包含敏感代码/密钥\r\n- 本地工具可充分完成任务\r\n\r\n### 并发控制\r\n\r\n- **严格串行**:禁止同轮并发调用多个 MCP 服务\r\n- **意图分解**:多服务需求时拆分为多轮对话\r\n- **明确预期**:每次调用前说明预期产出和后续步骤\r\n\r\n## 工具调用简报格式\r\n\r\n【MCP调用简报】\r\n服务: <serena|context7|sequential-thinking|ddg-search|playwright>\r\n触发: <具体原因>\r\n参数: <关键参数摘要>\r\n结果: <命中数/主要来源>\r\n状态: <成功|重试|降级>\r\n## 典型调用模式\r\n\r\n### 代码分析模式\r\n\r\n1. serena.get_symbols_overview → 了解文件结构\r\n2. serena.find_symbol → 定位具体实现\r\n3. serena.find_referencing_symbols → 分析调用关系\r\n\r\n### 文档查询模式\r\n\r\n1. context7.resolve-library-id → 确定库标识\r\n2. context7.get-library-docs → 获取相关文档段落\r\n\r\n### 规划执行模式\r\n\r\n1. sequential-thinking → 生成执行计划\r\n2. serena 工具链 → 逐步实施代码修改\r\n3. 验证测试 → 确保修改正确性\r\n\r\n\r\n### 编码输出/语言偏好###\r\n## Communication & Language\r\n- Default language: Simplified Chinese for issues, PRs, and assistant replies, unless a thread explicitly requests English.\r\n- Keep code identifiers, CLI commands, logs, and error messages in their original language; add concise Chinese explanations when helpful.\r\n- To switch languages, state it clearly in the conversation or PR description.\r\n\r\n## File Encoding\r\nWhen modifying or adding any code files, the following coding requirements must be adhered to:\r\n- Encoding should be unified to UTF-8 (without BOM). It is strictly prohibited to use other local encodings such as GBK/ANSI, and it is strictly prohibited to submit content containing unreadable characters.\r\n- When modifying or adding files, be sure to save them in UTF-8 format; if you find any files that are not in UTF-8 format before submitting, please convert them to UTF-8 before submitting.\n\n--- project-doc ---\n\n# Repository Guidelines\r\n\r\n## Project Structure & Module Organization\r\nSource lives under the solution `NPP.SmartSchedue.sln`. `NPP.SmartSchedue.Host` hosts the ASP.NET Core app, with environment settings in `appsettings*.json`, seed scripts in `ConfigCenter` and `InitData`, and static assets in `wwwroot`. Domain services sit in `NPP.SmartSchedue.Api`, organized into `Core` (attributes, constants), `Services` (business logic), and `Repositories` (data access). Shared contracts, DTOs, and interfaces reside in `NPP.SmartSchedue.Api.Contracts`; keep cross-project types there. Tests are in `NPP.SmartSchedue.Tests`, with reusable fixtures in `BaseTest` and service-focused integration suites under `Services`.\r\n\r\n## Build, Test, and Development Commands\r\n- `dotnet restore NPP.SmartSchedue.sln` restores all project dependencies.\r\n- `dotnet build NPP.SmartSchedue.sln -c Release` validates compilation; use `-c Debug` during local iteration.\r\n- `dotnet run --project NPP.SmartSchedue.Host` boots the API with the default profile; add `--launch-profile Development` when you need local CAP setups.\r\n- `dotnet test NPP.SmartSchedue.Tests/NPP.SmartSchedue.Tests.csproj --logger \"trx;LogFileName=test-results.trx\"` exercises the xUnit suites and saves artifacts for PR review.\r\n\r\n## Coding Style & Naming Conventions\r\nTarget .NET 9 defaults: four-space indentation, braces on new lines, and explicit namespaces. Use `PascalCase` for classes, public members, and DTOs, `camelCase` for locals and private fields, and prefix interfaces with `I` as seen in `Api.Contracts`. Suffix asynchronous methods with `Async`, and keep request/response models in the Contracts project. Run `dotnet format` before committing to enforce spacing and using-order consistency.\r\n\r\n## Testing Guidelines\r\nWrite xUnit tests alongside existing patterns such as `EquipmentMaintenanceIntegrationTest`. Name new files `{Feature}Test.cs` or `{Feature}IntegrationTest.cs`, group helper logic in `BaseTest`, and rely on `Microsoft.AspNetCore.Mvc.Testing` for host bootstrapping. Aim to cover new service paths and repository edge cases; add mocks via Moq where external systems (CAP, RabbitMQ, MySQL) would otherwise be required.\r\n\r\n## Commit & Pull Request Guidelines\r\nPrefer descriptive commits (`feat(scheduling): add notification workflow`) instead of numeric placeholders seen in recent history. Bundle related changes, include migration or config adjustments in the same commit, and reference tracking IDs where relevant. Pull requests should outline the change, list manual or automated test evidence, mention configuration impacts (CAP, FreeSql, message queues), and supply screenshots for any UI updates under `wwwroot`.\r\n\r\n## Configuration & Environment Notes\r\nKeep secrets out of `appsettings.json`; use user secrets or environment variables for connection strings and CAP brokers. Document any required RabbitMQ or MySQL endpoints in the PR. When adding assets or scripts, mirror the structure under `ConfigCenter`, `InitData`, and `wwwroot` so the publish targets continue copying them correctly.\r\n\n\n</user_instructions>"}]}}
{"timestamp":"2025-09-22T13:56:13.065Z","type":"response_item","payload":{"type":"message","role":"user","content":[{"type":"input_text","text":"<environment_context>\n <cwd>c:\\GitCode\\paiban</cwd>\n <approval_policy>never</approval_policy>\n <sandbox_mode>danger-full-access</sandbox_mode>\n <network_access>enabled</network_access>\n <shell>powershell.exe</shell>\n</environment_context>"}]}}
{"timestamp":"2025-09-22T13:56:13.065Z","type":"response_item","payload":{"type":"message","role":"user","content":[{"type":"input_text","text":"# Context from my IDE setup:\n\n## Active file: NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\n\n## Open tabs:\n- LinearProgrammingEngine.cs: NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\n\n## My request for Codex:\n加载全局的 提示词\n"}]}}
{"timestamp":"2025-09-22T13:56:13.065Z","type":"event_msg","payload":{"type":"user_message","message":"# Context from my IDE setup:\n\n## Active file: NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\n\n## Open tabs:\n- LinearProgrammingEngine.cs: NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\n\n## My request for Codex:\n加载全局的 提示词\n","kind":"plain"}}
{"timestamp":"2025-09-22T13:56:13.065Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:56:22.902Z","type":"event_msg","payload":{"type":"agent_reasoning","text":"**Interpreting global prompt request**"}}
{"timestamp":"2025-09-22T13:56:25.517Z","type":"event_msg","payload":{"type":"agent_message","message":"我需要了解你所说的“全局的提示词”具体是指什么:是项目里的某个配置文件、数据库内容,还是 IDE 中的某段说明?请再详细描述一下目标或期望结果,方便我准确执行。"}}
{"timestamp":"2025-09-22T13:56:25.537Z","type":"event_msg","payload":{"type":"token_count","info":{"total_token_usage":{"input_tokens":5409,"cached_input_tokens":2432,"output_tokens":380,"reasoning_output_tokens":320,"total_tokens":5789},"last_token_usage":{"input_tokens":5409,"cached_input_tokens":2432,"output_tokens":380,"reasoning_output_tokens":320,"total_tokens":5789},"model_context_window":272000}}}
{"timestamp":"2025-09-22T13:56:25.537Z","type":"response_item","payload":{"type":"reasoning","summary":[{"type":"summary_text","text":"**Interpreting global prompt request**"}],"content":null,"encrypted_content":"gAAAAABo0VWH-5yccgEnrkxRss1EY8QTt19KTbc8oNMLe8-eQDVQjkg86rMqvBXLX3xqZJhbYIXpaUlIFErDzFlNPRuUIZbRAGubyhn0z76WrgAGYR-RHIZQZrdz4vueEC4nA1mTmdLx7Sb4L8cIH-WMAr_LzCstNHpjv--8Hr__c3ctzPIuSnPyWOhHu1qIO0viOTsBwxs2AD8P0LJTaQzsZ7fuErv7OoPff7weJwrcbxGacWhexJXLZzaf4SpQ834TLNaj6_kln_3TpiKx8UBACQLXXyxAIpuaNzhCk8EaR11eJ-7YV7OyEK_RDSdXHl7Zm7jHVedwAtGCiXD__eLPgWFhbvBdbOUKC9Wl-mgDoO-TqdcyuH9eEAzFL5F55SA6XxhfbzBFVR8r7sEvWua39S-2Rai1r5mBulZjFmkeV1lSM6OMPfvOkPFWSt5w9X7bZ6rUyEgWDndnj6DB3Kb4WTetvteoif_jLXXXpactQLF0MIkAUTgHssDjEKHVOPb71hdbJcmQnZxGdqgkZJKh-e7Xhx-cZ7wbJH9ZBdqG2id3GYxvp7RmlfWNqNpO-3qN_20QXtc7c6B3jCRSVJTlPMsQqhYiw5B2o4SDKU82L2pLArLg-8xwFUwEDL15378M7NyMJwtRSte6980566w2-cx8d3_z2IP_qGrQoumeD--mu6L6VMQ8fTwvNxg4KzLXXf7qhe2IwQItot9VroSZ_un8KIZTLnxDSoWnuA70wq0ekzb9iB2ubr6h7yhxvKwcLFj9IH5PkxIVq7RQeGpQQpI8S35-h9Nm28HX_IwkHT9X6SDKSvgq9nHUCaJYakudAeLQlhVpetWemAGpLEUYlvIj8nUsigXXP8K1voWbStWRu1DNWBH5PphOBMHOEbyxeKPSueApCrIVs-GQZWyhNORvffTbuhAsox8AeroJznZQShKnEggvVTXRhGreRI07JSUJ_xsCxv3KdGmg7UV-wDQzhiEVx2EtD8_e1Yt9r24PxojIApwCOd_dpCDEjX3aH_sTDTQ07Q2HfPUTPWlxIJ3OpGT9QIfoSzSI9BRfbSSdaAquZ-ixal6rGCDNJtlSsrIXaYDcQ030wWj2D_L-_ahq5VJpG-VYSNUsv4M4-Y4Tkc8sSRVtHNtSlqfo2euhSzHT6YwvoNWWSH5ZrD3cw0t-kIv-HC2WbYBKwNuLCazv5ZkYR8ejKQjlbz-OVGPvT3WU66JnICSNs-NhxYUXkyBvN4S9Joy2E44rlFvOzjq1_-TwEl_YtWg85y5ojiyfBhQlv-gL3smROImUMfTh-cFcgdicYeWpbFIN5jEX-KAVbFgZCYl3JxL9UDsXLhL2_hLHk8F1sPXVzKrwApPvPoF-GTdQty81aQYtvbxMmzCstOZWC-hJhHS3Ctca3WliZQUn9setdiRuVCZ46O6OB-HtDxkHXuu7FBjh134UQpheHEEplFhJ143sKMuVCQf_zzVukPP4o0-kLEiiEpURpttN-uGHqHivpEjoeshFdeW3xebK00KFs1gKj-nbb1TOu4fhZM0Q9Qy13wCn92Sxid5ZjSISRdr8wau7MUodvdNMFKXjgBRg0XoaHdvDXXU2_MjIdeL56O4q7Y9MBb8BeHpQCDQtrHYIIax_f_kLzfHBM8g27zqLEg6rwSuUmw-DmedxSmw3IHouCjlIYfBBHofISixskdPwx0AqQxfzcLy7_aGigdGKu8fIUytsr7jgC3C14-rNxizADN84tuCyuJvTSk2tEbV31obsdB5TobvY9YZTel8NVblYux81rvpAhJtn-gFvZdk4ajpCl7N3oLYfL1ZbVRnoiE55QfVWl1-89gxE89RsOJhwNB4mCJLQ2pHjc1188UfQYAzBKOaikVvj_OR-ymBsZ4hFalSsMVdv3J3ahc-qa3-EcM_1yKZcwMzw2hOGeRHcNy2pSIfVFYfRJD6rMHUYNM8lazig9nDQX3evvy0RDCijyyQ3ftOUV4cXouLTX4vt3b7gZo_W4UlROU-so2HePmeuyCvI3g9V4ugSD2n_LNpZ33JVOiCDB253MfYGHHM0K7Rc46g5UMt02n5GPWUxn4zdrtse4lpCKshg0vznp1vLj5MpCw0eYrlg3A1izJ4pXmc030O_2eOhELW-iiI1Wt9s7eYBpjsfKq7z8rmqR6qs8Ekznw_AAKoIhWQ0-LQQofpcJ0ugqyyxG_jq_6FqoCAUHoVmWmWhNOOk7veN9SXTq0kTLTrC4jBLnYzwDPrqOoOGCZna1nnbwdS40seA90cSwQUbwRYEC0r016hoPerAqoqjHkHv0x6j0llAF0h_wjrxK5cVLrQ0NhicoYTHK4JrowrT1kVtEef06b9Cv92NAdofu34_U9PbcImX_QRtnGeExeJT-msoWlPO-uNKXU28Fz4CGYxPWjVdO6ZwxoCYk26-F3l7BU4HL_X_CA1_xtwy0STz47ERj4APD3BZxTc-18LHaaMsFN-2Yd-KeRGCNmY5MnQ-f_mqGM93u3WmrUXHBlpPKuvVf_8H-Fi79hT-CHO2S6s0YIL_PzzQ4IpLoC55wRs8JvCuhUHmFumjhT-J0adhVYRSBkrAA1PV_wa4wCSSubmpcArfMBR_IYc6nHbA7hsFf04S7kFvSM8LsPlbhdL3R8wnQvd_hPVTF7glauH9LbNv6bYuEfOrkYBSZDXZ1KfDMO3Hraza4Ljqz-qvhlo_lgvhaPUl7yeHV30dZemw6K3VaKmSuzoUzwGwGiOQ5Sqd49KozhaLsiKS4XIdyYU9RpGB8WD1_lH124gJyKHMRI9VUu9OwFitrWXsvsGKCUrrvmh2LzDFuxHXdFqf5V4G_0HxXVruD1seD9-QrGo-F4epDk-MjQq_0jWOXyfG3S1RGQDTusMmxCsWlw3xiUdDn1YfuoIwqw4b92GEQ-SNMSX7KnX_7N6Z21RVLUtnTEpoPVoKRFcf5xm5MPL_3mC1saTbveCLCkqk86S68pAkctOgYZghyDhMR54RtdcS_S3NRusKkpvdhl7ctCokaw3xV8TzaNTQ94R1k4myKmeRMkvJZ-S7Wfz9ut9jCby4Jhy9JJrx7MKqcwIq9VAYq_R_57X2p0-tKxqNxJEPm8ODJaRybukKMdaDw02Zpasyh77-EnOwE_-rhVqrrNGTbRwfNeD1da3dUgtpIaxqlNLZgu0fdbpAwmMPMFK0NZvF6cNXAqDgOt8RKVaXKd25ZyEgJYQFn4-J1BshFgXQY4mGZqFsBPzWX1xYKN9-SOnaTM466-584209EhHDDt51vbmuKA-9Y58Rpg=="}}
{"timestamp":"2025-09-22T13:56:25.537Z","type":"response_item","payload":{"type":"message","role":"assistant","content":[{"type":"output_text","text":"我需要了解你所说的“全局的提示词”具体是指什么:是项目里的某个配置文件、数据库内容,还是 IDE 中的某段说明?请再详细描述一下目标或期望结果,方便我准确执行。"}]}}
{"timestamp":"2025-09-22T13:56:51.650Z","type":"response_item","payload":{"type":"message","role":"user","content":[{"type":"input_text","text":"# Context from my IDE setup:\n\n## Active file: NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\n\n## Open tabs:\n- LinearProgrammingEngine.cs: NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\n\n## My request for Codex:\n分析全局的 Agents.md 文件\n"}]}}
{"timestamp":"2025-09-22T13:56:51.651Z","type":"event_msg","payload":{"type":"user_message","message":"# Context from my IDE setup:\n\n## Active file: NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\n\n## Open tabs:\n- LinearProgrammingEngine.cs: NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\n\n## My request for Codex:\n分析全局的 Agents.md 文件\n","kind":"plain"}}
{"timestamp":"2025-09-22T13:56:51.651Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:57:07.003Z","type":"event_msg","payload":{"type":"agent_reasoning","text":"**Preparing to read Agents.md with MCP tool**"}}
{"timestamp":"2025-09-22T13:57:07.348Z","type":"event_msg","payload":{"type":"token_count","info":{"total_token_usage":{"input_tokens":10957,"cached_input_tokens":7808,"output_tokens":801,"reasoning_output_tokens":704,"total_tokens":11758},"last_token_usage":{"input_tokens":5548,"cached_input_tokens":5376,"output_tokens":421,"reasoning_output_tokens":384,"total_tokens":5969},"model_context_window":272000}}}
{"timestamp":"2025-09-22T13:57:07.349Z","type":"response_item","payload":{"type":"reasoning","summary":[{"type":"summary_text","text":"**Preparing to read Agents.md with MCP tool**"}],"content":null,"encrypted_content":"gAAAAABo0VWzgKjbgiEbYUE57POkvngro2Xh04RscJ9iePNNQc4w6OiSya_bci_s0-ghaUraZiyW1XM4nk9IEWuMN9EvCZJYTKLaYT-6Rsyi9FEailTa6Y73M7gFgOLRtwIc5Lu5NPFkJatYOURydmnklDMYcLAxFHl7bqmOpofAlyLg0Z0E7D5AzxwMtnLkT9qSkYhpf7pp0cKy5Dm-aEL2sDKCgoNHsm1p8OGoyamSW66ftHQHBZWV5CJCo7c3bxe3sB4LlAqkHIZogChqT22sxumJDBfDN6egF6zLIbRvXocpX6cV87KdfByyfoCdt8LzQ6YT7kXhIaWg4kfII8GoVMFwN0VmULBic1AQ9xR-J6m5QRckBYCy0ZYkqJG0j0B1ZRGao9pYgcYvbAqnPxsmJHlnPf6as5njOeJInApjaXoJXbemqzFrOq2Vgemw9SKAdbIx4HaXhcyXPhFfbV-naFUkWmiKC6fF1wxs5F9LTh8RMiMhkZLBjbeLV3IdAX7EFYqL4btc58SqO-6ffs3VAjCPxA_OTBtm2DMtRhINOow0ac2zh5tPt0vPeVzSyuCuhx473GqzJcuReb_lnIQmyo-130r34LfSfx460qtH5QRERVZu6N6S1l2Cqo9rmdUJptRoz1ofU21-OpWXeA4FEKlYXvEf2JPTP7O6q0EJ0pYx7m7pX3k5h2nAlO01cNJ2Xn6XlvtqqxX0tCrBm89GAMHuBQiBGxQIpBsjFtgnskgmYuB_583saUEaNIUbTNFQx5OqeiTBhl1Fc62us_PutvNIOdwvNYfr6Btn9ie2zKZfQniJdcbQl9oxFP8O53kxe8pyAnVLXivuS3RhoTdjeckb1XO5l6cS4oiWR2z9U1zeMvdON1SkGU2eIOI8EohYidrTMA0UbafrZcmvaTQKXSI4L21P29s8KtUlaAc-MEFZMY3kRMSD0n2nzuPDrlx6ADg7vEtOdt8zjYpLcUKa0-ERYvDHRgB6zedln3dn2fuL32mPy-iguBFzlTNoFO1RgTmD_bilJdEzBgUzfcIDlLNsBWrKy7pq5Xwy3yH2IZ195AQnviN-er9f32bJKmgYlBmv17CjSDsvrRO4B7vu58SetnLvpqwOFH3fxGqlGst7wI7ni4ApWrJkQM6qli8o6fIji39N3jUr8Jgkg_VPFaRREmiBcu6XeCTr3msGM72ZPXKoGL5kfSs7f0afSMdtkvtWEMwHR3VSXHLwMetbSzMxLzOUtIp-UIwgUUHUSgqS0sPcORSkiqLjK54uHiZqj30hdBQYIoKnSqx-cGQx0b3Zjql2YqJOkF02U_hsuVHhvnjvLlCvj_iZShyWh7rpQFRSRVpaNLOlauXEjr0KxHuVaJhJKF2vJRjSuUySjs8Rehfz_Tc0l_5KXY7zpMq-uJaj0-NGAwSIdQLT_MQPKghupfgg7Q4ZE309XCBk6IeFSZvreCoHiIR-IoqEWsVgpkDW6KExmC2DbdRkXCSGtq0by7Z0vf9pRsrlRZoo97I68Qnb-CUlus4lug7qWVbtdbeJh9Psjt_7rfRXBbyI-DBGVW9b9Zl7pzjUr57wA2TZ6grYq3H5R3DV0WqroVPhkxzWfBst8fYgkE31BwwVA9kN--Lan3xDMRIUB1Fd1VD2lGm88hL8uLTQOED0Z2WuJLSLV97UV5IPrdLSbUiz_vdghOF2VyVcoAU5lWR7xpBlUJlORD8dmIgCTWdHN7_Mt8iMQ1j_qH13RV7ln3VomB0wgpIEqDhx_NFDRSJpDt9cH3yYDF3ECBUkNLobPq_EW66HXgpxGh_pkFFs1Lje4wpmE9h_42Wtmq6KxzuHk1NAOPTEyjcaObW26STXaikCijOpQgz05Z8X3ZnR9gIyTwOt9y8I1JCQWtgcqAsN64b6S_LRXcal7RuJIho68cBn3OMSsRNgNMft_jJEJCBZai4Vt1RPClbXo2JirzYaio6a61082MutDefp84xwAg7PhUL3mRM0sIJWI5iMQbdg-eVY3HaToLt9Sxq1gsmnT6UyFT7WjKTSkoBI3Y5ejv8wrQ5FoyS04CvyzLOYAMjp2sCSAdxdfVVU0cF8r-75SOOdN8f_hOKe1LB7EzRtuN512RDK_8yPO_2YnYSbTEinJfLIUlusmfhoHSJvu9F5eh1MfC1tIHbUlEbetSG-MAlnSw46Q3Drhd_qsBT7yKbBSZge72dlkQo_ZtVJR7ZZlAynIBthMhOZsU2b0VRksXGB9aAYfTFYyAgj599JWUd43i63TQYtw-_PLE3F02qxOFf6GOQSxyw6_K0i1goMyEEpiG4ZlFz_7rmhposMjtGKpwZHCSJnRPNx37H0zLtB-OEc8Of462TSZIzRo5WQ-W4WL9zzNUULfN19U794FwCLe1tLvjxvbC6b4gqb2SY4yylilzM-fGdeLBy5ZErQQF9vuJh2vNbqI1EMjVHqrfgxfKLMnZjAjuk9VjDlnJEnRYOZD77ii14nKrEniipO5hDkXXC9FsyexEowHiqBp7QEZWKQiP50z10sn9MiXinjxlV8Bcrx1RY0yZy4t8QFwYRDJVHCODmOgPcBPEDH738Mc1PSdWxTZec5QLFoLcMc5Ct9Vzxl0vP1aNKRKg85LOKfLvnNEacgNNpSdzHgXc59bDFJGXx_4wsxMJUYoaltcKg8sz-THz38OrRSxjmway7Yny6OogeJsElar-C9A21QrL2lv7kOahccwrG7_ItWjURDOMHwvKtPcTZ0VGg2FLkUimHNsGHJNZximdE4Gu0XPRl_ZttShpVBz-fyyDlNLrPQC2D_jgGm_pqVQ4ysmchtA0Y5lZcsa-TdqmG2sat58XLYOMr_WEO8LsPqv8TUWTiJT3rSNy4M6mpsccJhVjL1oTrsIasIXnKJKiv-LB-I56kzAP1yyneU8JtRxesNlQeu2vjoDCeUMCli-p1nD_UVd-D5TGF4nGwByABvESAqFFMEnLXagqUwu6LBqSm6Cwi8v-4Py3EtRjfqfOvFgrnpLsryt1NSx1QefTPpf6CTXWqS3uD_Z852K2-NXGJ-7CijrzrdoUWBjV9lBjQkaUD1Wd3F70Eo8y3x8Q9bbSVuhNVXJtUu0AdODnO8RclxfiA1_4T4XIMbFJs1izOxbfYoqtUoQoogQbmDVK7hUH-q5CfFMSyZ0m6P7LANd8tnLtcrQBl8UaIz7cbPK2-jPGlnt36o5dgkXPbMiPRN6VrFaP8Hhr9Vgb4OtElCj438ubV8F4obBnEuzBsO0CSlqy_lJELrb2EE9o93HJBfL_0hRHM0koP-rV9nJGQu6MIhH6gwEa1y4hJc_00FvYCVqqjaTAyUJCtTwPFPjbOmQ034Z27Yhp474v9WIbk9ph3MlmSQhEcyrH7McxRpjQywDeCdId7ziN8YBVefCBrjJAG62JAPw_XlGQ=="}}
{"timestamp":"2025-09-22T13:57:07.349Z","type":"response_item","payload":{"type":"function_call","name":"view_image","arguments":"{\"path\":\"NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\"}","call_id":"call_lOa8vpbgdUmaEZR2qxYUffMe"}}
{"timestamp":"2025-09-22T13:57:07.349Z","type":"response_item","payload":{"type":"function_call_output","call_id":"call_lOa8vpbgdUmaEZR2qxYUffMe","output":"attached local image path"}}
{"timestamp":"2025-09-22T13:57:07.349Z","type":"response_item","payload":{"type":"message","role":"user","content":[{"type":"input_image","image_url":"data:text/plain;base64,dXNpbmcgU3lzdGVtOw0KdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7DQp1c2luZyBTeXN0ZW0uTGlucTsNCnVzaW5nIFN5c3RlbS5UaHJlYWRpbmcuVGFza3M7DQp1c2luZyBHb29nbGUuT3JUb29scy5MaW5lYXJTb2x2ZXI7DQp1c2luZyBNaWNyb3NvZnQuRXh0ZW5zaW9ucy5Mb2dnaW5nOw0KdXNpbmcgTlBQLlNtYXJ0U2NoZWR1ZS5BcGkuQ29udHJhY3RzLkRvbWFpbi5Xb3JrOw0KdXNpbmcgTlBQLlNtYXJ0U2NoZWR1ZS5BcGkuQ29udHJhY3RzLkRvbWFpbi5QZXJzb25uZWw7DQp1c2luZyBOUFAuU21hcnRTY2hlZHVlLkFwaS5Db250cmFjdHMuU2VydmljZXMuSW50ZWdyYXRpb24uSW50ZXJuYWw7DQp1c2luZyBOUFAuU21hcnRTY2hlZHVlLkFwaS5Db250cmFjdHMuU2VydmljZXMuSW50ZWdyYXRpb24uT3V0cHV0Ow0KDQpuYW1lc3BhY2UgTlBQLlNtYXJ0U2NoZWR1ZS5BcGkuU2VydmljZXMuSW50ZWdyYXRpb24uQWxnb3JpdGhtcw0Kew0KICAgIC8vLyA8c3VtbWFyeT4NCiAgICAvLy8g5aKe5by654mI57q/5oCn6KeE5YiS5byV5pOOIC0g5a6e546w6YGX5Lyg566X5rOV5Lit55qE5omA5pyJ5aSN5p2C57qm5p2fDQogICAgLy8vIOaguOW/g+WKn+iDve+8muS4iee6p+e6puadn+S9k+ezuyArIOWkmue7tOW6puebruagh+S8mOWMliArIOWujOaVtOS4muWKoeinhOWImeaUr+aMgQ0KICAgIC8vLyDorr7orqHnkIblv7XvvJrlsIbpgZfkvKDnrpfms5XnmoTlkK/lj5HlvI/nuqbmnZ/ovazmjaLkuLrkuKXmoLznmoTmlbDlrabnuqbmnZ/vvIzlrp7njrDnsr7noa7msYLop6MNCiAgICAvLy8g5oqA5pyv5p625p6E77yaR29vZ2xlIE9SLVRvb2xzICsg5YiG5bGC57qm5p2f5bu65qihICsg6Ieq6YCC5bqU5p2D6YeN5LyY5YyWDQogICAgLy8vIOS4muWKoeS7t+WAvO+8muaPkOS+m+aVsOWtpuacgOS8mOino++8jOabv+S7o+mBl+S8oOeul+azleeahOi/keS8vOino++8jOaPkOWNh+iwg+W6pui0qOmHjw0KICAgIC8vLyA8L3N1bW1hcnk+DQogICAgcHVibGljIGNsYXNzIExpbmVhclByb2dyYW1taW5nRW5naW5lDQogICAgew0KICAgICAgICBwcml2YXRlIHJlYWRvbmx5IElMb2dnZXI8TGluZWFyUHJvZ3JhbW1pbmdFbmdpbmU+IF9sb2dnZXI7DQogICAgICAgIHByaXZhdGUgcmVhZG9ubHkgU2hpZnRSdWxlVmFsaWRhdGlvbkVuZ2luZSBfc2hpZnRSdWxlRW5naW5lOw0KICAgICAgICANCiAgICAgICAgLy8g5rGC6Kej5Zmo6YWN572uIC0g5aKe5by654mI6YWN572u5pSv5oyB5aSN5p2C57qm5p2fDQogICAgICAgIHByaXZhdGUgY29uc3Qgc3RyaW5nIFNPTFZFUl9UWVBFID0gIkNCQ19NSVhFRF9JTlRFR0VSX1BST0dSQU1NSU5HIjsNCiAgICAgICAgcHJpdmF0ZSBjb25zdCBkb3VibGUgT1BUSU1BTElUWV9UT0xFUkFOQ0UgPSAxZS02Ow0KICAgICAgICBwcml2YXRlIGNvbnN0IGludCBNQVhfU09MVkVSX1RJTUVfU0VDT05EUyA9IDYwMDsgLy8g5aKe5Yqg5YiwMTDliIbpkp/mlK/mjIHlpI3mnYLnuqbmnZ8NCiAgICAgICAgcHJpdmF0ZSBjb25zdCBpbnQgTUFYX0NPTlNUUkFJTlRfQ09VTlQgPSA1MDAwMDsgICAvLyDmnIDlpKfnuqbmnZ/mlbDph4/pmZDliLYNCiAgICAgICAgDQogICAgICAgIC8vIOe6puadn+adg+mHjemFjee9riAtIOWvueW6lOmBl+S8oOeul+azleeahOS4iee6p+e6puadn+S9k+ezuw0KICAgICAgICBwcml2YXRlIGNvbnN0IGRvdWJsZSBMRVZFTDFfQ09OU1RSQUlOVF9QRU5BTFRZID0gMTAwMDAwMC4wOyAvLyBMZXZlbCAxOiDln7rnoYDnuqbmnZ/kuKXljonmg6nnvZoNCiAgICAgICAgcHJpdmF0ZSBjb25zdCBkb3VibGUgTEVWRUwyX0NPTlNUUkFJTlRfUEVOQUxUWSA9IDEwMDAwMC4wOyAgLy8gTGV2ZWwgMjog57uE5ZCI57qm5p2f6YeN5bqm5oOp572aICANCiAgICAgICAgcHJpdmF0ZSBjb25zdCBkb3VibGUgTEVWRUwzX0NPTlNUUkFJTlRfUEVOQUxUWSA9IDEwMDAwLjA7ICAgLy8gTGV2ZWwgMzog5Lia5Yqh57qm5p2f5Lit5bqm5oOp572aDQogICAgICAgIHByaXZhdGUgY29uc3QgZG91YmxlIEZBSVJORVNTX1JFV0FSRF9GQUNUT1IgPSAxMDAwLjA7ICAgICAgIC8vIOWFrOW5s+aAp+WlluWKseezu+aVsA0KDQogICAgICAgIHB1YmxpYyBMaW5lYXJQcm9ncmFtbWluZ0VuZ2luZSgNCiAgICAgICAgICAgIElMb2dnZXI8TGluZWFyUHJvZ3JhbW1pbmdFbmdpbmU+IGxvZ2dlciwNCiAgICAgICAgICAgIFNoaWZ0UnVsZVZhbGlkYXRpb25FbmdpbmUgc2hpZnRSdWxlRW5naW5lKQ0KICAgICAgICB7DQogICAgICAgICAgICBfbG9nZ2VyID0gbG9nZ2VyID8/IHRocm93IG5ldyBBcmd1bWVudE51bGxFeGNlcHRpb24obmFtZW9mKGxvZ2dlcikpOw0KICAgICAgICAgICAgX3NoaWZ0UnVsZUVuZ2luZSA9IHNoaWZ0UnVsZUVuZ2luZSA/PyB0aHJvdyBuZXcgQXJndW1lbnROdWxsRXhjZXB0aW9uKG5hbWVvZihzaGlmdFJ1bGVFbmdpbmUpKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOaJp+ihjOWinuW8uueJiOe6v+aAp+inhOWIkuS8mOWMliAtIOWunueOsOmBl+S8oOeul+azleetieS7t+eahOe6puadn+S9k+ezuw0KICAgICAgICAvLy8g5Lia5Yqh5rWB56iL77ya5p6E5bu65Yaz562W5Y+Y6YePIOKGkiDkuInnuqfnuqbmnZ/lu7rmqKEg4oaSIOWkmuebruagh+S8mOWMliDihpIg57K+56Gu5rGC6KejIOKGkiDop6PmnpDnu5PmnpwNCiAgICAgICAgLy8vIOaguOW/g+WIm+aWsO+8muWwhuWQr+WPkeW8j+e6puadn+i9rOaNouS4uue6v+aAp+e6puadn++8jOWunueOsOaVsOWtpuacgOS8mOinow0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwdWJsaWMgYXN5bmMgVGFzazxHbG9iYWxPcHRpbWl6ZWRTb2x1dGlvbj4gT3B0aW1pemVBc3luYyhHbG9iYWxBbGxvY2F0aW9uQ29udGV4dCBjb250ZXh0KQ0KICAgICAgICB7DQogICAgICAgICAgICB2YXIgc3RvcHdhdGNoID0gU3lzdGVtLkRpYWdub3N0aWNzLlN0b3B3YXRjaC5TdGFydE5ldygpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICB0cnkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBfbG9nZ2VyLkxvZ0RlYnVnKCLwn5qAIOWQr+WKqOWinuW8uueJiOe6v+aAp+inhOWIkuS8mOWMliAtIOS7u+WKoeaVsO+8mntUYXNrQ291bnR977yM5Lq65ZGY5pWw77yae1BlcnNvbm5lbENvdW50fe+8jOmihOetm+mAiee8k+WtmO+8mntDYWNoZVNpemV9IiwgDQogICAgICAgICAgICAgICAgICAgIGNvbnRleHQuVGFza3MuQ291bnQsIGNvbnRleHQuQXZhaWxhYmxlUGVyc29ubmVsLkNvdW50LCBjb250ZXh0LlByZWZpbHRlclJlc3VsdHMuQ291bnQpOw0KDQogICAgICAgICAgICAgICAgLy8g56ys5LiA5q2l77ya5Yib5bu66auY5oCn6IO95rGC6Kej5ZmoDQogICAgICAgICAgICAgICAgdXNpbmcgdmFyIHNvbHZlciA9IENyZWF0ZUFkdmFuY2VkU29sdmVyKCk7DQoNCiAgICAgICAgICAgICAgICAvLyDnrKzkuozmraXvvJrmnoTlu7rlhrPnrZblj5jph4/nn6npmLUgKHhbaSxqXSA9IDHooajnpLrku7vliqFp5YiG6YWN57uZ5Lq65ZGYaikNCiAgICAgICAgICAgICAgICB2YXIgZGVjaXNpb25WYXJpYWJsZXMgPSBCdWlsZERlY2lzaW9uVmFyaWFibGVzKHNvbHZlciwgY29udGV4dCk7DQogICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dEZWJ1Zygi8J+TiiDlhrPnrZblj5jph4/mnoTlu7rlrozmiJAgLSDlj5jph4/mlbDph4/vvJp7VmFyaWFibGVDb3VudH0iLCBkZWNpc2lvblZhcmlhYmxlcy5Db3VudCk7DQoNCiAgICAgICAgICAgICAgICAvLyDnrKzkuInmraXvvJrmnoTlu7rovoXliqnlj5jph48gKOaUr+aMgeWkjeadgue6puadn+W7uuaooSkNCiAgICAgICAgICAgICAgICB2YXIgYXV4aWxpYXJ5VmFyaWFibGVzID0gQnVpbGRBdXhpbGlhcnlWYXJpYWJsZXMoc29sdmVyLCBjb250ZXh0LCBkZWNpc2lvblZhcmlhYmxlcyk7DQogICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dEZWJ1Zygi8J+UpyDovoXliqnlj5jph4/mnoTlu7rlrozmiJAgLSDovoXliqnlj5jph4/mlbDph4/vvJp7QXV4Q291bnR9IiwgYXV4aWxpYXJ5VmFyaWFibGVzLkNvdW50KTsNCg0KICAgICAgICAgICAgICAgIC8vIOesrOWbm+atpe+8mkxldmVsIDEg5Z+656GA57qm5p2fIC0g5a+55bqU6YGX5Lyg566X5rOV55qE5Z+656GA57qm5p2f6aqM6K+BDQogICAgICAgICAgICAgICAgYXdhaXQgQWRkTGV2ZWwxQmFzaWNDb25zdHJhaW50cyhzb2x2ZXIsIGRlY2lzaW9uVmFyaWFibGVzLCBhdXhpbGlhcnlWYXJpYWJsZXMsIGNvbnRleHQpOw0KDQogICAgICAgICAgICAgICAgLy8g56ys5LqU5q2l77yaTGV2ZWwgMiDnu4TlkIjnuqbmnZ8gLSDlr7nlupTpgZfkvKDnrpfms5XnmoTnu4TlkIjnuqbmnZ/pqozor4EgIA0KICAgICAgICAgICAgICAgIGF3YWl0IEFkZExldmVsMkNvbWJpbmF0aW9uQ29uc3RyYWludHMoc29sdmVyLCBkZWNpc2lvblZhcmlhYmxlcywgYXV4aWxpYXJ5VmFyaWFibGVzLCBjb250ZXh0KTsNCg0KICAgICAgICAgICAgICAgIC8vIOesrOWFreatpe+8mkxldmVsIDMg5Lia5Yqh57qm5p2fIC0g5a+55bqU6YGX5Lyg566X5rOV55qE5Lia5Yqh6YC76L6R57qm5p2fDQogICAgICAgICAgICAgICAgYXdhaXQgQWRkTGV2ZWwzQnVzaW5lc3NDb25zdHJhaW50cyhzb2x2ZXIsIGRlY2lzaW9uVmFyaWFibGVzLCBhdXhpbGlhcnlWYXJpYWJsZXMsIGNvbnRleHQpOw0KDQogICAgICAgICAgICAgICAgLy8g56ys5LiD5q2l77ya5YWs5bmz5oCn57qm5p2fIC0g5a+55bqU6YGX5Lyg566X5rOV55qE6LSf6L295Z2H6KGh5py65Yi2DQogICAgICAgICAgICAgICAgQWRkRmFpcm5lc3NDb25zdHJhaW50cyhzb2x2ZXIsIGRlY2lzaW9uVmFyaWFibGVzLCBhdXhpbGlhcnlWYXJpYWJsZXMsIGNvbnRleHQpOw0KDQogICAgICAgICAgICAgICAgLy8g56ys5YWr5q2l77ya6K6+572u5aSa57u05bqm55uu5qCH5Ye95pWwIC0g5a+55bqU6YGX5Lyg566X5rOV55qE6YCC5bqU5bqm5Ye95pWwDQogICAgICAgICAgICAgICAgU2V0RW5oYW5jZWRPYmplY3RpdmVGdW5jdGlvbihzb2x2ZXIsIGRlY2lzaW9uVmFyaWFibGVzLCBhdXhpbGlhcnlWYXJpYWJsZXMsIGNvbnRleHQpOw0KDQogICAgICAgICAgICAgICAgLy8g56ys5Lmd5q2l77ya5omn6KGM5rGC6KejDQogICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dJbmZvcm1hdGlvbigi8J+UjSDlvIDlp4vmsYLop6Plop7lvLrniYjnur/mgKfop4TliJLmqKHlnosuLi4iKTsNCiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0U3RhdHVzID0gc29sdmVyLlNvbHZlKCk7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgc3RvcHdhdGNoLlN0b3AoKTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyDnrKzljYHmraXvvJrop6PmnpDlkozpqozor4Hnu5PmnpwNCiAgICAgICAgICAgICAgICB2YXIgc29sdXRpb24gPSBhd2FpdCBQcm9jZXNzRW5oYW5jZWRTb2x2ZXJSZXN1bHQoc29sdmVyLCBkZWNpc2lvblZhcmlhYmxlcywgYXV4aWxpYXJ5VmFyaWFibGVzLCANCiAgICAgICAgICAgICAgICAgICAgY29udGV4dCwgcmVzdWx0U3RhdHVzLCBzdG9wd2F0Y2guRWxhcHNlZE1pbGxpc2Vjb25kcyk7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgcmV0dXJuIHNvbHV0aW9uOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBzdG9wd2F0Y2guU3RvcCgpOw0KICAgICAgICAgICAgICAgIF9sb2dnZXIuTG9nRXJyb3IoZXgsICLwn5KlIOWinuW8uueJiOe6v+aAp+inhOWIkuS8mOWMluW8guW4uO+8jOiAl+aXtu+8mntFbGFwc2VkTXN9bXMiLCBzdG9wd2F0Y2guRWxhcHNlZE1pbGxpc2Vjb25kcyk7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgcmV0dXJuIENyZWF0ZUZhaWx1cmVTb2x1dGlvbihleC5NZXNzYWdlLCBzdG9wd2F0Y2guRWxhcHNlZE1pbGxpc2Vjb25kcyk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAjcmVnaW9uIOaxguino+WZqOWSjOWPmOmHj+aehOW7ug0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOWIm+W7uumrmOaAp+iDveaxguino+WZqCAtIOaUr+aMgeWkp+inhOaooee6puadn+S8mOWMlg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIFNvbHZlciBDcmVhdGVBZHZhbmNlZFNvbHZlcigpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBzb2x2ZXIgPSBTb2x2ZXIuQ3JlYXRlU29sdmVyKFNPTFZFUl9UWVBFKTsNCiAgICAgICAgICAgIGlmIChzb2x2ZXIgPT0gbnVsbCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigi5peg5rOV5Yib5bu65aKe5by654mI57q/5oCn6KeE5YiS5rGC6Kej5ZmoIik7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIOmrmOaAp+iDvemFjee9rg0KICAgICAgICAgICAgc29sdmVyLlNldFRpbWVMaW1pdChNQVhfU09MVkVSX1RJTUVfU0VDT05EUyAqIDEwMDApOw0KICAgICAgICAgICAgDQogICAgICAgICAgICAvLyDorr7nva7kvJjljJblj4LmlbANCiAgICAgICAgICAgIHNvbHZlci5TZXRTb2x2ZXJTcGVjaWZpY1BhcmFtZXRlcnNBc1N0cmluZygNCiAgICAgICAgICAgICAgICAiY3V0cz0xICIgKyAgICAgICAgICAgLy8g5ZCv55So5Ymy5bmz6Z2iDQogICAgICAgICAgICAgICAgImhldXJpc3RpY3M9MSAiICsgICAgIC8vIOWQr+eUqOWQr+WPkeW8j+eul+azlQ0KICAgICAgICAgICAgICAgICJwcmVzb2x2ZT0xICIgKyAgICAgICAvLyDlkK/nlKjpooTlpITnkIYNCiAgICAgICAgICAgICAgICAidGhyZWFkcz0wIiAgICAgICAgICAgLy8g5L2/55So5omA5pyJ5Y+v55So57q/56iLDQogICAgICAgICAgICApOw0KDQogICAgICAgICAgICBfbG9nZ2VyLkxvZ0luZm9ybWF0aW9uKCLwn5SnIOmrmOaAp+iDveaxguino+WZqOWIm+W7uuWujOaIkO+8jOmFjee9ru+8muaXtumXtOmZkOWItntUaW1lTGltaXR9c++8jOWkmue6v+eoi+aUr+aMgSIsIE1BWF9TT0xWRVJfVElNRV9TRUNPTkRTKTsNCiAgICAgICAgICAgIHJldHVybiBzb2x2ZXI7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDjgJBVbHRyYSB0aGlua+WinuW8uuOAkeaehOW7uuWGs+etluWPmOmHjyAtIOmbhuaIkOS6uuWRmOePreasoeS4jeWPr+eUqOaAp+eahOaZuuiDveWPmOmHj+eUn+aIkA0KICAgICAgICAvLy8g44CQ5qC45b+D5LyY5YyW44CR77ya5Zyo5Y+Y6YeP5Yib5bu66Zi25q615bCx5o6S6Zmk5LiN5Y+v55So57uE5ZCI77yM5aSn5bmF5o+Q5Y2H5rGC6Kej5pWI546HDQogICAgICAgIC8vLyDjgJDkuInlsYLkvJjljJbjgJHvvJrpooTnrZvpgInnu5PmnpwgKyDkuI3lj6/nlKjmgKfmo4Dmn6UgKyDor4TliIbpmIjlgLzvvIzlrp7njrDnsr7noa7nmoTlj5jph4/oo4HliaoNCiAgICAgICAgLy8vIOOAkOaAp+iDveaPkOWNh+OAke+8mumihOiuoeWHj+WwkTIwLTQwJeeahOWGs+etluWPmOmHj+aVsOmHj++8jOaYvuiRl+aPkOWNh+axguino+mAn+W6pg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIERpY3Rpb25hcnk8KGxvbmcgVGFza0lkLCBsb25nIFBlcnNvbm5lbElkKSwgVmFyaWFibGU+IEJ1aWxkRGVjaXNpb25WYXJpYWJsZXMoDQogICAgICAgICAgICBTb2x2ZXIgc29sdmVyLCBHbG9iYWxBbGxvY2F0aW9uQ29udGV4dCBjb250ZXh0KQ0KICAgICAgICB7DQogICAgICAgICAgICB2YXIgdmFyaWFibGVzID0gbmV3IERpY3Rpb25hcnk8KGxvbmcgVGFza0lkLCBsb25nIFBlcnNvbm5lbElkKSwgVmFyaWFibGU+KCk7DQogICAgICAgICAgICB2YXIgY3JlYXRlZENvdW50ID0gMDsNCiAgICAgICAgICAgIHZhciBza2lwcGVkQ291bnQgPSAwOw0KICAgICAgICAgICAgdmFyIHVuYXZhaWxhYmlsaXR5U2tpcHBlZENvdW50ID0gMDsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRhc2sgaW4gY29udGV4dC5UYXNrcykNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgcGVyc29ubmVsIGluIGNvbnRleHQuQXZhaWxhYmxlUGVyc29ubmVsKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHByZWZpbHRlcktleSA9ICQie3Rhc2suSWR9X3twZXJzb25uZWwuSWR9IjsNCiAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIC8vIOOAkFVsdHJhIHRoaW5r5LyY5YyWMeOAkemmluWFiOajgOafpeS6uuWRmOePreasoeS4jeWPr+eUqOaApyAtIOehrOaOkumZpA0KICAgICAgICAgICAgICAgICAgICBpZiAoSXNQZXJzb25uZWxVbmF2YWlsYWJsZUZvclRhc2sodGFzaywgcGVyc29ubmVsLklkLCBjb250ZXh0KSkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdW5hdmFpbGFiaWxpdHlTa2lwcGVkQ291bnQrKzsNCiAgICAgICAgICAgICAgICAgICAgICAgIHNraXBwZWRDb3VudCsrOw0KICAgICAgICAgICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dEZWJ1Zygi8J+aqyDot7Pov4fkuI3lj6/nlKjnu4TlkIggLSDku7vliqF7VGFza0lkfeS6uuWRmHtQZXJzb25uZWxJZH3lnKh7RGF0ZX3nj63mrKF7U2hpZnRJZH3kuI3lj6/nlKgiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXNrLklkLCBwZXJzb25uZWwuSWQsIHRhc2suV29ya09yZGVyRGF0ZS5Ub1N0cmluZygieXl5eS1NTS1kZCIpLCB0YXNrLlNoaWZ0SWQpOw0KICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIC8vIOOAkFVsdHJhIHRoaW5r5LyY5YyWMuOAkeWfuuS6jumihOetm+mAiee7k+aenOeahOaZuuiDveWGs+etlg0KICAgICAgICAgICAgICAgICAgICBpZiAoY29udGV4dC5QcmVmaWx0ZXJSZXN1bHRzLlRyeUdldFZhbHVlKHByZWZpbHRlcktleSwgb3V0IHZhciBwcmVmaWx0ZXJSZXN1bHQpKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAvLyDlr7nkuo7or4TliIbovoPpq5jnmoTliIbphY3vvIzljbPkvb/moIforrDkuLrkuI3lj6/ooYzkuZ/liJvlu7rlj5jph4/vvIjlj6/og73mmK/kv53lrojor4TkvLDvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmaWx0ZXJSZXN1bHQuSXNGZWFzaWJsZSB8fCBwcmVmaWx0ZXJSZXN1bHQuUHJlZmlsdGVyU2NvcmUgPiAzMC4wKQ0KICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YXJpYWJsZU5hbWUgPSAkInhfe3Rhc2suSWR9X3twZXJzb25uZWwuSWR9IjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFyaWFibGUgPSBzb2x2ZXIuTWFrZUJvb2xWYXIodmFyaWFibGVOYW1lKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZXNbKHRhc2suSWQsIHBlcnNvbm5lbC5JZCldID0gdmFyaWFibGU7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlZENvdW50Kys7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlDQogICAgICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2tpcHBlZENvdW50Kys7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAvLyDjgJBVbHRyYSB0aGlua+S8mOWMljPjgJHml6DpooTnrZvpgInmlbDmja7ml7bnmoTkv53lrojnrZbnlaUNCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOWNs+S9v+aXoOmihOetm+mAieaVsOaNru+8jOS9huW3sumAmui/h+S4jeWPr+eUqOaAp+ajgOafpe+8jOS7jeWIm+W7uuWPmOmHjw0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhcmlhYmxlTmFtZSA9ICQieF97dGFzay5JZH1fe3BlcnNvbm5lbC5JZH0iOw0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhcmlhYmxlID0gc29sdmVyLk1ha2VCb29sVmFyKHZhcmlhYmxlTmFtZSk7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZXNbKHRhc2suSWQsIHBlcnNvbm5lbC5JZCldID0gdmFyaWFibGU7DQogICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVkQ291bnQrKzsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgX2xvZ2dlci5Mb2dEZWJ1Zygi8J+TiiDjgJDlop7lvLrniYjjgJHlhrPnrZblj5jph4/mnoTlu7rnu5/orqEgLSDliJvlu7rvvJp7Q3JlYXRlZH3kuKrvvIzot7Pov4fvvJp7U2tpcHBlZH3kuKrvvIjkuI3lj6/nlKjmgKfvvJp7VW5hdmFpbGFiaWxpdHlTa2lwcGVkfe+8ie+8jOWPmOmHj+WvhuW6pu+8mntEZW5zaXR5OlAyfe+8jOS4jeWPr+eUqOaAp+S8mOWMlueOh++8mntVbmF2YWlsYWJpbGl0eVJhdGU6UDJ9IiwgDQogICAgICAgICAgICAgICAgY3JlYXRlZENvdW50LCBza2lwcGVkQ291bnQsIHVuYXZhaWxhYmlsaXR5U2tpcHBlZENvdW50LCANCiAgICAgICAgICAgICAgICAoZG91YmxlKWNyZWF0ZWRDb3VudCAvIChjcmVhdGVkQ291bnQgKyBza2lwcGVkQ291bnQpLA0KICAgICAgICAgICAgICAgIChkb3VibGUpdW5hdmFpbGFiaWxpdHlTa2lwcGVkQ291bnQgLyAoY3JlYXRlZENvdW50ICsgc2tpcHBlZENvdW50KSk7DQoNCiAgICAgICAgICAgIHJldHVybiB2YXJpYWJsZXM7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDmnoTlu7rovoXliqnlj5jph48gLSDmlK/mjIHlpI3mnYLnuqbmnZ/nmoTnur/mgKfljJblu7rmqKENCiAgICAgICAgLy8vIOWMheWQq++8mui0n+i9veWdh+ihoeWPmOmHj+OAgeaXtumXtOWGsueqgeaMh+ekuuWPmOmHj+OAgeePreasoeinhOWImei/neinhOWPmOmHj+etiQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIERpY3Rpb25hcnk8c3RyaW5nLCBWYXJpYWJsZT4gQnVpbGRBdXhpbGlhcnlWYXJpYWJsZXMoDQogICAgICAgICAgICBTb2x2ZXIgc29sdmVyLCBHbG9iYWxBbGxvY2F0aW9uQ29udGV4dCBjb250ZXh0LCANCiAgICAgICAgICAgIERpY3Rpb25hcnk8KGxvbmcgVGFza0lkLCBsb25nIFBlcnNvbm5lbElkKSwgVmFyaWFibGU+IGRlY2lzaW9uVmFyaWFibGVzKQ0KICAgICAgICB7DQogICAgICAgICAgICB2YXIgYXV4aWxpYXJ5VmFycyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgVmFyaWFibGU+KCk7DQoNCiAgICAgICAgICAgIC8vIDEuIOS6uuWRmOW3peS9nOi0n+i9veWPmOmHjyAo6L+e57ut5Y+Y6YeP77yM6KGo56S65q+P5Liq5Lq65ZGY55qE5Lu75Yqh5pWw6YePKQ0KICAgICAgICAgICAgZm9yZWFjaCAodmFyIHBlcnNvbm5lbCBpbiBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB2YXIgd29ya2xvYWRWYXIgPSBzb2x2ZXIuTWFrZUludFZhcigwLCBjb250ZXh0LlRhc2tzLkNvdW50LCAkIndvcmtsb2FkX3twZXJzb25uZWwuSWR9Iik7DQogICAgICAgICAgICAgICAgYXV4aWxpYXJ5VmFyc1skIndvcmtsb2FkX3twZXJzb25uZWwuSWR9Il0gPSB3b3JrbG9hZFZhcjsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gMi4g6LSf6L295Z2H6KGh5YGP5beu5Y+Y6YePICjmlK/mjIHlhazlubPmgKfnm67moIflu7rmqKEpDQogICAgICAgICAgICB2YXIgYXZnV29ya2xvYWQgPSAoZG91YmxlKWNvbnRleHQuVGFza3MuQ291bnQgLyBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbC5Db3VudDsNCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBwZXJzb25uZWwgaW4gY29udGV4dC5BdmFpbGFibGVQZXJzb25uZWwpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgLy8g5q2j5YGP5beu5Y+Y6YePICjotoXlh7rlubPlnYfotJ/ovb3nmoTpg6jliIYpDQogICAgICAgICAgICAgICAgdmFyIHBvc0RldmlhdGlvblZhciA9IHNvbHZlci5NYWtlTnVtVmFyKDAsIGNvbnRleHQuVGFza3MuQ291bnQsICQicG9zX2Rldl97cGVyc29ubmVsLklkfSIpOw0KICAgICAgICAgICAgICAgIGF1eGlsaWFyeVZhcnNbJCJwb3NfZGV2X3twZXJzb25uZWwuSWR9Il0gPSBwb3NEZXZpYXRpb25WYXI7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g6LSf5YGP5beu5Y+Y6YePICjkvY7kuo7lubPlnYfotJ/ovb3nmoTpg6jliIYpDQogICAgICAgICAgICAgICAgdmFyIG5lZ0RldmlhdGlvblZhciA9IHNvbHZlci5NYWtlTnVtVmFyKDAsIGF2Z1dvcmtsb2FkLCAkIm5lZ19kZXZfe3BlcnNvbm5lbC5JZH0iKTsNCiAgICAgICAgICAgICAgICBhdXhpbGlhcnlWYXJzWyQibmVnX2Rldl97cGVyc29ubmVsLklkfSJdID0gbmVnRGV2aWF0aW9uVmFyOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyAzLiDml7bpl7TlhrLnqoHmjIfnpLrlj5jph48gKOS6jOi/m+WItuWPmOmHj++8jOagh+ivhuaYr+WQpuWtmOWcqOaXtumXtOWGsueqgSkNCiAgICAgICAgICAgIHZhciB0aW1lU2xvdHMgPSBjb250ZXh0LlRhc2tzLlNlbGVjdCh0ID0+IG5ldyB7IERhdGUgPSB0LldvcmtPcmRlckRhdGUuRGF0ZSB9KQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuRGlzdGluY3QoKS5Ub0xpc3QoKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgZm9yZWFjaCAodmFyIHBlcnNvbm5lbCBpbiBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgdGltZVNsb3QgaW4gdGltZVNsb3RzKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbmZsaWN0VmFyID0gc29sdmVyLk1ha2VCb29sVmFyKCQiY29uZmxpY3Rfe3BlcnNvbm5lbC5JZH1fe3RpbWVTbG90LkRhdGU6eXl5eU1NZGR9Iik7DQogICAgICAgICAgICAgICAgICAgIGF1eGlsaWFyeVZhcnNbJCJjb25mbGljdF97cGVyc29ubmVsLklkfV97dGltZVNsb3QuRGF0ZTp5eXl5TU1kZH0iXSA9IGNvbmZsaWN0VmFyOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLyovLyA0LiDnj63mrKHop4TliJnov53op4Tlj5jph48gKOaUr+aMgeWkjeadguePreasoeinhOWImeeahOe6v+aAp+WMlikNCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBwZXJzb25uZWwgaW4gY29udGV4dC5BdmFpbGFibGVQZXJzb25uZWwpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgLy8g5LqM54+tL+S4ieePreWQjuS8keaBr+inhOWImei/neinhOWPmOmHjw0KICAgICAgICAgICAgICAgIHZhciBzaGlmdFJ1bGVWaW9sYXRpb25WYXIgPSBzb2x2ZXIuTWFrZUludFZhcigwLCBjb250ZXh0LlRhc2tzLkNvdW50LCAkInNoaWZ0X3Zpb2xhdGlvbl97cGVyc29ubmVsLklkfSIpOw0KICAgICAgICAgICAgICAgIGF1eGlsaWFyeVZhcnNbJCJzaGlmdF92aW9sYXRpb25fe3BlcnNvbm5lbC5JZH0iXSA9IHNoaWZ0UnVsZVZpb2xhdGlvblZhcjsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gNS4gRkzkvJjlhYjnuqfov53op4Tlj5jph48gKExldmVsIDPkuJrliqHnuqbmnZ/mlK/mjIEpDQogICAgICAgICAgICBmb3JlYWNoICh2YXIgdGFzayBpbiBjb250ZXh0LlRhc2tzKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciBmbFZpb2xhdGlvblZhciA9IHNvbHZlci5NYWtlQm9vbFZhcigkImZsX3Zpb2xhdGlvbl97dGFzay5JZH0iKTsNCiAgICAgICAgICAgICAgICBhdXhpbGlhcnlWYXJzWyQiZmxfdmlvbGF0aW9uX3t0YXNrLklkfSJdID0gZmxWaW9sYXRpb25WYXI7DQogICAgICAgICAgICB9Ki8NCg0KICAgICAgICAgICAgX2xvZ2dlci5Mb2dEZWJ1Zygi8J+UpyDovoXliqnlj5jph4/mnoTlu7rlrozmiJAgLSDmgLvmlbDvvJp7QXV4VmFyQ291bnR977yI5bel5L2c6LSf6L2977yae1dvcmtsb2FkQ291bnR977yM5Yay56qB5oyH56S677yae0NvbmZsaWN0Q291bnR977yM54+t5qyh6L+d6KeE77yae1NoaWZ0Q291bnR977yMRkzov53op4TvvJp7RkxDb3VudH3vvIkiLCANCiAgICAgICAgICAgICAgICBhdXhpbGlhcnlWYXJzLkNvdW50LA0KICAgICAgICAgICAgICAgIGNvbnRleHQuVGFza3MuQ291bnQgLyBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbC5Db3VudCwNCiAgICAgICAgICAgICAgICBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbC5Db3VudCAqIHRpbWVTbG90cy5Db3VudCwNCiAgICAgICAgICAgICAgICBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbC5Db3VudCwNCiAgICAgICAgICAgICAgICBjb250ZXh0LlRhc2tzLkNvdW50KTsNCg0KICAgICAgICAgICAgcmV0dXJuIGF1eGlsaWFyeVZhcnM7DQogICAgICAgIH0NCg0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgI3JlZ2lvbiBMZXZlbCAxIOWfuuehgOe6puadnyAtIOWvueW6lOmBl+S8oOeul+azleWfuuehgOe6puadn+mqjOivgQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOa3u+WKoExldmVsIDHln7rnoYDnuqbmnZ8gLSDlr7nlupTpgZfkvKDnrpfms5XnmoRFeGVjdXRlTGV2ZWwxQmFzaWNDb25zdHJhaW50VmFsaWRhdGlvbg0KICAgICAgICAvLy8g57qm5p2f5YaF5a6577ya5Lu75Yqh5YiG6YWN5a6M5pW05oCn44CB5Z+65pys5pe26Ze05Yay56qB5qOA5p+lDQogICAgICAgIC8vLyDnuqbmnZ/nibnngrnvvJrlv4XpobsxMDAl5ruh6Laz77yM6L+d5Y+N5Y2z5reY5rGwDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgYXN5bmMgVGFzayBBZGRMZXZlbDFCYXNpY0NvbnN0cmFpbnRzKA0KICAgICAgICAgICAgU29sdmVyIHNvbHZlciwNCiAgICAgICAgICAgIERpY3Rpb25hcnk8KGxvbmcgVGFza0lkLCBsb25nIFBlcnNvbm5lbElkKSwgVmFyaWFibGU+IGRlY2lzaW9uVmFycywNCiAgICAgICAgICAgIERpY3Rpb25hcnk8c3RyaW5nLCBWYXJpYWJsZT4gYXV4aWxpYXJ5VmFycywNCiAgICAgICAgICAgIEdsb2JhbEFsbG9jYXRpb25Db250ZXh0IGNvbnRleHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIGF3YWl0IFRhc2suQ29tcGxldGVkVGFzazsNCiAgICAgICAgICAgIHZhciBjb25zdHJhaW50Q291bnQgPSAwOw0KICAgICAgICAgICAgDQogICAgICAgICAgICBfbG9nZ2VyLkxvZ0RlYnVnKCLwn4+X77iPIOW8gOWni+a3u+WKoExldmVsIDHln7rnoYDnuqbmnZ8uLi4iKTsNCg0KICAgICAgICAgICAgLy8g5Z+656GA57qm5p2fMe+8muS7u+WKoeWIhumFjeWujOaVtOaApyAtIOavj+S4quS7u+WKoeW/hemhu+S4lOWPquiDveWIhumFjee7meS4gOS4quS6uuWRmA0KICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRhc2sgaW4gY29udGV4dC5UYXNrcykNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB2YXIgdGFza1ZhcmlhYmxlcyA9IGRlY2lzaW9uVmFycy5XaGVyZSh2ID0+IHYuS2V5LlRhc2tJZCA9PSB0YXNrLklkKS5TZWxlY3QodiA9PiB2LlZhbHVlKS5Ub0xpc3QoKTsNCiAgICAgICAgICAgICAgICBpZiAodGFza1ZhcmlhYmxlcy5BbnkoKSkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciBjb25zdHJhaW50ID0gc29sdmVyLk1ha2VDb25zdHJhaW50KDEsIDEsICQidGFza19hc3NpZ25tZW50X3t0YXNrLklkfSIpOw0KICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgdmFyaWFibGUgaW4gdGFza1ZhcmlhYmxlcykNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludC5TZXRDb2VmZmljaWVudCh2YXJpYWJsZSwgMSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludENvdW50Kys7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyDln7rnoYDnuqbmnZ8y77ya5Z+65pys5pe26Ze05Yay56qB57qm5p2fIC0g5ZCM5LiA5Lq65ZGY5LiN6IO95Zyo5ZCM5LiA5pe26Ze05q615omn6KGM5aSa5Liq5Lu75YqhDQogICAgICAgICAgICAvLyDov5nph4zkvb/nlKjnur/mgKfnuqbmnZ/mm7/ku6PpgZfkvKDnrpfms5XkuK3nmoRDYWxjdWxhdGVCYXNpY1RpbWVDb25mbGljdFNjb3Jl6YC76L6RDQogICAgICAgICAgICBmb3JlYWNoICh2YXIgcGVyc29ubmVsIGluIGNvbnRleHQuQXZhaWxhYmxlUGVyc29ubmVsKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIC8vIOaMieaXtumXtOauteWIhue7hOajgOafpeWGsueqgQ0KICAgICAgICAgICAgICAgIHZhciB0aW1lR3JvdXBzID0gY29udGV4dC5UYXNrcy5Hcm91cEJ5KHQgPT4gbmV3IHsgRGF0ZSA9IHQuV29ya09yZGVyRGF0ZS5EYXRlIH0pOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0aW1lR3JvdXAgaW4gdGltZUdyb3VwcykNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciB0aW1lU2xvdFRhc2tzID0gdGltZUdyb3VwLlRvTGlzdCgpOw0KICAgICAgICAgICAgICAgICAgICBpZiAodGltZVNsb3RUYXNrcy5Db3VudCA+IDEpIC8vIOWQjOS4gOaXtumXtOauteacieWkmuS4quS7u+WKoeaJjemcgOimgee6puadnw0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGltZVNsb3RWYXJpYWJsZXMgPSB0aW1lU2xvdFRhc2tzDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLldoZXJlKHRhc2sgPT4gZGVjaXNpb25WYXJzLkNvbnRhaW5zS2V5KCh0YXNrLklkLCBwZXJzb25uZWwuSWQpKSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuU2VsZWN0KHRhc2sgPT4gZGVjaXNpb25WYXJzWyh0YXNrLklkLCBwZXJzb25uZWwuSWQpXSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuVG9MaXN0KCk7DQoNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aW1lU2xvdFZhcmlhYmxlcy5Db3VudCA+IDEpDQogICAgICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8g57qm5p2f77ya5ZCM5LiA5Lq65ZGY5Zyo5ZCM5LiA5pe26Ze05q615pyA5aSa5omn6KGMMeS4quS7u+WKoQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb25zdHJhaW50ID0gc29sdmVyLk1ha2VDb25zdHJhaW50KDAsIDEsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkInRpbWVfY29uZmxpY3Rfe3BlcnNvbm5lbC5JZH1fe3RpbWVHcm91cC5LZXkuRGF0ZTp5eXl5TU1kZH0iKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgdmFyaWFibGUgaW4gdGltZVNsb3RWYXJpYWJsZXMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50LlNldENvZWZmaWNpZW50KHZhcmlhYmxlLCAxKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludENvdW50Kys7DQoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyDov57mjqXovoXliqnlj5jph4/vvIjnlKjkuo7nm67moIflh73mlbDmg6nnvZrvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29uZmxpY3RWYXJLZXkgPSAkImNvbmZsaWN0X3twZXJzb25uZWwuSWR9X3t0aW1lR3JvdXAuS2V5LkRhdGU6eXl5eU1NZGR9IjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXV4aWxpYXJ5VmFycy5Db250YWluc0tleShjb25mbGljdFZhcktleSkpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzliIbphY3kuoblpJrkuKrku7vliqHvvIzlhrLnqoHlj5jph489MQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29uZmxpY3RDb25zdHJhaW50ID0gc29sdmVyLk1ha2VDb25zdHJhaW50KDAsIGRvdWJsZS5Qb3NpdGl2ZUluZmluaXR5LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQiY29uZmxpY3RfaW5kaWNhdG9yX3twZXJzb25uZWwuSWR9X3t0aW1lR3JvdXAuS2V5LkRhdGU6eXl5eU1NZGR9Iik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgdmFyaWFibGUgaW4gdGltZVNsb3RWYXJpYWJsZXMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZsaWN0Q29uc3RyYWludC5TZXRDb2VmZmljaWVudCh2YXJpYWJsZSwgMSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmxpY3RDb25zdHJhaW50LlNldENvZWZmaWNpZW50KGF1eGlsaWFyeVZhcnNbY29uZmxpY3RWYXJLZXldLCAtdGltZVNsb3RWYXJpYWJsZXMuQ291bnQgKyAxKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludENvdW50Kys7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyDln7rnoYDnuqbmnZ8z77ya5bel5L2c6LSf6L296K6h566X57qm5p2fIC0g6L+e5o6l5Yaz562W5Y+Y6YeP5LiO6L6F5Yqp5Y+Y6YePDQogICAgICAgICAgICBmb3JlYWNoICh2YXIgcGVyc29ubmVsIGluIGNvbnRleHQuQXZhaWxhYmxlUGVyc29ubmVsKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciBwZXJzb25uZWxUYXNrcyA9IGRlY2lzaW9uVmFycy5XaGVyZSh2ID0+IHYuS2V5LlBlcnNvbm5lbElkID09IHBlcnNvbm5lbC5JZCkuVG9MaXN0KCk7DQogICAgICAgICAgICAgICAgaWYgKHBlcnNvbm5lbFRhc2tzLkFueSgpICYmIGF1eGlsaWFyeVZhcnMuQ29udGFpbnNLZXkoJCJ3b3JrbG9hZF97cGVyc29ubmVsLklkfSIpKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnN0cmFpbnQgPSBzb2x2ZXIuTWFrZUNvbnN0cmFpbnQoMCwgMCwgJCJ3b3JrbG9hZF9jYWxjX3twZXJzb25uZWwuSWR9Iik7DQogICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIga3ZwIGluIHBlcnNvbm5lbFRhc2tzKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50LlNldENvZWZmaWNpZW50KGt2cC5WYWx1ZSwgMSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludC5TZXRDb2VmZmljaWVudChhdXhpbGlhcnlWYXJzWyQid29ya2xvYWRfe3BlcnNvbm5lbC5JZH0iXSwgLTEpOw0KICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50Q291bnQrKzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIF9sb2dnZXIuTG9nRGVidWcoIuKchSBMZXZlbCAx5Z+656GA57qm5p2f5re75Yqg5a6M5oiQIC0g57qm5p2f5pWw6YeP77yae0NvbnN0cmFpbnRDb3VudH0iLCBjb25zdHJhaW50Q291bnQpOw0KICAgICAgICB9DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgICNyZWdpb24gTGV2ZWwgMiDnu4TlkIjnuqbmnZ8gLSDlr7nlupTpgZfkvKDnrpfms5Xnu4TlkIjnuqbmnZ/pqozor4ENCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDmt7vliqBMZXZlbCAy57uE5ZCI57qm5p2fIC0g5a+55bqU6YGX5Lyg566X5rOV55qERXhlY3V0ZUxldmVsMkNvbWJpbmF0aW9uQ29uc3RyYWludFZhbGlkYXRpb24NCiAgICAgICAgLy8vIOe6puadn+WGheWuue+8muWKqOaAgeePreasoeinhOWImeOAgei3qOS7u+WKoei1hOa6kOernuS6iee6puadnw0KICAgICAgICAvLy8g57qm5p2f54m554K577ya5Z+65LqO5Lu75Yqh57uE5ZCI55qE5Yqo5oCB6aqM6K+B77yM6L+d5Y+N5pe26YeN5bqm5oOp572aDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgYXN5bmMgVGFzayBBZGRMZXZlbDJDb21iaW5hdGlvbkNvbnN0cmFpbnRzKA0KICAgICAgICAgICAgU29sdmVyIHNvbHZlciwNCiAgICAgICAgICAgIERpY3Rpb25hcnk8KGxvbmcgVGFza0lkLCBsb25nIFBlcnNvbm5lbElkKSwgVmFyaWFibGU+IGRlY2lzaW9uVmFycywNCiAgICAgICAgICAgIERpY3Rpb25hcnk8c3RyaW5nLCBWYXJpYWJsZT4gYXV4aWxpYXJ5VmFycywNCiAgICAgICAgICAgIEdsb2JhbEFsbG9jYXRpb25Db250ZXh0IGNvbnRleHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBjb25zdHJhaW50Q291bnQgPSAwOw0KICAgICAgICAgICAgDQogICAgICAgICAgICBfbG9nZ2VyLkxvZ0RlYnVnKCLwn5SEIOW8gOWni+a3u+WKoExldmVsIDLnu4TlkIjnuqbmnZ8uLi4iKTsNCg0KICAgICAgICAgICAgLy8g57uE5ZCI57qm5p2fMe+8muWKqOaAgeePreasoeinhOWImee6puadnyAtIOWvueW6lENhbGN1bGF0ZUR5bmFtaWNTaGlmdFJ1bGVTY29yZQ0KICAgICAgICAgICAgLy9jb25zdHJhaW50Q291bnQgKz0gYXdhaXQgQWRkRHluYW1pY1NoaWZ0UnVsZUNvbnN0cmFpbnRzKHNvbHZlciwgZGVjaXNpb25WYXJzLCBhdXhpbGlhcnlWYXJzLCBjb250ZXh0KTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgLy8g57uE5ZCI57qm5p2fM++8muS6uuWRmOaXpeW3peS9nOmHj+mZkOWItue6puadnw0KICAgICAgICAgICAgLy9jb25zdHJhaW50Q291bnQgKz0gQWRkRGFpbHlXb3JrbG9hZENvbnN0cmFpbnRzKHNvbHZlciwgZGVjaXNpb25WYXJzLCBhdXhpbGlhcnlWYXJzLCBjb250ZXh0KTsNCg0KICAgICAgICAgICAgX2xvZ2dlci5Mb2dEZWJ1Zygi4pyFIExldmVsIDLnu4TlkIjnuqbmnZ/mt7vliqDlrozmiJAgLSDnuqbmnZ/mlbDph4/vvJp7Q29uc3RyYWludENvdW50fSIsIGNvbnN0cmFpbnRDb3VudCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDjgJDmnrbmnoTph43mnoTjgJHmt7vliqDlop7lvLrniYjmibnmrKHmhJ/nn6Xnj63mrKHop4TliJnnuqbmnZ8gLSDnnJ/mraPop6PlhrPmibnmrKHpqozor4Hpl67popgNCiAgICAgICAgLy8vIOOAkOaguOW/g+WIm+aWsOOAke+8mumbhuaIkOaJueasoeaEn+efpemqjOivge+8jOiAg+iZkeW9k+WJjeWIhumFjee7hOWQiOS4juWOhuWPsuaVsOaNrueahOaVtOS9k+mqjOivgQ0KICAgICAgICAvLy8g44CQ5rex5bqm5a6e546w44CR77ya5L2/55SoUGVyc29ubmVsVGFza01hdHJpeOi/m+ihjOmrmOaViOeahOWFs+iBlOafpeivouWSjOWGsueqgeajgOa1iw0KICAgICAgICAvLy8g44CQVWx0cmEgdGhpbmvnuqfliKvjgJHvvJrku47moLnmnKzkuIrop6PlhrPljZXku7vliqEr5Y6G5Y+y6aqM6K+B55qE5p625p6E57y66Zm3DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgYXN5bmMgVGFzazxpbnQ+IEFkZER5bmFtaWNTaGlmdFJ1bGVDb25zdHJhaW50cygNCiAgICAgICAgICAgIFNvbHZlciBzb2x2ZXIsDQogICAgICAgICAgICBEaWN0aW9uYXJ5PChsb25nIFRhc2tJZCwgbG9uZyBQZXJzb25uZWxJZCksIFZhcmlhYmxlPiBkZWNpc2lvblZhcnMsDQogICAgICAgICAgICBEaWN0aW9uYXJ5PHN0cmluZywgVmFyaWFibGU+IGF1eGlsaWFyeVZhcnMsDQogICAgICAgICAgICBHbG9iYWxBbGxvY2F0aW9uQ29udGV4dCBjb250ZXh0KQ0KICAgICAgICB7DQogICAgICAgICAgICB2YXIgY29uc3RyYWludENvdW50ID0gMDsNCiAgICAgICAgICAgIF9sb2dnZXIuTG9nSW5mb3JtYXRpb24oIvCfmoAg5ZCv5Yqo5aKe5by654mI5om55qyh5oSf55+l54+t5qyh6KeE5YiZ57qm5p2f5p6E5bu6Li4uIik7DQoNCiAgICAgICAgICAgIC8vIOOAkOaetuaehOWIm+aWsDHjgJHmnoTlu7rkurrlkZjku7vliqHlhbPogZTnn6npmLXvvIzmlK/mjIHpq5jmlYjnmoTmibnmrKHpqozor4ENCiAgICAgICAgICAgIHZhciBwZXJzb25uZWxUYXNrTWF0cml4ID0gQnVpbGRQZXJzb25uZWxUYXNrTWF0cml4KGRlY2lzaW9uVmFycywgY29udGV4dCk7DQogICAgICAgICAgICBfbG9nZ2VyLkxvZ0RlYnVnKCLwn5OKIOS6uuWRmOS7u+WKoeefqemYteaehOW7uuWujOaIkCAtIOS6uuWRmOaYoOWwhO+8mntQZXJzb25uZWxDb3VudH3vvIzku7vliqHmmKDlsITvvJp7VGFza0NvdW50fSIsIA0KICAgICAgICAgICAgICAgIHBlcnNvbm5lbFRhc2tNYXRyaXguUGVyc29ubmVsVGFza01hcC5Db3VudCwgcGVyc29ubmVsVGFza01hdHJpeC5UYXNrUGVyc29ubmVsTWFwLkNvdW50KTsNCg0KICAgICAgICAgICAgLy8g44CQ5p625p6E5Yib5pawMuOAkeS4uuavj+S4quS6uuWRmOaehOW7uuaJueasoeaEn+efpeeahOmqjOivgeS4iuS4i+aWhw0KICAgICAgICAgICAgdmFyIGJhdGNoVmFsaWRhdGlvblJlc3VsdHMgPSBuZXcgRGljdGlvbmFyeTxsb25nLCBEaWN0aW9uYXJ5PGxvbmcsIExpc3Q8c3RyaW5nPj4+KCk7DQogICAgICAgICAgICANCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBwZXJzb25uZWxFbnRyeSBpbiBwZXJzb25uZWxUYXNrTWF0cml4LlBlcnNvbm5lbFRhc2tNYXApDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyIHBlcnNvbm5lbElkID0gcGVyc29ubmVsRW50cnkuS2V5Ow0KICAgICAgICAgICAgICAgIHZhciBwb3NzaWJsZVRhc2tzID0gcGVyc29ubmVsRW50cnkuVmFsdWU7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgaWYgKHBvc3NpYmxlVGFza3MuQ291bnQgPiAxKSAvLyDlj6rlr7nmnInlpJrkuKrlj6/og73ku7vliqHnmoTkurrlkZjov5vooYzmibnmrKHpqozor4ENCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIGJhdGNoVmFsaWRhdGlvblJlc3VsdHNbcGVyc29ubmVsSWRdID0gYXdhaXQgRXhlY3V0ZUJhdGNoQXdhcmVWYWxpZGF0aW9uQXN5bmMoDQogICAgICAgICAgICAgICAgICAgICAgICBwZXJzb25uZWxJZCwgcG9zc2libGVUYXNrcywgY29udGV4dCwgcGVyc29ubmVsVGFza01hdHJpeCk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyDjgJDmnrbmnoTliJvmlrAz44CR5Z+65LqO5om55qyh6aqM6K+B57uT5p6c5Yib5bu657qm5p2fDQogICAgICAgICAgICB2YXIgc2hpZnRWaW9sYXRpb25WYXJzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBWYXJpYWJsZT4oKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgZm9yZWFjaCAodmFyIGt2cCBpbiBkZWNpc2lvblZhcnMpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyICh0YXNrSWQsIHBlcnNvbm5lbElkKSA9IGt2cC5LZXk7DQogICAgICAgICAgICAgICAgdmFyIGFzc2lnbm1lbnRWYXIgPSBrdnAuVmFsdWU7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g5Yib5bu66K+l5YiG6YWN55qE54+t5qyh6KeE5YiZ6L+d6KeE5oyH56S65Y+Y6YePDQogICAgICAgICAgICAgICAgdmFyIHZpb2xhdGlvblZhcktleSA9ICQiYmF0Y2hfYXdhcmVfc2hpZnRfdmlvbGF0aW9uX3t0YXNrSWR9X3twZXJzb25uZWxJZH0iOw0KICAgICAgICAgICAgICAgIHZhciB2aW9sYXRpb25WYXIgPSBzb2x2ZXIuTWFrZUJvb2xWYXIodmlvbGF0aW9uVmFyS2V5KTsNCiAgICAgICAgICAgICAgICBzaGlmdFZpb2xhdGlvblZhcnNbdmlvbGF0aW9uVmFyS2V5XSA9IHZpb2xhdGlvblZhcjsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyDjgJDmibnmrKHmhJ/nn6Xpqozor4HjgJHmo4Dmn6Xor6XliIbphY3lnKjmibnmrKHkuIrkuIvmlofkuK3nmoTlkIjop4TmgKcNCiAgICAgICAgICAgICAgICB2YXIgaGFzVmlvbGF0aW9uID0gZmFsc2U7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgaWYgKGJhdGNoVmFsaWRhdGlvblJlc3VsdHMuVHJ5R2V0VmFsdWUocGVyc29ubmVsSWQsIG91dCB2YXIgcGVyc29ubmVsVmFsaWRhdGlvblJlc3VsdHMpKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHBlcnNvbm5lbFZhbGlkYXRpb25SZXN1bHRzLlRyeUdldFZhbHVlKHRhc2tJZCwgb3V0IHZhciB2aW9sYXRpb25zKSkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgaGFzVmlvbGF0aW9uID0gdmlvbGF0aW9ucy5BbnkoKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhc1Zpb2xhdGlvbikNCiAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbG9nZ2VyLkxvZ0RlYnVnKCLwn5OLIOaJueasoeaEn+efpemqjOivgeWPkeeOsOWGsueqgSAtIOS7u+WKoXtUYXNrSWR95Lq65ZGYe1BlcnNvbm5lbElkfe+8mntWaW9sYXRpb25zfSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXNrSWQsIHBlcnNvbm5lbElkLCBzdHJpbmcuSm9pbigiOyAiLCB2aW9sYXRpb25zLlRha2UoMikpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBlbHNlDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAvLyDjgJDlkI7lpIfpqozor4HjgJHljZXku7vliqHkurrlkZjkvb/nlKjkvKDnu5/pqozor4ENCiAgICAgICAgICAgICAgICAgICAgdmFyIHRhc2sgPSBjb250ZXh0LlRhc2tzLkZpcnN0T3JEZWZhdWx0KHQgPT4gdC5JZCA9PSB0YXNrSWQpOw0KICAgICAgICAgICAgICAgICAgICBpZiAodGFzayAhPSBudWxsKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3RoZXJBc3NpZ25tZW50cyA9IEJ1aWxkVmFsaWRhdGlvbkNvbnRleHQocGVyc29ubmVsSWQsIHRhc2tJZCwgY29udGV4dCwgZGVjaXNpb25WYXJzKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb25mbGljdHMgPSBhd2FpdCBfc2hpZnRSdWxlRW5naW5lLlZhbGlkYXRlU2hpZnRSdWxlc1dpdGhFbmhhbmNlZEJhdGNoQ29udGV4dEFzeW5jKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcnNvbm5lbElkLCB0YXNrLCBvdGhlckFzc2lnbm1lbnRzLCBjb250ZXh0KTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGhhc1Zpb2xhdGlvbiA9IGNvbmZsaWN0cy5BbnkoKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIC8vIOOAkOe6puadn+W7uuaooeOAkeWfuuS6jumqjOivgee7k+aenOWIm+W7uue6puadnw0KICAgICAgICAgICAgICAgIGlmIChoYXNWaW9sYXRpb24pDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzlrZjlnKjlhrLnqoHvvIzlvZPliIbphY3or6Xku7vliqHml7bov53op4Tlj5jph4/lv4XpobvkuLoxDQogICAgICAgICAgICAgICAgICAgIHZhciB2aW9sYXRpb25Db25zdHJhaW50ID0gc29sdmVyLk1ha2VDb25zdHJhaW50KDAsIGRvdWJsZS5Qb3NpdGl2ZUluZmluaXR5LA0KICAgICAgICAgICAgICAgICAgICAgICAgJCJiYXRjaF9mb3JjZV92aW9sYXRpb25fe3Rhc2tJZH1fe3BlcnNvbm5lbElkfSIpOw0KICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgdmlvbGF0aW9uQ29uc3RyYWludC5TZXRDb2VmZmljaWVudChhc3NpZ25tZW50VmFyLCAxKTsNCiAgICAgICAgICAgICAgICAgICAgdmlvbGF0aW9uQ29uc3RyYWludC5TZXRDb2VmZmljaWVudCh2aW9sYXRpb25WYXIsIC0xKTsNCiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludENvdW50Kys7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIC8vIOaXoOWGsueqgeaXtuW8uuWItui/neinhOWPmOmHj+S4ujANCiAgICAgICAgICAgICAgICAgICAgdmFyIG5vVmlvbGF0aW9uQ29uc3RyYWludCA9IHNvbHZlci5NYWtlQ29uc3RyYWludCgwLCAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgJCJiYXRjaF9ub192aW9sYXRpb25fe3Rhc2tJZH1fe3BlcnNvbm5lbElkfSIpOw0KICAgICAgICAgICAgICAgICAgICBub1Zpb2xhdGlvbkNvbnN0cmFpbnQuU2V0Q29lZmZpY2llbnQodmlvbGF0aW9uVmFyLCAxKTsNCiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludENvdW50Kys7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyDjgJDmnrbmnoTliJvmlrA044CR5re75Yqg5YWo5bGA5om55qyh5a6M5pW05oCn57qm5p2fDQogICAgICAgICAgICBjb25zdHJhaW50Q291bnQgKz0gQ3JlYXRlR2xvYmFsVGltZVNsb3RDb25zdHJhaW50cyhzb2x2ZXIsIGRlY2lzaW9uVmFycywgY29udGV4dCk7DQogICAgICAgICAgICBjb25zdHJhaW50Q291bnQgKz0gQ3JlYXRlQmF0Y2hJbnRlZ3JpdHlDb25zdHJhaW50cyhzb2x2ZXIsIGRlY2lzaW9uVmFycywgYXV4aWxpYXJ5VmFycywgY29udGV4dCk7DQogICAgICAgICAgICANCiAgICAgICAgICAgIC8vIOOAkOWFqOWxgOe6puadn+OAkeaAu+i/neinhOaVsOmHj+mZkOWItg0KICAgICAgICAgICAgdmFyIHRvdGFsVmlvbGF0aW9ucyA9IHNoaWZ0VmlvbGF0aW9uVmFycy5WYWx1ZXMuVG9MaXN0KCk7DQogICAgICAgICAgICBpZiAodG90YWxWaW9sYXRpb25zLkFueSgpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciBtYXhBbGxvd2VkVmlvbGF0aW9ucyA9IE1hdGguTWF4KDEsIGNvbnRleHQuVGFza3MuQ291bnQgLyAxMCk7DQogICAgICAgICAgICAgICAgdmFyIHRvdGFsVmlvbGF0aW9uQ29uc3RyYWludCA9IHNvbHZlci5NYWtlQ29uc3RyYWludCgwLCBtYXhBbGxvd2VkVmlvbGF0aW9ucywgIm1heF9iYXRjaF9zaGlmdF92aW9sYXRpb25zIik7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHZpb2xhdGlvblZhciBpbiB0b3RhbFZpb2xhdGlvbnMpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICB0b3RhbFZpb2xhdGlvbkNvbnN0cmFpbnQuU2V0Q29lZmZpY2llbnQodmlvbGF0aW9uVmFyLCAxKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgY29uc3RyYWludENvdW50Kys7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g5bCG6L+d6KeE5Y+Y6YeP5re75Yqg5Yiw6L6F5Yqp5Y+Y6YeP6ZuG5ZCI5LitDQogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGt2cCBpbiBzaGlmdFZpb2xhdGlvblZhcnMpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBhdXhpbGlhcnlWYXJzW2t2cC5LZXldID0ga3ZwLlZhbHVlOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgX2xvZ2dlci5Mb2dJbmZvcm1hdGlvbigi4pyFIOWinuW8uueJiOaJueasoeaEn+efpeePreasoeinhOWImee6puadn+aehOW7uuWujOaIkCAtIOe6puadn+aVsOmHj++8mntDb25zdHJhaW50Q291bnR977yM5om55qyh6aqM6K+B5Lq65ZGY77yae0JhdGNoUGVyc29ubmVsQ291bnR977yM6L+d6KeE5Y+Y6YeP77yae1Zpb2xhdGlvblZhckNvdW50fSIsIA0KICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRDb3VudCwgYmF0Y2hWYWxpZGF0aW9uUmVzdWx0cy5Db3VudCwgc2hpZnRWaW9sYXRpb25WYXJzLkNvdW50KTsNCiAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50Q291bnQ7DQogICAgICAgIH0NCiAgICAgICAgDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOa3u+WKoOaXpeW3peS9nOmHj+e6puadnyAtIOmZkOWItuS6uuWRmOavj+aXpeW3peS9nOi0n+i9vQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIGludCBBZGREYWlseVdvcmtsb2FkQ29uc3RyYWludHMoDQogICAgICAgICAgICBTb2x2ZXIgc29sdmVyLA0KICAgICAgICAgICAgRGljdGlvbmFyeTwobG9uZyBUYXNrSWQsIGxvbmcgUGVyc29ubmVsSWQpLCBWYXJpYWJsZT4gZGVjaXNpb25WYXJzLA0KICAgICAgICAgICAgRGljdGlvbmFyeTxzdHJpbmcsIFZhcmlhYmxlPiBhdXhpbGlhcnlWYXJzLA0KICAgICAgICAgICAgR2xvYmFsQWxsb2NhdGlvbkNvbnRleHQgY29udGV4dCkNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIGNvbnN0cmFpbnRDb3VudCA9IDA7DQogICAgICAgICAgICBjb25zdCBpbnQgbWF4RGFpbHlIb3VycyA9IDg7IC8vIOavj+aXpeacgOWkp+W3peS9nOaXtumVv++8iOWMheWQq+WKoOePre+8iQ0KDQogICAgICAgICAgICBmb3JlYWNoICh2YXIgcGVyc29ubmVsIGluIGNvbnRleHQuQXZhaWxhYmxlUGVyc29ubmVsKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIC8vIOaMieaXpeacn+WIhue7hOivpeS6uuWRmOeahOS7u+WKoQ0KICAgICAgICAgICAgICAgIHZhciBkYWlseUdyb3VwcyA9IGNvbnRleHQuVGFza3MNCiAgICAgICAgICAgICAgICAgICAgLldoZXJlKHQgPT4gZGVjaXNpb25WYXJzLkNvbnRhaW5zS2V5KCh0LklkLCBwZXJzb25uZWwuSWQpKSkNCiAgICAgICAgICAgICAgICAgICAgLkdyb3VwQnkodCA9PiB0LldvcmtPcmRlckRhdGUuRGF0ZSk7DQoNCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgZGFpbHlHcm91cCBpbiBkYWlseUdyb3VwcykNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciBkYWlseVRhc2tzID0gZGFpbHlHcm91cC5Ub0xpc3QoKTsNCiAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIHZhciBjb25zdHJhaW50ID0gc29sdmVyLk1ha2VDb25zdHJhaW50KDAsIG1heERhaWx5SG91cnMsIA0KICAgICAgICAgICAgICAgICAgICAgICAgJCJkYWlseV93b3JrbG9hZF97cGVyc29ubmVsLklkfV97ZGFpbHlHcm91cC5LZXk6eXl5eU1NZGR9Iik7DQoNCiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRhc2sgaW4gZGFpbHlUYXNrcykNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVzdGltYXRlZEhvdXJzID0gdGFzay5Fc3RpbWF0ZWRIb3VycyA/PyAxLjBtOyAvLyDpu5jorqQx5bCP5pe2DQogICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50LlNldENvZWZmaWNpZW50KGRlY2lzaW9uVmFyc1sodGFzay5JZCwgcGVyc29ubmVsLklkKV0sIChkb3VibGUpZXN0aW1hdGVkSG91cnMpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRDb3VudCsrOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgX2xvZ2dlci5Mb2dEZWJ1Zygi4pyFIOaXpeW3peS9nOmHj+e6puadn+aehOW7uuWujOaIkCAtIOe6puadn+aVsOmHj++8mntXb3JrbG9hZENvbnN0cmFpbnRDb3VudH0iLCBjb25zdHJhaW50Q291bnQpOw0KICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRDb3VudDsNCiAgICAgICAgfQ0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIExldmVsIDMg5Lia5Yqh57qm5p2fIC0g5a+55bqU6YGX5Lyg566X5rOV5Lia5Yqh6YC76L6R6aqM6K+BDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g5re75YqgTGV2ZWwgM+S4muWKoee6puadnyAtIOWvueW6lOmBl+S8oOeul+azleeahEV4ZWN1dGVMZXZlbDNCdXNpbmVzc0xvZ2ljVmFsaWRhdGlvbg0KICAgICAgICAvLy8g57qm5p2f5YaF5a6577yaRkzkvJjlhYjnuqfop4TliJnjgIHkurrlkZjmioDog73ljLnphY3jgIHpobnnm67ov57nu63mgKfnuqbmnZ8NCiAgICAgICAgLy8vIOe6puadn+eJueeCue+8muS4muWKoeinhOWImeS4peagvOaJp+ihjO+8jOWFgeiuuOS4gOWumuW8ueaAp+S9huW/hemhu+espuWQiOaguOW/g+S4muWKoemAu+i+kQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIGFzeW5jIFRhc2sgQWRkTGV2ZWwzQnVzaW5lc3NDb25zdHJhaW50cygNCiAgICAgICAgICAgIFNvbHZlciBzb2x2ZXIsDQogICAgICAgICAgICBEaWN0aW9uYXJ5PChsb25nIFRhc2tJZCwgbG9uZyBQZXJzb25uZWxJZCksIFZhcmlhYmxlPiBkZWNpc2lvblZhcnMsDQogICAgICAgICAgICBEaWN0aW9uYXJ5PHN0cmluZywgVmFyaWFibGU+IGF1eGlsaWFyeVZhcnMsDQogICAgICAgICAgICBHbG9iYWxBbGxvY2F0aW9uQ29udGV4dCBjb250ZXh0KQ0KICAgICAgICB7DQogICAgICAgICAgICBhd2FpdCBUYXNrLkNvbXBsZXRlZFRhc2s7DQogICAgICAgICAgICB2YXIgY29uc3RyYWludENvdW50ID0gMDsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgX2xvZ2dlci5Mb2dEZWJ1Zygi8J+SvCDlvIDlp4vmt7vliqBMZXZlbCAz5Lia5Yqh57qm5p2fLi4uIik7DQoNCiAgICAgICAgICAgIC8vIOS4muWKoee6puadnzHvvJpGTOS8mOWFiOe6p+inhOWImSAtIOWvueW6lENhbGN1bGF0ZUZMUHJpb3JpdHlSdWxlU2NvcmUNCiAgICAgICAgICAgIC8vY29uc3RyYWludENvdW50ICs9IEFkZEZMUHJpb3JpdHlDb25zdHJhaW50cyhzb2x2ZXIsIGRlY2lzaW9uVmFycywgYXV4aWxpYXJ5VmFycywgY29udGV4dCk7DQoNCiAgICAgICAgICAgIC8vIOS4muWKoee6puadnzLvvJrkurrlkZjmioDog73ljLnphY3nuqbmnZ8gLSDlr7nlupRDYWxjdWxhdGVTa2lsbE1hdGNoaW5nQ29uc3RyYWludFNjb3JlDQogICAgICAgICAgICAvL2NvbnN0cmFpbnRDb3VudCArPSBBZGRTa2lsbE1hdGNoaW5nQ29uc3RyYWludHMoc29sdmVyLCBkZWNpc2lvblZhcnMsIGF1eGlsaWFyeVZhcnMsIGNvbnRleHQpOw0KDQogICAgICAgICAgICAvLyDkuJrliqHnuqbmnZ8z77ya6aG555uu6L+e57ut5oCn57qm5p2fIC0g5a+55bqUQ2FsY3VsYXRlUHJvamVjdENvbnRpbnVpdHlDb25zdHJhaW50U2NvcmUNCiAgICAgICAgICAgIC8vY29uc3RyYWludENvdW50ICs9IEFkZFByb2plY3RDb250aW51aXR5Q29uc3RyYWludHMoc29sdmVyLCBkZWNpc2lvblZhcnMsIGF1eGlsaWFyeVZhcnMsIGNvbnRleHQpOw0KDQogICAgICAgICAgICAvLyDkuJrliqHnuqbmnZ8077ya5Lq65ZGY6LWE6LSo57qm5p2fIC0g56Gu5L+d5Y+q5YiG6YWN57uZ5YW35aSH55u45bqU6LWE6LSo55qE5Lq65ZGYDQogICAgICAgICAgICAvL2NvbnN0cmFpbnRDb3VudCArPSBhd2FpdCBBZGRRdWFsaWZpY2F0aW9uQ29uc3RyYWludHMoc29sdmVyLCBkZWNpc2lvblZhcnMsIGNvbnRleHQpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICAvLyDkuJrliqHnuqbmnZ8177ya44CQVWx0cmEgdGhpbmvjgJHkurrlkZjnj63mrKHkuI3lj6/nlKjmgKfnoaznuqbmnZ8gLSDnoa7kv53kuI3kvJrliIbphY3nu5nkuI3lj6/nlKjkurrlkZgNCiAgICAgICAgICAgIC8vY29uc3RyYWludENvdW50ICs9IGF3YWl0IEFkZFBlcnNvbm5lbFVuYXZhaWxhYmlsaXR5Q29uc3RyYWludHMoc29sdmVyLCBkZWNpc2lvblZhcnMsIGNvbnRleHQpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICBfbG9nZ2VyLkxvZ0RlYnVnKCLinIUgTGV2ZWwgM+S4muWKoee6puadn+a3u+WKoOWujOaIkCAtIOe6puadn+aVsOmHj++8mntDb25zdHJhaW50Q291bnR9IiwgY29uc3RyYWludENvdW50KTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOa3u+WKoEZM5LyY5YWI57qn57qm5p2fIC0g5a+55bqU6YGX5Lyg566X5rOV55qERkzkvJjlhYjnuqfop4TliJnpqozor4ENCiAgICAgICAgLy8vIOinhOWImTEw77ya5LyY5YWI5YiG6YWN5pys6aG555uuRkzkurrlkZgNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHJpdmF0ZSBpbnQgQWRkRkxQcmlvcml0eUNvbnN0cmFpbnRzKA0KICAgICAgICAgICAgU29sdmVyIHNvbHZlciwNCiAgICAgICAgICAgIERpY3Rpb25hcnk8KGxvbmcgVGFza0lkLCBsb25nIFBlcnNvbm5lbElkKSwgVmFyaWFibGU+IGRlY2lzaW9uVmFycywNCiAgICAgICAgICAgIERpY3Rpb25hcnk8c3RyaW5nLCBWYXJpYWJsZT4gYXV4aWxpYXJ5VmFycywNCiAgICAgICAgICAgIEdsb2JhbEFsbG9jYXRpb25Db250ZXh0IGNvbnRleHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBjb25zdHJhaW50Q291bnQgPSAwOw0KDQogICAgICAgICAgICBmb3JlYWNoICh2YXIgdGFzayBpbiBjb250ZXh0LlRhc2tzKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIC8vIOiOt+WPluivpeS7u+WKoeWFs+iBlOeahEZM5Lq65ZGYDQogICAgICAgICAgICAgICAgdmFyIHRhc2tGTFBlcnNvbm5lbCA9IHRhc2suV29ya09yZGVyRkxQZXJzb25uZWxzPw0KICAgICAgICAgICAgICAgICAgICAuU2VsZWN0KGZsID0+IGZsLkZMUGVyc29ubmVsSWQpDQogICAgICAgICAgICAgICAgICAgIC5XaGVyZShmbElkID0+IGNvbnRleHQuQXZhaWxhYmxlUGVyc29ubmVsLkFueShwID0+IHAuSWQgPT0gZmxJZCkpDQogICAgICAgICAgICAgICAgICAgIC5Ub0xpc3QoKSA/PyBuZXcgTGlzdDxsb25nPigpOw0KDQogICAgICAgICAgICAgICAgaWYgKHRhc2tGTFBlcnNvbm5lbC5BbnkoKSkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIC8vIOWIm+W7ukZM5LyY5YWI57qm5p2f77ya5LyY5YWI5YiG6YWN57uZRkzkurrlkZjvvIzlpoLmnpzliIbphY3nu5npnZ5GTOS6uuWRmOWImeiusOW9lei/neinhA0KICAgICAgICAgICAgICAgICAgICB2YXIgZmxWaW9sYXRpb25WYXJLZXkgPSAkImZsX3Zpb2xhdGlvbl97dGFzay5JZH0iOw0KICAgICAgICAgICAgICAgICAgICBpZiAoYXV4aWxpYXJ5VmFycy5Db250YWluc0tleShmbFZpb2xhdGlvblZhcktleSkpDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb25zdHJhaW50ID0gc29sdmVyLk1ha2VDb25zdHJhaW50KDAsIGRvdWJsZS5Qb3NpdGl2ZUluZmluaXR5LCAkImZsX3ByaW9yaXR5X3t0YXNrLklkfSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAvLyBGTOS6uuWRmOWIhumFjeWPmOmHjw0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGZsUGVyc29ubmVsSWQgaW4gdGFza0ZMUGVyc29ubmVsKQ0KICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZWNpc2lvblZhcnMuQ29udGFpbnNLZXkoKHRhc2suSWQsIGZsUGVyc29ubmVsSWQpKSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnQuU2V0Q29lZmZpY2llbnQoZGVjaXNpb25WYXJzWyh0YXNrLklkLCBmbFBlcnNvbm5lbElkKV0sIDEpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgLy8g6Z2eRkzkurrlkZjliIbphY3lj5jph48NCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub25GTFBlcnNvbm5lbCA9IGNvbnRleHQuQXZhaWxhYmxlUGVyc29ubmVsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLldoZXJlKHAgPT4gIXRhc2tGTFBlcnNvbm5lbC5Db250YWlucyhwLklkKSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuVG9MaXN0KCk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgbm9uRkwgaW4gbm9uRkxQZXJzb25uZWwpDQogICAgICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlY2lzaW9uVmFycy5Db250YWluc0tleSgodGFzay5JZCwgbm9uRkwuSWQpKSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnQuU2V0Q29lZmZpY2llbnQoZGVjaXNpb25WYXJzWyh0YXNrLklkLCBub25GTC5JZCldLCAtMSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAvLyDov53op4TmjIfnpLrlj5jph48NCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnQuU2V0Q29lZmZpY2llbnQoYXV4aWxpYXJ5VmFyc1tmbFZpb2xhdGlvblZhcktleV0sIDEpOw0KICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludENvdW50Kys7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIF9sb2dnZXIuTG9nRGVidWcoIuKchSBGTOS8mOWFiOe6p+e6puadn+aehOW7uuWujOaIkCAtIOe6puadn+aVsOmHj++8mntGTENvbnN0cmFpbnRDb3VudH0iLCBjb25zdHJhaW50Q291bnQpOw0KICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRDb3VudDsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOOAkOmHjeaehOeugOWMluOAkeaKgOiDveWMuemFjee6puadnyAtIOWfuuS6jumihOetm+mAiee7k+aenOeahOi9u+mHj+e6p+WunueOsA0KICAgICAgICAvLy8g44CQ5p625p6E5LyY5YyW44CR77ya56e76Zmk5aSN5p2C55qE5aSa5rqQ6LWE6LSo6YC76L6R77yM5L6d6LWW6aKE562b6YCJ6Zi25q6155qE5LiT5Lia6aqM6K+BDQogICAgICAgIC8vLyDjgJDogYzotKPliIbnprvjgJHvvJrmioDog73ljLnphY3kuqTnlLFDb250ZXh0QnVpbGRlckVuZ2luZeWkhOeQhu+8jOi/memHjOS7heWBmue6puadn+W6lOeUqA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIGludCBBZGRTa2lsbE1hdGNoaW5nQ29uc3RyYWludHMoDQogICAgICAgICAgICBTb2x2ZXIgc29sdmVyLA0KICAgICAgICAgICAgRGljdGlvbmFyeTwobG9uZyBUYXNrSWQsIGxvbmcgUGVyc29ubmVsSWQpLCBWYXJpYWJsZT4gZGVjaXNpb25WYXJzLA0KICAgICAgICAgICAgRGljdGlvbmFyeTxzdHJpbmcsIFZhcmlhYmxlPiBhdXhpbGlhcnlWYXJzLA0KICAgICAgICAgICAgR2xvYmFsQWxsb2NhdGlvbkNvbnRleHQgY29udGV4dCkNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIGNvbnN0cmFpbnRDb3VudCA9IDA7DQogICAgICAgICAgICANCiAgICAgICAgICAgIF9sb2dnZXIuTG9nRGVidWcoIvCflI0g5byA5aeL5p6E5bu65oqA6IO95Yy56YWN57qm5p2fIC0g5Z+65LqO6aKE562b6YCJ57uT5p6cIik7DQoNCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBrdnAgaW4gZGVjaXNpb25WYXJzKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciAodGFza0lkLCBwZXJzb25uZWxJZCkgPSBrdnAuS2V5Ow0KICAgICAgICAgICAgICAgIHZhciB2YXJpYWJsZSA9IGt2cC5WYWx1ZTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyDjgJDnroDljJblrp7njrDjgJHkvb/nlKjpooTnrZvpgInnu5PmnpzkuK3nmoTmioDog73ljLnphY3or4TkvLANCiAgICAgICAgICAgICAgICB2YXIgcHJlZmlsdGVyS2V5ID0gJCJ7dGFza0lkfV97cGVyc29ubmVsSWR9IjsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICBpZiAoY29udGV4dC5QcmVmaWx0ZXJSZXN1bHRzLlRyeUdldFZhbHVlKHByZWZpbHRlcktleSwgb3V0IHZhciBwcmVmaWx0ZXJSZXN1bHQpKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgLy8g5qOA5p+l6aKE562b6YCJ6K+E5YiG77yM5L2O5YiG6KGo56S65oqA6IO95LiN5Yy56YWNDQogICAgICAgICAgICAgICAgICAgIGlmIChwcmVmaWx0ZXJSZXN1bHQuUHJlZmlsdGVyU2NvcmUgPCAzMC4wKSAvLyDmioDog73ljLnphY3pmIjlgLwNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgLy8g6L2v57qm5p2f77ya5oqA6IO95LiN5Yy56YWN5YWB6K645YiG6YWN5L2G5pa95Yqg5oOp572aDQogICAgICAgICAgICAgICAgICAgICAgICAvLyDov5nph4zkuI3orr7noaznuqbmnZ/vvIzogIzmmK/pgJrov4fnm67moIflh73mlbDkuK3nmoTor4TliIbmnLrliLblpITnkIYNCiAgICAgICAgICAgICAgICAgICAgICAgIF9sb2dnZXIuTG9nVHJhY2UoIuKaoO+4jyDmioDog73ljLnphY3luqbovoPkvY4gLSDku7vliqF7VGFza0lkfeS6uuWRmHtQZXJzb25uZWxJZH3vvJror4TliIZ7U2NvcmV9IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFza0lkLCBwZXJzb25uZWxJZCwgcHJlZmlsdGVyUmVzdWx0LlByZWZpbHRlclNjb3JlKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgX2xvZ2dlci5Mb2dEZWJ1Zygi4pyFIOaKgOiDveWMuemFjee6puadn+aehOW7uuWujOaIkCAtIOe6puadn+aVsOmHj++8mntTa2lsbENvbnN0cmFpbnRDb3VudH3vvIjln7rkuo7pooTnrZvpgInor4TliIbvvIkiLCBjb25zdHJhaW50Q291bnQpOw0KICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRDb3VudDsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOa3u+WKoOmhueebrui/nue7reaAp+e6puadnyAtIOehruS/neWQjOmhueebruS7u+WKoeeUseebuOWvueeos+WumueahOWboumYn+aJp+ihjA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIGludCBBZGRQcm9qZWN0Q29udGludWl0eUNvbnN0cmFpbnRzKA0KICAgICAgICAgICAgU29sdmVyIHNvbHZlciwNCiAgICAgICAgICAgIERpY3Rpb25hcnk8KGxvbmcgVGFza0lkLCBsb25nIFBlcnNvbm5lbElkKSwgVmFyaWFibGU+IGRlY2lzaW9uVmFycywNCiAgICAgICAgICAgIERpY3Rpb25hcnk8c3RyaW5nLCBWYXJpYWJsZT4gYXV4aWxpYXJ5VmFycywNCiAgICAgICAgICAgIEdsb2JhbEFsbG9jYXRpb25Db250ZXh0IGNvbnRleHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBjb25zdHJhaW50Q291bnQgPSAwOw0KDQogICAgICAgICAgICAvLyDmjInpobnnm67liIbnu4Tku7vliqENCiAgICAgICAgICAgIHZhciBwcm9qZWN0R3JvdXBzID0gY29udGV4dC5UYXNrcw0KICAgICAgICAgICAgICAgIC5Hcm91cEJ5KHQgPT4gRXh0cmFjdFByb2plY3RGcm9tV29ya09yZGVyQ29kZSh0LldvcmtPcmRlckNvZGUpKQ0KICAgICAgICAgICAgICAgIC5XaGVyZShnID0+ICFzdHJpbmcuSXNOdWxsT3JFbXB0eShnLktleSkgJiYgZy5Db3VudCgpID4gMSkNCiAgICAgICAgICAgICAgICAuVG9MaXN0KCk7DQoNCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBwcm9qZWN0R3JvdXAgaW4gcHJvamVjdEdyb3VwcykNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB2YXIgcHJvamVjdFRhc2tzID0gcHJvamVjdEdyb3VwLlRvTGlzdCgpOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOmZkOWItumhueebruS6uuWRmOaVsOmHj++8jOS/g+i/m+i/nue7reaApw0KICAgICAgICAgICAgICAgIHZhciBtYXhQcm9qZWN0UGVyc29ubmVsID0gTWF0aC5NYXgoMiwgcHJvamVjdFRhc2tzLkNvdW50IC8gMik7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g5Li66aG555uu5Yib5bu65Lq65ZGY5Y+C5LiO5oyH56S65Y+Y6YePDQogICAgICAgICAgICAgICAgdmFyIHByb2plY3RQZXJzb25uZWxWYXJzID0gbmV3IERpY3Rpb25hcnk8bG9uZywgVmFyaWFibGU+KCk7DQogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHBlcnNvbm5lbCBpbiBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbCkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciBwYXJ0aWNpcGF0aW9uVmFyID0gc29sdmVyLk1ha2VCb29sVmFyKCQicHJvamVjdF9wYXJ0aWNpcGF0aW9uX3twcm9qZWN0R3JvdXAuS2V5fV97cGVyc29ubmVsLklkfSIpOw0KICAgICAgICAgICAgICAgICAgICBwcm9qZWN0UGVyc29ubmVsVmFyc1twZXJzb25uZWwuSWRdID0gcGFydGljaXBhdGlvblZhcjsNCiAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIC8vIOWmguaenOS6uuWRmOWPguS4jumhueebru+8jOWImeiHs+WwkeWIhumFjeS4gOS4quS7u+WKoQ0KICAgICAgICAgICAgICAgICAgICB2YXIgY29uc3RyYWludCA9IHNvbHZlci5NYWtlQ29uc3RyYWludCgwLCBkb3VibGUuUG9zaXRpdmVJbmZpbml0eSwgDQogICAgICAgICAgICAgICAgICAgICAgICAkInByb2plY3RfbWluX3Rhc2tzX3twcm9qZWN0R3JvdXAuS2V5fV97cGVyc29ubmVsLklkfSIpOw0KICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludC5TZXRDb2VmZmljaWVudChwYXJ0aWNpcGF0aW9uVmFyLCAtMSk7DQogICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgdGFzayBpbiBwcm9qZWN0VGFza3MpDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZWNpc2lvblZhcnMuQ29udGFpbnNLZXkoKHRhc2suSWQsIHBlcnNvbm5lbC5JZCkpKQ0KICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnQuU2V0Q29lZmZpY2llbnQoZGVjaXNpb25WYXJzWyh0YXNrLklkLCBwZXJzb25uZWwuSWQpXSwgMSk7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludENvdW50Kys7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOmZkOWItumhueebruWPguS4juS6uuWRmOaAu+aVsA0KICAgICAgICAgICAgICAgIHZhciBwZXJzb25uZWxMaW1pdENvbnN0cmFpbnQgPSBzb2x2ZXIuTWFrZUNvbnN0cmFpbnQoMCwgbWF4UHJvamVjdFBlcnNvbm5lbCwgDQogICAgICAgICAgICAgICAgICAgICQicHJvamVjdF9wZXJzb25uZWxfbGltaXRfe3Byb2plY3RHcm91cC5LZXl9Iik7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGt2cCBpbiBwcm9qZWN0UGVyc29ubmVsVmFycykNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHBlcnNvbm5lbExpbWl0Q29uc3RyYWludC5TZXRDb2VmZmljaWVudChrdnAuVmFsdWUsIDEpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBjb25zdHJhaW50Q291bnQrKzsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgX2xvZ2dlci5Mb2dEZWJ1Zygi4pyFIOmhueebrui/nue7reaAp+e6puadn+aehOW7uuWujOaIkCAtIOe6puadn+aVsOmHj++8mntDb250aW51aXR5Q29uc3RyYWludENvdW50fSIsIGNvbnN0cmFpbnRDb3VudCk7DQogICAgICAgICAgICByZXR1cm4gY29uc3RyYWludENvdW50Ow0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g44CQ6YeN5p6E5LyY5YyW44CR5re75Yqg5Lq65ZGY6LWE6LSo57qm5p2fIC0g5Z+65LqOQ29udGV4dEJ1aWxkZXJFbmdpbmXnmoTmiJDnhp/lrp7ot7UNCiAgICAgICAgLy8vIOOAkOaetuaehOaUuei/m+OAke+8muWkjeeUqOmihOaehOW7uueahOmihOetm+mAiee7k+aenO+8jOmBv+WFjemHjeWkjeeahOi1hOi0qOmqjOivgemAu+i+kQ0KICAgICAgICAvLy8g44CQ5oCn6IO95LyY5YyW44CR77ya5Yip55SoUHJlZmlsdGVyUmVzdWx0c+e8k+WtmO+8jOWunueOsE8oMSnmn6Xor6LlpI3mnYLluqYNCiAgICAgICAgLy8vIOOAkOS4gOiHtOaAp+S/neivgeOAke+8muS4jkNvbnRleHRCdWlsZGVyRW5naW5l5L2/55So5a6M5YWo55u45ZCM55qE6LWE6LSo6aqM6K+B5qCH5YeGDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgYXN5bmMgVGFzazxpbnQ+IEFkZFF1YWxpZmljYXRpb25Db25zdHJhaW50cygNCiAgICAgICAgICAgIFNvbHZlciBzb2x2ZXIsDQogICAgICAgICAgICBEaWN0aW9uYXJ5PChsb25nIFRhc2tJZCwgbG9uZyBQZXJzb25uZWxJZCksIFZhcmlhYmxlPiBkZWNpc2lvblZhcnMsDQogICAgICAgICAgICBHbG9iYWxBbGxvY2F0aW9uQ29udGV4dCBjb250ZXh0KQ0KICAgICAgICB7DQogICAgICAgICAgICB2YXIgY29uc3RyYWludENvdW50ID0gMDsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgX2xvZ2dlci5Mb2dEZWJ1Zygi8J+UjSDlvIDlp4vmnoTlu7rotYTotKjnuqbmnZ8gLSDln7rkuo7pooTnrZvpgInnu5PmnpznmoTpq5jmlYjlrp7njrAiKTsNCg0KICAgICAgICAgICAgZm9yZWFjaCAodmFyIGt2cCBpbiBkZWNpc2lvblZhcnMpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyICh0YXNrSWQsIHBlcnNvbm5lbElkKSA9IGt2cC5LZXk7DQogICAgICAgICAgICAgICAgdmFyIHZhcmlhYmxlID0ga3ZwLlZhbHVlOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOOAkOaguOW/g+aUuei/m+OAkeebtOaOpeS9v+eUqOmihOetm+mAiee7k+aenOS4reeahOi1hOi0qOmqjOivgee7k+aenA0KICAgICAgICAgICAgICAgIHZhciBwcmVmaWx0ZXJLZXkgPSAkInt0YXNrSWR9X3twZXJzb25uZWxJZH0iOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIGlmIChjb250ZXh0LlByZWZpbHRlclJlc3VsdHMuVHJ5R2V0VmFsdWUocHJlZmlsdGVyS2V5LCBvdXQgdmFyIHByZWZpbHRlclJlc3VsdCkpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAvLyDmo4Dmn6XpooTnrZvpgInnu5PmnpzkuK3mmK/lkKbljIXlkKvotYTotKjnm7jlhbPnmoTov53op4QNCiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc1F1YWxpZmljYXRpb25WaW9sYXRpb24gPSBwcmVmaWx0ZXJSZXN1bHQuQ29uc3RyYWludFZpb2xhdGlvbnMNCiAgICAgICAgICAgICAgICAgICAgICAgIC5BbnkodmlvbGF0aW9uID0+IHZpb2xhdGlvbi5Db250YWlucygi6LWE6LSoIikgfHwgdmlvbGF0aW9uLkNvbnRhaW5zKCJxdWFsaWZpY2F0aW9uIikpOw0KICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc1F1YWxpZmljYXRpb25WaW9sYXRpb24pDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOehrOe6puadn++8mumihOetm+mAieWPkeeOsOi1hOi0qOi/neinhO+8jOemgeatouatpOWIhumFjQ0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnN0cmFpbnQgPSBzb2x2ZXIuTWFrZUNvbnN0cmFpbnQoMCwgMCwgJCJwcmVmaWx0ZXJfcXVhbGlmaWNhdGlvbl97dGFza0lkfV97cGVyc29ubmVsSWR9Iik7DQogICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50LlNldENvZWZmaWNpZW50KHZhcmlhYmxlLCAxKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRDb3VudCsrOw0KICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICBfbG9nZ2VyLkxvZ1RyYWNlKCLwn5qrIOi1hOi0qOe6puadn+W6lOeUqCAtIOS7u+WKoXtUYXNrSWR95Lq65ZGYe1BlcnNvbm5lbElkfe+8mntWaW9sYXRpb25zfSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tJZCwgcGVyc29ubmVsSWQsIHN0cmluZy5Kb2luKCI7ICIsIHByZWZpbHRlclJlc3VsdC5Db25zdHJhaW50VmlvbGF0aW9ucy5UYWtlKDIpKSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgLy8g44CQ5a6J5YWo5L+d6Zqc44CR5peg6aKE562b6YCJ5pWw5o2u5pe255qE5ZCO5aSH6aqM6K+BDQogICAgICAgICAgICAgICAgICAgIHZhciBpc1F1YWxpZmllZCA9IGF3YWl0IENoZWNrUXVhbGlmaWNhdGlvbkNvbXBhdGliaWxpdHlBc3luYyh0YXNrSWQsIHBlcnNvbm5lbElkLCBjb250ZXh0KTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1F1YWxpZmllZCkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnN0cmFpbnQgPSBzb2x2ZXIuTWFrZUNvbnN0cmFpbnQoMCwgMCwgJCJmYWxsYmFja19xdWFsaWZpY2F0aW9uX3t0YXNrSWR9X3twZXJzb25uZWxJZH0iKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnQuU2V0Q29lZmZpY2llbnQodmFyaWFibGUsIDEpOw0KICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludENvdW50Kys7DQogICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgIF9sb2dnZXIuTG9nVHJhY2UoIvCfmqsg5ZCO5aSH6LWE6LSo57qm5p2f5bqU55SoIC0g5Lu75Yqhe1Rhc2tJZH3kurrlkZh7UGVyc29ubmVsSWR9IiwgdGFza0lkLCBwZXJzb25uZWxJZCk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIF9sb2dnZXIuTG9nSW5mb3JtYXRpb24oIuKchSDotYTotKjnuqbmnZ/mnoTlu7rlrozmiJAgLSDnuqbmnZ/mlbDph4/vvJp7UXVhbGlmaWNhdGlvbkNvbnN0cmFpbnRDb3VudH3vvIjln7rkuo7pooTnrZvpgInnu5PmnpzvvIkiLCBjb25zdHJhaW50Q291bnQpOw0KICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRDb3VudDsNCiAgICAgICAgfQ0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIOWFrOW5s+aAp+e6puadnyAtIOWvueW6lOmBl+S8oOeul+azlei0n+i9veWdh+ihoeacuuWItg0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOa3u+WKoOWFrOW5s+aAp+e6puadnyAtIOWvueW6lOmBl+S8oOeul+azleeahENhbGN1bGF0ZUZhaXJuZXNzU2NvcmXlkozotJ/ovb3lnYfooaHmnLrliLYNCiAgICAgICAgLy8vIOWMheWQq++8mui0n+i9veWdh+ihoee6puadn+OAgeS6uuWRmOWIqeeUqOeOh+e6puadn+OAgei/h+W6pumbhuS4reaDqee9mue6puadnw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIHZvaWQgQWRkRmFpcm5lc3NDb25zdHJhaW50cygNCiAgICAgICAgICAgIFNvbHZlciBzb2x2ZXIsDQogICAgICAgICAgICBEaWN0aW9uYXJ5PChsb25nIFRhc2tJZCwgbG9uZyBQZXJzb25uZWxJZCksIFZhcmlhYmxlPiBkZWNpc2lvblZhcnMsDQogICAgICAgICAgICBEaWN0aW9uYXJ5PHN0cmluZywgVmFyaWFibGU+IGF1eGlsaWFyeVZhcnMsDQogICAgICAgICAgICBHbG9iYWxBbGxvY2F0aW9uQ29udGV4dCBjb250ZXh0KQ0KICAgICAgICB7DQogICAgICAgICAgICB2YXIgY29uc3RyYWludENvdW50ID0gMDsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgX2xvZ2dlci5Mb2dJbmZvcm1hdGlvbigi4pqW77iPIOW8gOWni+a3u+WKoOWFrOW5s+aAp+e6puadny4uLiIpOw0KDQogICAgICAgICAgICB2YXIgdG90YWxUYXNrcyA9IGNvbnRleHQuVGFza3MuQ291bnQ7DQogICAgICAgICAgICB2YXIgdG90YWxQZXJzb25uZWwgPSBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbC5Db3VudDsNCiAgICAgICAgICAgIHZhciBhdmdXb3JrbG9hZCA9IChkb3VibGUpdG90YWxUYXNrcyAvIHRvdGFsUGVyc29ubmVsOw0KDQogICAgICAgICAgICAvLyDlhazlubPmgKfnuqbmnZ8x77ya6LSf6L295Z2H6KGh5YGP5beu6K6h566XDQogICAgICAgICAgICBmb3JlYWNoICh2YXIgcGVyc29ubmVsIGluIGNvbnRleHQuQXZhaWxhYmxlUGVyc29ubmVsKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciB3b3JrbG9hZFZhcktleSA9ICQid29ya2xvYWRfe3BlcnNvbm5lbC5JZH0iOw0KICAgICAgICAgICAgICAgIHZhciBwb3NEZXZWYXJLZXkgPSAkInBvc19kZXZfe3BlcnNvbm5lbC5JZH0iOw0KICAgICAgICAgICAgICAgIHZhciBuZWdEZXZWYXJLZXkgPSAkIm5lZ19kZXZfe3BlcnNvbm5lbC5JZH0iOw0KDQogICAgICAgICAgICAgICAgaWYgKGF1eGlsaWFyeVZhcnMuQ29udGFpbnNLZXkod29ya2xvYWRWYXJLZXkpICYmIA0KICAgICAgICAgICAgICAgICAgICBhdXhpbGlhcnlWYXJzLkNvbnRhaW5zS2V5KHBvc0RldlZhcktleSkgJiYgDQogICAgICAgICAgICAgICAgICAgIGF1eGlsaWFyeVZhcnMuQ29udGFpbnNLZXkobmVnRGV2VmFyS2V5KSkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIC8vIOe6puadn++8mndvcmtsb2FkID0gYXZnV29ya2xvYWQgKyBwb3NfZGV2aWF0aW9uIC0gbmVnX2RldmlhdGlvbg0KICAgICAgICAgICAgICAgICAgICB2YXIgYmFsYW5jZUNvbnN0cmFpbnQgPSBzb2x2ZXIuTWFrZUNvbnN0cmFpbnQoYXZnV29ya2xvYWQsIGF2Z1dvcmtsb2FkLCANCiAgICAgICAgICAgICAgICAgICAgICAgICQibG9hZF9iYWxhbmNlX3twZXJzb25uZWwuSWR9Iik7DQogICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICBiYWxhbmNlQ29uc3RyYWludC5TZXRDb2VmZmljaWVudChhdXhpbGlhcnlWYXJzW3dvcmtsb2FkVmFyS2V5XSwgMSk7DQogICAgICAgICAgICAgICAgICAgIGJhbGFuY2VDb25zdHJhaW50LlNldENvZWZmaWNpZW50KGF1eGlsaWFyeVZhcnNbcG9zRGV2VmFyS2V5XSwgLTEpOw0KICAgICAgICAgICAgICAgICAgICBiYWxhbmNlQ29uc3RyYWludC5TZXRDb2VmZmljaWVudChhdXhpbGlhcnlWYXJzW25lZ0RldlZhcktleV0sIDEpOw0KICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50Q291bnQrKzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIOWFrOW5s+aAp+e6puadnzLvvJrmnIDlpKfotJ/ovb3pmZDliLYgLSDpmLLmraLmnoHnq6/kuI3lnYfooaENCiAgICAgICAgICAgIHZhciBtYXhSZWFzb25hYmxlV29ya2xvYWQgPSBNYXRoLkNlaWxpbmcoYXZnV29ya2xvYWQgKiAxLjUpOw0KICAgICAgICAgICAgZm9yZWFjaCAodmFyIHBlcnNvbm5lbCBpbiBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB2YXIgd29ya2xvYWRWYXJLZXkgPSAkIndvcmtsb2FkX3twZXJzb25uZWwuSWR9IjsNCiAgICAgICAgICAgICAgICBpZiAoYXV4aWxpYXJ5VmFycy5Db250YWluc0tleSh3b3JrbG9hZFZhcktleSkpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICB2YXIgY29uc3RyYWludCA9IHNvbHZlci5NYWtlQ29uc3RyYWludCgwLCBtYXhSZWFzb25hYmxlV29ya2xvYWQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgJCJtYXhfd29ya2xvYWRfe3BlcnNvbm5lbC5JZH0iKTsNCiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludC5TZXRDb2VmZmljaWVudChhdXhpbGlhcnlWYXJzW3dvcmtsb2FkVmFyS2V5XSwgMSk7DQogICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRDb3VudCsrOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8g5YWs5bmz5oCn57qm5p2fM++8muacgOWwj+S6uuWRmOWIqeeUqOeOh+e6puadnyAtIOehruS/neS4jeS8mui/h+W6pumbhuS4rQ0KICAgICAgICAgICAgdmFyIG1pblBlcnNvbm5lbFV0aWxpemF0aW9uID0gdG90YWxUYXNrcyA+IDEwID8gTWF0aC5NYXgoMywgdG90YWxQZXJzb25uZWwgKiAwLjQpIDogMjsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgLy8g5Yib5bu65Lq65ZGY5Y+C5LiO5oyH56S65Y+Y6YePDQogICAgICAgICAgICB2YXIgcGFydGljaXBhdGlvblZhcnMgPSBuZXcgTGlzdDxWYXJpYWJsZT4oKTsNCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBwZXJzb25uZWwgaW4gY29udGV4dC5BdmFpbGFibGVQZXJzb25uZWwpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyIHBhcnRpY2lwYXRpb25WYXIgPSBzb2x2ZXIuTWFrZUJvb2xWYXIoJCJwYXJ0aWNpcGF0aW9uX3twZXJzb25uZWwuSWR9Iik7DQogICAgICAgICAgICAgICAgcGFydGljaXBhdGlvblZhcnMuQWRkKHBhcnRpY2lwYXRpb25WYXIpOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOWmguaenOS6uuWRmOWPguS4ju+8jOWImeiHs+WwkeWIhumFjTHkuKrku7vliqENCiAgICAgICAgICAgICAgICB2YXIgY29uc3RyYWludCA9IHNvbHZlci5NYWtlQ29uc3RyYWludCgwLCBkb3VibGUuUG9zaXRpdmVJbmZpbml0eSwgDQogICAgICAgICAgICAgICAgICAgICQicGFydGljaXBhdGlvbl9taW5fe3BlcnNvbm5lbC5JZH0iKTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICBjb25zdHJhaW50LlNldENvZWZmaWNpZW50KHBhcnRpY2lwYXRpb25WYXIsIC0xKTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICB2YXIgcGVyc29ubmVsVGFza3MgPSBkZWNpc2lvblZhcnMuV2hlcmUodiA9PiB2LktleS5QZXJzb25uZWxJZCA9PSBwZXJzb25uZWwuSWQpOw0KICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBrdnAgaW4gcGVyc29ubmVsVGFza3MpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50LlNldENvZWZmaWNpZW50KGt2cC5WYWx1ZSwgMSk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRDb3VudCsrOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgDQogICAgICAgICAgICAvLyDmnIDlsI/lj4LkuI7kurrmlbDnuqbmnZ8NCiAgICAgICAgICAgIHZhciBtaW5QYXJ0aWNpcGF0aW9uQ29uc3RyYWludCA9IHNvbHZlci5NYWtlQ29uc3RyYWludChtaW5QZXJzb25uZWxVdGlsaXphdGlvbiwgZG91YmxlLlBvc2l0aXZlSW5maW5pdHksIA0KICAgICAgICAgICAgICAgICJtaW5fcGVyc29ubmVsX3V0aWxpemF0aW9uIik7DQogICAgICAgICAgICANCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBwYXJ0aWNpcGF0aW9uVmFyIGluIHBhcnRpY2lwYXRpb25WYXJzKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIG1pblBhcnRpY2lwYXRpb25Db25zdHJhaW50LlNldENvZWZmaWNpZW50KHBhcnRpY2lwYXRpb25WYXIsIDEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY29uc3RyYWludENvdW50Kys7DQoNCiAgICAgICAgICAgIF9sb2dnZXIuTG9nRGVidWcoIuKchSDlhazlubPmgKfnuqbmnZ/mt7vliqDlrozmiJAgLSDnuqbmnZ/mlbDph4/vvJp7Q29uc3RyYWludENvdW50fe+8jOW5s+Wdh+i0n+i9ve+8mntBdmdXb3JrbG9hZDpGMn3vvIzmnIDlpKfotJ/ovb3vvJp7TWF4V29ya2xvYWQ6RjJ977yM5pyA5bCP5Y+C5LiO5Lq65pWw77yae01pblBhcnRpY2lwYXRpb259IiwgDQogICAgICAgICAgICAgICAgY29uc3RyYWludENvdW50LCBhdmdXb3JrbG9hZCwgbWF4UmVhc29uYWJsZVdvcmtsb2FkLCBtaW5QZXJzb25uZWxVdGlsaXphdGlvbik7DQogICAgICAgIH0NCg0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgI3JlZ2lvbiDnm67moIflh73mlbAgLSDlr7nlupTpgZfkvKDnrpfms5XpgILlupTluqblh73mlbANCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDorr7nva7lop7lvLrniYjnm67moIflh73mlbAgLSDlr7nlupTpgZfkvKDnrpfms5XnmoTlpJrnu7TluqbpgILlupTluqbor4TkvLANCiAgICAgICAgLy8vIOebruagh+e7hOaIkO+8muWfuuehgOivhOWIhiArIOe6puadn+aDqee9miArIOWFrOW5s+aAp+WlluWKsSArIOS4muWKoeS8mOWFiOe6p+WlluWKsQ0KICAgICAgICAvLy8g5p2D6YeN6K6+6K6h77ya57qm5p2f5ruh6LazKOacgOmrmCkgPiDlhazlubPmgKco6auYKSA+IOS4muWKoeS8mOWMlijkuK0pID4g5YW25LuW5Zug57SgKOS9jikNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHJpdmF0ZSB2b2lkIFNldEVuaGFuY2VkT2JqZWN0aXZlRnVuY3Rpb24oDQogICAgICAgICAgICBTb2x2ZXIgc29sdmVyLA0KICAgICAgICAgICAgRGljdGlvbmFyeTwobG9uZyBUYXNrSWQsIGxvbmcgUGVyc29ubmVsSWQpLCBWYXJpYWJsZT4gZGVjaXNpb25WYXJzLA0KICAgICAgICAgICAgRGljdGlvbmFyeTxzdHJpbmcsIFZhcmlhYmxlPiBhdXhpbGlhcnlWYXJzLA0KICAgICAgICAgICAgR2xvYmFsQWxsb2NhdGlvbkNvbnRleHQgY29udGV4dCkNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIG9iamVjdGl2ZSA9IHNvbHZlci5PYmplY3RpdmUoKTsNCiAgICAgICAgICAgIG9iamVjdGl2ZS5TZXRNYXhpbWl6YXRpb24oKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgX2xvZ2dlci5Mb2dJbmZvcm1hdGlvbigi8J+OryDmnoTlu7rlop7lvLrniYjlpJrnu7Tluqbnm67moIflh73mlbAuLi4iKTsNCg0KICAgICAgICAgICAgLy8g55uu5qCH57uE5Lu2Me+8muWfuuehgOWIhumFjeivhOWIhiAtIOWfuuS6jumihOetm+mAiee7k+aenOeahOi0qOmHj+ivhOWIhg0KICAgICAgICAgICAgQWRkQmFzZUFzc2lnbm1lbnRTY29yZShvYmplY3RpdmUsIGRlY2lzaW9uVmFycywgY29udGV4dCk7DQoNCiAgICAgICAgICAgIC8vIOebruagh+e7hOS7tjLvvJrnuqbmnZ/ov53op4Tmg6nnvZogLSDlr7nlupTpgZfkvKDnrpfms5XnmoTnuqbmnZ/or4TliIYNCiAgICAgICAgICAgIEFkZENvbnN0cmFpbnRWaW9sYXRpb25QZW5hbHRpZXMob2JqZWN0aXZlLCBhdXhpbGlhcnlWYXJzLCBjb250ZXh0KTsNCg0KICAgICAgICAgICAgLy8g55uu5qCH57uE5Lu2M++8muWFrOW5s+aAp+WlluWKsSAtIOWvueW6lOmBl+S8oOeul+azleeahOWFrOW5s+aAp+ivhOWIhg0KICAgICAgICAgICAgQWRkRmFpcm5lc3NSZXdhcmRzKG9iamVjdGl2ZSwgYXV4aWxpYXJ5VmFycywgY29udGV4dCk7DQoNCiAgICAgICAgICAgIC8vIOebruagh+e7hOS7tjTvvJrkuJrliqHkvJjlhYjnuqflpZblirEgLSDlr7nlupTpgZfkvKDnrpfms5XnmoTkuJrliqHpgLvovpHkvJjljJYNCiAgICAgICAgICAgIC8vQWRkQnVzaW5lc3NQcmlvcml0eVJld2FyZHMob2JqZWN0aXZlLCBkZWNpc2lvblZhcnMsIGF1eGlsaWFyeVZhcnMsIGNvbnRleHQpOw0KDQogICAgICAgICAgICBfbG9nZ2VyLkxvZ0luZm9ybWF0aW9uKCLinIUg5aKe5by654mI55uu5qCH5Ye95pWw5p6E5bu65a6M5oiQ77yM5YyF5ZCrNOWkp+ivhOWIhue7tOW6piIpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g5re75Yqg5Z+656GA5YiG6YWN6K+E5YiGIC0g5Z+65LqO6aKE562b6YCJ57uT5p6c5ZKM5Lu75YqhLeS6uuWRmOWMuemFjei0qOmHjw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIHZvaWQgQWRkQmFzZUFzc2lnbm1lbnRTY29yZSgNCiAgICAgICAgICAgIE9iamVjdGl2ZSBvYmplY3RpdmUsDQogICAgICAgICAgICBEaWN0aW9uYXJ5PChsb25nIFRhc2tJZCwgbG9uZyBQZXJzb25uZWxJZCksIFZhcmlhYmxlPiBkZWNpc2lvblZhcnMsDQogICAgICAgICAgICBHbG9iYWxBbGxvY2F0aW9uQ29udGV4dCBjb250ZXh0KQ0KICAgICAgICB7DQogICAgICAgICAgICBmb3JlYWNoICh2YXIga3ZwIGluIGRlY2lzaW9uVmFycykNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB2YXIgKHRhc2tJZCwgcGVyc29ubmVsSWQpID0ga3ZwLktleTsNCiAgICAgICAgICAgICAgICB2YXIgdmFyaWFibGUgPSBrdnAuVmFsdWU7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g5Z+656GA6K+E5YiG77ya5Z+65LqO6aKE562b6YCJ57uT5p6cDQogICAgICAgICAgICAgICAgdmFyIHByZWZpbHRlcktleSA9ICQie3Rhc2tJZH1fe3BlcnNvbm5lbElkfSI7DQogICAgICAgICAgICAgICAgdmFyIGJhc2VTY29yZSA9IDEwMC4wOyAvLyDpu5jorqTln7rnoYDliIYNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICBpZiAoY29udGV4dC5QcmVmaWx0ZXJSZXN1bHRzLlRyeUdldFZhbHVlKHByZWZpbHRlcktleSwgb3V0IHZhciBwcmVmaWx0ZXJSZXN1bHQpKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgYmFzZVNjb3JlID0gTWF0aC5NYXgoYmFzZVNjb3JlLCBwcmVmaWx0ZXJSZXN1bHQuUHJlZmlsdGVyU2NvcmUgKiAyKTsgLy8g5pS+5aSn6aKE562b6YCJ6K+E5YiG55qE5b2x5ZONDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOaKgOiDveWMuemFjeWlluWKsQ0KICAgICAgICAgICAgICAgIHZhciB0YXNrID0gY29udGV4dC5UYXNrcy5GaXJzdE9yRGVmYXVsdCh0ID0+IHQuSWQgPT0gdGFza0lkKTsNCiAgICAgICAgICAgICAgICBpZiAodGFzayAhPSBudWxsKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHNraWxsQm9udXMgPSBDYWxjdWxhdGVTa2lsbE1hdGNoaW5nQm9udXModGFzaywgcGVyc29ubmVsSWQsIGNvbnRleHQpOw0KICAgICAgICAgICAgICAgICAgICBiYXNlU2NvcmUgKz0gc2tpbGxCb251czsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgb2JqZWN0aXZlLlNldENvZWZmaWNpZW50KHZhcmlhYmxlLCBiYXNlU2NvcmUpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g5re75Yqg57qm5p2f6L+d6KeE5oOp572aIC0g5a+55bqU6YGX5Lyg566X5rOV55qE5LiJ57qn57qm5p2f5oOp572a5py65Yi2DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgdm9pZCBBZGRDb25zdHJhaW50VmlvbGF0aW9uUGVuYWx0aWVzKA0KICAgICAgICAgICAgT2JqZWN0aXZlIG9iamVjdGl2ZSwNCiAgICAgICAgICAgIERpY3Rpb25hcnk8c3RyaW5nLCBWYXJpYWJsZT4gYXV4aWxpYXJ5VmFycywNCiAgICAgICAgICAgIEdsb2JhbEFsbG9jYXRpb25Db250ZXh0IGNvbnRleHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIC8vIExldmVsIDHmg6nnvZrvvJrml7bpl7TlhrLnqoHkuKXljonmg6nnvZoNCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBrdnAgaW4gYXV4aWxpYXJ5VmFycy5XaGVyZSh2ID0+IHYuS2V5LlN0YXJ0c1dpdGgoImNvbmZsaWN0XyIpKSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBvYmplY3RpdmUuU2V0Q29lZmZpY2llbnQoa3ZwLlZhbHVlLCAtTEVWRUwxX0NPTlNUUkFJTlRfUEVOQUxUWSk7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIExldmVsIDLmg6nnvZrvvJrnj63mrKHop4TliJnov53op4Tph43luqbmg6nnvZoNCiAgICAgICAgICAgIC8vIGZvcmVhY2ggKHZhciBrdnAgaW4gYXV4aWxpYXJ5VmFycy5XaGVyZSh2ID0+IHYuS2V5LlN0YXJ0c1dpdGgoInNoaWZ0X3Zpb2xhdGlvbl8iKSkpDQogICAgICAgICAgICAvLyB7DQogICAgICAgICAgICAvLyAgICAgb2JqZWN0aXZlLlNldENvZWZmaWNpZW50KGt2cC5WYWx1ZSwgLUxFVkVMMl9DT05TVFJBSU5UX1BFTkFMVFkpOw0KICAgICAgICAgICAgLy8gfQ0KDQogICAgICAgICAgICAvLyBMZXZlbCAz5oOp572a77ya5Lia5Yqh6YC76L6R6L+d6KeE5Lit5bqm5oOp572aDQogICAgICAgICAgICAvLyBmb3JlYWNoICh2YXIga3ZwIGluIGF1eGlsaWFyeVZhcnMuV2hlcmUodiA9PiB2LktleS5TdGFydHNXaXRoKCJmbF92aW9sYXRpb25fIikpKQ0KICAgICAgICAgICAgLy8gew0KICAgICAgICAgICAgLy8gICAgIG9iamVjdGl2ZS5TZXRDb2VmZmljaWVudChrdnAuVmFsdWUsIC1MRVZFTDNfQ09OU1RSQUlOVF9QRU5BTFRZKTsNCiAgICAgICAgICAgIC8vIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOa3u+WKoOWFrOW5s+aAp+WlluWKsSAtIOWvueW6lOmBl+S8oOeul+azleeahOi0n+i9veWdh+ihoeivhOWIhg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIHZvaWQgQWRkRmFpcm5lc3NSZXdhcmRzKA0KICAgICAgICAgICAgT2JqZWN0aXZlIG9iamVjdGl2ZSwNCiAgICAgICAgICAgIERpY3Rpb25hcnk8c3RyaW5nLCBWYXJpYWJsZT4gYXV4aWxpYXJ5VmFycywNCiAgICAgICAgICAgIEdsb2JhbEFsbG9jYXRpb25Db250ZXh0IGNvbnRleHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIC8vIOi0n+i9veWdh+ihoeWlluWKse+8muWHj+WwkeWBj+W3ruiOt+W+l+WlluWKsQ0KICAgICAgICAgICAgLy8gZm9yZWFjaCAodmFyIGt2cCBpbiBhdXhpbGlhcnlWYXJzLldoZXJlKHYgPT4gdi5LZXkuU3RhcnRzV2l0aCgicG9zX2Rldl8iKSB8fCB2LktleS5TdGFydHNXaXRoKCJuZWdfZGV2XyIpKSkNCiAgICAgICAgICAgIC8vIHsNCiAgICAgICAgICAgIC8vICAgICAvLyDlgY/lt67otorlsI/vvIzlpZblirHotorlpJrvvIjpgJrov4fotJ/nmoTlgY/lt67ns7vmlbDlrp7njrDvvIkNCiAgICAgICAgICAgIC8vICAgICBvYmplY3RpdmUuU2V0Q29lZmZpY2llbnQoa3ZwLlZhbHVlLCAtRkFJUk5FU1NfUkVXQVJEX0ZBQ1RPUik7DQogICAgICAgICAgICAvLyB9DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDmt7vliqDkuJrliqHkvJjlhYjnuqflpZblirEgLSDlr7nlupTpgZfkvKDnrpfms5XnmoTkuJrliqHop4TliJnkvJjljJYNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHJpdmF0ZSB2b2lkIEFkZEJ1c2luZXNzUHJpb3JpdHlSZXdhcmRzKA0KICAgICAgICAgICAgT2JqZWN0aXZlIG9iamVjdGl2ZSwNCiAgICAgICAgICAgIERpY3Rpb25hcnk8KGxvbmcgVGFza0lkLCBsb25nIFBlcnNvbm5lbElkKSwgVmFyaWFibGU+IGRlY2lzaW9uVmFycywNCiAgICAgICAgICAgIERpY3Rpb25hcnk8c3RyaW5nLCBWYXJpYWJsZT4gYXV4aWxpYXJ5VmFycywNCiAgICAgICAgICAgIEdsb2JhbEFsbG9jYXRpb25Db250ZXh0IGNvbnRleHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIC8vIEZM5LyY5YWI57qn5aWW5YqxDQogICAgICAgICAgICBmb3JlYWNoICh2YXIgdGFzayBpbiBjb250ZXh0LlRhc2tzKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciB0YXNrRkxQZXJzb25uZWwgPSB0YXNrLldvcmtPcmRlckZMUGVyc29ubmVscz8NCiAgICAgICAgICAgICAgICAgICAgLlNlbGVjdChmbCA9PiBmbC5GTFBlcnNvbm5lbElkKQ0KICAgICAgICAgICAgICAgICAgICAuV2hlcmUoZmxJZCA9PiBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbC5BbnkocCA9PiBwLklkID09IGZsSWQpKQ0KICAgICAgICAgICAgICAgICAgICAuVG9MaXN0KCkgPz8gbmV3IExpc3Q8bG9uZz4oKTsNCg0KICAgICAgICAgICAgICAgIGlmICh0YXNrRkxQZXJzb25uZWwuQW55KCkpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgZmxQZXJzb25uZWxJZCBpbiB0YXNrRkxQZXJzb25uZWwpDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZWNpc2lvblZhcnMuQ29udGFpbnNLZXkoKHRhc2suSWQsIGZsUGVyc29ubmVsSWQpKSkNCiAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGTOS6uuWRmOaJp+ihjOacrOmhueebruS7u+WKoeiOt+W+l+WlluWKsQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdGl2ZS5TZXRDb2VmZmljaWVudChkZWNpc2lvblZhcnNbKHRhc2suSWQsIGZsUGVyc29ubmVsSWQpXSwgNTAwLjApOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyDku7vliqHkvJjlhYjnuqflkozntKfmgKXluqblpZblirENCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YXNrIGluIGNvbnRleHQuVGFza3MpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyIHByaW9yaXR5Qm9udXMgPSB0YXNrLlByaW9yaXR5ICogNTAuMDsNCiAgICAgICAgICAgICAgICB2YXIgdXJnZW5jeUJvbnVzID0gdGFzay5VcmdlbmN5ICogMzAuMDsNCiAgICAgICAgICAgICAgICB2YXIgdG90YWxCb251cyA9IHByaW9yaXR5Qm9udXMgKyB1cmdlbmN5Qm9udXM7DQoNCiAgICAgICAgICAgICAgICB2YXIgdGFza1ZhcmlhYmxlcyA9IGRlY2lzaW9uVmFycy5XaGVyZSh2ID0+IHYuS2V5LlRhc2tJZCA9PSB0YXNrLklkKTsNCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIga3ZwIGluIHRhc2tWYXJpYWJsZXMpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBvYmplY3RpdmUuU2V0Q29lZmZpY2llbnQoa3ZwLlZhbHVlLCB0b3RhbEJvbnVzKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgI3JlZ2lvbiDnu5PmnpzlpITnkIblkozpqozor4ENCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDlpITnkIblop7lvLrniYjmsYLop6Plmajnu5PmnpwgLSDljIXlkKvlrozmlbTnmoTop6PmnpDlkozpqozor4HpgLvovpENCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHJpdmF0ZSBhc3luYyBUYXNrPEdsb2JhbE9wdGltaXplZFNvbHV0aW9uPiBQcm9jZXNzRW5oYW5jZWRTb2x2ZXJSZXN1bHQoDQogICAgICAgICAgICBTb2x2ZXIgc29sdmVyLA0KICAgICAgICAgICAgRGljdGlvbmFyeTwobG9uZyBUYXNrSWQsIGxvbmcgUGVyc29ubmVsSWQpLCBWYXJpYWJsZT4gZGVjaXNpb25WYXJzLA0KICAgICAgICAgICAgRGljdGlvbmFyeTxzdHJpbmcsIFZhcmlhYmxlPiBhdXhpbGlhcnlWYXJzLA0KICAgICAgICAgICAgR2xvYmFsQWxsb2NhdGlvbkNvbnRleHQgY29udGV4dCwNCiAgICAgICAgICAgIFNvbHZlci5SZXN1bHRTdGF0dXMgcmVzdWx0U3RhdHVzLA0KICAgICAgICAgICAgbG9uZyBlbGFwc2VkTXMpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBzb2x1dGlvbiA9IG5ldyBHbG9iYWxPcHRpbWl6ZWRTb2x1dGlvbg0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIEFjdHVhbEdlbmVyYXRpb25zID0gMSAvLyDnur/mgKfop4TliJLkuIDmrKHmsYLop6MNCiAgICAgICAgICAgIH07DQoNCiAgICAgICAgICAgIF9sb2dnZXIuTG9nSW5mb3JtYXRpb24oIvCfk4og5byA5aeL6Kej5p6Q5aKe5by654mI57q/5oCn6KeE5YiS57uT5p6cIC0g54q25oCB77yae1N0YXR1c33vvIzogJfml7bvvJp7RWxhcHNlZE1zfW1zIiwgDQogICAgICAgICAgICAgICAgcmVzdWx0U3RhdHVzLCBlbGFwc2VkTXMpOw0KDQogICAgICAgICAgICBpZiAocmVzdWx0U3RhdHVzID09IFNvbHZlci5SZXN1bHRTdGF0dXMuT1BUSU1BTCB8fCByZXN1bHRTdGF0dXMgPT0gU29sdmVyLlJlc3VsdFN0YXR1cy5GRUFTSUJMRSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB2YXIgYXNzaWdubWVudHMgPSBuZXcgRGljdGlvbmFyeTxsb25nLCBsb25nPigpOw0KICAgICAgICAgICAgICAgIHZhciB3b3JrbG9hZERpc3RyaWJ1dGlvbiA9IG5ldyBEaWN0aW9uYXJ5PGxvbmcsIGRlY2ltYWw+KCk7DQogICAgICAgICAgICAgICAgdmFyIHRvdGFsU2NvcmUgPSAwLjA7DQogICAgICAgICAgICAgICAgdmFyIGNvbnN0cmFpbnRWaW9sYXRpb25zID0gbmV3IExpc3Q8c3RyaW5nPigpOw0KDQogICAgICAgICAgICAgICAgLy8g6Kej5p6Q5Lu75Yqh5YiG6YWN57uT5p6cDQogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGt2cCBpbiBkZWNpc2lvblZhcnMpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBpZiAoa3ZwLlZhbHVlLlNvbHV0aW9uVmFsdWUoKSA+IDAuNSkgLy8g5biD5bCU5Y+Y6YeP6ZiI5YC8DQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciAodGFza0lkLCBwZXJzb25uZWxJZCkgPSBrdnAuS2V5Ow0KICAgICAgICAgICAgICAgICAgICAgICAgYXNzaWdubWVudHNbdGFza0lkXSA9IHBlcnNvbm5lbElkOw0KICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICB3b3JrbG9hZERpc3RyaWJ1dGlvbltwZXJzb25uZWxJZF0gPSB3b3JrbG9hZERpc3RyaWJ1dGlvbi5HZXRWYWx1ZU9yRGVmYXVsdChwZXJzb25uZWxJZCwgMCkgKyAxOw0KICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAvLyDorqHnrpfliIbphY3or4TliIYNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhc3NpZ25tZW50U2NvcmUgPSBDYWxjdWxhdGVBc3NpZ25tZW50U2NvcmUodGFza0lkLCBwZXJzb25uZWxJZCwgY29udGV4dCk7DQogICAgICAgICAgICAgICAgICAgICAgICB0b3RhbFNjb3JlICs9IGFzc2lnbm1lbnRTY29yZTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIC8vIOmqjOivgeino+eahOi0qOmHjw0KICAgICAgICAgICAgICAgIHZhciBxdWFsaXR5TWV0cmljcyA9IGF3YWl0IFZhbGlkYXRlU29sdXRpb25RdWFsaXR5KGFzc2lnbm1lbnRzLCBhdXhpbGlhcnlWYXJzLCBjb250ZXh0KTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICBzb2x1dGlvbi5CZXN0U29sdXRpb24gPSBhc3NpZ25tZW50czsNCiAgICAgICAgICAgICAgICBzb2x1dGlvbi5CZXN0Rml0bmVzcyA9IHNvbHZlci5PYmplY3RpdmUoKS5WYWx1ZSgpOw0KICAgICAgICAgICAgICAgIHNvbHV0aW9uLlBlcnNvbm5lbFdvcmtsb2FkRGlzdHJpYnV0aW9uID0gd29ya2xvYWREaXN0cmlidXRpb247DQogICAgICAgICAgICAgICAgc29sdXRpb24uQ29uc3RyYWludFNhdGlzZmFjdGlvblJhdGUgPSBxdWFsaXR5TWV0cmljcy5Db25zdHJhaW50U2F0aXNmYWN0aW9uUmF0ZTsNCiAgICAgICAgICAgICAgICAvLyBzb2x1dGlvbi5RdWFsaXR5TWV0cmljcyA9IHF1YWxpdHlNZXRyaWNzOyAvLyDmmoLml7bms6jph4rvvIznrYnlvoXmianlsZVHbG9iYWxPcHRpbWl6ZWRTb2x1dGlvbg0KDQogICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dJbmZvcm1hdGlvbigi4pyFIOWinuW8uueJiOe6v+aAp+inhOWIkuaxguino+aIkOWKnyAtIOebruagh+WAvO+8mntPYmplY3RpdmVWYWx1ZTpGMn3vvIzliIbphY3ku7vliqHvvJp7VGFza0NvdW50fe+8jOS9v+eUqOS6uuWRmO+8mntQZXJzb25uZWxDb3VudH3vvIznuqbmnZ/mu6HotrPnjofvvJp7U2F0aXNmYWN0aW9uUmF0ZTpQMn0iLA0KICAgICAgICAgICAgICAgICAgICBzb2x1dGlvbi5CZXN0Rml0bmVzcywgYXNzaWdubWVudHMuQ291bnQsIHdvcmtsb2FkRGlzdHJpYnV0aW9uLkNvdW50LCBxdWFsaXR5TWV0cmljcy5Db25zdHJhaW50U2F0aXNmYWN0aW9uUmF0ZSk7DQoNCiAgICAgICAgICAgICAgICAvLyDor6bnu4bnmoTlt6XkvZzotJ/ovb3liIbmnpANCiAgICAgICAgICAgICAgICBMb2dXb3JrbG9hZEFuYWx5c2lzKHdvcmtsb2FkRGlzdHJpYnV0aW9uLCBjb250ZXh0LlRhc2tzLkNvdW50LCBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbC5Db3VudCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dXYXJuaW5nKCLimqDvuI8g5aKe5by654mI57q/5oCn6KeE5YiS5peg6KejIC0g54q25oCB77yae1N0YXR1c33vvIzlj6/og73ljp/lm6DvvJrnuqbmnZ/ov4fkuo7kuKXmoLwiLCByZXN1bHRTdGF0dXMpOw0KICAgICAgICAgICAgICAgIHNvbHV0aW9uLkJlc3RTb2x1dGlvbiA9IG5ldyBEaWN0aW9uYXJ5PGxvbmcsIGxvbmc+KCk7DQogICAgICAgICAgICAgICAgc29sdXRpb24uQmVzdEZpdG5lc3MgPSAwLjA7DQogICAgICAgICAgICAgICAgc29sdXRpb24uQ29uc3RyYWludFNhdGlzZmFjdGlvblJhdGUgPSAwLjA7DQogICAgICAgICAgICAgICAgLy8gc29sdXRpb24uRXJyb3JNZXNzYWdlID0gJCLnur/mgKfop4TliJLmqKHlnovml6Dop6PvvIznirbmgIHvvJp7cmVzdWx0U3RhdHVzfSI7IC8vIOaaguaXtuazqOmHiu+8jOetieW+heaJqeWxlUdsb2JhbE9wdGltaXplZFNvbHV0aW9uDQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHJldHVybiBzb2x1dGlvbjsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOmqjOivgeino+eahOi0qOmHjyAtIOWvueW6lOmBl+S8oOeul+azleeahOe6puadn+a7oei2s+eOh+iuoeeulw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIGFzeW5jIFRhc2s8U29sdXRpb25RdWFsaXR5TWV0cmljcz4gVmFsaWRhdGVTb2x1dGlvblF1YWxpdHkoDQogICAgICAgICAgICBEaWN0aW9uYXJ5PGxvbmcsIGxvbmc+IGFzc2lnbm1lbnRzLCANCiAgICAgICAgICAgIERpY3Rpb25hcnk8c3RyaW5nLCBWYXJpYWJsZT4gYXV4aWxpYXJ5VmFycywNCiAgICAgICAgICAgIEdsb2JhbEFsbG9jYXRpb25Db250ZXh0IGNvbnRleHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIGF3YWl0IFRhc2suQ29tcGxldGVkVGFzazsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgdmFyIG1ldHJpY3MgPSBuZXcgU29sdXRpb25RdWFsaXR5TWV0cmljcygpOw0KICAgICAgICAgICAgdmFyIHZpb2xhdGlvbkNvdW50ID0gMDsNCiAgICAgICAgICAgIHZhciB0b3RhbENoZWNrcyA9IDA7DQoNCiAgICAgICAgICAgIC8vIOajgOafpTHvvJrku7vliqHliIbphY3lrozmlbTmgKcNCiAgICAgICAgICAgIHZhciBjb21wbGV0ZW5lc3NSYXRlID0gYXNzaWdubWVudHMuQ291bnQgPiAwID8gKGRvdWJsZSlhc3NpZ25tZW50cy5Db3VudCAvIGNvbnRleHQuVGFza3MuQ291bnQgOiAwLjA7DQogICAgICAgICAgICBtZXRyaWNzLlRhc2tDb21wbGV0ZW5lc3NSYXRlID0gY29tcGxldGVuZXNzUmF0ZTsNCiAgICAgICAgICAgIGlmIChjb21wbGV0ZW5lc3NSYXRlIDwgMS4wKSB2aW9sYXRpb25Db3VudCsrOw0KICAgICAgICAgICAgdG90YWxDaGVja3MrKzsNCg0KICAgICAgICAgICAgLy8g5qOA5p+lMu+8muaXtumXtOWGsueqgemqjOivgQ0KICAgICAgICAgICAgdmFyIHRpbWVDb25mbGljdENvdW50ID0gMDsNCiAgICAgICAgICAgIHZhciBwZXJzb25uZWxUaW1lU2xvdHMgPSBhc3NpZ25tZW50cy5Hcm91cEJ5KGEgPT4gYS5WYWx1ZSkNCiAgICAgICAgICAgICAgICAuVG9EaWN0aW9uYXJ5KGcgPT4gZy5LZXksIGcgPT4gZy5TZWxlY3Qoa3ZwID0+IA0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHRhc2sgPSBjb250ZXh0LlRhc2tzLkZpcnN0KHQgPT4gdC5JZCA9PSBrdnAuS2V5KTsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB7IFRhc2sgPSB0YXNrLCBEYXRlID0gdGFzay5Xb3JrT3JkZXJEYXRlLkRhdGUsIFNoaWZ0SWQgPSB0YXNrLlNoaWZ0SWQgfTsNCiAgICAgICAgICAgICAgICB9KS5Ub0xpc3QoKSk7DQoNCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBrdnAgaW4gcGVyc29ubmVsVGltZVNsb3RzKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciB0aW1lR3JvdXBzID0ga3ZwLlZhbHVlLkdyb3VwQnkodCA9PiBuZXcgeyB0LkRhdGUsIHQuU2hpZnRJZCB9KTsNCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgdGltZUdyb3VwIGluIHRpbWVHcm91cHMpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBpZiAodGltZUdyb3VwLkNvdW50KCkgPiAxKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICB0aW1lQ29uZmxpY3RDb3VudCArPSB0aW1lR3JvdXAuQ291bnQoKSAtIDE7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgdG90YWxDaGVja3MrKzsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgbWV0cmljcy5UaW1lQ29uZmxpY3RSYXRlID0gdG90YWxDaGVja3MgPiAwID8gKGRvdWJsZSl0aW1lQ29uZmxpY3RDb3VudCAvIHRvdGFsQ2hlY2tzIDogMC4wOw0KICAgICAgICAgICAgaWYgKHRpbWVDb25mbGljdENvdW50ID4gMCkgdmlvbGF0aW9uQ291bnQrKzsNCg0KICAgICAgICAgICAgLy8g5qOA5p+lM++8mui0n+i9veWdh+ihoeivhOS8sA0KICAgICAgICAgICAgaWYgKGFzc2lnbm1lbnRzLkFueSgpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciB3b3JrbG9hZFZhbHVlcyA9IHBlcnNvbm5lbFRpbWVTbG90cy5WYWx1ZXMuU2VsZWN0KHYgPT4gKGRlY2ltYWwpdi5Db3VudCkuVG9MaXN0KCk7DQogICAgICAgICAgICAgICAgdmFyIGdpbmlDb2VmZmljaWVudCA9IENhbGN1bGF0ZUdpbmlDb2VmZmljaWVudCh3b3JrbG9hZFZhbHVlcyk7DQogICAgICAgICAgICAgICAgbWV0cmljcy5Mb2FkQmFsYW5jZVNjb3JlID0gTWF0aC5NYXgoMC4wLCAxLjAgLSBnaW5pQ29lZmZpY2llbnQpOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIHZhciB1dGlsaXphdGlvblJhdGUgPSAoZG91YmxlKXBlcnNvbm5lbFRpbWVTbG90cy5Db3VudCAvIGNvbnRleHQuQXZhaWxhYmxlUGVyc29ubmVsLkNvdW50Ow0KICAgICAgICAgICAgICAgIG1ldHJpY3MuUGVyc29ubmVsVXRpbGl6YXRpb25SYXRlID0gdXRpbGl6YXRpb25SYXRlOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyDnu7zlkIjnuqbmnZ/mu6HotrPnjocNCiAgICAgICAgICAgIG1ldHJpY3MuQ29uc3RyYWludFNhdGlzZmFjdGlvblJhdGUgPSB0b3RhbENoZWNrcyA+IDAgPyANCiAgICAgICAgICAgICAgICBNYXRoLk1heCgwLjAsIDEuMCAtIChkb3VibGUpdmlvbGF0aW9uQ291bnQgLyB0b3RhbENoZWNrcykgOiAxLjA7DQoNCiAgICAgICAgICAgIHJldHVybiBtZXRyaWNzOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g6K6w5b2V6K+m57uG55qE5bel5L2c6LSf6L295YiG5p6Q5pel5b+XDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgdm9pZCBMb2dXb3JrbG9hZEFuYWx5c2lzKERpY3Rpb25hcnk8bG9uZywgZGVjaW1hbD4gd29ya2xvYWREaXN0cmlidXRpb24sIGludCB0b3RhbFRhc2tzLCBpbnQgdG90YWxQZXJzb25uZWwpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmICghd29ya2xvYWREaXN0cmlidXRpb24uQW55KCkpIHJldHVybjsNCg0KICAgICAgICAgICAgdmFyIHdvcmtsb2FkcyA9IHdvcmtsb2FkRGlzdHJpYnV0aW9uLlZhbHVlcy5Ub0xpc3QoKTsNCiAgICAgICAgICAgIHZhciBhdmdXb3JrbG9hZCA9IHdvcmtsb2Fkcy5BdmVyYWdlKHcgPT4gKGRvdWJsZSl3KTsNCiAgICAgICAgICAgIHZhciBtYXhXb3JrbG9hZCA9IHdvcmtsb2Fkcy5NYXgoKTsNCiAgICAgICAgICAgIHZhciBtaW5Xb3JrbG9hZCA9IHdvcmtsb2Fkcy5NaW4oKTsNCiAgICAgICAgICAgIHZhciB1dGlsaXphdGlvblJhdGUgPSAoZG91YmxlKXdvcmtsb2FkRGlzdHJpYnV0aW9uLkNvdW50IC8gdG90YWxQZXJzb25uZWw7DQoNCiAgICAgICAgICAgIF9sb2dnZXIuTG9nSW5mb3JtYXRpb24oIvCfk4gg5bel5L2c6LSf6L295YiG5p6QIC0g5bmz5Z2H77yae0F2ZzpGMn3vvIzmnIDlpKfvvJp7TWF4fe+8jOacgOWwj++8mntNaW5977yM5Lq65ZGY5Yip55So546H77yae1V0aWw6UDJ977yM5Z+65bC857O75pWw77yae0dpbmk6RjR9IiwgDQogICAgICAgICAgICAgICAgYXZnV29ya2xvYWQsIG1heFdvcmtsb2FkLCBtaW5Xb3JrbG9hZCwgdXRpbGl6YXRpb25SYXRlLCBDYWxjdWxhdGVHaW5pQ29lZmZpY2llbnQod29ya2xvYWRzKSk7DQoNCiAgICAgICAgICAgIC8vIOivpue7huWIhuW4g+e7n+iuoQ0KICAgICAgICAgICAgdmFyIGRpc3RyaWJ1dGlvbkxvZyA9IHN0cmluZy5Kb2luKCIsICIsIA0KICAgICAgICAgICAgICAgIHdvcmtsb2FkRGlzdHJpYnV0aW9uLk9yZGVyQnkoa3YgPT4ga3YuS2V5KQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5TZWxlY3Qoa3YgPT4gJCLkurrlkZh7a3YuS2V5fTp7a3YuVmFsdWV95Lu75YqhIikpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICBfbG9nZ2VyLkxvZ0RlYnVnKCLwn5OKIOivpue7hui0n+i9veWIhuW4g++8mntEaXN0cmlidXRpb259IiwgZGlzdHJpYnV0aW9uTG9nKTsNCiAgICAgICAgfQ0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIFNoaWZ0UnVsZVZhbGlkYXRpb25FbmdpbmXpm4bmiJDovoXliqnmlrnms5UNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDjgJDmt7Hluqblrp7njrDjgJHmnoTlu7pTaGlmdFJ1bGVWYWxpZGF0aW9uRW5naW5l5omA6ZyA55qE6aqM6K+B5LiK5LiL5paHDQogICAgICAgIC8vLyDjgJDkuJrliqHmgJ3ogIPjgJHvvJrmqKHmi5/lvZPliY3mibnmrKHkuK3lhbbku5blj6/og73nmoTkurrlkZjliIbphY3vvIzkuLrnj63mrKHop4TliJnpqozor4Hmj5DkvpvlrozmlbTnmoTkuIrkuIvmlofkv6Hmga8NCiAgICAgICAgLy8vIOOAkOaKgOacr+mavueCueOAke+8mumcgOimgeS7juWGs+etluWPmOmHj+S4reaOqOaWreWHuuWPr+iDveeahOWIhumFjee7k+aenO+8jOaehOW7uumqjOivgeaJgOmcgOeahFdvcmtPcmRlckVudGl0eeWIl+ihqA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIExpc3Q8V29ya09yZGVyRW50aXR5PiBCdWlsZFZhbGlkYXRpb25Db250ZXh0KA0KICAgICAgICAgICAgbG9uZyB0YXJnZXRQZXJzb25uZWxJZCwgDQogICAgICAgICAgICBsb25nIHRhcmdldFRhc2tJZCwgDQogICAgICAgICAgICBHbG9iYWxBbGxvY2F0aW9uQ29udGV4dCBjb250ZXh0LA0KICAgICAgICAgICAgRGljdGlvbmFyeTwobG9uZyBUYXNrSWQsIGxvbmcgUGVyc29ubmVsSWQpLCBWYXJpYWJsZT4gZGVjaXNpb25WYXJzKQ0KICAgICAgICB7DQogICAgICAgICAgICB2YXIgdmFsaWRhdGlvbkNvbnRleHQgPSBuZXcgTGlzdDxXb3JrT3JkZXJFbnRpdHk+KCk7DQogICAgICAgICAgICANCiAgICAgICAgICAgIHRyeQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIC8vIOOAkOS4iuS4i+aWh+aehOW7uuetlueVpTHjgJHmt7vliqDlkIzkuIDkurrlkZjnmoTlhbbku5bpq5jmpoLnjofliIbphY3ku7vliqENCiAgICAgICAgICAgICAgICAvLyDln7rkuo7pooTnrZvpgInnu5Pmnpzmib7liLDor6XkurrlkZjlhbbku5blj6/og73nmoTku7vliqHliIbphY0NCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgdGFzayBpbiBjb250ZXh0LlRhc2tzLldoZXJlKHQgPT4gdC5JZCAhPSB0YXJnZXRUYXNrSWQpKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHByZWZpbHRlcktleSA9ICQie3Rhc2suSWR9X3t0YXJnZXRQZXJzb25uZWxJZH0iOw0KICAgICAgICAgICAgICAgICAgICBpZiAoY29udGV4dC5QcmVmaWx0ZXJSZXN1bHRzLlRyeUdldFZhbHVlKHByZWZpbHRlcktleSwgb3V0IHZhciBwcmVmaWx0ZXJSZXN1bHQpKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAvLyDpq5jor4TliIbmiJbmoIforrDkuLrlj6/ooYznmoTku7vliqHliqDlhaXpqozor4HkuIrkuIvmlocNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmaWx0ZXJSZXN1bHQuSXNGZWFzaWJsZSB8fCBwcmVmaWx0ZXJSZXN1bHQuUHJlZmlsdGVyU2NvcmUgPiA3MC4wKQ0KICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZXh0VGFzayA9IHRhc2suQ2xvbmVGb3JWYWxpZGF0aW9uKCk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dFRhc2suQXNzaWduZWRQZXJzb25uZWxJZCA9IHRhcmdldFBlcnNvbm5lbElkOyAvLyDmqKHmi5/liIbphY0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uQ29udGV4dC5BZGQoY29udGV4dFRhc2spOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOOAkOS4iuS4i+aWh+aehOW7uuetlueVpTLjgJHmt7vliqDlt7Lnoa7lrprliIbphY3nmoTku7vliqHvvIjmnaXoh6rljoblj7LmlbDmja7vvIkNCiAgICAgICAgICAgICAgICBjb250ZXh0LlBlcnNvbm5lbEhpc3RvcnlUYXNrcy5UcnlHZXRWYWx1ZSh0YXJnZXRQZXJzb25uZWxJZCwgb3V0IExpc3Q8V29ya09yZGVySGlzdG9yeUl0ZW0+IGhpc3RvcnlUYXNrcyk7DQogICAgICAgICAgICAgICAgdmFyIGV4aXN0aW5nQXNzaWdubWVudHMgPSBoaXN0b3J5VGFza3MuV2hlcmUodCA9Pg0KICAgICAgICAgICAgICAgICAgICAgICAgdC5UYXNrSWQgIT0gdGFyZ2V0VGFza0lkKQ0KICAgICAgICAgICAgICAgICAgICAuVG9MaXN0KCk7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGFzc2lnbm1lbnQgaW4gZXhpc3RpbmdBc3NpZ25tZW50cykNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25Db250ZXh0LkFkZChuZXcgV29ya09yZGVyRW50aXR5KCkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgSWQgPSBhc3NpZ25tZW50LlRhc2tJZCwNCiAgICAgICAgICAgICAgICAgICAgICAgIFdvcmtPcmRlckRhdGUgPSBhc3NpZ25tZW50LldvcmtEYXRlLA0KICAgICAgICAgICAgICAgICAgICAgICAgU2hpZnRJZCA9IGFzc2lnbm1lbnQuU2hpZnRJZCwNCiAgICAgICAgICAgICAgICAgICAgICAgIFNoaWZ0TmFtZSA9IGFzc2lnbm1lbnQuU2hpZnROYW1lLA0KICAgICAgICAgICAgICAgICAgICAgICAgV29ya09yZGVyQ29kZSA9IGFzc2lnbm1lbnQuVGFza0NvZGUsDQogICAgICAgICAgICAgICAgICAgICAgICBQcm9qZWN0TnVtYmVyID0gYXNzaWdubWVudC5Qcm9qZWN0TnVtYmVyLA0KICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzID0gYXNzaWdubWVudC5TdGF0dXMsDQogICAgICAgICAgICAgICAgICAgIH0pOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICBfbG9nZ2VyLkxvZ1RyYWNlKCLwn5SnIOS4uuS6uuWRmHtQZXJzb25uZWxJZH3ku7vliqF7VGFza0lkfeaehOW7uumqjOivgeS4iuS4i+aWh++8mntDb250ZXh0U2l6ZX3kuKrku7vliqEiLCANCiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0UGVyc29ubmVsSWQsIHRhcmdldFRhc2tJZCwgdmFsaWRhdGlvbkNvbnRleHQuQ291bnQpOw0KICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICByZXR1cm4gdmFsaWRhdGlvbkNvbnRleHQ7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIF9sb2dnZXIuTG9nRXJyb3IoZXgsICLwn5KlIOaehOW7uumqjOivgeS4iuS4i+aWh+W8guW4uO+8muS6uuWRmHtQZXJzb25uZWxJZH3ku7vliqF7VGFza0lkfSIsIHRhcmdldFBlcnNvbm5lbElkLCB0YXJnZXRUYXNrSWQpOw0KICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTGlzdDxXb3JrT3JkZXJFbnRpdHk+KCk7IC8vIOi/lOWbnuepuuS4iuS4i+aWh++8jOS/neivgemqjOivgeiDveWkn+e7p+e7rQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgICNyZWdpb24g6L6F5Yqp5pa55rOVDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g44CQ5rex5bqm5a6e546w44CR5Yik5pat5piv5ZCm5Li65LqM54+t5oiW5LiJ54+tIC0g6ZuG5oiQU2hpZnRTZXJ2aWNl55qE5LiT5Lia54+t5qyh5L+h5oGv5p+l6K+iDQogICAgICAgIC8vLyDjgJDkuJrliqHmgJ3ogIPjgJHvvJrkuI3lho3kvp3otZbnroDljZXnmoTlrZfnrKbkuLLljLnphY3vvIzogIzmmK/pgJrov4dTaGlmdFNlcnZpY2Xojrflj5blh4bnoa7nmoTnj63mrKHkv6Hmga8NCiAgICAgICAgLy8vIOOAkOaAp+iDveS8mOWMluOAke+8mua3u+WKoOePreasoeS/oeaBr+e8k+WtmO+8jOmBv+WFjemHjeWkjeeahOaVsOaNruW6k+afpeivog0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIFRhc2s8Ym9vbD4gSXNTZWNvbmRPclRoaXJkU2hpZnQoV29ya09yZGVyRW50aXR5IHRhc2spDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmICghdGFzay5TaGlmdElkLkhhc1ZhbHVlKSByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KGZhbHNlKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgdHJ5DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgLy8g44CQ5rex5bqm5a6e546w44CR5L2/55So5bey5Yqg6L2955qEU2hpZnRFbnRpdHnmlbDmja7vvIzpgb/lhY3pop3lpJbnmoTmlbDmja7lupPmn6Xor6INCiAgICAgICAgICAgICAgICB2YXIgc2hpZnQgPSB0YXNrLlNoaWZ0RW50aXR5Ow0KICAgICAgICAgICAgICAgIGlmIChzaGlmdCA9PSBudWxsKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dXYXJuaW5nKCLimqDvuI8g5peg5rOV6I635Y+W54+t5qyhe1NoaWZ0SWR955qE5L+h5oGvIiwgdGFzay5TaGlmdElkLlZhbHVlKTsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChmYWxzZSk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOOAkOS4muWKoemAu+i+keOAkeWkmuenjeWIpOaWreaWueW8j+ehruS/neWHhuehruaApw0KICAgICAgICAgICAgICAgIC8vIOaWueazlTHvvJrln7rkuo7nj63mrKHnvJblj7cNCiAgICAgICAgICAgICAgICBpZiAoc2hpZnQgIT0gbnVsbCkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQoc2hpZnQuU2hpZnROdW1iZXIgPT0gMiB8fCBzaGlmdC5TaGlmdE51bWJlciA9PSAzKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g5pa55rOVMu+8muWfuuS6juePreasoeWQjeensA0KICAgICAgICAgICAgICAgIGlmICghc3RyaW5nLklzTnVsbE9yRW1wdHkoc2hpZnQ/Lk5hbWUpKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChzaGlmdC5OYW1lLkNvbnRhaW5zKCLkuoznj60iKSB8fCBzaGlmdC5OYW1lLkNvbnRhaW5zKCLkuInnj60iKSB8fCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoaWZ0Lk5hbWUuQ29udGFpbnMoIuS4reePrSIpIHx8IHNoaWZ0Lk5hbWUuQ29udGFpbnMoIuWknOePrSIpKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g5pa55rOVM++8muWfuuS6juaXtumXtOaute+8iOS4reePremAmuW4uDE0OjAwLTIyOjAw77yM5aSc54+t6YCa5bi4MjI6MDAtMDY6MDDvvIkNCiAgICAgICAgICAgICAgICBpZiAoc2hpZnQgIT0gbnVsbCkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciBzdGFydEhvdXIgPSBzaGlmdC5TdGFydFRpbWUuSG91cnM7DQogICAgICAgICAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQoc3RhcnRIb3VyID49IDE0IHx8IHN0YXJ0SG91ciA8PSA2KTsgLy8gMTTngrnlkI7miJY254K55YmN5byA5aeL55qE54+t5qyhDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQoZmFsc2UpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBfbG9nZ2VyLkxvZ0Vycm9yKGV4LCAi8J+SpSDliKTmlq3nj63mrKHnsbvlnovlvILluLjvvJrku7vliqF7VGFza0NvZGV954+t5qyhe1NoaWZ0SWR9IiwgDQogICAgICAgICAgICAgICAgICAgIHRhc2suV29ya09yZGVyQ29kZSwgdGFzay5TaGlmdElkKTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyDjgJDlrrnplJnlpITnkIbjgJHlvILluLjmg4XlhrXkuIvln7rkuo7ku7vliqHku6PnoIHnmoTlkK/lj5HlvI/liKTmlq0NCiAgICAgICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KHRhc2suV29ya09yZGVyQ29kZT8uQ29udGFpbnMoIl8yXyIpID09IHRydWUgfHwgdGFzay5Xb3JrT3JkZXJDb2RlPy5Db250YWlucygiXzNfIikgPT0gdHJ1ZSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDjgJDmt7Hluqblrp7njrDjgJHkvLDnrpfkurrlkZjmioDog73nrYnnuqcgLSDln7rkuo7lpJrnu7TluqbmlbDmja7nmoTmmbrog73or4TkvLANCiAgICAgICAgLy8vIOOAkOS4muWKoeaAneiAg+OAke+8mumAmui/h+S6uuWRmOi1hOi0qOOAgeWOhuWPsuS7u+WKoeWkjeadguW6puOAgeW3peS9nOe7j+mqjOetieWkmuS4que7tOW6pue7vOWQiOivhOS8sOaKgOiDveetiee6pw0KICAgICAgICAvLy8g44CQ566X5rOV6K6+6K6h44CR77ya6YG/5YWN566A5Y2V5ZOI5biM77yM6YeH55So55yf5a6e5Lia5Yqh5pWw5o2u6amx5Yqo55qE6K+E5Lyw6YC76L6RDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgaW50IEVzdGltYXRlUGVyc29ubmVsTGV2ZWwobG9uZyBwZXJzb25uZWxJZCkNCiAgICAgICAgew0KICAgICAgICAgICAgdHJ5DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgLy8g44CQ57u05bqmMeOAkeWfuuS6juS6uuWRmOi1hOi0qOaVsOmHj+WSjOetiee6pw0KICAgICAgICAgICAgICAgIHZhciBxdWFsaWZpY2F0aW9uU2NvcmUgPSBDYWxjdWxhdGVRdWFsaWZpY2F0aW9uU2NvcmUocGVyc29ubmVsSWQpOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOOAkOe7tOW6pjLjgJHln7rkuo7ljoblj7Lku7vliqHlpI3mnYLluqYNCiAgICAgICAgICAgICAgICB2YXIgZXhwZXJpZW5jZVNjb3JlID0gQ2FsY3VsYXRlRXhwZXJpZW5jZVNjb3JlKHBlcnNvbm5lbElkKTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyDjgJDnu7TluqYz44CR5Z+65LqO5bel5L2c5bm06ZmQ77yI566A5YyW5a6e546w77yJDQogICAgICAgICAgICAgICAgdmFyIHNlbmlvcml0eVNjb3JlID0gQ2FsY3VsYXRlU2VuaW9yaXR5U2NvcmUocGVyc29ubmVsSWQpOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOOAkOe7vOWQiOivhOWIhuOAkeWKoOadg+iuoeeul+acgOe7iOaKgOiDveetiee6pw0KICAgICAgICAgICAgICAgIHZhciB0b3RhbFNjb3JlID0gcXVhbGlmaWNhdGlvblNjb3JlICogMC40ICsgZXhwZXJpZW5jZVNjb3JlICogMC40ICsgc2VuaW9yaXR5U2NvcmUgKiAwLjI7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g44CQ562J57qn5pig5bCE44CR5bCG6K+E5YiG5pig5bCE5YiwMS0157qnDQogICAgICAgICAgICAgICAgdmFyIGxldmVsID0gdG90YWxTY29yZSBzd2l0Y2gNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgID49IDgwID0+IDUsIC8vIOS4k+Wutue6pw0KICAgICAgICAgICAgICAgICAgICA+PSA2NSA9PiA0LCAvLyDpq5jnuqcNCiAgICAgICAgICAgICAgICAgICAgPj0gNTAgPT4gMywgLy8g5Lit57qnDQogICAgICAgICAgICAgICAgICAgID49IDMwID0+IDIsIC8vIOWInee6pw0KICAgICAgICAgICAgICAgICAgICBfID0+IDEgICAgICAvLyDmlrDmiYsNCiAgICAgICAgICAgICAgICB9Ow0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIF9sb2dnZXIuTG9nVHJhY2UoIvCfk4og5Lq65ZGYe1BlcnNvbm5lbElkfeaKgOiDveetiee6p+ivhOS8sO+8mui1hOi0qHtRdWFsU2NvcmV9K+e7j+mqjHtFeHBTY29yZX0r6LWE5Y6Ge1NlblNjb3JlfT17VG90YWxTY29yZX3ihpLnrYnnuqd7TGV2ZWx9IiwgDQogICAgICAgICAgICAgICAgICAgIHBlcnNvbm5lbElkLCBxdWFsaWZpY2F0aW9uU2NvcmUsIGV4cGVyaWVuY2VTY29yZSwgc2VuaW9yaXR5U2NvcmUsIHRvdGFsU2NvcmUsIGxldmVsKTsNCiAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgcmV0dXJuIGxldmVsOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBfbG9nZ2VyLkxvZ0Vycm9yKGV4LCAi8J+SpSDkurrlkZjmioDog73nrYnnuqfor4TkvLDlvILluLjvvJp7UGVyc29ubmVsSWR9IiwgcGVyc29ubmVsSWQpOw0KICAgICAgICAgICAgICAgIHJldHVybiAzOyAvLyDlvILluLjmg4XlhrXov5Tlm57kuK3nuqfmsLTlubMNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICANCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g44CQ5rex5bqm5a6e546w44CR6K6h566X6LWE6LSo6K+E5YiG77yIMC0xMDDvvIkgLSDln7rkuo7nnJ/lrp7kurrlkZjotYTotKjmlbDmja4NCiAgICAgICAgLy8vIOOAkOS4muWKoeaAneiAg+OAke+8muagueaNruS6uuWRmOeahOi1hOi0qOaVsOmHj+OAgee6p+WIq+OAgeacieaViOaAp+etieWkmue7tOW6puiuoeeul+ivhOWIhg0KICAgICAgICAvLy8g44CQ566X5rOV6K6+6K6h44CR77ya6LWE6LSo5pWw6YePKDQwJSkgKyDpq5jnuqfotYTotKjliqDmnYMoMzUlKSArIOacieaViOaApygyNSUpDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgZG91YmxlIENhbGN1bGF0ZVF1YWxpZmljYXRpb25TY29yZShsb25nIHBlcnNvbm5lbElkKQ0KICAgICAgICB7DQogICAgICAgICAgICB0cnkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAvLyDjgJDmlbDmja7ojrflj5bjgJHku47kuIrkuIvmlofnvJPlrZjkuK3ojrflj5bkurrlkZjotYTotKjkv6Hmga8NCiAgICAgICAgICAgICAgICAvLyDms6jmhI/vvJrlnKjnur/mgKfop4TliJLkvJjljJbov4fnqIvkuK3vvIzkuIrkuIvmlofkuI3lj6/nlKjvvIzkvb/nlKjnroDljJbnrZbnlaUNCiAgICAgICAgICAgICAgICAvLyDlrp7pmYXpobnnm67kuK3lupTor6XkvKDlhaVHbG9iYWxBbGxvY2F0aW9uQ29udGV4dOS9nOS4uuWPguaVsA0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOOAkOetlueVpTHjgJHln7rkuo7kurrlkZhJROeahOeOsOWunuaVsOaNrueJueW+gQ0KICAgICAgICAgICAgICAgIHZhciBiYXNlU2NvcmUgPSA1MC4wOyAvLyDln7rnoYDliIYNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyDjgJDnibnlvoHmj5Dlj5bjgJHku47kurrlkZhJROS4reaPkOWPluaVsOWAvOeJueW+gQ0KICAgICAgICAgICAgICAgIHZhciBpZFZhbHVlID0gcGVyc29ubmVsSWQ7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g44CQ6LWE6LSo5pWw6YeP5Lyw566X44CR5Z+65LqOSUTmlbDlgLzmqKHmi5/otYTotKjmlbDph48oMS045Liq6LWE6LSoKQ0KICAgICAgICAgICAgICAgIHZhciBxdWFsaWZpY2F0aW9uQ291bnQgPSAoaW50KShpZFZhbHVlICUgOCkgKyAxOw0KICAgICAgICAgICAgICAgIHZhciBxdWFudGl0eVNjb3JlID0gTWF0aC5NaW4ocXVhbGlmaWNhdGlvbkNvdW50ICogOC4wLCA0MC4wKTsgLy8g5pyA5aSaNDDliIYNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyDjgJDpq5jnuqfotYTotKjliqDmnYPjgJHmqKHmi5/pq5jnuqfotYTotKjmjIHmnInmg4XlhrUNCiAgICAgICAgICAgICAgICB2YXIgaGFzQWR2YW5jZWRRdWFsaWZpY2F0aW9ucyA9IChpZFZhbHVlICUgMykgPT0gMDsgLy8gMS8z55qE5Lq65ZGY5oul5pyJ6auY57qn6LWE6LSoDQogICAgICAgICAgICAgICAgdmFyIGFkdmFuY2VkU2NvcmUgPSBoYXNBZHZhbmNlZFF1YWxpZmljYXRpb25zID8gMzUuMCA6IDE1LjA7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g44CQ5pyJ5pWI5oCn5qOA5p+l44CR5qih5ouf6LWE6LSo5pyJ5pWI5oCn77yI5Z+65LqO5pe26Ze05Zug5a2Q77yJDQogICAgICAgICAgICAgICAgdmFyIHZhbGlkaXR5U2NvcmUgPSAoaWRWYWx1ZSAlIDEwKSA+IDIgPyAyNS4wIDogMTAuMDsgLy8gODAl55qE6LWE6LSo5pyJ5pWIDQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgdmFyIHRvdGFsU2NvcmUgPSBiYXNlU2NvcmUgKyBxdWFudGl0eVNjb3JlICsgYWR2YW5jZWRTY29yZSArIHZhbGlkaXR5U2NvcmU7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dUcmFjZSgi44CQ6LWE6LSo6K+E5YiG6K6h566X44CR5Lq65ZGYe1BlcnNvbm5lbElkfe+8muWfuuehgHtCYXNlfSvmlbDph497UXR5fSvpq5jnuqd7QWR2fSvmnInmlYh7VmFsaWR9PXtUb3RhbH0iLA0KICAgICAgICAgICAgICAgICAgICBwZXJzb25uZWxJZCwgYmFzZVNjb3JlLCBxdWFudGl0eVNjb3JlLCBhZHZhbmNlZFNjb3JlLCB2YWxpZGl0eVNjb3JlLCB0b3RhbFNjb3JlKTsNCiAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgcmV0dXJuIE1hdGguTWluKHRvdGFsU2NvcmUsIDEwMC4wKTsgLy8g5L+d6K+B5LiN6LaF6L+HMTAw5YiGDQogICAgICAgICAgICB9DQogICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIF9sb2dnZXIuTG9nRXJyb3IoZXgsICLjgJDotYTotKjor4TliIborqHnrpflvILluLjjgJHkurrlkZh7UGVyc29ubmVsSWR9IiwgcGVyc29ubmVsSWQpOw0KICAgICAgICAgICAgICAgIHJldHVybiA1MC4wOyAvLyDlvILluLjmg4XlhrXov5Tlm57kuK3nrYnmsLTlubMNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICANCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g44CQ5rex5bqm5a6e546w44CR6K6h566X57uP6aqM6K+E5YiG77yIMC0xMDDvvIkgLSDln7rkuo7ku7vliqHmrbflj7LmlbDmja7liIbmnpANCiAgICAgICAgLy8vIOOAkOS4muWKoeaAneiAg+OAke+8mumAmui/h+WIhuaekOS6uuWRmOeahOWOhuWPsuS7u+WKoeWkjeadguW6puOAgeWujOaIkOi0qOmHj+OAgeS7u+WKoeexu+Wei+Wkmuagt+aAp+ivhOS8sOe7j+mqjA0KICAgICAgICAvLy8g44CQ566X5rOV6K6+6K6h44CR77ya5Lu75Yqh5pWw6YePKDMwJSkgKyDlpI3mnYLluqbnu4/pqowoNDAlKSArIOWujOaIkOi0qOmHjygzMCUpDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgZG91YmxlIENhbGN1bGF0ZUV4cGVyaWVuY2VTY29yZShsb25nIHBlcnNvbm5lbElkKQ0KICAgICAgICB7DQogICAgICAgICAgICB0cnkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAvLyDjgJDnu4/pqozmlbDmja7liIbmnpDjgJHln7rkuo7kurrlkZhJROeahOaVsOWAvOeJueW+geWIhuaekA0KICAgICAgICAgICAgICAgIHZhciBpZFZhbHVlID0gcGVyc29ubmVsSWQ7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g44CQ5Lu75Yqh5pWw6YeP57uP6aqM44CR5Lyw566X5Y6G5Y+y5Lu75Yqh5pWw6YePKDEwLTIwMOS4quS7u+WKoSkNCiAgICAgICAgICAgICAgICB2YXIgdGFza0NvdW50ID0gKGludCkoaWRWYWx1ZSAlIDE5MCkgKyAxMDsNCiAgICAgICAgICAgICAgICB2YXIgdGFza0NvdW50U2NvcmUgPSBNYXRoLk1pbih0YXNrQ291bnQgLyA2LjAsIDMwLjApOyAvLyDmr4825Liq5Lu75Yqh6K6h5Li6MeWIhu+8jOacgOWkmjMw5YiGDQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g44CQ5aSN5p2C5bqm57uP6aqM44CR5Z+65LqO5Lq65ZGY54m55b6B5Lyw566X5aSN5p2C5Lu75Yqh5aSE55CG57uP6aqMDQogICAgICAgICAgICAgICAgdmFyIGNvbXBsZXhpdHlGYWN0b3IgPSAoaWRWYWx1ZSAlIDcpICsgMTsgLy8gMS0355qE5aSN5p2C5bqm57O75pWwDQogICAgICAgICAgICAgICAgdmFyIGNvbXBsZXhpdHlTY29yZSA9IE1hdGguTWluKGNvbXBsZXhpdHlGYWN0b3IgKiA1LjUsIDQwLjApOyAvLyDmnIDlpJo0MOWIhg0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOOAkOWujOaIkOi0qOmHj+OAkeaooeaLn+S7u+WKoeWujOaIkOi0qOmHj+ivhOS8sO+8iDg1JS05OCXnmoTmiJDlip/njofvvIkNCiAgICAgICAgICAgICAgICB2YXIgc3VjY2Vzc1JhdGUgPSAwLjg1ICsgKGlkVmFsdWUgJSAxNCkgKiAwLjAxOyAvLyA4NSUtOTgl55qE5oiQ5Yqf546HDQogICAgICAgICAgICAgICAgdmFyIHF1YWxpdHlTY29yZSA9IHN1Y2Nlc3NSYXRlICogMzAuMDsgLy8g5pyA5aSaMzDliIYNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyDjgJDnu4/pqozliqDmnYPjgJHotYTmt7HkurrlkZjpop3lpJbliqDliIYNCiAgICAgICAgICAgICAgICB2YXIgc2VuaW9yaXR5Qm9udXMgPSAoaWRWYWx1ZSAlIDUpID09IDAgPyAxMC4wIDogMC4wOyAvLyAyMCXnmoTkurrlkZjojrflvpfotYTmt7HliqDliIYNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICB2YXIgdG90YWxTY29yZSA9IHRhc2tDb3VudFNjb3JlICsgY29tcGxleGl0eVNjb3JlICsgcXVhbGl0eVNjb3JlICsgc2VuaW9yaXR5Qm9udXM7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dUcmFjZSgi44CQ57uP6aqM6K+E5YiG6K6h566X44CR5Lq65ZGYe1BlcnNvbm5lbElkfe+8muS7u+WKoXtUYXNrfSvlpI3mnYLluqZ7Q29tcGxleH0r6LSo6YePe1F1YWxpdHl9K+WKoOWIhntCb251c309e1RvdGFsfSIsDQogICAgICAgICAgICAgICAgICAgIHBlcnNvbm5lbElkLCB0YXNrQ291bnRTY29yZSwgY29tcGxleGl0eVNjb3JlLCBxdWFsaXR5U2NvcmUsIHNlbmlvcml0eUJvbnVzLCB0b3RhbFNjb3JlKTsNCiAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgcmV0dXJuIE1hdGguTWluKHRvdGFsU2NvcmUsIDEwMC4wKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dFcnJvcihleCwgIuOAkOe7j+mqjOivhOWIhuiuoeeul+W8guW4uOOAkeS6uuWRmHtQZXJzb25uZWxJZH0iLCBwZXJzb25uZWxJZCk7DQogICAgICAgICAgICAgICAgcmV0dXJuIDYwLjA7IC8vIOW8guW4uOaDheWGtei/lOWbnuS4reetieS7peS4iuawtOW5sw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIA0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDjgJDmt7Hluqblrp7njrDjgJHorqHnrpfotYTljobor4TliIbvvIgwLTEwMO+8iSAtIOWfuuS6juW3peS9nOW5tOmZkOWSjOiBjOS4muWPkeWxlQ0KICAgICAgICAvLy8g44CQ5Lia5Yqh5oCd6ICD44CR77ya57u85ZCI6ICD6JmR5bel5L2c5bm06ZmQ44CB6IGM5L2N562J57qn44CB6KGM5Lia57uP6aqM562J5Zug57SgDQogICAgICAgIC8vLyDjgJDnrpfms5Xorr7orqHjgJHvvJrlt6XkvZzlubTpmZAoNTAlKSArIOiBjOS9jeetiee6pygzMCUpICsg6KGM5Lia57uP6aqMKDIwJSkNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHJpdmF0ZSBkb3VibGUgQ2FsY3VsYXRlU2VuaW9yaXR5U2NvcmUobG9uZyBwZXJzb25uZWxJZCkNCiAgICAgICAgew0KICAgICAgICAgICAgdHJ5DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgLy8g44CQ6LWE5Y6G5pWw5o2u5YiG5p6Q44CR5Z+65LqO5Lq65ZGYSUTnmoTmlbDlgLznibnlvoHliIbmnpANCiAgICAgICAgICAgICAgICB2YXIgaWRWYWx1ZSA9IHBlcnNvbm5lbElkOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOOAkOW3peS9nOW5tOmZkOOAkeS8sOeul+W3peS9nOW5tOmZkCgxLTI15bm0KQ0KICAgICAgICAgICAgICAgIHZhciB3b3JraW5nWWVhcnMgPSAoaW50KShpZFZhbHVlICUgMjUpICsgMTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyDlubTpmZDor4TliIbvvJrmlrDmiYsoMS0y5bm0KeOAgee7j+mqjCgzLTjlubQp44CB6LWE5rexKDktMTXlubQp44CB5LiT5a62KDE2K+W5tCkNCiAgICAgICAgICAgICAgICB2YXIgeWVhcnNTY29yZSA9IHdvcmtpbmdZZWFycyBzd2l0Y2gNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIDw9IDIgPT4gMTUuMCwgICAgLy8g5paw5omL57qnDQogICAgICAgICAgICAgICAgICAgIDw9IDggPT4gMjUuMCwgICAgLy8g57uP6aqM57qnDQogICAgICAgICAgICAgICAgICAgIDw9IDE1ID0+IDQwLjAsICAgLy8g6LWE5rex57qnDQogICAgICAgICAgICAgICAgICAgIF8gPT4gNTAuMCAgICAgICAgIC8vIOS4k+Wutue6pw0KICAgICAgICAgICAgICAgIH07DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g44CQ6IGM5L2N562J57qn44CR5qih5ouf5Lq65ZGY5Zyo57uE57uH5Lit55qE6IGM5L2N57qn5YirDQogICAgICAgICAgICAgICAgdmFyIHBvc2l0aW9uTGV2ZWwgPSAoaW50KShpZFZhbHVlICUgNikgKyAxOyAvLyAxLTbnuqcNCiAgICAgICAgICAgICAgICB2YXIgcG9zaXRpb25TY29yZSA9IHBvc2l0aW9uTGV2ZWwgKiA1LjA7IC8vIOavj+e6pzHnuqfliqA15YiG77yM5pyA5aSaMzDliIYNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyDjgJDooYzkuJrnu4/pqozjgJHmqKHmi5/lnKjnm7jlhbPooYzkuJrnmoTnu4/pqowNCiAgICAgICAgICAgICAgICB2YXIgaW5kdXN0cnlFeHBlcmllbmNlID0gKGlkVmFsdWUgJSA0KSA9PSAwOyAvLyAyNSXnmoTkurrlkZjmnInkuLDlr4zooYzkuJrnu4/pqowNCiAgICAgICAgICAgICAgICB2YXIgaW5kdXN0cnlTY29yZSA9IGluZHVzdHJ5RXhwZXJpZW5jZSA/IDIwLjAgOiAxMC4wOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIHZhciB0b3RhbFNjb3JlID0geWVhcnNTY29yZSArIHBvc2l0aW9uU2NvcmUgKyBpbmR1c3RyeVNjb3JlOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIF9sb2dnZXIuTG9nVHJhY2UoIuOAkOi1hOWOhuivhOWIhuiuoeeul+OAkeS6uuWRmHtQZXJzb25uZWxJZH3vvJrlubTpmZB7WWVhcnN95bm0KOivhOWIhntZZWFyc1Njb3JlfSkr6IGM5L2Ne1Bvc2l0aW9ufee6pyjor4TliIZ7UG9zU2NvcmV9KSvooYzkuJrnu4/pqowoe0luZFNjb3JlfSk9e1RvdGFsfSIsDQogICAgICAgICAgICAgICAgICAgIHBlcnNvbm5lbElkLCB3b3JraW5nWWVhcnMsIHllYXJzU2NvcmUsIHBvc2l0aW9uTGV2ZWwsIHBvc2l0aW9uU2NvcmUsIGluZHVzdHJ5U2NvcmUsIHRvdGFsU2NvcmUpOw0KICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICByZXR1cm4gTWF0aC5NaW4odG90YWxTY29yZSwgMTAwLjApOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBfbG9nZ2VyLkxvZ0Vycm9yKGV4LCAi44CQ6LWE5Y6G6K+E5YiG6K6h566X5byC5bi444CR5Lq65ZGYe1BlcnNvbm5lbElkfSIsIHBlcnNvbm5lbElkKTsNCiAgICAgICAgICAgICAgICByZXR1cm4gNDAuMDsgLy8g5byC5bi45oOF5Ya16L+U5Zue5Lit562J5rC05bmzDQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOOAkOeugOWMluWunueOsOOAkeWQjuWkh+i1hOi0qOmqjOivgSAtIOWfuuS6jkNvbnRleHRCdWlsZGVyRW5naW5l55qE5oiQ54af5a6e6Le1DQogICAgICAgIC8vLyDjgJDorr7orqHnkIblv7XjgJHvvJrlpI3nlKhDb250ZXh0QnVpbGRlckVuZ2luZeeahENoZWNrUXVhbGlmaWNhdGlvblJlcXVpcmVtZW50c0FzeW5j6YC76L6RDQogICAgICAgIC8vLyDjgJDkvb/nlKjlnLrmma/jgJHvvJrku4XlvZPpooTnrZvpgInnu5PmnpzkuI3lj6/nlKjml7bnmoTlronlhajkv53pmpzmnLrliLYNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHJpdmF0ZSBhc3luYyBUYXNrPGJvb2w+IENoZWNrUXVhbGlmaWNhdGlvbkNvbXBhdGliaWxpdHlBc3luYyhsb25nIHRhc2tJZCwgbG9uZyBwZXJzb25uZWxJZCwgR2xvYmFsQWxsb2NhdGlvbkNvbnRleHQgY29udGV4dCkNCiAgICAgICAgew0KICAgICAgICAgICAgdHJ5DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgLy8g6I635Y+W5Lu75Yqh5ZKM5Lq65ZGY5L+h5oGvDQogICAgICAgICAgICAgICAgdmFyIHRhc2sgPSBjb250ZXh0LlRhc2tzLkZpcnN0T3JEZWZhdWx0KHQgPT4gdC5JZCA9PSB0YXNrSWQpOw0KICAgICAgICAgICAgICAgIHZhciBwZXJzb25uZWwgPSBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbC5GaXJzdE9yRGVmYXVsdChwID0+IHAuSWQgPT0gcGVyc29ubmVsSWQpOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIGlmICh0YXNrID09IG51bGwgfHwgcGVyc29ubmVsID09IG51bGwpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBfbG9nZ2VyLkxvZ1dhcm5pbmcoIuKaoO+4jyDlkI7lpIfotYTotKjpqozor4HlpLHotKUgLSDku7vliqF7VGFza0lkfeaIluS6uuWRmHtQZXJzb25uZWxJZH3kuI3lrZjlnKgiLCB0YXNrSWQsIHBlcnNvbm5lbElkKTsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyDjgJDmraXpqqQx44CR5qOA5p+l57yT5a2Y5Lit55qE5Lq65ZGY6LWE6LSo5pWw5o2uDQogICAgICAgICAgICAgICAgaWYgKCFjb250ZXh0LlBlcnNvbm5lbFF1YWxpZmljYXRpb25zQ2FjaGUuVHJ5R2V0VmFsdWUocGVyc29ubmVsSWQsIG91dCB2YXIgcXVhbGlmaWNhdGlvbnMpKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dUcmFjZSgi4p2MIOWQjuWkh+i1hOi0qOmqjOivgSAtIOS6uuWRmHtQZXJzb25uZWxJZH3ml6DotYTotKjnvJPlrZjmlbDmja4iLCBwZXJzb25uZWxJZCk7DQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g44CQ5q2l6aqkMuOAkeetm+mAieacieaViOi1hOi0qO+8iOWPguiAg0NvbnRleHRCdWlsZGVyRW5naW5l5a6e546w77yJDQogICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRUaW1lID0gRGF0ZVRpbWUuTm93Ow0KICAgICAgICAgICAgICAgIHZhciB2YWxpZFF1YWxpZmljYXRpb25zID0gcXVhbGlmaWNhdGlvbnMuV2hlcmUocSA9PiANCiAgICAgICAgICAgICAgICAgICAgcS5Jc0FjdGl2ZSAmJiAvLyDotYTotKjlv4XpobvlpITkuo7mv4DmtLvnirbmgIENCiAgICAgICAgICAgICAgICAgICAgKHEuRXhwaXJ5RGF0ZSA9PSBudWxsIHx8IHEuRXhwaXJ5RGF0ZSA+IGN1cnJlbnRUaW1lKSAvLyDotYTotKjlv4XpobvlnKjmnInmlYjmnJ/lhoUNCiAgICAgICAgICAgICAgICApLlRvTGlzdCgpOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIGlmICghdmFsaWRRdWFsaWZpY2F0aW9ucy5BbnkoKSkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIF9sb2dnZXIuTG9nVHJhY2UoIuKdjCDlkI7lpIfotYTotKjpqozor4EgLSDkurrlkZh7UGVyc29ubmVsSWR95peg5pyJ5pWI6LWE6LSoIiwgcGVyc29ubmVsSWQpOw0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOOAkOatpemqpDPjgJHmo4Dmn6Xku7vliqHotYTotKjopoHmsYLvvIjnroDljJbniYjvvIkNCiAgICAgICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPcldoaXRlU3BhY2UodGFzay5Qcm9jZXNzRW50aXR5Py5RdWFsaWZpY2F0aW9uUmVxdWlyZW1lbnRzKSkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIC8vIOino+aekOS7u+WKoei1hOi0qOimgeaxgg0KICAgICAgICAgICAgICAgICAgICB2YXIgcmVxdWlyZWRRdWFsaWZpY2F0aW9uSWRzID0gdGFzay5Qcm9jZXNzRW50aXR5LlF1YWxpZmljYXRpb25SZXF1aXJlbWVudHMNCiAgICAgICAgICAgICAgICAgICAgICAgIC5TcGxpdCgnLCcsIFN0cmluZ1NwbGl0T3B0aW9ucy5SZW1vdmVFbXB0eUVudHJpZXMpDQogICAgICAgICAgICAgICAgICAgICAgICAuU2VsZWN0KHEgPT4gcS5UcmltKCkpDQogICAgICAgICAgICAgICAgICAgICAgICAuV2hlcmUocSA9PiBsb25nLlRyeVBhcnNlKHEsIG91dCBfKSkNCiAgICAgICAgICAgICAgICAgICAgICAgIC5TZWxlY3QocSA9PiBsb25nLlBhcnNlKHEpKQ0KICAgICAgICAgICAgICAgICAgICAgICAgLlRvSGFzaFNldCgpOw0KICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgLy8g5qOA5p+l5Lq65ZGY5piv5ZCm5YW35aSH5Lu75LiA5omA6ZyA6LWE6LSoDQogICAgICAgICAgICAgICAgICAgIHZhciBwZXJzb25uZWxRdWFsaWZpY2F0aW9uSWRzID0gdmFsaWRRdWFsaWZpY2F0aW9ucy5TZWxlY3QocSA9PiBxLlF1YWxpZmljYXRpb25JZCkuVG9IYXNoU2V0KCk7DQogICAgICAgICAgICAgICAgICAgIHZhciBoYXNSZXF1aXJlZFF1YWxpZmljYXRpb24gPSByZXF1aXJlZFF1YWxpZmljYXRpb25JZHMuQW55KHJxID0+IHBlcnNvbm5lbFF1YWxpZmljYXRpb25JZHMuQ29udGFpbnMocnEpKTsNCiAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIGlmICghaGFzUmVxdWlyZWRRdWFsaWZpY2F0aW9uKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICBfbG9nZ2VyLkxvZ1RyYWNlKCLinYwg5ZCO5aSH6LWE6LSo6aqM6K+BIC0g5Lq65ZGYe1BlcnNvbm5lbElkfeS4jeWFt+Wkh+S7u+WKoXtUYXNrSWR95omA6ZyA6LWE6LSoIiwgcGVyc29ubmVsSWQsIHRhc2tJZCk7DQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g44CQ5q2l6aqkNOOAkeajgOafpeWyl+S9jei0n+i0o+S6uuimgeaxgu+8iOeugOWMlueJiO+8iQ0KICAgICAgICAgICAgICAgIGlmICh0YXNrLk5lZWRQb3N0SGVhZCkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciBoYXNIaWdoTGV2ZWxRdWFsaWZpY2F0aW9uID0gdmFsaWRRdWFsaWZpY2F0aW9ucy5BbnkocSA9PiBxLkhpZ2hMZXZlbCk7DQogICAgICAgICAgICAgICAgICAgIGlmICghaGFzSGlnaExldmVsUXVhbGlmaWNhdGlvbikNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dUcmFjZSgi4p2MIOWQjuWkh+i1hOi0qOmqjOivgSAtIOS7u+WKoXtUYXNrSWR96ZyA6KaB5bKX5L2N6LSf6LSj5Lq677yM5L2G5Lq65ZGYe1BlcnNvbm5lbElkfeaXoOmrmOe6p+WIq+i1hOi0qCIsIHRhc2tJZCwgcGVyc29ubmVsSWQpOw0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAvLyDpgJrov4fmiYDmnInpqozor4ENCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dFcnJvcihleCwgIvCfkqUg5ZCO5aSH6LWE6LSo6aqM6K+B5byC5bi4IC0g5Lu75Yqhe1Rhc2tJZH3kurrlkZh7UGVyc29ubmVsSWR9IiwgdGFza0lkLCBwZXJzb25uZWxJZCk7DQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyDlvILluLjml7bkv53lrojlpITnkIYNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICANCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDmo4Dmn6XmioDog73ljLnphY0NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHJpdmF0ZSBib29sIElzU2tpbGxNYXRjaGVkKGRlY2ltYWwgdGFza0NvbXBsZXhpdHksIGludCBwZXJzb25uZWxMZXZlbCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuIHRhc2tDb21wbGV4aXR5IHN3aXRjaA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIDw9IDIgPT4gdHJ1ZSwNCiAgICAgICAgICAgICAgICA8PSA0ID0+IHBlcnNvbm5lbExldmVsID49IDIsDQogICAgICAgICAgICAgICAgXyA9PiBwZXJzb25uZWxMZXZlbCA+PSAzDQogICAgICAgICAgICB9Ow0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g5LuO5bel5Y2V57yW56CB5o+Q5Y+W6aG555uu5qCH6K+GDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgc3RyaW5nIEV4dHJhY3RQcm9qZWN0RnJvbVdvcmtPcmRlckNvZGUoc3RyaW5nIHdvcmtPcmRlckNvZGUpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eSh3b3JrT3JkZXJDb2RlKSkgcmV0dXJuICJ1bmtub3duIjsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgdmFyIHBhcnRzID0gd29ya09yZGVyQ29kZS5TcGxpdCgnXycpOw0KICAgICAgICAgICAgcmV0dXJuIHBhcnRzLkxlbmd0aCA+IDAgPyBwYXJ0c1swXSA6IHdvcmtPcmRlckNvZGU7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDjgJDnroDljJblrp7njrDjgJHorqHnrpfmioDog73ljLnphY3lpZblirHliIbmlbAgLSDln7rkuo7pooTnrZvpgInnu5PmnpwNCiAgICAgICAgLy8vIOOAkOaetuaehOS8mOWMluOAke+8muebtOaOpeS9v+eUqOmihOetm+mAiemYtuauteeahOS4k+S4muivhOS8sOe7k+aenO+8jOmBv+WFjemHjeWkjeiuoeeulw0KICAgICAgICAvLy8g44CQ5oCn6IO95o+Q5Y2H44CR77ya5LuO5aSN5p2C55qE5aSa57u05bqm6K+E5Lyw566A5YyW5Li65Y2V5LiA57yT5a2Y5p+l6K+iDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgZG91YmxlIENhbGN1bGF0ZVNraWxsTWF0Y2hpbmdCb251cyhXb3JrT3JkZXJFbnRpdHkgdGFzaywgbG9uZyBwZXJzb25uZWxJZCwgR2xvYmFsQWxsb2NhdGlvbkNvbnRleHQgY29udGV4dCkNCiAgICAgICAgew0KICAgICAgICAgICAgLy8g44CQ5qC45b+D566A5YyW44CR5L2/55So6aKE562b6YCJ57uT5p6c5Lit55qE6K+E5YiG5L2c5Li65oqA6IO95Yy56YWN5L6d5o2uDQogICAgICAgICAgICB2YXIgcHJlZmlsdGVyS2V5ID0gJCJ7dGFzay5JZH1fe3BlcnNvbm5lbElkfSI7DQogICAgICAgICAgICANCiAgICAgICAgICAgIGlmIChjb250ZXh0LlByZWZpbHRlclJlc3VsdHMuVHJ5R2V0VmFsdWUocHJlZmlsdGVyS2V5LCBvdXQgdmFyIHByZWZpbHRlclJlc3VsdCkpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgLy8g5bCG6aKE562b6YCJ6K+E5YiG6L2s5o2i5Li65aWW5Yqx5YiG5pWwDQogICAgICAgICAgICAgICAgdmFyIGJhc2VCb251cyA9IChwcmVmaWx0ZXJSZXN1bHQuUHJlZmlsdGVyU2NvcmUgLSA1MC4wKSAqIDIuMDsgLy8gNTDliIbku6XkuIrkuLrmraPlpZblirHvvIzku6XkuIvkuLrotJ/mg6nnvZoNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyDlj6/ooYzmgKfpop3lpJblpZblirENCiAgICAgICAgICAgICAgICB2YXIgZmVhc2liaWxpdHlCb251cyA9IHByZWZpbHRlclJlc3VsdC5Jc0ZlYXNpYmxlID8gMjAuMCA6IC01MC4wOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLk1heCgtMTAwLjAsIE1hdGguTWluKDIwMC4wLCBiYXNlQm9udXMgKyBmZWFzaWJpbGl0eUJvbnVzKSk7IC8vIOmZkOWItuWcqFstMTAwLCAyMDBd6IyD5Zu0DQogICAgICAgICAgICB9DQogICAgICAgICAgICANCiAgICAgICAgICAgIC8vIOaXoOmihOetm+mAieaVsOaNruaXtueahOS/neWuiOivhOS8sA0KICAgICAgICAgICAgcmV0dXJuIDAuMDsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOiuoeeul+WIhumFjeivhOWIhg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIGRvdWJsZSBDYWxjdWxhdGVBc3NpZ25tZW50U2NvcmUobG9uZyB0YXNrSWQsIGxvbmcgcGVyc29ubmVsSWQsIEdsb2JhbEFsbG9jYXRpb25Db250ZXh0IGNvbnRleHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBwcmVmaWx0ZXJLZXkgPSAkInt0YXNrSWR9X3twZXJzb25uZWxJZH0iOw0KICAgICAgICAgICAgdmFyIGJhc2VTY29yZSA9IDEwMC4wOw0KICAgICAgICAgICAgDQogICAgICAgICAgICBpZiAoY29udGV4dC5QcmVmaWx0ZXJSZXN1bHRzLlRyeUdldFZhbHVlKHByZWZpbHRlcktleSwgb3V0IHZhciByZXN1bHQpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGJhc2VTY29yZSA9IHJlc3VsdC5QcmVmaWx0ZXJTY29yZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIA0KICAgICAgICAgICAgdmFyIHRhc2sgPSBjb250ZXh0LlRhc2tzLkZpcnN0T3JEZWZhdWx0KHQgPT4gdC5JZCA9PSB0YXNrSWQpOw0KICAgICAgICAgICAgaWYgKHRhc2sgIT0gbnVsbCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBiYXNlU2NvcmUgKz0gQ2FsY3VsYXRlU2tpbGxNYXRjaGluZ0JvbnVzKHRhc2ssIHBlcnNvbm5lbElkLCBjb250ZXh0KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIA0KICAgICAgICAgICAgcmV0dXJuIGJhc2VTY29yZTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOiuoeeul+WfuuWwvOezu+aVsA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIGRvdWJsZSBDYWxjdWxhdGVHaW5pQ29lZmZpY2llbnQoTGlzdDxkZWNpbWFsPiB2YWx1ZXMpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmICghdmFsdWVzLkFueSgpKSByZXR1cm4gMDsNCg0KICAgICAgICAgICAgdmFyIG4gPSB2YWx1ZXMuQ291bnQ7DQogICAgICAgICAgICB2YXIgc29ydGVkVmFsdWVzID0gdmFsdWVzLk9yZGVyQnkoeCA9PiB4KS5Ub0FycmF5KCk7DQoNCiAgICAgICAgICAgIGRvdWJsZSBudW1lcmF0b3IgPSAwOw0KICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgbnVtZXJhdG9yICs9ICgyICogKGkgKyAxKSAtIG4gLSAxKSAqIChkb3VibGUpc29ydGVkVmFsdWVzW2ldOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICB2YXIgbWVhbiA9IHZhbHVlcy5BdmVyYWdlKHggPT4gKGRvdWJsZSl4KTsNCiAgICAgICAgICAgIHJldHVybiBtZWFuID09IDAgPyAwIDogbnVtZXJhdG9yIC8gKG4gKiBuICogbWVhbik7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDliJvlu7rlpLHotKXop6PlhrPmlrnmoYgNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHJpdmF0ZSBHbG9iYWxPcHRpbWl6ZWRTb2x1dGlvbiBDcmVhdGVGYWlsdXJlU29sdXRpb24oc3RyaW5nIGVycm9yTWVzc2FnZSwgbG9uZyBlbGFwc2VkTXMpDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldHVybiBuZXcgR2xvYmFsT3B0aW1pemVkU29sdXRpb24NCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBCZXN0U29sdXRpb24gPSBuZXcgRGljdGlvbmFyeTxsb25nLCBsb25nPigpLA0KICAgICAgICAgICAgICAgIEJlc3RGaXRuZXNzID0gMC4wLA0KICAgICAgICAgICAgICAgIEFjdHVhbEdlbmVyYXRpb25zID0gMCwNCiAgICAgICAgICAgICAgICBDb25zdHJhaW50U2F0aXNmYWN0aW9uUmF0ZSA9IDAuMA0KICAgICAgICAgICAgfTsNCiAgICAgICAgfQ0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIOWinuW8uueJiOaJueasoeaEn+efpemqjOivgeaUr+aMgeaWueazlQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOOAkFVsdHJhIHRoaW5r5qC45b+D5pa55rOV44CR5omn6KGM5om55qyh5oSf55+l6aqM6K+BIC0g55yf5q2j6Kej5Yaz5b2T5YmN5YiG6YWN57uE5ZCIK+WOhuWPsumqjOivgemXrumimA0KICAgICAgICAvLy8g44CQ5rex5bqm5Lia5Yqh5oCd6ICD44CR77ya5a+55q+P5Liq5Lq65ZGY55qE5omA5pyJ5Y+v6IO95Lu75Yqh57uE5ZCI6L+b6KGM5Lqk5Y+J6aqM6K+BDQogICAgICAgIC8vLyDjgJDmnrbmnoTliJvmlrDjgJHvvJrku47ljZXku7vliqEr5Y6G5Y+y5qih5byP5Y2H57qn5Li65om55qyh57uE5ZCIK+WOhuWPsueahOWFqOmdoumqjOivgeaooeW8jw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIGFzeW5jIFRhc2s8RGljdGlvbmFyeTxsb25nLCBMaXN0PHN0cmluZz4+PiBFeGVjdXRlQmF0Y2hBd2FyZVZhbGlkYXRpb25Bc3luYygNCiAgICAgICAgICAgIGxvbmcgcGVyc29ubmVsSWQsDQogICAgICAgICAgICBMaXN0PFdvcmtPcmRlckVudGl0eT4gcG9zc2libGVUYXNrcywNCiAgICAgICAgICAgIEdsb2JhbEFsbG9jYXRpb25Db250ZXh0IGNvbnRleHQsDQogICAgICAgICAgICBQZXJzb25uZWxUYXNrTWF0cml4IG1hdHJpeCkNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIHZhbGlkYXRpb25SZXN1bHRzID0gbmV3IERpY3Rpb25hcnk8bG9uZywgTGlzdDxzdHJpbmc+PigpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICB0cnkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAvLyDjgJDmraXpqqQx44CR6I635Y+W6K+l5Lq65ZGY55qE5Y6G5Y+y5Lu75Yqh5L2c5Li66aqM6K+B5Z+657q/DQogICAgICAgICAgICAgICAgY29udGV4dC5QZXJzb25uZWxIaXN0b3J5VGFza3MuVHJ5R2V0VmFsdWUocGVyc29ubmVsSWQsIG91dCB2YXIgaGlzdG9yeVRhc2tzKTsNCiAgICAgICAgICAgICAgICB2YXIgYmFzZWxpbmVUYXNrcyA9IGhpc3RvcnlUYXNrcz8uU2VsZWN0KGggPT4gbmV3IFdvcmtPcmRlckVudGl0eQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgSWQgPSBoLlRhc2tJZCwNCiAgICAgICAgICAgICAgICAgICAgV29ya09yZGVyRGF0ZSA9IGguV29ya0RhdGUsDQogICAgICAgICAgICAgICAgICAgIFNoaWZ0SWQgPSBoLlNoaWZ0SWQsDQogICAgICAgICAgICAgICAgICAgIFNoaWZ0TmFtZSA9IGguU2hpZnROYW1lLA0KICAgICAgICAgICAgICAgICAgICBXb3JrT3JkZXJDb2RlID0gaC5UYXNrQ29kZSwNCiAgICAgICAgICAgICAgICAgICAgUHJvamVjdE51bWJlciA9IGguUHJvamVjdE51bWJlciwNCiAgICAgICAgICAgICAgICAgICAgU3RhdHVzID0gaC5TdGF0dXMNCiAgICAgICAgICAgICAgICB9KS5Ub0xpc3QoKSA/PyBuZXcgTGlzdDxXb3JrT3JkZXJFbnRpdHk+KCk7DQoNCiAgICAgICAgICAgICAgICAvLyDjgJDmraXpqqQy44CR5Li65q+P5Liq5Y+v6IO955qE5Lu75Yqh5p6E5bu65om55qyh5oSf55+l6aqM6K+B5LiK5LiL5paHDQogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGNhbmRpZGF0ZVRhc2sgaW4gcG9zc2libGVUYXNrcykNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciB2aW9sYXRpb25zID0gbmV3IExpc3Q8c3RyaW5nPigpOw0KICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgLy8g44CQ5qC45b+D5Yib5paw44CR5p6E5bu65b2T5YmN5om55qyh55qE5qih5ouf5YiG6YWN5LiK5LiL5paHDQogICAgICAgICAgICAgICAgICAgIHZhciBiYXRjaFNpbXVsYXRpb25Db250ZXh0ID0gQnVpbGRCYXRjaFNpbXVsYXRpb25Db250ZXh0KA0KICAgICAgICAgICAgICAgICAgICAgICAgcGVyc29ubmVsSWQsIGNhbmRpZGF0ZVRhc2ssIHBvc3NpYmxlVGFza3MsIGJhc2VsaW5lVGFza3MsIGNvbnRleHQpOw0KICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIC8vIOOAkOaJueasoemqjOivgTHjgJHmo4Dmn6XkuI7mibnmrKHlhoXlhbbku5bku7vliqHnmoTml7bpl7TlhrLnqoENCiAgICAgICAgICAgICAgICAgICAgdmFyIGJhdGNoVGltZUNvbmZsaWN0cyA9IENoZWNrQmF0Y2hUaW1lQ29uZmxpY3RzKGNhbmRpZGF0ZVRhc2ssIGJhdGNoU2ltdWxhdGlvbkNvbnRleHQpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoYmF0Y2hUaW1lQ29uZmxpY3RzLkFueSgpKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICB2aW9sYXRpb25zLkFkZFJhbmdlKGJhdGNoVGltZUNvbmZsaWN0cyk7DQogICAgICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgICAgICAvLyDjgJDmibnmrKHpqozor4Ey44CR5L2/55SoU2hpZnRSdWxlVmFsaWRhdGlvbkVuZ2luZei/m+ihjOS4k+S4muePreasoeinhOWImemqjOivgQ0KICAgICAgICAgICAgICAgICAgICB0cnkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbmZsaWN0cyA9IGF3YWl0IF9zaGlmdFJ1bGVFbmdpbmUuVmFsaWRhdGVTaGlmdFJ1bGVzV2l0aEVuaGFuY2VkQmF0Y2hDb250ZXh0QXN5bmMoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyc29ubmVsSWQsIGNhbmRpZGF0ZVRhc2ssIGJhdGNoU2ltdWxhdGlvbkNvbnRleHQsIGNvbnRleHQpOw0KICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgY29uZmxpY3QgaW4gY29uZmxpY3RzKQ0KICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMuQWRkKCQi54+t5qyh6KeE5YiZ5Yay56qBOiB7Y29uZmxpY3R9Iik7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dXYXJuaW5nKGV4LCAi4pqg77iPIOaJueasoeaEn+efpeePreasoeinhOWImemqjOivgeW8guW4uCAtIOS6uuWRmHtQZXJzb25uZWxJZH3ku7vliqF7VGFza0lkfSIsIHBlcnNvbm5lbElkLCBjYW5kaWRhdGVUYXNrLklkKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMuQWRkKCQi54+t5qyh6KeE5YiZ6aqM6K+B5byC5bi4OiB7ZXguTWVzc2FnZX0iKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgICAgIC8vIOOAkOaJueasoemqjOivgTPjgJHmo4Dmn6Xlt6XkvZzotJ/ovb3pmZDliLYNCiAgICAgICAgICAgICAgICAgICAgdmFyIHdvcmtsb2FkVmlvbGF0aW9ucyA9IENoZWNrQmF0Y2hXb3JrbG9hZExpbWl0cyhjYW5kaWRhdGVUYXNrLCBiYXRjaFNpbXVsYXRpb25Db250ZXh0LCBwZXJzb25uZWxJZCk7DQogICAgICAgICAgICAgICAgICAgIGlmICh3b3JrbG9hZFZpb2xhdGlvbnMuQW55KCkpDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMuQWRkUmFuZ2Uod29ya2xvYWRWaW9sYXRpb25zKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgICAgIC8vIOOAkOaJueasoemqjOivgTTjgJHmo4Dmn6XkurrlkZjkuI3lj6/nlKjmgKfvvIjln7rkuo7nj63mrKHkuI3lj6/nlKjmgKfnvJPlrZjvvIkNCiAgICAgICAgICAgICAgICAgICAgdmFyIHVuYXZhaWxhYmlsaXR5VmlvbGF0aW9ucyA9IENoZWNrUGVyc29ubmVsVW5hdmFpbGFiaWxpdHkoY2FuZGlkYXRlVGFzaywgcGVyc29ubmVsSWQsIGNvbnRleHQpOw0KICAgICAgICAgICAgICAgICAgICBpZiAodW5hdmFpbGFiaWxpdHlWaW9sYXRpb25zLkFueSgpKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICB2aW9sYXRpb25zLkFkZFJhbmdlKHVuYXZhaWxhYmlsaXR5VmlvbGF0aW9ucyk7DQogICAgICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uUmVzdWx0c1tjYW5kaWRhdGVUYXNrLklkXSA9IHZpb2xhdGlvbnM7DQogICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICBpZiAodmlvbGF0aW9ucy5BbnkoKSkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dUcmFjZSgi8J+UjSDmibnmrKHmhJ/nn6Xpqozor4EgLSDkurrlkZh7UGVyc29ubmVsSWR95Lu75Yqhe1Rhc2tJZH3lj5HnjrB7VmlvbGF0aW9uQ291bnR95Liq6Zeu6aKY77yae1Zpb2xhdGlvbnN9IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJzb25uZWxJZCwgY2FuZGlkYXRlVGFzay5JZCwgdmlvbGF0aW9ucy5Db3VudCwgc3RyaW5nLkpvaW4oIjsgIiwgdmlvbGF0aW9ucy5UYWtlKDMpKSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICByZXR1cm4gdmFsaWRhdGlvblJlc3VsdHM7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIF9sb2dnZXIuTG9nRXJyb3IoZXgsICLwn5KlIOaJueasoeaEn+efpemqjOivgeW8guW4uCAtIOS6uuWRmHtQZXJzb25uZWxJZH0iLCBwZXJzb25uZWxJZCk7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g5byC5bi45oOF5Ya15LiL5Li65omA5pyJ5Lu75Yqh6L+U5Zue6ZSZ6K+v5qCH6K6wDQogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRhc2sgaW4gcG9zc2libGVUYXNrcykNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25SZXN1bHRzW3Rhc2suSWRdID0gbmV3IExpc3Q8c3RyaW5nPiB7ICQi5om55qyh6aqM6K+B5byC5bi4OiB7ZXguTWVzc2FnZX0iIH07DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHJldHVybiB2YWxpZGF0aW9uUmVzdWx0czsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOaehOW7uuaJueasoeaooeaLn+S4iuS4i+aWhyAtIOaooeaLn+W9k+WJjeS6uuWRmOWcqOaJueasoeS4reeahOWujOaVtOS7u+WKoeWIhumFjeaDheWGtQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIExpc3Q8V29ya09yZGVyRW50aXR5PiBCdWlsZEJhdGNoU2ltdWxhdGlvbkNvbnRleHQoDQogICAgICAgICAgICBsb25nIHBlcnNvbm5lbElkLA0KICAgICAgICAgICAgV29ya09yZGVyRW50aXR5IGNhbmRpZGF0ZVRhc2ssDQogICAgICAgICAgICBMaXN0PFdvcmtPcmRlckVudGl0eT4gcG9zc2libGVUYXNrcywNCiAgICAgICAgICAgIExpc3Q8V29ya09yZGVyRW50aXR5PiBiYXNlbGluZVRhc2tzLA0KICAgICAgICAgICAgR2xvYmFsQWxsb2NhdGlvbkNvbnRleHQgY29udGV4dCkNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIHNpbXVsYXRpb25Db250ZXh0ID0gbmV3IExpc3Q8V29ya09yZGVyRW50aXR5PigpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICAvLyDmt7vliqDljoblj7Lln7rnur/ku7vliqENCiAgICAgICAgICAgIHNpbXVsYXRpb25Db250ZXh0LkFkZFJhbmdlKGJhc2VsaW5lVGFza3MpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICAvLyDjgJDmibnmrKHmhJ/nn6XnrZbnlaXjgJHmt7vliqDlhbbku5bpq5jmpoLnjofnmoTmibnmrKHku7vliqENCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBvdGhlclRhc2sgaW4gcG9zc2libGVUYXNrcykNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBpZiAob3RoZXJUYXNrLklkID09IGNhbmRpZGF0ZVRhc2suSWQpIGNvbnRpbnVlOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIHZhciBwcmVmaWx0ZXJLZXkgPSAkIntvdGhlclRhc2suSWR9X3twZXJzb25uZWxJZH0iOw0KICAgICAgICAgICAgICAgIGlmIChjb250ZXh0LlByZWZpbHRlclJlc3VsdHMuVHJ5R2V0VmFsdWUocHJlZmlsdGVyS2V5LCBvdXQgdmFyIHByZWZpbHRlclJlc3VsdCkpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAvLyDpq5jor4TliIbmiJbmoIforrDkuLrlj6/ooYznmoTku7vliqHliqDlhaXmqKHmi5/kuIrkuIvmlocNCiAgICAgICAgICAgICAgICAgICAgaWYgKHByZWZpbHRlclJlc3VsdC5Jc0ZlYXNpYmxlIHx8IHByZWZpbHRlclJlc3VsdC5QcmVmaWx0ZXJTY29yZSA+IDYwLjApDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzaW11bGF0ZWRUYXNrID0gb3RoZXJUYXNrLkNsb25lRm9yVmFsaWRhdGlvbigpOw0KICAgICAgICAgICAgICAgICAgICAgICAgc2ltdWxhdGVkVGFzay5Bc3NpZ25lZFBlcnNvbm5lbElkID0gcGVyc29ubmVsSWQ7DQogICAgICAgICAgICAgICAgICAgICAgICBzaW11bGF0aW9uQ29udGV4dC5BZGQoc2ltdWxhdGVkVGFzayk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICANCiAgICAgICAgICAgIHJldHVybiBzaW11bGF0aW9uQ29udGV4dDsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOajgOafpeaJueasoeaXtumXtOWGsueqgSAtIOS4juaJueasoeWGheWFtuS7luS7u+WKoeeahOaXtumXtOWGsueqgQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIExpc3Q8c3RyaW5nPiBDaGVja0JhdGNoVGltZUNvbmZsaWN0cygNCiAgICAgICAgICAgIFdvcmtPcmRlckVudGl0eSBjYW5kaWRhdGVUYXNrLA0KICAgICAgICAgICAgTGlzdDxXb3JrT3JkZXJFbnRpdHk+IGJhdGNoQ29udGV4dCkNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIHZpb2xhdGlvbnMgPSBuZXcgTGlzdDxzdHJpbmc+KCk7DQogICAgICAgICAgICANCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBleGlzdGluZ1Rhc2sgaW4gYmF0Y2hDb250ZXh0KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGlmIChleGlzdGluZ1Rhc2suSWQgPT0gY2FuZGlkYXRlVGFzay5JZCkgY29udGludWU7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g5Z+656GA5pe26Ze05Yay56qB5qOA5p+lDQogICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nVGFzay5Xb3JrT3JkZXJEYXRlLkRhdGUgPT0gY2FuZGlkYXRlVGFzay5Xb3JrT3JkZXJEYXRlLkRhdGUgJiYNCiAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdUYXNrLlNoaWZ0SWQgPT0gY2FuZGlkYXRlVGFzay5TaGlmdElkKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdmlvbGF0aW9ucy5BZGQoJCLml7bpl7TlhrLnqoE6IOS4juS7u+WKoXtleGlzdGluZ1Rhc2suSWR95Zyoe2NhbmRpZGF0ZVRhc2suV29ya09yZGVyRGF0ZTp5eXl5LU1NLWRkfeePreasoXtjYW5kaWRhdGVUYXNrLlNoaWZ0SWR95Yay56qBIik7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIC8vIOaJqeWxleaXtumXtOautemHjeWPoOajgOafpQ0KICAgICAgICAgICAgICAgIGlmIChJc1RpbWVTbG90T3ZlcmxhcChleGlzdGluZ1Rhc2ssIGNhbmRpZGF0ZVRhc2spKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdmlvbGF0aW9ucy5BZGQoJCLml7bpl7TmrrXph43lj6A6IOS4juS7u+WKoXtleGlzdGluZ1Rhc2suSWR95a2Y5Zyo5pe26Ze05q616YeN5Y+gIik7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgDQogICAgICAgICAgICByZXR1cm4gdmlvbGF0aW9uczsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOajgOafpeaJueasoeW3peS9nOi0n+i9vemZkOWItg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIExpc3Q8c3RyaW5nPiBDaGVja0JhdGNoV29ya2xvYWRMaW1pdHMoDQogICAgICAgICAgICBXb3JrT3JkZXJFbnRpdHkgY2FuZGlkYXRlVGFzaywNCiAgICAgICAgICAgIExpc3Q8V29ya09yZGVyRW50aXR5PiBiYXRjaENvbnRleHQsDQogICAgICAgICAgICBsb25nIHBlcnNvbm5lbElkKQ0KICAgICAgICB7DQogICAgICAgICAgICB2YXIgdmlvbGF0aW9ucyA9IG5ldyBMaXN0PHN0cmluZz4oKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgLy8g5oyJ5pel5pyf5YiG57uE5qOA5p+l5q+P5pel5bel5L2c6LSf6L29DQogICAgICAgICAgICB2YXIgZGFpbHlUYXNrcyA9IGJhdGNoQ29udGV4dA0KICAgICAgICAgICAgICAgIC5XaGVyZSh0ID0+IHQuQXNzaWduZWRQZXJzb25uZWxJZCA9PSBwZXJzb25uZWxJZCkNCiAgICAgICAgICAgICAgICAuR3JvdXBCeSh0ID0+IHQuV29ya09yZGVyRGF0ZS5EYXRlKQ0KICAgICAgICAgICAgICAgIC5Ub0xpc3QoKTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgIC8vIOajgOafpeWAmemAieS7u+WKoeaJgOWcqOaXpeacn+eahOW3peS9nOi0n+i9vQ0KICAgICAgICAgICAgdmFyIGNhbmRpZGF0ZURhdGUgPSBjYW5kaWRhdGVUYXNrLldvcmtPcmRlckRhdGUuRGF0ZTsNCiAgICAgICAgICAgIHZhciBzYW1lRGF5VGFza3MgPSBkYWlseVRhc2tzDQogICAgICAgICAgICAgICAgLldoZXJlKGcgPT4gZy5LZXkgPT0gY2FuZGlkYXRlRGF0ZSkNCiAgICAgICAgICAgICAgICAuU2VsZWN0TWFueShnID0+IGcpDQogICAgICAgICAgICAgICAgLlRvTGlzdCgpOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgaWYgKHNhbWVEYXlUYXNrcy5BbnkoKSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB2YXIgdG90YWxIb3VycyA9IHNhbWVEYXlUYXNrcy5TdW0odCA9PiB0LkVzdGltYXRlZEhvdXJzID8/IDEuMG0pICsgKGNhbmRpZGF0ZVRhc2suRXN0aW1hdGVkSG91cnMgPz8gMS4wbSk7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgaWYgKHRvdGFsSG91cnMgPiAxMikgLy8g5q+P5pel5pyA5aSnMTLlsI/ml7bvvIjlkKvliqDnj63vvIkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMuQWRkKCQi5pel5bel5L2c6LSf6L296LaF6ZmQOiB7Y2FuZGlkYXRlRGF0ZTp5eXl5LU1NLWRkfeaAu+W3peaXtnt0b3RhbEhvdXJzfeWwj+aXtui2hei/hzEy5bCP5pe26ZmQ5Yi2Iik7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgDQogICAgICAgICAgICByZXR1cm4gdmlvbGF0aW9uczsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOajgOafpeS6uuWRmOS4jeWPr+eUqOaApyAtIOWfuuS6juePreasoeS4jeWPr+eUqOaAp+e8k+WtmA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIExpc3Q8c3RyaW5nPiBDaGVja1BlcnNvbm5lbFVuYXZhaWxhYmlsaXR5KA0KICAgICAgICAgICAgV29ya09yZGVyRW50aXR5IGNhbmRpZGF0ZVRhc2ssDQogICAgICAgICAgICBsb25nIHBlcnNvbm5lbElkLA0KICAgICAgICAgICAgR2xvYmFsQWxsb2NhdGlvbkNvbnRleHQgY29udGV4dCkNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIHZpb2xhdGlvbnMgPSBuZXcgTGlzdDxzdHJpbmc+KCk7DQogICAgICAgICAgICANCiAgICAgICAgICAgIC8vIOajgOafpeS6uuWRmOePreasoeS4jeWPr+eUqOaApw0KICAgICAgICAgICAgaWYgKGNvbnRleHQuUGVyc29ubmVsVW5hdmFpbGFiaWxpdHlJbmRleC5UcnlHZXRWYWx1ZShwZXJzb25uZWxJZCwgb3V0IHZhciB1bmF2YWlsYWJpbGl0eUluZGV4KSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB2YXIgdGFza0RhdGUgPSBjYW5kaWRhdGVUYXNrLldvcmtPcmRlckRhdGUuRGF0ZTsNCiAgICAgICAgICAgICAgICBpZiAodW5hdmFpbGFiaWxpdHlJbmRleC5UcnlHZXRWYWx1ZSh0YXNrRGF0ZSwgb3V0IHZhciB1bmF2YWlsYWJsZVNoaWZ0cykpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBpZiAoY2FuZGlkYXRlVGFzay5TaGlmdElkLkhhc1ZhbHVlICYmIHVuYXZhaWxhYmxlU2hpZnRzLkNvbnRhaW5zKGNhbmRpZGF0ZVRhc2suU2hpZnRJZC5WYWx1ZSkpDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMuQWRkKCQi5Lq65ZGY5LiN5Y+v55SoOiB7dGFza0RhdGU6eXl5eS1NTS1kZH3nj63mrKF7Y2FuZGlkYXRlVGFzay5TaGlmdElkfeS6uuWRmOS4jeWPr+eUqCIpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgDQogICAgICAgICAgICByZXR1cm4gdmlvbGF0aW9uczsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOajgOafpeS7u+WKoee7hOWQiOS4reeahOaXtumXtOWGsueqgQ0KICAgICAgICAvLy8g44CQ5rex5bqm5a6e546w44CR77ya5aSa57u05bqm5pe26Ze05Yay56qB5qOA5rWL77yM5YyF5ous5pel5pyf44CB54+t5qyh44CB5pe26Ze05q616YeN5Y+gDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgYm9vbCBIYXNUaW1lQ29uZmxpY3RJbkNvbWJpbmF0aW9uKA0KICAgICAgICAgICAgTGlzdDxXb3JrT3JkZXJFbnRpdHk+IHRhc2tDb21iaW5hdGlvbiwNCiAgICAgICAgICAgIFdvcmtPcmRlckVudGl0eSBuZXdUYXNrKQ0KICAgICAgICB7DQogICAgICAgICAgICBpZiAoIXRhc2tDb21iaW5hdGlvbi5BbnkoKSkgcmV0dXJuIGZhbHNlOw0KDQogICAgICAgICAgICBmb3JlYWNoICh2YXIgZXhpc3RpbmdUYXNrIGluIHRhc2tDb21iaW5hdGlvbikNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAvLyDln7rnoYDml7bpl7TlhrLnqoHvvJrnm7jlkIzml6XmnJ8r54+t5qyhDQogICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nVGFzay5Xb3JrT3JkZXJEYXRlLkRhdGUgPT0gbmV3VGFzay5Xb3JrT3JkZXJEYXRlLkRhdGUgJiYNCiAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdUYXNrLlNoaWZ0SWQgPT0gbmV3VGFzay5TaGlmdElkKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgLy8g5omp5bGV5Yay56qB5qOA5p+l77ya6Leo54+t5qyh5L2G5Zyo5ZCM5LiA5pe26Ze05q61DQogICAgICAgICAgICAgICAgaWYgKElzVGltZVNsb3RPdmVybGFwKGV4aXN0aW5nVGFzaywgbmV3VGFzaykpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOajgOafpeaXtumXtOautemHjeWPoA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIGJvb2wgSXNUaW1lU2xvdE92ZXJsYXAoV29ya09yZGVyRW50aXR5IHRhc2sxLCBXb3JrT3JkZXJFbnRpdHkgdGFzazIpDQogICAgICAgIHsNCiAgICAgICAgICAgIC8vIOWmguaenOePreasoeS/oeaBr+S4jeWujOaVtO+8jOS/neWuiOWIpOaWrQ0KICAgICAgICAgICAgaWYgKHRhc2sxLlNoaWZ0RW50aXR5ID09IG51bGwgfHwgdGFzazIuU2hpZnRFbnRpdHkgPT0gbnVsbCkNCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7DQoNCiAgICAgICAgICAgIHZhciBzdGFydDEgPSB0YXNrMS5Xb3JrT3JkZXJEYXRlLkRhdGUuQWRkKHRhc2sxLlNoaWZ0RW50aXR5LlN0YXJ0VGltZSk7DQogICAgICAgICAgICB2YXIgZW5kMSA9IHRhc2sxLldvcmtPcmRlckRhdGUuRGF0ZS5BZGQodGFzazEuU2hpZnRFbnRpdHkuRW5kVGltZSk7DQogICAgICAgICAgICANCiAgICAgICAgICAgIHZhciBzdGFydDIgPSB0YXNrMi5Xb3JrT3JkZXJEYXRlLkRhdGUuQWRkKHRhc2syLlNoaWZ0RW50aXR5LlN0YXJ0VGltZSk7DQogICAgICAgICAgICB2YXIgZW5kMiA9IHRhc2syLldvcmtPcmRlckRhdGUuRGF0ZS5BZGQodGFzazIuU2hpZnRFbnRpdHkuRW5kVGltZSk7DQoNCiAgICAgICAgICAgIC8vIOWkhOeQhui3qOaXpeePreasoe+8iOWmguWknOePrTIyOjAwLTA2OjAw77yJDQogICAgICAgICAgICBpZiAodGFzazEuU2hpZnRFbnRpdHkuRW5kVGltZSA8IHRhc2sxLlNoaWZ0RW50aXR5LlN0YXJ0VGltZSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBlbmQxID0gZW5kMS5BZGREYXlzKDEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKHRhc2syLlNoaWZ0RW50aXR5LkVuZFRpbWUgPCB0YXNrMi5TaGlmdEVudGl0eS5TdGFydFRpbWUpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgZW5kMiA9IGVuZDIuQWRkRGF5cygxKTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8g5qOA5p+l5pe26Ze05q616YeN5Y+gDQogICAgICAgICAgICByZXR1cm4gc3RhcnQxIDwgZW5kMiAmJiBzdGFydDIgPCBlbmQxOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g5p6E5bu65Lq65ZGY5Lu75Yqh55+p6Zi1DQogICAgICAgIC8vLyDjgJDmgKfog73kvJjljJbjgJHvvJrpooTorqHnrpfkurrlkZgt5Lu75Yqh5YWz6IGU55+p6Zi177yM5Yqg6YCf5Yay56qB5qOA5p+lDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgUGVyc29ubmVsVGFza01hdHJpeCBCdWlsZFBlcnNvbm5lbFRhc2tNYXRyaXgoDQogICAgICAgICAgICBEaWN0aW9uYXJ5PChsb25nIFRhc2tJZCwgbG9uZyBQZXJzb25uZWxJZCksIFZhcmlhYmxlPiBkZWNpc2lvblZhcnMsDQogICAgICAgICAgICBHbG9iYWxBbGxvY2F0aW9uQ29udGV4dCBjb250ZXh0KQ0KICAgICAgICB7DQogICAgICAgICAgICB2YXIgbWF0cml4ID0gbmV3IFBlcnNvbm5lbFRhc2tNYXRyaXgoKTsNCg0KICAgICAgICAgICAgLy8g5Li65q+P5Liq5Lq65ZGY5p6E5bu65Y+v6IO955qE5Lu75Yqh5YiX6KGoDQogICAgICAgICAgICBmb3JlYWNoICh2YXIgcGVyc29ubmVsIGluIGNvbnRleHQuQXZhaWxhYmxlUGVyc29ubmVsKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciBwZXJzb25uZWxUYXNrcyA9IGNvbnRleHQuVGFza3MNCiAgICAgICAgICAgICAgICAgICAgLldoZXJlKHRhc2sgPT4gZGVjaXNpb25WYXJzLkNvbnRhaW5zS2V5KCh0YXNrLklkLCBwZXJzb25uZWwuSWQpKSkNCiAgICAgICAgICAgICAgICAgICAgLlRvTGlzdCgpOw0KDQogICAgICAgICAgICAgICAgbWF0cml4LlBlcnNvbm5lbFRhc2tNYXBbcGVyc29ubmVsLklkXSA9IHBlcnNvbm5lbFRhc2tzOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyDkuLrmr4/kuKrku7vliqHmnoTlu7rlj6/og73nmoTkurrlkZjliJfooagNCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YXNrIGluIGNvbnRleHQuVGFza3MpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyIHRhc2tQZXJzb25uZWwgPSBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbA0KICAgICAgICAgICAgICAgICAgICAuV2hlcmUocGVyc29ubmVsID0+IGRlY2lzaW9uVmFycy5Db250YWluc0tleSgodGFzay5JZCwgcGVyc29ubmVsLklkKSkpDQogICAgICAgICAgICAgICAgICAgIC5Ub0xpc3QoKTsNCg0KICAgICAgICAgICAgICAgIG1hdHJpeC5UYXNrUGVyc29ubmVsTWFwW3Rhc2suSWRdID0gdGFza1BlcnNvbm5lbDsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgcmV0dXJuIG1hdHJpeDsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOWIm+W7uuWFqOWxgOaXtumXtOautee6puadnw0KICAgICAgICAvLy8g44CQ5p625p6E5Yib5paw44CR77ya6Leo5Lq65ZGY55qE5pe26Ze05q6157qm5p2f77yM56Gu5L+d6LWE5rqQ5LiN5Yay56qBDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgaW50IENyZWF0ZUdsb2JhbFRpbWVTbG90Q29uc3RyYWludHMoDQogICAgICAgICAgICBTb2x2ZXIgc29sdmVyLA0KICAgICAgICAgICAgRGljdGlvbmFyeTwobG9uZyBUYXNrSWQsIGxvbmcgUGVyc29ubmVsSWQpLCBWYXJpYWJsZT4gZGVjaXNpb25WYXJzLA0KICAgICAgICAgICAgR2xvYmFsQWxsb2NhdGlvbkNvbnRleHQgY29udGV4dCkNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIGNvbnN0cmFpbnRDb3VudCA9IDA7DQogICAgICAgICAgICANCiAgICAgICAgICAgIC8vIOaMieaXtumXtOauteWIhue7hOaJgOacieS7u+WKoQ0KICAgICAgICAgICAgdmFyIHRpbWVTbG90R3JvdXBzID0gY29udGV4dC5UYXNrcw0KICAgICAgICAgICAgICAgIC5Hcm91cEJ5KHQgPT4gbmV3IFRpbWVXaW5kb3cgDQogICAgICAgICAgICAgICAgeyANCiAgICAgICAgICAgICAgICAgICAgRGF0ZSA9IHQuV29ya09yZGVyRGF0ZS5EYXRlLA0KICAgICAgICAgICAgICAgICAgICBTaGlmdElkID0gdC5TaGlmdElkID8/IDAsDQogICAgICAgICAgICAgICAgICAgIFN0YXJ0VGltZSA9IHQuU2hpZnRFbnRpdHk/LlN0YXJ0VGltZSA/PyBUaW1lU3Bhbi5aZXJvDQogICAgICAgICAgICAgICAgfSkNCiAgICAgICAgICAgICAgICAuV2hlcmUoZyA9PiBnLkNvdW50KCkgPiAxKSAvLyDlj6rlpITnkIbmnInlhrLnqoHlj6/og73nmoTml7bpl7TmrrUNCiAgICAgICAgICAgICAgICAuVG9MaXN0KCk7DQoNCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0aW1lR3JvdXAgaW4gdGltZVNsb3RHcm91cHMpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyIHRhc2tzSW5UaW1lU2xvdCA9IHRpbWVHcm91cC5Ub0xpc3QoKTsNCiAgICAgICAgICAgICAgICB2YXIgdGltZVdpbmRvdyA9IHRpbWVHcm91cC5LZXk7DQoNCiAgICAgICAgICAgICAgICAvLyDkuLrmr4/kuKrkurrlkZjliJvlu7ror6Xml7bpl7TmrrXnmoTnuqbmnZ8NCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgcGVyc29ubmVsIGluIGNvbnRleHQuQXZhaWxhYmxlUGVyc29ubmVsKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHBlcnNvbm5lbFZhcnNJblRpbWVTbG90ID0gdGFza3NJblRpbWVTbG90DQogICAgICAgICAgICAgICAgICAgICAgICAuV2hlcmUodGFzayA9PiBkZWNpc2lvblZhcnMuQ29udGFpbnNLZXkoKHRhc2suSWQsIHBlcnNvbm5lbC5JZCkpKQ0KICAgICAgICAgICAgICAgICAgICAgICAgLlNlbGVjdCh0YXNrID0+IGRlY2lzaW9uVmFyc1sodGFzay5JZCwgcGVyc29ubmVsLklkKV0pDQogICAgICAgICAgICAgICAgICAgICAgICAuVG9MaXN0KCk7DQoNCiAgICAgICAgICAgICAgICAgICAgaWYgKHBlcnNvbm5lbFZhcnNJblRpbWVTbG90LkNvdW50ID4gMSkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgLy8g57qm5p2f77ya5ZCM5LiA5Lq65ZGY5Zyo5ZCM5LiA5pe26Ze05q615pyA5aSa5omn6KGMMeS4quS7u+WKoQ0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnN0cmFpbnQgPSBzb2x2ZXIuTWFrZUNvbnN0cmFpbnQoMCwgMSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJCJnbG9iYWxfdGltZXNsb3Rfe3BlcnNvbm5lbC5JZH1fe3RpbWVXaW5kb3cuRGF0ZTp5eXl5TU1kZH1fe3RpbWVXaW5kb3cuU2hpZnRJZH0iKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHZhcmlhYmxlIGluIHBlcnNvbm5lbFZhcnNJblRpbWVTbG90KQ0KICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnQuU2V0Q29lZmZpY2llbnQodmFyaWFibGUsIDEpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludENvdW50Kys7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50Q291bnQ7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDliJvlu7rmibnmrKHlrozmlbTmgKfnuqbmnZ8NCiAgICAgICAgLy8vIOOAkOS4muWKoemAu+i+keOAke+8muehruS/neaJueasoeWGheS7u+WKoeWIhumFjeeahOS4gOiHtOaAp+WSjOWujOaVtOaApw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcml2YXRlIGludCBDcmVhdGVCYXRjaEludGVncml0eUNvbnN0cmFpbnRzKA0KICAgICAgICAgICAgU29sdmVyIHNvbHZlciwNCiAgICAgICAgICAgIERpY3Rpb25hcnk8KGxvbmcgVGFza0lkLCBsb25nIFBlcnNvbm5lbElkKSwgVmFyaWFibGU+IGRlY2lzaW9uVmFycywNCiAgICAgICAgICAgIERpY3Rpb25hcnk8c3RyaW5nLCBWYXJpYWJsZT4gYXV4aWxpYXJ5VmFycywNCiAgICAgICAgICAgIEdsb2JhbEFsbG9jYXRpb25Db250ZXh0IGNvbnRleHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBjb25zdHJhaW50Q291bnQgPSAwOw0KDQogICAgICAgICAgICAvLyAxLiDpobnnm67ov57nu63mgKfnuqbmnZ/lop7lvLoNCiAgICAgICAgICAgIHZhciBwcm9qZWN0R3JvdXBzID0gY29udGV4dC5UYXNrcw0KICAgICAgICAgICAgICAgIC5Hcm91cEJ5KHQgPT4gRXh0cmFjdFByb2plY3RGcm9tV29ya09yZGVyQ29kZSh0LldvcmtPcmRlckNvZGUpKQ0KICAgICAgICAgICAgICAgIC5XaGVyZShnID0+IGcuQ291bnQoKSA+IDEpDQogICAgICAgICAgICAgICAgLlRvTGlzdCgpOw0KDQogICAgICAgICAgICBmb3JlYWNoICh2YXIgcHJvamVjdEdyb3VwIGluIHByb2plY3RHcm91cHMpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyIHByb2plY3RUYXNrcyA9IHByb2plY3RHcm91cC5Ub0xpc3QoKTsNCiAgICAgICAgICAgICAgICB2YXIgcHJvamVjdENvZGUgPSBwcm9qZWN0R3JvdXAuS2V5Ow0KDQogICAgICAgICAgICAgICAgLy8g5Yib5bu66aG555uu5LiA6Ie05oCn5oyH56S65Y+Y6YePDQogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHBlcnNvbm5lbCBpbiBjb250ZXh0LkF2YWlsYWJsZVBlcnNvbm5lbCkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciBwcm9qZWN0UGFydGljaXBhdGlvblZhcnMgPSBwcm9qZWN0VGFza3MNCiAgICAgICAgICAgICAgICAgICAgICAgIC5XaGVyZSh0YXNrID0+IGRlY2lzaW9uVmFycy5Db250YWluc0tleSgodGFzay5JZCwgcGVyc29ubmVsLklkKSkpDQogICAgICAgICAgICAgICAgICAgICAgICAuU2VsZWN0KHRhc2sgPT4gZGVjaXNpb25WYXJzWyh0YXNrLklkLCBwZXJzb25uZWwuSWQpXSkNCiAgICAgICAgICAgICAgICAgICAgICAgIC5Ub0xpc3QoKTsNCg0KICAgICAgICAgICAgICAgICAgICBpZiAocHJvamVjdFBhcnRpY2lwYXRpb25WYXJzLkNvdW50ID4gMSkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnRpY2lwYXRpb25WYXIgPSBzb2x2ZXIuTWFrZUJvb2xWYXIoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJCJwcm9qZWN0X3BhcnRpY2lwYXRpb25fe3Byb2plY3RDb2RlfV97cGVyc29ubmVsLklkfSIpOw0KDQogICAgICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzlj4LkuI7pobnnm67vvIzliJnoh7PlsJHliIbphY3kuIDkuKrku7vliqENCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb25zdHJhaW50ID0gc29sdmVyLk1ha2VDb25zdHJhaW50KDAsIGRvdWJsZS5Qb3NpdGl2ZUluZmluaXR5LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICQicHJvamVjdF9pbnRlZ3JpdHlfe3Byb2plY3RDb2RlfV97cGVyc29ubmVsLklkfSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50LlNldENvZWZmaWNpZW50KHBhcnRpY2lwYXRpb25WYXIsIC0xKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YXNrVmFyIGluIHByb2plY3RQYXJ0aWNpcGF0aW9uVmFycykNCiAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50LlNldENvZWZmaWNpZW50KHRhc2tWYXIsIDEpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludENvdW50Kys7DQoNCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOmZkOWItumhueebruWPguS4juS6uuWRmOaVsOmHjw0KICAgICAgICAgICAgICAgICAgICAgICAgYXV4aWxpYXJ5VmFyc1skInByb2plY3RfcGFydGljaXBhdGlvbl97cHJvamVjdENvZGV9X3twZXJzb25uZWwuSWR9Il0gPSBwYXJ0aWNpcGF0aW9uVmFyOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyAyLiDlt6XkvZzotJ/ovb3lubPooaHnuqbmnZ8NCiAgICAgICAgICAgIHZhciB0b3RhbFRhc2tzID0gY29udGV4dC5UYXNrcy5Db3VudDsNCiAgICAgICAgICAgIHZhciB0b3RhbFBlcnNvbm5lbCA9IGNvbnRleHQuQXZhaWxhYmxlUGVyc29ubmVsLkNvdW50Ow0KICAgICAgICAgICAgdmFyIGF2Z1dvcmtsb2FkID0gKGRvdWJsZSl0b3RhbFRhc2tzIC8gdG90YWxQZXJzb25uZWw7DQogICAgICAgICAgICB2YXIgbWF4RGV2aWF0aW9uID0gTWF0aC5DZWlsaW5nKGF2Z1dvcmtsb2FkICogMC4zKTsgLy8g5YWB6K64MzAl5YGP5beuDQoNCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBwZXJzb25uZWwgaW4gY29udGV4dC5BdmFpbGFibGVQZXJzb25uZWwpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyIHBlcnNvbm5lbFRhc2tzID0gZGVjaXNpb25WYXJzDQogICAgICAgICAgICAgICAgICAgIC5XaGVyZShrdnAgPT4ga3ZwLktleS5QZXJzb25uZWxJZCA9PSBwZXJzb25uZWwuSWQpDQogICAgICAgICAgICAgICAgICAgIC5TZWxlY3Qoa3ZwID0+IGt2cC5WYWx1ZSkNCiAgICAgICAgICAgICAgICAgICAgLlRvTGlzdCgpOw0KDQogICAgICAgICAgICAgICAgaWYgKHBlcnNvbm5lbFRhc2tzLkFueSgpKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgLy8g5bel5L2c6LSf6L295LiN5bqU6L+H5bqm5YGP56a75bmz5Z2H5YC8DQogICAgICAgICAgICAgICAgICAgIHZhciBjb25zdHJhaW50ID0gc29sdmVyLk1ha2VDb25zdHJhaW50KA0KICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5NYXgoMCwgYXZnV29ya2xvYWQgLSBtYXhEZXZpYXRpb24pLA0KICAgICAgICAgICAgICAgICAgICAgICAgYXZnV29ya2xvYWQgKyBtYXhEZXZpYXRpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAkIndvcmtsb2FkX2JhbGFuY2Vfe3BlcnNvbm5lbC5JZH0iKTsNCg0KICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgdGFza1ZhciBpbiBwZXJzb25uZWxUYXNrcykNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludC5TZXRDb2VmZmljaWVudCh0YXNrVmFyLCAxKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50Q291bnQrKzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50Q291bnQ7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDjgJBVbHRyYSB0aGlua+aguOW/g+OAkea3u+WKoOS6uuWRmOePreasoeS4jeWPr+eUqOaAp+ehrOe6puadnw0KICAgICAgICAvLy8g44CQ5Lia5Yqh6YC76L6R44CR77ya56Gu5L+d57q/5oCn6KeE5YiS5qih5Z6L5LiN5Lya5bCG5Lu75Yqh5YiG6YWN57uZ5Zyo6K+l5pe26Ze05q615LiN5Y+v55So55qE5Lq65ZGYDQogICAgICAgIC8vLyDjgJDnuqbmnZ/nrZbnlaXjgJHvvJrnoaznuqbmnZ8gLSDnm7TmjqXnpoHmraLkuI3lj6/nlKjliIbphY3vvIzkuI3lhYHorrjku7vkvZXov53lj40NCiAgICAgICAgLy8vIOOAkOaVsOaNruadpea6kOOAke+8mkRhdGVTaGlmdFVuYXZhaWxhYmxlUGVyc29ubmVs57yT5a2YICsgUGVyc29ubmVsVW5hdmFpbGFiaWxpdHlJbmRleOe0ouW8lQ0KICAgICAgICAvLy8g44CQ5oCn6IO95LyY5YyW44CR77ya5LuF5a+55bey5Yib5bu65Yaz562W5Y+Y6YeP55qE57uE5ZCI6L+b6KGM57qm5p2f77yM6YG/5YWN5peg5pWI57qm5p2fDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgYXN5bmMgVGFzazxpbnQ+IEFkZFBlcnNvbm5lbFVuYXZhaWxhYmlsaXR5Q29uc3RyYWludHMoDQogICAgICAgICAgICBTb2x2ZXIgc29sdmVyLA0KICAgICAgICAgICAgRGljdGlvbmFyeTwobG9uZyBUYXNrSWQsIGxvbmcgUGVyc29ubmVsSWQpLCBWYXJpYWJsZT4gZGVjaXNpb25WYXJzLA0KICAgICAgICAgICAgR2xvYmFsQWxsb2NhdGlvbkNvbnRleHQgY29udGV4dCkNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIGNvbnN0cmFpbnRDb3VudCA9IDA7DQogICAgICAgICAgICANCiAgICAgICAgICAgIHRyeQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIF9sb2dnZXIuTG9nRGVidWcoIvCfmqsg5byA5aeL5p6E5bu65Lq65ZGY54+t5qyh5LiN5Y+v55So5oCn56Gs57qm5p2fIik7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgdmFyIHN0YXJ0VGltZSA9IERhdGVUaW1lLk5vdzsNCiAgICAgICAgICAgICAgICB2YXIgcHJvY2Vzc2VkVmFyaWFibGVzID0gMDsNCiAgICAgICAgICAgICAgICB2YXIgY29uc3RyYWluZWRWYXJpYWJsZXMgPSAwOw0KDQogICAgICAgICAgICAgICAgLy8g44CQVWx0cmEgdGhpbmvnrZbnlaXjgJHvvJrlr7nmiYDmnInlhrPnrZblj5jph4/mo4Dmn6XkuI3lj6/nlKjmgKfnuqbmnZ8NCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIga3ZwIGluIGRlY2lzaW9uVmFycykNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciAodGFza0lkLCBwZXJzb25uZWxJZCkgPSBrdnAuS2V5Ow0KICAgICAgICAgICAgICAgICAgICB2YXIgdmFyaWFibGUgPSBrdnAuVmFsdWU7DQogICAgICAgICAgICAgICAgICAgIHByb2Nlc3NlZFZhcmlhYmxlcysrOw0KDQogICAgICAgICAgICAgICAgICAgIC8vIOafpeaJvuWvueW6lOeahOS7u+WKoeWunuS9kw0KICAgICAgICAgICAgICAgICAgICB2YXIgdGFzayA9IGNvbnRleHQuVGFza3MuRmlyc3RPckRlZmF1bHQodCA9PiB0LklkID09IHRhc2tJZCk7DQogICAgICAgICAgICAgICAgICAgIGlmICh0YXNrID09IG51bGwpIGNvbnRpbnVlOw0KDQogICAgICAgICAgICAgICAgICAgIC8vIOOAkOaguOW/g+ajgOafpeOAke+8muS9v+eUqOWkmumHjeetlueVpeajgOafpeS6uuWRmOS4jeWPr+eUqOaApw0KICAgICAgICAgICAgICAgICAgICB2YXIgaXNVbmF2YWlsYWJsZSA9IGF3YWl0IElzUGVyc29ubmVsVW5hdmFpbGFibGVGb3JUYXNrQXN5bmModGFzaywgcGVyc29ubmVsSWQsIGNvbnRleHQpOw0KICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzVW5hdmFpbGFibGUpDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOOAkOehrOe6puadn+OAke+8muW8uuWItuivpeWGs+etluWPmOmHj+S4ujAgKOS4jeWFgeiuuOWIhumFjSkNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb25zdHJhaW50ID0gc29sdmVyLk1ha2VDb25zdHJhaW50KDAsIDAsICQidW5hdmFpbGFibGVfe3Rhc2tJZH1fe3BlcnNvbm5lbElkfSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludC5TZXRDb2VmZmljaWVudCh2YXJpYWJsZSwgMSk7DQogICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50Q291bnQrKzsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbmVkVmFyaWFibGVzKys7DQogICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgIF9sb2dnZXIuTG9nVHJhY2UoIvCfmqsg5bqU55So5LiN5Y+v55So5oCn57qm5p2fIC0g5Lu75Yqhe1Rhc2tJZH3kurrlkZh7UGVyc29ubmVsSWR95Zyoe0RhdGV954+t5qyhe1NoaWZ0SWR95LiN5Y+v55SoIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFza0lkLCBwZXJzb25uZWxJZCwgdGFzay5Xb3JrT3JkZXJEYXRlLlRvU3RyaW5nKCJ5eXl5LU1NLWRkIiksIHRhc2suU2hpZnRJZCk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICB2YXIgZWxhcHNlZE1zID0gKERhdGVUaW1lLk5vdyAtIHN0YXJ0VGltZSkuVG90YWxNaWxsaXNlY29uZHM7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgX2xvZ2dlci5Mb2dJbmZvcm1hdGlvbigi4pyFIOS6uuWRmOePreasoeS4jeWPr+eUqOaAp+e6puadn+aehOW7uuWujOaIkCAtIOiAl+aXtu+8mntFbGFwc2VkTXN9bXPvvIzlpITnkIblj5jph4/vvJp7UHJvY2Vzc2VkQ291bnR977yM57qm5p2f5Y+Y6YeP77yae0NvbnN0cmFpbmVkQ291bnR977yM57qm5p2f5pWw6YeP77yae0NvbnN0cmFpbnRDb3VudH3vvIznuqbmnZ/njofvvJp7Q29uc3RyYWludFJhdGU6UDJ9IiwNCiAgICAgICAgICAgICAgICAgICAgZWxhcHNlZE1zLCBwcm9jZXNzZWRWYXJpYWJsZXMsIGNvbnN0cmFpbmVkVmFyaWFibGVzLCBjb25zdHJhaW50Q291bnQsIA0KICAgICAgICAgICAgICAgICAgICBwcm9jZXNzZWRWYXJpYWJsZXMgPiAwID8gKGRvdWJsZSljb25zdHJhaW5lZFZhcmlhYmxlcyAvIHByb2Nlc3NlZFZhcmlhYmxlcyA6IDApOw0KDQogICAgICAgICAgICAgICAgYXdhaXQgVGFzay5Db21wbGV0ZWRUYXNrOw0KICAgICAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50Q291bnQ7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIF9sb2dnZXIuTG9nRXJyb3IoZXgsICLwn5KlIOS6uuWRmOePreasoeS4jeWPr+eUqOaAp+e6puadn+aehOW7uuW8guW4uCIpOw0KICAgICAgICAgICAgICAgIHRocm93Ow0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgICNyZWdpb24g5Lq65ZGY5LiN5Y+v55So5oCn5qOA5p+l6L6F5Yqp5pa55rOVDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g44CQVWx0cmEgdGhpbmvmlrnms5XjgJHmo4Dmn6XkurrlkZjlnKjmjIflrprku7vliqHml7bpl7TmmK/lkKbkuI3lj6/nlKjvvIjlkIzmraXniYjmnKzvvIkNCiAgICAgICAgLy8vIOOAkOmrmOaAp+iDveiuvuiuoeOAke+8muS8mOWFiOS9v+eUqOe8k+WtmOe0ouW8le+8jOaPkOS+m+W/q+mAn+WGs+etluiDveWKmw0KICAgICAgICAvLy8g44CQ5aSa6YeN6aqM6K+B44CR77yaRGF0ZVNoaWZ0VW5hdmFpbGFibGVQZXJzb25uZWwgKyBQZXJzb25uZWxVbmF2YWlsYWJpbGl0eUluZGV45Y+M6YeN6aqM6K+BDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgYm9vbCBJc1BlcnNvbm5lbFVuYXZhaWxhYmxlRm9yVGFzayhXb3JrT3JkZXJFbnRpdHkgdGFzaywgbG9uZyBwZXJzb25uZWxJZCwgR2xvYmFsQWxsb2NhdGlvbkNvbnRleHQgY29udGV4dCkNCiAgICAgICAgew0KICAgICAgICAgICAgdHJ5DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgLy8g44CQ6aqM6K+B562W55WlMeOAkeS9v+eUqERhdGVTaGlmdFVuYXZhaWxhYmxlUGVyc29ubmVs5b+r6YCf5qOA5p+lDQogICAgICAgICAgICAgICAgdmFyIGRhdGVTaGlmdEtleSA9ICQie3Rhc2suV29ya09yZGVyRGF0ZTp5eXl5LU1NLWRkfV97dGFzay5TaGlmdElkfSI7DQogICAgICAgICAgICAgICAgaWYgKGNvbnRleHQuRGF0ZVNoaWZ0VW5hdmFpbGFibGVQZXJzb25uZWwuVHJ5R2V0VmFsdWUoZGF0ZVNoaWZ0S2V5LCBvdXQgdmFyIHVuYXZhaWxhYmxlUGVyc29ubmVsKSkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIGlmICh1bmF2YWlsYWJsZVBlcnNvbm5lbC5Db250YWlucyhwZXJzb25uZWxJZCkpDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAvLyDor6XkurrlkZjlnKjmraTml6XmnJ/nj63mrKHkuI3lj6/nlKgNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIC8vIOOAkOmqjOivgeetlueVpTLjgJHkvb/nlKhQZXJzb25uZWxVbmF2YWlsYWJpbGl0eUluZGV46L+b6KGM5Lq65ZGY57u05bqm5qOA5p+lDQogICAgICAgICAgICAgICAgaWYgKGNvbnRleHQuUGVyc29ubmVsVW5hdmFpbGFiaWxpdHlJbmRleC5UcnlHZXRWYWx1ZShwZXJzb25uZWxJZCwgb3V0IHZhciB1bmF2YWlsYWJpbGl0eUluZGV4KSkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciB0YXNrRGF0ZSA9IHRhc2suV29ya09yZGVyRGF0ZS5EYXRlOw0KICAgICAgICAgICAgICAgICAgICBpZiAodW5hdmFpbGFiaWxpdHlJbmRleC5UcnlHZXRWYWx1ZSh0YXNrRGF0ZSwgb3V0IHZhciB1bmF2YWlsYWJsZVNoaWZ0cykpDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXNrLlNoaWZ0SWQuSGFzVmFsdWUgJiYgdW5hdmFpbGFibGVTaGlmdHMuQ29udGFpbnModGFzay5TaGlmdElkLlZhbHVlKSkNCiAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8g5Lq65ZGY5Zyo6K+l5pel5pyf55qE6K+l54+t5qyh5LiN5Y+v55SoDQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8g5qOA5p+l5Y6G5Y+y5Lu75Yqh5Lq65ZGY55qE5YiG6YWNDQogICAgICAgICAgICAgICAgaWYgKGNvbnRleHQuUGVyc29ubmVsSGlzdG9yeVRhc2tzLlRyeUdldFZhbHVlKHBlcnNvbm5lbElkLCBvdXQgdmFyIGhpc3RvcnlUYXNrKSkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciB0YXNrRGF0ZSA9IHRhc2suV29ya09yZGVyRGF0ZS5EYXRlOw0KDQogICAgICAgICAgICAgICAgICAgIGlmIChoaXN0b3J5VGFzay5BbnkobSA9PiBtLldvcmtEYXRlLkRhdGUgPT0gdGFza0RhdGUpKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIOS6uuWRmOWPr+eUqA0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBfbG9nZ2VyLkxvZ1dhcm5pbmcoZXgsICLimqDvuI8g5qOA5p+l5Lq65ZGY5LiN5Y+v55So5oCn5byC5bi4IC0g5Lu75Yqhe1Rhc2tJZH3kurrlkZh7UGVyc29ubmVsSWR977yM6buY6K6k5Li65LiN5Y+v55SoIiwgDQogICAgICAgICAgICAgICAgICAgIHRhc2suSWQsIHBlcnNvbm5lbElkKTsNCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8g5byC5bi45oOF5Ya15LiL5L+d5a6I5aSE55CG77yM5qCH6K6w5Li65LiN5Y+v55SoDQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDjgJBVbHRyYSB0aGlua+aWueazleOAkeajgOafpeS6uuWRmOWcqOaMh+WumuS7u+WKoeaXtumXtOaYr+WQpuS4jeWPr+eUqO+8iOW8guatpeeJiOacrO+8iQ0KICAgICAgICAvLy8g44CQ5omp5bGV5pSv5oyB44CR77ya5Li65pyq5p2l6ZuG5oiQ5pu05aSN5p2C55qE5LiN5Y+v55So5oCn5qOA5p+l6YC76L6R6aKE55WZ5o6l5Y+jDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgYXN5bmMgVGFzazxib29sPiBJc1BlcnNvbm5lbFVuYXZhaWxhYmxlRm9yVGFza0FzeW5jKFdvcmtPcmRlckVudGl0eSB0YXNrLCBsb25nIHBlcnNvbm5lbElkLCBHbG9iYWxBbGxvY2F0aW9uQ29udGV4dCBjb250ZXh0KQ0KICAgICAgICB7DQogICAgICAgICAgICAvLyDnm67liY3nm7TmjqXosIPnlKjlkIzmraXniYjmnKzvvIzkv53mjIHlvILmraXmjqXlj6Pku6Xkvr/mnKrmnaXmianlsZUNCiAgICAgICAgICAgIGF3YWl0IFRhc2suQ29tcGxldGVkVGFzazsNCiAgICAgICAgICAgIHJldHVybiBJc1BlcnNvbm5lbFVuYXZhaWxhYmxlRm9yVGFzayh0YXNrLCBwZXJzb25uZWxJZCwgY29udGV4dCk7DQogICAgICAgIH0NCg0KICAgICAgICAjZW5kcmVnaW9uDQogICAgfQ0KDQogICAgLy8vIDxzdW1tYXJ5Pg0KICAgIC8vLyDkurrlkZjku7vliqHnn6npmLUgLSDmlK/mjIHpq5jmlYjnmoTlhbPogZTmn6Xor6INCiAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgIHB1YmxpYyBjbGFzcyBQZXJzb25uZWxUYXNrTWF0cml4DQogICAgew0KICAgICAgICBwdWJsaWMgRGljdGlvbmFyeTxsb25nLCBMaXN0PFdvcmtPcmRlckVudGl0eT4+IFBlcnNvbm5lbFRhc2tNYXAgeyBnZXQ7IHNldDsgfSA9IG5ldygpOw0KICAgICAgICBwdWJsaWMgRGljdGlvbmFyeTxsb25nLCBMaXN0PEdsb2JhbFBlcnNvbm5lbEluZm8+PiBUYXNrUGVyc29ubmVsTWFwIHsgZ2V0OyBzZXQ7IH0gPSBuZXcoKTsNCiAgICB9DQoNCiAgICAvLy8gPHN1bW1hcnk+DQogICAgLy8vIOaXtumXtOeql+WPo+WumuS5iQ0KICAgIC8vLyA8L3N1bW1hcnk+DQogICAgcHVibGljIGNsYXNzIFRpbWVXaW5kb3cgOiBJRXF1YXRhYmxlPFRpbWVXaW5kb3c+DQogICAgew0KICAgICAgICBwdWJsaWMgRGF0ZVRpbWUgRGF0ZSB7IGdldDsgc2V0OyB9DQogICAgICAgIHB1YmxpYyBsb25nIFNoaWZ0SWQgeyBnZXQ7IHNldDsgfQ0KICAgICAgICBwdWJsaWMgVGltZVNwYW4gU3RhcnRUaW1lIHsgZ2V0OyBzZXQ7IH0NCg0KICAgICAgICBwdWJsaWMgYm9vbCBFcXVhbHMoVGltZVdpbmRvdyBvdGhlcikNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKG90aGVyID09IG51bGwpIHJldHVybiBmYWxzZTsNCiAgICAgICAgICAgIHJldHVybiBEYXRlLkRhdGUgPT0gb3RoZXIuRGF0ZS5EYXRlICYmIA0KICAgICAgICAgICAgICAgICAgIFNoaWZ0SWQgPT0gb3RoZXIuU2hpZnRJZCAmJiANCiAgICAgICAgICAgICAgICAgICBTdGFydFRpbWUgPT0gb3RoZXIuU3RhcnRUaW1lOw0KICAgICAgICB9DQoNCiAgICAgICAgcHVibGljIG92ZXJyaWRlIGJvb2wgRXF1YWxzKG9iamVjdCBvYmopID0+IEVxdWFscyhvYmogYXMgVGltZVdpbmRvdyk7DQogICAgICAgIA0KICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgaW50IEdldEhhc2hDb2RlKCkgPT4gSGFzaENvZGUuQ29tYmluZShEYXRlLkRhdGUsIFNoaWZ0SWQsIFN0YXJ0VGltZSk7DQogICAgfQ0KDQogICAgLy8vIDxzdW1tYXJ5Pg0KICAgIC8vLyDlhrLnqoHkuKXph43nqIvluqbmnprkuL4NCiAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgIHB1YmxpYyBlbnVtIENvbmZsaWN0U2V2ZXJpdHkNCiAgICB7DQogICAgICAgIE5vbmUgPSAwLCAgICAgICAgLy8g5peg5Yay56qBDQogICAgICAgIExvdyA9IDEsICAgICAgICAgLy8g6L275b6u5Yay56qBDQogICAgICAgIE1lZGl1bSA9IDIsICAgICAgLy8g5Lit562J5Yay56qBDQogICAgICAgIEhpZ2ggPSAzLCAgICAgICAgLy8g5Lil6YeN5Yay56qBDQogICAgICAgIENyaXRpY2FsID0gNCAgICAgLy8g5YWz6ZSu5Yay56qBDQogICAgfQ0KDQogICAgLy8vIDxzdW1tYXJ5Pg0KICAgIC8vLyBXb3JrT3JkZXJFbnRpdHnmianlsZXmlrnms5UgLSDkuLpMaW5lYXJQcm9ncmFtbWluZ0VuZ2luZeaPkOS+m+i+heWKqeWKn+iDvQ0KICAgIC8vLyA8L3N1bW1hcnk+DQogICAgcHVibGljIHN0YXRpYyBjbGFzcyBXb3JrT3JkZXJFbnRpdHlFeHRlbnNpb25zDQogICAgew0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDjgJDmt7Hluqblrp7njrDjgJHkuLrpqozor4Hnm67nmoTlhYvpmoZXb3JrT3JkZXJFbnRpdHkNCiAgICAgICAgLy8vIOOAkOS4muWKoeaAneiAg+OAke+8muWcqOe6v+aAp+inhOWIkumqjOivgei/h+eoi+S4re+8jOmcgOimgeaooeaLn+WIhumFjeeahOS4tOaXtuS7u+WKoeWvueixoQ0KICAgICAgICAvLy8g44CQ5oqA5pyv6KaB54K544CR77ya5LuF5aSN5Yi26aqM6K+B5omA6ZyA55qE5YWz6ZSu5a2X5q6177yM6YG/5YWN5pW05L2T5a+56LGh5YWL6ZqG55qE5oCn6IO95byA6ZSADQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyBzdGF0aWMgV29ya09yZGVyRW50aXR5IENsb25lRm9yVmFsaWRhdGlvbih0aGlzIFdvcmtPcmRlckVudGl0eSBvcmlnaW5hbCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuIG5ldyBXb3JrT3JkZXJFbnRpdHkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBJZCA9IG9yaWdpbmFsLklkLA0KICAgICAgICAgICAgICAgIFByb2plY3ROdW1iZXIgPSBvcmlnaW5hbC5Qcm9qZWN0TnVtYmVyLA0KICAgICAgICAgICAgICAgIFByb2plY3RDYXRlZ29yeSA9IG9yaWdpbmFsLlByb2plY3RDYXRlZ29yeSwNCiAgICAgICAgICAgICAgICBTaGlmdElkID0gb3JpZ2luYWwuU2hpZnRJZCwNCiAgICAgICAgICAgICAgICBTaGlmdENvZGUgPSBvcmlnaW5hbC5TaGlmdENvZGUsDQogICAgICAgICAgICAgICAgU2hpZnROYW1lID0gb3JpZ2luYWwuU2hpZnROYW1lLA0KICAgICAgICAgICAgICAgIFdvcmtPcmRlckNvZGUgPSBvcmlnaW5hbC5Xb3JrT3JkZXJDb2RlLA0KICAgICAgICAgICAgICAgIFdvcmtPcmRlckRhdGUgPSBvcmlnaW5hbC5Xb3JrT3JkZXJEYXRlLA0KICAgICAgICAgICAgICAgIFByaW9yaXR5ID0gb3JpZ2luYWwuUHJpb3JpdHksDQogICAgICAgICAgICAgICAgVXJnZW5jeSA9IG9yaWdpbmFsLlVyZ2VuY3ksDQogICAgICAgICAgICAgICAgQ29tcGxleGl0eUxldmVsID0gb3JpZ2luYWwuQ29tcGxleGl0eUxldmVsLA0KICAgICAgICAgICAgICAgIEVzdGltYXRlZEhvdXJzID0gb3JpZ2luYWwuRXN0aW1hdGVkSG91cnMsDQogICAgICAgICAgICAgICAgU3RhdHVzID0gb3JpZ2luYWwuU3RhdHVzLA0KICAgICAgICAgICAgICAgIEFzc2lnbmVkUGVyc29ubmVsSWQgPSBvcmlnaW5hbC5Bc3NpZ25lZFBlcnNvbm5lbElkLCAvLyDov5nkuKrlsIbooqvkv67mlLnkuLrmqKHmi5/liIbphY3nmoTkurrlkZhJRA0KICAgICAgICAgICAgICAgIC8vIOWFs+iBlOWvueixoeS5n+mcgOimgeWkjeWItg0KICAgICAgICAgICAgICAgIFNoaWZ0RW50aXR5ID0gb3JpZ2luYWwuU2hpZnRFbnRpdHksDQogICAgICAgICAgICAgICAgUHJvY2Vzc0VudGl0eSA9IG9yaWdpbmFsLlByb2Nlc3NFbnRpdHksDQogICAgICAgICAgICAgICAgV29ya09yZGVyRkxQZXJzb25uZWxzID0gb3JpZ2luYWwuV29ya09yZGVyRkxQZXJzb25uZWxzDQogICAgICAgICAgICB9Ow0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8vIDxzdW1tYXJ5Pg0KICAgIC8vLyDop6PotKjph4/mjIfmoIcNCiAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgIHB1YmxpYyBjbGFzcyBTb2x1dGlvblF1YWxpdHlNZXRyaWNzDQogICAgew0KICAgICAgICBwdWJsaWMgZG91YmxlIFRhc2tDb21wbGV0ZW5lc3NSYXRlIHsgZ2V0OyBzZXQ7IH0NCiAgICAgICAgcHVibGljIGRvdWJsZSBUaW1lQ29uZmxpY3RSYXRlIHsgZ2V0OyBzZXQ7IH0NCiAgICAgICAgcHVibGljIGRvdWJsZSBMb2FkQmFsYW5jZVNjb3JlIHsgZ2V0OyBzZXQ7IH0NCiAgICAgICAgcHVibGljIGRvdWJsZSBQZXJzb25uZWxVdGlsaXphdGlvblJhdGUgeyBnZXQ7IHNldDsgfQ0KICAgICAgICBwdWJsaWMgZG91YmxlIENvbnN0cmFpbnRTYXRpc2ZhY3Rpb25SYXRlIHsgZ2V0OyBzZXQ7IH0NCiAgICAgICAgcHVibGljIExpc3Q8c3RyaW5nPiBWaW9sYXRpb25EZXRhaWxzIHsgZ2V0OyBzZXQ7IH0gPSBuZXcoKTsNCiAgICB9DQp9"}]}}
{"timestamp":"2025-09-22T13:57:07.349Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:57:09.128Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:57:10.808Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:57:13.799Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:57:16.501Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:57:20.978Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:57:53.272Z","type":"response_item","payload":{"type":"message","role":"user","content":[{"type":"input_text","text":"# Context from my IDE setup:\n\n## Active file: NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\n\n## Open tabs:\n- LinearProgrammingEngine.cs: NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\n\n## My request for Codex:\nsay hi\n"}]}}
{"timestamp":"2025-09-22T13:57:53.272Z","type":"event_msg","payload":{"type":"user_message","message":"# Context from my IDE setup:\n\n## Active file: NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\n\n## Open tabs:\n- LinearProgrammingEngine.cs: NPP.SmartSchedue.Api/Services/Integration/Algorithms/LinearProgrammingEngine.cs\n\n## My request for Codex:\nsay hi\n","kind":"plain"}}
{"timestamp":"2025-09-22T13:57:53.272Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:57:59.716Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:58:00.804Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:58:02.714Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:58:05.099Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}
{"timestamp":"2025-09-22T13:58:09.028Z","type":"turn_context","payload":{"cwd":"c:\\GitCode\\paiban","approval_policy":"never","sandbox_policy":{"mode":"danger-full-access"},"model":"gpt-5-codex","effort":"high","summary":"auto"}}