diff --git a/delay-list-skill/SKILL.md b/delay-list-skill/SKILL.md index e6a9db1..5633607 100644 --- a/delay-list-skill/SKILL.md +++ b/delay-list-skill/SKILL.md @@ -1,226 +1 @@ ---- -name: Delay Processor — Daily Traffic Team Workflow** -description: "Daily delay list processing skill for the traffic team. Fetches the delay list via API, categorizes orders, auto-snoozes packaged orders from known suppliers, sends bundled supplier emails, notifies customers, logs complaints, and updates tracking. Use this skill whenever the user mentions: delay list, delayed orders, dispatch delays, snooze orders, supplier outreach, delay processing, traffic team workflow, daily delays, or order not shipped. Also trigger when the user asks to process delays or check today's delays." - - - -**Overview** - -Each day, orders that have surpassed their expected dispatch date appear on the delay list — whether still in production or packaged. This skill processes that list systematically: auto-snoozing where safe, emailing suppliers (bundled per supplier), notifying customers, logging complaints, and flagging edge cases for human review. - -**Scale**: \~4,000 orders/day, delay list can be extensive. - ---- - -## **Inputs** - -1. **Delay List** — Fetched via the Delay List API (not a file upload). The API returns the current delay list with the following fields per order: - - * `Order` (order number) - * `id_order_detail` (order line ID) - * `Assigned` (team member or blank) - * `Status` (Open, Customer Informed, Checking, etc.) - * `Delay Reason` (No delay reason given, Email Sent to Supplier, etc.) - * `New Target Dispatch` (updated date if any) - * `Product` (product type/SKU) - * `Supplier` (supplier name) - * `Sales Price` - * `State` (production/packaging state — see values below) - * `Delay` (days past target dispatch) - * `Carrier` (carrier name if available) - * `Tracking Link` (if available) - * `Target Dispatch Date` - * `Actual Dispatched Date` - * `Latest Delivery Date` - * `shop_country_code` - * `Shop_name` - * `Supplier Order number` - * `Postcode` -2. **Operator context** — Any special notes for the day (supplier outages, holidays, known issues). - -3. **Supplier Complaint Classification Spreadsheet** — Reference for whether a supplier is volume-based (zero cost complaint) or discount-based (10% discount complaint). Read from `references/supplier-classification.md` if available. - ---- - -## **Processing Workflow — Execution Order** - -Process in this exact order to ensure data is fresh for downstream decisions: - -### **Step 1: Fetch & Validate the Delay List** - -* Call the Delay List API to retrieve today's current delay list -* Validate expected fields are present in the API response -* Flag any records with missing critical data (Order, Supplier, State) for MANUAL\_REVIEW -* Calculate correct delay days: business days between Target Dispatch Date and today (note: the system's built-in delay count can be incorrect — see Edge Cases) - -### **Step 2: Auto-Snooze Packaged Orders (High Confidence)** - -**Criteria — ALL must match:** - -| Field | Required Value | -| ----- | ----- | -| **State** | `Your order has been packaged` | -| **Target Dispatch Date** | Previous working day | -| **Carrier** | One of: `UPS-UPS_STANDARD`, `UPS-UPS_SAVER`, `DPDINT-STANDARD_UK`, `DPDINT-STANDARD`, `CORREOS-STANDARD` | -| **Tracking Link** | Must be present (non-empty) | -| **Supplier** | One of the approved auto-snooze suppliers (see list below) | - - -**Attention** Always pass the full raw API response into the filter. Never manually subset the data before filtering. Validate record counts before executing any snoozes. - -**Approved Auto-Snooze Suppliers:** - -* De Groot Drukkerij B.V. -* The Postermen -* Intervlag -* Vila Etiketten -* VG Print BV -* Zalsman BV -* Oakdene Services -* I print 1925 -* Digiforce -* Enson -* Probo -* Promio -* Inpromo -* Today's Media -* Pressing -* Drukkerij Van As - -**Action**: If you want to snooze an order call n8n-mcp snooze-order workflow. -with a body like this: -{ - orderDetailIds: [ - %id_orderdetail% - ] - "hours" : "12" -} - - -**Confidence:** If ALL criteria match exactly → auto-execute (99%+ confidence). If any field is ambiguous or missing → MANUAL\_REVIEW. - ---- - -## **Logging & Tracking** - -**Every action must be logged. No exceptions.** - -### **Processing Log** - -Maintain a structured log (CSV) saved to the outputs directory with the following fields per order processed: - -| Field | Description | -| ----- | ----- | -| `timestamp` | ISO 8601 timestamp of action | -| `order_id` | Order number | -| `id_order_detail` | Order line ID | -| `supplier` | Supplier name | -| `product` | Product type | -| `state` | Order state at time of processing | -| `delay_days` | Calculated delay in business days | -| `category` | Action category (see list below) | -| `action_taken` | Specific action executed | -| `confidence` | Confidence percentage | -| `auto_or_manual` | AUTO / FLAGGED\_FOR\_REVIEW | -| `human_decision` | Operator decision if flagged (blank if auto) | -| `batch_number` | Batch ID | -| `status` | SUCCESS / FAILED / PENDING\_REVIEW | -| `error_details` | Error info if failed | -| `email_sent_to` | Supplier/customer email triggered | -| `email_bundled_with` | Other order IDs in same supplier email | -| `complaint_logged` | true/false | -| `complaint_type` | Carrier / Supplier | -| `complaint_cost` | Zero / 10% discount | -| `snooze_hours` | Hours snoozed | -| `notes` | Additional context | - -**Action categories:** `SNOOZE` | `SUPPLIER_EMAIL` | `CUSTOMER_NOTIFY` | `COMPLAINT_CARRIER` | `COMPLAINT_SUPPLIER` | `TRACKING_UPDATE` | `STATUS_UPDATE` | `LABEL_REISSUE` | `MANUAL_REVIEW` - -### **Daily Summary Report** - -Generate at end of processing and save as a file: - -* Total orders on delay list and total processed -* Breakdown by action category (counts and percentages) -* Auto-processed vs. flagged for review (counts) -* Supplier emails sent — count and list of suppliers contacted -* Customer notifications sent — count -* Complaints logged — carrier vs. supplier, with cost breakdown -* Orders snoozed — count and average snooze duration -* Failed actions with details -* Pending manual review — full list with proposed actions -* Top delayed suppliers — ranked by number of delayed orders -* Orders delayed 3+ days — highlighted for urgency - ---- - -## **MCP & API Integration Points** - -| Action | Integration | Template/Endpoint | -| ----- | ----- | ----- | -| Fetch delay list | Delay List API | GET current delay list | -| Snooze order | Order Management MCP | Snooze by configurable hours (default 12h) | - -Before processing begins, verify all required MCP servers and API endpoints are accessible. If any integration is unavailable, flag ALL affected orders for MANUAL\_REVIEW rather than failing silently. - ---- - -## **Configuration** - -These defaults can be overridden by the operator at the start of each run: - -``` -snooze_default_hours: 12 -max_batch_size: 100 -confidence_threshold: 99 # Percentage — below this → MANUAL_REVIEW -customer_notify_after_days: 2 # Notify customer after X business days delayed -supplier_email_after_days: 1 # Email supplier after X days with no movement -auto_snooze_carriers: - - UPS-UPS_STANDARD - - UPS-UPS_SAVER - - DPDINT-STANDARD_UK - - DPDINT-STANDARD -supplier_specific_processes: - probo: on_hold - flyeralarm: on_hold - masterprint: completed -``` - ---- - -## **Edge Cases & Known Issues** - -1. **Incorrect delay day calculation** — The system sometimes shows different delay counts for orders with the same dispatch date. Always recalculate: business days between Target Dispatch Date and today. - -2. **Sales price shows full order, not order-line** — The delay list may show full order price. Be aware when assessing value thresholds. - -3. **False delays from Probo** — Orders shipped together across multiple order lines trigger false delays. When Probo processes activate, always check if lines were shipped together before acting. - -4. **Duplicate supplier emails** — The bundling rule is critical. Always deduplicate and group before sending. Check if a supplier was already emailed today. - -5. **Tracking lag vs. genuine delay** — Packaged orders with tracking from approved carriers/suppliers are most often tracking lag. Auto-snooze handles this, but if an order reappears after multiple snoozes, escalate to MANUAL\_REVIEW. - -6. **Orders assigned to team members** — If an order has an `Assigned` value, it means someone is already working on it. Consider skipping or noting this in the review queue. - -7. **Incomplete order evaluation when filtering** -When filtering the delay list, always feed the raw API response directly into the filter logic — never manually reconstruct or subset the data. After filtering, validate that: Every order with statename = "Your order has been packaged" appears in either the match list or the reject list -The count of (matches + rejects) equals the total number of packaged orders in the raw response - -8. **The Posterman Exception** -When the supplier is **The Postermen**, the carrier field may be any value when validating snooze applicability. All other matching criteria still apply as normal. - - - ---- - -## **Example Run** - -``` -Operator: "Process today's delay list. No special notes." - -Step 1: Fetched delay list via API → 347 delayed orders. 4 records missing data → MANUAL_REVIEW. -Step 2: 89 orders match auto-snooze criteria → Snoozed 12h. Batch 1/1 (89). All succeeded - -SUMMARY: 343 processed | 16 manual review | 0 failures -Logs saved: delay_log_2026-02-12.csv, summary_2026-02-12.md -``` +LS0tCm5hbWU6IGRlbGF5LWxpc3QtcHJvY2Vzc29yCmRlc2NyaXB0aW9uOiAiRGFpbHkgZGVsYXkgbGlzdCBwcm9jZXNzaW5nIHNraWxsIGZvciB0aGUgdHJhZmZpYyB0ZWFtLiBGZXRjaGVzIHRoZSBkZWxheSBsaXN0IHZpYSBBUEksIGNhdGVnb3JpemVzIG9yZGVycywgYXV0by1zbm9vemVzIHBhY2thZ2VkIG9yZGVycyBmcm9tIGtub3duIHN1cHBsaWVycywgc2VuZHMgYnVuZGxlZCBzdXBwbGllciBlbWFpbHMsIG5vdGlmaWVzIGN1c3RvbWVycywgbG9ncyBjb21wbGFpbnRzLCBhbmQgdXBkYXRlcyB0cmFja2luZy4gVXNlIHRoaXMgc2tpbGwgd2hlbmV2ZXIgdGhlIHVzZXIgbWVudGlvbnM6IGRlbGF5IGxpc3QsIGRlbGF5ZWQgb3JkZXJzLCBkaXNwYXRjaCBkZWxheXMsIHNub296ZSBvcmRlcnMsIHN1cHBsaWVyIG91dHJlYWNoLCBkZWxheSBwcm9jZXNzaW5nLCB0cmFmZmljIHRlYW0gd29ya2Zsb3csIGRhaWx5IGRlbGF5cywgb3Igb3JkZXIgbm90IHNoaXBwZWQuIEFsc28gdHJpZ2dlciB3aGVuIHRoZSB1c2VyIGFza3MgdG8gcHJvY2VzcyBkZWxheXMgb3IgY2hlY2sgdG9kYXkncyBkZWxheXMuIgotLS0KCgoqKk92ZXJ2aWV3KioKCkVhY2ggZGF5LCBvcmRlcnMgdGhhdCBoYXZlIHN1cnBhc3NlZCB0aGVpciBleHBlY3RlZCBkaXNwYXRjaCBkYXRlIGFwcGVhciBvbiB0aGUgZGVsYXkgbGlzdCDigJQgd2hldGhlciBzdGlsbCBpbiBwcm9kdWN0aW9uIG9yIHBhY2thZ2VkLiBUaGlzIHNraWxsIHByb2Nlc3NlcyB0aGF0IGxpc3Qgc3lzdGVtYXRpY2FsbHk6IGF1dG8tc25vb3ppbmcgd2hlcmUgc2FmZSwgZW1haWxpbmcgc3VwcGxpZXJzIChidW5kbGVkIHBlciBzdXBwbGllciksIG5vdGlmeWluZyBjdXN0b21lcnMsIGxvZ2dpbmcgY29tcGxhaW50cywgYW5kIGZsYWdnaW5nIGVkZ2UgY2FzZXMgZm9yIGh1bWFuIHJldmlldy4KCioqU2NhbGUqKjogXH40LDAwMCBvcmRlcnMvZGF5LCBkZWxheSBsaXN0IGNhbiBiZSBleHRlbnNpdmUuCgotLS0KCiMjICoqSW5wdXRzKioKCjEuICoqRGVsYXkgTGlzdCoqIOKAlCBGZXRjaGVkIHZpYSB0aGUgRGVsYXkgTGlzdCBBUEkgKG5vdCBhIGZpbGUgdXBsb2FkKS4gVGhlIEFQSSByZXR1cm5zIHRoZSBjdXJyZW50IGRlbGF5IGxpc3Qgd2l0aCB0aGUgZm9sbG93aW5nIGZpZWxkcyBwZXIgb3JkZXI6CgogICAqIGBPcmRlcmAgKG9yZGVyIG51bWJlcikKICAgKiBgaWRfb3JkZXJfZGV0YWlsYCAob3JkZXIgbGluZSBJRCkKICAgKiBgQXNzaWduZWRgICh0ZWFtIG1lbWJlciBvciBibGFuaykKICAgKiBgU3RhdHVzYCAoT3BlbiwgQ3VzdG9tZXIgSW5mb3JtZWQsIENoZWNraW5nLCBldGMuKQogICAqIGBEZWxheSBSZWFzb25gIChObyBkZWxheSByZWFzb24gZ2l2ZW4sIEVtYWlsIFNlbnQgdG8gU3VwcGxpZXIsIGV0Yy4pCiAgICogYE5ldyBUYXJnZXQgRGlzcGF0Y2hgICh1cGRhdGVkIGRhdGUgaWYgYW55KQogICAqIGBQcm9kdWN0YCAocHJvZHVjdCB0eXBlL1NLVSkKICAgKiBgU3VwcGxpZXJgIChzdXBwbGllciBuYW1lKQogICAqIGBTYWxlcyBQcmljZWAKICAgKiBgU3RhdGVgIChwcm9kdWN0aW9uL3BhY2thZ2luZyBzdGF0ZSDigJQgc2VlIHZhbHVlcyBiZWxvdykKICAgKiBgRGVsYXlgIChkYXlzIHBhc3QgdGFyZ2V0IGRpc3BhdGNoKQogICAqIGBDYXJyaWVyYCAoY2FycmllciBuYW1lIGlmIGF2YWlsYWJsZSkKICAgKiBgVHJhY2tpbmcgTGlua2AgKGlmIGF2YWlsYWJsZSkKICAgKiBgVGFyZ2V0IERpc3BhdGNoIERhdGVgCiAgICogYEFjdHVhbCBEaXNwYXRjaGVkIERhdGVgCiAgICogYExhdGVzdCBEZWxpdmVyeSBEYXRlYAogICAqIGBzaG9wX2NvdW50cnlfY29kZWAKICAgKiBgU2hvcF9uYW1lYAogICAqIGBTdXBwbGllciBPcmRlciBudW1iZXJgCiAgICogYFBvc3Rjb2RlYAoyLiAqKk9wZXJhdG9yIGNvbnRleHQqKiDigJQgQW55IHNwZWNpYWwgbm90ZXMgZm9yIHRoZSBkYXkgKHN1cHBsaWVyIG91dGFnZXMsIGhvbGlkYXlzLCBrbm93biBpc3N1ZXMpLgoKMy4gKipTdXBwbGllciBDb21wbGFpbnQgQ2xhc3NpZmljYXRpb24gU3ByZWFkc2hlZXQqKiDigJQgUmVmZXJlbmNlIGZvciB3aGV0aGVyIGEgc3VwcGxpZXIgaXMgdm9sdW1lLWJhc2VkICh6ZXJvIGNvc3QgY29tcGxhaW50KSBvciBkaXNjb3VudC1iYXNlZCAoMTAlIGRpc2NvdW50IGNvbXBsYWludCkuIFJlYWQgZnJvbSBgcmVmZXJlbmNlcy9zdXBwbGllci1jbGFzc2lmaWNhdGlvbi5tZGAgaWYgYXZhaWxhYmxlLgoKLS0tCgojIyAqKlByb2Nlc3NpbmcgV29ya2Zsb3cg4oCUIEV4ZWN1dGlvbiBPcmRlcioqCgpQcm9jZXNzIGluIHRoaXMgZXhhY3Qgb3JkZXIgdG8gZW5zdXJlIGRhdGEgaXMgZnJlc2ggZm9yIGRvd25zdHJlYW0gZGVjaXNpb25zOgoKIyMjICoqU3RlcCAxOiBGZXRjaCAmIFZhbGlkYXRlIHRoZSBEZWxheSBMaXN0KioKCiogQ2FsbCB0aGUgRGVsYXkgTGlzdCBBUEkgdG8gcmV0cmlldmUgdG9kYXkncyBjdXJyZW50IGRlbGF5IGxpc3QKKiBWYWxpZGF0ZSBleHBlY3RlZCBmaWVsZHMgYXJlIHByZXNlbnQgaW4gdGhlIEFQSSByZXNwb25zZQoqIEZsYWcgYW55IHJlY29yZHMgd2l0aCBtaXNzaW5nIGNyaXRpY2FsIGRhdGEgKE9yZGVyLCBTdXBwbGllciwgU3RhdGUpIGZvciBNQU5VQUxcX1JFVklFVwoqIENhbGN1bGF0ZSBjb3JyZWN0IGRlbGF5IGRheXM6IGJ1c2luZXNzIGRheXMgYmV0d2VlbiBUYXJnZXQgRGlzcGF0Y2ggRGF0ZSBhbmQgdG9kYXkgKG5vdGU6IHRoZSBzeXN0ZW0ncyBidWlsdC1pbiBkZWxheSBjb3VudCBjYW4gYmUgaW5jb3JyZWN0IOKAlCBzZWUgRWRnZSBDYXNlcykKCiMjIyAqKlN0ZXAgMjogQXV0by1Tbm9vemUgUGFja2FnZWQgT3JkZXJzIChIaWdoIENvbmZpZGVuY2UpKioKCioqQ3JpdGVyaWEg4oCUIEFMTCBtdXN0IG1hdGNoOioqCgp8IEZpZWxkIHwgUmVxdWlyZWQgVmFsdWUgfAp8IC0tLS0tIHwgLS0tLS0gfAp8ICoqU3RhdGUqKiB8IGBZb3VyIG9yZGVyIGhhcyBiZWVuIHBhY2thZ2VkYCB8CnwgKipUYXJnZXQgRGlzcGF0Y2ggRGF0ZSoqIHwgUHJldmlvdXMgd29ya2luZyBkYXkgfAp8ICoqQ2FycmllcioqIHwgT25lIG9mOiBgVVBTLVVQU19TVEFOREFSRGAsIGBVUFMtVVBTX1NBVkVSYCwgYERQRElOVC1TVEFOREFSRF9VS2AsIGBEUERJTlQtU1RBTkRBUkRgLCBgQ09SUkVPUy1TVEFOREFSRGAgfAp8ICoqVHJhY2tpbmcgTGluayoqIHwgTXVzdCBiZSBwcmVzZW50IChub24tZW1wdHkpIHwKfCAqKlN1cHBsaWVyKiogfCBPbmUgb2YgdGhlIGFwcHJvdmVkIGF1dG8tc25vb3plIHN1cHBsaWVycyAoc2VlIGxpc3QgYmVsb3cpIHwKCgoqKkF0dGVudGlvbioqIEFsd2F5cyBwYXNzIHRoZSBmdWxsIHJhdyBBUEkgcmVzcG9uc2UgaW50byB0aGUgZmlsdGVyLiBOZXZlciBtYW51YWxseSBzdWJzZXQgdGhlIGRhdGEgYmVmb3JlIGZpbHRlcmluZy4gVmFsaWRhdGUgcmVjb3JkIGNvdW50cyBiZWZvcmUgZXhlY3V0aW5nIGFueSBzbm9vemVzLgoKKipBcHByb3ZlZCBBdXRvLVNub296ZSBTdXBwbGllcnM6KioKCiogRGUgR3Jvb3QgRHJ1a2tlcmlqIEIuVi4KKiBUaGUgUG9zdGVybWVuCiogSW50ZXJ2bGFnCiogVmlsYSBFdGlrZXR0ZW4KKiBWRyBQcmludCBCVgoqIFphbHNtYW4gQlYKKiBPYWtkZW5lIFNlcnZpY2VzCiogSSBwcmludCAxOTI1CiogRGlnaWZvcmNlCiogRW5zb24KKiBQcm9ibwoqIFByb21pbwoqIElucHJvbW8KKiBUb2RheSdzIE1lZGlhCiogUHJlc3NpbmcKKiBEcnVra2VyaWogVmFuIEFzCiogT2FrZGVuZSBTZXJ2aWNlcwoKKipBY3Rpb24qKjogSWYgeW91IHdhbnQgdG8gc25vb3plIGFuIG9yZGVyIGNhbGwgbjhuLW1jcCBzbm9vemUtb3JkZXIgd29ya2Zsb3cuCndpdGggYSBib2R5IGxpa2UgdGhpczoKewogIG9yZGVyRGV0YWlsSWQ6ICVpZF9vcmRlcmRldGFpbCUKfQoKCioqQ29uZmlkZW5jZToqKiBJZiBBTEwgY3JpdGVyaWEgbWF0Y2ggZXhhY3RseSDihpIgYXV0by1leGVjdXRlICg5OSUrIGNvbmZpZGVuY2UpLiBJZiBhbnkgZmllbGQgaXMgYW1iaWd1b3VzIG9yIG1pc3Npbmcg4oaSIE1BTlVBTFxfUkVWSUVXLgoKLS0tCgojIyAqKkxvZ2dpbmcgJiBUcmFja2luZyoqCgoqKkV2ZXJ5IGFjdGlvbiBtdXN0IGJlIGxvZ2dlZC4gTm8gZXhjZXB0aW9ucy4qKgoKIyMjICoqUHJvY2Vzc2luZyBMb2cqKgoKTWFpbnRhaW4gYSBzdHJ1Y3R1cmVkIGxvZyAoQ1NWKSBzYXZlZCB0byB0aGUgb3V0cHV0cyBkaXJlY3Rvcnkgd2l0aCB0aGUgZm9sbG93aW5nIGZpZWxkcyBwZXIgb3JkZXIgcHJvY2Vzc2VkOgoKfCBGaWVsZCB8IERlc2NyaXB0aW9uIHwKfCAtLS0tLSB8IC0tLS0tIHwKfCBgdGltZXN0YW1wYCB8IElTTyA4NjAxIHRpbWVzdGFtcCBvZiBhY3Rpb24gfAp8IGBvcmRlcl9pZGAgfCBPcmRlciBudW1iZXIgfAp8IGBpZF9vcmRlcl9kZXRhaWxgIHwgT3JkZXIgbGluZSBJRCB8CnwgYHN1cHBsaWVyYCB8IFN1cHBsaWVyIG5hbWUgfAp8IGBwcm9kdWN0YCB8IFByb2R1Y3QgdHlwZSB8CnwgYHN0YXRlYCB8IE9yZGVyIHN0YXRlIGF0IHRpbWUgb2YgcHJvY2Vzc2luZyB8CnwgYGRlbGF5X2RheXNgIHwgQ2FsY3VsYXRlZCBkZWxheSBpbiBidXNpbmVzcyBkYXlzIHwKfCBgY2F0ZWdvcnlgIHwgQWN0aW9uIGNhdGVnb3J5IChzZWUgbGlzdCBiZWxvdykgfAp8IGBhY3Rpb25fdGFrZW5gIHwgU3BlY2lmaWMgYWN0aW9uIGV4ZWN1dGVkIHwKfCBgY29uZmlkZW5jZWAgfCBDb25maWRlbmNlIHBlcmNlbnRhZ2UgfAp8IGBhdXRvX29yX21hbnVhbGAgfCBBVVRPIC8gRkxBR0dFRFxfRk9SXF9SRVZJRVcgfAp8IGBodW1hbl9kZWNpc2lvbmAgfCBPcGVyYXRvciBkZWNpc2lvbiBpZiBmbGFnZ2VkIChibGFuayBpZiBhdXRvKSB8CnwgYGJhdGNoX251bWJlcmAgfCBCYXRjaCBJRCB8CnwgYHN0YXR1c2AgfCBTVUNDRVNTIC8gRkFJTEVEIC8gUEVORElOR1xfUkVWSUVXIHwKfCBgZXJyb3JfZGV0YWlsc2AgfCBFcnJvciBpbmZvIGlmIGZhaWxlZCB8CnwgYGVtYWlsX3NlbnRfdG9gIHwgU3VwcGxpZXIvY3VzdG9tZXIgZW1haWwgdHJpZ2dlcmVkIHwKfCBgZW1haWxfYnVuZGxlZF93aXRoYCB8IE90aGVyIG9yZGVyIElEcyBpbiBzYW1lIHN1cHBsaWVyIGVtYWlsIHwKfCBgY29tcGxhaW50X2xvZ2dlZGAgfCB0cnVlL2ZhbHNlIHwKfCBgY29tcGxhaW50X3R5cGVgIHwgQ2FycmllciAvIFN1cHBsaWVyIHwKfCBgY29tcGxhaW50X2Nvc3RgIHwgWmVybyAvIDEwJSBkaXNjb3VudCB8CnwgYHNub296ZV9ob3Vyc2AgfCBIb3VycyBzbm9vemVkIHwKfCBgbm90ZXNgIHwgQWRkaXRpb25hbCBjb250ZXh0IHwKCioqQWN0aW9uIGNhdGVnb3JpZXM6KiogYFNOT09aRWAgfCBgU1VQUExJRVJfRU1BSUxgIHwgYENVU1RPTUVSX05PVElGWWAgfCBgQ09NUExBSU5UX0NBUlJJRVJgIHwgYENPTVBMQUlOVF9TVVBQTElFUmAgfCBgVFJBQ0tJTkdfVVBEQVRFYCB8IGBTVEFUVVNfVVBEQVRFYCB8IGBMQUJFTF9SRUlTU1VFYCB8IGBNQU5VQUxfUkVWSUVXYAoKIyMjICoqRGFpbHkgU3VtbWFyeSBSZXBvcnQqKgoKR2VuZXJhdGUgYXQgZW5kIG9mIHByb2Nlc3NpbmcgYW5kIHNhdmUgYXMgYSBmaWxlOgoKKiBUb3RhbCBvcmRlcnMgb24gZGVsYXkgbGlzdCBhbmQgdG90YWwgcHJvY2Vzc2VkCiogQnJlYWtkb3duIGJ5IGFjdGlvbiBjYXRlZ29yeSAoY291bnRzIGFuZCBwZXJjZW50YWdlcykKKiBBdXRvLXByb2Nlc3NlZCB2cy4gZmxhZ2dlZCBmb3IgcmV2aWV3IChjb3VudHMpCiogU3VwcGxpZXIgZW1haWxzIHNlbnQg4oCUIGNvdW50IGFuZCBsaXN0IG9mIHN1cHBsaWVycyBjb250YWN0ZWQKKiBDdXN0b21lciBub3RpZmljYXRpb25zIHNlbnQg4oCUIGNvdW50CiogQ29tcGxhaW50cyBsb2dnZWQg4oCUIGNhcnJpZXIgdnMuIHN1cHBsaWVyLCB3aXRoIGNvc3QgYnJlYWtkb3duCiogT3JkZXJzIHNub296ZWQg4oCUIGNvdW50IGFuZCBhdmVyYWdlIHNub296ZSBkdXJhdGlvbgoqIEZhaWxlZCBhY3Rpb25zIHdpdGggZGV0YWlscwoqIFBlbmRpbmcgbWFudWFsIHJldmlldyDigJQgZnVsbCBsaXN0IHdpdGggcHJvcG9zZWQgYWN0aW9ucwoqIFRvcCBkZWxheWVkIHN1cHBsaWVycyDigJQgcmFua2VkIGJ5IG51bWJlciBvZiBkZWxheWVkIG9yZGVycwoqIE9yZGVycyBkZWxheWVkIDMrIGRheXMg4oCUIGhpZ2hsaWdodGVkIGZvciB1cmdlbmN5CgotLS0KCiMjICoqTUNQICYgQVBJIEludGVncmF0aW9uIFBvaW50cyoqCgp8IEFjdGlvbiB8IEludGVncmF0aW9uIHwgVGVtcGxhdGUvRW5kcG9pbnQgfAp8IC0tLS0tIHwgLS0tLS0gfCAtLS0tLSB8CnwgRmV0Y2ggZGVsYXkgbGlzdCB8IHRyYWZmaWMtbWNwIHwgZ2V0LWRlbGF5LWxpc3Qgd29ya2Zsb3cgfAp8IFNub296ZSBvcmRlciB8IHRyYWZmaWMtbWNwIHwgc25vb3plLW9yZGVycyB3b3JrZmxvdyB8CgpCZWZvcmUgcHJvY2Vzc2luZyBiZWdpbnMsIHZlcmlmeSBhbGwgcmVxdWlyZWQgTUNQIHNlcnZlcnMgYW5kIEFQSSBlbmRwb2ludHMgYXJlIGFjY2Vzc2libGUuIElmIGFueSBpbnRlZ3JhdGlvbiBpcyB1bmF2YWlsYWJsZSwgZmxhZyBBTEwgYWZmZWN0ZWQgb3JkZXJzIGZvciBNQU5VQUxcX1JFVklFVyByYXRoZXIgdGhhbiBmYWlsaW5nIHNpbGVudGx5LgoKLS0tCgojIyAqKkNvbmZpZ3VyYXRpb24qKgoKVGhlc2UgZGVmYXVsdHMgY2FuIGJlIG92ZXJyaWRkZW4gYnkgdGhlIG9wZXJhdG9yIGF0IHRoZSBzdGFydCBvZiBlYWNoIHJ1bjoKCmBgYApzbm9vemVfZGVmYXVsdF9ob3VyczogMTIKbWF4X2JhdGNoX3NpemU6IDEwMApjb25maWRlbmNlX3RocmVzaG9sZDogOTkgICAgICAgIyBQZXJjZW50YWdlIOKAlCBiZWxvdyB0aGlzIOKGkiBNQU5VQUxfUkVWSUVXCmN1c3RvbWVyX25vdGlmeV9hZnRlcl9kYXlzOiAyICAjIE5vdGlmeSBjdXN0b21lciBhZnRlciBYIGJ1c2luZXNzIGRheXMgZGVsYXllZApzdXBwbGllcl9lbWFpbF9hZnRlcl9kYXlzOiAxICAgIyBFbWFpbCBzdXBwbGllciBhZnRlciBYIGRheXMgd2l0aCBubyBtb3ZlbWVudAphdXRvX3Nub296ZV9jYXJyaWVyczoKICAtIFVQUy1VUFNfU1RBTkRBUkQKICAtIFVQUy1VUFNfU0FWRVIKICAtIERQRElOVC1TVEFOREFSRF9VSwogIC0gRFBESU5ULVNUQU5EQVJECnN1cHBsaWVyX3NwZWNpZmljX3Byb2Nlc3NlczoKICBwcm9ibzogb25faG9sZAogIGZseWVyYWxhcm06IG9uX2hvbGQKICBtYXN0ZXJwcmludDogY29tcGxldGVkCmBgYAoKLS0tCgojIyAqKkVkZ2UgQ2FzZXMgJiBLbm93biBJc3N1ZXMqKgoKMS4gKipJbmNvcnJlY3QgZGVsYXkgZGF5IGNhbGN1bGF0aW9uKiog4oCUIFRoZSBzeXN0ZW0gc29tZXRpbWVzIHNob3dzIGRpZmZlcmVudCBkZWxheSBjb3VudHMgZm9yIG9yZGVycyB3aXRoIHRoZSBzYW1lIGRpc3BhdGNoIGRhdGUuIEFsd2F5cyByZWNhbGN1bGF0ZTogYnVzaW5lc3MgZGF5cyBiZXR3ZWVuIFRhcmdldCBEaXNwYXRjaCBEYXRlIGFuZCB0b2RheS4KCjIuICoqU2FsZXMgcHJpY2Ugc2hvd3MgZnVsbCBvcmRlciwgbm90IG9yZGVyLWxpbmUqKiDigJQgVGhlIGRlbGF5IGxpc3QgbWF5IHNob3cgZnVsbCBvcmRlciBwcmljZS4gQmUgYXdhcmUgd2hlbiBhc3Nlc3NpbmcgdmFsdWUgdGhyZXNob2xkcy4KCjMuICoqRmFsc2UgZGVsYXlzIGZyb20gUHJvYm8qKiDigJQgT3JkZXJzIHNoaXBwZWQgdG9nZXRoZXIgYWNyb3NzIG11bHRpcGxlIG9yZGVyIGxpbmVzIHRyaWdnZXIgZmFsc2UgZGVsYXlzLiBXaGVuIFByb2JvIHByb2Nlc3NlcyBhY3RpdmF0ZSwgYWx3YXlzIGNoZWNrIGlmIGxpbmVzIHdlcmUgc2hpcHBlZCB0b2dldGhlciBiZWZvcmUgYWN0aW5nLgoKNC4gKipEdXBsaWNhdGUgc3VwcGxpZXIgZW1haWxzKiog4oCUIFRoZSBidW5kbGluZyBydWxlIGlzIGNyaXRpY2FsLiBBbHdheXMgZGVkdXBsaWNhdGUgYW5kIGdyb3VwIGJlZm9yZSBzZW5kaW5nLiBDaGVjayBpZiBhIHN1cHBsaWVyIHdhcyBhbHJlYWR5IGVtYWlsZWQgdG9kYXkuCgo1LiAqKlRyYWNraW5nIGxhZyB2cy4gZ2VudWluZSBkZWxheSoqIOKAlCBQYWNrYWdlZCBvcmRlcnMgd2l0aCB0cmFja2luZyBmcm9tIGFwcHJvdmVkIGNhcnJpZXJzL3N1cHBsaWVycyBhcmUgbW9zdCBvZnRlbiB0cmFja2luZyBsYWcuIEF1dG8tc25vb3plIGhhbmRsZXMgdGhpcywgYnV0IGlmIGFuIG9yZGVyIHJlYXBwZWFycyBhZnRlciBtdWx0aXBsZSBzbm9vemVzLCBlc2NhbGF0ZSB0byBNQU5VQUxcX1JFVklFVy4KCjYuICoqT3JkZXJzIGFzc2lnbmVkIHRvIHRlYW0gbWVtYmVycyoqIOKAlCBJZiBhbiBvcmRlciBoYXMgYW4gYEFzc2lnbmVkYCB2YWx1ZSwgaXQgbWVhbnMgc29tZW9uZSBpcyBhbHJlYWR5IHdvcmtpbmcgb24gaXQuIENvbnNpZGVyIHNraXBwaW5nIG9yIG5vdGluZyB0aGlzIGluIHRoZSByZXZpZXcgcXVldWUuCgo3LiAqKkluY29tcGxldGUgb3JkZXIgZXZhbHVhdGlvbiB3aGVuIGZpbHRlcmluZyoqCldoZW4gZmlsdGVyaW5nIHRoZSBkZWxheSBsaXN0LCBhbHdheXMgZmVlZCB0aGUgcmF3IEFQSSByZXNwb25zZSBkaXJlY3RseSBpbnRvIHRoZSBmaWx0ZXIgbG9naWMg4oCUIG5ldmVyIG1hbnVhbGx5IHJlY29uc3RydWN0IG9yIHN1YnNldCB0aGUgZGF0YS4gQWZ0ZXIgZmlsdGVyaW5nLCB2YWxpZGF0ZSB0aGF0OiBFdmVyeSBvcmRlciB3aXRoIHN0YXRlbmFtZSA9ICJZb3VyIG9yZGVyIGhhcyBiZWVuIHBhY2thZ2VkIiBhcHBlYXJzIGluIGVpdGhlciB0aGUgbWF0Y2ggbGlzdCBvciB0aGUgcmVqZWN0IGxpc3QKVGhlIGNvdW50IG9mIChtYXRjaGVzICsgcmVqZWN0cykgZXF1YWxzIHRoZSB0b3RhbCBudW1iZXIgb2YgcGFja2FnZWQgb3JkZXJzIGluIHRoZSByYXcgcmVzcG9uc2UKCjguICoqVGhlIFBvc3Rlcm1hbiBFeGNlcHRpb24qKgpXaGVuIHRoZSBzdXBwbGllciBpcyAqKlRoZSBQb3N0ZXJtZW4qKiwgdGhlIGNhcnJpZXIgZmllbGQgbWF5IGJlIGFueSB2YWx1ZSB3aGVuIHZhbGlkYXRpbmcgc25vb3plIGFwcGxpY2FiaWxpdHkuIEFsbCBvdGhlciBtYXRjaGluZyBjcml0ZXJpYSBzdGlsbCBhcHBseSBhcyBub3JtYWwuCgo5LiBPcmRlcnMgZnJvbSBzdXBwbGllciAqKk9ha2RlbmUgU2VydmljZXMqKiB3aXRoIGEgY2FycmllciBvZiBgRFBEVUstU1RBTkRBUkRgIG9yIGBEUERVSy1FWFBSRVNTUEFLYCBhcmUgZWxpZ2libGUgZm9yIGF1dG8tc25vb3plIGlmIGFsbCBvdGhlciBhdXRvLXNub296ZSBjcml0ZXJpYSBhcmUgYWxzbyBtZXQuCgoKCi0tLQoKIyMgKipFeGFtcGxlIFJ1bioqCgpgYGAKT3BlcmF0b3I6ICJQcm9jZXNzIHRvZGF5J3MgZGVsYXkgbGlzdC4gTm8gc3BlY2lhbCBub3Rlcy4iCgpTdGVwIDE6IEZldGNoZWQgZGVsYXkgbGlzdCB2aWEgQVBJIOKGkiAzNDcgZGVsYXllZCBvcmRlcnMuIDQgcmVjb3JkcyBtaXNzaW5nIGRhdGEg4oaSIE1BTlVBTF9SRVZJRVcuClN0ZXAgMjogODkgb3JkZXJzIG1hdGNoIGF1dG8tc25vb3plIGNyaXRlcmlhIOKGkiBTbm9vemVkIDEyaC4gQmF0Y2ggMS8xICg4OSkuIEFsbCBzdWNjZWVkZWQKClNVTU1BUlk6IDM0MyBwcm9jZXNzZWQgfCAxNiBtYW51YWwgcmV2aWV3IHwgMCBmYWlsdXJlcwpMb2dzIHNhdmVkOiBkZWxheV9sb2dfMjAyNi0wMi0xMi5jc3YsIHN1bW1hcnlfMjAyNi0wMi0xMi5tZApgYGAK \ No newline at end of file