[
  {
    "path": ".eslintignore",
    "content": "backup/\ndist/\nnode_modules/\nrollup.config.mjs\nrollup.config copy.js\nrollup.new.config.mjs"
  },
  {
    "path": ".eslintrc.json",
    "content": "{\n  \"root\": true,\n  \"parser\": \"@typescript-eslint/parser\",\n  \"parserOptions\": {\n    \"ecmaVersion\": 2022,\n    \"sourceType\": \"module\"\n  },\n  \"plugins\": [\n    \"@typescript-eslint\"\n  ],\n  \"extends\": [\n    \"eslint:recommended\",\n    \"plugin:@typescript-eslint/recommended\",\n    \"airbnb-base\"\n  ],\n  \"rules\": {\n    \"operator-linebreak\": \"warn\",\n    \"no-trailing-spaces\": \"warn\",\n    \"one-var\": \"warn\",\n    \"one-var-declaration-per-line\": \"warn\",\n    \"dot-notation\": \"warn\",\n    \"max-len\": [\"error\", { \"code\": 150 }],\n    \"eol-last\": [\"error\", \"always\"],\n    \"no-console\": \"off\",\n    \"no-unused-vars\": [\"warn\", { \"args\": \"none\", \"ignoreRestSiblings\": true }],\n    \"nonblock-statement-body-position\": \"warn\",\n    \"@typescript-eslint/no-unused-vars\": \"warn\",\n    \"max-classes-per-file\": [\"warn\", 3],\n    \"import/extensions\": [\"warn\", \"ignorePackages\", {\n      \"ts\": \"never\",\n      \"js\": \"never\"\n    }]\n  },\n  \"settings\": {\n    \"import/resolver\": {\n      \"node\": {\n        \"extensions\": [\".js\", \".ts\", \".jsx\", \".tsx\"]\n      }\n    }\n  },\n  \"env\": {\n    \"browser\": true,\n    \"es2022\": true\n  }\n}\n"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "content": "name: \"CodeQL\"\n\non:\n  push:\n    branches: [ \"master\" ]\n  pull_request:\n    branches: [ \"master\" ]\n  schedule:\n    - cron: \"22 7 * * 0\"\n\njobs:\n  analyze:\n    name: Analyze\n    runs-on: ubuntu-latest\n    permissions:\n      actions: read\n      contents: read\n      security-events: write\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [ javascript ]\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n\n      - name: Initialize CodeQL\n        uses: github/codeql-action/init@v2\n        with:\n          languages: ${{ matrix.language }}\n          queries: +security-and-quality\n\n      - name: Autobuild\n        uses: github/codeql-action/autobuild@v2\n\n      - name: Perform CodeQL Analysis\n        uses: github/codeql-action/analyze@v2\n        with:\n          category: \"/language:${{ matrix.language }}\"\n"
  },
  {
    "path": ".gitignore",
    "content": "# ####### ####### #######\n# Folders\n\n.idea\n__pycache__\n/node_modules/\n/.rpt2_cache/\n/trash/\n/backup/\n\n# ####### ####### #######\n# Files\npackage-lock.json\n\n"
  },
  {
    "path": ".npmignore",
    "content": "# OS X\n.DS_Store\nbackup"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n    \"eslint.enable\": true,\n    \"eslint.validate\": [\n      \"javascript\",\n      \"javascriptreact\",\n      \"typescript\",\n      \"typescriptreact\"\n    ],\n    \"editor.tabSize\": 2,\n\n    \"ha_module_path\": \"/home/drp/homeassistant/www/community/ha-card-weather-conditions\",\n    \"editor.wordWrap\": \"wordWrapColumn\",\n    \"editor.wordWrapColumn\": 120,\n  }\n  "
  },
  {
    "path": "CHANGELOG.md",
    "content": "# HA (Lovelace) Card Weather Conditions\n\nThe format is based on [Keep a Changelog](http://keepachangelog.com/)\nand this project adheres to [Semantic Versioning](http://semver.org/).\n\n## [2.0.1] 2025-06-08\n### Fixed\n\n### Added\n- ru locale\n\n### Changed\n- nl locale\n\n## [2.0.0] 2025-06-08\n### Changed\n- Readme and PNG image\n- Fully reengineered the card\n- Czech locale\n\n### Changed\n- Update Spanish locale\n\n## [1.9.12] 2021-01-29\n### Fixed\n- Minor bug fixing\n\n## [1.9.11] 2021-01-29\n### Fixed\n- Minor bug fixing\n\n## [1.9.10] 2021-01-24\n### Changed\nUpdate ClimaCel icons map\n\n## [1.9.9] 2021-01-11\n### Added\n- Norwegian locale\n\n## [1.9.8] 2021-01-07\n### Added\n- Danish locale\n\n## [1.9.7] 2020-12-06\n### Fixed\n- Fixed the snow icon name for the night time (climacell, darksky, openweathermap)\n\n## [1.9.6] 2020-08-17\n### Fixed\n- German locale, fix for \"Feels Like\" word\n\n## [1.9.6] 2020-08-08\n### Added\n- Icon model for: buienradar, defaulthass\n\n## [1.9.5] 2020-08-08\n### Fixed\n- Documentation\n\n## [1.9.5] 2020-07-21\n### Added\n- Errors catch and display while loading translations files\n\n## [1.9.4] 2020-07-19\n### Fixed\n- Minor bug fixing\n\n## [1.9.3] 2020-07-18\n### Changed\n- Exposition time change from hours to minutes\n\n## [1.9.2] 2020-07-10\n### Fixed\n- Minor bug fixing\n\n## [1.9.1] 2020-06-22\n### Added\n- Added icon override mode for the pollen layer\n\n## [1.9.0] 2020-06-21\n### Fixed\n- Minor bug fixing\n\n### Added\n- Add `sea` Weather Forecast session\n\n## [1.8.1] 2020-06-15\n### Fixed\n- Minor bug fixing\n\n## [1.8.0] 2020-06-15\n### Fixed\n- Minor bug fixing\n\n### Changed\n- Internationalization model \n\n### Added\n- Add `pt` language\n- Add Alert Layer\n\n### Changed\n## [1.7.1] 2020-05-24\n### Fixed\n- Minor bug fixing\n\n## [1.7.0] 2020-05-23\n### Fixed\n- Minor bug fixing\n\n### Added\n- Add `sr-latn` language\n\n## [1.6.0] 2020-05-22\n### Added\n- Add `fr` language\n\n## [1.5.1] 2020-05-21\n### Fixed\n- Minor bug fixing\n\n## [1.5.0] 2020-05-14\n### Fixed\n- Minor bug fixing\n### Added\n- Add `uv` (ultraviolet) session\n\n## [1.4.0] 2020-05-13\n### Added\n- Add `es` language\n\n## [1.3.1] 2020-05-13\n### Fixed\n- Minor bug fixing\n\n## [1.3.0] 2020-05-10\n### Added\n- Add moon phase\n\n## [1.2.0] 2020-05-08\n### Added\n- Add NL (Dutch) language\n\n## [1.1.0] 2020-05-07\n### Added\n- Add feels_like sensor\n\n## [1.0.1] 2020-05-07\n### Fixed\n- Minor bug fixing\n\n## [1.0.0] 2020-05-03\n- Initial stable version"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 Renato Rossi, https://www.linkedin.com/in/renatorossi/\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Weather Conditions Card\nha-card-weather-conditions is a powerful and flexible Lovelace card for Home Assistant. It integrates a variety of weather-related data sources to present a comprehensive summary and forecast.<br>\n\n[![hacs_badge](https://img.shields.io/badge/HACS-Default-orange.svg)](https://github.com/hacs/integration)\n\n[![License][license-shield]](LICENSE)\n[![Total alerts](https://img.shields.io/lgtm/alerts/g/r-renato/ha-card-weather-conditions.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/r-renato/ha-card-weather-conditions/alerts/)\n[![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/r-renato/ha-card-weather-conditions.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/r-renato/ha-card-weather-conditions/context:javascript)\n\n[![BuyMeCoffee][buymecoffeebadge]][buymecoffee]\n\n## Features\n\n* Current and forecast weather conditions\n* Marine forecast (swell, wave, wind)\n* Ultraviolet radiation index and protection advice\n* Pollen level display (tree, weed, grass)\n* Air quality index with multiple pollutant types\n* Weather alerts (fire, storm, hydrogeological, hydraulic)\n* Meteogram and camera integration\n* Multilingual support\n* Display MeteoAlarm (Early Warnings for Europe) and Dipartimento Protezione Civile (Italy only) Alert\n\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-overview.png\" width=\"100%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n<!-- <p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-full.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-1.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-2.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>     -->\n\n## **Card Configuration**\n\nTo use the ```ha-card-weather-conditions``` card, add the following configuration to your ```lovelace``` dashboard:\n\n```yaml\nresources:\n  # Required: Load the card if installed via HACS\n  - url: /hacsfiles/ha-card-weather-conditions/ha-card-weather-conditions.js\n    type: module\n  # Optional: Load Card Mod to enable advanced styling/customization\n  - url: /hacsfiles/lovelace-card-mod/card-mod.js\n    type: module\n  # ...\n```\n\n## **Card Schema Summary**\n\n| **Parameter** | **Type**  | **Required** | **Default** | **Description**                                                                                            |\n| ------------- | --------- | ------------ | ----------- | ---------------------------------------------------------------------------------------------------------- |\n| `type`        | `string`  | Yes          | —           | Must be set to `custom:ha-card-weather-conditions`.                                                        |\n| `language`    | `string`  | No           | `en`        | Language for labels. Supported values: `en`, `it`, `nl`, `es`, `de`, `fr`, `sr-latn`, `pt`, `da`, `no-NO`, `cs`, `ru`. |\n| `weather`     | `object`  | No           | —           | Configuration for main weather source. See dedicated section.                                              |\n| `ultraviolet` | `object`  | No           | —           | Configuration for UV index display. See dedicated section for details.                                     |\n| `pollen`      | `object`  | No           | —           | Configuration for pollen levels. See dedicated section.                                                    |\n| `airquality`  | `object`  | No           | —           | Configuration for air quality index. See dedicated section.                                                |\n| `camera`      | `string`  | No           | —           | Entity ID of the camera to display.                                                                        |\n\n## **1 `weather` Object Schema**\nThe following parameters configure the weather object to display current conditions, short-term and long-term forecasts, as well as related alerts.\nThis card has been tested with weather data provided by `pirateweather`, `climacell`, `darksky` and `openweathermap` integrations.\n| **Name**                  | **Type**  | **Required** | **Default**     | **Description**                                                                                                            |\n| ------------------------- | --------- | ------------ | --------------- | -------------------------------------------------------------------------------------------------------------------------- |\n| `name`                    | `string`  | No           | —               | Name of the location displayed in the summary section.                                                                     |\n| `sun`                     | `string`  | No           | —               | Entity ID for the sun sensor (used to adjust visuals for daylight, sunrise, and sunset).                                   |\n| `moonphase`               | `string`  | No           | —               | Entity ID for the moon phase sensor.                                                                                       |\n| `icons_model`             | `string`  | **Yes**      | `pirateweather` | Icon set to use. Supported values: `pirateweather`, `climacell`, `darksky`, `openweathermap`, `buienradar`, `defaulthass`. |\n| `animation`               | `boolean` | No           | `false`         | Enables visual effects like moving clouds, rain, or waves based on weather conditions.                                     |\n| `present`                 | `object`  | No           | —               | Object containing current weather data (e.g., temperature, humidity, pressure).                                            |\n| `daily_forecasts`         | `object`  | No           | —               | Object containing multi-day weather forecast data.                                                                         |\n| `hourly_forecasts`        | `object`  | No           | —               | Object containing hourly weather forecast data.                                                                            |\n| `marine_daily_forecasts`  | `object`  | No           | —               | Object with daily marine forecast data (e.g., wave height, wind, tides).                                                   |\n| `marine_hourly_forecasts` | `object`  | No           | —               | Object with hourly marine forecast data.                                                                                   |\n| `meteoalarm`              | `string`  | No           | —               | Entity ID from [Meteoalarm](https://meteoalarm.org/) integration for regional weather warnings.                            |\n| `dpcalarm`                | `object`  | No           | —               | Object providing DPC (Protezione Civile) alerts such as thunderstorm or flood risks.                                       |\n\n### **1.1 `present` Object Schema**\nThe present object defines the entities used to display the current weather conditions in the summary section of the card. Each property corresponds to a specific sensor or attribute providing real-time environmental data.\n| **Name**                    |  **Type**  | **Required** | **Default** | **Description**                                                               |\n| --------------------------- | ---------- | ------------ | ----------- | ----------------------------------------------------------------------------- |\n| `condition`                 | `string`   | No           | —           | Entity ID providing the current weather condition (e.g. sunny, cloudy, rain). |\n| `temperature`               | `string`   | No           | —           | Entity ID providing the current temperature.                                  |\n| `temperature_feelslike`     | `string`   | No           | —           | Entity ID providing the perceived (feels-like) temperature.                   |\n| `temperature_min`           | `string`   | No           | —           | Entity ID providing the minimum temperature of the day.                       |\n| `temperature_max`           | `string`   | No           | —           | Entity ID providing the maximum temperature of the day.                       |\n| `humidity`                  | `string`   | No           | —           | Entity ID providing the current humidity level (%).                           |\n| `pressure`                  | `string`   | No           | —           | Entity ID providing the current atmospheric pressure.                         |\n| `visibility`                | `string`   | No           | —           | Entity ID providing the current visibility level.                             |\n| `wind_bearing`              | `string`   | No           | —           | Entity ID providing the wind direction in degrees.                            |\n| `wind_speed`                | `string`   | No           | —           | Entity ID providing the wind speed.                                           |\n| `precipitation_intensity`   | `string`   | No           | —           | Entity ID providing the precipitation rate (e.g. mm/h).                       |\n| `precipitation_probability` | `string`   | No           | —           | Entity ID providing the probability of precipitation (%).                     |\n\n### **1.2 `daily_forecasts` Object Schema**\nThis object defines the structure for multi-day forecast data, where each property can include multiple time slots (e.g. `day_1`, `day_2`, `day_3`…).\nEach forecast element (such as `temperature`, `condition`, `precipitation probability`, etc.) must be represented as a Home Assistant entity (e.g., sensor) that includes the following attributes:\n\n- `datetime`: the timestamp indicating the forecast reference time, in ISO 8601 format, for example: <code>2025-06-12T22:00:00+00:00</code>\n\n- `unit_of_measurement`: the unit of measure for the forecasted value (e.g., \"`°C`\", \"`mm`\", \"`%`\"), which must be exposed as an attribute of the sensor.\n\nThese attributes are essential to ensure accurate time alignment and proper rendering of the forecast data.\n\n| **Name**                    | **Type**     | **Required** | **Default** | **Description**                                                            |\n| --------------------------- | ------------ | ------------ | ----------- | -------------------------------------------------------------------------- |\n| `condition`                 | `iTimeSlots` | No           | —           | Object containing the weather condition icons or states for each day slot. |\n| `temperature_high`          | `iTimeSlots` | No           | —           | Object containing the daily high temperature values per slot.              |\n| `temperature_low`           | `iTimeSlots` | No           | —           | Object containing the daily low temperature values per slot.               |\n| `precipitation_intensity`   | `iTimeSlots` | No           | —           | Object with the forecasted precipitation amount for each slot.             |\n| `precipitation_probability` | `iTimeSlots` | No           | —           | Object with the probability of precipitation (%) per slot.                 |\n\n### **1.3 `hourly_forecasts` Object Schema**\nThis object defines the structure for hourly weather forecast data. All fields are optional and do not have default values.\nEach forecast element (such as `temperature`, `condition`, `precipitation probability`, etc.) must be represented as a Home Assistant entity (e.g., sensor) that includes the following attributes:\n\n- `datetime`: the timestamp indicating the forecast reference time, in ISO 8601 format, for example: <code>2025-06-12T22:00:00+00:00</code>\n\n- `unit_of_measurement`: the unit of measure for the forecasted value (e.g., \"`°C`\", \"`mm`\", \"`%`\"), which must be exposed as an attribute of the sensor.\n\nThese attributes are essential to ensure accurate time alignment and proper rendering of the forecast data.\n\n| **Name**                    | **Type**     | **Required** | **Default** | **Description**                                                               |\n| --------------------------- | ------------ | ------------ | ----------- | ----------------------------------------------------------------------------- |\n| `condition`                 | `iTimeSlots` | No           | —           | Object containing the weather condition icons or states for each hourly slot. |\n| `temperature`               | `iTimeSlots` | No           | —           | Object containing the perceived ambient temperature for each hour.            |\n| `temperature_feelslike`     | `iTimeSlots` | No           | —           | Object containing the \"feels like\" temperature values for each hour.          |\n| `precipitation_intensity`   | `iTimeSlots` | No           | —           | Object with forecasted precipitation amount per hour.                         |\n| `precipitation_probability` | `iTimeSlots` | No           | —           | Object with probability of precipitation (%) per hour.                        |\n| `wind_bearing`              | `iTimeSlots` | No           | —           | Object with wind direction (in degrees or cardinal direction) per hour.       |\n| `wind_speed`                | `iTimeSlots` | No           | —           | Object with wind speed values per hour.                                       |\n\n### **1.3.1 `iTimeSlots` Object Schema**\nThis object represents a set of six time slots used to store sequential forecast data (e.g., hourly, daily, etc.).\n| **Name** | **Type** | **Required** | **Description**                                              |\n| -------- | -------- | ------------ | ------------------------------------------------------------ |\n| `slot1`  | `string` | No           | Value for the first time slot (e.g., current or first hour). |\n| `slot2`  | `string` | No           | Value for the second time slot.                              |\n| `slot3`  | `string` | No           | Value for the third time slot.                               |\n| `slot4`  | `string` | No           | Value for the fourth time slot.                              |\n| `slot5`  | `string` | No           | Value for the fifth time slot.                               |\n| `slot6`  | `string` | No           | Value for the sixth time slot.                               |\n\n### **1.4 `dpcalarm` Object Schema**\nThe `dpcalarm` object is used to configure weather-related alerts provided by the Italian Civil Protection Department (DPC), including thunderstorms, hydraulic, and hydrogeological risks. Each property should reference a specific sensor entity ID.\n| **Name**          | **Type** | **Required** | **Description**                                                              |\n| ----------------- | -------- | ------------ | ---------------------------------------------------------------------------- |\n| `thunderstorms`   | `string`   | No           | Entity ID providing thunderstorm alert information from DPC.                 |\n| `hydraulic`       | `string`   | No           | Entity ID providing hydraulic (river/stream flooding) alert information.     |\n| `hydrogeological` | `string`   | No           | Entity ID providing hydrogeological (landslide/soil instability) alert data. |\n\n## **2 `ultraviolet` Object Schema**\nThe ultraviolet object allows you to display UV-related data such as the current index, ozone level, protection window, and safe exposure times for different skin types (I–VI).\n| **Name**            | **Type** | **Required** | **Description**                                                                 |\n| ------------------- | -------- | ------------ | ------------------------------------------------------------------------------- |\n| `protection_window` | `string` | No           | Entity ID providing the time window during which sun protection is recommended. |\n| `ozone_level`       | `string` | No           | Entity ID providing the current atmospheric ozone level.                        |\n| `uv_index`          | `string` | No           | Entity ID providing the current UV index value.                                 |\n| `uv_level`          | `string` | No           | Entity ID describing the UV risk level (e.g. low, moderate, high).              |\n| `max_uv_index`      | `string` | No           | Entity ID providing the maximum forecasted UV index for the day.                |\n| `set_skin_type_1`   | `string` | No           | Entity ID providing sun exposure time recommendation for skin type I.           |\n| `set_skin_type_2`   | `string` | No           | Entity ID providing sun exposure time recommendation for skin type II.          |\n| `set_skin_type_3`   | `string` | No           | Entity ID providing sun exposure time recommendation for skin type III.         |\n| `set_skin_type_4`   | `string` | No           | Entity ID providing sun exposure time recommendation for skin type IV.          |\n| `set_skin_type_5`   | `string` | No           | Entity ID providing sun exposure time recommendation for skin type V.           |\n| `set_skin_type_6`   | `string` | No           | Entity ID providing sun exposure time recommendation for skin type VI.          |\n\n## **3 `pollen` Object Schema**\nThe pollen object provides information about airborne allergens. It defines the range of measured values (`min` and `max`) and includes a list of `entities` describing each pollen type.\n| **Name**   | **Type**        | **Required** | **Description**                                                         |\n| ---------- | --------------- | ------------ | ----------------------------------------------------------------------- |\n| `entities` | `iPollenItem[]` | Yes          | Array of pollen data objects, each representing a specific pollen type. |\n| `min`      | `number`        | Yes          | Minimum expected pollen concentration (used for scaling).               |\n| `max`      | `number`        | Yes          | Maximum expected pollen concentration (used for scaling).               |\n\n## **3.1 `iPollenItem` Object Schema**\nEach `iPollenItem` defines a specific pollen type to be tracked, including a name for display and the corresponding entity ID in Home Assistant.\n| **Name** | **Type** | **Required** | **Description**                                                   |\n| -------- | -------- | ------------ | ----------------------------------------------------------------- |\n| `name`   | `string`   | Yes        | Display name of the pollen type (e.g., “Grass”, “Birch”).         |\n| `entity` | `string`   | Yes        | Home Assistant entity ID providing the pollen concentration data. |\n\n## **4 `airquality` Object Schema**\nThe `airquality` object defines the Home Assistant entity IDs used to monitor various air pollution metrics and EPA health indicators. Each field corresponds to a specific air quality parameter.\n| **Name**                | **Type** | **Required** | **Description**                                                              |\n| ----------------------- | -------- | ------------ | ---------------------------------------------------------------------------- |\n| `pm25`                  | `string` | No           | Entity ID providing PM2.5 (fine particulate matter) concentration.           |\n| `pm10`                  | `string` | No           | Entity ID providing PM10 (coarse particulate matter) concentration.          |\n| `o3`                    | `string` | No           | Entity ID providing Ozone (O₃) concentration.                                |\n| `no2`                   | `string` | No           | Entity ID providing Nitrogen Dioxide (NO₂) concentration.                    |\n| `co`                    | `string` | No           | Entity ID providing Carbon Monoxide (CO) concentration.                      |\n| `so2`                   | `string` | No           | Entity ID providing Sulfur Dioxide (SO₂) concentration.                      |\n| `epa_aqi`               | `string` | No           | Entity ID providing the EPA-computed Air Quality Index.                      |\n| `epa_primary_pollutant` | `string` | No           | Entity ID providing the EPA-designated primary pollutant.                    |\n| `epa_health_concern`    | `string` | No           | Entity ID describing the EPA-assigned health concern level (e.g., moderate). |\n\n## **Card Layers Sample**\nThis section showcases a complete example of the different visual layers supported by the `ha-card-weather-conditions` card.\nEach layer such as summary, weather conditions, air quality, UV index, and alerts—can be configured independently, allowing full control over how and where data appears.\n\nUse this reference as a guide when designing your Lovelace configuration to build a fully personalized weather dashboard.\n\n### **Summary Layer**\nThe summary layers present a concise visual overview of current weather conditions.\n\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-summary.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nweather:\n  name: \"Acquafredda\" \n  icons_model: pirateweather\n  moonphase: sensor.moon_phase\n  present:\n    condition: sensor.home_condition\n    temperature: sensor.home_temperature\n    temperature_feelslike: sensor.home_apparent_temperature\n```\n\n### **Present Layer**\nThis layer displays the current weather conditions using entity data such as temperature, humidity, wind, and more.\n\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-present.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nweather:\n  icons_model: pirateweather\n  sun: sun.sun\n  present:\n    temperature_min: sensor.home_temperature_min\n    temperature_max: sensor.home_temperature_max\n    humidity: sensor.home_relative_humidity\n    pressure: sensor.home_pressure\n    wind_bearing: sensor.home_wind_bearing\n    wind_speed: sensor.home_wind_speed\n    precipitation_intensity: sensor.home_precipitation\n    precipitation_probability: sensor.home_precipitation_probability\n```\n### **Daily Forecast Layer**\nThis layer provides a multi-day weather overview, including expected temperature highs and lows, precipitation probability, and general conditions.\n\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-daily-forecast.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nweather:\n  icons_model: pirateweather\n  daily_forecasts:\n    condition:\n      slot1: sensor.home_daily_forecast_condition_d1\n      slot2: sensor.home_daily_forecast_condition_d2\n      slot3: sensor.home_daily_forecast_condition_d3\n      slot4: sensor.home_daily_forecast_condition_d4                         \n    temperature_high:\n      slot1: sensor.home_daily_forecast_temperature_max_d1\n      slot2: sensor.home_daily_forecast_temperature_max_d2\n      slot3: sensor.home_daily_forecast_temperature_max_d3\n      slot4: sensor.home_daily_forecast_temperature_max_d4\n    temperature_low:\n      slot1: sensor.home_daily_forecast_temperature_min_d1\n      slot2: sensor.home_daily_forecast_temperature_min_d2\n      slot3: sensor.home_daily_forecast_temperature_min_d3\n      slot4: sensor.home_daily_forecast_temperature_min_d4\n    precipitation_probability:\n      slot1: sensor.home_daily_forecast_precipitation_probability_d1\n      slot2: sensor.home_daily_forecast_precipitation_probability_d2\n      slot3: sensor.home_daily_forecast_precipitation_probability_d3\n      slot4: sensor.home_daily_forecast_precipitation_probability_d4\n    precipitation_intensity:\n      slot1: sensor.home_daily_forecast_precipitation_d1\n      slot2: sensor.home_daily_forecast_precipitation_d2\n      slot3: sensor.home_daily_forecast_precipitation_d3\n      slot4: sensor.home_daily_forecast_precipitation_d4\n```\n\n### **Hourly Forecast Layer**\nThis layer displays detailed weather data for the next several hours, including temperature, precipitation, and wind conditions.\n\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-hourly-forecast.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nweather:\n  icons_model: pirateweather\n  hourly_forecasts:\n    condition:\n      slot1: sensor.home_hourly_forecast_condition_h1\n      slot2: sensor.home_hourly_forecast_condition_h2\n      slot3: sensor.home_hourly_forecast_condition_h3\n      slot4: sensor.home_hourly_forecast_condition_h4\n    temperature:\n      slot1: sensor.home_hourly_forecast_temperature_h1\n      slot2: sensor.home_hourly_forecast_temperature_h2\n      slot3: sensor.home_hourly_forecast_temperature_h3\n      slot4: sensor.home_hourly_forecast_temperature_h4\n    temperature_feelslike:\n      slot1: sensor.home_hourly_forecast_apparent_temperature_h1\n      slot2: sensor.home_hourly_forecast_apparent_temperature_h2\n      slot3: sensor.home_hourly_forecast_apparent_temperature_h3\n      slot4: sensor.home_hourly_forecast_apparent_temperature_h4\n    precipitation_intensity:\n      slot1: sensor.home_hourly_forecast_precipitation_h1\n      slot2: sensor.home_hourly_forecast_precipitation_h2\n      slot3: sensor.home_hourly_forecast_precipitation_h3\n      slot4: sensor.home_hourly_forecast_precipitation_h4\n    precipitation_probability:\n      slot1: sensor.home_hourly_forecast_precipitation_probability_h1\n      slot2: sensor.home_hourly_forecast_precipitation_probability_h2\n      slot3: sensor.home_hourly_forecast_precipitation_probability_h3\n      slot4: sensor.home_hourly_forecast_precipitation_probability_h4\n    wind_bearing:\n      slot1: sensor.home_hourly_forecast_wind_bearing_h1\n      slot2: sensor.home_hourly_forecast_wind_bearing_h2\n      slot3: sensor.home_hourly_forecast_wind_bearing_h3\n      slot4: sensor.home_hourly_forecast_wind_bearing_h4\n    wind_speed:\n      slot1: sensor.home_hourly_forecast_wind_speed_h1\n      slot2: sensor.home_hourly_forecast_wind_speed_h2\n      slot3: sensor.home_hourly_forecast_wind_speed_h3\n      slot4: sensor.home_hourly_forecast_wind_speed_h4\n```\n### **Marine Daily Forecast Layer**\nThis layer provides daily marine weather forecasts, including information such as wave height, wind speed, and sea conditions.\n\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-marine-daily-forecast.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nweather:\n  icons_model: pirateweather\n  marine_daily_forecasts:\n    wave_height_max:\n      slot1: sensor.marine_wave_height_max_day_0\n      slot2: sensor.marine_wave_height_max_day_1\n      slot3: sensor.marine_wave_height_max_day_2\n      slot4: sensor.marine_wave_height_max_day_3\n    wave_direction:\n      slot1: sensor.marine_wave_direction_dominant_day_0\n      slot2: sensor.marine_wave_direction_dominant_day_1\n      slot3: sensor.marine_wave_direction_dominant_day_2\n      slot4: sensor.marine_wave_direction_dominant_day_3                            \n    swell_wave_height_max:\n      slot1: sensor.amarine_swell_wave_height_max_day_0\n      slot2: sensor.marine_swell_wave_height_max_day_1\n      slot3: sensor.marine_swell_wave_height_max_day_2\n      slot4: sensor.marine_swell_wave_height_max_day_3                              \n    wind_wave_height_max:\n      slot1: sensor.marine_wind_wave_height_max_day_0\n      slot2: sensor.marine_wind_wave_height_max_day_1\n      slot3: sensor.marine_wind_wave_height_max_day_2\n      slot4: sensor.marine_wind_wave_height_max_day_3 \n```\n### **Alarms Layer**\nThis layer displays weather alerts and warnings from official sources such as Meteoalarm and the Italian Civil Protection Department (DPC). \n\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-alarms.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nweather:\n  icons_model: pirateweather\n  meteoalarm: binary_sensor.italy_basilicata_meteo_alarm\n  dpcalarm:\n    thunderstorms: binary_sensor.dpc_basilicata_temporali_oggi\n    hydraulic: binary_sensor.dpc_basilicata_idraulico_oggi\n    hydrogeological: binary_sensor.dpc_basilicata_idrogeologico_oggi\n```\n### **Ultraviolet Layer**\nThis layer presents real-time ultraviolet (UV) radiation data, including UV index levels, ozone concentration, and skin protection recommendations.\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-ultraviolet.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nultraviolet:\n  protection_window: binary_sensor.openuv_protection_window\n  ozone_level: sensor.openuv_current_ozone_level\n  uv_index: sensor.openuv_current_uv_index\n  uv_level: sensor.openuv_current_uv_level\n  max_uv_index: sensor.openuv_max_uv_index\n\n  set_skin_type_1: sensor.openuv_skin_type_1_safe_exposure_time\n  set_skin_type_2: sensor.openuv_skin_type_2_safe_exposure_time\n  set_skin_type_3: sensor.openuv_skin_type_3_safe_exposure_time\n  set_skin_type_4: sensor.openuv_skin_type_4_safe_exposure_time\n  set_skin_type_5: sensor.openuv_skin_type_5_safe_exposure_time\n  set_skin_type_6: sensor.openuv_skin_type_6_safe_exposure_time\n```\n### **Pollen Layer**\nThis layer displays information about airborne pollen levels, helping users monitor potential allergen exposure.\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-pollen.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \npollen:\n  min: 1\n  max: 4\n  entities:\n    - name: Alder\n      entity: sensor.openmeteo_pollen_alder_level \n    - name: Birch\n      entity: sensor.openmeteo_pollen_birch_level\n    - name: Grass\n      entity: sensor.openmeteo_pollen_grass_level\n    - name: Mugwort\n      entity: sensor.openmeteo_pollen_mugwort_level\n    - name: Olive\n      entity: sensor.openmeteo_pollen_olive_level \n    - name: Ragweed\n      entity: sensor.openmeteo_pollen_ragweed_level  \n```\n### **Air Quality Layer**\nThis layer presents real-time data on key air quality indicators such as PM2.5, PM10, ozone, and nitrogen dioxide levels.\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-air-quality.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nairquality:\n  pm25: sensor.lazio_italy_pm2_5\n  pm10: sensor.lazio_italy_pm10\n  o3: sensor.roma_lazio_italy_ozone\n  co: sensor.roma_lazio_italy_carbon_monoxide\n  epa_aqi: sensor.lazio_italy_air_quality_index\n  epa_primary_pollutant: sensor.lazio_italy_dominant_pollutant\n```\n\n[license-shield]:https://img.shields.io/github/license/r-renato/ha-card-weather-conditions\n[buymecoffee]: https://www.buymeacoffee.com/0D3WbkKrn\n[buymecoffeebadge]: https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow?style=for-the-badge\n"
  },
  {
    "path": "dist/ha-card-weather-conditions.js",
    "content": "function e(e,t,i,n){var a,s=arguments.length,o=s<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,i):n;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,n);else for(var r=e.length-1;r>=0;r--)(a=e[r])&&(o=(s<3?a(o):s>3?a(t,i,o):a(t,i))||o);return s>3&&o&&Object.defineProperty(t,i,o),o}\"function\"==typeof SuppressedError&&SuppressedError;\n/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t=globalThis,i=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&\"adoptedStyleSheets\"in Document.prototype&&\"replace\"in CSSStyleSheet.prototype,n=Symbol(),a=new WeakMap;let s=class{constructor(e,t,i){if(this._$cssResult$=!0,i!==n)throw Error(\"CSSResult is not constructable. Use `unsafeCSS` or `css` instead.\");this.cssText=e,this.t=t}get styleSheet(){let e=this.o;const t=this.t;if(i&&void 0===e){const i=void 0!==t&&1===t.length;i&&(e=a.get(t)),void 0===e&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),i&&a.set(t,e))}return e}toString(){return this.cssText}};const o=(e,...t)=>{const i=1===e.length?e[0]:t.reduce(((t,i,n)=>t+(e=>{if(!0===e._$cssResult$)return e.cssText;if(\"number\"==typeof e)return e;throw Error(\"Value passed to 'css' function must be a 'css' function result: \"+e+\". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.\")})(i)+e[n+1]),e[0]);return new s(i,e,n)},r=i?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t=\"\";for(const i of e.cssRules)t+=i.cssText;return(e=>new s(\"string\"==typeof e?e:e+\"\",void 0,n))(t)})(e):e\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */,{is:l,defineProperty:c,getOwnPropertyDescriptor:d,getOwnPropertyNames:h,getOwnPropertySymbols:u,getPrototypeOf:p}=Object,m=globalThis,g=m.trustedTypes,y=g?g.emptyScript:\"\",f=m.reactiveElementPolyfillSupport,v=(e,t)=>e,_={toAttribute(e,t){switch(t){case Boolean:e=e?y:null;break;case Object:case Array:e=null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){let i=e;switch(t){case Boolean:i=null!==e;break;case Number:i=null===e?null:Number(e);break;case Object:case Array:try{i=JSON.parse(e)}catch(e){i=null}}return i}},w=(e,t)=>!l(e,t),$={attribute:!0,type:String,converter:_,reflect:!1,useDefault:!1,hasChanged:w};Symbol.metadata??=Symbol(\"metadata\"),m.litPropertyMetadata??=new WeakMap;let x=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=$){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){const i=Symbol(),n=this.getPropertyDescriptor(e,i,t);void 0!==n&&c(this.prototype,e,n)}}static getPropertyDescriptor(e,t,i){const{get:n,set:a}=d(this.prototype,e)??{get(){return this[t]},set(e){this[t]=e}};return{get:n,set(t){const s=n?.call(this);a?.call(this,t),this.requestUpdate(e,s,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??$}static _$Ei(){if(this.hasOwnProperty(v(\"elementProperties\")))return;const e=p(this);e.finalize(),void 0!==e.l&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(v(\"finalized\")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(v(\"properties\"))){const e=this.properties,t=[...h(e),...u(e)];for(const i of t)this.createProperty(i,e[i])}const e=this[Symbol.metadata];if(null!==e){const t=litPropertyMetadata.get(e);if(void 0!==t)for(const[e,i]of t)this.elementProperties.set(e,i)}this._$Eh=new Map;for(const[e,t]of this.elementProperties){const i=this._$Eu(e,t);void 0!==i&&this._$Eh.set(i,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const i=new Set(e.flat(1/0).reverse());for(const e of i)t.unshift(r(e))}else void 0!==e&&t.push(r(e));return t}static _$Eu(e,t){const i=t.attribute;return!1===i?void 0:\"string\"==typeof i?i:\"string\"==typeof e?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise((e=>this.enableUpdating=e)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((e=>e(this)))}addController(e){(this._$EO??=new Set).add(e),void 0!==this.renderRoot&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){const e=new Map,t=this.constructor.elementProperties;for(const i of t.keys())this.hasOwnProperty(i)&&(e.set(i,this[i]),delete this[i]);e.size>0&&(this._$Ep=e)}createRenderRoot(){const e=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((e,n)=>{if(i)e.adoptedStyleSheets=n.map((e=>e instanceof CSSStyleSheet?e:e.styleSheet));else for(const i of n){const n=document.createElement(\"style\"),a=t.litNonce;void 0!==a&&n.setAttribute(\"nonce\",a),n.textContent=i.cssText,e.appendChild(n)}})(e,this.constructor.elementStyles),e}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach((e=>e.hostConnected?.()))}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach((e=>e.hostDisconnected?.()))}attributeChangedCallback(e,t,i){this._$AK(e,i)}_$ET(e,t){const i=this.constructor.elementProperties.get(e),n=this.constructor._$Eu(e,i);if(void 0!==n&&!0===i.reflect){const a=(void 0!==i.converter?.toAttribute?i.converter:_).toAttribute(t,i.type);this._$Em=e,null==a?this.removeAttribute(n):this.setAttribute(n,a),this._$Em=null}}_$AK(e,t){const i=this.constructor,n=i._$Eh.get(e);if(void 0!==n&&this._$Em!==n){const e=i.getPropertyOptions(n),a=\"function\"==typeof e.converter?{fromAttribute:e.converter}:void 0!==e.converter?.fromAttribute?e.converter:_;this._$Em=n,this[n]=a.fromAttribute(t,e.type)??this._$Ej?.get(n)??null,this._$Em=null}}requestUpdate(e,t,i){if(void 0!==e){const n=this.constructor,a=this[e];if(i??=n.getPropertyOptions(e),!((i.hasChanged??w)(a,t)||i.useDefault&&i.reflect&&a===this._$Ej?.get(e)&&!this.hasAttribute(n._$Eu(e,i))))return;this.C(e,t,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(e,t,{useDefault:i,reflect:n,wrapped:a},s){i&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,s??t??this[e]),!0!==a||void 0!==s)||(this._$AL.has(e)||(this.hasUpdated||i||(t=void 0),this._$AL.set(e,t)),!0===n&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}const e=this.scheduleUpdate();return null!=e&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[e,t]of this._$Ep)this[e]=t;this._$Ep=void 0}const e=this.constructor.elementProperties;if(e.size>0)for(const[t,i]of e){const{wrapped:e}=i,n=this[t];!0!==e||this._$AL.has(t)||void 0===n||this.C(t,void 0,i,n)}}let e=!1;const t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach((e=>e.hostUpdate?.())),this.update(t)):this._$EM()}catch(t){throw e=!1,this._$EM(),t}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach((e=>e.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach((e=>this._$ET(e,this[e]))),this._$EM()}updated(e){}firstUpdated(e){}};x.elementStyles=[],x.shadowRootOptions={mode:\"open\"},x[v(\"elementProperties\")]=new Map,x[v(\"finalized\")]=new Map,f?.({ReactiveElement:x}),(m.reactiveElementVersions??=[]).push(\"2.1.0\");\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst b=globalThis,A=b.trustedTypes,z=A?A.createPolicy(\"lit-html\",{createHTML:e=>e}):void 0,E=\"$lit$\",k=`lit$${Math.random().toFixed(9).slice(2)}$`,S=\"?\"+k,C=`<${S}>`,I=document,N=()=>I.createComment(\"\"),P=e=>null===e||\"object\"!=typeof e&&\"function\"!=typeof e,T=Array.isArray,U=\"[ \\t\\n\\f\\r]\",D=/<(?:(!--|\\/[^a-zA-Z])|(\\/?[a-zA-Z][^>\\s]*)|(\\/?$))/g,O=/-->/g,M=/>/g,L=RegExp(`>|${U}(?:([^\\\\s\"'>=/]+)(${U}*=${U}*(?:[^ \\t\\n\\f\\r\"'\\`<>=]|(\"|')|))|$)`,\"g\"),j=/'/g,R=/\"/g,H=/^(?:script|style|textarea|title)$/i,F=(e=>(t,...i)=>({_$litType$:e,strings:t,values:i}))(1),V=Symbol.for(\"lit-noChange\"),W=Symbol.for(\"lit-nothing\"),B=new WeakMap,q=I.createTreeWalker(I,129);function Z(e,t){if(!T(e)||!e.hasOwnProperty(\"raw\"))throw Error(\"invalid template strings array\");return void 0!==z?z.createHTML(t):t}const J=(e,t)=>{const i=e.length-1,n=[];let a,s=2===t?\"<svg>\":3===t?\"<math>\":\"\",o=D;for(let t=0;t<i;t++){const i=e[t];let r,l,c=-1,d=0;for(;d<i.length&&(o.lastIndex=d,l=o.exec(i),null!==l);)d=o.lastIndex,o===D?\"!--\"===l[1]?o=O:void 0!==l[1]?o=M:void 0!==l[2]?(H.test(l[2])&&(a=RegExp(\"</\"+l[2],\"g\")),o=L):void 0!==l[3]&&(o=L):o===L?\">\"===l[0]?(o=a??D,c=-1):void 0===l[1]?c=-2:(c=o.lastIndex-l[2].length,r=l[1],o=void 0===l[3]?L:'\"'===l[3]?R:j):o===R||o===j?o=L:o===O||o===M?o=D:(o=L,a=void 0);const h=o===L&&e[t+1].startsWith(\"/>\")?\" \":\"\";s+=o===D?i+C:c>=0?(n.push(r),i.slice(0,c)+E+i.slice(c)+k+h):i+k+(-2===c?t:h)}return[Z(e,s+(e[i]||\"<?>\")+(2===t?\"</svg>\":3===t?\"</math>\":\"\")),n]};class Y{constructor({strings:e,_$litType$:t},i){let n;this.parts=[];let a=0,s=0;const o=e.length-1,r=this.parts,[l,c]=J(e,t);if(this.el=Y.createElement(l,i),q.currentNode=this.el.content,2===t||3===t){const e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;null!==(n=q.nextNode())&&r.length<o;){if(1===n.nodeType){if(n.hasAttributes())for(const e of n.getAttributeNames())if(e.endsWith(E)){const t=c[s++],i=n.getAttribute(e).split(k),o=/([.?@])?(.*)/.exec(t);r.push({type:1,index:a,name:o[2],strings:i,ctor:\".\"===o[1]?ee:\"?\"===o[1]?te:\"@\"===o[1]?ie:X}),n.removeAttribute(e)}else e.startsWith(k)&&(r.push({type:6,index:a}),n.removeAttribute(e));if(H.test(n.tagName)){const e=n.textContent.split(k),t=e.length-1;if(t>0){n.textContent=A?A.emptyScript:\"\";for(let i=0;i<t;i++)n.append(e[i],N()),q.nextNode(),r.push({type:2,index:++a});n.append(e[t],N())}}}else if(8===n.nodeType)if(n.data===S)r.push({type:2,index:a});else{let e=-1;for(;-1!==(e=n.data.indexOf(k,e+1));)r.push({type:7,index:a}),e+=k.length-1}a++}}static createElement(e,t){const i=I.createElement(\"template\");return i.innerHTML=e,i}}function Q(e,t,i=e,n){if(t===V)return t;let a=void 0!==n?i._$Co?.[n]:i._$Cl;const s=P(t)?void 0:t._$litDirective$;return a?.constructor!==s&&(a?._$AO?.(!1),void 0===s?a=void 0:(a=new s(e),a._$AT(e,i,n)),void 0!==n?(i._$Co??=[])[n]=a:i._$Cl=a),void 0!==a&&(t=Q(e,a._$AS(e,t.values),a,n)),t}class K{constructor(e,t){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=t}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){const{el:{content:t},parts:i}=this._$AD,n=(e?.creationScope??I).importNode(t,!0);q.currentNode=n;let a=q.nextNode(),s=0,o=0,r=i[0];for(;void 0!==r;){if(s===r.index){let t;2===r.type?t=new G(a,a.nextSibling,this,e):1===r.type?t=new r.ctor(a,r.name,r.strings,this,e):6===r.type&&(t=new ne(a,this,e)),this._$AV.push(t),r=i[++o]}s!==r?.index&&(a=q.nextNode(),s++)}return q.currentNode=I,n}p(e){let t=0;for(const i of this._$AV)void 0!==i&&(void 0!==i.strings?(i._$AI(e,i,t),t+=i.strings.length-2):i._$AI(e[t])),t++}}class G{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,t,i,n){this.type=2,this._$AH=W,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=i,this.options=n,this._$Cv=n?.isConnected??!0}get parentNode(){let e=this._$AA.parentNode;const t=this._$AM;return void 0!==t&&11===e?.nodeType&&(e=t.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e,t=this){e=Q(this,e,t),P(e)?e===W||null==e||\"\"===e?(this._$AH!==W&&this._$AR(),this._$AH=W):e!==this._$AH&&e!==V&&this._(e):void 0!==e._$litType$?this.$(e):void 0!==e.nodeType?this.T(e):(e=>T(e)||\"function\"==typeof e?.[Symbol.iterator])(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==W&&P(this._$AH)?this._$AA.nextSibling.data=e:this.T(I.createTextNode(e)),this._$AH=e}$(e){const{values:t,_$litType$:i}=e,n=\"number\"==typeof i?this._$AC(e):(void 0===i.el&&(i.el=Y.createElement(Z(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===n)this._$AH.p(t);else{const e=new K(n,this),i=e.u(this.options);e.p(t),this.T(i),this._$AH=e}}_$AC(e){let t=B.get(e.strings);return void 0===t&&B.set(e.strings,t=new Y(e)),t}k(e){T(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let i,n=0;for(const a of e)n===t.length?t.push(i=new G(this.O(N()),this.O(N()),this,this.options)):i=t[n],i._$AI(a),n++;n<t.length&&(this._$AR(i&&i._$AB.nextSibling,n),t.length=n)}_$AR(e=this._$AA.nextSibling,t){for(this._$AP?.(!1,!0,t);e&&e!==this._$AB;){const t=e.nextSibling;e.remove(),e=t}}setConnected(e){void 0===this._$AM&&(this._$Cv=e,this._$AP?.(e))}}class X{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,i,n,a){this.type=1,this._$AH=W,this._$AN=void 0,this.element=e,this.name=t,this._$AM=n,this.options=a,i.length>2||\"\"!==i[0]||\"\"!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=W}_$AI(e,t=this,i,n){const a=this.strings;let s=!1;if(void 0===a)e=Q(this,e,t,0),s=!P(e)||e!==this._$AH&&e!==V,s&&(this._$AH=e);else{const n=e;let o,r;for(e=a[0],o=0;o<a.length-1;o++)r=Q(this,n[i+o],t,o),r===V&&(r=this._$AH[o]),s||=!P(r)||r!==this._$AH[o],r===W?e=W:e!==W&&(e+=(r??\"\")+a[o+1]),this._$AH[o]=r}s&&!n&&this.j(e)}j(e){e===W?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,e??\"\")}}class ee extends X{constructor(){super(...arguments),this.type=3}j(e){this.element[this.name]=e===W?void 0:e}}class te extends X{constructor(){super(...arguments),this.type=4}j(e){this.element.toggleAttribute(this.name,!!e&&e!==W)}}class ie extends X{constructor(e,t,i,n,a){super(e,t,i,n,a),this.type=5}_$AI(e,t=this){if((e=Q(this,e,t,0)??W)===V)return;const i=this._$AH,n=e===W&&i!==W||e.capture!==i.capture||e.once!==i.once||e.passive!==i.passive,a=e!==W&&(i===W||n);n&&this.element.removeEventListener(this.name,this,i),a&&this.element.addEventListener(this.name,this,e),this._$AH=e}handleEvent(e){\"function\"==typeof this._$AH?this._$AH.call(this.options?.host??this.element,e):this._$AH.handleEvent(e)}}class ne{constructor(e,t,i){this.element=e,this.type=6,this._$AN=void 0,this._$AM=t,this.options=i}get _$AU(){return this._$AM._$AU}_$AI(e){Q(this,e)}}const ae=b.litHtmlPolyfillSupport;ae?.(Y,G),(b.litHtmlVersions??=[]).push(\"3.3.0\");const se=globalThis;\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */class oe extends x{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){const t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=((e,t,i)=>{const n=i?.renderBefore??t;let a=n._$litPart$;if(void 0===a){const e=i?.renderBefore??null;n._$litPart$=a=new G(t.insertBefore(N(),e),e,void 0,i??{})}return a._$AI(e),a})(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return V}}oe._$litElement$=!0,oe.finalized=!0,se.litElementHydrateSupport?.({LitElement:oe});const re=se.litElementPolyfillSupport;re?.({LitElement:oe}),(se.litElementVersions??=[]).push(\"4.2.0\");\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst le={attribute:!0,type:String,converter:_,reflect:!1,hasChanged:w},ce=(e=le,t,i)=>{const{kind:n,metadata:a}=i;let s=globalThis.litPropertyMetadata.get(a);if(void 0===s&&globalThis.litPropertyMetadata.set(a,s=new Map),\"setter\"===n&&((e=Object.create(e)).wrapped=!0),s.set(i.name,e),\"accessor\"===n){const{name:n}=i;return{set(i){const a=t.get.call(this);t.set.call(this,i),this.requestUpdate(n,a,e)},init(t){return void 0!==t&&this.C(n,void 0,e,t),t}}}if(\"setter\"===n){const{name:n}=i;return function(i){const a=this[n];t.call(this,i),this.requestUpdate(n,a,e)}}throw Error(\"Unsupported decorator location: \"+n)};\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */function de(e){return(t,i)=>\"object\"==typeof i?ce(e,t,i):((e,t,i)=>{const n=t.hasOwnProperty(i);return t.constructor.createProperty(i,e),n?Object.getOwnPropertyDescriptor(t,i):void 0})(e,t,i)}const he=o`\n  --default-red: 244, 67, 54;\n  --default-pink: 233, 30, 99;\n  --default-purple: 146, 107, 199;\n  --default-deep-purple: 110, 65, 171;\n  --default-indigo: 63, 81, 181;\n  --default-blue: 33, 150, 243;\n  --default-light-blue: 3, 169, 244;\n  --default-cyan: 0, 188, 212;\n  --default-teal: 0, 150, 136;\n  --default-green: 76, 175, 80;\n  --default-light-green: 139, 195, 74;\n  --default-lime: 205, 220, 57;\n  --default-yellow: 255, 235, 59;\n  --default-amber: 255, 193, 7;\n  --default-orange: 255, 152, 0;\n  --default-deep-orange: 255, 111, 34;\n  --default-brown: 121, 85, 72;\n  --default-light-grey: 189, 189, 189;\n  --default-grey: 158, 158, 158;\n  --default-dark-grey: 96, 96, 96;\n  --default-blue-grey: 96, 125, 139;\n  --default-black: 0, 0, 0;\n  --default-white: 255, 255, 255;\n  --default-disabled: 189, 189, 189;\n`,ue=o`\n  --default-disabled: 111, 111, 111;\n`,pe=\"%c WEATHER-CONDITION-CARD %c 2.0.0\",me=\"/local/community/ha-card-weather-conditions/icons\",ge=\"/local/ha-card-weather-conditions/icons\",ye=\"color: white; background: green; font-weight: 700;\",fe=\"color: green; background: white; font-weight: 700;\",ve=\"color: black; background: white; font-weight: 700;\",_e={en:0,it:1,nl:2,es:3,de:4,fr:5,\"sr-latn\":6,pt:7,da:8,\"no-no\":9,cs:10,ru:11},we={snowy:\"snowy-3\",\"light-snow\":\"snowy-2\",\"snowy-rainy\":\"snowy-1\",\"partlycloudy-light-snow\":\"snowy-1\",\"partlycloudy-snow\":\"snowy-1\",\"partlycloudy-light-rain\":\"rainy-1\",\"light-rain\":\"rainy-1\",rainy:\"rainy-2\",\"partlycloudy-rain\":\"rainy-1\",\"partlycloudy-fog\":\"fog\",cloudy:\"cloudy-original\",partlycloudy:\"cloudy-day-2\",\"partlycloudy-lightning\":\"cloudy-day-1\",lightning:\"cloudy-day-1\",clear:\"day\"},$e={...we},xe={freezing_rain_heavy:\"rainy-3\",\"heavy freezing rain\":\"rainy-3\",freezing_rain:\"rainy-2\",\"freezing rain\":\"rainy-2\",freezing_rain_light:\"rainy-1\",\"light freezing rain\":\"rainy-1\",freezing_drizzle:\"rain-and-sleet-mix\",\"freezing drizzle\":\"rain-and-sleet-mix\",ice_pellets_heavy:\"rain-and-snow-mix\",\"heavy ice pellets\":\"rain-and-snow-mix\",ice_pellets:\"rain-and-snow-mix\",\"ice pellets\":\"rain-and-snow-mix\",ice_pellets_light:\"rain-and-snow-mix\",\"light ice pellets\":\"rain-and-snow-mix\",snow_heavy:\"snowy-3\",\"heavy snow\":\"snowy-3\",snow:\"snowy-2\",snow_light:\"snowy-1\",\"light snow\":\"snowy-1\",flurries:\"wind\",tstorm:\"tropical-storm\",rain_heavy:\"rainy-3\",\"heavy rain\":\"rainy-3\",rain_light:\"rainy-1\",\"light rain\":\"rainy-1\",rain:\"rainy-2\",drizzle:\"rainy-1\",fog_light:\"haze\",\"light fog\":\"haze\",fog:\"fog\",cloudy:\"cloudy-original\",mostly_cloudy:\"cloudy-day-3\",\"mostly cloudy\":\"cloudy-day-3\",partly_cloudy:\"cloudy-day-2\",\"partly cloudy\":\"cloudy-day-2\",mostly_clear:\"cloudy-day-1\",\"mostly clear\":\"cloudy-day-1\",clear:\"day\"},be={...xe,freezing_rain_heavy:\"rainy-6\",\"heavy freezing rain\":\"rainy-6\",freezing_rain:\"rainy-5\",\"freezing rain\":\"rainy-5\",freezing_rain_light:\"rainy-4\",\"light freezing rain\":\"rainy-4\",snow_heavy:\"snowy-6\",\"heavy snow\":\"snowy-6\",snow:\"snowy-5\",snow_light:\"snowy-4\",\"light snow\":\"snowy-4\",rain_heavy:\"rainy-6\",\"heavy rain\":\"rainy-6\",rain_light:\"rainy-4\",\"light rain\":\"rainy-4\",rain:\"rainy-5\",drizzle:\"rainy-4\",mostly_cloudy:\"cloudy-night-3\",\"mostly cloudy\":\"cloudy-night-3\",partly_cloudy:\"cloudy-night-2\",\"partly cloudy\":\"cloudy-night-2\",mostly_clear:\"cloudy-night-1\",\"mostly clear\":\"cloudy-night-1\",clear:\"night\",sunny:\"night\"},Ae={clear:\"day\",\"clear-day\":\"day\",rain:\"rainy-2\",snow:\"snowy-2\",sleet:\"rain-and-sleet-mix\",wind:\"cloudy-day-1\",fog:\"fog\",cloudy:\"cloudy-original\",\"partly-cloudy-day\":\"cloudy-day-2\"},ze={...Ae,clear:\"night\",\"clear-night\":\"night\",wind:\"cloudy-night-1\",\"partly-cloudy-day\":\"cloudy-night-2\",\"partly-cloudy-night\":\"cloudy-night-2\"},Ee={cloudy:\"cloudy-day-3\",exceptional:\"severe-thunderstorm\",fog:\"fog\",hail:\"snow-and-sleet-mix\",lightning:\"severe-thunderstorm\",\"lightning-rainy\":\"scattered-thunderstorms\",partlycloudy:\"cloudy-day-3\",pouring:\"rainy-6\",rainy:\"rainy-5\",snowy:\"snowy-6\",\"snowy-rainy\":\"snow-and-sleet-mix\",sunny:\"clear-day\",windy:\"wind\",\"windy-variant\":\"wind\"},ke={...Ee,\"clear-night\":\"clear-night\"},Se={\"clear sky\":\"day\",\"few clouds\":\"cloudy-day-1\",\"scattered clouds\":\"cloudy-day-2\",\"broken clouds\":\"cloudy-day-3\",\"shower rain\":\"rainy-3\",rain:\"rainy-2\",thunderstorm:\"tropical-storm\",snow:\"snowy-2\",mist:\"fog\"},Ce={...Se,\"clear sky\":\"day-night\",\"few clouds\":\"cloudy-night-1\",\"scattered clouds\":\"cloudy-night-2\",\"broken clouds\":\"cloudy-night-3\"},Ie={freezing_rain_heavy:\"rainy-3\",\"heavy freezing rain\":\"rainy-3\",freezing_rain:\"rainy-2\",\"freezing rain\":\"rainy-2\",freezing_rain_light:\"rainy-1\",\"light freezing rain\":\"rainy-1\",freezing_drizzle:\"rain-and-sleet-mix\",sleet:\"rain-and-sleet-mix\",\"freezing drizzle\":\"rain-and-sleet-mix\",ice_pellets_heavy:\"rain-and-snow-mix\",\"heavy ice pellets\":\"rain-and-snow-mix\",ice_pellets:\"rain-and-snow-mix\",\"ice pellets\":\"rain-and-snow-mix\",ice_pellets_light:\"rain-and-snow-mix\",\"light ice pellets\":\"rain-and-snow-mix\",snow_heavy:\"snowy-3\",\"heavy snow\":\"snowy-3\",snow:\"snowy-2\",snow_light:\"snowy-1\",\"light snow\":\"snowy-1\",flurries:\"wind\",tstorm:\"tropical-storm\",rain_heavy:\"rainy-3\",\"heavy rain\":\"rainy-3\",rain_light:\"rainy-1\",rainy:\"rainy-1\",\"light rain\":\"rainy-1\",rain:\"rainy-2\",drizzle:\"rainy-1\",fog_light:\"haze\",\"light fog\":\"haze\",fog:\"fog\",cloudy:\"cloudy-original\",mostly_cloudy:\"cloudy-day-3\",\"mostly cloudy\":\"cloudy-day-3\",partly_cloudy:\"cloudy-day-2\",partlycloudy:\"cloudy-day-2\",\"partly-cloudy-day\":\"cloudy-day-2\",\"partly cloudy\":\"cloudy-day-2\",mostly_clear:\"cloudy-day-1\",\"mostly clear\":\"cloudy-day-1\",clear:\"day\",\"clear-day\":\"day\",wind:\"wind\",windy:\"wind\",sunny:\"day\",\"clear-night\":\"day\"},Ne={...Ie,freezing_rain_heavy:\"rainy-6\",\"heavy freezing rain\":\"rainy-6\",freezing_rain:\"rainy-5\",\"freezing rain\":\"rainy-5\",freezing_rain_light:\"rainy-4\",\"light freezing rain\":\"rainy-4\",snow_heavy:\"snowy-6\",\"heavy snow\":\"snowy-6\",snow:\"snowy-5\",snow_light:\"snowy-4\",\"light snow\":\"snowy-4\",rain_heavy:\"rainy-6\",\"heavy rain\":\"rainy-6\",rain_light:\"rainy-4\",\"light rain\":\"rainy-4\",rain:\"rainy-5\",drizzle:\"rainy-4\",mostly_cloudy:\"cloudy-night-3\",\"mostly cloudy\":\"cloudy-night-3\",partly_cloudy:\"cloudy-night-2\",partlycloudy:\"cloudy-night-2\",\"partly-cloudy-night\":\"cloudy-night-2\",\"partly cloudy\":\"cloudy-night-2\",mostly_clear:\"cloudy-night-1\",\"mostly clear\":\"cloudy-night-1\",clear:\"night\",\"clear-night\":\"night\",sunny:\"night\"},Pe={pirateweather:{iconsDay:Ie,iconsNight:Ne},climacell:{iconsDay:xe,iconsNight:be},darksky:{iconsDay:Ae,iconsNight:ze},openweathermap:{iconsDay:Se,iconsNight:Ce},buienradar:{iconsDay:we,iconsNight:$e},defaulthass:{iconsDay:Ee,iconsNight:ke}},Te=(e,t)=>{const i=Object.keys(t).find((t=>t.toLowerCase()===e.toLowerCase()));return i?t[i]:e},Ue=e=>{const t={en:0,it:1,nl:2,es:3,de:4,fr:5,\"sr-latn\":6,pt:7,da:8,\"no-no\":9,cs:10,ru:11};return{locale:{en:\"en-US\",it:\"it-IT\",nl:\"nl-NL\",es:\"es-ES\",de:\"de-DE\",fr:\"fr-FR\",\"sr-latn\":\"sr-Latn\",pt:\"pt-PT\",da:\"da-DK\",\"no-no\":\"nb-NO\",cs:\"cs-CZ\",ru:\"ru-RU\"}[e]||e,timezone:{en:\"America/New_York\",it:\"Europe/Rome\",nl:\"Europe/Amsterdam\",es:\"Europe/Madrid\",de:\"Europe/Berlin\",fr:\"Europe/Paris\",\"sr-latn\":\"Europe/Belgrade\",ja:\"Asia/Tokyo\",pt:\"Europe/Lisbon\",da:\"Europe/Copenhagen\",\"no-no\":\"Europe/Oslo\",cs:\"Europe/Prague\",ru:\"Europe/Moscow\"}[e]||\"UTC\",...e in t&&{cwc:t[e]}}},De=e=>({it:\"it-IT\",en:\"en-US\",fr:\"fr-FR\",de:\"de-DE\",es:\"es-ES\",ja:\"ja-JP\",zh:\"zh-CN\"}[e]||`${e}-${e.toUpperCase()}`),Oe=({stringNumber:e,lang:t=\"en\",fractionDigits:i=1,useGrouping:n=!1})=>{const a=parseFloat(e);if(Number.isNaN(a))return\"\";const s=((e=\"en-US\",t=1,i=!1)=>new Intl.NumberFormat(e,{minimumFractionDigits:t,maximumFractionDigits:t,useGrouping:i}))(De(t),i,n);return s.format(a)};const Me=(e,t)=>t&&e.states[t]?.state,Le=(e,t,i)=>t&&e.states[t]?.attributes[i],je=({entityId:e,hass:t,lang:i=\"en\",decimals:n=0}={})=>{const a=t&&e&&t.states[e]?.state;return void 0!==a?Oe({stringNumber:a,fractionDigits:n,lang:i}):void 0},Re=(e,t)=>t&&e.states[t]?.attributes?.unit_of_measurement,He=(e,t)=>t&&e.states[t]?.attributes?.icon,Fe=(e,t)=>{const i=\"number\"==typeof e?e:parseFloat(e);if(Number.isNaN(i))return t[e]??null;if(i<0||i>360)return console.error(`Invalid wind direction: '${e}'. Valid values are between 0 and 360 degrees.`),null;return t[[\"N\",\"NNE\",\"NE\",\"ENE\",\"E\",\"ESE\",\"SE\",\"SSE\",\"S\",\"SSW\",\"SW\",\"WSW\",\"W\",\"WNW\",\"NW\",\"NNW\"][Math.floor((i+11.25)%360/22.5)]]??null};function Ve(e,t=5e3){return new Promise((i=>{const n=new Image,a=setTimeout((()=>{n.src=\"\",i(!1)}),t);n.onload=()=>{clearTimeout(a),i(!0)},n.onerror=()=>{clearTimeout(a),i(!1)},n.src=e}))}function We(e,...t){console.info(e,...t.length?t:[])}function Be(e,t=\"en-US\"){if(\"number\"==typeof e)return e;const i=e.replace(/\\./g,\"\").replace(\",\",\".\");return Number(i)}const qe={new_moon:\"🌑\",new:\"🌑\",waxing_crescent:\"🌒\",first_quarter:\"🌓\",waxing_gibbous:\"🌔\",full:\"🌕\",full_moon:\"🌕\",waning_gibbous:\"🌖\",third_quarter:\"🌗\",last_quarter:\"🌗\",waning_crescent:\"🌘\"},Ze=o`\n  ha-card {\n    cursor: pointer;\n    position: relative;\n    width: 100%;\n  }\n\n  .ha-card-weather-conditions {\n    width: 100%;\n    box-sizing: border-box;\n    background-color: var(--card-background-color, #1c1c1c);\n    color: var(--primary-text-color, #ffffff);\n    border-radius: var(--ha-card-border-radius, 12px);\n    box-shadow: var(--ha-card-box-shadow, 0 2px 6px rgba(0, 0, 0, 0.2));\n    overflow: hidden;\n    padding: 0;\n    display: flex;\n    flex-direction: column;\n  }\n\n  .nd-container {\n    width: 100%;\n    box-sizing: border-box;\n    display: flex;\n    flex-direction: column;\n    padding: 16px 20px; /* ← padding orizzontale più ampio */\n    gap: 12px;\n    background-size: cover;\n    background-position: center;\n    transition: background-image 0.3s ease-in-out;\n  }\n\n  /* Esempio di stile dinamico aggiuntivo se habgImage è una classe */\n  .nd-container.sunny {\n    background-image: url('/local/images/sunny-bg.jpg');\n  }\n\n  .nd-container.rainy {\n    background-image: url('/local/images/rainy-bg.jpg');\n  }\n\n  /* -------------- */\n\n`,Je=o`\n\n.summary-grid-container {\n  position: relative;\n  z-index: 1;\n  display: grid;\n  grid-template-columns: 1fr 1fr 1fr; /* <-- 3 colonne reali */\n  grid-template-rows: auto auto;\n  width: 100%;\n  max-width: 600px;\n  // background: #1c1c1c;\n  // color: white;\n  gap: 4px;\n  padding: 0px;\n  box-sizing: border-box;\n  // border: 1px solid #444; /* debug */\n}\n\n.summary-col-left {\n  grid-column: 1;\n  grid-row: 1 / span 2;\n  // background: #2c2c2c;\n  padding-top: 0px;\n  padding-right: 0px;\n  padding-bottom: 0px;\n  padding-left: 0px;\n  \n  display: flex;                 /* Attiva Flexbox */\n  justify-content: center;      /* Centra orizzontalmente */\n  align-items: center;          /* Centra verticalmente */\n\n  width: 100%;\n  max-width: 100%;\n  aspect-ratio: 1 / 1; /* opzionale: mantiene forma quadrata */\n  overflow: hidden;\n}\n\n.summary-top-right {\n  grid-column: 2 / span 2; /* occupa colonne 2 e 3 */\n  grid-row: 1;\n  // background: #3c3c3c;\n  padding-top: 0px;\n  padding-right: 8px;\n  padding-bottom: 0px;\n  padding-left: 8px;\n  display: flex;            /* aggiunto */\n  align-items: center;      /* centra verticalmente */\n  justify-content: flex-start; /* allinea a sinistra */\n}\n\n.summary-bottom-right-left {\n  grid-column: 2;\n  grid-row: 2;\n  // background: #4c4c4c;\n  padding-top: 0px;\n  padding-right: 8px;\n  padding-bottom: 0px;\n  padding-left: 8px;\n\n  display: flex;                 /* Attiva Flexbox */\n  justify-content: center;      /* Centra orizzontalmente */\n  align-items: center;          /* Centra verticalmente */\n}\n\n.summary-bottom-right-right {\n  grid-column: 3;\n  grid-row: 2;\n  // background: #5c5c5c;\n  padding-top: 0px;\n  padding-right: 8px;\n  padding-bottom: 0px;\n  padding-left: 8px;\n}\n\n.weather-condition-icon {\n  width: 100%;\n  height: auto;\n  max-width: 100%;\n  max-height: 100%;\n  object-fit: contain;\n  // max-width: 100%;\n  // max-height: 100%;\n  // width: 72px;\n  // height: 72px;\n  // object-fit: contain;\n\n  transition: transform 0.2s ease;\n}\n  \n.summary-col-left:hover .weather-condition-icon {\n  transform: scale(1.05);\n}\n\n.weather-city-name {\n  font-size: clamp(1em, 2vw, 1.2em);\n  text-align: left;\n}\n\n.moon-row {\n  display: flex;\n  align-items: center;\n  gap: 6px;\n  // font-size: 0.95em;\n  // color: #eeeeee;\n}\n\n.summary-moon-icon {\n  font-size: 1.8em;\n  display: inline-block;\n}\n\n.temperature-block {\n  display: flex;\n  flex-direction: column;\n  align-items: flex-end;\n  text-align: right;\n}\n\n.temperature {\n  font-size: 1.6em;\n  font-weight: bold;\n}\n\n.temp-unit {\n  font-size: 0.95em;\n  vertical-align: super;\n  margin-left: 2px;\n}\n\n.feels-like {\n  font-size: 0.85em;\n  // color: #aaaaaa;\n}\n\n.summary-wrapper {\n  position: relative;\n  width: 100%;\n  height: 100%;\n  min-height: 100px; /* oppure clamp() dinamico */\n  overflow: visible;\n}\n\n.lightning-background {\n  position: absolute;\n  inset: 0; /* top: 0; right: 0; bottom: 0; left: 0 */\n  pointer-events: none;\n  z-index: 0;\n}\n\n.lightning-flash {\n  position: absolute;\n  width: 2px;\n  background: white;\n  opacity: 0.7;\n  transform: translate(-50%, -50%);\n  animation-name: flash-blink;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n  border-radius: 1px;\n  filter: blur(0.5px);\n  box-shadow: 0 0 4px rgba(255,255,255,0.6);\n\n  z-index: 0;\n}\n\n@keyframes flash-blink {\n  0%, 100% {\n    opacity: 0.1;\n  }\n  50% {\n    opacity: 0.9;\n  }\n}\n\n.lightning-flash-zigzag {\n  position: absolute;\n  width: 2px;\n  height: 0;\n  background: linear-gradient(to bottom, yellow, white);\n  clip-path: polygon(var(--points));\n  animation: flash-zigzag linear forwards;\n  z-index: 3;\n}\n\n@keyframes flash-zigzag {\n  0% {\n    opacity: 1;\n    transform: scaleY(1);\n  }\n  100% {\n    opacity: 0;\n    transform: scaleY(1.2);\n  }\n}\n\n.lightning-svg {\n  position: absolute;\n  transform: translate(-50%, 0);\n  opacity: 0;\n  filter: drop-shadow(0 0 4px rgba(98, 61, 173, 0.6));\n  animation-name: flash-zigzag-svg;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: 1;\n  z-index: 3;\n}\n\n@keyframes flash-zigzag-svg {\n  0%, 100% {\n    opacity: 0;\n  }\n  40% {\n    opacity: 1;\n  }\n  60% {\n    opacity: 0.5;\n  }\n}\n`,Ye=o`\n.present-grid-container {\n  display: flex;\n  flex-direction: column;\n  gap: 4px;\n}\n\n.present-row {\n  display: flex;\n  justify-content: space-between;\n  gap: 16px;\n}\n\n.present-left,\n.present-right {\n  flex: 1;\n}\n\n.present-left {\n  display: flex;\n  justify-content: flex-start;\n}\n\n.present-right {\n  display: flex;\n  justify-content: flex-end;\n}\n\n.present-value-block {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n}\n\n.present-unit {\n  font-size: 0.9em;\n  opacity: 0.8;\n}\n`,Qe=o`\n.ultraviolet-grid-container {\n  display: flex;\n  flex-direction: column;\n  gap: 4px;\n}\n\n.ultraviolet-row {\n  display: flex;\n  justify-content: space-between;\n  gap: 16px;\n}\n\n.ultraviolet-left,\n.present-right {\n  flex: 1;\n}\n\n.ultraviolet-left {\n  display: flex;\n  justify-content: flex-start;\n}\n\n.ultraviolet-right {\n  display: flex;\n  justify-content: flex-end;\n}\n\n.ultraviolet-value-block {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n}\n\n.ultraviolet-unit {\n  font-size: 0.9em;\n  opacity: 0.8;\n}\n\n------------------------------------------------------------------\n\n// .ultraviolet-grid-container {\n//   display: flex;\n//   flex-direction: column;\n//   gap: 12px;\n// }\n\n// .ultraviolet-row {\n//   display: flex;\n//   justify-content: space-between;\n//   padding: 4px 0;\n// }\n\n// .ultraviolet-value-block {\n//   display: flex;\n//   align-items: center;\n//   gap: 4px;\n// }\n\n// .ultraviolet-unit {\n//   font-size: 0.9em;\n//   opacity: 0.7;\n// }\n\n.ultraviolet-skin-type-grid {\n  display: grid;\n  grid-template-columns: repeat(auto-fit, minmax(48px, 1fr));\n  gap: 8px;\n  margin-top: 8px;\n}\n\n.ultraviolet-skin-type-cell {\n  flex: 1;\n  min-width: 48px;\n  height: 48px;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  border-radius: 6px;\n  font-family: 'Segoe UI', sans-serif;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n  color: black;\n}\n\n.ultraviolet-skin-type-label {\n  font-weight: bold;\n  font-size: 0.95em;\n  line-height: 1em;\n}\n\n.ultraviolet-exposure-time {\n  font-size: 0.75em;\n  margin-top: 2px;\n  color: #222;\n  opacity: 0.85;\n}\n\n\n\n\n\n\n`,Ke=o`\n.pollen-grid-container {\n  display: grid;\n  grid-template-columns: repeat(auto-fit, minmax(48px, 1fr));\n  gap: 8px 12px;\n  width: 100%;\n  justify-items: center;\n  align-items: end;\n  padding: 8px 4px;\n  box-sizing: border-box;\n}\n\n\n.pollen-stack {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 4px;\n  min-width: 48px;\n}\n\n\n  .levels {\n    display: flex;\n    flex-direction: column-reverse;\n    gap: clamp(1px, 0.2vw, 2px);\n  }\n\n  .level {\n    width: clamp(16px, 3.5vw, 24px);\n    height: clamp(5px, 0.7vw, 8px);     /* 👈 anche in altezza */\n    border-radius: 3px;\n    opacity: 0.3;\n    transition: opacity 0.2s ease;\n  }\n\n  .level.active {\n    opacity: 1;\n    outline: 1px solid #333;\n  }\n\n  .molto-alto {\n    background-color: #f44336;\n  }\n\n  .alto {\n    background-color: #ff9800;\n  }\n\n  .moderato {\n    background-color: #ffeb3b;\n  }\n\n  .basso {\n    background-color: #4caf50;\n  }\n\n  .pollen-name {\n    font-size: clamp(0.55em, 1.3vw, 0.85em); /* 👈 stringe di più */\n    // font-weight: 500;\n    text-align: center;\n    // color: #333;\n    white-space: nowrap;\n  }\n\n  .label {\n    width: 100%;\n    text-align: center;\n    font-size: clamp(0.55em, 1.3vw, 0.85em);\n    // font-weight: 500;\n    margin-top: clamp(4px, 0.5vw, 8px);\n  }\n`,Ge=o`\n  .camera-container {\n    margin-top: 10px;\n    width: 100%;\n    display: flex;\n    align-items: stretch;\n  }\n\n  .camera-image {\n    aspect-ratio: 16 / 9;\n    width: 100%;\n    position: relative;\n    overflow: hidden;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n  }\n\n  .camera-image > img {\n    width: 100%;\n    height: 100%;\n    object-fit: cover;\n  }\n`,Xe=o`\n\n.weather-forecast-grid-container {\n  display: grid;\n  grid-template-columns: repeat(auto-fit, minmax(78px, 1fr));\n  column-gap: 2px; /* spazio orizzontale tra i giorni */\n  row-gap: 6px;    /* spazio verticale tra righe, se ci sono */\n  align-items: stretch;\n  font-family: 'Segoe UI', sans-serif;\n  width: 100%;\n}\n  \n.weather-forecast-grid-wrapper {\n  display: flex;\n  flex-direction: column;\n  align-items: center; /* centrare il titolo orizzontalmente */\n}\n\n.weather-forecast-title {\n  font-size: clamp(0.85em, 1vw, 0.95em);\n  font-weight: bold;\n  // margin-bottom: 0.5em;\n  text-align: center;\n}\n\n.weather-forecast-slot {\n  text-align: center;\n  padding: 8px 4px;\n  min-width: 0;\n  overflow: hidden;\n}\n\n.weather-forecast-slot:last-child {\n  border-right: none;\n}\n\n.weather-forecast-label-slot {\n  font-size: 0.9em;\n  font-weight: bold;\n  margin-bottom: 6px; /* ridotto */\n}\n\n.weather-forecast-icon {\n  font-size: 1.6rem; /* ridotto */\n  /* margin: 6px 0; ridotto */\n  height: 32px;\n}\n\n.weather-forecast-temperature {\n  font-size: clamp(0.8em, 1vw, 0.9em); /* leggermente più piccolo */\n  margin: 4px 0; /* meno margine */\n}\n\n.weather-forecast-temperature .high {\n  font-weight: bold;\n}\n\n.weather-forecast-precipitation {\n  font-size: clamp(0.65em, 1vw, 0.75em);\n  line-height: 1.2; /* compatta verticalmente */\n}\n\n.weather-forecast-precipitation .mm {\n  font-weight: bold;\n}\n`,et=o`\n.meteodcpalarm-grid-container {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: center;\n  gap: 16px;\n  padding: 12px;\n}\n\n.meteodcpalarm-group {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  flex: 1 1 72px;     /* 👈 cresce, ma non scende sotto i 72px */\n  max-width: 220px;   /* 👈 opzionale: previene allargamento eccessivo */\n  text-align: center;\n}\n\n.meteodcpalarm-group ha-icon {\n  --mdc-icon-size: 36px;\n}\n\n.meteodcpalarm-label {\n  margin-top: 6px;\n  font-size: 0.85em;\n  color: var(--primary-text-color);\n}\n\n\n`,tt=(e,t,i)=>{const n=\"below_horizon\"===i,a=(n?t.iconsNight:t.iconsDay)[e];return t.path||console.info(\"Image path not found.\"),a?`${t.path}/${t.iconType}/${a}.svg`:(console.info(`Icons issue. Model=${t.icons_model}, Time=${n?\"night\":\"day\"}, Condition=${e}`),\"\")};function it(e){return!!e&&e.themes.darkMode}async function nt(){const[e,t]=await Promise.all([Ve(`${me}/static/cloudy.svg`),Ve(`${ge}/static/cloudy.svg`)]);let i=null;if(i=e?me:t?ge:null,!i)return We(`${pe} - Impossibile determinare il path immagini.`),{translations:[],imagePath:null};const n=`${i}/../transl/`;return{translations:await Promise.all([\"en\",\"it\",\"nl\",\"es\",\"de\",\"fr\",\"sr-latn\",\"pt\",\"da\",\"no-NO\",\"cs\"].map((e=>async function(e){try{const t=await fetch(e);if(!t.ok){const i=`ERROR retrieving JSON file: '${e}', status: ${t.status} ${t.statusText}`;throw console.info(i),new Error(i)}return console.info(`Locale '${e}' loaded`),await t.text()}catch(t){throw console.info(`Fetch failed for '${e}':`,t),t}}(`${n}${e}.json`)))),imagePath:i}}class at extends oe{constructor(){super(...arguments),this.isPanel=!1,this.editMode=!1,this.invalidConfig=!1,this._hasPresent=!1,this._hasDailyForecasts=!1,this._hasHourlyForecasts=!1,this._hasMarineDailyForecasts=!1,this._hasMarineHourlyForecasts=!1,this._hasMetealarm=!1,this._hasDPCalarm=!1,this._hasMeteogram=!1,this._hasAirQuality=!1,this._hasPollen=!1,this._hasUltraviolet=!1,this._hasAlert=!1,this._hasSea=!1,this._hasCamera=!1}updated(e){if(super.updated(e),e.has(\"hass\")&&this.hass){const t=it(e.get(\"hass\")),i=it(this.hass);t!==i&&this.toggleAttribute(\"dark-mode\",i)}}static get styles(){return[o`\n        :host {\n          ${he}\n        }\n        :host([dark-mode]) {\n          ${ue}\n        }\n        ${o`\n${Ze}\n${Je}\n${Ye}\n${Xe}\n${Qe}\n${Ke}\n${Ge}\n${et}\n`}\n      `]}async setConfig(e){if(!e)throw this.invalidConfig=!0,new Error(\"Invalid configuration\");if(!this._translations?.length||!this._imagesPath){const{translations:e,imagePath:t}=await nt();this._translations=e,this._imagesPath=t}this._name=e?.weather?.name??void 0,this._language=e.language?.toLowerCase()||\"en\",this._loadTranslations(this._language),this._detectDataSections(e),this._setupIcons(e.weather?.icons_model),this._config=e,We(`${pe} - Config loaded.`)}getCardSize(){return 1}_loadTranslations(e){try{const t=JSON.parse(this._translations[_e[e]]);this._terms={windDirections:t.cwcLocWindDirections,words:t.cwcTerms},We(`${pe}%c card \"${this._name}\", locale is '${e}'.`,ye,fe,ve)}catch(t){const i=\"en\",n=JSON.parse(this._translations[_e[i]]);this._terms={windDirections:n.cwcLocWindDirections,words:n.cwcTerms},We(`${pe}%c card \"${this._name}\" unable to use '${e}' locale, set as default '${i}'.`,ye,fe,ve)}}_detectDataSections(e){this._hasPresent=!!e.weather?.present,this._hasDailyForecasts=!!e.weather?.daily_forecasts,this._hasHourlyForecasts=!!e.weather?.hourly_forecasts,this._hasMarineDailyForecasts=!!e.weather?.marine_daily_forecasts,this._hasMarineHourlyForecasts=!!e.weather?.marine_hourly_forecasts,this._hasMetealarm=!!e.weather?.meteoalarm,this._hasDPCalarm=!!e.weather?.dpcalarm,this._hasAirQuality=!!e.airquality,this._hasPollen=e.pollen&&Array.isArray(e.pollen.entities)&&e.pollen.entities.length>0,this._hasUltraviolet=!!e.ultraviolet,this._hasCamera=!!e.camera}_setupIcons(e){if(this._iconsConfig={path:this._imagesPath,iconType:this._config?.weather?.animation?\"animated\":\"static\",icons_model:e||\"pirateweather\",iconsDay:Ie,iconsNight:Ne},e){const t=(e=>{const t=e.toLowerCase()??\"climacell\";if(t in Pe){const{iconsDay:e,iconsNight:i}=Pe[t];return{iconsModel:t,iconsDay:e,iconsNight:i}}console.warn(`Unknown icons model: ${t}. Falling back to 'climacell'.`);const i=Pe.climacell;return{iconsModel:\"climacell\",iconsDay:i.iconsDay,iconsNight:i.iconsNight}})(e);this._iconsConfig.icons_model=t.iconsModel,this._iconsConfig.iconsDay=t.iconsDay,this._iconsConfig.iconsNight=t.iconsNight}}render(){return this.invalidConfig?F`\n        <ha-card class=\"ha-card-weather-conditions\">\n            <div class='banner'>\n                <div class=\"header\">ha-card-weather-conditions</div>\n            </div>\n            <div class='content'>\n                Configuration ERROR!\n            </div>\n        </ha-card>\n    `:this._render()}}e([de({attribute:!1})],at.prototype,\"hass\",void 0),e([de({attribute:!1})],at.prototype,\"_config\",void 0);const st=(e,t,i,n,a,s,o,r)=>{const l=Me(e,r),c=l?qe[l.toLowerCase()]:\"\";const d=Me(e,o),h=Me(e,s.condition)?.toLowerCase()||\"na\",u=s.temperature?je({entityId:s.temperature,hass:e,lang:t})??void 0:void 0,p=s.temperature_feelslike?je({entityId:s.temperature_feelslike,hass:e,lang:t})??void 0:void 0,m=e.states[s.temperature_feelslike]?.attributes.icon??\"\";return(({title:e,moonText:t,moonIcon:i,conditionText:n,conditionIcon:a,temperature:s,temperatureUnit:o,feelsLikeTerm:r,temperatureFeelsLike:l,temperatureFeelsLikeIcon:c})=>a||t||s?F`\n    <div class=\"summary-wrapper\">\n      ${W}\n      <div class=\"summary-grid-container\">\n        ${a?F`\n          <div class=\"summary-col-left\">\n            <img class=\"weather-condition-icon\" src=\"${a}\" alt=\"${n}\" />\n          </div>\n        `:W}\n        ${e?F`\n          <div class=\"summary-top-right\">\n            <span class=\"weather-city-name\">${e}</span>\n          </div>    \n        `:W}\n        ${t?F`\n          <div class=\"summary-bottom-right-left\">\n            <div class=\"moon-row\">\n              <span class=\"summary-moon-icon\">${i}</span>\n              <span class=\"summary-moon-text\">${t}</span>\n            </div>  \n          </div>   \n        `:W}\n        ${s?F`\n          <div class=\"summary-bottom-right-right\">\n            <div class=\"temperature-block\">\n              <div>\n                <span class=\"temperature\">${s}</span>\n                <span class=\"temp-unit\">${o}</span>\n              </div>\n              ${l&&F`<div class=\"feels-like\">${r} <div>${l} ${o}</div></div>`}\n            </div>  \n          </div>\n          `:W}\n      </div>\n    </div>\n    `:F``)({title:a??void 0,moonText:r?Te(l,i.words):void 0,moonIcon:c,conditionText:h,conditionIcon:tt(h,n,d),temperature:u,temperatureUnit:Re(e,s.temperature),feelsLikeTerm:Te(\"Feels Like\",i.words),temperatureFeelsLike:p,temperatureFeelsLikeIcon:m})},ot=e=>\"string\"==typeof e||\"number\"==typeof e,rt=(e,t)=>{const i=[],n=e.precipitationIntensity?.value,a=e.precipitationProbability?.value;if(ot(n)&&ot(a)){const s=De(t),o=Be(n,s),r=Be(a,s);!Number.isNaN(Number(o))&&!Number.isNaN(Number(r))&&o>0&&r>0&&i.push({icon:e.precipitationIntensity.icon||e.precipitationProbability.icon||\"mdi:weather-rainy\",value:`${e.precipitationIntensity.value} ${e.precipitationIntensity.unit} / ${e.precipitationProbability.value} ${e.precipitationProbability.unit}`})}void 0!==e.temperatureLow?.value&&void 0!==e.temperatureHigh?.value&&i.push({icon:e.temperatureLow.icon||e.temperatureHigh.icon||\"mdi:thermometer\",value:`${e.temperatureLow.value} / ${e.temperatureHigh.value}`,unit:e.temperatureLow.unit||e.temperatureHigh.unit});return[\"humidity\",\"pressure\",\"visibility\"].forEach((t=>{return n=e[t],void(void 0!==n?.value&&i.push(n));var n})),void 0===e.windSpeed?.value&&void 0===e.windBearing?.value||i.push({icon:e.windSpeed?.icon||\"mdi:weather-windy\",value:`${e.windBearing?.value?`${e.windBearing.value} `:\"\"}${e.windSpeed?.value??\"\"}`,unit:e.windSpeed?.unit?`${e.windSpeed.unit}`:\"\"}),[\"nextRising\",\"nextSetting\"].forEach((t=>{const n=e[t];n?.value&&i.push({icon:n.icon,value:n.value,unit:\"\"})})),i},lt=(e,t)=>{const i=[];return[\"epa_aqi\",\"epa_primary_pollutant\",\"pm25\",\"pm10\",\"o3\",\"no2\",\"co\",\"so2\"].forEach((t=>{return n=e[t],void(void 0!==n?.value&&i.push(n));var n})),i},ct=(e,t)=>{const i=[],n=e=>F`\n    <span class=\"present-value-block\">\n      ${e.value}${e.unit?F`<span class=\"present-unit\">${e.unit}</span>`:\"\"}\n      <ha-icon icon=\"${e.icon}\" style=${e.icon_color?`color: ${e.icon_color}`:\"\"}></ha-icon>\n    </span>\n  `;i.push(...rt(e,t),...lt(e));const a=[];for(let e=0;e<i.length;e+=2){const t=i[e],o=i[e+1];(t&&t.value||o&&o.value)&&a.push(F`\n        <div class=\"present-row\">\n          <div class=\"present-left\">${t?(s=t,F`\n    <span class=\"present-value-block\">\n      <ha-icon icon=\"${s.icon}\" style=${s.icon_color?`color: ${s.icon_color}`:\"\"}></ha-icon>\n      ${s.value}${s.unit?F`<span class=\"present-unit\">${s.unit}</span>`:\"\"}\n    </span>\n  `):F``}</div>\n          <div class=\"present-right\">${o?n(o):F``}</div>\n        </div>\n      `)}var s;return a.length>0?F`\n    <div class=\"present-grid-container\">\n      ${a}\n    </div>\n  `:F``},dt=(e,t,i,n,a)=>{const s=t||e.selectedLanguage||e.language,o=((e,t,i,n,a)=>{const s=Ue(t),o=a?e.states[a]:void 0,{next_rising:r,next_setting:l}=o?.attributes??{};return{nextRising:{value:r?new Date(r).toLocaleTimeString(s.locale,{hour:\"2-digit\",minute:\"2-digit\",second:\"2-digit\",hour12:!1,timeZone:s.timezone}):void 0,icon:\"mdi:weather-sunset-up\"},nextSetting:{value:r?new Date(l).toLocaleTimeString(s.locale,{hour:\"2-digit\",minute:\"2-digit\",second:\"2-digit\",hour12:!1,timeZone:s.timezone}):void 0,icon:\"mdi:weather-sunset-down\"},precipitationIntensity:{value:je({entityId:n.precipitation_intensity,hass:e,lang:t,decimals:2}),unit:Re(e,n.precipitation_intensity),icon:\"mdi:weather-rainy\"},precipitationProbability:{value:je({entityId:n.precipitation_probability,hass:e,lang:t,decimals:0}),unit:Re(e,n.precipitation_probability),icon:\"mdi:weather-rainy\"},humidity:{value:je({entityId:n.humidity,hass:e,lang:t,decimals:0}),unit:Re(e,n.humidity),icon:\"mdi:water-percent\"},windBearing:{value:Fe(Me(e,n.wind_bearing),i)},windSpeed:{value:je({entityId:n.wind_speed,hass:e,lang:t,decimals:0}),unit:Re(e,n.wind_speed),icon:\"mdi:weather-windy\"},pressure:{value:je({entityId:n.pressure,hass:e,lang:t,decimals:0}),unit:Re(e,n.pressure),icon:\"mdi:gauge\"},visibility:{value:je({entityId:n.visibility,hass:e,lang:t,decimals:0}),unit:Re(e,n.visibility),icon:\"mdi:weather-fog\"},temperatureHigh:{value:je({entityId:n.temperature_max,hass:e,lang:t,decimals:0}),unit:Re(e,n.temperature_max),icon:\"mdi:thermometer\"},temperatureLow:{value:je({entityId:n.temperature_min,hass:e,lang:t,decimals:0}),unit:Re(e,n.temperature_min),icon:\"mdi:thermometer\"}}})(e,s,i.windDirections,n,a);return ct({...o},s)},ht=[\"I\",\"II\",\"III\",\"IV\",\"V\",\"VI\"],ut=[\"#F1D1B1\",\"#E4B590\",\"#CF9F7D\",\"#B67851\",\"#A15E2D\",\"#513938\"],pt=(e,t)=>{const i=[],n=e=>F`\n    <span class=\"ultraviolet-value-block\">\n      ${e.value}${e.unit?F`<span class=\"ultraviolet-unit\">${e.unit}</span>`:\"\"}\n      <ha-icon icon=\"${e.icon}\" style=\"${\"on\"===e.value?\"color: red;\":\"\"}\"></ha-icon>\n    </span>\n  `,a=(e,t)=>{void 0!==t?.value&&i.push(t)};let s=[\"protectionWindow\",\"currentUVLevel\"];s.forEach((t=>a(0,e[t]))),void 0!==e.currentUVIndex?.value&&void 0!==e.maxUVIndex?.value&&i.push({icon:e.currentUVIndex.icon||e.maxUVIndex.icon||\"mdi:weather-sunny\",value:`${e.currentUVIndex.value} / ${e.maxUVIndex.value}`,unit:e.currentUVIndex.unit||e.maxUVIndex.unit}),s=[\"currentOzoneLevel\"],s.forEach((t=>a(0,e[t])));const o=[];for(let e=0;e<i.length;e+=2){const t=i[e],a=i[e+1];o.push(F`\n      <div class=\"ultraviolet-row\">\n        <div class=\"ultraviolet-left\">${t?(r=t,F`\n    <span class=\"ultraviolet-value-block\">\n      <ha-icon icon=\"${r.icon}\" style=\"${\"on\"===r.value?\"color: red;\":\"\"}\"></ha-icon>\n      ${r.value}${r.unit?F`<span class=\"ultraviolet-unit\">${r.unit}</span>`:\"\"}\n    </span>\n  `):F``}</div>\n        <div class=\"ultraviolet-right\">${a?n(a):F``}</div>\n      </div>\n    `)}var r;const l=[t.skinType1,t.skinType2,t.skinType3,t.skinType4,t.skinType5,t.skinType6],c=F`\n  <div class=\"ultraviolet-skin-type-grid\">\n  ${l.map(((e,t)=>{const i=ut[t],n=(e=>{const t=e.replace(\"#\",\"\");return(299*parseInt(t.substr(0,2),16)+587*parseInt(t.substr(2,2),16)+114*parseInt(t.substr(4,2),16))/1e3>125?\"#000\":\"#fff\"})(i);return F`\n      <div\n        class=\"ultraviolet-skin-type-cell\"\n        style=\"background: ${i};\"\n        title=\"Fototipo ${ht[t]}\"\n      >\n        <div class=\"ultraviolet-skin-type-label\">${ht[t]}</div>\n        <div class=\"ultraviolet-exposure-time\" style=\"color: ${n};\">${e.value||\"--\"}</div>\n      </div>\n    `}))}\n  </div>\n  `;return F`\n    <div class=\"ultraviolet-grid-container\">\n      ${o}\n      ${c}\n    </div>\n  `},mt=e=>{const t=\"string\"==typeof e&&\"unknown\"===e.toLowerCase()?NaN:Number(e);if(!Number.isFinite(t)||t<0)return\"--\";const i=Math.floor(t/60),n=t%60;return i>0?`${i}:${function(e,t,i=\"0\"){return e.toString().padStart(t,i)}(n,2)} h`:`${n} m`},gt=(e,t,i)=>({protectionWindow:{value:Me(e,i.protection_window)&&\"unknown\"!==Me(e,i.protection_window)?Me(e,i.protection_window):\"off\",icon:\"mdi:sunglasses\"},currentUVLevel:{value:Me(e,i.uv_level),icon:\"mdi:weather-sunny\"},currentUVIndex:{value:je({entityId:i.uv_index,hass:e,lang:t}),unit:\"UV Idx\",icon:\"mdi:weather-sunny\"},maxUVIndex:{value:je({entityId:i.max_uv_index,hass:e,lang:t}),unit:\"UV Idx\",icon:\"mdi:weather-sunny\"},currentOzoneLevel:{value:je({entityId:i.ozone_level,hass:e,lang:t}),unit:\"DU\",icon:\"mdi:vector-triangle\"}}),yt=(e,t,i)=>({skinType1:{value:mt(je({entityId:i.set_skin_type_1,hass:e,lang:t}))},skinType2:{value:mt(je({entityId:i.set_skin_type_2,hass:e,lang:t}))},skinType3:{value:mt(je({entityId:i.set_skin_type_3,hass:e,lang:t}))},skinType4:{value:mt(je({entityId:i.set_skin_type_4,hass:e,lang:t}))},skinType5:{value:mt(je({entityId:i.set_skin_type_5,hass:e,lang:t}))},skinType6:{value:mt(je({entityId:i.set_skin_type_6,hass:e,lang:t}))}}),ft=[\"basso\",\"moderato\",\"alto\",\"molto-alto\",\"estremo\"],vt=(e,t,i)=>{const n=i-t+1,a=ft.slice(0,n);return 0===e.length?F``:F`\n    <div class=\"pollen-grid-container\">\n      ${e.map((e=>{const n=((e,t,i)=>{const n=(i-t+1)/ft.length,a=Math.floor((e-t)/n);return Math.min(a,ft.length-1)})(e.value,t,i);return F`\n          <div class=\"pollen-stack\">\n            <div class=\"levels\">\n              ${a.map(((e,t)=>F`\n                <div\n                  class=\"level ${e} ${t===n?\"active\":\"\"}\"\n                  title=\"${e}\"\n                ></div>\n              `))}\n            </div>\n            <div class=\"pollen-name\">${e.name}</div>\n          </div>\n        `}))}\n    </div>\n  `},_t=(e,t,i)=>{const n=[];return Array.isArray(i.entities)&&i.entities.length>0&&i.entities.forEach((t=>{const a=Me(e,t.entity);if(a&&\"unknown\"!==a&&\"unavailable\"!==a){let a=((e,t=\"en-US\")=>{if(\"number\"==typeof e)return e;const i=new Intl.NumberFormat(t).formatToParts(1234567.89),n=i.find((e=>\"group\"===e.type))?.value||\"\",a=i.find((e=>\"decimal\"===e.type))?.value||\".\",s=e.replace(new RegExp(`\\\\${n}`,\"g\"),\"\").replace(new RegExp(`\\\\${a}`),\".\");return Number(s)})(Me(e,t.entity));(Number.isNaN(a)||a<i.min||a>i.max)&&(a=0),n.push({name:t.name,value:a})}})),vt(n,i.min,i.max)},wt=(e,t)=>{const i=t.map((e=>{const t=e.reference?.value,i=e.condition?.img,n=e.condition?.icon,a=e.condition?.iconColor,s=e.temperature_low?.value,o=e.temperature_high?.value,r=e.temperature_high?.unit||e.temperature_low?.unit,l=Number(e.precipitation_probability?.value??0),c=e.precipitation_intensity?.value,d=e.precipitation_intensity?.unit,h=e.temperature?.value,u=e.temperature?.unit||e.temperature_feelslike?.unit,p=e.temperature_feelslike?.value,m=e.wind_speed?.value,g=e.wind_speed?.unit,y=e.wind_bearing?.value,f=e.wind_wave_height_max?.value,v=e.swell_wave_height_max?.value,_=e.wave_height_max?.value,w=e.wave_direction?.value,$=e.wave_direction?.icon,x=e.wave_height_max?.unit;return F`\n      <div class=\"weather-forecast-slot\">\n        ${t?F`<div class=\"weather-forecast-label-slot\">${t}</div>`:\"\"}\n        ${i?F`<img class=\"weather-forecast-icon\" src=\"${i}\" alt=\"${i}\" />`:\"\"}\n        ${n?F`<ha-icon icon=\"${n}\" style=${a?`color: ${a}`:\"\"}></ha-icon>`:\"\"}\n        ${void 0!==s&&void 0!==o?F`\n                <div class=\"weather-forecast-temperature\">\n                  ${s} / <span class=\"high\">${o}${r?` ${r}`:\"\"}</span>\n                </div>\n              `:\"\"}\n        ${void 0!==h&&void 0!==p?F`\n                <div class=\"weather-forecast-temperature\">\n                  ${h} / <span class=\"high\">${p}${u?` ${u}`:\"\"}</span>\n                </div>\n              `:\"\"}\n        ${void 0!==m&&void 0!==y?F`\n                <div class=\"weather-forecast-temperature\">\n                  ${m} ${g} ${y}</span>\n                </div>\n              `:\"\"}\n        ${void 0!==_?F`\n                <div class=\"weather-forecast-temperature\">\n                  ${_} ${x?` ${x}`:\"\"}\n                </div>\n              `:\"\"}\n        ${void 0!==w?F`\n                <div class=\"weather-forecast-temperature\">\n                  ${$?F`<ha-icon\n                        icon=\"mdi:arrow-up-thin\"\n                        style=\"display:inline-block; transform: rotate(${$}deg);\"\n                      ></ha-icon>`:\"\"} ${w}\n                </div>\n              `:\"\"}\n        ${void 0!==f&&void 0!==v?F`\n                <div class=\"weather-forecast-temperature\">\n                  ${v} / ${f} ${x?` ${x}`:\"\"}\n                </div>\n              `:\"\"}\n        ${void 0!==l&&void 0!==c&&0!==l?F`\n                <div class=\"weather-forecast-precipitation\">\n                  ${l} % / <span class=\"mm\">${c}${d?` ${d}`:\"\"}</span>\n                </div>\n              `:\"\"}\n      </div>\n    `}));let n=\"Daily\";return 1===e?n=\"Hourly\":2===e?n=\"Marine daily\":3===e&&(n=\"Marine hourly\"),F`\n  <div class=\"weather-forecast-grid-wrapper\">\n    <div class=\"weather-forecast-title\">${n} forecast</div>\n    <div class=\"weather-forecast-grid-container\">\n      ${i}\n    </div>\n  </div>\n  `},$t=e=>e.includes(\"temperature\")?\"mdi:thermometer\":e.includes(\"precipitation\")?\"mdi:weather-rainy\":\"mdi:help-circle-outline\",xt=(e,t,i,n,a,s,o,r,l,c)=>{const d=[],h=Me(e,c);let u=d;if(n){u=Object.keys(n.condition||n.temperature_high||n.temperature_low||n.precipitation_intensity||n.precipitation_probability||{}).map((i=>((e,t,i,n,a,s,o)=>{const r={},l=Ue(t);let c;if(i.condition&&i.condition[o]&&(r.condition={img:tt(Me(e,i.condition[o]),a,s)}),[\"temperature_high\",\"temperature_low\",\"precipitation_intensity\",\"precipitation_probability\"].forEach((n=>{const a=i[n],s=a?.[o];let l=0;s&&(\"precipitation_intensity\"===n&&(l=2),c=new Date(Le(e,s,\"datetime\")),r[n]={value:je({entityId:s,hass:e,lang:t,decimals:l}),unit:Re(e,s),img:He(e,s)||$t(n)})})),c&&Object.keys(r).length>0){const e=c.toLocaleDateString(l.locale,{weekday:\"short\",timeZone:\"UTC\"}),t=c.toLocaleTimeString(l.locale,{hour:\"2-digit\",minute:\"2-digit\",timeZone:l.timezone});r.reference={value:0===n?e.toUpperCase():t}}return r})(e,t,n,r,l,h,i)))}let p=d;if(a){p=Object.keys(a.condition||a.temperature||a.temperature_feelslike||a.precipitation_intensity||a.precipitation_probability||{}).map((n=>((e,t,i,n,a,s,o,r)=>{const l={},c=Ue(t);let d;if(n.condition&&n.condition[r]&&(l.condition={img:tt(Me(e,n.condition[r]),s,o)}),n.wind_bearing&&n.wind_bearing[r]&&(l.wind_bearing={value:Fe(Me(e,n.wind_bearing[r]),i)}),[\"temperature\",\"temperature_feelslike\",\"precipitation_intensity\",\"precipitation_probability\",\"wind_speed\"].forEach((i=>{const a=n[i],s=a?.[r];let o=0;s&&(\"precipitation_intensity\"===i&&(o=2),d=new Date(Le(e,s,\"datetime\")),l[i]={value:je({entityId:s,hass:e,lang:t,decimals:o}),unit:Re(e,s),img:He(e,s)||$t(i)})})),d&&Object.keys(l).length>0){const e=d.toLocaleTimeString(c.locale,{hour:\"2-digit\",minute:\"2-digit\",timeZone:c.timezone});l.reference={value:e}}return l})(e,t,i.windDirections,a,0,l,h,n)))}let m=d;if(s){m=Object.keys(s.swell_wave_height_max||s.wave_direction||s.wave_height_max||s.wind_wave_height_max||{}).map((n=>((e,t,i,n,a,s,o,r)=>{const l={},c=Ue(t);let d;var h,u,p;if(n.wave_height_max&&n.swell_wave_height_max&&n.wind_wave_height_max&&n.swell_wave_height_max[r]&&n.wind_wave_height_max[r]&&(l.condition={icon:\"mdi:flag-variant\",iconColor:(h=n.wave_height_max[r],u=n.swell_wave_height_max[r],p=n.wind_wave_height_max[r],h>=1.8||u>=1.5&&p>=.8?\"red\":h>=1||u>=.8||p>=.6?\"yellow\":\"green\")}),n.wave_direction&&n.wave_direction[r]&&(l.wave_direction={value:Fe(Me(e,n.wave_direction[r]),i),icon:Me(e,n.wave_direction[r])}),[\"wave_height_max\",\"swell_wave_height_max\",\"wind_wave_height_max\"].forEach((i=>{const a=n[i],s=a?.[r];s&&(d=new Date(Le(e,s,\"datetime\")),l[i]={value:je({entityId:s,hass:e,lang:t,decimals:1}),unit:Re(e,s),img:He(e,s)||$t(i)})})),d&&Object.keys(l).length>0){const e=d.toLocaleDateString(c.locale,{weekday:\"short\",timeZone:\"UTC\"}),t=d.toLocaleTimeString(c.locale,{hour:\"2-digit\",minute:\"2-digit\",timeZone:c.timezone});l.reference={value:2===a?e.toUpperCase():t}}return l})(e,t,i.windDirections,s,r,0,0,n)))}switch(r){case 0:return wt(r,u);case 1:return wt(r,p);case 2:return wt(r,m);default:return wt(r,d)}},bt=(e,t,i,n,a)=>{const s=a&&e.states[a],o=s?.attributes?.entity_picture;return((e,t,i,n)=>i?F`\n    <div \n      class=\"camera-container\"\n      @click=${i=>e(i,t)}\n    >\n      <div class=\"camera-image\">\n        <img \n          src=\"${i}\" \n          alt=\"${n}\"\n          loading=\"lazy\"\n        />\n      </div>\n    </div>\n  `:F``)(n,a,o,s?.attributes?.friendly_name??a)};const At=(e,t,i,n)=>{const a={wind:\"mdi:weather-windy\",\"snow-ice\":\"mdi:snowflake-alert\",thunderstorm:\"mdi:weather-lightning\",fog:\"mdi:weather-fog\",\"high-temperature\":\"mdi:weather-sunny-alert\",\"low-temperature\":\"mdi:thermometer-low\",\"coastal-event\":\"mdi:home-flood\",\"forest-fire\":\"mdi:pine-tree-fire\",avalanche:\"mdi:image-filter-hdr\",rain:\"mdi:weather-pouring\",flood:\"mdi:home-flood\",\"rain-flood\":\"mdi:weather-pouring\",\"marine-hazard\":\"mdi:weather-hurricane\",drought:\"mdi:water-off\"},s={green:\"green\",yellow:\"#ffa600\",orange:\"orange\",red:\"red\"},o=n&&e.states[n];if(!o?.attributes)return{};const r={};if(\"on\"===o.state&&o.attributes){const e=Ue(t),{event:i,severity:n,awareness_type:l,awareness_level:c,effective:d}=o.attributes,h=l?.split(\";\")[1]?.trim().toLowerCase()||\"\",u=c?.split(\";\")[1]?.trim().toLowerCase()||\"\",p=i||\"\",m=n?.split(\";\")[1]?.trim()||\"\";(e=>{const t=new Date(e),i=new Date,n=new Date(i.getFullYear(),i.getMonth(),i.getDate()),a=new Date(t.getFullYear(),t.getMonth(),t.getDate()),s=Math.round((a.getTime()-n.getTime())/864e5);let o;o=0===s?\"oggi\":1===s?\"domani\":2===s?\"dopodomani\":void 0})(d),r.meteoalarm={event:p,severity:m,icon:a[h]||\"mdi:alert\",icon_color:s[u]||\"grey\",datetime:new Date(d).toLocaleDateString(e.locale,{weekday:\"short\",timeZone:e.timezone}).toLocaleUpperCase()}}return r},zt=(e,t,i,n)=>{if(!n)return{};const a=Ue(t),s={0:\"gray\",1:\"green\",2:\"#ffa600\",3:\"orange\",4:\"red\"},o={};return[\"thunderstorms\",\"hydraulic\",\"hydrogeological\"].forEach((t=>{const i=n[t],r=i&&e.states[i];if(r&&\"on\"===r.state&&r.attributes){const{level:e,info:i,icon:n}=r.attributes;o[t]={event:i,severity:e,icon:n,icon_color:s[e],datetime:(new Date).toLocaleDateString(a.locale,{weekday:\"short\",timeZone:a.timezone}).toLocaleUpperCase()}}})),o},Et=(e,t,i,n,a)=>{const s={...At(e,t,0,n),...zt(e,t,0,a)};return(o=s)&&0!==Object.keys(o).length?F`\n  <div class=\"meteodcpalarm-grid-container\">\n    ${Object.entries(o).map((([e,t])=>F`\n      <div class=\"meteodcpalarm-group\">\n        <ha-icon icon=\"${t.icon}\" style=\"color: ${t.icon_color};\"></ha-icon>\n        <div class=\"meteodcpalarm-label\">${t.datetime}</div>\n        <div class=\"meteodcpalarm-label\">${t.event}</div>\n      </div>\n    `))}\n  </div>\n  `:F``;var o},{translations:kt,imagePath:St}=await nt();let Ct=class extends at{constructor(){super(...arguments),this._translations=kt,this._imagesPath=St}_render(){return F`\n      <ha-card class=\"ha-card-weather-conditions\">\n        <div class=\"nd-container\">\n          ${this._buildTemplate()}\n        </div>\n      </ha-card>\n    `}_buildTemplate(){let e=F``,t=F``,i=F``,n=F``,a=F``,s=F``,o=F``,r=F``,l=F``,c=F``,d=F``;const h=e=>xt(this.hass,this._language,this._terms,this._config.weather.daily_forecasts,this._config.weather.hourly_forecasts,this._config.weather.marine_daily_forecasts,this._config.weather.marine_hourly_forecasts,e,this._iconsConfig,this._config.weather.sun);var u,p,m;return this._hasPresent&&(e=st(this.hass,this._language,this._terms,this._iconsConfig,this._config.weather?.name,this._config?.weather?.present||null,this._config?.weather?.sun,this._config?.weather?.moonphase)),this._hasPresent&&(t=dt(this.hass,this._language,this._terms,this._config?.weather?.present||{},this._config?.weather?.sun)),(this._hasMetealarm||this._hasDPCalarm)&&(o=Et(this.hass,this._language,this._terms,this._config?.weather?.meteoalarm,this._config?.weather?.dpcalarm)),this._hasDailyForecasts&&(i=h(0)),this._hasHourlyForecasts&&(n=h(1)),this._hasMarineDailyForecasts&&(a=h(2)),this._hasMarineHourlyForecasts&&(s=h(3)),this._hasUltraviolet&&(u=this.hass,p=this._language,m=this._config.ultraviolet,r=pt({...gt(u,p,m)},{...yt(u,p,m)})),this._hasPollen&&(l=_t(this.hass,this._language,this._config.pollen)),this._hasAirQuality&&(c=((e,t,i)=>{const n=t||e.selectedLanguage||e.language,a=je({entityId:i.pm25,hass:e,lang:t,decimals:0}),s=je({entityId:i.pm10,hass:e,lang:t,decimals:0}),o=je({entityId:i.o3,hass:e,lang:t,decimals:1}),r=je({entityId:i.no2,hass:e,lang:t,decimals:0}),l=je({entityId:i.co,hass:e,lang:t,decimals:1}),c=je({entityId:i.so2,hass:e,lang:t,decimals:0}),d=je({entityId:i.epa_aqi,hass:e,lang:t,decimals:0}),h=Me(e,i.epa_primary_pollutant),u={pm25:{value:a?`pm2.5 ${a}`:a,unit:Re(e,i.pm25)||\"µg/m³\",icon:\"mdi:weather-hazy\"},pm10:{value:s?`pm10 ${s}`:s,unit:Re(e,i.pm10)||\"µg/m³\",icon:\"mdi:weather-hazy\"},o3:{value:o?`o3 ${o}`:o,unit:Re(e,i.o3)||\"µg/m³\",icon:\"mdi:molecule\"},no2:{value:r?`no2 ${r}`:r,unit:Re(e,i.no2)||\"µg/m³\",icon:\"mdi:molecule\"},co:{value:l?`co ${l}`:l,unit:Re(e,i.co)||\"µg/m³\",icon:\"mdi:molecule\"},so2:{value:c?`so2 ${c}`:c,unit:Re(e,i.so2)||\"µg/m³\",icon:\"mdi:molecule\"},epa_aqi:{value:d?`Air Quality Index ${d}`:d,icon:\"mdi:weather-hazy\",icon_color:(p=Number(Me(e,i.epa_aqi)),p<=50?\"#009966\":p<=100?\"#ffde33\":p<=150?\"#ff9933\":p<=200?\"#cc0033\":p<=300?\"#660099\":\"#7e0023\")},epa_primary_pollutant:{value:h?`Primary ${h}`:h,icon:\"mdi:weather-hazy\"}};var p;return ct(u,n)})(this.hass,this._language,this._config.airquality)),this._hasCamera&&(d=bt(this.hass,this._language,this._terms,this._handlePopup.bind(this),this._config.camera)),F`\n    ${e}\n    ${t}\n    ${n}\n    ${i}\n    ${s}\n    ${a}\n    ${o}\n    ${l}\n    ${r}\n    ${c}\n    ${d}`}_handlePopup(e,t){e.stopPropagation();const i=new Event(\"hass-more-info\",{composed:!0});i.detail={entityId:t},this.dispatchEvent(i)}};Ct=e([(e=>(t,i)=>{void 0!==i?i.addInitializer((()=>{customElements.define(e,t)})):customElements.define(e,t)})(\"ha-card-weather-conditions\")],Ct);export{Ct as HaCardWeatherConditions};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGEtY2FyZC13ZWF0aGVyLWNvbmRpdGlvbnMuanMiLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5lczYuanMiLCIuLi9ub2RlX21vZHVsZXMvQGxpdC9yZWFjdGl2ZS1lbGVtZW50L2Nzcy10YWcuanMiLCIuLi9ub2RlX21vZHVsZXMvQGxpdC9yZWFjdGl2ZS1lbGVtZW50L3JlYWN0aXZlLWVsZW1lbnQuanMiLCIuLi9ub2RlX21vZHVsZXMvbGl0LWh0bWwvbGl0LWh0bWwuanMiLCIuLi9ub2RlX21vZHVsZXMvbGl0LWVsZW1lbnQvbGl0LWVsZW1lbnQuanMiLCIuLi9ub2RlX21vZHVsZXMvQGxpdC9yZWFjdGl2ZS1lbGVtZW50L2RlY29yYXRvcnMvY3VzdG9tLWVsZW1lbnQuanMiLCIuLi9ub2RlX21vZHVsZXMvQGxpdC9yZWFjdGl2ZS1lbGVtZW50L2RlY29yYXRvcnMvcHJvcGVydHkuanMiLCIuLi9zcmMvdXRpbHMvY29sb3JzLnRzIiwiLi4vc3JjL3V0aWxzL2NvbnN0LnRzIiwiLi4vc3JjL2ljb25tb2RlbHMvaW0tYnVpZW5yYWRhci50cyIsIi4uL3NyYy9pY29ubW9kZWxzL2ltLWNsaW1hY2VsbC50cyIsIi4uL3NyYy9pY29ubW9kZWxzL2ltLWRhcmtza3kudHMiLCIuLi9zcmMvaWNvbm1vZGVscy9pbS1oYXNzLnRzIiwiLi4vc3JjL2ljb25tb2RlbHMvaW0tb3BlbndlYXRoZXJtYXAudHMiLCIuLi9zcmMvaWNvbm1vZGVscy9pbS1waXJhdGV3ZWF0aGVyLnRzIiwiLi4vYmFja3VwL3R5cGVzLnRzIiwiLi4vc3JjL3V0aWxzL2hlbHBlci50cyIsIi4uL2JhY2t1cC9oYS1jd2MtY29uc3RzLnRzIiwiLi4vc3JjL2Nzcy9jc3MtYmFzZS1jYXJkLnRzIiwiLi4vc3JjL2Nzcy9jc3Mtc3VtbWFyeS50cyIsIi4uL3NyYy9jc3MvY3NzLXByZXNlbnQudHMiLCIuLi9zcmMvY3NzL2Nzcy11bHRyYXZpb2xldC50cyIsIi4uL3NyYy9jc3MvY3NzLXBvbGxlbi50cyIsIi4uL3NyYy9jc3MvY3NzLWNhbWVyYS50cyIsIi4uL3NyYy9jc3MvY3NzLXdlYXRoZXItZm9yZWNhc3QudHMiLCIuLi9zcmMvY3NzL2Nzcy1tZXRlb2FsYXJtLnRzIiwiLi4vc3JjL3V0aWxzL2hlbHBlci1yZW5kZXIudHMiLCIuLi9zcmMvYmFzZS9sb3ZlbGFjZS1iYXNlLnRzIiwiLi4vc3JjL3RlbXBsYXRlcy90LXN1bW1hcnkudHMiLCIuLi9zcmMvYnVpbGRlci9iLXN1bW1hcnkudHMiLCIuLi9zcmMvdGVtcGxhdGVzL3QtcHJlc2VudC50cyIsIi4uL3NyYy9idWlsZGVyL2ItcHJlc2VudC50cyIsIi4uL3NyYy90ZW1wbGF0ZXMvdC11bHRyYXZpb2xldC50cyIsIi4uL3NyYy9idWlsZGVyL2ItdWx0cmF2aW9sZXQudHMiLCIuLi9zcmMvdGVtcGxhdGVzL3QtcG9sbGVuLnRzIiwiLi4vc3JjL2J1aWxkZXIvYi1wb2xsZW4udHMiLCIuLi9zcmMvdGVtcGxhdGVzL3Qtd2VhdGhlci1mb3JlY2FzdC50cyIsIi4uL3NyYy9idWlsZGVyL2Itd2VhdGhlci1mb3JlY2FzdC50cyIsIi4uL3NyYy9idWlsZGVyL2ItY2FtZXJhLnRzIiwiLi4vc3JjL3RlbXBsYXRlcy90LWNhbWVyYS50cyIsIi4uL3NyYy9idWlsZGVyL2ItYWlycXVhbGl0eS50cyIsIi4uL3NyYy9idWlsZGVyL2ItbWV0ZW9hbGFybS50cyIsIi4uL3NyYy90ZW1wbGF0ZXMvdC1tZXRlb2FsYXJtLnRzIiwiLi4vc3JjL2hhLXdlYXRoZXItZWNhcmQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlLCBTdXBwcmVzc2VkRXJyb3IsIFN5bWJvbCwgSXRlcmF0b3IgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXNEZWNvcmF0ZShjdG9yLCBkZXNjcmlwdG9ySW4sIGRlY29yYXRvcnMsIGNvbnRleHRJbiwgaW5pdGlhbGl6ZXJzLCBleHRyYUluaXRpYWxpemVycykge1xyXG4gICAgZnVuY3Rpb24gYWNjZXB0KGYpIHsgaWYgKGYgIT09IHZvaWQgMCAmJiB0eXBlb2YgZiAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRnVuY3Rpb24gZXhwZWN0ZWRcIik7IHJldHVybiBmOyB9XHJcbiAgICB2YXIga2luZCA9IGNvbnRleHRJbi5raW5kLCBrZXkgPSBraW5kID09PSBcImdldHRlclwiID8gXCJnZXRcIiA6IGtpbmQgPT09IFwic2V0dGVyXCIgPyBcInNldFwiIDogXCJ2YWx1ZVwiO1xyXG4gICAgdmFyIHRhcmdldCA9ICFkZXNjcmlwdG9ySW4gJiYgY3RvciA/IGNvbnRleHRJbltcInN0YXRpY1wiXSA/IGN0b3IgOiBjdG9yLnByb3RvdHlwZSA6IG51bGw7XHJcbiAgICB2YXIgZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JJbiB8fCAodGFyZ2V0ID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGNvbnRleHRJbi5uYW1lKSA6IHt9KTtcclxuICAgIHZhciBfLCBkb25lID0gZmFsc2U7XHJcbiAgICBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIHZhciBjb250ZXh0ID0ge307XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4pIGNvbnRleHRbcF0gPSBwID09PSBcImFjY2Vzc1wiID8ge30gOiBjb250ZXh0SW5bcF07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4uYWNjZXNzKSBjb250ZXh0LmFjY2Vzc1twXSA9IGNvbnRleHRJbi5hY2Nlc3NbcF07XHJcbiAgICAgICAgY29udGV4dC5hZGRJbml0aWFsaXplciA9IGZ1bmN0aW9uIChmKSB7IGlmIChkb25lKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGFkZCBpbml0aWFsaXplcnMgYWZ0ZXIgZGVjb3JhdGlvbiBoYXMgY29tcGxldGVkXCIpOyBleHRyYUluaXRpYWxpemVycy5wdXNoKGFjY2VwdChmIHx8IG51bGwpKTsgfTtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gKDAsIGRlY29yYXRvcnNbaV0pKGtpbmQgPT09IFwiYWNjZXNzb3JcIiA/IHsgZ2V0OiBkZXNjcmlwdG9yLmdldCwgc2V0OiBkZXNjcmlwdG9yLnNldCB9IDogZGVzY3JpcHRvcltrZXldLCBjb250ZXh0KTtcclxuICAgICAgICBpZiAoa2luZCA9PT0gXCJhY2Nlc3NvclwiKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IHZvaWQgMCkgY29udGludWU7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZFwiKTtcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmdldCkpIGRlc2NyaXB0b3IuZ2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LnNldCkpIGRlc2NyaXB0b3Iuc2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmluaXQpKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoXyA9IGFjY2VwdChyZXN1bHQpKSB7XHJcbiAgICAgICAgICAgIGlmIChraW5kID09PSBcImZpZWxkXCIpIGluaXRpYWxpemVycy51bnNoaWZ0KF8pO1xyXG4gICAgICAgICAgICBlbHNlIGRlc2NyaXB0b3Jba2V5XSA9IF87XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRhcmdldCkgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgY29udGV4dEluLm5hbWUsIGRlc2NyaXB0b3IpO1xyXG4gICAgZG9uZSA9IHRydWU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19ydW5Jbml0aWFsaXplcnModGhpc0FyZywgaW5pdGlhbGl6ZXJzLCB2YWx1ZSkge1xyXG4gICAgdmFyIHVzZVZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluaXRpYWxpemVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHZhbHVlID0gdXNlVmFsdWUgPyBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnLCB2YWx1ZSkgOiBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB1c2VWYWx1ZSA/IHZhbHVlIDogdm9pZCAwO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcHJvcEtleSh4KSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHggPT09IFwic3ltYm9sXCIgPyB4IDogXCJcIi5jb25jYXQoeCk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zZXRGdW5jdGlvbk5hbWUoZiwgbmFtZSwgcHJlZml4KSB7XHJcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIG5hbWUgPSBuYW1lLmRlc2NyaXB0aW9uID8gXCJbXCIuY29uY2F0KG5hbWUuZGVzY3JpcHRpb24sIFwiXVwiKSA6IFwiXCI7XHJcbiAgICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGYsIFwibmFtZVwiLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHByZWZpeCA/IFwiXCIuY29uY2F0KHByZWZpeCwgXCIgXCIsIG5hbWUpIDogbmFtZSB9KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGcgPSBPYmplY3QuY3JlYXRlKCh0eXBlb2YgSXRlcmF0b3IgPT09IFwiZnVuY3Rpb25cIiA/IEl0ZXJhdG9yIDogT2JqZWN0KS5wcm90b3R5cGUpO1xyXG4gICAgcmV0dXJuIGcubmV4dCA9IHZlcmIoMCksIGdbXCJ0aHJvd1wiXSA9IHZlcmIoMSksIGdbXCJyZXR1cm5cIl0gPSB2ZXJiKDIpLCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKGcgJiYgKGcgPSAwLCBvcFswXSAmJiAoXyA9IDApKSwgXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XHJcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xyXG4gICAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XHJcbiAgICB9XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xyXG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIG9bazJdID0gbVtrXTtcclxufSk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIG8pIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBzID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5pdGVyYXRvciwgbSA9IHMgJiYgb1tzXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheSh0bywgZnJvbSwgcGFjaykge1xyXG4gICAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICBpZiAoYXIgfHwgIShpIGluIGZyb20pKSB7XHJcbiAgICAgICAgICAgIGlmICghYXIpIGFyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSwgMCwgaSk7XHJcbiAgICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IE9iamVjdC5jcmVhdGUoKHR5cGVvZiBBc3luY0l0ZXJhdG9yID09PSBcImZ1bmN0aW9uXCIgPyBBc3luY0l0ZXJhdG9yIDogT2JqZWN0KS5wcm90b3R5cGUpLCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIsIGF3YWl0UmV0dXJuKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gYXdhaXRSZXR1cm4oZikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGYsIHJlamVjdCk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpZiAoZ1tuXSkgeyBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyBpZiAoZikgaVtuXSA9IGYoaVtuXSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IGZhbHNlIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbnZhciBvd25LZXlzID0gZnVuY3Rpb24obykge1xyXG4gICAgb3duS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIHx8IGZ1bmN0aW9uIChvKSB7XHJcbiAgICAgICAgdmFyIGFyID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgayBpbiBvKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIGspKSBhclthci5sZW5ndGhdID0gaztcclxuICAgICAgICByZXR1cm4gYXI7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIG93bktleXMobyk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayA9IG93bktleXMobW9kKSwgaSA9IDA7IGkgPCBrLmxlbmd0aDsgaSsrKSBpZiAoa1tpXSAhPT0gXCJkZWZhdWx0XCIpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwga1tpXSk7XHJcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4oc3RhdGUsIHJlY2VpdmVyKSB7XHJcbiAgICBpZiAocmVjZWl2ZXIgPT09IG51bGwgfHwgKHR5cGVvZiByZWNlaXZlciAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVjZWl2ZXIgIT09IFwiZnVuY3Rpb25cIikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgdXNlICdpbicgb3BlcmF0b3Igb24gbm9uLW9iamVjdFwiKTtcclxuICAgIHJldHVybiB0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyID09PSBzdGF0ZSA6IHN0YXRlLmhhcyhyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZShlbnYsIHZhbHVlLCBhc3luYykge1xyXG4gICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB2b2lkIDApIHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IGV4cGVjdGVkLlwiKTtcclxuICAgICAgICB2YXIgZGlzcG9zZSwgaW5uZXI7XHJcbiAgICAgICAgaWYgKGFzeW5jKSB7XHJcbiAgICAgICAgICAgIGlmICghU3ltYm9sLmFzeW5jRGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0Rpc3Bvc2UgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgICAgICAgICBkaXNwb3NlID0gdmFsdWVbU3ltYm9sLmFzeW5jRGlzcG9zZV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkaXNwb3NlID09PSB2b2lkIDApIHtcclxuICAgICAgICAgICAgaWYgKCFTeW1ib2wuZGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5kaXNwb3NlIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgICAgICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5kaXNwb3NlXTtcclxuICAgICAgICAgICAgaWYgKGFzeW5jKSBpbm5lciA9IGRpc3Bvc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0eXBlb2YgZGlzcG9zZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IG5vdCBkaXNwb3NhYmxlLlwiKTtcclxuICAgICAgICBpZiAoaW5uZXIpIGRpc3Bvc2UgPSBmdW5jdGlvbigpIHsgdHJ5IHsgaW5uZXIuY2FsbCh0aGlzKTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7IH0gfTtcclxuICAgICAgICBlbnYuc3RhY2sucHVzaCh7IHZhbHVlOiB2YWx1ZSwgZGlzcG9zZTogZGlzcG9zZSwgYXN5bmM6IGFzeW5jIH0pO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoYXN5bmMpIHtcclxuICAgICAgICBlbnYuc3RhY2sucHVzaCh7IGFzeW5jOiB0cnVlIH0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG5cclxufVxyXG5cclxudmFyIF9TdXBwcmVzc2VkRXJyb3IgPSB0eXBlb2YgU3VwcHJlc3NlZEVycm9yID09PSBcImZ1bmN0aW9uXCIgPyBTdXBwcmVzc2VkRXJyb3IgOiBmdW5jdGlvbiAoZXJyb3IsIHN1cHByZXNzZWQsIG1lc3NhZ2UpIHtcclxuICAgIHZhciBlID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xyXG4gICAgcmV0dXJuIGUubmFtZSA9IFwiU3VwcHJlc3NlZEVycm9yXCIsIGUuZXJyb3IgPSBlcnJvciwgZS5zdXBwcmVzc2VkID0gc3VwcHJlc3NlZCwgZTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2Rpc3Bvc2VSZXNvdXJjZXMoZW52KSB7XHJcbiAgICBmdW5jdGlvbiBmYWlsKGUpIHtcclxuICAgICAgICBlbnYuZXJyb3IgPSBlbnYuaGFzRXJyb3IgPyBuZXcgX1N1cHByZXNzZWRFcnJvcihlLCBlbnYuZXJyb3IsIFwiQW4gZXJyb3Igd2FzIHN1cHByZXNzZWQgZHVyaW5nIGRpc3Bvc2FsLlwiKSA6IGU7XHJcbiAgICAgICAgZW52Lmhhc0Vycm9yID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIHZhciByLCBzID0gMDtcclxuICAgIGZ1bmN0aW9uIG5leHQoKSB7XHJcbiAgICAgICAgd2hpbGUgKHIgPSBlbnYuc3RhY2sucG9wKCkpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGlmICghci5hc3luYyAmJiBzID09PSAxKSByZXR1cm4gcyA9IDAsIGVudi5zdGFjay5wdXNoKHIpLCBQcm9taXNlLnJlc29sdmUoKS50aGVuKG5leHQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHIuZGlzcG9zZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSByLmRpc3Bvc2UuY2FsbChyLnZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoci5hc3luYykgcmV0dXJuIHMgfD0gMiwgUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCkudGhlbihuZXh0LCBmdW5jdGlvbihlKSB7IGZhaWwoZSk7IHJldHVybiBuZXh0KCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBzIHw9IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIGZhaWwoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHMgPT09IDEpIHJldHVybiBlbnYuaGFzRXJyb3IgPyBQcm9taXNlLnJlamVjdChlbnYuZXJyb3IpIDogUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgaWYgKGVudi5oYXNFcnJvcikgdGhyb3cgZW52LmVycm9yO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5leHQoKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uKHBhdGgsIHByZXNlcnZlSnN4KSB7XHJcbiAgICBpZiAodHlwZW9mIHBhdGggPT09IFwic3RyaW5nXCIgJiYgL15cXC5cXC4/XFwvLy50ZXN0KHBhdGgpKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhdGgucmVwbGFjZSgvXFwuKHRzeCkkfCgoPzpcXC5kKT8pKCg/OlxcLlteLi9dKz8pPylcXC4oW2NtXT8pdHMkL2ksIGZ1bmN0aW9uIChtLCB0c3gsIGQsIGV4dCwgY20pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRzeCA/IHByZXNlcnZlSnN4ID8gXCIuanN4XCIgOiBcIi5qc1wiIDogZCAmJiAoIWV4dCB8fCAhY20pID8gbSA6IChkICsgZXh0ICsgXCIuXCIgKyBjbS50b0xvd2VyQ2FzZSgpICsgXCJqc1wiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBwYXRoO1xyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCB7XHJcbiAgICBfX2V4dGVuZHM6IF9fZXh0ZW5kcyxcclxuICAgIF9fYXNzaWduOiBfX2Fzc2lnbixcclxuICAgIF9fcmVzdDogX19yZXN0LFxyXG4gICAgX19kZWNvcmF0ZTogX19kZWNvcmF0ZSxcclxuICAgIF9fcGFyYW06IF9fcGFyYW0sXHJcbiAgICBfX2VzRGVjb3JhdGU6IF9fZXNEZWNvcmF0ZSxcclxuICAgIF9fcnVuSW5pdGlhbGl6ZXJzOiBfX3J1bkluaXRpYWxpemVycyxcclxuICAgIF9fcHJvcEtleTogX19wcm9wS2V5LFxyXG4gICAgX19zZXRGdW5jdGlvbk5hbWU6IF9fc2V0RnVuY3Rpb25OYW1lLFxyXG4gICAgX19tZXRhZGF0YTogX19tZXRhZGF0YSxcclxuICAgIF9fYXdhaXRlcjogX19hd2FpdGVyLFxyXG4gICAgX19nZW5lcmF0b3I6IF9fZ2VuZXJhdG9yLFxyXG4gICAgX19jcmVhdGVCaW5kaW5nOiBfX2NyZWF0ZUJpbmRpbmcsXHJcbiAgICBfX2V4cG9ydFN0YXI6IF9fZXhwb3J0U3RhcixcclxuICAgIF9fdmFsdWVzOiBfX3ZhbHVlcyxcclxuICAgIF9fcmVhZDogX19yZWFkLFxyXG4gICAgX19zcHJlYWQ6IF9fc3ByZWFkLFxyXG4gICAgX19zcHJlYWRBcnJheXM6IF9fc3ByZWFkQXJyYXlzLFxyXG4gICAgX19zcHJlYWRBcnJheTogX19zcHJlYWRBcnJheSxcclxuICAgIF9fYXdhaXQ6IF9fYXdhaXQsXHJcbiAgICBfX2FzeW5jR2VuZXJhdG9yOiBfX2FzeW5jR2VuZXJhdG9yLFxyXG4gICAgX19hc3luY0RlbGVnYXRvcjogX19hc3luY0RlbGVnYXRvcixcclxuICAgIF9fYXN5bmNWYWx1ZXM6IF9fYXN5bmNWYWx1ZXMsXHJcbiAgICBfX21ha2VUZW1wbGF0ZU9iamVjdDogX19tYWtlVGVtcGxhdGVPYmplY3QsXHJcbiAgICBfX2ltcG9ydFN0YXI6IF9faW1wb3J0U3RhcixcclxuICAgIF9faW1wb3J0RGVmYXVsdDogX19pbXBvcnREZWZhdWx0LFxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldDogX19jbGFzc1ByaXZhdGVGaWVsZEdldCxcclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQ6IF9fY2xhc3NQcml2YXRlRmllbGRTZXQsXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkSW46IF9fY2xhc3NQcml2YXRlRmllbGRJbixcclxuICAgIF9fYWRkRGlzcG9zYWJsZVJlc291cmNlOiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZSxcclxuICAgIF9fZGlzcG9zZVJlc291cmNlczogX19kaXNwb3NlUmVzb3VyY2VzLFxyXG4gICAgX19yZXdyaXRlUmVsYXRpdmVJbXBvcnRFeHRlbnNpb246IF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uLFxyXG59O1xyXG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlXG4gKi9cbmNvbnN0IHQ9Z2xvYmFsVGhpcyxlPXQuU2hhZG93Um9vdCYmKHZvaWQgMD09PXQuU2hhZHlDU1N8fHQuU2hhZHlDU1MubmF0aXZlU2hhZG93KSYmXCJhZG9wdGVkU3R5bGVTaGVldHNcImluIERvY3VtZW50LnByb3RvdHlwZSYmXCJyZXBsYWNlXCJpbiBDU1NTdHlsZVNoZWV0LnByb3RvdHlwZSxzPVN5bWJvbCgpLG89bmV3IFdlYWtNYXA7Y2xhc3Mgbntjb25zdHJ1Y3Rvcih0LGUsbyl7aWYodGhpcy5fJGNzc1Jlc3VsdCQ9ITAsbyE9PXMpdGhyb3cgRXJyb3IoXCJDU1NSZXN1bHQgaXMgbm90IGNvbnN0cnVjdGFibGUuIFVzZSBgdW5zYWZlQ1NTYCBvciBgY3NzYCBpbnN0ZWFkLlwiKTt0aGlzLmNzc1RleHQ9dCx0aGlzLnQ9ZX1nZXQgc3R5bGVTaGVldCgpe2xldCB0PXRoaXMubztjb25zdCBzPXRoaXMudDtpZihlJiZ2b2lkIDA9PT10KXtjb25zdCBlPXZvaWQgMCE9PXMmJjE9PT1zLmxlbmd0aDtlJiYodD1vLmdldChzKSksdm9pZCAwPT09dCYmKCh0aGlzLm89dD1uZXcgQ1NTU3R5bGVTaGVldCkucmVwbGFjZVN5bmModGhpcy5jc3NUZXh0KSxlJiZvLnNldChzLHQpKX1yZXR1cm4gdH10b1N0cmluZygpe3JldHVybiB0aGlzLmNzc1RleHR9fWNvbnN0IHI9dD0+bmV3IG4oXCJzdHJpbmdcIj09dHlwZW9mIHQ/dDp0K1wiXCIsdm9pZCAwLHMpLGk9KHQsLi4uZSk9Pntjb25zdCBvPTE9PT10Lmxlbmd0aD90WzBdOmUucmVkdWNlKCgoZSxzLG8pPT5lKyh0PT57aWYoITA9PT10Ll8kY3NzUmVzdWx0JClyZXR1cm4gdC5jc3NUZXh0O2lmKFwibnVtYmVyXCI9PXR5cGVvZiB0KXJldHVybiB0O3Rocm93IEVycm9yKFwiVmFsdWUgcGFzc2VkIHRvICdjc3MnIGZ1bmN0aW9uIG11c3QgYmUgYSAnY3NzJyBmdW5jdGlvbiByZXN1bHQ6IFwiK3QrXCIuIFVzZSAndW5zYWZlQ1NTJyB0byBwYXNzIG5vbi1saXRlcmFsIHZhbHVlcywgYnV0IHRha2UgY2FyZSB0byBlbnN1cmUgcGFnZSBzZWN1cml0eS5cIil9KShzKSt0W28rMV0pLHRbMF0pO3JldHVybiBuZXcgbihvLHQscyl9LFM9KHMsbyk9PntpZihlKXMuYWRvcHRlZFN0eWxlU2hlZXRzPW8ubWFwKCh0PT50IGluc3RhbmNlb2YgQ1NTU3R5bGVTaGVldD90OnQuc3R5bGVTaGVldCkpO2Vsc2UgZm9yKGNvbnN0IGUgb2Ygbyl7Y29uc3Qgbz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIiksbj10LmxpdE5vbmNlO3ZvaWQgMCE9PW4mJm8uc2V0QXR0cmlidXRlKFwibm9uY2VcIixuKSxvLnRleHRDb250ZW50PWUuY3NzVGV4dCxzLmFwcGVuZENoaWxkKG8pfX0sYz1lP3Q9PnQ6dD0+dCBpbnN0YW5jZW9mIENTU1N0eWxlU2hlZXQ/KHQ9PntsZXQgZT1cIlwiO2Zvcihjb25zdCBzIG9mIHQuY3NzUnVsZXMpZSs9cy5jc3NUZXh0O3JldHVybiByKGUpfSkodCk6dDtleHBvcnR7biBhcyBDU1NSZXN1bHQsUyBhcyBhZG9wdFN0eWxlcyxpIGFzIGNzcyxjIGFzIGdldENvbXBhdGlibGVTdHlsZSxlIGFzIHN1cHBvcnRzQWRvcHRpbmdTdHlsZVNoZWV0cyxyIGFzIHVuc2FmZUNTU307XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jc3MtdGFnLmpzLm1hcFxuIiwiaW1wb3J0e2dldENvbXBhdGlibGVTdHlsZSBhcyB0LGFkb3B0U3R5bGVzIGFzIHN9ZnJvbVwiLi9jc3MtdGFnLmpzXCI7ZXhwb3J0e0NTU1Jlc3VsdCxjc3Msc3VwcG9ydHNBZG9wdGluZ1N0eWxlU2hlZXRzLHVuc2FmZUNTU31mcm9tXCIuL2Nzcy10YWcuanNcIjtcbi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2VcbiAqL2NvbnN0e2lzOmksZGVmaW5lUHJvcGVydHk6ZSxnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I6aCxnZXRPd25Qcm9wZXJ0eU5hbWVzOnIsZ2V0T3duUHJvcGVydHlTeW1ib2xzOm8sZ2V0UHJvdG90eXBlT2Y6bn09T2JqZWN0LGE9Z2xvYmFsVGhpcyxjPWEudHJ1c3RlZFR5cGVzLGw9Yz9jLmVtcHR5U2NyaXB0OlwiXCIscD1hLnJlYWN0aXZlRWxlbWVudFBvbHlmaWxsU3VwcG9ydCxkPSh0LHMpPT50LHU9e3RvQXR0cmlidXRlKHQscyl7c3dpdGNoKHMpe2Nhc2UgQm9vbGVhbjp0PXQ/bDpudWxsO2JyZWFrO2Nhc2UgT2JqZWN0OmNhc2UgQXJyYXk6dD1udWxsPT10P3Q6SlNPTi5zdHJpbmdpZnkodCl9cmV0dXJuIHR9LGZyb21BdHRyaWJ1dGUodCxzKXtsZXQgaT10O3N3aXRjaChzKXtjYXNlIEJvb2xlYW46aT1udWxsIT09dDticmVhaztjYXNlIE51bWJlcjppPW51bGw9PT10P251bGw6TnVtYmVyKHQpO2JyZWFrO2Nhc2UgT2JqZWN0OmNhc2UgQXJyYXk6dHJ5e2k9SlNPTi5wYXJzZSh0KX1jYXRjaCh0KXtpPW51bGx9fXJldHVybiBpfX0sZj0odCxzKT0+IWkodCxzKSxiPXthdHRyaWJ1dGU6ITAsdHlwZTpTdHJpbmcsY29udmVydGVyOnUscmVmbGVjdDohMSx1c2VEZWZhdWx0OiExLGhhc0NoYW5nZWQ6Zn07U3ltYm9sLm1ldGFkYXRhPz89U3ltYm9sKFwibWV0YWRhdGFcIiksYS5saXRQcm9wZXJ0eU1ldGFkYXRhPz89bmV3IFdlYWtNYXA7Y2xhc3MgeSBleHRlbmRzIEhUTUxFbGVtZW50e3N0YXRpYyBhZGRJbml0aWFsaXplcih0KXt0aGlzLl8kRWkoKSwodGhpcy5sPz89W10pLnB1c2godCl9c3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKXtyZXR1cm4gdGhpcy5maW5hbGl6ZSgpLHRoaXMuXyRFaCYmWy4uLnRoaXMuXyRFaC5rZXlzKCldfXN0YXRpYyBjcmVhdGVQcm9wZXJ0eSh0LHM9Yil7aWYocy5zdGF0ZSYmKHMuYXR0cmlidXRlPSExKSx0aGlzLl8kRWkoKSx0aGlzLnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSh0KSYmKChzPU9iamVjdC5jcmVhdGUocykpLndyYXBwZWQ9ITApLHRoaXMuZWxlbWVudFByb3BlcnRpZXMuc2V0KHQscyksIXMubm9BY2Nlc3Nvcil7Y29uc3QgaT1TeW1ib2woKSxoPXRoaXMuZ2V0UHJvcGVydHlEZXNjcmlwdG9yKHQsaSxzKTt2b2lkIDAhPT1oJiZlKHRoaXMucHJvdG90eXBlLHQsaCl9fXN0YXRpYyBnZXRQcm9wZXJ0eURlc2NyaXB0b3IodCxzLGkpe2NvbnN0e2dldDplLHNldDpyfT1oKHRoaXMucHJvdG90eXBlLHQpPz97Z2V0KCl7cmV0dXJuIHRoaXNbc119LHNldCh0KXt0aGlzW3NdPXR9fTtyZXR1cm57Z2V0OmUsc2V0KHMpe2NvbnN0IGg9ZT8uY2FsbCh0aGlzKTtyPy5jYWxsKHRoaXMscyksdGhpcy5yZXF1ZXN0VXBkYXRlKHQsaCxpKX0sY29uZmlndXJhYmxlOiEwLGVudW1lcmFibGU6ITB9fXN0YXRpYyBnZXRQcm9wZXJ0eU9wdGlvbnModCl7cmV0dXJuIHRoaXMuZWxlbWVudFByb3BlcnRpZXMuZ2V0KHQpPz9ifXN0YXRpYyBfJEVpKCl7aWYodGhpcy5oYXNPd25Qcm9wZXJ0eShkKFwiZWxlbWVudFByb3BlcnRpZXNcIikpKXJldHVybjtjb25zdCB0PW4odGhpcyk7dC5maW5hbGl6ZSgpLHZvaWQgMCE9PXQubCYmKHRoaXMubD1bLi4udC5sXSksdGhpcy5lbGVtZW50UHJvcGVydGllcz1uZXcgTWFwKHQuZWxlbWVudFByb3BlcnRpZXMpfXN0YXRpYyBmaW5hbGl6ZSgpe2lmKHRoaXMuaGFzT3duUHJvcGVydHkoZChcImZpbmFsaXplZFwiKSkpcmV0dXJuO2lmKHRoaXMuZmluYWxpemVkPSEwLHRoaXMuXyRFaSgpLHRoaXMuaGFzT3duUHJvcGVydHkoZChcInByb3BlcnRpZXNcIikpKXtjb25zdCB0PXRoaXMucHJvcGVydGllcyxzPVsuLi5yKHQpLC4uLm8odCldO2Zvcihjb25zdCBpIG9mIHMpdGhpcy5jcmVhdGVQcm9wZXJ0eShpLHRbaV0pfWNvbnN0IHQ9dGhpc1tTeW1ib2wubWV0YWRhdGFdO2lmKG51bGwhPT10KXtjb25zdCBzPWxpdFByb3BlcnR5TWV0YWRhdGEuZ2V0KHQpO2lmKHZvaWQgMCE9PXMpZm9yKGNvbnN0W3QsaV1vZiBzKXRoaXMuZWxlbWVudFByb3BlcnRpZXMuc2V0KHQsaSl9dGhpcy5fJEVoPW5ldyBNYXA7Zm9yKGNvbnN0W3Qsc11vZiB0aGlzLmVsZW1lbnRQcm9wZXJ0aWVzKXtjb25zdCBpPXRoaXMuXyRFdSh0LHMpO3ZvaWQgMCE9PWkmJnRoaXMuXyRFaC5zZXQoaSx0KX10aGlzLmVsZW1lbnRTdHlsZXM9dGhpcy5maW5hbGl6ZVN0eWxlcyh0aGlzLnN0eWxlcyl9c3RhdGljIGZpbmFsaXplU3R5bGVzKHMpe2NvbnN0IGk9W107aWYoQXJyYXkuaXNBcnJheShzKSl7Y29uc3QgZT1uZXcgU2V0KHMuZmxhdCgxLzApLnJldmVyc2UoKSk7Zm9yKGNvbnN0IHMgb2YgZSlpLnVuc2hpZnQodChzKSl9ZWxzZSB2b2lkIDAhPT1zJiZpLnB1c2godChzKSk7cmV0dXJuIGl9c3RhdGljIF8kRXUodCxzKXtjb25zdCBpPXMuYXR0cmlidXRlO3JldHVybiExPT09aT92b2lkIDA6XCJzdHJpbmdcIj09dHlwZW9mIGk/aTpcInN0cmluZ1wiPT10eXBlb2YgdD90LnRvTG93ZXJDYXNlKCk6dm9pZCAwfWNvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLl8kRXA9dm9pZCAwLHRoaXMuaXNVcGRhdGVQZW5kaW5nPSExLHRoaXMuaGFzVXBkYXRlZD0hMSx0aGlzLl8kRW09bnVsbCx0aGlzLl8kRXYoKX1fJEV2KCl7dGhpcy5fJEVTPW5ldyBQcm9taXNlKCh0PT50aGlzLmVuYWJsZVVwZGF0aW5nPXQpKSx0aGlzLl8kQUw9bmV3IE1hcCx0aGlzLl8kRV8oKSx0aGlzLnJlcXVlc3RVcGRhdGUoKSx0aGlzLmNvbnN0cnVjdG9yLmw/LmZvckVhY2goKHQ9PnQodGhpcykpKX1hZGRDb250cm9sbGVyKHQpeyh0aGlzLl8kRU8/Pz1uZXcgU2V0KS5hZGQodCksdm9pZCAwIT09dGhpcy5yZW5kZXJSb290JiZ0aGlzLmlzQ29ubmVjdGVkJiZ0Lmhvc3RDb25uZWN0ZWQ/LigpfXJlbW92ZUNvbnRyb2xsZXIodCl7dGhpcy5fJEVPPy5kZWxldGUodCl9XyRFXygpe2NvbnN0IHQ9bmV3IE1hcCxzPXRoaXMuY29uc3RydWN0b3IuZWxlbWVudFByb3BlcnRpZXM7Zm9yKGNvbnN0IGkgb2Ygcy5rZXlzKCkpdGhpcy5oYXNPd25Qcm9wZXJ0eShpKSYmKHQuc2V0KGksdGhpc1tpXSksZGVsZXRlIHRoaXNbaV0pO3Quc2l6ZT4wJiYodGhpcy5fJEVwPXQpfWNyZWF0ZVJlbmRlclJvb3QoKXtjb25zdCB0PXRoaXMuc2hhZG93Um9vdD8/dGhpcy5hdHRhY2hTaGFkb3codGhpcy5jb25zdHJ1Y3Rvci5zaGFkb3dSb290T3B0aW9ucyk7cmV0dXJuIHModCx0aGlzLmNvbnN0cnVjdG9yLmVsZW1lbnRTdHlsZXMpLHR9Y29ubmVjdGVkQ2FsbGJhY2soKXt0aGlzLnJlbmRlclJvb3Q/Pz10aGlzLmNyZWF0ZVJlbmRlclJvb3QoKSx0aGlzLmVuYWJsZVVwZGF0aW5nKCEwKSx0aGlzLl8kRU8/LmZvckVhY2goKHQ9PnQuaG9zdENvbm5lY3RlZD8uKCkpKX1lbmFibGVVcGRhdGluZyh0KXt9ZGlzY29ubmVjdGVkQ2FsbGJhY2soKXt0aGlzLl8kRU8/LmZvckVhY2goKHQ9PnQuaG9zdERpc2Nvbm5lY3RlZD8uKCkpKX1hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sodCxzLGkpe3RoaXMuXyRBSyh0LGkpfV8kRVQodCxzKXtjb25zdCBpPXRoaXMuY29uc3RydWN0b3IuZWxlbWVudFByb3BlcnRpZXMuZ2V0KHQpLGU9dGhpcy5jb25zdHJ1Y3Rvci5fJEV1KHQsaSk7aWYodm9pZCAwIT09ZSYmITA9PT1pLnJlZmxlY3Qpe2NvbnN0IGg9KHZvaWQgMCE9PWkuY29udmVydGVyPy50b0F0dHJpYnV0ZT9pLmNvbnZlcnRlcjp1KS50b0F0dHJpYnV0ZShzLGkudHlwZSk7dGhpcy5fJEVtPXQsbnVsbD09aD90aGlzLnJlbW92ZUF0dHJpYnV0ZShlKTp0aGlzLnNldEF0dHJpYnV0ZShlLGgpLHRoaXMuXyRFbT1udWxsfX1fJEFLKHQscyl7Y29uc3QgaT10aGlzLmNvbnN0cnVjdG9yLGU9aS5fJEVoLmdldCh0KTtpZih2b2lkIDAhPT1lJiZ0aGlzLl8kRW0hPT1lKXtjb25zdCB0PWkuZ2V0UHJvcGVydHlPcHRpb25zKGUpLGg9XCJmdW5jdGlvblwiPT10eXBlb2YgdC5jb252ZXJ0ZXI/e2Zyb21BdHRyaWJ1dGU6dC5jb252ZXJ0ZXJ9OnZvaWQgMCE9PXQuY29udmVydGVyPy5mcm9tQXR0cmlidXRlP3QuY29udmVydGVyOnU7dGhpcy5fJEVtPWUsdGhpc1tlXT1oLmZyb21BdHRyaWJ1dGUocyx0LnR5cGUpPz90aGlzLl8kRWo/LmdldChlKT8/bnVsbCx0aGlzLl8kRW09bnVsbH19cmVxdWVzdFVwZGF0ZSh0LHMsaSl7aWYodm9pZCAwIT09dCl7Y29uc3QgZT10aGlzLmNvbnN0cnVjdG9yLGg9dGhpc1t0XTtpZihpPz89ZS5nZXRQcm9wZXJ0eU9wdGlvbnModCksISgoaS5oYXNDaGFuZ2VkPz9mKShoLHMpfHxpLnVzZURlZmF1bHQmJmkucmVmbGVjdCYmaD09PXRoaXMuXyRFaj8uZ2V0KHQpJiYhdGhpcy5oYXNBdHRyaWJ1dGUoZS5fJEV1KHQsaSkpKSlyZXR1cm47dGhpcy5DKHQscyxpKX0hMT09PXRoaXMuaXNVcGRhdGVQZW5kaW5nJiYodGhpcy5fJEVTPXRoaXMuXyRFUCgpKX1DKHQscyx7dXNlRGVmYXVsdDppLHJlZmxlY3Q6ZSx3cmFwcGVkOmh9LHIpe2kmJiEodGhpcy5fJEVqPz89bmV3IE1hcCkuaGFzKHQpJiYodGhpcy5fJEVqLnNldCh0LHI/P3M/P3RoaXNbdF0pLCEwIT09aHx8dm9pZCAwIT09cil8fCh0aGlzLl8kQUwuaGFzKHQpfHwodGhpcy5oYXNVcGRhdGVkfHxpfHwocz12b2lkIDApLHRoaXMuXyRBTC5zZXQodCxzKSksITA9PT1lJiZ0aGlzLl8kRW0hPT10JiYodGhpcy5fJEVxPz89bmV3IFNldCkuYWRkKHQpKX1hc3luYyBfJEVQKCl7dGhpcy5pc1VwZGF0ZVBlbmRpbmc9ITA7dHJ5e2F3YWl0IHRoaXMuXyRFU31jYXRjaCh0KXtQcm9taXNlLnJlamVjdCh0KX1jb25zdCB0PXRoaXMuc2NoZWR1bGVVcGRhdGUoKTtyZXR1cm4gbnVsbCE9dCYmYXdhaXQgdCwhdGhpcy5pc1VwZGF0ZVBlbmRpbmd9c2NoZWR1bGVVcGRhdGUoKXtyZXR1cm4gdGhpcy5wZXJmb3JtVXBkYXRlKCl9cGVyZm9ybVVwZGF0ZSgpe2lmKCF0aGlzLmlzVXBkYXRlUGVuZGluZylyZXR1cm47aWYoIXRoaXMuaGFzVXBkYXRlZCl7aWYodGhpcy5yZW5kZXJSb290Pz89dGhpcy5jcmVhdGVSZW5kZXJSb290KCksdGhpcy5fJEVwKXtmb3IoY29uc3RbdCxzXW9mIHRoaXMuXyRFcCl0aGlzW3RdPXM7dGhpcy5fJEVwPXZvaWQgMH1jb25zdCB0PXRoaXMuY29uc3RydWN0b3IuZWxlbWVudFByb3BlcnRpZXM7aWYodC5zaXplPjApZm9yKGNvbnN0W3MsaV1vZiB0KXtjb25zdHt3cmFwcGVkOnR9PWksZT10aGlzW3NdOyEwIT09dHx8dGhpcy5fJEFMLmhhcyhzKXx8dm9pZCAwPT09ZXx8dGhpcy5DKHMsdm9pZCAwLGksZSl9fWxldCB0PSExO2NvbnN0IHM9dGhpcy5fJEFMO3RyeXt0PXRoaXMuc2hvdWxkVXBkYXRlKHMpLHQ/KHRoaXMud2lsbFVwZGF0ZShzKSx0aGlzLl8kRU8/LmZvckVhY2goKHQ9PnQuaG9zdFVwZGF0ZT8uKCkpKSx0aGlzLnVwZGF0ZShzKSk6dGhpcy5fJEVNKCl9Y2F0Y2gocyl7dGhyb3cgdD0hMSx0aGlzLl8kRU0oKSxzfXQmJnRoaXMuXyRBRShzKX13aWxsVXBkYXRlKHQpe31fJEFFKHQpe3RoaXMuXyRFTz8uZm9yRWFjaCgodD0+dC5ob3N0VXBkYXRlZD8uKCkpKSx0aGlzLmhhc1VwZGF0ZWR8fCh0aGlzLmhhc1VwZGF0ZWQ9ITAsdGhpcy5maXJzdFVwZGF0ZWQodCkpLHRoaXMudXBkYXRlZCh0KX1fJEVNKCl7dGhpcy5fJEFMPW5ldyBNYXAsdGhpcy5pc1VwZGF0ZVBlbmRpbmc9ITF9Z2V0IHVwZGF0ZUNvbXBsZXRlKCl7cmV0dXJuIHRoaXMuZ2V0VXBkYXRlQ29tcGxldGUoKX1nZXRVcGRhdGVDb21wbGV0ZSgpe3JldHVybiB0aGlzLl8kRVN9c2hvdWxkVXBkYXRlKHQpe3JldHVybiEwfXVwZGF0ZSh0KXt0aGlzLl8kRXEmJj10aGlzLl8kRXEuZm9yRWFjaCgodD0+dGhpcy5fJEVUKHQsdGhpc1t0XSkpKSx0aGlzLl8kRU0oKX11cGRhdGVkKHQpe31maXJzdFVwZGF0ZWQodCl7fX15LmVsZW1lbnRTdHlsZXM9W10seS5zaGFkb3dSb290T3B0aW9ucz17bW9kZTpcIm9wZW5cIn0seVtkKFwiZWxlbWVudFByb3BlcnRpZXNcIildPW5ldyBNYXAseVtkKFwiZmluYWxpemVkXCIpXT1uZXcgTWFwLHA/Lih7UmVhY3RpdmVFbGVtZW50Onl9KSwoYS5yZWFjdGl2ZUVsZW1lbnRWZXJzaW9ucz8/PVtdKS5wdXNoKFwiMi4xLjBcIik7ZXhwb3J0e3kgYXMgUmVhY3RpdmVFbGVtZW50LHMgYXMgYWRvcHRTdHlsZXMsdSBhcyBkZWZhdWx0Q29udmVydGVyLHQgYXMgZ2V0Q29tcGF0aWJsZVN0eWxlLGYgYXMgbm90RXF1YWx9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVhY3RpdmUtZWxlbWVudC5qcy5tYXBcbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2VcbiAqL1xuY29uc3QgdD1nbG9iYWxUaGlzLGk9dC50cnVzdGVkVHlwZXMscz1pP2kuY3JlYXRlUG9saWN5KFwibGl0LWh0bWxcIix7Y3JlYXRlSFRNTDp0PT50fSk6dm9pZCAwLGU9XCIkbGl0JFwiLGg9YGxpdCQke01hdGgucmFuZG9tKCkudG9GaXhlZCg5KS5zbGljZSgyKX0kYCxvPVwiP1wiK2gsbj1gPCR7b30+YCxyPWRvY3VtZW50LGw9KCk9PnIuY3JlYXRlQ29tbWVudChcIlwiKSxjPXQ9Pm51bGw9PT10fHxcIm9iamVjdFwiIT10eXBlb2YgdCYmXCJmdW5jdGlvblwiIT10eXBlb2YgdCxhPUFycmF5LmlzQXJyYXksdT10PT5hKHQpfHxcImZ1bmN0aW9uXCI9PXR5cGVvZiB0Py5bU3ltYm9sLml0ZXJhdG9yXSxkPVwiWyBcXHRcXG5cXGZcXHJdXCIsZj0vPCg/OighLS18XFwvW15hLXpBLVpdKXwoXFwvP1thLXpBLVpdW14+XFxzXSopfChcXC8/JCkpL2csdj0vLS0+L2csXz0vPi9nLG09UmVnRXhwKGA+fCR7ZH0oPzooW15cXFxcc1wiJz49L10rKSgke2R9Kj0ke2R9Kig/OlteIFxcdFxcblxcZlxcclwiJ1xcYDw+PV18KFwifCcpfCkpfCQpYCxcImdcIikscD0vJy9nLGc9L1wiL2csJD0vXig/OnNjcmlwdHxzdHlsZXx0ZXh0YXJlYXx0aXRsZSkkL2kseT10PT4oaSwuLi5zKT0+KHtfJGxpdFR5cGUkOnQsc3RyaW5nczppLHZhbHVlczpzfSkseD15KDEpLGI9eSgyKSx3PXkoMyksVD1TeW1ib2wuZm9yKFwibGl0LW5vQ2hhbmdlXCIpLEU9U3ltYm9sLmZvcihcImxpdC1ub3RoaW5nXCIpLEE9bmV3IFdlYWtNYXAsQz1yLmNyZWF0ZVRyZWVXYWxrZXIociwxMjkpO2Z1bmN0aW9uIFAodCxpKXtpZighYSh0KXx8IXQuaGFzT3duUHJvcGVydHkoXCJyYXdcIikpdGhyb3cgRXJyb3IoXCJpbnZhbGlkIHRlbXBsYXRlIHN0cmluZ3MgYXJyYXlcIik7cmV0dXJuIHZvaWQgMCE9PXM/cy5jcmVhdGVIVE1MKGkpOml9Y29uc3QgVj0odCxpKT0+e2NvbnN0IHM9dC5sZW5ndGgtMSxvPVtdO2xldCByLGw9Mj09PWk/XCI8c3ZnPlwiOjM9PT1pP1wiPG1hdGg+XCI6XCJcIixjPWY7Zm9yKGxldCBpPTA7aTxzO2krKyl7Y29uc3Qgcz10W2ldO2xldCBhLHUsZD0tMSx5PTA7Zm9yKDt5PHMubGVuZ3RoJiYoYy5sYXN0SW5kZXg9eSx1PWMuZXhlYyhzKSxudWxsIT09dSk7KXk9Yy5sYXN0SW5kZXgsYz09PWY/XCIhLS1cIj09PXVbMV0/Yz12OnZvaWQgMCE9PXVbMV0/Yz1fOnZvaWQgMCE9PXVbMl0/KCQudGVzdCh1WzJdKSYmKHI9UmVnRXhwKFwiPC9cIit1WzJdLFwiZ1wiKSksYz1tKTp2b2lkIDAhPT11WzNdJiYoYz1tKTpjPT09bT9cIj5cIj09PXVbMF0/KGM9cj8/ZixkPS0xKTp2b2lkIDA9PT11WzFdP2Q9LTI6KGQ9Yy5sYXN0SW5kZXgtdVsyXS5sZW5ndGgsYT11WzFdLGM9dm9pZCAwPT09dVszXT9tOidcIic9PT11WzNdP2c6cCk6Yz09PWd8fGM9PT1wP2M9bTpjPT09dnx8Yz09PV8/Yz1mOihjPW0scj12b2lkIDApO2NvbnN0IHg9Yz09PW0mJnRbaSsxXS5zdGFydHNXaXRoKFwiLz5cIik/XCIgXCI6XCJcIjtsKz1jPT09Zj9zK246ZD49MD8oby5wdXNoKGEpLHMuc2xpY2UoMCxkKStlK3Muc2xpY2UoZCkraCt4KTpzK2grKC0yPT09ZD9pOngpfXJldHVybltQKHQsbCsodFtzXXx8XCI8Pz5cIikrKDI9PT1pP1wiPC9zdmc+XCI6Mz09PWk/XCI8L21hdGg+XCI6XCJcIikpLG9dfTtjbGFzcyBOe2NvbnN0cnVjdG9yKHtzdHJpbmdzOnQsXyRsaXRUeXBlJDpzfSxuKXtsZXQgcjt0aGlzLnBhcnRzPVtdO2xldCBjPTAsYT0wO2NvbnN0IHU9dC5sZW5ndGgtMSxkPXRoaXMucGFydHMsW2Ysdl09Vih0LHMpO2lmKHRoaXMuZWw9Ti5jcmVhdGVFbGVtZW50KGYsbiksQy5jdXJyZW50Tm9kZT10aGlzLmVsLmNvbnRlbnQsMj09PXN8fDM9PT1zKXtjb25zdCB0PXRoaXMuZWwuY29udGVudC5maXJzdENoaWxkO3QucmVwbGFjZVdpdGgoLi4udC5jaGlsZE5vZGVzKX1mb3IoO251bGwhPT0ocj1DLm5leHROb2RlKCkpJiZkLmxlbmd0aDx1Oyl7aWYoMT09PXIubm9kZVR5cGUpe2lmKHIuaGFzQXR0cmlidXRlcygpKWZvcihjb25zdCB0IG9mIHIuZ2V0QXR0cmlidXRlTmFtZXMoKSlpZih0LmVuZHNXaXRoKGUpKXtjb25zdCBpPXZbYSsrXSxzPXIuZ2V0QXR0cmlidXRlKHQpLnNwbGl0KGgpLGU9LyhbLj9AXSk/KC4qKS8uZXhlYyhpKTtkLnB1c2goe3R5cGU6MSxpbmRleDpjLG5hbWU6ZVsyXSxzdHJpbmdzOnMsY3RvcjpcIi5cIj09PWVbMV0/SDpcIj9cIj09PWVbMV0/STpcIkBcIj09PWVbMV0/TDprfSksci5yZW1vdmVBdHRyaWJ1dGUodCl9ZWxzZSB0LnN0YXJ0c1dpdGgoaCkmJihkLnB1c2goe3R5cGU6NixpbmRleDpjfSksci5yZW1vdmVBdHRyaWJ1dGUodCkpO2lmKCQudGVzdChyLnRhZ05hbWUpKXtjb25zdCB0PXIudGV4dENvbnRlbnQuc3BsaXQoaCkscz10Lmxlbmd0aC0xO2lmKHM+MCl7ci50ZXh0Q29udGVudD1pP2kuZW1wdHlTY3JpcHQ6XCJcIjtmb3IobGV0IGk9MDtpPHM7aSsrKXIuYXBwZW5kKHRbaV0sbCgpKSxDLm5leHROb2RlKCksZC5wdXNoKHt0eXBlOjIsaW5kZXg6KytjfSk7ci5hcHBlbmQodFtzXSxsKCkpfX19ZWxzZSBpZig4PT09ci5ub2RlVHlwZSlpZihyLmRhdGE9PT1vKWQucHVzaCh7dHlwZToyLGluZGV4OmN9KTtlbHNle2xldCB0PS0xO2Zvcig7LTEhPT0odD1yLmRhdGEuaW5kZXhPZihoLHQrMSkpOylkLnB1c2goe3R5cGU6NyxpbmRleDpjfSksdCs9aC5sZW5ndGgtMX1jKyt9fXN0YXRpYyBjcmVhdGVFbGVtZW50KHQsaSl7Y29uc3Qgcz1yLmNyZWF0ZUVsZW1lbnQoXCJ0ZW1wbGF0ZVwiKTtyZXR1cm4gcy5pbm5lckhUTUw9dCxzfX1mdW5jdGlvbiBTKHQsaSxzPXQsZSl7aWYoaT09PVQpcmV0dXJuIGk7bGV0IGg9dm9pZCAwIT09ZT9zLl8kQ28/LltlXTpzLl8kQ2w7Y29uc3Qgbz1jKGkpP3ZvaWQgMDppLl8kbGl0RGlyZWN0aXZlJDtyZXR1cm4gaD8uY29uc3RydWN0b3IhPT1vJiYoaD8uXyRBTz8uKCExKSx2b2lkIDA9PT1vP2g9dm9pZCAwOihoPW5ldyBvKHQpLGguXyRBVCh0LHMsZSkpLHZvaWQgMCE9PWU/KHMuXyRDbz8/PVtdKVtlXT1oOnMuXyRDbD1oKSx2b2lkIDAhPT1oJiYoaT1TKHQsaC5fJEFTKHQsaS52YWx1ZXMpLGgsZSkpLGl9Y2xhc3MgTXtjb25zdHJ1Y3Rvcih0LGkpe3RoaXMuXyRBVj1bXSx0aGlzLl8kQU49dm9pZCAwLHRoaXMuXyRBRD10LHRoaXMuXyRBTT1pfWdldCBwYXJlbnROb2RlKCl7cmV0dXJuIHRoaXMuXyRBTS5wYXJlbnROb2RlfWdldCBfJEFVKCl7cmV0dXJuIHRoaXMuXyRBTS5fJEFVfXUodCl7Y29uc3R7ZWw6e2NvbnRlbnQ6aX0scGFydHM6c309dGhpcy5fJEFELGU9KHQ/LmNyZWF0aW9uU2NvcGU/P3IpLmltcG9ydE5vZGUoaSwhMCk7Qy5jdXJyZW50Tm9kZT1lO2xldCBoPUMubmV4dE5vZGUoKSxvPTAsbj0wLGw9c1swXTtmb3IoO3ZvaWQgMCE9PWw7KXtpZihvPT09bC5pbmRleCl7bGV0IGk7Mj09PWwudHlwZT9pPW5ldyBSKGgsaC5uZXh0U2libGluZyx0aGlzLHQpOjE9PT1sLnR5cGU/aT1uZXcgbC5jdG9yKGgsbC5uYW1lLGwuc3RyaW5ncyx0aGlzLHQpOjY9PT1sLnR5cGUmJihpPW5ldyB6KGgsdGhpcyx0KSksdGhpcy5fJEFWLnB1c2goaSksbD1zWysrbl19byE9PWw/LmluZGV4JiYoaD1DLm5leHROb2RlKCksbysrKX1yZXR1cm4gQy5jdXJyZW50Tm9kZT1yLGV9cCh0KXtsZXQgaT0wO2Zvcihjb25zdCBzIG9mIHRoaXMuXyRBVil2b2lkIDAhPT1zJiYodm9pZCAwIT09cy5zdHJpbmdzPyhzLl8kQUkodCxzLGkpLGkrPXMuc3RyaW5ncy5sZW5ndGgtMik6cy5fJEFJKHRbaV0pKSxpKyt9fWNsYXNzIFJ7Z2V0IF8kQVUoKXtyZXR1cm4gdGhpcy5fJEFNPy5fJEFVPz90aGlzLl8kQ3Z9Y29uc3RydWN0b3IodCxpLHMsZSl7dGhpcy50eXBlPTIsdGhpcy5fJEFIPUUsdGhpcy5fJEFOPXZvaWQgMCx0aGlzLl8kQUE9dCx0aGlzLl8kQUI9aSx0aGlzLl8kQU09cyx0aGlzLm9wdGlvbnM9ZSx0aGlzLl8kQ3Y9ZT8uaXNDb25uZWN0ZWQ/PyEwfWdldCBwYXJlbnROb2RlKCl7bGV0IHQ9dGhpcy5fJEFBLnBhcmVudE5vZGU7Y29uc3QgaT10aGlzLl8kQU07cmV0dXJuIHZvaWQgMCE9PWkmJjExPT09dD8ubm9kZVR5cGUmJih0PWkucGFyZW50Tm9kZSksdH1nZXQgc3RhcnROb2RlKCl7cmV0dXJuIHRoaXMuXyRBQX1nZXQgZW5kTm9kZSgpe3JldHVybiB0aGlzLl8kQUJ9XyRBSSh0LGk9dGhpcyl7dD1TKHRoaXMsdCxpKSxjKHQpP3Q9PT1FfHxudWxsPT10fHxcIlwiPT09dD8odGhpcy5fJEFIIT09RSYmdGhpcy5fJEFSKCksdGhpcy5fJEFIPUUpOnQhPT10aGlzLl8kQUgmJnQhPT1UJiZ0aGlzLl8odCk6dm9pZCAwIT09dC5fJGxpdFR5cGUkP3RoaXMuJCh0KTp2b2lkIDAhPT10Lm5vZGVUeXBlP3RoaXMuVCh0KTp1KHQpP3RoaXMuayh0KTp0aGlzLl8odCl9Tyh0KXtyZXR1cm4gdGhpcy5fJEFBLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHQsdGhpcy5fJEFCKX1UKHQpe3RoaXMuXyRBSCE9PXQmJih0aGlzLl8kQVIoKSx0aGlzLl8kQUg9dGhpcy5PKHQpKX1fKHQpe3RoaXMuXyRBSCE9PUUmJmModGhpcy5fJEFIKT90aGlzLl8kQUEubmV4dFNpYmxpbmcuZGF0YT10OnRoaXMuVChyLmNyZWF0ZVRleHROb2RlKHQpKSx0aGlzLl8kQUg9dH0kKHQpe2NvbnN0e3ZhbHVlczppLF8kbGl0VHlwZSQ6c309dCxlPVwibnVtYmVyXCI9PXR5cGVvZiBzP3RoaXMuXyRBQyh0KToodm9pZCAwPT09cy5lbCYmKHMuZWw9Ti5jcmVhdGVFbGVtZW50KFAocy5oLHMuaFswXSksdGhpcy5vcHRpb25zKSkscyk7aWYodGhpcy5fJEFIPy5fJEFEPT09ZSl0aGlzLl8kQUgucChpKTtlbHNle2NvbnN0IHQ9bmV3IE0oZSx0aGlzKSxzPXQudSh0aGlzLm9wdGlvbnMpO3QucChpKSx0aGlzLlQocyksdGhpcy5fJEFIPXR9fV8kQUModCl7bGV0IGk9QS5nZXQodC5zdHJpbmdzKTtyZXR1cm4gdm9pZCAwPT09aSYmQS5zZXQodC5zdHJpbmdzLGk9bmV3IE4odCkpLGl9ayh0KXthKHRoaXMuXyRBSCl8fCh0aGlzLl8kQUg9W10sdGhpcy5fJEFSKCkpO2NvbnN0IGk9dGhpcy5fJEFIO2xldCBzLGU9MDtmb3IoY29uc3QgaCBvZiB0KWU9PT1pLmxlbmd0aD9pLnB1c2gocz1uZXcgUih0aGlzLk8obCgpKSx0aGlzLk8obCgpKSx0aGlzLHRoaXMub3B0aW9ucykpOnM9aVtlXSxzLl8kQUkoaCksZSsrO2U8aS5sZW5ndGgmJih0aGlzLl8kQVIocyYmcy5fJEFCLm5leHRTaWJsaW5nLGUpLGkubGVuZ3RoPWUpfV8kQVIodD10aGlzLl8kQUEubmV4dFNpYmxpbmcsaSl7Zm9yKHRoaXMuXyRBUD8uKCExLCEwLGkpO3QmJnQhPT10aGlzLl8kQUI7KXtjb25zdCBpPXQubmV4dFNpYmxpbmc7dC5yZW1vdmUoKSx0PWl9fXNldENvbm5lY3RlZCh0KXt2b2lkIDA9PT10aGlzLl8kQU0mJih0aGlzLl8kQ3Y9dCx0aGlzLl8kQVA/Lih0KSl9fWNsYXNzIGt7Z2V0IHRhZ05hbWUoKXtyZXR1cm4gdGhpcy5lbGVtZW50LnRhZ05hbWV9Z2V0IF8kQVUoKXtyZXR1cm4gdGhpcy5fJEFNLl8kQVV9Y29uc3RydWN0b3IodCxpLHMsZSxoKXt0aGlzLnR5cGU9MSx0aGlzLl8kQUg9RSx0aGlzLl8kQU49dm9pZCAwLHRoaXMuZWxlbWVudD10LHRoaXMubmFtZT1pLHRoaXMuXyRBTT1lLHRoaXMub3B0aW9ucz1oLHMubGVuZ3RoPjJ8fFwiXCIhPT1zWzBdfHxcIlwiIT09c1sxXT8odGhpcy5fJEFIPUFycmF5KHMubGVuZ3RoLTEpLmZpbGwobmV3IFN0cmluZyksdGhpcy5zdHJpbmdzPXMpOnRoaXMuXyRBSD1FfV8kQUkodCxpPXRoaXMscyxlKXtjb25zdCBoPXRoaXMuc3RyaW5ncztsZXQgbz0hMTtpZih2b2lkIDA9PT1oKXQ9Uyh0aGlzLHQsaSwwKSxvPSFjKHQpfHx0IT09dGhpcy5fJEFIJiZ0IT09VCxvJiYodGhpcy5fJEFIPXQpO2Vsc2V7Y29uc3QgZT10O2xldCBuLHI7Zm9yKHQ9aFswXSxuPTA7bjxoLmxlbmd0aC0xO24rKylyPVModGhpcyxlW3Mrbl0saSxuKSxyPT09VCYmKHI9dGhpcy5fJEFIW25dKSxvfHw9IWMocil8fHIhPT10aGlzLl8kQUhbbl0scj09PUU/dD1FOnQhPT1FJiYodCs9KHI/P1wiXCIpK2hbbisxXSksdGhpcy5fJEFIW25dPXJ9byYmIWUmJnRoaXMuaih0KX1qKHQpe3Q9PT1FP3RoaXMuZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUodGhpcy5uYW1lKTp0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKHRoaXMubmFtZSx0Pz9cIlwiKX19Y2xhc3MgSCBleHRlbmRzIGt7Y29uc3RydWN0b3IoKXtzdXBlciguLi5hcmd1bWVudHMpLHRoaXMudHlwZT0zfWoodCl7dGhpcy5lbGVtZW50W3RoaXMubmFtZV09dD09PUU/dm9pZCAwOnR9fWNsYXNzIEkgZXh0ZW5kcyBre2NvbnN0cnVjdG9yKCl7c3VwZXIoLi4uYXJndW1lbnRzKSx0aGlzLnR5cGU9NH1qKHQpe3RoaXMuZWxlbWVudC50b2dnbGVBdHRyaWJ1dGUodGhpcy5uYW1lLCEhdCYmdCE9PUUpfX1jbGFzcyBMIGV4dGVuZHMga3tjb25zdHJ1Y3Rvcih0LGkscyxlLGgpe3N1cGVyKHQsaSxzLGUsaCksdGhpcy50eXBlPTV9XyRBSSh0LGk9dGhpcyl7aWYoKHQ9Uyh0aGlzLHQsaSwwKT8/RSk9PT1UKXJldHVybjtjb25zdCBzPXRoaXMuXyRBSCxlPXQ9PT1FJiZzIT09RXx8dC5jYXB0dXJlIT09cy5jYXB0dXJlfHx0Lm9uY2UhPT1zLm9uY2V8fHQucGFzc2l2ZSE9PXMucGFzc2l2ZSxoPXQhPT1FJiYocz09PUV8fGUpO2UmJnRoaXMuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHRoaXMubmFtZSx0aGlzLHMpLGgmJnRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKHRoaXMubmFtZSx0aGlzLHQpLHRoaXMuXyRBSD10fWhhbmRsZUV2ZW50KHQpe1wiZnVuY3Rpb25cIj09dHlwZW9mIHRoaXMuXyRBSD90aGlzLl8kQUguY2FsbCh0aGlzLm9wdGlvbnM/Lmhvc3Q/P3RoaXMuZWxlbWVudCx0KTp0aGlzLl8kQUguaGFuZGxlRXZlbnQodCl9fWNsYXNzIHp7Y29uc3RydWN0b3IodCxpLHMpe3RoaXMuZWxlbWVudD10LHRoaXMudHlwZT02LHRoaXMuXyRBTj12b2lkIDAsdGhpcy5fJEFNPWksdGhpcy5vcHRpb25zPXN9Z2V0IF8kQVUoKXtyZXR1cm4gdGhpcy5fJEFNLl8kQVV9XyRBSSh0KXtTKHRoaXMsdCl9fWNvbnN0IFo9e006ZSxQOmgsQTpvLEM6MSxMOlYsUjpNLEQ6dSxWOlMsSTpSLEg6ayxOOkksVTpMLEI6SCxGOnp9LGo9dC5saXRIdG1sUG9seWZpbGxTdXBwb3J0O2o/LihOLFIpLCh0LmxpdEh0bWxWZXJzaW9ucz8/PVtdKS5wdXNoKFwiMy4zLjBcIik7Y29uc3QgQj0odCxpLHMpPT57Y29uc3QgZT1zPy5yZW5kZXJCZWZvcmU/P2k7bGV0IGg9ZS5fJGxpdFBhcnQkO2lmKHZvaWQgMD09PWgpe2NvbnN0IHQ9cz8ucmVuZGVyQmVmb3JlPz9udWxsO2UuXyRsaXRQYXJ0JD1oPW5ldyBSKGkuaW5zZXJ0QmVmb3JlKGwoKSx0KSx0LHZvaWQgMCxzPz97fSl9cmV0dXJuIGguXyRBSSh0KSxofTtleHBvcnR7WiBhcyBfJExILHggYXMgaHRtbCx3IGFzIG1hdGhtbCxUIGFzIG5vQ2hhbmdlLEUgYXMgbm90aGluZyxCIGFzIHJlbmRlcixiIGFzIHN2Z307XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saXQtaHRtbC5qcy5tYXBcbiIsImltcG9ydHtSZWFjdGl2ZUVsZW1lbnQgYXMgdH1mcm9tXCJAbGl0L3JlYWN0aXZlLWVsZW1lbnRcIjtleHBvcnQqZnJvbVwiQGxpdC9yZWFjdGl2ZS1lbGVtZW50XCI7aW1wb3J0e3JlbmRlciBhcyBlLG5vQ2hhbmdlIGFzIHJ9ZnJvbVwibGl0LWh0bWxcIjtleHBvcnQqZnJvbVwibGl0LWh0bWxcIjtcbi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2VcbiAqL2NvbnN0IHM9Z2xvYmFsVGhpcztjbGFzcyBpIGV4dGVuZHMgdHtjb25zdHJ1Y3Rvcigpe3N1cGVyKC4uLmFyZ3VtZW50cyksdGhpcy5yZW5kZXJPcHRpb25zPXtob3N0OnRoaXN9LHRoaXMuXyREbz12b2lkIDB9Y3JlYXRlUmVuZGVyUm9vdCgpe2NvbnN0IHQ9c3VwZXIuY3JlYXRlUmVuZGVyUm9vdCgpO3JldHVybiB0aGlzLnJlbmRlck9wdGlvbnMucmVuZGVyQmVmb3JlPz89dC5maXJzdENoaWxkLHR9dXBkYXRlKHQpe2NvbnN0IHI9dGhpcy5yZW5kZXIoKTt0aGlzLmhhc1VwZGF0ZWR8fCh0aGlzLnJlbmRlck9wdGlvbnMuaXNDb25uZWN0ZWQ9dGhpcy5pc0Nvbm5lY3RlZCksc3VwZXIudXBkYXRlKHQpLHRoaXMuXyREbz1lKHIsdGhpcy5yZW5kZXJSb290LHRoaXMucmVuZGVyT3B0aW9ucyl9Y29ubmVjdGVkQ2FsbGJhY2soKXtzdXBlci5jb25uZWN0ZWRDYWxsYmFjaygpLHRoaXMuXyREbz8uc2V0Q29ubmVjdGVkKCEwKX1kaXNjb25uZWN0ZWRDYWxsYmFjaygpe3N1cGVyLmRpc2Nvbm5lY3RlZENhbGxiYWNrKCksdGhpcy5fJERvPy5zZXRDb25uZWN0ZWQoITEpfXJlbmRlcigpe3JldHVybiByfX1pLl8kbGl0RWxlbWVudCQ9ITAsaVtcImZpbmFsaXplZFwiXT0hMCxzLmxpdEVsZW1lbnRIeWRyYXRlU3VwcG9ydD8uKHtMaXRFbGVtZW50Oml9KTtjb25zdCBvPXMubGl0RWxlbWVudFBvbHlmaWxsU3VwcG9ydDtvPy4oe0xpdEVsZW1lbnQ6aX0pO2NvbnN0IG49e18kQUs6KHQsZSxyKT0+e3QuXyRBSyhlLHIpfSxfJEFMOnQ9PnQuXyRBTH07KHMubGl0RWxlbWVudFZlcnNpb25zPz89W10pLnB1c2goXCI0LjIuMFwiKTtleHBvcnR7aSBhcyBMaXRFbGVtZW50LG4gYXMgXyRMRX07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saXQtZWxlbWVudC5qcy5tYXBcbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2VcbiAqL1xuY29uc3QgdD10PT4oZSxvKT0+e3ZvaWQgMCE9PW8/by5hZGRJbml0aWFsaXplcigoKCk9PntjdXN0b21FbGVtZW50cy5kZWZpbmUodCxlKX0pKTpjdXN0b21FbGVtZW50cy5kZWZpbmUodCxlKX07ZXhwb3J0e3QgYXMgY3VzdG9tRWxlbWVudH07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jdXN0b20tZWxlbWVudC5qcy5tYXBcbiIsImltcG9ydHtkZWZhdWx0Q29udmVydGVyIGFzIHQsbm90RXF1YWwgYXMgZX1mcm9tXCIuLi9yZWFjdGl2ZS1lbGVtZW50LmpzXCI7XG4vKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlXG4gKi9jb25zdCBvPXthdHRyaWJ1dGU6ITAsdHlwZTpTdHJpbmcsY29udmVydGVyOnQscmVmbGVjdDohMSxoYXNDaGFuZ2VkOmV9LHI9KHQ9byxlLHIpPT57Y29uc3R7a2luZDpuLG1ldGFkYXRhOml9PXI7bGV0IHM9Z2xvYmFsVGhpcy5saXRQcm9wZXJ0eU1ldGFkYXRhLmdldChpKTtpZih2b2lkIDA9PT1zJiZnbG9iYWxUaGlzLmxpdFByb3BlcnR5TWV0YWRhdGEuc2V0KGkscz1uZXcgTWFwKSxcInNldHRlclwiPT09biYmKCh0PU9iamVjdC5jcmVhdGUodCkpLndyYXBwZWQ9ITApLHMuc2V0KHIubmFtZSx0KSxcImFjY2Vzc29yXCI9PT1uKXtjb25zdHtuYW1lOm99PXI7cmV0dXJue3NldChyKXtjb25zdCBuPWUuZ2V0LmNhbGwodGhpcyk7ZS5zZXQuY2FsbCh0aGlzLHIpLHRoaXMucmVxdWVzdFVwZGF0ZShvLG4sdCl9LGluaXQoZSl7cmV0dXJuIHZvaWQgMCE9PWUmJnRoaXMuQyhvLHZvaWQgMCx0LGUpLGV9fX1pZihcInNldHRlclwiPT09bil7Y29uc3R7bmFtZTpvfT1yO3JldHVybiBmdW5jdGlvbihyKXtjb25zdCBuPXRoaXNbb107ZS5jYWxsKHRoaXMsciksdGhpcy5yZXF1ZXN0VXBkYXRlKG8sbix0KX19dGhyb3cgRXJyb3IoXCJVbnN1cHBvcnRlZCBkZWNvcmF0b3IgbG9jYXRpb246IFwiK24pfTtmdW5jdGlvbiBuKHQpe3JldHVybihlLG8pPT5cIm9iamVjdFwiPT10eXBlb2Ygbz9yKHQsZSxvKTooKHQsZSxvKT0+e2NvbnN0IHI9ZS5oYXNPd25Qcm9wZXJ0eShvKTtyZXR1cm4gZS5jb25zdHJ1Y3Rvci5jcmVhdGVQcm9wZXJ0eShvLHQpLHI/T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihlLG8pOnZvaWQgMH0pKHQsZSxvKX1leHBvcnR7biBhcyBwcm9wZXJ0eSxyIGFzIHN0YW5kYXJkUHJvcGVydHl9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cHJvcGVydHkuanMubWFwXG4iLCJpbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuaW1wb3J0ICogYXMgQ29sb3IgZnJvbSAnY29sb3InO1xuXG5leHBvcnQgY29uc3QgQ09MT1JTID0gW1xuICAncHJpbWFyeScsXG4gICdhY2NlbnQnLFxuICAncmVkJyxcbiAgJ3BpbmsnLFxuICAncHVycGxlJyxcbiAgJ2RlZXAtcHVycGxlJyxcbiAgJ2luZGlnbycsXG4gICdibHVlJyxcbiAgJ2xpZ2h0LWJsdWUnLFxuICAnY3lhbicsXG4gICd0ZWFsJyxcbiAgJ2dyZWVuJyxcbiAgJ2xpZ2h0LWdyZWVuJyxcbiAgJ2xpbWUnLFxuICAneWVsbG93JyxcbiAgJ2FtYmVyJyxcbiAgJ29yYW5nZScsXG4gICdkZWVwLW9yYW5nZScsXG4gICdicm93bicsXG4gICdsaWdodC1ncmV5JyxcbiAgJ2dyZXknLFxuICAnZGFyay1ncmV5JyxcbiAgJ2JsdWUtZ3JleScsXG4gICdibGFjaycsXG4gICd3aGl0ZScsXG4gICdkaXNhYmxlZCcsXG5dO1xuXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZVJnYkNvbG9yKGNvbG9yOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoY29sb3IgPT09ICdwcmltYXJ5JyB8fCBjb2xvciA9PT0gJ2FjY2VudCcpIHtcbiAgICByZXR1cm4gYHZhcigtLXJnYi0ke2NvbG9yfS1jb2xvcilgO1xuICB9XG4gIGlmIChDT0xPUlMuaW5jbHVkZXMoY29sb3IpKSB7XG4gICAgcmV0dXJuIGB2YXIoLS1yZ2ItJHtjb2xvcn0pYDtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVsc2UtcmV0dXJuXG4gIH0gZWxzZSBpZiAoY29sb3Iuc3RhcnRzV2l0aCgnIycpKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBDb2xvci5yZ2IoY29sb3IpLnJnYigpLmFycmF5KCkuam9pbignLCAnKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNvbG9yO1xufVxuXG5mdW5jdGlvbiBjYXBpdGFsaXplRmlyc3RMZXR0ZXIoc3RyaW5nKSB7XG4gIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlQ29sb3JOYW1lKGNvbG9yOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gY29sb3JcbiAgICAuc3BsaXQoJy0nKVxuICAgIC5tYXAoKHMpID0+IGNhcGl0YWxpemVGaXJzdExldHRlcihzKSlcbiAgICAuam9pbignICcpO1xufVxuXG5leHBvcnQgY29uc3QgZGVmYXVsdENvbG9yQ3NzID0gY3NzYFxuICAtLWRlZmF1bHQtcmVkOiAyNDQsIDY3LCA1NDtcbiAgLS1kZWZhdWx0LXBpbms6IDIzMywgMzAsIDk5O1xuICAtLWRlZmF1bHQtcHVycGxlOiAxNDYsIDEwNywgMTk5O1xuICAtLWRlZmF1bHQtZGVlcC1wdXJwbGU6IDExMCwgNjUsIDE3MTtcbiAgLS1kZWZhdWx0LWluZGlnbzogNjMsIDgxLCAxODE7XG4gIC0tZGVmYXVsdC1ibHVlOiAzMywgMTUwLCAyNDM7XG4gIC0tZGVmYXVsdC1saWdodC1ibHVlOiAzLCAxNjksIDI0NDtcbiAgLS1kZWZhdWx0LWN5YW46IDAsIDE4OCwgMjEyO1xuICAtLWRlZmF1bHQtdGVhbDogMCwgMTUwLCAxMzY7XG4gIC0tZGVmYXVsdC1ncmVlbjogNzYsIDE3NSwgODA7XG4gIC0tZGVmYXVsdC1saWdodC1ncmVlbjogMTM5LCAxOTUsIDc0O1xuICAtLWRlZmF1bHQtbGltZTogMjA1LCAyMjAsIDU3O1xuICAtLWRlZmF1bHQteWVsbG93OiAyNTUsIDIzNSwgNTk7XG4gIC0tZGVmYXVsdC1hbWJlcjogMjU1LCAxOTMsIDc7XG4gIC0tZGVmYXVsdC1vcmFuZ2U6IDI1NSwgMTUyLCAwO1xuICAtLWRlZmF1bHQtZGVlcC1vcmFuZ2U6IDI1NSwgMTExLCAzNDtcbiAgLS1kZWZhdWx0LWJyb3duOiAxMjEsIDg1LCA3MjtcbiAgLS1kZWZhdWx0LWxpZ2h0LWdyZXk6IDE4OSwgMTg5LCAxODk7XG4gIC0tZGVmYXVsdC1ncmV5OiAxNTgsIDE1OCwgMTU4O1xuICAtLWRlZmF1bHQtZGFyay1ncmV5OiA5NiwgOTYsIDk2O1xuICAtLWRlZmF1bHQtYmx1ZS1ncmV5OiA5NiwgMTI1LCAxMzk7XG4gIC0tZGVmYXVsdC1ibGFjazogMCwgMCwgMDtcbiAgLS1kZWZhdWx0LXdoaXRlOiAyNTUsIDI1NSwgMjU1O1xuICAtLWRlZmF1bHQtZGlzYWJsZWQ6IDE4OSwgMTg5LCAxODk7XG5gO1xuXG5leHBvcnQgY29uc3QgZGVmYXVsdERhcmtDb2xvckNzcyA9IGNzc2BcbiAgLS1kZWZhdWx0LWRpc2FibGVkOiAxMTEsIDExMSwgMTExO1xuYDtcbiIsImV4cG9ydCBjb25zdCBsb2dvOiBzdHJpbmcgPSAnJWMgV0VBVEhFUi1DT05ESVRJT04tQ0FSRCAlYyAyLjAuMCc7XG5cbmV4cG9ydCBjb25zdCBoYWNzSW1hZ2VQYXRoOiBzdHJpbmcgPSAnL2xvY2FsL2NvbW11bml0eS9oYS1jYXJkLXdlYXRoZXItY29uZGl0aW9ucy9pY29ucyc7XG5leHBvcnQgY29uc3QgbWFuSW1hZ2VQYXRoOiBzdHJpbmcgPSAnL2xvY2FsL2hhLWNhcmQtd2VhdGhlci1jb25kaXRpb25zL2ljb25zJztcblxuZXhwb3J0IGNvbnN0IG9wdENvbnNvbGVQYXJhbTE6IHN0cmluZyA9ICdjb2xvcjogd2hpdGU7IGJhY2tncm91bmQ6IGdyZWVuOyBmb250LXdlaWdodDogNzAwOyc7XG5leHBvcnQgY29uc3Qgb3B0Q29uc29sZVBhcmFtMjogc3RyaW5nID0gJ2NvbG9yOiBncmVlbjsgYmFja2dyb3VuZDogd2hpdGU7IGZvbnQtd2VpZ2h0OiA3MDA7JztcbmV4cG9ydCBjb25zdCBvcHRDb25zb2xlUGFyYW0zOiBzdHJpbmcgPSAnY29sb3I6IGJsYWNrOyBiYWNrZ3JvdW5kOiB3aGl0ZTsgZm9udC13ZWlnaHQ6IDcwMDsnO1xuXG5leHBvcnQgY29uc3QgaWNvblRlbXBlcmF0dXJlOiBzdHJpbmcgPSAnbWRpOnRoZXJtb21ldGVyJztcbmV4cG9ydCBjb25zdCBpY29uUHJlY2lwaXRhdGlvbjogc3RyaW5nID0gJ21kaTp3ZWF0aGVyLXJhaW55JztcblxuZXhwb3J0IGNvbnN0IGN3Y0xvY2FsZSA9IHtcbiAgZW46IDAsXG4gIGl0OiAxLFxuICBubDogMixcbiAgZXM6IDMsXG4gIGRlOiA0LFxuICBmcjogNSxcbiAgJ3NyLWxhdG4nOiA2LFxuICBwdDogNyxcbiAgZGE6IDgsXG4gICduby1ubyc6IDksXG4gIGNzOiAxMCxcbiAgcnU6IDExLFxufTtcblxuLy8g8J+MkSDwn4ySIPCfjJMg8J+MlCDwn4yVIPCfjJYg8J+MlyDwn4yYIPCfjJFcbmV4cG9ydCBjb25zdCBjd2NNb29uUGhhc2VJY29ucyA9IHtcbiAgbmV3X21vb246ICfwn4yRJyxcbiAgbmV3OiAn8J+MkScsXG4gIHdheGluZ19jcmVzY2VudDogJ/CfjJInLFxuICBmaXJzdF9xdWFydGVyOiAn8J+MkycsXG4gIHdheGluZ19naWJib3VzOiAn8J+MlCcsXG4gIGZ1bGw6ICfwn4yVJyxcbiAgZnVsbF9tb29uOiAn8J+MlScsXG4gIHdhbmluZ19naWJib3VzOiAn8J+MlicsXG4gIHRoaXJkX3F1YXJ0ZXI6ICfwn4yXJyxcbiAgbGFzdF9xdWFydGVyOiAn8J+MlycsXG4gIHdhbmluZ19jcmVzY2VudDogJ/CfjJgnLFxufTtcbiIsIi8vIGNsZWFyPW9rLCBwYXJ0bHljbG91ZHk9b2ssIGNsb3VkeT1vaywgcGFydGx5Y2xvdWR5LWZvZz1vaywgcGFydGx5Y2xvdWR5LWxpZ2h0LXJhaW49b2ssIHBhcnRseWNsb3VkeS1yYWluPW9rLFxuLy8gbGlnaHQtcmFpbj1vaywgcmFpbnk9b2ssIHNub3d5LXJhaW55PW9rLCBwYXJ0bHljbG91ZHktbGlnaHQtc25vdz1vaywgcGFydGx5Y2xvdWR5LXNub3c9b2ssIGxpZ2h0LXNub3c9b2ssIHNub3d5PW9rLFxuLy8gcGFydGx5Y2xvdWR5LWxpZ2h0bmluZz1vayBvciBsaWdodG5pbmdcblxuZXhwb3J0IGNvbnN0IGN3Y0J1aWVucmFkYXJEYXlJY29uczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmc7IH0gPSB7XG4gIC8vIGZyZWV6aW5nX3JhaW5faGVhdnk6ICdyYWlueS0zJyxcbiAgLy8gZnJlZXppbmdfcmFpbjogJ3JhaW55LTInLFxuICAvLyBmcmVlemluZ19yYWluX2xpZ2h0OiAncmFpbnktMScsXG4gIC8vIGZyZWV6aW5nX2RyaXp6bGU6ICdyYWluLWFuZC1zbGVldC1taXgnLFxuICAvLyBpY2VfcGVsbGV0c19oZWF2eTogJ3JhaW4tYW5kLXNub3ctbWl4JyxcbiAgLy8gaWNlX3BlbGxldHM6ICdyYWluLWFuZC1zbm93LW1peCcsXG4gIC8vIGljZV9wZWxsZXRzX2xpZ2h0OiAncmFpbi1hbmQtc25vdy1taXgnLFxuICBzbm93eTogJ3Nub3d5LTMnLFxuICAnbGlnaHQtc25vdyc6ICdzbm93eS0yJyxcbiAgJ3Nub3d5LXJhaW55JzogJ3Nub3d5LTEnLFxuICAncGFydGx5Y2xvdWR5LWxpZ2h0LXNub3cnOiAnc25vd3ktMScsXG4gICdwYXJ0bHljbG91ZHktc25vdyc6ICdzbm93eS0xJyxcbiAgLy8gZmx1cnJpZXM6ICd3aW5kJyxcbiAgLy8gdHN0b3JtOiAndHJvcGljYWwtc3Rvcm0nLFxuICAvLyByYWluX2hlYXZ5OiAncmFpbnktMycsXG4gICdwYXJ0bHljbG91ZHktbGlnaHQtcmFpbic6ICdyYWlueS0xJyxcbiAgJ2xpZ2h0LXJhaW4nOiAncmFpbnktMScsXG4gIHJhaW55OiAncmFpbnktMicsXG4gICdwYXJ0bHljbG91ZHktcmFpbic6ICdyYWlueS0xJyxcbiAgLy8gZm9nX2xpZ2h0OiAnaGF6ZScsXG4gICdwYXJ0bHljbG91ZHktZm9nJzogJ2ZvZycsXG4gIGNsb3VkeTogJ2Nsb3VkeS1vcmlnaW5hbCcsXG4gIC8vIG1vc3RseV9jbG91ZHk6ICdjbG91ZHktZGF5LTMnLFxuICBwYXJ0bHljbG91ZHk6ICdjbG91ZHktZGF5LTInLFxuICAncGFydGx5Y2xvdWR5LWxpZ2h0bmluZyc6ICdjbG91ZHktZGF5LTEnLFxuICBsaWdodG5pbmc6ICdjbG91ZHktZGF5LTEnLFxuICAvLyBtb3N0bHlfY2xlYXI6ICdjbG91ZHktZGF5LTEnLFxuICBjbGVhcjogJ2RheScsXG59O1xuXG5leHBvcnQgY29uc3QgY3djQnVpZW5yYWRhck5pZ2h0SWNvbnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nOyB9ID0ge1xuICAuLi5jd2NCdWllbnJhZGFyRGF5SWNvbnMsXG4gIC8vIGZyZWV6aW5nX3JhaW5faGVhdnk6ICdyYWlueS02JyxcbiAgLy8gZnJlZXppbmdfcmFpbjogJ3JhaW55LTUnLFxuICAvLyBmcmVlemluZ19yYWluX2xpZ2h0OiAncmFpbnktNCcsXG4gIC8vIGZyZWV6aW5nX2RyaXp6bGU6ICdyYWluLWFuZC1zbGVldC1taXgnLFxuICAvLyBpY2VfcGVsbGV0c19oZWF2eTogJ3JhaW4tYW5kLXNub3ctbWl4JyxcbiAgLy8gaWNlX3BlbGxldHM6ICdyYWluLWFuZC1zbm93LW1peCcsXG4gIC8vIGljZV9wZWxsZXRzX2xpZ2h0OiAncmFpbi1hbmQtc25vdy1taXgnLFxuICAvLyBzbm93X2hlYXZ5OiAnc25vd3ktNicsXG4gIC8vIHNub3c6ICdub3d5LTUnLFxuICAvLyBzbm93X2xpZ2h0OiAnbm93eS00JyxcbiAgLy8gZmx1cnJpZXM6ICd3aW5kJyxcbiAgLy8gdHN0b3JtOiAndHJvcGljYWwtc3Rvcm0nLFxuICAvLyByYWluX2hlYXZ5OiAncmFpbnktNicsXG4gIC8vIHJhaW5fbGlnaHQ6ICdyYWlueS00JyxcbiAgLy8gcmFpbjogJ3JhaW55LTUnLFxuICAvLyBkcml6emxlOiAncmFpbnktNCcsXG4gIC8vIGZvZ19saWdodDogJ2hhemUnLFxuICAvLyBmb2c6ICdmb2cnLFxuICAvLyBjbG91ZHk6ICdjbG91ZHknLFxuICAvLyBtb3N0bHlfY2xvdWR5OiAnY2xvdWR5LW5pZ2h0LTMnLFxuICAvLyBwYXJ0bHlfY2xvdWR5OiAnY2xvdWR5LW5pZ2h0LTInLFxuICAvLyBtb3N0bHlfY2xlYXI6ICdjbG91ZHktbmlnaHQtMScsXG4gIC8vIGNsZWFyOiAnbmlnaHQnXG59O1xuIiwiZXhwb3J0IGNvbnN0IGN3Y0NsaW1hY2VsbERheUljb25zOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZzsgfSA9IHtcbiAgZnJlZXppbmdfcmFpbl9oZWF2eTogJ3JhaW55LTMnLFxuICAnaGVhdnkgZnJlZXppbmcgcmFpbic6ICdyYWlueS0zJyxcbiAgZnJlZXppbmdfcmFpbjogJ3JhaW55LTInLFxuICAnZnJlZXppbmcgcmFpbic6ICdyYWlueS0yJyxcbiAgZnJlZXppbmdfcmFpbl9saWdodDogJ3JhaW55LTEnLFxuICAnbGlnaHQgZnJlZXppbmcgcmFpbic6ICdyYWlueS0xJyxcbiAgZnJlZXppbmdfZHJpenpsZTogJ3JhaW4tYW5kLXNsZWV0LW1peCcsXG4gICdmcmVlemluZyBkcml6emxlJzogJ3JhaW4tYW5kLXNsZWV0LW1peCcsXG4gIGljZV9wZWxsZXRzX2hlYXZ5OiAncmFpbi1hbmQtc25vdy1taXgnLFxuICAnaGVhdnkgaWNlIHBlbGxldHMnOiAncmFpbi1hbmQtc25vdy1taXgnLFxuICBpY2VfcGVsbGV0czogJ3JhaW4tYW5kLXNub3ctbWl4JyxcbiAgJ2ljZSBwZWxsZXRzJzogJ3JhaW4tYW5kLXNub3ctbWl4JyxcbiAgaWNlX3BlbGxldHNfbGlnaHQ6ICdyYWluLWFuZC1zbm93LW1peCcsXG4gICdsaWdodCBpY2UgcGVsbGV0cyc6ICdyYWluLWFuZC1zbm93LW1peCcsXG4gIHNub3dfaGVhdnk6ICdzbm93eS0zJyxcbiAgJ2hlYXZ5IHNub3cnOiAnc25vd3ktMycsXG4gIHNub3c6ICdzbm93eS0yJyxcbiAgc25vd19saWdodDogJ3Nub3d5LTEnLFxuICAnbGlnaHQgc25vdyc6ICdzbm93eS0xJyxcbiAgZmx1cnJpZXM6ICd3aW5kJyxcbiAgdHN0b3JtOiAndHJvcGljYWwtc3Rvcm0nLFxuICByYWluX2hlYXZ5OiAncmFpbnktMycsXG4gICdoZWF2eSByYWluJzogJ3JhaW55LTMnLFxuICByYWluX2xpZ2h0OiAncmFpbnktMScsXG4gICdsaWdodCByYWluJzogJ3JhaW55LTEnLFxuICByYWluOiAncmFpbnktMicsXG4gIGRyaXp6bGU6ICdyYWlueS0xJyxcbiAgZm9nX2xpZ2h0OiAnaGF6ZScsXG4gICdsaWdodCBmb2cnOiAnaGF6ZScsXG4gIGZvZzogJ2ZvZycsXG4gIGNsb3VkeTogJ2Nsb3VkeS1vcmlnaW5hbCcsXG4gIG1vc3RseV9jbG91ZHk6ICdjbG91ZHktZGF5LTMnLFxuICAnbW9zdGx5IGNsb3VkeSc6ICdjbG91ZHktZGF5LTMnLFxuICBwYXJ0bHlfY2xvdWR5OiAnY2xvdWR5LWRheS0yJyxcbiAgJ3BhcnRseSBjbG91ZHknOiAnY2xvdWR5LWRheS0yJyxcbiAgbW9zdGx5X2NsZWFyOiAnY2xvdWR5LWRheS0xJyxcbiAgJ21vc3RseSBjbGVhcic6ICdjbG91ZHktZGF5LTEnLFxuICBjbGVhcjogJ2RheScsXG59O1xuXG5leHBvcnQgY29uc3QgY3djQ2xpbWFjZWxsTmlnaHRJY29uczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmc7IH0gPSB7XG4gIC4uLmN3Y0NsaW1hY2VsbERheUljb25zLFxuICBmcmVlemluZ19yYWluX2hlYXZ5OiAncmFpbnktNicsXG4gICdoZWF2eSBmcmVlemluZyByYWluJzogJ3JhaW55LTYnLFxuICBmcmVlemluZ19yYWluOiAncmFpbnktNScsXG4gICdmcmVlemluZyByYWluJzogJ3JhaW55LTUnLFxuICBmcmVlemluZ19yYWluX2xpZ2h0OiAncmFpbnktNCcsXG4gICdsaWdodCBmcmVlemluZyByYWluJzogJ3JhaW55LTQnLFxuICAvLyBmcmVlemluZ19kcml6emxlOiAncmFpbi1hbmQtc2xlZXQtbWl4JyxcbiAgLy8gaWNlX3BlbGxldHNfaGVhdnk6ICdyYWluLWFuZC1zbm93LW1peCcsXG4gIC8vIGljZV9wZWxsZXRzOiAncmFpbi1hbmQtc25vdy1taXgnLFxuICAvLyBpY2VfcGVsbGV0c19saWdodDogJ3JhaW4tYW5kLXNub3ctbWl4JyxcbiAgc25vd19oZWF2eTogJ3Nub3d5LTYnLFxuICAnaGVhdnkgc25vdyc6ICdzbm93eS02JyxcbiAgc25vdzogJ3Nub3d5LTUnLFxuICBzbm93X2xpZ2h0OiAnc25vd3ktNCcsXG4gICdsaWdodCBzbm93JzogJ3Nub3d5LTQnLFxuICAvLyBmbHVycmllczogJ3dpbmQnLFxuICAvLyB0c3Rvcm06ICd0cm9waWNhbC1zdG9ybScsXG4gIHJhaW5faGVhdnk6ICdyYWlueS02JyxcbiAgJ2hlYXZ5IHJhaW4nOiAncmFpbnktNicsXG4gIHJhaW5fbGlnaHQ6ICdyYWlueS00JyxcbiAgJ2xpZ2h0IHJhaW4nOiAncmFpbnktNCcsXG4gIHJhaW46ICdyYWlueS01JyxcbiAgZHJpenpsZTogJ3JhaW55LTQnLFxuICAvLyBmb2dfbGlnaHQ6ICdoYXplJyxcbiAgLy8gZm9nOiAnZm9nJyxcbiAgLy8gY2xvdWR5OiAnY2xvdWR5JyxcbiAgbW9zdGx5X2Nsb3VkeTogJ2Nsb3VkeS1uaWdodC0zJyxcbiAgJ21vc3RseSBjbG91ZHknOiAnY2xvdWR5LW5pZ2h0LTMnLFxuICBwYXJ0bHlfY2xvdWR5OiAnY2xvdWR5LW5pZ2h0LTInLFxuICAncGFydGx5IGNsb3VkeSc6ICdjbG91ZHktbmlnaHQtMicsXG4gIG1vc3RseV9jbGVhcjogJ2Nsb3VkeS1uaWdodC0xJyxcbiAgJ21vc3RseSBjbGVhcic6ICdjbG91ZHktbmlnaHQtMScsXG4gIGNsZWFyOiAnbmlnaHQnLFxuICBzdW5ueTogJ25pZ2h0Jyxcbn07XG5cbmV4cG9ydCBjb25zdCBjd2NDbGltYWNlbGxEYXlCZzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmc7IH0gPSB7XG4gIGZyZWV6aW5nX3JhaW5faGVhdnk6ICdyYWlueS0zJyxcbiAgZnJlZXppbmdfcmFpbjogJ3JhaW55LTInLFxuICBmcmVlemluZ19yYWluX2xpZ2h0OiAncmFpbnktMScsXG4gIGZyZWV6aW5nX2RyaXp6bGU6ICdyYWluLWFuZC1zbGVldC1taXgnLFxuICBpY2VfcGVsbGV0c19oZWF2eTogJ3JhaW4tYW5kLXNub3ctbWl4JyxcbiAgaWNlX3BlbGxldHM6ICdyYWluLWFuZC1zbm93LW1peCcsXG4gIGljZV9wZWxsZXRzX2xpZ2h0OiAncmFpbi1hbmQtc25vdy1taXgnLFxuICBzbm93X2hlYXZ5OiAnc25vd3ktMycsXG4gIHNub3c6ICdzbm93eS0yJyxcbiAgc25vd19saWdodDogJ3Nub3d5LTEnLFxuICBmbHVycmllczogJ3dpbmQnLFxuICB0c3Rvcm06ICd0cm9waWNhbC1zdG9ybScsXG4gIHJhaW5faGVhdnk6ICdyYWlueS0zJyxcbiAgcmFpbl9saWdodDogJ3JhaW55LTEnLFxuICByYWluOiAncmFpbnktMicsXG4gIGRyaXp6bGU6ICdyYWlueS0xJyxcbiAgZm9nX2xpZ2h0OiAnaGF6ZScsXG4gIGZvZzogJ2ZvZycsXG4gIGNsb3VkeTogJ2Nsb3VkeS1vcmlnaW5hbCcsXG4gIG1vc3RseV9jbG91ZHk6ICdkYXktY2xvdWQtMy5qcGcnLFxuICBwYXJ0bHlfY2xvdWR5OiAnZGF5LWNsb3VkLTIuanBnJyxcbiAgbW9zdGx5X2NsZWFyOiAnZGF5LWNsb3VkLTEuanBnJyxcbiAgY2xlYXI6ICdkYXktY2xlYXIuanBnJyxcbn07XG4iLCJleHBvcnQgY29uc3QgY3djRGFya3NreURheUljb25zOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZzsgfSA9IHtcbiAgY2xlYXI6ICdkYXknLFxuICAnY2xlYXItZGF5JzogJ2RheScsXG4gIHJhaW46ICdyYWlueS0yJyxcbiAgc25vdzogJ3Nub3d5LTInLFxuICBzbGVldDogJ3JhaW4tYW5kLXNsZWV0LW1peCcsXG4gIHdpbmQ6ICdjbG91ZHktZGF5LTEnLFxuICBmb2c6ICdmb2cnLFxuICBjbG91ZHk6ICdjbG91ZHktb3JpZ2luYWwnLFxuICAncGFydGx5LWNsb3VkeS1kYXknOiAnY2xvdWR5LWRheS0yJyxcbn07XG5cbmV4cG9ydCBjb25zdCBjd2NEYXJrc2t5TmlnaHRJY29uczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmc7IH0gPSB7XG4gIC4uLmN3Y0Rhcmtza3lEYXlJY29ucyxcbiAgY2xlYXI6ICduaWdodCcsXG4gICdjbGVhci1uaWdodCc6ICduaWdodCcsXG4gIHdpbmQ6ICdjbG91ZHktbmlnaHQtMScsXG4gICdwYXJ0bHktY2xvdWR5LWRheSc6ICdjbG91ZHktbmlnaHQtMicsXG4gICdwYXJ0bHktY2xvdWR5LW5pZ2h0JzogJ2Nsb3VkeS1uaWdodC0yJyxcbn07XG4iLCJleHBvcnQgY29uc3QgY3djRGVmYXVsdEhhc3NEYXlJY29uczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgY2xvdWR5OiAnY2xvdWR5LWRheS0zJyxcbiAgZXhjZXB0aW9uYWw6ICdzZXZlcmUtdGh1bmRlcnN0b3JtJyxcbiAgZm9nOiAnZm9nJyxcbiAgaGFpbDogJ3Nub3ctYW5kLXNsZWV0LW1peCcsXG4gIGxpZ2h0bmluZzogJ3NldmVyZS10aHVuZGVyc3Rvcm0nLFxuICAnbGlnaHRuaW5nLXJhaW55JzogJ3NjYXR0ZXJlZC10aHVuZGVyc3Rvcm1zJyxcbiAgcGFydGx5Y2xvdWR5OiAnY2xvdWR5LWRheS0zJyxcbiAgcG91cmluZzogJ3JhaW55LTYnLFxuICByYWlueTogJ3JhaW55LTUnLFxuICBzbm93eTogJ3Nub3d5LTYnLFxuICAnc25vd3ktcmFpbnknOiAnc25vdy1hbmQtc2xlZXQtbWl4JyxcbiAgc3Vubnk6ICdjbGVhci1kYXknLFxuICB3aW5keTogJ3dpbmQnLFxuICAnd2luZHktdmFyaWFudCc6ICd3aW5kJyxcbn07XG5cbmV4cG9ydCBjb25zdCBjd2NEZWZhdWx0SGFzc05pZ2h0SWNvbnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gIC4uLmN3Y0RlZmF1bHRIYXNzRGF5SWNvbnMsXG4gICdjbGVhci1uaWdodCc6ICdjbGVhci1uaWdodCcsXG59O1xuIiwiZXhwb3J0IGNvbnN0IGN3Y09wZW5XZWF0aGVyTWFwRGF5SWNvbnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nOyB9ID0ge1xuICAnY2xlYXIgc2t5JzogJ2RheScsXG4gICdmZXcgY2xvdWRzJzogJ2Nsb3VkeS1kYXktMScsXG4gICdzY2F0dGVyZWQgY2xvdWRzJzogJ2Nsb3VkeS1kYXktMicsXG4gICdicm9rZW4gY2xvdWRzJzogJ2Nsb3VkeS1kYXktMycsXG4gICdzaG93ZXIgcmFpbic6ICdyYWlueS0zJyxcbiAgcmFpbjogJ3JhaW55LTInLFxuICB0aHVuZGVyc3Rvcm06ICd0cm9waWNhbC1zdG9ybScsXG4gIHNub3c6ICdzbm93eS0yJyxcbiAgbWlzdDogJ2ZvZycsXG59O1xuXG5leHBvcnQgY29uc3QgY3djT3BlbldlYXRoZXJNYXBOaWdodEljb25zOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZzsgfSA9IHtcbiAgLi4uY3djT3BlbldlYXRoZXJNYXBEYXlJY29ucyxcbiAgJ2NsZWFyIHNreSc6ICdkYXktbmlnaHQnLFxuICAnZmV3IGNsb3Vkcyc6ICdjbG91ZHktbmlnaHQtMScsXG4gICdzY2F0dGVyZWQgY2xvdWRzJzogJ2Nsb3VkeS1uaWdodC0yJyxcbiAgJ2Jyb2tlbiBjbG91ZHMnOiAnY2xvdWR5LW5pZ2h0LTMnLFxufTtcbiIsIi8vIFBpcmF0ZSBXZWF0aGVyIEljb25zXG4vLyBjbGVhci1kYXksIGNsZWFyLW5pZ2h0LCByYWluLCBzbm93LCBzbGVldCwgd2luZCwgZm9nLCBjbG91ZHksIHBhcnRseS1jbG91ZHktZGF5IGFuZCBwYXJ0bHktY2xvdWR5LW5pZ2h0XG4vLyBtb3N0bHktY2xlYXItZGF5LCBtb3N0bHktY2xlYXItbmlnaHQsIG1vc3RseS1jbG91ZHktZGF5LCBtb3N0bHktY2xvdWR5LW5pZ2h0LCBwb3NzaWJsZS1yYWluLWRheSwgcG9zc2libGUtcmFpbi1uaWdodFxuLy8gcG9zc2libGUtc25vdy1kYXksIHBvc3NpYmxlLXNub3ctbmlnaHQsIHBvc3NpYmxlLXNsZWV0LWRheSwgcG9zc2libGUtc2xlZXQtbmlnaHQsIHBvc3NpYmxlLXByZWNpcGl0YXRpb24tZGF5XG4vLyBwb3NzaWJsZS1wcmVjaXBpdGF0aW9uLW5pZ2h0LCBwcmVjaXBpdGF0aW9uLCBkcml6emxlLCBsaWdodC1yYWluLCBoZWF2eS1yYWluLCBmbHVycmllcywgbGlnaHQtc25vdywgaGVhdnktc25vd1xuLy8gdmVyeS1saWdodC1zbGVldCwgbGlnaHQtc2xlZXQsIGhlYXZ5LXNsZWV0LCBicmVlenksIGRhbmdlcm91cy13aW5kXG5cbmV4cG9ydCBjb25zdCBjd2NEYXl0aW1lUGlyYXRlV2VhdGhlckljb25zOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZzsgfSA9IHtcbiAgZnJlZXppbmdfcmFpbl9oZWF2eTogJ3JhaW55LTMnLFxuICAnaGVhdnkgZnJlZXppbmcgcmFpbic6ICdyYWlueS0zJyxcbiAgZnJlZXppbmdfcmFpbjogJ3JhaW55LTInLFxuICAnZnJlZXppbmcgcmFpbic6ICdyYWlueS0yJyxcbiAgZnJlZXppbmdfcmFpbl9saWdodDogJ3JhaW55LTEnLFxuICAnbGlnaHQgZnJlZXppbmcgcmFpbic6ICdyYWlueS0xJyxcbiAgZnJlZXppbmdfZHJpenpsZTogJ3JhaW4tYW5kLXNsZWV0LW1peCcsXG4gIHNsZWV0OiAncmFpbi1hbmQtc2xlZXQtbWl4JyxcbiAgJ2ZyZWV6aW5nIGRyaXp6bGUnOiAncmFpbi1hbmQtc2xlZXQtbWl4JyxcbiAgaWNlX3BlbGxldHNfaGVhdnk6ICdyYWluLWFuZC1zbm93LW1peCcsXG4gICdoZWF2eSBpY2UgcGVsbGV0cyc6ICdyYWluLWFuZC1zbm93LW1peCcsXG4gIGljZV9wZWxsZXRzOiAncmFpbi1hbmQtc25vdy1taXgnLFxuICAnaWNlIHBlbGxldHMnOiAncmFpbi1hbmQtc25vdy1taXgnLFxuICBpY2VfcGVsbGV0c19saWdodDogJ3JhaW4tYW5kLXNub3ctbWl4JyxcbiAgJ2xpZ2h0IGljZSBwZWxsZXRzJzogJ3JhaW4tYW5kLXNub3ctbWl4JyxcbiAgc25vd19oZWF2eTogJ3Nub3d5LTMnLFxuICAnaGVhdnkgc25vdyc6ICdzbm93eS0zJyxcbiAgc25vdzogJ3Nub3d5LTInLFxuICBzbm93X2xpZ2h0OiAnc25vd3ktMScsXG4gICdsaWdodCBzbm93JzogJ3Nub3d5LTEnLFxuICBmbHVycmllczogJ3dpbmQnLFxuICB0c3Rvcm06ICd0cm9waWNhbC1zdG9ybScsXG4gIHJhaW5faGVhdnk6ICdyYWlueS0zJyxcbiAgJ2hlYXZ5IHJhaW4nOiAncmFpbnktMycsXG4gIHJhaW5fbGlnaHQ6ICdyYWlueS0xJyxcbiAgcmFpbnk6ICdyYWlueS0xJyxcbiAgJ2xpZ2h0IHJhaW4nOiAncmFpbnktMScsXG4gIHJhaW46ICdyYWlueS0yJyxcbiAgZHJpenpsZTogJ3JhaW55LTEnLFxuICBmb2dfbGlnaHQ6ICdoYXplJyxcbiAgJ2xpZ2h0IGZvZyc6ICdoYXplJyxcbiAgZm9nOiAnZm9nJyxcbiAgY2xvdWR5OiAnY2xvdWR5LW9yaWdpbmFsJyxcbiAgbW9zdGx5X2Nsb3VkeTogJ2Nsb3VkeS1kYXktMycsXG4gICdtb3N0bHkgY2xvdWR5JzogJ2Nsb3VkeS1kYXktMycsXG4gIHBhcnRseV9jbG91ZHk6ICdjbG91ZHktZGF5LTInLFxuICBwYXJ0bHljbG91ZHk6ICdjbG91ZHktZGF5LTInLFxuICAncGFydGx5LWNsb3VkeS1kYXknOiAnY2xvdWR5LWRheS0yJyxcbiAgJ3BhcnRseSBjbG91ZHknOiAnY2xvdWR5LWRheS0yJyxcbiAgbW9zdGx5X2NsZWFyOiAnY2xvdWR5LWRheS0xJyxcbiAgJ21vc3RseSBjbGVhcic6ICdjbG91ZHktZGF5LTEnLFxuICBjbGVhcjogJ2RheScsXG4gICdjbGVhci1kYXknOiAnZGF5JyxcbiAgd2luZDogJ3dpbmQnLFxuICB3aW5keTogJ3dpbmQnLFxuICBzdW5ueTogJ2RheScsXG4gICdjbGVhci1uaWdodCc6ICdkYXknLFxufTtcblxuZXhwb3J0IGNvbnN0IGN3Y05pZ2h0bHlQaXJhdGVXZWF0ZXJJY29uczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmc7IH0gPSB7XG4gIC4uLmN3Y0RheXRpbWVQaXJhdGVXZWF0aGVySWNvbnMsXG4gIGZyZWV6aW5nX3JhaW5faGVhdnk6ICdyYWlueS02JyxcbiAgJ2hlYXZ5IGZyZWV6aW5nIHJhaW4nOiAncmFpbnktNicsXG4gIGZyZWV6aW5nX3JhaW46ICdyYWlueS01JyxcbiAgJ2ZyZWV6aW5nIHJhaW4nOiAncmFpbnktNScsXG4gIGZyZWV6aW5nX3JhaW5fbGlnaHQ6ICdyYWlueS00JyxcbiAgJ2xpZ2h0IGZyZWV6aW5nIHJhaW4nOiAncmFpbnktNCcsXG4gIC8vIGZyZWV6aW5nX2RyaXp6bGU6ICdyYWluLWFuZC1zbGVldC1taXgnLFxuICAvLyBpY2VfcGVsbGV0c19oZWF2eTogJ3JhaW4tYW5kLXNub3ctbWl4JyxcbiAgLy8gaWNlX3BlbGxldHM6ICdyYWluLWFuZC1zbm93LW1peCcsXG4gIC8vIGljZV9wZWxsZXRzX2xpZ2h0OiAncmFpbi1hbmQtc25vdy1taXgnLFxuICBzbm93X2hlYXZ5OiAnc25vd3ktNicsXG4gICdoZWF2eSBzbm93JzogJ3Nub3d5LTYnLFxuICBzbm93OiAnc25vd3ktNScsXG4gIHNub3dfbGlnaHQ6ICdzbm93eS00JyxcbiAgJ2xpZ2h0IHNub3cnOiAnc25vd3ktNCcsXG4gIC8vIGZsdXJyaWVzOiAnd2luZCcsXG4gIC8vIHRzdG9ybTogJ3Ryb3BpY2FsLXN0b3JtJyxcbiAgcmFpbl9oZWF2eTogJ3JhaW55LTYnLFxuICAnaGVhdnkgcmFpbic6ICdyYWlueS02JyxcbiAgcmFpbl9saWdodDogJ3JhaW55LTQnLFxuICAnbGlnaHQgcmFpbic6ICdyYWlueS00JyxcbiAgcmFpbjogJ3JhaW55LTUnLFxuICBkcml6emxlOiAncmFpbnktNCcsXG4gIC8vIGZvZ19saWdodDogJ2hhemUnLFxuICAvLyBmb2c6ICdmb2cnLFxuICAvLyBjbG91ZHk6ICdjbG91ZHknLFxuICBtb3N0bHlfY2xvdWR5OiAnY2xvdWR5LW5pZ2h0LTMnLFxuICAnbW9zdGx5IGNsb3VkeSc6ICdjbG91ZHktbmlnaHQtMycsXG4gIHBhcnRseV9jbG91ZHk6ICdjbG91ZHktbmlnaHQtMicsXG4gIHBhcnRseWNsb3VkeTogJ2Nsb3VkeS1uaWdodC0yJyxcbiAgJ3BhcnRseS1jbG91ZHktbmlnaHQnOiAnY2xvdWR5LW5pZ2h0LTInLFxuICAncGFydGx5IGNsb3VkeSc6ICdjbG91ZHktbmlnaHQtMicsXG4gIG1vc3RseV9jbGVhcjogJ2Nsb3VkeS1uaWdodC0xJyxcbiAgJ21vc3RseSBjbGVhcic6ICdjbG91ZHktbmlnaHQtMScsXG4gIGNsZWFyOiAnbmlnaHQnLFxuICAnY2xlYXItbmlnaHQnOiAnbmlnaHQnLFxuICBzdW5ueTogJ25pZ2h0Jyxcbn07XG4iLCJpbXBvcnQgeyBjd2NCdWllbnJhZGFyRGF5SWNvbnMsIGN3Y0J1aWVucmFkYXJOaWdodEljb25zIH0gZnJvbSAnLi4vc3JjL2ljb25tb2RlbHMvaW0tYnVpZW5yYWRhcic7XG5pbXBvcnQgeyBjd2NDbGltYWNlbGxEYXlJY29ucywgY3djQ2xpbWFjZWxsTmlnaHRJY29ucyB9IGZyb20gJy4uL3NyYy9pY29ubW9kZWxzL2ltLWNsaW1hY2VsbCc7XG5pbXBvcnQgeyBjd2NEYXJrc2t5RGF5SWNvbnMsIGN3Y0Rhcmtza3lOaWdodEljb25zIH0gZnJvbSAnLi4vc3JjL2ljb25tb2RlbHMvaW0tZGFya3NreSc7XG5pbXBvcnQgeyBjd2NEZWZhdWx0SGFzc0RheUljb25zLCBjd2NEZWZhdWx0SGFzc05pZ2h0SWNvbnMgfSBmcm9tICcuLi9zcmMvaWNvbm1vZGVscy9pbS1oYXNzJztcbmltcG9ydCB7IGN3Y09wZW5XZWF0aGVyTWFwRGF5SWNvbnMsIGN3Y09wZW5XZWF0aGVyTWFwTmlnaHRJY29ucyB9IGZyb20gJy4uL3NyYy9pY29ubW9kZWxzL2ltLW9wZW53ZWF0aGVybWFwJztcbmltcG9ydCB7IGN3Y0RheXRpbWVQaXJhdGVXZWF0aGVySWNvbnMsIGN3Y05pZ2h0bHlQaXJhdGVXZWF0ZXJJY29ucyB9IGZyb20gJy4uL3NyYy9pY29ubW9kZWxzL2ltLXBpcmF0ZXdlYXRoZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFsZXJ0SXRlbSB7XG4gIGVudGl0eTogc3RyaW5nXG4gIGljb24/OiBzdHJpbmcgO1xuICBtaW4/OiBudW1iZXIgO1xuICBtYXg/OiBudW1iZXIgO1xuICBzaG93X2lmX29uPzogYm9vbGVhbiA7XG4gIHNob3dfaWZfZ2U/OiBudW1iZXIgO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBvbGxlbkl0ZW0ge1xuICBlbnRpdHk6IHN0cmluZyA7XG4gIGljb24/OiBzdHJpbmcgO1xuICBtaW46IG51bWJlciA7XG4gIG1heDogbnVtYmVyIDtcbiAgbG93PzogbnVtYmVyIDtcbiAgaGlnaD86IG51bWJlciA7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUG9sbGVuIHtcbiAgdHJlZT86IFBvbGxlbkl0ZW0gO1xuICB3ZWVkPzogUG9sbGVuSXRlbSA7XG4gIGdyYXNzPzogUG9sbGVuSXRlbSA7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWlyUXVhbGl0eSB7XG4gIHBtMjU/OiBzdHJpbmcgO1xuICBwbTEwPzogc3RyaW5nIDtcbiAgbzM/OiBzdHJpbmcgO1xuICBubzI/OiBzdHJpbmcgO1xuICBjbz86IHN0cmluZyA7XG4gIHNvMj86IHN0cmluZyA7XG4gIGVwYV9hcWk/OiBzdHJpbmcgO1xuICBlcGFfcHJpbWFyeV9wb2xsdXRhbnQ/OiBzdHJpbmcgO1xuICBlcGFfaGVhbHRoX2NvbmNlcm4/OiBzdHJpbmcgO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFV2IHtcbiAgcHJvdGVjdGlvbl93aW5kb3c/OiBzdHJpbmcgO1xuICBvem9uZV9sZXZlbD86IHN0cmluZyA7XG4gIHV2X2luZGV4Pzogc3RyaW5nIDtcbiAgdXZfbGV2ZWw/OiBzdHJpbmcgO1xuICBtYXhfdXZfaW5kZXg/OiBzdHJpbmcgO1xuICBzZXRfc2tpbl90eXBlXzE/OiBzdHJpbmcgO1xuICBzZXRfc2tpbl90eXBlXzI/OiBzdHJpbmcgO1xuICBzZXRfc2tpbl90eXBlXzM/OiBzdHJpbmcgO1xuICBzZXRfc2tpbl90eXBlXzQ/OiBzdHJpbmcgO1xuICBzZXRfc2tpbl90eXBlXzU/OiBzdHJpbmcgO1xuICBzZXRfc2tpbl90eXBlXzY/OiBzdHJpbmcgO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERheXMge1xuICBkYXlfMTogc3RyaW5nIDtcbiAgZGF5XzI6IHN0cmluZyA7XG4gIGRheV8zOiBzdHJpbmcgO1xuICBkYXlfNDogc3RyaW5nIDtcbiAgZGF5XzU6IHN0cmluZyA7XG4gIGRheV82OiBzdHJpbmcgO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEN1cnJlbnQge1xuICBzdW4/OiBzdHJpbmcgO1xuICBtb29uX3BoYXNlPzogc3RyaW5nIDtcbiAgLy8gZGFpbHlfc3VtbWFyeT86IHN0cmluZyA7XG4gIGN1cnJlbnRfY29uZGl0aW9ucz86IHN0cmluZ1xuICBodW1pZGl0eT86IHN0cmluZyA7XG4gIHByZXNzdXJlPzogc3RyaW5nIDtcbiAgdGVtcGVyYXR1cmU/OiBzdHJpbmcgO1xuICBmZWVsc19saWtlPzogc3RyaW5nIDtcbiAgdmlzaWJpbGl0eT86IHN0cmluZyA7XG4gIHdpbmRfYmVhcmluZz86IHN0cmluZyA7XG4gIHdpbmRfc3BlZWQ/OiBzdHJpbmcgO1xuICBwcmVjaXBpdGF0aW9uPzogc3RyaW5nIDtcbiAgZm9yZWNhc3Q/OiBib29sZWFuIDtcbn1cbmV4cG9ydCBpbnRlcmZhY2UgRm9yZWNhc3Qge1xuICBtZXRlb2dyYW0/OiBzdHJpbmcgO1xuICB0ZW1wZXJhdHVyZV9oaWdoPzogRGF5cyA7XG4gIHRlbXBlcmF0dXJlX2xvdz86IERheXMgO1xuICBzdW1tYXJ5PzogRGF5cyA7XG4gIGljb25zPzogRGF5cyA7XG4gIHByZWNpcGl0YXRpb25fcHJvYmFiaWxpdHk/OiBEYXlzIDtcbiAgcHJlY2lwaXRhdGlvbl9pbnRlbnNpdHk/OiBEYXlzIDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXZWF0aGVyIHtcbiAgaWNvbnNfbW9kZWw6IHN0cmluZyA7XG4gIGN1cnJlbnQ6IEN1cnJlbnQgO1xuICBmb3JlY2FzdD86IEZvcmVjYXN0IDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIb3VycyB7XG4gIGhvdXJfMTogc3RyaW5nIDtcbiAgaG91cl8yOiBzdHJpbmcgO1xuICBob3VyXzM6IHN0cmluZyA7XG4gIGhvdXJfNDogc3RyaW5nIDtcbiAgaG91cl81OiBzdHJpbmcgO1xuICBob3VyXzY6IHN0cmluZyA7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSWNvbnNDb25maWcge1xuICBwYXRoOiBzdHJpbmcgO1xuICBpY29uVHlwZTogc3RyaW5nIDtcbiAgaWNvbnNfbW9kZWw6IHN0cmluZyA7XG4gIGljb25zRGF5OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZzsgfSA7XG4gIGljb25zTmlnaHQ6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nOyB9IDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJVGVybXMge1xuICAgd2luZERpcmVjdGlvbnM7XG4gICB3b3Jkcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBbGVydCB7XG4gIGZpcmVfcmlzaz86IEFsZXJ0SXRlbSA7XG4gIHRodW5kZXJzdG9ybXNfcmlzaz86IEFsZXJ0SXRlbSA7XG4gIGh5ZHJhdWxpY19yaXNrPzogQWxlcnRJdGVtIDtcbiAgaHlkcm9nZW9sb2dpY2FsX3Jpc2s/OiBBbGVydEl0ZW0gO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNlYSB7XG4gIHN3ZWxsX2RpcmVjdGlvbj86IEhvdXJzIDtcbiAgc3dlbGxfaGVpZ2h0PzogSG91cnMgO1xuICBzd2VsbF9wZXJpb2Q/OiBIb3VycyA7XG4gIHdpbmRfZGlyZWN0aW9uOiBIb3VycyA7XG4gIHdpbmRfc3BlZWQ6IEhvdXJzIDtcbiAgYWlyX3RlbXBlcmF0dXJlOiBIb3VycyA7XG4gIHdhdGVyX3RlbXBlcmF0dXJlOiBIb3VycyA7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FyZENvbmZpZyB7XG4gIHR5cGU6IHN0cmluZyA7XG4gIG5hbWU/OiBzdHJpbmcgO1xuICBsYW5ndWFnZT86IHN0cmluZyA7XG4gIGFuaW1hdGlvbj86IGJvb2xlYW4gO1xuICBkaXNwbGF5OiBzdHJpbmdbXVxuICB1dj86IFV2IDtcbiAgYWlyX3F1YWxpdHk/OiBBaXJRdWFsaXR5IDtcbiAgcG9sbGVuPzogUG9sbGVuIDtcbiAgd2VhdGhlcjogV2VhdGhlciA7XG4gIGNhbWVyYT86IHN0cmluZyA7XG4gIGFsZXJ0OiBBbGVydCA7XG4gIHNlYTogU2VhIDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJY29uc01vZGVsQ29uZmlnIHtcbiAgaWNvbnNEYXk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGljb25zTmlnaHQ6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59XG5cbmV4cG9ydCBjb25zdCBpY29uc01vZGVsczogUmVjb3JkPHN0cmluZywgSWNvbnNNb2RlbENvbmZpZz4gPSB7XG4gIHBpcmF0ZXdlYXRoZXI6IHtcbiAgICBpY29uc0RheTogY3djRGF5dGltZVBpcmF0ZVdlYXRoZXJJY29ucyxcbiAgICBpY29uc05pZ2h0OiBjd2NOaWdodGx5UGlyYXRlV2VhdGVySWNvbnMsXG4gIH0sXG4gIGNsaW1hY2VsbDoge1xuICAgIGljb25zRGF5OiBjd2NDbGltYWNlbGxEYXlJY29ucyxcbiAgICBpY29uc05pZ2h0OiBjd2NDbGltYWNlbGxOaWdodEljb25zLFxuICB9LFxuICBkYXJrc2t5OiB7XG4gICAgaWNvbnNEYXk6IGN3Y0Rhcmtza3lEYXlJY29ucyxcbiAgICBpY29uc05pZ2h0OiBjd2NEYXJrc2t5TmlnaHRJY29ucyxcbiAgfSxcbiAgb3BlbndlYXRoZXJtYXA6IHtcbiAgICBpY29uc0RheTogY3djT3BlbldlYXRoZXJNYXBEYXlJY29ucyxcbiAgICBpY29uc05pZ2h0OiBjd2NPcGVuV2VhdGhlck1hcE5pZ2h0SWNvbnMsXG4gIH0sXG4gIGJ1aWVucmFkYXI6IHtcbiAgICBpY29uc0RheTogY3djQnVpZW5yYWRhckRheUljb25zLFxuICAgIGljb25zTmlnaHQ6IGN3Y0J1aWVucmFkYXJOaWdodEljb25zLFxuICB9LFxuICBkZWZhdWx0aGFzczoge1xuICAgIGljb25zRGF5OiBjd2NEZWZhdWx0SGFzc0RheUljb25zLFxuICAgIGljb25zTmlnaHQ6IGN3Y0RlZmF1bHRIYXNzTmlnaHRJY29ucyxcbiAgfSxcbn07XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbmltcG9ydCB7IEhvbWVBc3Npc3RhbnQgfSBmcm9tICdjdXN0b20tY2FyZC1oZWxwZXJzL2Rpc3QnO1xuaW1wb3J0IHsgaWNvbnNNb2RlbHMgfSBmcm9tICcuLi8uLi9iYWNrdXAvdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEljb25zQ29uZmlnUmVzdWx0IHtcbiAgaWNvbnNNb2RlbDogc3RyaW5nO1xuICBpY29uc0RheTogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgaWNvbnNOaWdodDogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbn1cblxuLy8gZXhwb3J0IGNvbnN0IGdldEVudGl0eVN0YXRlID0gKGhhc3M6IEhvbWVBc3Npc3RhbnQsIGVudGl0eUlkPzogc3RyaW5nKSA9PiAoXG4vLyAgIGVudGl0eUlkID8gaGFzcy5zdGF0ZXNbZW50aXR5SWRdPy5zdGF0ZSA6IHVuZGVmaW5lZFxuLy8gKTtcblxuLyoqXG4gKiBSZXN0aXR1aXNjZSBsYSB0cmFkdXppb25lIGRpIHVuIHRlcm1pbmUgdXNhbmRvIHVuIGRpemlvbmFyaW8sIGluIG1vZG8gY2FzZS1pbnNlbnNpdGl2ZS5cbiAqIFNlIGlsIHRlcm1pbmUgbm9uIMOoIHRyb3ZhdG8sIHJlc3RpdHVpc2NlIGwnb3JpZ2luYWxlLlxuICovXG5leHBvcnQgY29uc3QgdHJhbnNsYXRlID0gKHRlcm06IHN0cmluZywgZGljdGlvbmFyeTogUmVjb3JkPHN0cmluZywgc3RyaW5nPik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGtleSA9IE9iamVjdC5rZXlzKGRpY3Rpb25hcnkpLmZpbmQoKGspID0+IGsudG9Mb3dlckNhc2UoKSA9PT0gdGVybS50b0xvd2VyQ2FzZSgpKTtcbiAgcmV0dXJuIGtleSA/IGRpY3Rpb25hcnlba2V5XSA6IHRlcm07XG59O1xuXG50eXBlIExvY2FsZUluZm8gPSB7XG4gIGxvY2FsZTogc3RyaW5nO1xuICB0aW1lem9uZTogc3RyaW5nO1xuICBjd2M/OiBudW1iZXI7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0TG9jYWxlSW5mbyA9IChsYW5nOiBzdHJpbmcpOiBMb2NhbGVJbmZvID0+IHtcbiAgY29uc3QgbG9jYWxlTWFwOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIGVuOiAnZW4tVVMnLFxuICAgIGl0OiAnaXQtSVQnLFxuICAgIG5sOiAnbmwtTkwnLFxuICAgIGVzOiAnZXMtRVMnLFxuICAgIGRlOiAnZGUtREUnLFxuICAgIGZyOiAnZnItRlInLFxuICAgICdzci1sYXRuJzogJ3NyLUxhdG4nLFxuICAgIHB0OiAncHQtUFQnLFxuICAgIGRhOiAnZGEtREsnLFxuICAgICduby1ubyc6ICduYi1OTycsXG4gICAgY3M6ICdjcy1DWicsXG4gICAgcnU6ICdydS1SVScsXG4gIH07XG5cbiAgY29uc3QgdGltZXpvbmVNYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgZW46ICdBbWVyaWNhL05ld19Zb3JrJyxcbiAgICBpdDogJ0V1cm9wZS9Sb21lJyxcbiAgICBubDogJ0V1cm9wZS9BbXN0ZXJkYW0nLFxuICAgIGVzOiAnRXVyb3BlL01hZHJpZCcsXG4gICAgZGU6ICdFdXJvcGUvQmVybGluJyxcbiAgICBmcjogJ0V1cm9wZS9QYXJpcycsXG4gICAgJ3NyLWxhdG4nOiAnRXVyb3BlL0JlbGdyYWRlJyxcbiAgICBqYTogJ0FzaWEvVG9reW8nLFxuICAgIHB0OiAnRXVyb3BlL0xpc2JvbicsXG4gICAgZGE6ICdFdXJvcGUvQ29wZW5oYWdlbicsXG4gICAgJ25vLW5vJzogJ0V1cm9wZS9Pc2xvJyxcbiAgICBjczogJ0V1cm9wZS9QcmFndWUnLFxuICAgIHJ1OiAnRXVyb3BlL01vc2NvdycsXG4gIH07XG5cbiAgY29uc3QgY3djTG9jYWxlOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+ID0ge1xuICAgIGVuOiAwLFxuICAgIGl0OiAxLFxuICAgIG5sOiAyLFxuICAgIGVzOiAzLFxuICAgIGRlOiA0LFxuICAgIGZyOiA1LFxuICAgICdzci1sYXRuJzogNixcbiAgICBwdDogNyxcbiAgICBkYTogOCxcbiAgICAnbm8tbm8nOiA5LFxuICAgIGNzOiAxMCxcbiAgICBydTogMTEsXG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBsb2NhbGU6IGxvY2FsZU1hcFtsYW5nXSB8fCBsYW5nLFxuICAgIHRpbWV6b25lOiB0aW1lem9uZU1hcFtsYW5nXSB8fCAnVVRDJyxcbiAgICAuLi4obGFuZyBpbiBjd2NMb2NhbGUgJiYgeyBjd2M6IGN3Y0xvY2FsZVtsYW5nXSB9KSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRMb2NhbGUgPSAobGFuZzogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IG1hcCA9IHtcbiAgICBpdDogJ2l0LUlUJyxcbiAgICBlbjogJ2VuLVVTJyxcbiAgICBmcjogJ2ZyLUZSJyxcbiAgICBkZTogJ2RlLURFJyxcbiAgICBlczogJ2VzLUVTJyxcbiAgICBqYTogJ2phLUpQJyxcbiAgICB6aDogJ3poLUNOJyxcbiAgICAvLyBBZ2dpdW5naSBhbHRyaSBzZSBzZXJ2b25vXG4gIH07XG4gIHJldHVybiBtYXBbbGFuZ10gfHwgYCR7bGFuZ30tJHtsYW5nLnRvVXBwZXJDYXNlKCl9YDsgLy8gZmFsbGJhY2sgZ2VuZXJpY29cbn07XG5cbmV4cG9ydCBjb25zdCBnZXRGb3JtYXR0ZXIgPSAoXG4gIGxvY2FsZTogc3RyaW5nID0gJ2VuLVVTJyxcbiAgZnJhY3Rpb25EaWdpdHM6IG51bWJlciA9IDEsXG4gIHVzZUdyb3VwaW5nOiBib29sZWFuID0gZmFsc2UsXG4pOiBJbnRsLk51bWJlckZvcm1hdCA9PiBuZXcgSW50bC5OdW1iZXJGb3JtYXQobG9jYWxlLCB7XG4gIG1pbmltdW1GcmFjdGlvbkRpZ2l0czogZnJhY3Rpb25EaWdpdHMsXG4gIG1heGltdW1GcmFjdGlvbkRpZ2l0czogZnJhY3Rpb25EaWdpdHMsXG4gIHVzZUdyb3VwaW5nLFxufSk7XG5cbmV4cG9ydCBjb25zdCBmb3JtYXROdW1iZXIgPSAoXG4gIHtcbiAgICBzdHJpbmdOdW1iZXIsXG4gICAgbGFuZyA9ICdlbicsXG4gICAgZnJhY3Rpb25EaWdpdHMgPSAxLFxuICAgIHVzZUdyb3VwaW5nID0gZmFsc2UsXG4gIH06IHtcbiAgICBzdHJpbmdOdW1iZXI6IHN0cmluZztcbiAgICBsYW5nPzogc3RyaW5nO1xuICAgIGZyYWN0aW9uRGlnaXRzPzogbnVtYmVyO1xuICAgIHVzZUdyb3VwaW5nPzogYm9vbGVhbjtcbiAgfSxcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IG51bWJlciA9IHBhcnNlRmxvYXQoc3RyaW5nTnVtYmVyKTtcbiAgaWYgKE51bWJlci5pc05hTihudW1iZXIpKSByZXR1cm4gJyc7XG5cbiAgY29uc3QgZWZmZWN0aXZlRm9ybWF0dGVyID0gZ2V0Rm9ybWF0dGVyKGdldExvY2FsZShsYW5nKSwgZnJhY3Rpb25EaWdpdHMsIHVzZUdyb3VwaW5nKTtcbiAgLy8gY29uc29sZS5kZWJ1ZyhgPj4+fHwgJHtudW1iZXJ9ICR7ZWZmZWN0aXZlRm9ybWF0dGVyLmZvcm1hdChudW1iZXIpfWApO1xuICByZXR1cm4gZWZmZWN0aXZlRm9ybWF0dGVyLmZvcm1hdChudW1iZXIpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEljb25Nb2RlbERhdGEgPSAoaWNvbnNNb2RlbDogc3RyaW5nKTogSWNvbnNDb25maWdSZXN1bHQgPT4ge1xuICBjb25zdCBtb2RlbE5hbWUgPSBpY29uc01vZGVsLnRvTG93ZXJDYXNlKCkgPz8gJ2NsaW1hY2VsbCc7XG5cbiAgaWYgKG1vZGVsTmFtZSBpbiBpY29uc01vZGVscykge1xuICAgIGNvbnN0IHsgaWNvbnNEYXksIGljb25zTmlnaHQgfSA9IGljb25zTW9kZWxzW21vZGVsTmFtZV07XG4gICAgcmV0dXJuIHtcbiAgICAgIGljb25zTW9kZWw6IG1vZGVsTmFtZSxcbiAgICAgIGljb25zRGF5LFxuICAgICAgaWNvbnNOaWdodCxcbiAgICB9O1xuICB9XG5cbiAgY29uc29sZS53YXJuKGBVbmtub3duIGljb25zIG1vZGVsOiAke21vZGVsTmFtZX0uIEZhbGxpbmcgYmFjayB0byAnY2xpbWFjZWxsJy5gKTtcblxuICBjb25zdCBmYWxsYmFjayA9IGljb25zTW9kZWxzWydjbGltYWNlbGwnXTtcbiAgcmV0dXJuIHtcbiAgICBpY29uc01vZGVsOiAnY2xpbWFjZWxsJyxcbiAgICBpY29uc0RheTogZmFsbGJhY2suaWNvbnNEYXksXG4gICAgaWNvbnNOaWdodDogZmFsbGJhY2suaWNvbnNOaWdodCxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYWQobjogbnVtYmVyIHwgc3RyaW5nLCB3aWR0aDogbnVtYmVyLCB6ID0gJzAnKTogc3RyaW5nIHtcbiAgcmV0dXJuIG4udG9TdHJpbmcoKS5wYWRTdGFydCh3aWR0aCwgeik7XG59XG5cbi8qKlxuICogQ29udmVydGUgdW5hIHN0cmluZ2EgbnVtZXJpY2EgbG9jYWxpenphdGEgaW4gdW4gbnVtZXJvLlxuICogRXNlbXBpbzogJzEuMjM0LDU2JyAoaXQtSVQpIOKGkiAxMjM0LjU2XG4gKiBAcGFyYW0gaW5wdXQgLSBMYSBzdHJpbmdhIG8gbnVtZXJvIGRhIGNvbnZlcnRpcmUuXG4gKiBAcGFyYW0gbG9jYWxlIC0gSWwgbG9jYWxlIGRhIHV0aWxpenphcmUgcGVyIGRldGVybWluYXJlIGkgc2VwYXJhdG9yaS5cbiAqIEByZXR1cm5zIElsIG51bWVybyBjb252ZXJ0aXRvIG8gTmFOIHNlIGxhIGNvbnZlcnNpb25lIGZhbGxpc2NlLlxuICovXG5leHBvcnQgY29uc3Qgc3RyaW5nMk51bWJlciA9IChpbnB1dDogc3RyaW5nIHwgbnVtYmVyLCBsb2NhbGU6IHN0cmluZyA9ICdlbi1VUycpOiBudW1iZXIgPT4ge1xuICBpZiAodHlwZW9mIGlucHV0ID09PSAnbnVtYmVyJykgcmV0dXJuIGlucHV0O1xuXG4gIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBJbnRsLk51bWJlckZvcm1hdChsb2NhbGUpO1xuICBjb25zdCBwYXJ0cyA9IGZvcm1hdHRlci5mb3JtYXRUb1BhcnRzKDEyMzQ1NjcuODkpO1xuXG4gIGNvbnN0IGdyb3VwID0gcGFydHMuZmluZCgocGFydCkgPT4gcGFydC50eXBlID09PSAnZ3JvdXAnKT8udmFsdWUgfHwgJyc7XG4gIGNvbnN0IGRlY2ltYWwgPSBwYXJ0cy5maW5kKChwYXJ0KSA9PiBwYXJ0LnR5cGUgPT09ICdkZWNpbWFsJyk/LnZhbHVlIHx8ICcuJztcblxuICAvLyBSaW11b3ZlIGkgc2VwYXJhdG9yaSBkZWxsZSBtaWdsaWFpYSBlIHNvc3RpdHVpc2NlIGlsIHNlcGFyYXRvcmUgZGVjaW1hbGUgY29uICcuJ1xuICBjb25zdCBub3JtYWxpemVkID0gaW5wdXRcbiAgICAucmVwbGFjZShuZXcgUmVnRXhwKGBcXFxcJHtncm91cH1gLCAnZycpLCAnJylcbiAgICAucmVwbGFjZShuZXcgUmVnRXhwKGBcXFxcJHtkZWNpbWFsfWApLCAnLicpO1xuXG4gIHJldHVybiBOdW1iZXIobm9ybWFsaXplZCk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0RW50aXR5UmF3VmFsdWUgPSAoaGFzczogSG9tZUFzc2lzdGFudCwgZW50aXR5SWQ/OiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4gKFxuICBlbnRpdHlJZCAmJiBoYXNzLnN0YXRlc1tlbnRpdHlJZF0/LnN0YXRlXG4pO1xuXG5leHBvcnQgY29uc3QgZ2V0RW50aXR5UmF3QXR0cmlidXRlID0gKGhhc3M6IEhvbWVBc3Npc3RhbnQsIGVudGl0eUlkOiBzdHJpbmcsIGF0dHJpYnV0ZTogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IChcbiAgZW50aXR5SWQgJiYgaGFzcy5zdGF0ZXNbZW50aXR5SWRdPy5hdHRyaWJ1dGVzW2F0dHJpYnV0ZV1cbik7XG5cbmV4cG9ydCBjb25zdCBnZXRFbnRpdHlOdW1lcmljVmFsdWUgPSAoXG4gIHtcbiAgICBlbnRpdHlJZCxcbiAgICBoYXNzLFxuICAgIGxhbmcgPSAnZW4nLFxuICAgIGRlY2ltYWxzID0gMCxcbiAgfToge1xuICAgIGVudGl0eUlkPzogc3RyaW5nO1xuICAgIGhhc3M/OiBIb21lQXNzaXN0YW50O1xuICAgIGxhbmc/OiBzdHJpbmc7XG4gICAgZGVjaW1hbHM/OiBudW1iZXI7XG4gIH0gPSB7fSxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IHN0YXRlID0gaGFzcyAmJiBlbnRpdHlJZCAmJiBoYXNzLnN0YXRlc1tlbnRpdHlJZF0/LnN0YXRlO1xuICByZXR1cm4gc3RhdGUgIT09IHVuZGVmaW5lZCA/IGZvcm1hdE51bWJlcih7IHN0cmluZ051bWJlcjogc3RhdGUsIGZyYWN0aW9uRGlnaXRzOiBkZWNpbWFscywgbGFuZyB9KSA6IHVuZGVmaW5lZDtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRFbnRpdHlVbml0ID0gKGhhc3M6IEhvbWVBc3Npc3RhbnQsIGVudGl0eUlkPzogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IChcbiAgZW50aXR5SWQgJiYgaGFzcy5zdGF0ZXNbZW50aXR5SWRdPy5hdHRyaWJ1dGVzPy51bml0X29mX21lYXN1cmVtZW50XG4pO1xuXG5leHBvcnQgY29uc3QgZ2V0RW50aXR5SWNvbiA9IChoYXNzOiBIb21lQXNzaXN0YW50LCBlbnRpdHlJZD86IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiAoXG4gIGVudGl0eUlkICYmIGhhc3Muc3RhdGVzW2VudGl0eUlkXT8uYXR0cmlidXRlcz8uaWNvblxuKTtcblxuZXhwb3J0IGNvbnN0IGdldFdpbmREaXJlY3Rpb25zID0gKFxuICB3ZDogbnVtYmVyIHwgc3RyaW5nLFxuICBjd2NMb2NXaW5kRGlyZWN0aW9ucyxcbik6IHN0cmluZyB8IG51bGwgPT4ge1xuICBjb25zdCB3ZE51bWJlciA9IHR5cGVvZiB3ZCA9PT0gJ251bWJlcicgPyB3ZCA6IHBhcnNlRmxvYXQod2QpO1xuXG4gIGlmIChOdW1iZXIuaXNOYU4od2ROdW1iZXIpKSB7XG4gICAgcmV0dXJuIGN3Y0xvY1dpbmREaXJlY3Rpb25zW3dkXSA/PyBudWxsO1xuICB9XG5cbiAgaWYgKHdkTnVtYmVyIDwgMCB8fCB3ZE51bWJlciA+IDM2MCkge1xuICAgIGNvbnNvbGUuZXJyb3IoYEludmFsaWQgd2luZCBkaXJlY3Rpb246ICcke3dkfScuIFZhbGlkIHZhbHVlcyBhcmUgYmV0d2VlbiAwIGFuZCAzNjAgZGVncmVlcy5gKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGRpcmVjdGlvbnMgPSBbXG4gICAgJ04nLCAnTk5FJywgJ05FJywgJ0VORScsICdFJywgJ0VTRScsXG4gICAgJ1NFJywgJ1NTRScsICdTJywgJ1NTVycsICdTVycsICdXU1cnLFxuICAgICdXJywgJ1dOVycsICdOVycsICdOTlcnLFxuICBdO1xuXG4gIGNvbnN0IGluZGV4ID0gTWF0aC5mbG9vcigoKHdkTnVtYmVyICsgMTEuMjUpICUgMzYwKSAvIDIyLjUpO1xuXG4gIGNvbnN0IGRpcktleSA9IGRpcmVjdGlvbnNbaW5kZXhdO1xuXG4gIHJldHVybiBjd2NMb2NXaW5kRGlyZWN0aW9uc1tkaXJLZXldID8/IG51bGw7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gaW1hZ2VFeGlzdChpbWFnZVNyYzogc3RyaW5nLCB0aW1lb3V0ID0gNTAwMCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICByZXR1cm4gbmV3IFByb21pc2U8Ym9vbGVhbj4oKHJlc29sdmUpID0+IHtcbiAgICBjb25zdCBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaW1nLnNyYyA9ICcnOyAvLyBmb3J6YSBzdG9wXG4gICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICB9LCB0aW1lb3V0KTtcblxuICAgIGltZy5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICB9O1xuICAgIGltZy5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgIH07XG4gICAgaW1nLnNyYyA9IGltYWdlU3JjO1xuICB9KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRKU09OKGZ1bGxfcGF0aF9maWxlOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goZnVsbF9wYXRoX2ZpbGUpO1xuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIGNvbnN0IGVyciA9IGBFUlJPUiByZXRyaWV2aW5nIEpTT04gZmlsZTogJyR7ZnVsbF9wYXRoX2ZpbGV9Jywgc3RhdHVzOiAke3Jlc3BvbnNlLnN0YXR1c30gJHtyZXNwb25zZS5zdGF0dXNUZXh0fWA7XG4gICAgICBjb25zb2xlLmluZm8oZXJyKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihlcnIpO1xuICAgIH1cbiAgICBjb25zb2xlLmluZm8oYExvY2FsZSAnJHtmdWxsX3BhdGhfZmlsZX0nIGxvYWRlZGApO1xuICAgIHJldHVybiBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc29sZS5pbmZvKGBGZXRjaCBmYWlsZWQgZm9yICcke2Z1bGxfcGF0aF9maWxlfSc6YCwgZXJyb3IpO1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2dJbmZvKG1lc3NhZ2U6IHN0cmluZywgLi4uc3R5bGVzOiB1bmtub3duW10pIHtcbiAgY29uc29sZS5pbmZvKG1lc3NhZ2UsIC4uLihzdHlsZXMubGVuZ3RoID8gc3R5bGVzIDogW10pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTG9jYWxpemVkTnVtYmVyKHZhbHVlOiBzdHJpbmcgfCBudW1iZXIsIGxvY2FsZSA9ICdlbi1VUycpOiBudW1iZXIge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykgcmV0dXJuIHZhbHVlO1xuXG4gIC8vIFNlbXBsaWZpY2F6aW9uZSBzb2xvIHBlciAnaXQtSVQnOiB1c2EgdmlyZ29sYSBjb21lIHNlcGFyYXRvcmUgZGVjaW1hbGVcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHZhbHVlLnJlcGxhY2UoL1xcLi9nLCAnJykucmVwbGFjZSgnLCcsICcuJyk7XG4gIHJldHVybiBOdW1iZXIobm9ybWFsaXplZCk7XG59XG4iLCIvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JqZWN0LWN1cmx5LW5ld2xpbmVcbmV4cG9ydCBjb25zdCBjd2NMb2NhbGUgPSB7IGVuOiAwLCBpdDogMSwgbmw6IDIsIGVzOiAzLCBkZTogNCwgZnI6IDUsICdzci1sYXRuJzogNiwgcHQ6IDcsIGRhOiA4LCAnbm8tbm8nOiA5LCBjczogMTAgfTtcblxuLy8gZXhwb3J0IGxldCBjd2NMb2NXaW5kRGlyZWN0aW9ucyA9IHtcbi8vICAgJ04nOiBbJ04nLCAnTicsICdOJywgJ04nLCAnTicsICdOJywgJ1MnXSxcbi8vICAgJ05ORSc6IFsnTk5FJywgJ05ORScsICdOTk8nLCAnTk5FJywgJ05OTycsICdOTkUnLCAnU1NJJ10sXG4vLyAgICdORSc6IFsnTkUnLCAnTkUnLCAnTk8nLCAnTkUnLCAnTk8nLCAnTkUnLCAnU0knXSxcbi8vICAgJ0VORSc6IFsnRU5FJywgJ0VORScsICdPTk8nLCAnRU5FJywgJ09OTycsICdFTkUnLCAnSVNJJ10sXG4vLyAgICdFJzogWydFJywgJ0UnLCAnTycsICdFJywgJ08nLCAnRScsICdJJ10sXG4vLyAgICdFU0UnOiBbJ0VTRScsICdFU0UnLCAnT1pPJywgJ0VTRScsICdPU08nLCAnRVNFJywgJ0lKSSddLFxuLy8gICAnU0UnOiBbJ1NFJywgJ1NFJywgJ1pPJywgJ1NFJywgJ1NPJywgJ1NFJywgJ0pJJ10sXG4vLyAgICdTU0UnOiBbJ1NTRScsICdTU0UnLCAnWlpPJywgJ1NTRScsICdTU08nLCAnU1NFJywgJ0pKSSddLFxuLy8gICAnUyc6IFsnUycsICdTJywgJ1onLCAnUycsICdTJywgJ1MnLCAnSiddLFxuLy8gICAnU1NXJzogWydTU1cnLCAnU1NPJywgJ1paVycsICdTU08nLCAnU1NXJywgJ1NTTycsICdKSlonXSxcbi8vICAgJ1NXJzogWydTVycsICdTTycsICdaVycsICdTTycsICdTVycsICdTTycsICdKWiddLFxuLy8gICAnV1NXJzogWydXU1cnLCAnT1NPJywgJ1daVycsICdPU08nLCAnV1NXJywgJ09TTycsICdaU1onXSxcbi8vICAgJ1cnOiBbJ1cnLCAnTycsICdXJywgJ08nLCAnVycsICdPJywgJ1onXSxcbi8vICAgJ1dOVyc6IFsnV05XJywgJ09OTycsICdXTlcnLCAnT05PJywgJ1dOVycsICdPTk8nLCAnWlNaJ10sXG4vLyAgICdOVyc6IFsnTlcnLCAnTk8nLCAnTlcnLCAnTk8nLCAnTlcnLCAnTk8nLCAnU1onXSxcbi8vICAgJ05OVyc6IFsnTk5XJywgJ05OTycsICdOTlcnLCAnTk5PJywgJ05OVycsICdOTk8nLCAnU1NaJ10sXG4vLyB9O1xuXG4vLyBleHBvcnQgbGV0IGN3Y1Rlcm1zID0ge1xuLy8gICAnRmVlbHMgTGlrZScgOiBbJ0ZlZWxzIExpa2UnLCAnUGVyY2VwaXRhJywgJ1ZvZWx0IEFscycsICdQYXJlY2UgcXVlJywgJ0dlZiZ1dW1sO2hsdCcsXG4vLyAgICAgJ1Jlc3NlbnRpZScsICdTdWJqZWt0aXZuaSBvc2XEh2FqJ10sXG4vLyAgICduZXdfbW9vbic6IFsgJ05ldyBtb29uJywgJ05vdmlsdW5pbycsICdOaWV1d2UgbWFhbicsICdMdW5hIG51ZXZhJywgJ05ldW1vbmQnLFxuLy8gICAgICdOb3V2ZWxsZSBsdW5lJywgJ01sYWQgbWVzZWMnXSxcbi8vICAgJ25ldyc6IFsgJ05ldyBtb29uJywgJ05vdmlsdW5pbycsICdOaWV1d2UgbWFhbicsICdMdW5hIG51ZXZhJywgJ05ldW1vbmQnLFxuLy8gICAgICdOb3V2ZWxsZSBsdW5lJywgJ01sYWQgbWVzZWMnXSxcbi8vICAgJ3dheGluZ19jcmVzY2VudCc6IFsnV2F4aW5nIGNyZXNjZW50JywgJ0x1bmEgY3Jlc2NlbnRlJywgJ1dhc3NlbmRlIHNpa2tlbCcsICdNZWRpYSBsdW5hIGRlIGNlcmEnLCAnWnVuZWhtZW5kZSBTaWNoZWwnLFxuLy8gICAgICdQcmVtaWVyIGNyb2lzc2FudCcsICdQcnZhIG9zbWluYSddLFxuLy8gICAnZmlyc3RfcXVhcnRlcic6IFsnRmlyc3QgcXVhcnRlcicsICdQcmltbyBRdWFydG8nLCAnRWVyc3RlIGt3YXJ0YWFsJywgJ1ByaW1lciB0cmltZXN0cmUnLCAnRXJzdGVzIFZpZXJ0ZWwnLFxuLy8gICAgICdQcmVtaWVyIHF1YXJ0aWVyJywgJ1BydmEgxI1ldHZydCddLFxuLy8gICAnd2F4aW5nX2dpYmJvdXMnOiBbJ1dheGluZyBHaWJib3VzJywgJ0dpYmJvc2EgY3Jlc2NlbnRlJywgJ1dhc3NlbiBHaWJib3VzJywgJ0VuY2VyYWRvIEdpYmJvdXMnLCAnWnVuZWhtZW5kZXIgSGFsYm1vbmQnLFxuLy8gICAgICdHaWJiZXVzZSBjcm9pc3NhbnRlJywgJ1RyZcSHYSBvc21pbmEnXSxcbi8vICAgJ2Z1bGwnOiBbJ0Z1bGwnLCAnTHVuYSBwaWVuYScsICdWb2xsZWRpZycsICdDb21wbGV0bycsICdWb2xsbW9uZCcsXG4vLyAgICAgJ1BsZWluZSBsdW5lJywgJ1B1biBtZXNlYyddLFxuLy8gICAnd2FuaW5nX2dpYmJvdXMnOiBbJ1dhbmluZyBHaWJib3VzJywgJ0dpYmJvc2EgY2FsYW50ZScsICdad2VtbWVuZGUgR2liYm91cycsICdXYW5pbmcgR2liYm91cycsICdBYm5laG1lbmRlciBIYWxibW9uZCcsXG4vLyAgICAgJ0dpYmJldXNlIGTDqWNyb2lzc2FudGUnLCAnUGV0YSBvc21pbmEnXSxcbi8vICAgJ3RoaXJkX3F1YXJ0ZXInOiBbJ1RoaXJkIFF1YXJ0ZXInLCAnVWx0aW1vIHF1YXJ0bycsICdEZXJkZSBLd2FydGllcicsICdUZXJjZXIgY3VhcnRvJywgJ0RyaXR0ZXMgVmllcnRlbCcsXG4vLyAgICAgJ0Rlcm5pZXIgcXVhcnRpZXInLCAnVHJlxIdhIMSNZXR2cnRpbmEnXSxcbi8vICAgJ2xhc3RfcXVhcnRlcic6IFsnTGFzdCBRdWFydGVyJywgJ1VsdGltbyBxdWFydG8nLCAnTGFhdHN0ZSBLd2FydGllcicsICfDmmx0aW1vIGN1YXJ0bycsICdMZXR6dGVzIFZpZXJ0ZWwnLFxuLy8gICAgICdEZXJuaWVyIHF1YXJ0aWVyJywgJ1phZG5qYSDEjWV0dnJ0aW5hJ10sXG4vLyAgICd3YW5pbmdfY3Jlc2NlbnQnOiBbJ1dhbmluZyBDcmVzY2VudCcsICdMdW5hIGNhbGFudGUnLCAnWndlbW1lbmRlIHNpa2tlbCcsICdXYW5pbmcgQ3Jlc2NlbnQnLCAnQWJuZWhtZW5kZSBTaWNoZWwnLFxuLy8gICAgICdMdW5lIGTDqWNyb2lzc2FudGUnLCAnU2VkbWEgb3NtaW5hJ10sXG4vLyB9IDtcblxuLy8g8J+MkSDwn4ySIPCfjJMg8J+MlCDwn4yVIPCfjJYg8J+MlyDwn4yYIPCfjJFcbmV4cG9ydCBjb25zdCBjd2NNb29uUGhhc2VJY29ucyA9IHtcbiAgbmV3X21vb246ICfwn4yRJyxcbiAgbmV3OiAn8J+MkScsXG4gIHdheGluZ19jcmVzY2VudDogJ/CfjJInLFxuICBmaXJzdF9xdWFydGVyOiAn8J+MkycsXG4gIHdheGluZ19naWJib3VzOiAn8J+MlCcsXG4gIGZ1bGw6ICfwn4yVJyxcbiAgZnVsbF9tb29uOiAn8J+MlScsXG4gIHdhbmluZ19naWJib3VzOiAn8J+MlicsXG4gIHRoaXJkX3F1YXJ0ZXI6ICfwn4yXJyxcbiAgbGFzdF9xdWFydGVyOiAn8J+MlycsXG4gIHdhbmluZ19jcmVzY2VudDogJ/CfjJgnLFxufTtcbiIsImltcG9ydCB7IGNzcyB9IGZyb20gJ2xpdCc7XG5cbmNvbnN0IGNhcmRTdHlsZSA9IGNzc2BcbiAgaGEtY2FyZCB7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICB3aWR0aDogMTAwJTtcbiAgfVxuXG4gIC5oYS1jYXJkLXdlYXRoZXItY29uZGl0aW9ucyB7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1jYXJkLWJhY2tncm91bmQtY29sb3IsICMxYzFjMWMpO1xuICAgIGNvbG9yOiB2YXIoLS1wcmltYXJ5LXRleHQtY29sb3IsICNmZmZmZmYpO1xuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLWhhLWNhcmQtYm9yZGVyLXJhZGl1cywgMTJweCk7XG4gICAgYm94LXNoYWRvdzogdmFyKC0taGEtY2FyZC1ib3gtc2hhZG93LCAwIDJweCA2cHggcmdiYSgwLCAwLCAwLCAwLjIpKTtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIHBhZGRpbmc6IDA7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICB9XG5cbiAgLm5kLWNvbnRhaW5lciB7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgcGFkZGluZzogMTZweCAyMHB4OyAvKiDihpAgcGFkZGluZyBvcml6em9udGFsZSBwacO5IGFtcGlvICovXG4gICAgZ2FwOiAxMnB4O1xuICAgIGJhY2tncm91bmQtc2l6ZTogY292ZXI7XG4gICAgYmFja2dyb3VuZC1wb3NpdGlvbjogY2VudGVyO1xuICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQtaW1hZ2UgMC4zcyBlYXNlLWluLW91dDtcbiAgfVxuXG4gIC8qIEVzZW1waW8gZGkgc3RpbGUgZGluYW1pY28gYWdnaXVudGl2byBzZSBoYWJnSW1hZ2Ugw6ggdW5hIGNsYXNzZSAqL1xuICAubmQtY29udGFpbmVyLnN1bm55IHtcbiAgICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoJy9sb2NhbC9pbWFnZXMvc3VubnktYmcuanBnJyk7XG4gIH1cblxuICAubmQtY29udGFpbmVyLnJhaW55IHtcbiAgICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoJy9sb2NhbC9pbWFnZXMvcmFpbnktYmcuanBnJyk7XG4gIH1cblxuICAvKiAtLS0tLS0tLS0tLS0tLSAqL1xuXG5gO1xuXG5leHBvcnQgZGVmYXVsdCBjYXJkU3R5bGU7XG4iLCJpbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuXG5jb25zdCBzdW1tYXJ5U3R5bGUgPSBjc3NgXG5cbi5zdW1tYXJ5LWdyaWQtY29udGFpbmVyIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB6LWluZGV4OiAxO1xuICBkaXNwbGF5OiBncmlkO1xuICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDFmciAxZnIgMWZyOyAvKiA8LS0gMyBjb2xvbm5lIHJlYWxpICovXG4gIGdyaWQtdGVtcGxhdGUtcm93czogYXV0byBhdXRvO1xuICB3aWR0aDogMTAwJTtcbiAgbWF4LXdpZHRoOiA2MDBweDtcbiAgLy8gYmFja2dyb3VuZDogIzFjMWMxYztcbiAgLy8gY29sb3I6IHdoaXRlO1xuICBnYXA6IDRweDtcbiAgcGFkZGluZzogMHB4O1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAvLyBib3JkZXI6IDFweCBzb2xpZCAjNDQ0OyAvKiBkZWJ1ZyAqL1xufVxuXG4uc3VtbWFyeS1jb2wtbGVmdCB7XG4gIGdyaWQtY29sdW1uOiAxO1xuICBncmlkLXJvdzogMSAvIHNwYW4gMjtcbiAgLy8gYmFja2dyb3VuZDogIzJjMmMyYztcbiAgcGFkZGluZy10b3A6IDBweDtcbiAgcGFkZGluZy1yaWdodDogMHB4O1xuICBwYWRkaW5nLWJvdHRvbTogMHB4O1xuICBwYWRkaW5nLWxlZnQ6IDBweDtcbiAgXG4gIGRpc3BsYXk6IGZsZXg7ICAgICAgICAgICAgICAgICAvKiBBdHRpdmEgRmxleGJveCAqL1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgICAgICAvKiBDZW50cmEgb3JpenpvbnRhbG1lbnRlICovXG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7ICAgICAgICAgIC8qIENlbnRyYSB2ZXJ0aWNhbG1lbnRlICovXG5cbiAgd2lkdGg6IDEwMCU7XG4gIG1heC13aWR0aDogMTAwJTtcbiAgYXNwZWN0LXJhdGlvOiAxIC8gMTsgLyogb3B6aW9uYWxlOiBtYW50aWVuZSBmb3JtYSBxdWFkcmF0YSAqL1xuICBvdmVyZmxvdzogaGlkZGVuO1xufVxuXG4uc3VtbWFyeS10b3AtcmlnaHQge1xuICBncmlkLWNvbHVtbjogMiAvIHNwYW4gMjsgLyogb2NjdXBhIGNvbG9ubmUgMiBlIDMgKi9cbiAgZ3JpZC1yb3c6IDE7XG4gIC8vIGJhY2tncm91bmQ6ICMzYzNjM2M7XG4gIHBhZGRpbmctdG9wOiAwcHg7XG4gIHBhZGRpbmctcmlnaHQ6IDhweDtcbiAgcGFkZGluZy1ib3R0b206IDBweDtcbiAgcGFkZGluZy1sZWZ0OiA4cHg7XG4gIGRpc3BsYXk6IGZsZXg7ICAgICAgICAgICAgLyogYWdnaXVudG8gKi9cbiAgYWxpZ24taXRlbXM6IGNlbnRlcjsgICAgICAvKiBjZW50cmEgdmVydGljYWxtZW50ZSAqL1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtc3RhcnQ7IC8qIGFsbGluZWEgYSBzaW5pc3RyYSAqL1xufVxuXG4uc3VtbWFyeS1ib3R0b20tcmlnaHQtbGVmdCB7XG4gIGdyaWQtY29sdW1uOiAyO1xuICBncmlkLXJvdzogMjtcbiAgLy8gYmFja2dyb3VuZDogIzRjNGM0YztcbiAgcGFkZGluZy10b3A6IDBweDtcbiAgcGFkZGluZy1yaWdodDogOHB4O1xuICBwYWRkaW5nLWJvdHRvbTogMHB4O1xuICBwYWRkaW5nLWxlZnQ6IDhweDtcblxuICBkaXNwbGF5OiBmbGV4OyAgICAgICAgICAgICAgICAgLyogQXR0aXZhIEZsZXhib3ggKi9cbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7ICAgICAgLyogQ2VudHJhIG9yaXp6b250YWxtZW50ZSAqL1xuICBhbGlnbi1pdGVtczogY2VudGVyOyAgICAgICAgICAvKiBDZW50cmEgdmVydGljYWxtZW50ZSAqL1xufVxuXG4uc3VtbWFyeS1ib3R0b20tcmlnaHQtcmlnaHQge1xuICBncmlkLWNvbHVtbjogMztcbiAgZ3JpZC1yb3c6IDI7XG4gIC8vIGJhY2tncm91bmQ6ICM1YzVjNWM7XG4gIHBhZGRpbmctdG9wOiAwcHg7XG4gIHBhZGRpbmctcmlnaHQ6IDhweDtcbiAgcGFkZGluZy1ib3R0b206IDBweDtcbiAgcGFkZGluZy1sZWZ0OiA4cHg7XG59XG5cbi53ZWF0aGVyLWNvbmRpdGlvbi1pY29uIHtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogYXV0bztcbiAgbWF4LXdpZHRoOiAxMDAlO1xuICBtYXgtaGVpZ2h0OiAxMDAlO1xuICBvYmplY3QtZml0OiBjb250YWluO1xuICAvLyBtYXgtd2lkdGg6IDEwMCU7XG4gIC8vIG1heC1oZWlnaHQ6IDEwMCU7XG4gIC8vIHdpZHRoOiA3MnB4O1xuICAvLyBoZWlnaHQ6IDcycHg7XG4gIC8vIG9iamVjdC1maXQ6IGNvbnRhaW47XG5cbiAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuMnMgZWFzZTtcbn1cbiAgXG4uc3VtbWFyeS1jb2wtbGVmdDpob3ZlciAud2VhdGhlci1jb25kaXRpb24taWNvbiB7XG4gIHRyYW5zZm9ybTogc2NhbGUoMS4wNSk7XG59XG5cbi53ZWF0aGVyLWNpdHktbmFtZSB7XG4gIGZvbnQtc2l6ZTogY2xhbXAoMWVtLCAydncsIDEuMmVtKTtcbiAgdGV4dC1hbGlnbjogbGVmdDtcbn1cblxuLm1vb24tcm93IHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiA2cHg7XG4gIC8vIGZvbnQtc2l6ZTogMC45NWVtO1xuICAvLyBjb2xvcjogI2VlZWVlZTtcbn1cblxuLnN1bW1hcnktbW9vbi1pY29uIHtcbiAgZm9udC1zaXplOiAxLjhlbTtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xufVxuXG4udGVtcGVyYXR1cmUtYmxvY2sge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBhbGlnbi1pdGVtczogZmxleC1lbmQ7XG4gIHRleHQtYWxpZ246IHJpZ2h0O1xufVxuXG4udGVtcGVyYXR1cmUge1xuICBmb250LXNpemU6IDEuNmVtO1xuICBmb250LXdlaWdodDogYm9sZDtcbn1cblxuLnRlbXAtdW5pdCB7XG4gIGZvbnQtc2l6ZTogMC45NWVtO1xuICB2ZXJ0aWNhbC1hbGlnbjogc3VwZXI7XG4gIG1hcmdpbi1sZWZ0OiAycHg7XG59XG5cbi5mZWVscy1saWtlIHtcbiAgZm9udC1zaXplOiAwLjg1ZW07XG4gIC8vIGNvbG9yOiAjYWFhYWFhO1xufVxuXG4uc3VtbWFyeS13cmFwcGVyIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xuICBtaW4taGVpZ2h0OiAxMDBweDsgLyogb3BwdXJlIGNsYW1wKCkgZGluYW1pY28gKi9cbiAgb3ZlcmZsb3c6IHZpc2libGU7XG59XG5cbi5saWdodG5pbmctYmFja2dyb3VuZCB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgaW5zZXQ6IDA7IC8qIHRvcDogMDsgcmlnaHQ6IDA7IGJvdHRvbTogMDsgbGVmdDogMCAqL1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgei1pbmRleDogMDtcbn1cblxuLmxpZ2h0bmluZy1mbGFzaCB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgd2lkdGg6IDJweDtcbiAgYmFja2dyb3VuZDogd2hpdGU7XG4gIG9wYWNpdHk6IDAuNztcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XG4gIGFuaW1hdGlvbi1uYW1lOiBmbGFzaC1ibGluaztcbiAgYW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjogZWFzZS1pbi1vdXQ7XG4gIGFuaW1hdGlvbi1pdGVyYXRpb24tY291bnQ6IGluZmluaXRlO1xuICBib3JkZXItcmFkaXVzOiAxcHg7XG4gIGZpbHRlcjogYmx1cigwLjVweCk7XG4gIGJveC1zaGFkb3c6IDAgMCA0cHggcmdiYSgyNTUsMjU1LDI1NSwwLjYpO1xuXG4gIHotaW5kZXg6IDA7XG59XG5cbkBrZXlmcmFtZXMgZmxhc2gtYmxpbmsge1xuICAwJSwgMTAwJSB7XG4gICAgb3BhY2l0eTogMC4xO1xuICB9XG4gIDUwJSB7XG4gICAgb3BhY2l0eTogMC45O1xuICB9XG59XG5cbi5saWdodG5pbmctZmxhc2gtemlnemFnIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB3aWR0aDogMnB4O1xuICBoZWlnaHQ6IDA7XG4gIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCh0byBib3R0b20sIHllbGxvdywgd2hpdGUpO1xuICBjbGlwLXBhdGg6IHBvbHlnb24odmFyKC0tcG9pbnRzKSk7XG4gIGFuaW1hdGlvbjogZmxhc2gtemlnemFnIGxpbmVhciBmb3J3YXJkcztcbiAgei1pbmRleDogMztcbn1cblxuQGtleWZyYW1lcyBmbGFzaC16aWd6YWcge1xuICAwJSB7XG4gICAgb3BhY2l0eTogMTtcbiAgICB0cmFuc2Zvcm06IHNjYWxlWSgxKTtcbiAgfVxuICAxMDAlIHtcbiAgICBvcGFjaXR5OiAwO1xuICAgIHRyYW5zZm9ybTogc2NhbGVZKDEuMik7XG4gIH1cbn1cblxuLmxpZ2h0bmluZy1zdmcge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIDApO1xuICBvcGFjaXR5OiAwO1xuICBmaWx0ZXI6IGRyb3Atc2hhZG93KDAgMCA0cHggcmdiYSg5OCwgNjEsIDE3MywgMC42KSk7XG4gIGFuaW1hdGlvbi1uYW1lOiBmbGFzaC16aWd6YWctc3ZnO1xuICBhbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOiBlYXNlLWluLW91dDtcbiAgYW5pbWF0aW9uLWl0ZXJhdGlvbi1jb3VudDogMTtcbiAgei1pbmRleDogMztcbn1cblxuQGtleWZyYW1lcyBmbGFzaC16aWd6YWctc3ZnIHtcbiAgMCUsIDEwMCUge1xuICAgIG9wYWNpdHk6IDA7XG4gIH1cbiAgNDAlIHtcbiAgICBvcGFjaXR5OiAxO1xuICB9XG4gIDYwJSB7XG4gICAgb3BhY2l0eTogMC41O1xuICB9XG59XG5gO1xuXG5leHBvcnQgZGVmYXVsdCBzdW1tYXJ5U3R5bGU7XG4iLCJpbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuXG5jb25zdCBwcmVzZW50U3R5bGUgPSBjc3NgXG4ucHJlc2VudC1ncmlkLWNvbnRhaW5lciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogNHB4O1xufVxuXG4ucHJlc2VudC1yb3cge1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gIGdhcDogMTZweDtcbn1cblxuLnByZXNlbnQtbGVmdCxcbi5wcmVzZW50LXJpZ2h0IHtcbiAgZmxleDogMTtcbn1cblxuLnByZXNlbnQtbGVmdCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogZmxleC1zdGFydDtcbn1cblxuLnByZXNlbnQtcmlnaHQge1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xufVxuXG4ucHJlc2VudC12YWx1ZS1ibG9jayB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogNHB4O1xufVxuXG4ucHJlc2VudC11bml0IHtcbiAgZm9udC1zaXplOiAwLjllbTtcbiAgb3BhY2l0eTogMC44O1xufVxuYDtcblxuZXhwb3J0IGRlZmF1bHQgcHJlc2VudFN0eWxlO1xuIiwiaW1wb3J0IHsgY3NzIH0gZnJvbSAnbGl0JztcblxuY29uc3QgdWx0cmF2aW9sZXRTdHlsZSA9IGNzc2Bcbi51bHRyYXZpb2xldC1ncmlkLWNvbnRhaW5lciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogNHB4O1xufVxuXG4udWx0cmF2aW9sZXQtcm93IHtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBnYXA6IDE2cHg7XG59XG5cbi51bHRyYXZpb2xldC1sZWZ0LFxuLnByZXNlbnQtcmlnaHQge1xuICBmbGV4OiAxO1xufVxuXG4udWx0cmF2aW9sZXQtbGVmdCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogZmxleC1zdGFydDtcbn1cblxuLnVsdHJhdmlvbGV0LXJpZ2h0IHtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDtcbn1cblxuLnVsdHJhdmlvbGV0LXZhbHVlLWJsb2NrIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiA0cHg7XG59XG5cbi51bHRyYXZpb2xldC11bml0IHtcbiAgZm9udC1zaXplOiAwLjllbTtcbiAgb3BhY2l0eTogMC44O1xufVxuXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gLnVsdHJhdmlvbGV0LWdyaWQtY29udGFpbmVyIHtcbi8vICAgZGlzcGxheTogZmxleDtcbi8vICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbi8vICAgZ2FwOiAxMnB4O1xuLy8gfVxuXG4vLyAudWx0cmF2aW9sZXQtcm93IHtcbi8vICAgZGlzcGxheTogZmxleDtcbi8vICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuLy8gICBwYWRkaW5nOiA0cHggMDtcbi8vIH1cblxuLy8gLnVsdHJhdmlvbGV0LXZhbHVlLWJsb2NrIHtcbi8vICAgZGlzcGxheTogZmxleDtcbi8vICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbi8vICAgZ2FwOiA0cHg7XG4vLyB9XG5cbi8vIC51bHRyYXZpb2xldC11bml0IHtcbi8vICAgZm9udC1zaXplOiAwLjllbTtcbi8vICAgb3BhY2l0eTogMC43O1xuLy8gfVxuXG4udWx0cmF2aW9sZXQtc2tpbi10eXBlLWdyaWQge1xuICBkaXNwbGF5OiBncmlkO1xuICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IHJlcGVhdChhdXRvLWZpdCwgbWlubWF4KDQ4cHgsIDFmcikpO1xuICBnYXA6IDhweDtcbiAgbWFyZ2luLXRvcDogOHB4O1xufVxuXG4udWx0cmF2aW9sZXQtc2tpbi10eXBlLWNlbGwge1xuICBmbGV4OiAxO1xuICBtaW4td2lkdGg6IDQ4cHg7XG4gIGhlaWdodDogNDhweDtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgZm9udC1mYW1pbHk6ICdTZWdvZSBVSScsIHNhbnMtc2VyaWY7XG4gIGJveC1zaGFkb3c6IDAgMXB4IDNweCByZ2JhKDAsIDAsIDAsIDAuMik7XG4gIGNvbG9yOiBibGFjaztcbn1cblxuLnVsdHJhdmlvbGV0LXNraW4tdHlwZS1sYWJlbCB7XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xuICBmb250LXNpemU6IDAuOTVlbTtcbiAgbGluZS1oZWlnaHQ6IDFlbTtcbn1cblxuLnVsdHJhdmlvbGV0LWV4cG9zdXJlLXRpbWUge1xuICBmb250LXNpemU6IDAuNzVlbTtcbiAgbWFyZ2luLXRvcDogMnB4O1xuICBjb2xvcjogIzIyMjtcbiAgb3BhY2l0eTogMC44NTtcbn1cblxuXG5cblxuXG5cbmA7XG5cbmV4cG9ydCBkZWZhdWx0IHVsdHJhdmlvbGV0U3R5bGU7XG4iLCJpbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuXG5jb25zdCBwb2xsZW5TdHlsZSA9IGNzc2Bcbi5wb2xsZW4tZ3JpZC1jb250YWluZXIge1xuICBkaXNwbGF5OiBncmlkO1xuICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IHJlcGVhdChhdXRvLWZpdCwgbWlubWF4KDQ4cHgsIDFmcikpO1xuICBnYXA6IDhweCAxMnB4O1xuICB3aWR0aDogMTAwJTtcbiAganVzdGlmeS1pdGVtczogY2VudGVyO1xuICBhbGlnbi1pdGVtczogZW5kO1xuICBwYWRkaW5nOiA4cHggNHB4O1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xufVxuXG5cbi5wb2xsZW4tc3RhY2sge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDRweDtcbiAgbWluLXdpZHRoOiA0OHB4O1xufVxuXG5cbiAgLmxldmVscyB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uLXJldmVyc2U7XG4gICAgZ2FwOiBjbGFtcCgxcHgsIDAuMnZ3LCAycHgpO1xuICB9XG5cbiAgLmxldmVsIHtcbiAgICB3aWR0aDogY2xhbXAoMTZweCwgMy41dncsIDI0cHgpO1xuICAgIGhlaWdodDogY2xhbXAoNXB4LCAwLjd2dywgOHB4KTsgICAgIC8qIPCfkYggYW5jaGUgaW4gYWx0ZXp6YSAqL1xuICAgIGJvcmRlci1yYWRpdXM6IDNweDtcbiAgICBvcGFjaXR5OiAwLjM7XG4gICAgdHJhbnNpdGlvbjogb3BhY2l0eSAwLjJzIGVhc2U7XG4gIH1cblxuICAubGV2ZWwuYWN0aXZlIHtcbiAgICBvcGFjaXR5OiAxO1xuICAgIG91dGxpbmU6IDFweCBzb2xpZCAjMzMzO1xuICB9XG5cbiAgLm1vbHRvLWFsdG8ge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICNmNDQzMzY7XG4gIH1cblxuICAuYWx0byB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2ZmOTgwMDtcbiAgfVxuXG4gIC5tb2RlcmF0byB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZWIzYjtcbiAgfVxuXG4gIC5iYXNzbyB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogIzRjYWY1MDtcbiAgfVxuXG4gIC5wb2xsZW4tbmFtZSB7XG4gICAgZm9udC1zaXplOiBjbGFtcCgwLjU1ZW0sIDEuM3Z3LCAwLjg1ZW0pOyAvKiDwn5GIIHN0cmluZ2UgZGkgcGnDuSAqL1xuICAgIC8vIGZvbnQtd2VpZ2h0OiA1MDA7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIC8vIGNvbG9yOiAjMzMzO1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIH1cblxuICAubGFiZWwge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICBmb250LXNpemU6IGNsYW1wKDAuNTVlbSwgMS4zdncsIDAuODVlbSk7XG4gICAgLy8gZm9udC13ZWlnaHQ6IDUwMDtcbiAgICBtYXJnaW4tdG9wOiBjbGFtcCg0cHgsIDAuNXZ3LCA4cHgpO1xuICB9XG5gO1xuXG5leHBvcnQgZGVmYXVsdCBwb2xsZW5TdHlsZTtcbiIsImltcG9ydCB7IGNzcyB9IGZyb20gJ2xpdCc7XG5cbmNvbnN0IGNhbWVyYVN0eWxlID0gY3NzYFxuICAuY2FtZXJhLWNvbnRhaW5lciB7XG4gICAgbWFyZ2luLXRvcDogMTBweDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBzdHJldGNoO1xuICB9XG5cbiAgLmNhbWVyYS1pbWFnZSB7XG4gICAgYXNwZWN0LXJhdGlvOiAxNiAvIDk7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICB9XG5cbiAgLmNhbWVyYS1pbWFnZSA+IGltZyB7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIG9iamVjdC1maXQ6IGNvdmVyO1xuICB9XG5gO1xuXG5leHBvcnQgZGVmYXVsdCBjYW1lcmFTdHlsZTtcbiIsImltcG9ydCB7IGNzcyB9IGZyb20gJ2xpdCc7XG5cbmNvbnN0IHdlYXRoZXJGb3JlY2FzdFN0eWxlID0gY3NzYFxuXG4ud2VhdGhlci1mb3JlY2FzdC1ncmlkLWNvbnRhaW5lciB7XG4gIGRpc3BsYXk6IGdyaWQ7XG4gIGdyaWQtdGVtcGxhdGUtY29sdW1uczogcmVwZWF0KGF1dG8tZml0LCBtaW5tYXgoNzhweCwgMWZyKSk7XG4gIGNvbHVtbi1nYXA6IDJweDsgLyogc3BhemlvIG9yaXp6b250YWxlIHRyYSBpIGdpb3JuaSAqL1xuICByb3ctZ2FwOiA2cHg7ICAgIC8qIHNwYXppbyB2ZXJ0aWNhbGUgdHJhIHJpZ2hlLCBzZSBjaSBzb25vICovXG4gIGFsaWduLWl0ZW1zOiBzdHJldGNoO1xuICBmb250LWZhbWlseTogJ1NlZ29lIFVJJywgc2Fucy1zZXJpZjtcbiAgd2lkdGg6IDEwMCU7XG59XG4gIFxuLndlYXRoZXItZm9yZWNhc3QtZ3JpZC13cmFwcGVyIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjsgLyogY2VudHJhcmUgaWwgdGl0b2xvIG9yaXp6b250YWxtZW50ZSAqL1xufVxuXG4ud2VhdGhlci1mb3JlY2FzdC10aXRsZSB7XG4gIGZvbnQtc2l6ZTogY2xhbXAoMC44NWVtLCAxdncsIDAuOTVlbSk7XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xuICAvLyBtYXJnaW4tYm90dG9tOiAwLjVlbTtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xufVxuXG4ud2VhdGhlci1mb3JlY2FzdC1zbG90IHtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBwYWRkaW5nOiA4cHggNHB4O1xuICBtaW4td2lkdGg6IDA7XG4gIG92ZXJmbG93OiBoaWRkZW47XG59XG5cbi53ZWF0aGVyLWZvcmVjYXN0LXNsb3Q6bGFzdC1jaGlsZCB7XG4gIGJvcmRlci1yaWdodDogbm9uZTtcbn1cblxuLndlYXRoZXItZm9yZWNhc3QtbGFiZWwtc2xvdCB7XG4gIGZvbnQtc2l6ZTogMC45ZW07XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xuICBtYXJnaW4tYm90dG9tOiA2cHg7IC8qIHJpZG90dG8gKi9cbn1cblxuLndlYXRoZXItZm9yZWNhc3QtaWNvbiB7XG4gIGZvbnQtc2l6ZTogMS42cmVtOyAvKiByaWRvdHRvICovXG4gIC8qIG1hcmdpbjogNnB4IDA7IHJpZG90dG8gKi9cbiAgaGVpZ2h0OiAzMnB4O1xufVxuXG4ud2VhdGhlci1mb3JlY2FzdC10ZW1wZXJhdHVyZSB7XG4gIGZvbnQtc2l6ZTogY2xhbXAoMC44ZW0sIDF2dywgMC45ZW0pOyAvKiBsZWdnZXJtZW50ZSBwacO5IHBpY2NvbG8gKi9cbiAgbWFyZ2luOiA0cHggMDsgLyogbWVubyBtYXJnaW5lICovXG59XG5cbi53ZWF0aGVyLWZvcmVjYXN0LXRlbXBlcmF0dXJlIC5oaWdoIHtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XG59XG5cbi53ZWF0aGVyLWZvcmVjYXN0LXByZWNpcGl0YXRpb24ge1xuICBmb250LXNpemU6IGNsYW1wKDAuNjVlbSwgMXZ3LCAwLjc1ZW0pO1xuICBsaW5lLWhlaWdodDogMS4yOyAvKiBjb21wYXR0YSB2ZXJ0aWNhbG1lbnRlICovXG59XG5cbi53ZWF0aGVyLWZvcmVjYXN0LXByZWNpcGl0YXRpb24gLm1tIHtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XG59XG5gO1xuXG5leHBvcnQgZGVmYXVsdCB3ZWF0aGVyRm9yZWNhc3RTdHlsZTtcbiIsImltcG9ydCB7IGNzcyB9IGZyb20gJ2xpdCc7XG5cbmNvbnN0IG1ldGVvZGNwYWxhcm1TdHlsZSA9IGNzc2Bcbi5tZXRlb2RjcGFsYXJtLWdyaWQtY29udGFpbmVyIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC13cmFwOiB3cmFwO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgZ2FwOiAxNnB4O1xuICBwYWRkaW5nOiAxMnB4O1xufVxuXG4ubWV0ZW9kY3BhbGFybS1ncm91cCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGZsZXg6IDEgMSA3MnB4OyAgICAgLyog8J+RiCBjcmVzY2UsIG1hIG5vbiBzY2VuZGUgc290dG8gaSA3MnB4ICovXG4gIG1heC13aWR0aDogMjIwcHg7ICAgLyog8J+RiCBvcHppb25hbGU6IHByZXZpZW5lIGFsbGFyZ2FtZW50byBlY2Nlc3Npdm8gKi9cbiAgdGV4dC1hbGlnbjogY2VudGVyO1xufVxuXG4ubWV0ZW9kY3BhbGFybS1ncm91cCBoYS1pY29uIHtcbiAgLS1tZGMtaWNvbi1zaXplOiAzNnB4O1xufVxuXG4ubWV0ZW9kY3BhbGFybS1sYWJlbCB7XG4gIG1hcmdpbi10b3A6IDZweDtcbiAgZm9udC1zaXplOiAwLjg1ZW07XG4gIGNvbG9yOiB2YXIoLS1wcmltYXJ5LXRleHQtY29sb3IpO1xufVxuXG5cbmA7XG5cbmV4cG9ydCBkZWZhdWx0IG1ldGVvZGNwYWxhcm1TdHlsZTtcbiIsImltcG9ydCB7IGNzcyB9IGZyb20gJ2xpdCc7XG4vLyBpbXBvcnQgeyBIb21lQXNzaXN0YW50IH0gZnJvbSAnY3VzdG9tLWNhcmQtaGVscGVycy9kaXN0JztcblxuaW1wb3J0IHsgY3djTW9vblBoYXNlSWNvbnMgfSBmcm9tICcuLi8uLi9iYWNrdXAvaGEtY3djLWNvbnN0cyc7XG5cbmltcG9ydCBjYXJkU3R5bGUgZnJvbSAnLi4vY3NzL2Nzcy1iYXNlLWNhcmQnO1xuaW1wb3J0IHN1bW1hcnlTdHlsZXMgZnJvbSAnLi4vY3NzL2Nzcy1zdW1tYXJ5JztcbmltcG9ydCBwcmVzZW50U3R5bGUgZnJvbSAnLi4vY3NzL2Nzcy1wcmVzZW50JztcbmltcG9ydCB1bHRyYXZpb2xldFN0eWxlIGZyb20gJy4uL2Nzcy9jc3MtdWx0cmF2aW9sZXQnO1xuaW1wb3J0IHBvbGxlblN0eWxlIGZyb20gJy4uL2Nzcy9jc3MtcG9sbGVuJztcbmltcG9ydCBjYW1lcmFTdHlsZSBmcm9tICcuLi9jc3MvY3NzLWNhbWVyYSc7XG5pbXBvcnQgeyBpSWNvbnNDb25maWcgfSBmcm9tICcuLi9iYXNlL2xvdmVsYWNlLWJhc2UnO1xuaW1wb3J0IHdlYXRoZXJGb3JlY2FzdFN0eWxlIGZyb20gJy4uL2Nzcy9jc3Mtd2VhdGhlci1mb3JlY2FzdCc7XG5pbXBvcnQgbWV0ZW9kY3BhbGFybVN0eWxlIGZyb20gJy4uL2Nzcy9jc3MtbWV0ZW9hbGFybSc7XG5cbmV4cG9ydCBjb25zdCBnZXRNb29uSWNvbiA9IChwaGFzZTogc3RyaW5nKTogc3RyaW5nID0+IGN3Y01vb25QaGFzZUljb25zW3BoYXNlLnRvTG93ZXJDYXNlKCldO1xuXG5leHBvcnQgY29uc3QgZ2V0V2VhdGhlckljb24gPSAoXG4gIGNvbmRpdGlvbjogc3RyaW5nLFxuICBpY29uc0NvbmZpZzogaUljb25zQ29uZmlnLFxuICBzdW5TdGF0ZTogc3RyaW5nLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgaXNOaWdodCA9IHN1blN0YXRlID09PSAnYmVsb3dfaG9yaXpvbic7XG4gIGNvbnN0IGljb25NYXAgPSBpc05pZ2h0ID8gaWNvbnNDb25maWcuaWNvbnNOaWdodCA6IGljb25zQ29uZmlnLmljb25zRGF5O1xuICBjb25zdCBpY29uTmFtZSA9IGljb25NYXBbY29uZGl0aW9uXTtcblxuICBpZiAoIWljb25zQ29uZmlnLnBhdGgpIHtcbiAgICBjb25zb2xlLmluZm8oJ0ltYWdlIHBhdGggbm90IGZvdW5kLicpO1xuICB9XG5cbiAgaWYgKCFpY29uTmFtZSkge1xuICAgIGNvbnNvbGUuaW5mbyhcbiAgICAgIGBJY29ucyBpc3N1ZS4gTW9kZWw9JHtpY29uc0NvbmZpZy5pY29uc19tb2RlbH0sIFRpbWU9JHtpc05pZ2h0ID8gJ25pZ2h0JyA6ICdkYXknfSwgQ29uZGl0aW9uPSR7Y29uZGl0aW9ufWAsXG4gICAgKTtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICByZXR1cm4gYCR7aWNvbnNDb25maWcucGF0aH0vJHtpY29uc0NvbmZpZy5pY29uVHlwZX0vJHtpY29uTmFtZX0uc3ZnYDtcbn07XG5cbi8vIGV4cG9ydCBjb25zdCBnZXRTZW5zb3JVbml0ID0gKGhhc3M6IEhvbWVBc3Npc3RhbnQsIG1lYXN1cmU6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4vLyAgIGNvbnN0IGxlbmd0aFVuaXQgPSBoYXNzLmNvbmZpZy51bml0X3N5c3RlbS5sZW5ndGg7XG5cbi8vICAgY29uc3QgdW5pdE92ZXJyaWRlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbi8vICAgICBhaXJfcHJlc3N1cmU6IGxlbmd0aFVuaXQgPT09ICdrbScgPyAnaFBhJyA6ICdpbkhnJyxcbi8vICAgICBwcmVjaXBpdGF0aW9uOiBsZW5ndGhVbml0ID09PSAna20nID8gJ21tJyA6ICdpbicsXG4vLyAgICAgbGVuZ3RoOiBsZW5ndGhVbml0LFxuLy8gICB9O1xuXG4vLyAgIGlmIChtZWFzdXJlIGluIHVuaXRPdmVycmlkZXMpIHtcbi8vICAgICByZXR1cm4gdW5pdE92ZXJyaWRlc1ttZWFzdXJlXTtcbi8vICAgfVxuXG4vLyAgIGNvbnN0IHVuaXQgPSAoaGFzcy5jb25maWcudW5pdF9zeXN0ZW0gYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPilbbWVhc3VyZV07XG5cbi8vICAgaWYgKHVuaXQgIT09IHVuZGVmaW5lZCkge1xuLy8gICAgIHJldHVybiB1bml0O1xuLy8gICB9XG5cbi8vICAgY29uc29sZS53YXJuKGBVbml0IGZvciAnJHttZWFzdXJlfScgbm90IGZvdW5kIGluIGhhc3MuY29uZmlnLnVuaXRfc3lzdGVtLmApO1xuLy8gICByZXR1cm4gJyc7XG4vLyB9O1xuXG5leHBvcnQgY29uc3QgZ2V0Q2FyZFN0eWxlcyA9ICgpID0+IGNzc2BcbiR7Y2FyZFN0eWxlfVxuJHtzdW1tYXJ5U3R5bGVzfVxuJHtwcmVzZW50U3R5bGV9XG4ke3dlYXRoZXJGb3JlY2FzdFN0eWxlfVxuJHt1bHRyYXZpb2xldFN0eWxlfVxuJHtwb2xsZW5TdHlsZX1cbiR7Y2FtZXJhU3R5bGV9XG4ke21ldGVvZGNwYWxhcm1TdHlsZX1cbmA7XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlcnNjb3JlLWRhbmdsZSAqL1xuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqL1xuaW1wb3J0IHtcbiAgY3NzLFxuICBDU1NSZXN1bHRHcm91cCxcbiAgaHRtbCxcbiAgTGl0RWxlbWVudCxcbiAgUHJvcGVydHlWYWx1ZXMsXG4gIFRlbXBsYXRlUmVzdWx0LFxufSBmcm9tICdsaXQnO1xuaW1wb3J0IHsgcHJvcGVydHkgfSBmcm9tICdsaXQvZGVjb3JhdG9ycy5qcyc7XG5pbXBvcnQgeyBIb21lQXNzaXN0YW50IH0gZnJvbSAnY3VzdG9tLWNhcmQtaGVscGVycyc7XG5cbmltcG9ydCB7IGRlZmF1bHRDb2xvckNzcywgZGVmYXVsdERhcmtDb2xvckNzcyB9IGZyb20gJy4uL3V0aWxzL2NvbG9ycyc7XG5pbXBvcnQgeyBpQ2FyZENvbmZpZywgaUxvdmVsYWNlQ2FyZENvbmZpZyB9IGZyb20gJy4uL3V0aWxzL2NvbmZpZy1zY2hlbWEnO1xuaW1wb3J0IHtcbiAgY3djTG9jYWxlLFxuICBoYWNzSW1hZ2VQYXRoLFxuICBsb2dvLFxuICBtYW5JbWFnZVBhdGgsXG4gIG9wdENvbnNvbGVQYXJhbTEsXG4gIG9wdENvbnNvbGVQYXJhbTIsXG4gIG9wdENvbnNvbGVQYXJhbTMsXG59IGZyb20gJy4uL3V0aWxzL2NvbnN0JztcbmltcG9ydCB7XG4gIGdldEljb25Nb2RlbERhdGEsXG4gIGltYWdlRXhpc3QsXG4gIGxvYWRKU09OLFxuICBsb2dJbmZvLFxufSBmcm9tICcuLi91dGlscy9oZWxwZXInO1xuaW1wb3J0IHsgY3djQ2xpbWFjZWxsRGF5SWNvbnMsIGN3Y0NsaW1hY2VsbE5pZ2h0SWNvbnMgfSBmcm9tICcuLi9pY29ubW9kZWxzL2ltLWNsaW1hY2VsbCc7XG5pbXBvcnQgeyBnZXRDYXJkU3R5bGVzIH0gZnJvbSAnLi4vdXRpbHMvaGVscGVyLXJlbmRlcic7XG5pbXBvcnQgeyBjd2NEYXl0aW1lUGlyYXRlV2VhdGhlckljb25zLCBjd2NOaWdodGx5UGlyYXRlV2VhdGVySWNvbnMgfSBmcm9tICcuLi9pY29ubW9kZWxzL2ltLXBpcmF0ZXdlYXRoZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIGlUZXJtcyB7XG4gICB3aW5kRGlyZWN0aW9uczogc3RyaW5nO1xuICAgd29yZHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgaUljb25zQ29uZmlnIHtcbiAgcGF0aDogc3RyaW5nIDtcbiAgaWNvblR5cGU6IHN0cmluZyA7XG4gIGljb25zX21vZGVsOiBzdHJpbmcgO1xuICBpY29uc0RheTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmc7IH0gO1xuICBpY29uc05pZ2h0OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZzsgfSA7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgaUxvdmVsYWNlQ2FyZCBleHRlbmRzIEhUTUxFbGVtZW50IHtcbiAgaGFzcz86IEhvbWVBc3Npc3RhbnQ7XG4gIGlzUGFuZWw/OiBib29sZWFuO1xuICBlZGl0TW9kZT86IGJvb2xlYW47XG4gIGdldENhcmRTaXplKCk6IG51bWJlciB8IFByb21pc2U8bnVtYmVyPjtcbiAgc2V0Q29uZmlnKGNvbmZpZzogaUxvdmVsYWNlQ2FyZENvbmZpZyk6IHZvaWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlRGFya01vZGUoaGFzcz86IEhvbWVBc3Npc3RhbnQpOiBib29sZWFuIHtcbiAgaWYgKCFoYXNzKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiAoaGFzcy50aGVtZXMgYXMgYW55KS5kYXJrTW9kZSBhcyBib29sZWFuO1xufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLSBWQVJJQUJJTEkgR0xPQkFMSSAtLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuLy8gbGV0IGxvYWRlZFRyYW5zbGF0aW9uczogYW55W10gPSBbXTtcbi8vIGxldCByZXNvbHZlZEltYWdlUGF0aDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcmVsb2FkUmVzb3VyY2VzKCk6IFByb21pc2U8eyB0cmFuc2xhdGlvbnM6IGFueVtdOyBpbWFnZVBhdGg6IHN0cmluZyB8IG51bGwgfT4ge1xuICBjb25zdCBbaGFjc1Jlc3VsdCwgbWFuUmVzdWx0XSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICBpbWFnZUV4aXN0KGAke2hhY3NJbWFnZVBhdGh9L3N0YXRpYy9jbG91ZHkuc3ZnYCksXG4gICAgaW1hZ2VFeGlzdChgJHttYW5JbWFnZVBhdGh9L3N0YXRpYy9jbG91ZHkuc3ZnYCksXG4gIF0pO1xuXG4gIGxldCBpbWFnZVBhdGg6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIGlmIChoYWNzUmVzdWx0KSB7XG4gICAgaW1hZ2VQYXRoID0gaGFjc0ltYWdlUGF0aDtcbiAgfSBlbHNlIGlmIChtYW5SZXN1bHQpIHtcbiAgICBpbWFnZVBhdGggPSBtYW5JbWFnZVBhdGg7XG4gIH0gZWxzZSB7XG4gICAgaW1hZ2VQYXRoID0gbnVsbDtcbiAgfVxuXG4gIGlmICghaW1hZ2VQYXRoKSB7XG4gICAgbG9nSW5mbyhgJHtsb2dvfSAtIEltcG9zc2liaWxlIGRldGVybWluYXJlIGlsIHBhdGggaW1tYWdpbmkuYCk7XG4gICAgcmV0dXJuIHsgdHJhbnNsYXRpb25zOiBbXSwgaW1hZ2VQYXRoOiBudWxsIH07XG4gIH1cblxuICBjb25zdCBsYW5ncyA9IFsnZW4nLCAnaXQnLCAnbmwnLCAnZXMnLCAnZGUnLCAnZnInLCAnc3ItbGF0bicsICdwdCcsICdkYScsICduby1OTycsICdjcyddO1xuICBjb25zdCB0cmFuc2xQYXRoID0gYCR7aW1hZ2VQYXRofS8uLi90cmFuc2wvYDtcbiAgY29uc3QgdHJhbnNsYXRpb25zID0gYXdhaXQgUHJvbWlzZS5hbGwobGFuZ3MubWFwKChsYW5nKSA9PiBsb2FkSlNPTihgJHt0cmFuc2xQYXRofSR7bGFuZ30uanNvbmApKSk7XG5cbiAgcmV0dXJuIHsgdHJhbnNsYXRpb25zLCBpbWFnZVBhdGggfTtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIExvdmVsYWNlQmFzZUVsZW1lbnQgZXh0ZW5kcyBMaXRFbGVtZW50IHtcbiAgQHByb3BlcnR5KHsgYXR0cmlidXRlOiBmYWxzZSB9KSBwdWJsaWMgaGFzcyE6IEhvbWVBc3Npc3RhbnQ7XG5cbiAgQHByb3BlcnR5KHsgYXR0cmlidXRlOiBmYWxzZSB9KSBwcm90ZWN0ZWQgX2NvbmZpZz86IGlDYXJkQ29uZmlnO1xuXG4gIHB1YmxpYyBpc1BhbmVsPzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHB1YmxpYyBlZGl0TW9kZT86IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwdWJsaWMgaW52YWxpZENvbmZpZzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHByb3RlY3RlZCBfaWNvbnNDb25maWc6IGlJY29uc0NvbmZpZztcblxuICBwcm90ZWN0ZWQgX2ltYWdlc1BhdGg6IHN0cmluZztcblxuICBwcm90ZWN0ZWQgX25hbWU6IHN0cmluZztcblxuICBwcm90ZWN0ZWQgX2xhbmd1YWdlOiBzdHJpbmc7XG5cbiAgcHJvdGVjdGVkIF90cmFuc2xhdGlvbnM6IHN0cmluZ1tdO1xuXG4gIHByb3RlY3RlZCBfdGVybXM6IGlUZXJtcztcblxuICBwcm90ZWN0ZWQgX2hhc1ByZXNlbnQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcm90ZWN0ZWQgX2hhc0RhaWx5Rm9yZWNhc3RzOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcHJvdGVjdGVkIF9oYXNIb3VybHlGb3JlY2FzdHM6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcm90ZWN0ZWQgX2hhc01hcmluZURhaWx5Rm9yZWNhc3RzOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcHJvdGVjdGVkIF9oYXNNYXJpbmVIb3VybHlGb3JlY2FzdHM6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcm90ZWN0ZWQgX2hhc01ldGVhbGFybTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHByb3RlY3RlZCBfaGFzRFBDYWxhcm06IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcm90ZWN0ZWQgX2hhc01ldGVvZ3JhbTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHByb3RlY3RlZCBfaGFzQWlyUXVhbGl0eTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHByb3RlY3RlZCBfaGFzUG9sbGVuOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcHJvdGVjdGVkIF9oYXNVbHRyYXZpb2xldDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHByb3RlY3RlZCBfaGFzQWxlcnQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcm90ZWN0ZWQgX2hhc1NlYTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHByb3RlY3RlZCBfaGFzQ2FtZXJhOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcHJvdGVjdGVkIHVwZGF0ZWQoY2hhbmdlZFByb3BzOiBQcm9wZXJ0eVZhbHVlcyk6IHZvaWQge1xuICAgIHN1cGVyLnVwZGF0ZWQoY2hhbmdlZFByb3BzKTtcbiAgICBpZiAoY2hhbmdlZFByb3BzLmhhcygnaGFzcycpICYmIHRoaXMuaGFzcykge1xuICAgICAgY29uc3QgY3VycmVudERhcmtNb2RlID0gY29tcHV0ZURhcmtNb2RlKGNoYW5nZWRQcm9wcy5nZXQoJ2hhc3MnKSk7XG4gICAgICBjb25zdCBuZXdEYXJrTW9kZSA9IGNvbXB1dGVEYXJrTW9kZSh0aGlzLmhhc3MpO1xuICAgICAgaWYgKGN1cnJlbnREYXJrTW9kZSAhPT0gbmV3RGFya01vZGUpIHtcbiAgICAgICAgdGhpcy50b2dnbGVBdHRyaWJ1dGUoJ2RhcmstbW9kZScsIG5ld0RhcmtNb2RlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzdGF0aWMgZ2V0IHN0eWxlcygpOiBDU1NSZXN1bHRHcm91cCB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC8vIGFuaW1hdGlvbnMsXG4gICAgICBjc3NgXG4gICAgICAgIDpob3N0IHtcbiAgICAgICAgICAke2RlZmF1bHRDb2xvckNzc31cbiAgICAgICAgfVxuICAgICAgICA6aG9zdChbZGFyay1tb2RlXSkge1xuICAgICAgICAgICR7ZGVmYXVsdERhcmtDb2xvckNzc31cbiAgICAgICAgfVxuICAgICAgICAke2dldENhcmRTdHlsZXMoKX1cbiAgICAgIGAsXG4gICAgXTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRDb25maWcoY29uZmlnOiBpQ2FyZENvbmZpZykge1xuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRDb25maWcgPSB0cnVlO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvbmZpZ3VyYXRpb24nKTtcbiAgICB9XG5cbiAgICAvLyBjb25zb2xlLmxvZyh7IGNhcmRfY29uZmlnOiBjb25maWcgfSk7XG5cbiAgICBpZiAoIXRoaXMuX3RyYW5zbGF0aW9ucz8ubGVuZ3RoIHx8ICF0aGlzLl9pbWFnZXNQYXRoKSB7XG4gICAgICBjb25zdCB7IHRyYW5zbGF0aW9ucywgaW1hZ2VQYXRoIH0gPSBhd2FpdCBwcmVsb2FkUmVzb3VyY2VzKCk7XG4gICAgICB0aGlzLl90cmFuc2xhdGlvbnMgPSB0cmFuc2xhdGlvbnM7XG4gICAgICB0aGlzLl9pbWFnZXNQYXRoID0gaW1hZ2VQYXRoO1xuICAgIH1cblxuICAgIHRoaXMuX25hbWUgPSBjb25maWc/LndlYXRoZXI/Lm5hbWUgPz8gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2xhbmd1YWdlID0gY29uZmlnLmxhbmd1YWdlPy50b0xvd2VyQ2FzZSgpIHx8ICdlbic7XG5cbiAgICB0aGlzLl9sb2FkVHJhbnNsYXRpb25zKHRoaXMuX2xhbmd1YWdlKTtcbiAgICAvLyB0aGlzLl9pbml0TnVtYmVyRm9ybWF0dGVycyh0aGlzLl9sYW5ndWFnZSk7XG5cbiAgICAvLyB0aGlzLl9zZXR1cERpc3BsYXlTZWN0aW9ucyhjb25maWcuZGlzcGxheSA/PyBbXSk7XG4gICAgdGhpcy5fZGV0ZWN0RGF0YVNlY3Rpb25zKGNvbmZpZyk7XG5cbiAgICB0aGlzLl9zZXR1cEljb25zKGNvbmZpZy53ZWF0aGVyPy5pY29uc19tb2RlbCk7XG4gICAgdGhpcy5fY29uZmlnID0gY29uZmlnO1xuXG4gICAgbG9nSW5mbyhgJHtsb2dvfSAtIENvbmZpZyBsb2FkZWQuYCk7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2xhc3MtbWV0aG9kcy11c2UtdGhpc1xuICBwdWJsaWMgZ2V0Q2FyZFNpemUoKTogbnVtYmVyIHwgUHJvbWlzZTxudW1iZXI+IHtcbiAgICByZXR1cm4gMTtcbiAgfVxuXG4gIHByaXZhdGUgX2xvYWRUcmFuc2xhdGlvbnMobGFuZzogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRyYW5zbHMgPSBKU09OLnBhcnNlKHRoaXMuX3RyYW5zbGF0aW9uc1tjd2NMb2NhbGVbbGFuZ11dKTtcbiAgICAgIHRoaXMuX3Rlcm1zID0ge1xuICAgICAgICB3aW5kRGlyZWN0aW9uczogdHJhbnNscy5jd2NMb2NXaW5kRGlyZWN0aW9ucyxcbiAgICAgICAgd29yZHM6IHRyYW5zbHMuY3djVGVybXMsXG4gICAgICB9O1xuXG4gICAgICBsb2dJbmZvKFxuICAgICAgICBgJHtsb2dvfSVjIGNhcmQgXCIke3RoaXMuX25hbWV9XCIsIGxvY2FsZSBpcyAnJHtsYW5nfScuYCxcbiAgICAgICAgb3B0Q29uc29sZVBhcmFtMSxcbiAgICAgICAgb3B0Q29uc29sZVBhcmFtMixcbiAgICAgICAgb3B0Q29uc29sZVBhcmFtMyxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc3QgZmFsbGJhY2sgPSAnZW4nO1xuICAgICAgY29uc3QgdHJhbnNscyA9IEpTT04ucGFyc2UodGhpcy5fdHJhbnNsYXRpb25zW2N3Y0xvY2FsZVtmYWxsYmFja11dKTtcbiAgICAgIHRoaXMuX3Rlcm1zID0ge1xuICAgICAgICB3aW5kRGlyZWN0aW9uczogdHJhbnNscy5jd2NMb2NXaW5kRGlyZWN0aW9ucyxcbiAgICAgICAgd29yZHM6IHRyYW5zbHMuY3djVGVybXMsXG4gICAgICB9O1xuXG4gICAgICBsb2dJbmZvKFxuICAgICAgICBgJHtsb2dvfSVjIGNhcmQgXCIke3RoaXMuX25hbWV9XCIgdW5hYmxlIHRvIHVzZSAnJHtsYW5nfScgbG9jYWxlLCBzZXQgYXMgZGVmYXVsdCAnJHtmYWxsYmFja30nLmAsXG4gICAgICAgIG9wdENvbnNvbGVQYXJhbTEsXG4gICAgICAgIG9wdENvbnNvbGVQYXJhbTIsXG4gICAgICAgIG9wdENvbnNvbGVQYXJhbTMsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2RldGVjdERhdGFTZWN0aW9ucyhjb25maWc6IGlDYXJkQ29uZmlnKSB7XG4gICAgdGhpcy5faGFzUHJlc2VudCA9ICEhY29uZmlnLndlYXRoZXI/LnByZXNlbnQ7XG4gICAgdGhpcy5faGFzRGFpbHlGb3JlY2FzdHMgPSAhIWNvbmZpZy53ZWF0aGVyPy5kYWlseV9mb3JlY2FzdHM7XG4gICAgdGhpcy5faGFzSG91cmx5Rm9yZWNhc3RzID0gISFjb25maWcud2VhdGhlcj8uaG91cmx5X2ZvcmVjYXN0cztcbiAgICB0aGlzLl9oYXNNYXJpbmVEYWlseUZvcmVjYXN0cyA9ICEhY29uZmlnLndlYXRoZXI/Lm1hcmluZV9kYWlseV9mb3JlY2FzdHM7XG4gICAgdGhpcy5faGFzTWFyaW5lSG91cmx5Rm9yZWNhc3RzID0gISFjb25maWcud2VhdGhlcj8ubWFyaW5lX2hvdXJseV9mb3JlY2FzdHM7XG4gICAgdGhpcy5faGFzTWV0ZWFsYXJtID0gISFjb25maWcud2VhdGhlcj8ubWV0ZW9hbGFybTtcbiAgICB0aGlzLl9oYXNEUENhbGFybSA9ICEhY29uZmlnLndlYXRoZXI/LmRwY2FsYXJtO1xuICAgIC8vIHRoaXMuX2hhc01ldGVvZ3JhbSA9ICEhY29uZmlnLndlYXRoZXI/LmZvcmVjYXN0Py5tZXRlb2dyYW07XG4gICAgdGhpcy5faGFzQWlyUXVhbGl0eSA9ICEhY29uZmlnLmFpcnF1YWxpdHk7XG4gICAgdGhpcy5faGFzUG9sbGVuID0gY29uZmlnLnBvbGxlbiAmJiBBcnJheS5pc0FycmF5KGNvbmZpZy5wb2xsZW4uZW50aXRpZXMpICYmIGNvbmZpZy5wb2xsZW4uZW50aXRpZXMubGVuZ3RoID4gMDtcbiAgICB0aGlzLl9oYXNVbHRyYXZpb2xldCA9ICEhY29uZmlnLnVsdHJhdmlvbGV0O1xuICAgIHRoaXMuX2hhc0NhbWVyYSA9ICEhY29uZmlnLmNhbWVyYTtcbiAgICAvLyB0aGlzLl9oYXNBbGVydCA9ICEhY29uZmlnLmFsZXJ0O1xuICB9XG5cbiAgcHJpdmF0ZSBfc2V0dXBJY29ucyhpY29uc01vZGVsPzogc3RyaW5nKSB7XG4gICAgdGhpcy5faWNvbnNDb25maWcgPSB7XG4gICAgICBwYXRoOiB0aGlzLl9pbWFnZXNQYXRoLFxuICAgICAgaWNvblR5cGU6IHRoaXMuX2NvbmZpZz8ud2VhdGhlcj8uYW5pbWF0aW9uID8gJ2FuaW1hdGVkJyA6ICdzdGF0aWMnLFxuICAgICAgaWNvbnNfbW9kZWw6IGljb25zTW9kZWwgfHwgJ3BpcmF0ZXdlYXRoZXInLFxuICAgICAgaWNvbnNEYXk6IGN3Y0RheXRpbWVQaXJhdGVXZWF0aGVySWNvbnMsXG4gICAgICBpY29uc05pZ2h0OiBjd2NOaWdodGx5UGlyYXRlV2VhdGVySWNvbnMsXG4gICAgfTtcblxuICAgIGlmIChpY29uc01vZGVsKSB7XG4gICAgICBjb25zdCBtb2RlbERhdGEgPSBnZXRJY29uTW9kZWxEYXRhKGljb25zTW9kZWwpO1xuICAgICAgdGhpcy5faWNvbnNDb25maWcuaWNvbnNfbW9kZWwgPSBtb2RlbERhdGEuaWNvbnNNb2RlbDtcbiAgICAgIHRoaXMuX2ljb25zQ29uZmlnLmljb25zRGF5ID0gbW9kZWxEYXRhLmljb25zRGF5O1xuICAgICAgdGhpcy5faWNvbnNDb25maWcuaWNvbnNOaWdodCA9IG1vZGVsRGF0YS5pY29uc05pZ2h0O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBnZW5lcmF0ZXMgdGhlIGNhcmQgSFRNTFxuICAgKiBAcmV0dXJuIHtUZW1wbGF0ZVJlc3VsdH1cbiAgICovXG4gIHB1YmxpYyByZW5kZXIoKTogVGVtcGxhdGVSZXN1bHQge1xuICAgIGlmICh0aGlzLmludmFsaWRDb25maWcpIHtcbiAgICAgIHJldHVybiBodG1sYFxuICAgICAgICA8aGEtY2FyZCBjbGFzcz1cImhhLWNhcmQtd2VhdGhlci1jb25kaXRpb25zXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPSdiYW5uZXInPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXJcIj5oYS1jYXJkLXdlYXRoZXItY29uZGl0aW9uczwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPSdjb250ZW50Jz5cbiAgICAgICAgICAgICAgICBDb25maWd1cmF0aW9uIEVSUk9SIVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvaGEtY2FyZD5cbiAgICBgO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9yZW5kZXIoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBfcmVuZGVyKCk6IFRlbXBsYXRlUmVzdWx0O1xufVxuIiwiaW1wb3J0IHsgaHRtbCwgbm90aGluZyB9IGZyb20gJ2xpdCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2VhdGhlclN1bW1hcnlJbnRlcmZhY2Uge1xuICB0aXRsZT86IHN0cmluZztcbiAgbW9vblRleHQ/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIG1vb25JY29uPzogc3RyaW5nO1xuICBjb25kaXRpb25UZXh0OiBzdHJpbmc7XG4gIGNvbmRpdGlvbkljb246IHN0cmluZztcbiAgdGVtcGVyYXR1cmU/OiBzdHJpbmc7XG4gIHRlbXBlcmF0dXJlVW5pdD86IHN0cmluZztcbiAgZmVlbHNMaWtlVGVybT86IHN0cmluZztcbiAgdGVtcGVyYXR1cmVGZWVsc0xpa2U/OiBzdHJpbmc7XG4gIHRlbXBlcmF0dXJlRmVlbHNMaWtlSWNvbj86IHN0cmluZztcbn1cblxuY29uc3QgcmVuZGVyTGlnaHRuaW5nRmxhc2haaWd6YWcgPSAoeFBlcmNlbnQ6IG51bWJlciwgeVBlcmNlbnQ6IG51bWJlciwgc2VnbWVudHM6IG51bWJlciA9IDcpID0+IHtcbiAgY29uc3Qgd2lkdGggPSAxMDsgLy8gbGFyZ2hlenphIGluIHBpeGVsIGRlbGxhIHZpZXdwb3J0IFNWR1xuICBjb25zdCBoZWlnaHQgPSAyMCArIE1hdGgucmFuZG9tKCkgKiA1MDtcblxuICBjb25zdCBwb2ludHMgPSBbXTtcbiAgbGV0IHggPSB3aWR0aCAvIDI7XG4gIGxldCB5ID0gMDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNlZ21lbnRzOyBpICs9IDEpIHtcbiAgICAvLyB4ICs9IChNYXRoLnJhbmRvbSgpICogd2lkdGggLSB3aWR0aCAvIDIpO1xuICAgIC8vIHkgKz0gaGVpZ2h0IC8gc2VnbWVudHM7XG4gICAgeCArPSAoTWF0aC5yYW5kb20oKSAqIHdpZHRoICogMS41IC0gd2lkdGggKiAwLjc1KTsgLy8gbWFnZ2lvcmUgemlnemFnXG4gICAgeSArPSAoaGVpZ2h0IC8gc2VnbWVudHMpICogKDAuNyArIE1hdGgucmFuZG9tKCkgKiAwLjYpOyAvLyBsdW5naGV6emEgdmFyaWFiaWxlXG4gICAgcG9pbnRzLnB1c2goYCR7eH0sJHt5fWApO1xuICB9XG5cbiAgY29uc3QgcGF0aEQgPSBgTSR7d2lkdGggLyAyfSwwICR7cG9pbnRzLm1hcCgocCkgPT4gYEwke3B9YCkuam9pbignICcpfWA7XG5cbiAgY29uc3QgZGVsYXkgPSBNYXRoLnJhbmRvbSgpICogMTUuNTtcbiAgY29uc3QgZHVyYXRpb24gPSAwLjIgKyBNYXRoLnJhbmRvbSgpICogMC4zICogMzM7XG5cbiAgcmV0dXJuIGh0bWxgXG4gICAgPHN2Z1xuICAgICAgY2xhc3M9XCJsaWdodG5pbmctc3ZnXCJcbiAgICAgIHN0eWxlPVwiXG4gICAgICAgIHRvcDogJHt5UGVyY2VudH0lO1xuICAgICAgICBsZWZ0OiAke3hQZXJjZW50fSU7XG4gICAgICAgIGFuaW1hdGlvbi1kZWxheTogJHtkZWxheX1zO1xuICAgICAgICBhbmltYXRpb24tZHVyYXRpb246ICR7ZHVyYXRpb259cztcbiAgICAgIFwiXG4gICAgICB3aWR0aD1cIiR7d2lkdGh9XCIgaGVpZ2h0PVwiJHtoZWlnaHR9XCIgdmlld0JveD1cIjAgMCAke3dpZHRofSAke2hlaWdodH1cIj5cbiAgICAgIDxwYXRoIGQ9XCIke3BhdGhEfVwiIHN0cm9rZT1cIndoaXRlXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgZmlsbD1cIm5vbmVcIiAvPlxuICAgIDwvc3ZnPlxuICBgO1xufTtcblxuY29uc3QgcmVuZGVyTGlnaHRuaW5nRmxhc2hlcyA9IChhemltdXRoOiBudW1iZXIsIGRpc3RhbmNlOiBudW1iZXIsIHN0cmlrZXM6IG51bWJlcikgPT4ge1xuICBjb25zdCBmbGFzaGVzID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3RyaWtlczsgaSArPSAxKSB7XG4gICAgY29uc3QgeCA9IE1hdGgucmFuZG9tKCkgKiAxMDA7XG4gICAgY29uc3QgeSA9IE1hdGgucmFuZG9tKCkgKiAyMDtcbiAgICBmbGFzaGVzLnB1c2gocmVuZGVyTGlnaHRuaW5nRmxhc2haaWd6YWcoeCwgeSkpO1xuICB9XG4gIHJldHVybiBmbGFzaGVzO1xufTtcblxuY29uc3QgcmVuZGVyV2VhdGhlclN1bW1hcnkgPSAoe1xuICB0aXRsZSxcbiAgbW9vblRleHQsXG4gIG1vb25JY29uLFxuICBjb25kaXRpb25UZXh0LFxuICBjb25kaXRpb25JY29uLFxuICB0ZW1wZXJhdHVyZSxcbiAgdGVtcGVyYXR1cmVVbml0LFxuICBmZWVsc0xpa2VUZXJtLFxuICB0ZW1wZXJhdHVyZUZlZWxzTGlrZSxcbiAgdGVtcGVyYXR1cmVGZWVsc0xpa2VJY29uLFxufTogV2VhdGhlclN1bW1hcnlJbnRlcmZhY2UpID0+IHtcbiAgY29uc3QgbGlnaHRuaW5nQXppbXV0aCA9IDA7IC8vIFJlcGxhY2Ugd2l0aCBhY3R1YWwgZGF0YVxuICBjb25zdCBsaWdodG5pbmdEaXN0YW5jZUttID0gMDsgLy8gUmVwbGFjZSB3aXRoIGFjdHVhbCBkYXRhXG4gIGNvbnN0IGxpZ2h0bmluZ1N0cmlrZXMgPSAwOyAvLyBSZXBsYWNlIHdpdGggYWN0dWFsIGRhdGFcblxuICBjb25zdCBzaG93TGlnaHRuaW5nID1cbiAgbGlnaHRuaW5nU3RyaWtlcyA+IDAgJiZcbiAgdHlwZW9mIGxpZ2h0bmluZ0F6aW11dGggPT09ICdudW1iZXInICYmXG4gIHR5cGVvZiBsaWdodG5pbmdEaXN0YW5jZUttID09PSAnbnVtYmVyJztcblxuICBpZiAoY29uZGl0aW9uSWNvbiB8fCBtb29uVGV4dCB8fCB0ZW1wZXJhdHVyZSkge1xuICAgIHJldHVybiBodG1sYFxuICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXdyYXBwZXJcIj5cbiAgICAgICR7c2hvd0xpZ2h0bmluZyA/IGh0bWxgXG4gICAgICAgIDxkaXYgY2xhc3M9XCJsaWdodG5pbmctYmFja2dyb3VuZFwiPlxuICAgICAgICAgICR7cmVuZGVyTGlnaHRuaW5nRmxhc2hlcyhsaWdodG5pbmdBemltdXRoISwgbGlnaHRuaW5nRGlzdGFuY2VLbSEsIGxpZ2h0bmluZ1N0cmlrZXMpfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIGAgOiBub3RoaW5nfVxuICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktZ3JpZC1jb250YWluZXJcIj5cbiAgICAgICAgJHtjb25kaXRpb25JY29uID8gaHRtbGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1jb2wtbGVmdFwiPlxuICAgICAgICAgICAgPGltZyBjbGFzcz1cIndlYXRoZXItY29uZGl0aW9uLWljb25cIiBzcmM9XCIke2NvbmRpdGlvbkljb259XCIgYWx0PVwiJHtjb25kaXRpb25UZXh0fVwiIC8+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIGAgOiBub3RoaW5nfVxuICAgICAgICAke3RpdGxlID8gaHRtbGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS10b3AtcmlnaHRcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwid2VhdGhlci1jaXR5LW5hbWVcIj4ke3RpdGxlfTwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj4gICAgXG4gICAgICAgIGAgOiBub3RoaW5nfVxuICAgICAgICAke21vb25UZXh0ID8gaHRtbGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1ib3R0b20tcmlnaHQtbGVmdFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vb24tcm93XCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3VtbWFyeS1tb29uLWljb25cIj4ke21vb25JY29ufTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LW1vb24tdGV4dFwiPiR7bW9vblRleHR9PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+ICBcbiAgICAgICAgICA8L2Rpdj4gICBcbiAgICAgICAgYCA6IG5vdGhpbmd9XG4gICAgICAgICR7dGVtcGVyYXR1cmUgPyBodG1sYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWJvdHRvbS1yaWdodC1yaWdodFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRlbXBlcmF0dXJlLWJsb2NrXCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZW1wZXJhdHVyZVwiPiR7dGVtcGVyYXR1cmV9PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGVtcC11bml0XCI+JHt0ZW1wZXJhdHVyZVVuaXR9PC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgJHt0ZW1wZXJhdHVyZUZlZWxzTGlrZSAmJiBodG1sYDxkaXYgY2xhc3M9XCJmZWVscy1saWtlXCI+JHtmZWVsc0xpa2VUZXJtfSA8ZGl2PiR7dGVtcGVyYXR1cmVGZWVsc0xpa2V9ICR7dGVtcGVyYXR1cmVVbml0fTwvZGl2PjwvZGl2PmB9XG4gICAgICAgICAgICA8L2Rpdj4gIFxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIGAgOiBub3RoaW5nfVxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgYDtcbiAgfVxuXG4gIHJldHVybiBodG1sYGA7XG59O1xuXG5leHBvcnQgZGVmYXVsdCByZW5kZXJXZWF0aGVyU3VtbWFyeTtcbiIsImltcG9ydCB7IEhvbWVBc3Npc3RhbnQgfSBmcm9tICdjdXN0b20tY2FyZC1oZWxwZXJzL2Rpc3QnO1xuXG5pbXBvcnQgcmVuZGVyV2VhdGhlclN1bW1hcnkgZnJvbSAnLi4vdGVtcGxhdGVzL3Qtc3VtbWFyeSc7XG5pbXBvcnQge1xuICBnZXRFbnRpdHlOdW1lcmljVmFsdWUsXG4gIGdldEVudGl0eVJhd1ZhbHVlLFxuICBnZXRFbnRpdHlVbml0LFxuICB0cmFuc2xhdGUsXG59IGZyb20gJy4uL3V0aWxzL2hlbHBlcic7XG5cbmltcG9ydCB7IGdldE1vb25JY29uLCBnZXRXZWF0aGVySWNvbiB9IGZyb20gJy4uL3V0aWxzL2hlbHBlci1yZW5kZXInO1xuaW1wb3J0IHsgaVByZXNlbnREYXRhIH0gZnJvbSAnLi4vdXRpbHMvY29uZmlnLXNjaGVtYSc7XG5pbXBvcnQgeyBpSWNvbnNDb25maWcsIGlUZXJtcyB9IGZyb20gJy4uL2Jhc2UvbG92ZWxhY2UtYmFzZSc7XG5cbmNvbnN0IGJ1aWxkV2VhdGhlclN1bW1hcnkgPSAoXG4gIGhhc3M6IEhvbWVBc3Npc3RhbnQsXG4gIGxhbmd1YWdlOiBzdHJpbmcsXG4gIHRlcm1zOiBpVGVybXMsXG4gIGljb25zQ29uZmlnOiBpSWNvbnNDb25maWcsXG4gIG5hbWU6IHN0cmluZyxcbiAgcHJlc2VudERhdGE6IGlQcmVzZW50RGF0YSxcbiAgc3VuSWQ6IHN0cmluZyxcbiAgbW9vbnBoYXNlOiBzdHJpbmcsXG4pID0+IHtcbiAgY29uc3QgbW9vblBoYXNlID0gZ2V0RW50aXR5UmF3VmFsdWUoaGFzcywgbW9vbnBoYXNlKTtcbiAgY29uc3QgbW9vbkljb246IHN0cmluZyA9IG1vb25QaGFzZSA/IGdldE1vb25JY29uKG1vb25QaGFzZSkgOiAnJztcbiAgY29uc3Qgc3VuID0gZ2V0RW50aXR5UmF3VmFsdWUoaGFzcywgc3VuSWQpO1xuICBjb25zdCBjdXJyZW50Q29uZGl0aW9ucyA9IGdldEVudGl0eVJhd1ZhbHVlKGhhc3MsIHByZXNlbnREYXRhLmNvbmRpdGlvbik/LnRvTG93ZXJDYXNlKCkgfHwgJ25hJztcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgY29uc3QgdGVtcGVyYXR1cmUgPSBwcmVzZW50RGF0YS50ZW1wZXJhdHVyZSA/IGdldEVudGl0eU51bWVyaWNWYWx1ZSh7IGVudGl0eUlkOiBwcmVzZW50RGF0YS50ZW1wZXJhdHVyZSwgaGFzcywgbGFuZzogbGFuZ3VhZ2UgfSkgPz8gdW5kZWZpbmVkIDogdW5kZWZpbmVkO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICBjb25zdCB0ZW1wZXJhdHVyZUZlZWxzTGlrZSA9IHByZXNlbnREYXRhLnRlbXBlcmF0dXJlX2ZlZWxzbGlrZSA/IGdldEVudGl0eU51bWVyaWNWYWx1ZSh7IGVudGl0eUlkOiBwcmVzZW50RGF0YS50ZW1wZXJhdHVyZV9mZWVsc2xpa2UsIGhhc3MsIGxhbmc6IGxhbmd1YWdlIH0pID8/IHVuZGVmaW5lZCA6IHVuZGVmaW5lZDtcbiAgY29uc3QgdGVtcGVyYXR1cmVGZWVsc0xpa2VJY29uID0gaGFzcy5zdGF0ZXNbcHJlc2VudERhdGEudGVtcGVyYXR1cmVfZmVlbHNsaWtlXT8uYXR0cmlidXRlcy5pY29uID8/ICcnO1xuXG4gIHJldHVybiByZW5kZXJXZWF0aGVyU3VtbWFyeSh7XG4gICAgdGl0bGU6IG5hbWUgPz8gdW5kZWZpbmVkLCAvLyAnVmVya2huZW5vdm9rdXRsdW1iZXR5ZXZvJyxcbiAgICBtb29uVGV4dDogKG1vb25waGFzZSA/IHRyYW5zbGF0ZShtb29uUGhhc2UsIHRlcm1zLndvcmRzKSA6IHVuZGVmaW5lZCksXG4gICAgbW9vbkljb24sXG4gICAgY29uZGl0aW9uVGV4dDogY3VycmVudENvbmRpdGlvbnMsXG4gICAgY29uZGl0aW9uSWNvbjogZ2V0V2VhdGhlckljb24oY3VycmVudENvbmRpdGlvbnMsIGljb25zQ29uZmlnLCBzdW4pLFxuICAgIHRlbXBlcmF0dXJlLFxuICAgIHRlbXBlcmF0dXJlVW5pdDogZ2V0RW50aXR5VW5pdChoYXNzLCBwcmVzZW50RGF0YS50ZW1wZXJhdHVyZSksXG4gICAgZmVlbHNMaWtlVGVybTogdHJhbnNsYXRlKCdGZWVscyBMaWtlJywgdGVybXMud29yZHMpLFxuICAgIHRlbXBlcmF0dXJlRmVlbHNMaWtlLFxuICAgIHRlbXBlcmF0dXJlRmVlbHNMaWtlSWNvbixcbiAgfSk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBidWlsZFdlYXRoZXJTdW1tYXJ5O1xuIiwiaW1wb3J0IHsgaHRtbCB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgeyBnZXRMb2NhbGUsIHBhcnNlTG9jYWxpemVkTnVtYmVyIH0gZnJvbSAnLi4vdXRpbHMvaGVscGVyJztcblxuZXhwb3J0IGludGVyZmFjZSBpUmVuZGVyRGF0YUl0ZW0ge1xuICB2YWx1ZT86IG51bWJlciB8IHN0cmluZyB8IERhdGU7XG4gIHVuaXQ/OiBzdHJpbmc7XG4gIGljb24/OiBzdHJpbmc7XG4gIGljb25fY29sb3I/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2VhdGhlckRhdGEge1xuICB0ZW1wZXJhdHVyZUhpZ2g/OiBpUmVuZGVyRGF0YUl0ZW07XG4gIHRlbXBlcmF0dXJlTG93PzogaVJlbmRlckRhdGFJdGVtO1xuICBwcmVjaXBpdGF0aW9uUHJvYmFiaWxpdHk/OiBpUmVuZGVyRGF0YUl0ZW07XG4gIHByZWNpcGl0YXRpb25JbnRlbnNpdHk/OiBpUmVuZGVyRGF0YUl0ZW07XG4gIG5leHRSaXNpbmc/OiBpUmVuZGVyRGF0YUl0ZW07XG4gIG5leHRTZXR0aW5nPzogaVJlbmRlckRhdGFJdGVtO1xuXG4gIC8vIHByZWNpcGl0YXRpb24/OiBpUmVuZGVyRGF0YUl0ZW07XG4gIGh1bWlkaXR5PzogaVJlbmRlckRhdGFJdGVtO1xuICB3aW5kQmVhcmluZz86IGlSZW5kZXJEYXRhSXRlbTtcbiAgd2luZFNwZWVkPzogaVJlbmRlckRhdGFJdGVtO1xuICBwcmVzc3VyZT86IGlSZW5kZXJEYXRhSXRlbTtcbiAgdmlzaWJpbGl0eT86IGlSZW5kZXJEYXRhSXRlbTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBpQWlyUXVhbGl0eURhdGEge1xuICBwbTI1OiBpUmVuZGVyRGF0YUl0ZW0sXG4gIHBtMTA6aVJlbmRlckRhdGFJdGVtLFxuICBvMzogaVJlbmRlckRhdGFJdGVtLFxuICBubzI6IGlSZW5kZXJEYXRhSXRlbSxcbiAgY286IGlSZW5kZXJEYXRhSXRlbSxcbiAgc28yOiBpUmVuZGVyRGF0YUl0ZW0sXG4gIGVwYV9hcWk6IGlSZW5kZXJEYXRhSXRlbSxcbiAgZXBhX3ByaW1hcnlfcG9sbHV0YW50OiBpUmVuZGVyRGF0YUl0ZW0sXG59XG5cbmNvbnN0IGlzVmFsaWRJbnB1dCA9ICh2YWw6IHVua25vd24pOiB2YWwgaXMgc3RyaW5nIHwgbnVtYmVyID0+IHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiB2YWwgPT09ICdudW1iZXInO1xuXG5jb25zdCBwcmVwYXJlV2VhdGhlclByZXNlbnQgPSAoZGF0YTogV2VhdGhlckRhdGEsIGxhbmd1YWdlOiBzdHJpbmcpID0+IHtcbiAgY29uc3QgYWxsSXRlbXM6IGlSZW5kZXJEYXRhSXRlbVtdID0gW107XG5cbiAgY29uc3QgYWRkSWZWYWxpZCA9IChrZXk6IGtleW9mIFdlYXRoZXJEYXRhLCBpdGVtPzogaVJlbmRlckRhdGFJdGVtKSA9PiB7XG4gICAgaWYgKGl0ZW0/LnZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybjtcblxuICAgIGFsbEl0ZW1zLnB1c2goaXRlbSk7XG4gIH07XG5cbiAgY29uc3QgcGkgPSBkYXRhLnByZWNpcGl0YXRpb25JbnRlbnNpdHk/LnZhbHVlO1xuICBjb25zdCBwcCA9IGRhdGEucHJlY2lwaXRhdGlvblByb2JhYmlsaXR5Py52YWx1ZTtcblxuICBpZiAoaXNWYWxpZElucHV0KHBpKSAmJiBpc1ZhbGlkSW5wdXQocHApKSB7XG4gICAgY29uc3QgbG9jYWxlID0gZ2V0TG9jYWxlKGxhbmd1YWdlKTtcbiAgICBjb25zdCBwYXJzZWRQSSA9IHBhcnNlTG9jYWxpemVkTnVtYmVyKHBpLCBsb2NhbGUpO1xuICAgIGNvbnN0IHBhcnNlZFBQID0gcGFyc2VMb2NhbGl6ZWROdW1iZXIocHAsIGxvY2FsZSk7XG5cbiAgICBpZiAoIU51bWJlci5pc05hTihOdW1iZXIocGFyc2VkUEkpKSAmJiAhTnVtYmVyLmlzTmFOKE51bWJlcihwYXJzZWRQUCkpICYmIHBhcnNlZFBJID4gMCAmJiBwYXJzZWRQUCA+IDApIHtcbiAgICAgIGFsbEl0ZW1zLnB1c2goe1xuICAgICAgICBpY29uOlxuICAgICAgICAgIGRhdGEucHJlY2lwaXRhdGlvbkludGVuc2l0eS5pY29uIHx8XG4gICAgICAgICAgZGF0YS5wcmVjaXBpdGF0aW9uUHJvYmFiaWxpdHkuaWNvbiB8fFxuICAgICAgICAgICdtZGk6d2VhdGhlci1yYWlueScsXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgIHZhbHVlOiBgJHtkYXRhLnByZWNpcGl0YXRpb25JbnRlbnNpdHkudmFsdWV9ICR7ZGF0YS5wcmVjaXBpdGF0aW9uSW50ZW5zaXR5LnVuaXR9IC8gJHtkYXRhLnByZWNpcGl0YXRpb25Qcm9iYWJpbGl0eS52YWx1ZX0gJHtkYXRhLnByZWNpcGl0YXRpb25Qcm9iYWJpbGl0eS51bml0fWAsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvLyBUZW1wZXJhdHVyYSBtaW4vbWF4IGNvbWJpbmF0YVxuICBpZiAoXG4gICAgZGF0YS50ZW1wZXJhdHVyZUxvdz8udmFsdWUgIT09IHVuZGVmaW5lZCAmJlxuICAgIGRhdGEudGVtcGVyYXR1cmVIaWdoPy52YWx1ZSAhPT0gdW5kZWZpbmVkXG4gICkge1xuICAgIGFsbEl0ZW1zLnB1c2goe1xuICAgICAgaWNvbjogZGF0YS50ZW1wZXJhdHVyZUxvdy5pY29uIHx8IGRhdGEudGVtcGVyYXR1cmVIaWdoLmljb24gfHwgJ21kaTp0aGVybW9tZXRlcicsXG4gICAgICB2YWx1ZTogYCR7ZGF0YS50ZW1wZXJhdHVyZUxvdy52YWx1ZX0gLyAke2RhdGEudGVtcGVyYXR1cmVIaWdoLnZhbHVlfWAsXG4gICAgICB1bml0OiBkYXRhLnRlbXBlcmF0dXJlTG93LnVuaXQgfHwgZGF0YS50ZW1wZXJhdHVyZUhpZ2gudW5pdCxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IGtleXM6IChrZXlvZiBXZWF0aGVyRGF0YSlbXSA9IFtcbiAgICAnaHVtaWRpdHknLFxuICAgICdwcmVzc3VyZScsXG4gICAgJ3Zpc2liaWxpdHknLFxuICBdO1xuICBrZXlzLmZvckVhY2goKGspID0+IGFkZElmVmFsaWQoaywgZGF0YVtrXSkpO1xuXG4gIC8vIFdpbmQgKGJlYXJpbmcgKyBzcGVlZClcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgaWYgKGRhdGEud2luZFNwZWVkPy52YWx1ZSAhPT0gdW5kZWZpbmVkIHx8IGRhdGEud2luZEJlYXJpbmc/LnZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICBhbGxJdGVtcy5wdXNoKHtcbiAgICAgIGljb246IGRhdGEud2luZFNwZWVkPy5pY29uIHx8ICdtZGk6d2VhdGhlci13aW5keScsXG4gICAgICB2YWx1ZTogYCR7ZGF0YS53aW5kQmVhcmluZz8udmFsdWUgPyBgJHtkYXRhLndpbmRCZWFyaW5nLnZhbHVlfSBgIDogJyd9JHtkYXRhLndpbmRTcGVlZD8udmFsdWUgPz8gJyd9YCxcbiAgICAgIHVuaXQ6IGRhdGEud2luZFNwZWVkPy51bml0ID8gYCR7ZGF0YS53aW5kU3BlZWQudW5pdH1gIDogJycsXG4gICAgfSk7XG4gIH1cblxuICAvLyBTdW4gdGltZXNcbiAgWyduZXh0UmlzaW5nJywgJ25leHRTZXR0aW5nJ10uZm9yRWFjaCgoaykgPT4ge1xuICAgIGNvbnN0IGl0ZW0gPSBkYXRhW2sgYXMga2V5b2YgV2VhdGhlckRhdGFdO1xuICAgIGlmIChpdGVtPy52YWx1ZSkge1xuICAgICAgYWxsSXRlbXMucHVzaCh7XG4gICAgICAgIGljb246IGl0ZW0uaWNvbixcbiAgICAgICAgdmFsdWU6IGl0ZW0udmFsdWUsXG4gICAgICAgIHVuaXQ6ICcnLFxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gYWxsSXRlbXM7XG59O1xuXG5jb25zdCBwcmVwYXJlQWlyUXVhbGl0eSA9IChkYXRhOiBpQWlyUXVhbGl0eURhdGEsIGxhbmd1YWdlOiBzdHJpbmcpID0+IHtcbiAgY29uc3QgYWxsSXRlbXM6IGlSZW5kZXJEYXRhSXRlbVtdID0gW107XG5cbiAgY29uc3QgYWRkSWZWYWxpZCA9IChrZXk6IGtleW9mIGlBaXJRdWFsaXR5RGF0YSwgaXRlbT86IGlSZW5kZXJEYXRhSXRlbSkgPT4ge1xuICAgIGlmIChpdGVtPy52YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG5cbiAgICBhbGxJdGVtcy5wdXNoKGl0ZW0pO1xuICB9O1xuXG4gIGNvbnN0IGtleXM6IChrZXlvZiBpQWlyUXVhbGl0eURhdGEpW10gPSBbXG4gICAgJ2VwYV9hcWknLFxuICAgICdlcGFfcHJpbWFyeV9wb2xsdXRhbnQnLFxuICAgICdwbTI1JyxcbiAgICAncG0xMCcsXG4gICAgJ28zJyxcbiAgICAnbm8yJyxcbiAgICAnY28nLFxuICAgICdzbzInLFxuICBdO1xuICBrZXlzLmZvckVhY2goKGspID0+IGFkZElmVmFsaWQoaywgZGF0YVtrXSkpO1xuXG4gIHJldHVybiBhbGxJdGVtcztcbn07XG5cbmV4cG9ydCBjb25zdCByZW5kZXJXZWF0aGVyUHJlc2VudCA9IChkYXRhLCBsYW5ndWFnZTogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IGFsbEl0ZW1zOiBpUmVuZGVyRGF0YUl0ZW1bXSA9IFtdO1xuXG4gIGNvbnN0IGJ1aWxkQmxvY2tMZWZ0ID0gKGl0ZW06IGlSZW5kZXJEYXRhSXRlbSkgPT4gaHRtbGBcbiAgICA8c3BhbiBjbGFzcz1cInByZXNlbnQtdmFsdWUtYmxvY2tcIj5cbiAgICAgIDxoYS1pY29uIGljb249XCIke2l0ZW0uaWNvbn1cIiBzdHlsZT0ke2l0ZW0uaWNvbl9jb2xvciA/IGBjb2xvcjogJHtpdGVtLmljb25fY29sb3J9YCA6ICcnfT48L2hhLWljb24+XG4gICAgICAke2l0ZW0udmFsdWV9JHtpdGVtLnVuaXQgPyBodG1sYDxzcGFuIGNsYXNzPVwicHJlc2VudC11bml0XCI+JHtpdGVtLnVuaXR9PC9zcGFuPmAgOiAnJ31cbiAgICA8L3NwYW4+XG4gIGA7XG5cbiAgY29uc3QgYnVpbGRCbG9ja1JpZ2h0ID0gKGl0ZW06IGlSZW5kZXJEYXRhSXRlbSkgPT4gaHRtbGBcbiAgICA8c3BhbiBjbGFzcz1cInByZXNlbnQtdmFsdWUtYmxvY2tcIj5cbiAgICAgICR7aXRlbS52YWx1ZX0ke2l0ZW0udW5pdCA/IGh0bWxgPHNwYW4gY2xhc3M9XCJwcmVzZW50LXVuaXRcIj4ke2l0ZW0udW5pdH08L3NwYW4+YCA6ICcnfVxuICAgICAgPGhhLWljb24gaWNvbj1cIiR7aXRlbS5pY29ufVwiIHN0eWxlPSR7aXRlbS5pY29uX2NvbG9yID8gYGNvbG9yOiAke2l0ZW0uaWNvbl9jb2xvcn1gIDogJyd9PjwvaGEtaWNvbj5cbiAgICA8L3NwYW4+XG4gIGA7XG5cbiAgYWxsSXRlbXMucHVzaCguLi5wcmVwYXJlV2VhdGhlclByZXNlbnQoZGF0YSwgbGFuZ3VhZ2UpLCAuLi5wcmVwYXJlQWlyUXVhbGl0eShkYXRhLCBsYW5ndWFnZSkpO1xuXG4gIGNvbnN0IHJvd3MgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhbGxJdGVtcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIGNvbnN0IGxlZnQgPSBhbGxJdGVtc1tpXTtcbiAgICBjb25zdCByaWdodCA9IGFsbEl0ZW1zW2kgKyAxXTtcblxuICAgIGlmICgobGVmdCAmJiBsZWZ0LnZhbHVlKSB8fCAocmlnaHQgJiYgcmlnaHQudmFsdWUpKSB7XG4gICAgICByb3dzLnB1c2goaHRtbGBcbiAgICAgICAgPGRpdiBjbGFzcz1cInByZXNlbnQtcm93XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInByZXNlbnQtbGVmdFwiPiR7bGVmdCA/IGJ1aWxkQmxvY2tMZWZ0KGxlZnQpIDogaHRtbGBgfTwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwcmVzZW50LXJpZ2h0XCI+JHtyaWdodCA/IGJ1aWxkQmxvY2tSaWdodChyaWdodCkgOiBodG1sYGB9PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgYCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJvd3MubGVuZ3RoID4gMCA/IGh0bWxgXG4gICAgPGRpdiBjbGFzcz1cInByZXNlbnQtZ3JpZC1jb250YWluZXJcIj5cbiAgICAgICR7cm93c31cbiAgICA8L2Rpdj5cbiAgYCA6IGh0bWxgYDtcbn07XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbmltcG9ydCB7IEhvbWVBc3Npc3RhbnQgfSBmcm9tICdjdXN0b20tY2FyZC1oZWxwZXJzL2Rpc3QnO1xuaW1wb3J0IHtcbiAgZ2V0RW50aXR5TnVtZXJpY1ZhbHVlLFxuICBnZXRFbnRpdHlSYXdWYWx1ZSxcbiAgZ2V0RW50aXR5VW5pdCxcbiAgZ2V0TG9jYWxlSW5mbyxcbiAgZ2V0V2luZERpcmVjdGlvbnMsXG59IGZyb20gJy4uL3V0aWxzL2hlbHBlcic7XG4vLyBpbXBvcnQgeyBnZXRTZW5zb3JVbml0IH0gZnJvbSAnLi4vdXRpbHMvaGVscGVyLXJlbmRlcic7XG5pbXBvcnQgeyByZW5kZXJXZWF0aGVyUHJlc2VudCB9IGZyb20gJy4uL3RlbXBsYXRlcy90LXByZXNlbnQnO1xuaW1wb3J0IHsgaVByZXNlbnREYXRhIH0gZnJvbSAnLi4vdXRpbHMvY29uZmlnLXNjaGVtYSc7XG5pbXBvcnQgeyBpVGVybXMgfSBmcm9tICcuLi9iYXNlL2xvdmVsYWNlLWJhc2UnO1xuXG5jb25zdCBwcmVzZW50ID0gKGhhc3M6IEhvbWVBc3Npc3RhbnQsIGxhbmd1YWdlOiBzdHJpbmcsIGN3Y0xvY1dpbmREaXJlY3Rpb25zLCBwcmVzZW50RGF0YTogaVByZXNlbnREYXRhLCBzdW5JZDogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IGxvY2FsZUluZm8gPSBnZXRMb2NhbGVJbmZvKGxhbmd1YWdlKTtcbiAgY29uc3Qgc3VuRW50aXR5ID0gc3VuSWQgPyBoYXNzLnN0YXRlc1tzdW5JZF0gOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHsgbmV4dF9yaXNpbmcsIG5leHRfc2V0dGluZyB9ID0gc3VuRW50aXR5Py5hdHRyaWJ1dGVzID8/IHt9O1xuXG4gIGNvbnN0IG5leHRfcmlzaW5nX2Zvcm1hdHRlZCA9IG5leHRfcmlzaW5nID8gbmV3IERhdGUobmV4dF9yaXNpbmcpLnRvTG9jYWxlVGltZVN0cmluZyhsb2NhbGVJbmZvLmxvY2FsZSwge1xuICAgIGhvdXI6ICcyLWRpZ2l0JyxcbiAgICBtaW51dGU6ICcyLWRpZ2l0JyxcbiAgICBzZWNvbmQ6ICcyLWRpZ2l0JyxcbiAgICBob3VyMTI6IGZhbHNlLFxuICAgIHRpbWVab25lOiBsb2NhbGVJbmZvLnRpbWV6b25lLFxuICB9KSA6IHVuZGVmaW5lZDtcblxuICBjb25zdCBuZXh0X3NldHRpbmdfZm9ybWF0dGVkID0gbmV4dF9yaXNpbmcgPyBuZXcgRGF0ZShuZXh0X3NldHRpbmcpLnRvTG9jYWxlVGltZVN0cmluZyhsb2NhbGVJbmZvLmxvY2FsZSwge1xuICAgIGhvdXI6ICcyLWRpZ2l0JyxcbiAgICBtaW51dGU6ICcyLWRpZ2l0JyxcbiAgICBzZWNvbmQ6ICcyLWRpZ2l0JyxcbiAgICBob3VyMTI6IGZhbHNlLFxuICAgIHRpbWVab25lOiBsb2NhbGVJbmZvLnRpbWV6b25lLFxuICB9KSA6IHVuZGVmaW5lZDtcblxuICByZXR1cm4ge1xuICAgIG5leHRSaXNpbmc6IHsgdmFsdWU6IG5leHRfcmlzaW5nX2Zvcm1hdHRlZCwgaWNvbjogJ21kaTp3ZWF0aGVyLXN1bnNldC11cCcgfSxcbiAgICBuZXh0U2V0dGluZzogeyB2YWx1ZTogbmV4dF9zZXR0aW5nX2Zvcm1hdHRlZCwgaWNvbjogJ21kaTp3ZWF0aGVyLXN1bnNldC1kb3duJyB9LFxuXG4gICAgcHJlY2lwaXRhdGlvbkludGVuc2l0eToge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG9iamVjdC1jdXJseS1uZXdsaW5lXG4gICAgICB2YWx1ZTogZ2V0RW50aXR5TnVtZXJpY1ZhbHVlKHsgZW50aXR5SWQ6IHByZXNlbnREYXRhLnByZWNpcGl0YXRpb25faW50ZW5zaXR5LCBoYXNzLCBsYW5nOiBsYW5ndWFnZSwgZGVjaW1hbHM6IDIgfSksXG4gICAgICB1bml0OiBnZXRFbnRpdHlVbml0KGhhc3MsIHByZXNlbnREYXRhLnByZWNpcGl0YXRpb25faW50ZW5zaXR5KSxcbiAgICAgIGljb246ICdtZGk6d2VhdGhlci1yYWlueScsXG4gICAgfSxcbiAgICBwcmVjaXBpdGF0aW9uUHJvYmFiaWxpdHk6IHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBvYmplY3QtY3VybHktbmV3bGluZVxuICAgICAgdmFsdWU6IGdldEVudGl0eU51bWVyaWNWYWx1ZSh7IGVudGl0eUlkOiBwcmVzZW50RGF0YS5wcmVjaXBpdGF0aW9uX3Byb2JhYmlsaXR5LCBoYXNzLCBsYW5nOiBsYW5ndWFnZSwgZGVjaW1hbHM6IDAgfSksXG4gICAgICB1bml0OiBnZXRFbnRpdHlVbml0KGhhc3MsIHByZXNlbnREYXRhLnByZWNpcGl0YXRpb25fcHJvYmFiaWxpdHkpLFxuICAgICAgaWNvbjogJ21kaTp3ZWF0aGVyLXJhaW55JyxcbiAgICB9LFxuICAgIGh1bWlkaXR5OiB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JqZWN0LWN1cmx5LW5ld2xpbmVcbiAgICAgIHZhbHVlOiBnZXRFbnRpdHlOdW1lcmljVmFsdWUoeyBlbnRpdHlJZDogcHJlc2VudERhdGEuaHVtaWRpdHksIGhhc3MsIGxhbmc6IGxhbmd1YWdlLCBkZWNpbWFsczogMCB9KSxcbiAgICAgIHVuaXQ6IGdldEVudGl0eVVuaXQoaGFzcywgcHJlc2VudERhdGEuaHVtaWRpdHkpLFxuICAgICAgaWNvbjogJ21kaTp3YXRlci1wZXJjZW50JyxcbiAgICB9LFxuICAgIHdpbmRCZWFyaW5nOiB7IHZhbHVlOiBnZXRXaW5kRGlyZWN0aW9ucyhnZXRFbnRpdHlSYXdWYWx1ZShoYXNzLCBwcmVzZW50RGF0YS53aW5kX2JlYXJpbmcpLCBjd2NMb2NXaW5kRGlyZWN0aW9ucykgfSxcbiAgICB3aW5kU3BlZWQ6IHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBvYmplY3QtY3VybHktbmV3bGluZVxuICAgICAgdmFsdWU6IGdldEVudGl0eU51bWVyaWNWYWx1ZSh7IGVudGl0eUlkOiBwcmVzZW50RGF0YS53aW5kX3NwZWVkLCBoYXNzLCBsYW5nOiBsYW5ndWFnZSwgZGVjaW1hbHM6IDAgfSksXG4gICAgICB1bml0OiBnZXRFbnRpdHlVbml0KGhhc3MsIHByZXNlbnREYXRhLndpbmRfc3BlZWQpLFxuICAgICAgaWNvbjogJ21kaTp3ZWF0aGVyLXdpbmR5JyxcbiAgICB9LFxuICAgIHByZXNzdXJlOiB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JqZWN0LWN1cmx5LW5ld2xpbmVcbiAgICAgIHZhbHVlOiBnZXRFbnRpdHlOdW1lcmljVmFsdWUoeyBlbnRpdHlJZDogcHJlc2VudERhdGEucHJlc3N1cmUsIGhhc3MsIGxhbmc6IGxhbmd1YWdlLCBkZWNpbWFsczogMCB9KSxcbiAgICAgIHVuaXQ6IGdldEVudGl0eVVuaXQoaGFzcywgcHJlc2VudERhdGEucHJlc3N1cmUpLFxuICAgICAgaWNvbjogJ21kaTpnYXVnZScsXG4gICAgfSxcbiAgICB2aXNpYmlsaXR5OiB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JqZWN0LWN1cmx5LW5ld2xpbmVcbiAgICAgIHZhbHVlOiBnZXRFbnRpdHlOdW1lcmljVmFsdWUoeyBlbnRpdHlJZDogcHJlc2VudERhdGEudmlzaWJpbGl0eSwgaGFzcywgbGFuZzogbGFuZ3VhZ2UsIGRlY2ltYWxzOiAwIH0pLFxuICAgICAgdW5pdDogZ2V0RW50aXR5VW5pdChoYXNzLCBwcmVzZW50RGF0YS52aXNpYmlsaXR5KSxcbiAgICAgIGljb246ICdtZGk6d2VhdGhlci1mb2cnLFxuICAgIH0sXG4gICAgdGVtcGVyYXR1cmVIaWdoOiB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JqZWN0LWN1cmx5LW5ld2xpbmVcbiAgICAgIHZhbHVlOiBnZXRFbnRpdHlOdW1lcmljVmFsdWUoeyBlbnRpdHlJZDogcHJlc2VudERhdGEudGVtcGVyYXR1cmVfbWF4LCBoYXNzLCBsYW5nOiBsYW5ndWFnZSwgZGVjaW1hbHM6IDAgfSksXG4gICAgICB1bml0OiBnZXRFbnRpdHlVbml0KGhhc3MsIHByZXNlbnREYXRhLnRlbXBlcmF0dXJlX21heCksXG4gICAgICBpY29uOiAnbWRpOnRoZXJtb21ldGVyJyxcbiAgICB9LFxuICAgIHRlbXBlcmF0dXJlTG93OiB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JqZWN0LWN1cmx5LW5ld2xpbmVcbiAgICAgIHZhbHVlOiBnZXRFbnRpdHlOdW1lcmljVmFsdWUoeyBlbnRpdHlJZDogcHJlc2VudERhdGEudGVtcGVyYXR1cmVfbWluLCBoYXNzLCBsYW5nOiBsYW5ndWFnZSwgZGVjaW1hbHM6IDAgfSksXG4gICAgICB1bml0OiBnZXRFbnRpdHlVbml0KGhhc3MsIHByZXNlbnREYXRhLnRlbXBlcmF0dXJlX21pbiksXG4gICAgICBpY29uOiAnbWRpOnRoZXJtb21ldGVyJyxcbiAgICB9LFxuICB9O1xufTtcblxuLy8gY29uc3QgcHJlc2VudEZyb21Gb3JlY2FzdERhdGEgPSAoaGFzczogSG9tZUFzc2lzdGFudCwgbGFuZ3VhZ2U6IHN0cmluZywgZm9yZWNhc3RDZmc6IEZvcmVjYXN0KSA9PiB7XG4vLyAgIGNvbnN0IGdldFZhbHVlID0gKG9iajogUmVjb3JkPHN0cmluZywgc3RyaW5nPikgPT4ge1xuLy8gICAgIGNvbnN0IFtrZXksIGVudGl0eUlkXSA9IE9iamVjdC5lbnRyaWVzKG9iailbMF0gPz8gW107XG4vLyAgICAgY29uc3Qgc3RhdGUgPSBlbnRpdHlJZCAmJiBoYXNzLnN0YXRlc1tlbnRpdHlJZF0/LnN0YXRlO1xuLy8gICAgIHJldHVybiBzdGF0ZSAhPT0gdW5kZWZpbmVkID8gZm9ybWF0TnVtYmVyKHsgc3RyaW5nTnVtYmVyOiBzdGF0ZSwgbGFuZzogbGFuZ3VhZ2UsIGZyYWN0aW9uRGlnaXRzOiAwIH0pIDogdW5kZWZpbmVkO1xuLy8gICB9O1xuXG4vLyAgIGNvbnN0IHtcbi8vICAgICB0ZW1wZXJhdHVyZV9oaWdoID0ge30sXG4vLyAgICAgdGVtcGVyYXR1cmVfbG93ID0ge30sXG4vLyAgICAgcHJlY2lwaXRhdGlvbl9wcm9iYWJpbGl0eSA9IHt9LFxuLy8gICAgIHByZWNpcGl0YXRpb25faW50ZW5zaXR5ID0ge30sXG4vLyAgIH0gPSBmb3JlY2FzdENmZztcblxuLy8gICByZXR1cm4ge1xuLy8gICAgIHRlbXBlcmF0dXJlSGlnaDogeyB2YWx1ZTogZ2V0VmFsdWUodGVtcGVyYXR1cmVfaGlnaCksIHVuaXQ6IGdldEVudGl0eVVuaXQoaGFzcywgdGVtcGVyYXR1cmVfaGlnaCksIGljb246ICdtZGk6dGhlcm1vbWV0ZXInIH0sXG4vLyAgICAgdGVtcGVyYXR1cmVMb3c6IHsgdmFsdWU6IGdldFZhbHVlKHRlbXBlcmF0dXJlX2xvdyksIHVuaXQ6IGdldEVudGl0eVVuaXQoaGFzcywgJ3RlbXBlcmF0dXJlJyksIGljb246ICdtZGk6dGhlcm1vbWV0ZXInIH0sXG4vLyAgICAgcHJlY2lwaXRhdGlvblByb2JhYmlsaXR5OiB7IHZhbHVlOiBnZXRWYWx1ZShwcmVjaXBpdGF0aW9uX3Byb2JhYmlsaXR5KSwgdW5pdDogJyUnLCBpY29uOiAnbWRpOndlYXRoZXItcmFpbnknIH0sXG4vLyAgICAgcHJlY2lwaXRhdGlvbkludGVuc2l0eTogeyB2YWx1ZTogZ2V0VmFsdWUocHJlY2lwaXRhdGlvbl9pbnRlbnNpdHkpLCB1bml0OiBnZXRFbnRpdHlVbml0KGhhc3MsICdwcmVjaXBpdGF0aW9uJyksIGljb246ICdtZGk6d2VhdGhlci1yYWlueScgfSxcbi8vICAgfTtcbi8vIH07XG5cbmNvbnN0IGJ1aWxkV2VhdGhlclByZXNlbnQgPSAoXG4gIGhhc3M6IEhvbWVBc3Npc3RhbnQsXG4gIGxhbmd1YWdlOiBzdHJpbmcsXG4gIHRlcm1zOiBpVGVybXMsXG4gIHByZXNlbnREYXRhOiBpUHJlc2VudERhdGEsXG4gIHN1bklkOiBzdHJpbmcsXG4pID0+IHtcbiAgY29uc3QgbGFuZyA9IGxhbmd1YWdlIHx8IGhhc3Muc2VsZWN0ZWRMYW5ndWFnZSB8fCBoYXNzLmxhbmd1YWdlO1xuXG4gIGNvbnN0IHByZXNlbnRPYmogPSBwcmVzZW50KGhhc3MsIGxhbmcsIHRlcm1zLndpbmREaXJlY3Rpb25zLCBwcmVzZW50RGF0YSwgc3VuSWQpO1xuICAvLyBjb25zdCBwcmVzZW50RnJvbUZvcmVjYXN0T2JqID0gcHJlc2VudEZyb21Gb3JlY2FzdERhdGEoaGFzcywgbGFuZ3VhZ2UsIGZvcmVjYXN0Q2ZnKTtcblxuICAvLyBjb25zb2xlLmRlYnVnKCdidWlsZFdlYXRoZXJQcmVzZW50JywgeyBwcmVzZW50T2JqIH0pO1xuICByZXR1cm4gcmVuZGVyV2VhdGhlclByZXNlbnQoeyAuLi5wcmVzZW50T2JqIH0sIGxhbmcpO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgYnVpbGRXZWF0aGVyUHJlc2VudDtcbiIsImltcG9ydCB7IGh0bWwgfSBmcm9tICdsaXQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlbmRlckRhdGFJdGVtIHtcbiAgdmFsdWU/OiBudW1iZXIgfCBzdHJpbmcgfCBEYXRlO1xuICB1bml0Pzogc3RyaW5nO1xuICBpY29uPzogc3RyaW5nO1xufVxuZXhwb3J0IGludGVyZmFjZSBSZW5kZXJEYXRhIHtcbiAgcHJvdGVjdGlvbldpbmRvdz86IFJlbmRlckRhdGFJdGVtLFxuICBjdXJyZW50VVZMZXZlbD86IFJlbmRlckRhdGFJdGVtLFxuICBjdXJyZW50VVZJbmRleD86IFJlbmRlckRhdGFJdGVtLFxuICBtYXhVVkluZGV4PzogUmVuZGVyRGF0YUl0ZW0sXG4gIGN1cnJlbnRPem9uZUxldmVsPzogUmVuZGVyRGF0YUl0ZW0sXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVuZGVyU2tpbkRhdGEge1xuICBza2luVHlwZTE6IFJlbmRlckRhdGFJdGVtLFxuICBza2luVHlwZTI6IFJlbmRlckRhdGFJdGVtLFxuICBza2luVHlwZTM6IFJlbmRlckRhdGFJdGVtLFxuICBza2luVHlwZTQ6IFJlbmRlckRhdGFJdGVtLFxuICBza2luVHlwZTU6IFJlbmRlckRhdGFJdGVtLFxuICBza2luVHlwZTY6IFJlbmRlckRhdGFJdGVtLFxufVxuXG5jb25zdCBudW0gPSBbJ0knLCAnSUknLCAnSUlJJywgJ0lWJywgJ1YnLCAnVkknXTtcbmNvbnN0IGNvbG9ycyA9IFsnI0YxRDFCMScsICcjRTRCNTkwJywgJyNDRjlGN0QnLCAnI0I2Nzg1MScsICcjQTE1RTJEJywgJyM1MTM5MzgnXTtcblxuY29uc3QgZ2V0VGV4dENvbG9yID0gKGhleDogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgY29uc3QgYyA9IGhleC5yZXBsYWNlKCcjJywgJycpO1xuICBjb25zdCByID0gcGFyc2VJbnQoYy5zdWJzdHIoMCwgMiksIDE2KTtcbiAgY29uc3QgZyA9IHBhcnNlSW50KGMuc3Vic3RyKDIsIDIpLCAxNik7XG4gIGNvbnN0IGIgPSBwYXJzZUludChjLnN1YnN0cig0LCAyKSwgMTYpO1xuICBjb25zdCBicmlnaHRuZXNzID0gKHIgKiAyOTkgKyBnICogNTg3ICsgYiAqIDExNCkgLyAxMDAwO1xuICByZXR1cm4gYnJpZ2h0bmVzcyA+IDEyNSA/ICcjMDAwJyA6ICcjZmZmJztcbn07XG5cbmNvbnN0IHJlbmRlclVsdHJhdmlvbGV0ID0gKGRhdGE6IFJlbmRlckRhdGEsIHNraW5EYXRhOiBSZW5kZXJTa2luRGF0YSkgPT4ge1xuICBjb25zdCBhbGxJdGVtczogUmVuZGVyRGF0YUl0ZW1bXSA9IFtdO1xuXG4gIGNvbnN0IGJ1aWxkQmxvY2tMZWZ0ID0gKGl0ZW06IFJlbmRlckRhdGFJdGVtKSA9PiBodG1sYFxuICAgIDxzcGFuIGNsYXNzPVwidWx0cmF2aW9sZXQtdmFsdWUtYmxvY2tcIj5cbiAgICAgIDxoYS1pY29uIGljb249XCIke2l0ZW0uaWNvbn1cIiBzdHlsZT1cIiR7aXRlbS52YWx1ZSA9PT0gJ29uJyA/ICdjb2xvcjogcmVkOycgOiAnJ31cIj48L2hhLWljb24+XG4gICAgICAke2l0ZW0udmFsdWV9JHtpdGVtLnVuaXQgPyBodG1sYDxzcGFuIGNsYXNzPVwidWx0cmF2aW9sZXQtdW5pdFwiPiR7aXRlbS51bml0fTwvc3Bhbj5gIDogJyd9XG4gICAgPC9zcGFuPlxuICBgO1xuXG4gIGNvbnN0IGJ1aWxkQmxvY2tSaWdodCA9IChpdGVtOiBSZW5kZXJEYXRhSXRlbSkgPT4gaHRtbGBcbiAgICA8c3BhbiBjbGFzcz1cInVsdHJhdmlvbGV0LXZhbHVlLWJsb2NrXCI+XG4gICAgICAke2l0ZW0udmFsdWV9JHtpdGVtLnVuaXQgPyBodG1sYDxzcGFuIGNsYXNzPVwidWx0cmF2aW9sZXQtdW5pdFwiPiR7aXRlbS51bml0fTwvc3Bhbj5gIDogJyd9XG4gICAgICA8aGEtaWNvbiBpY29uPVwiJHtpdGVtLmljb259XCIgc3R5bGU9XCIke2l0ZW0udmFsdWUgPT09ICdvbicgPyAnY29sb3I6IHJlZDsnIDogJyd9XCI+PC9oYS1pY29uPlxuICAgIDwvc3Bhbj5cbiAgYDtcbiAgXG4gIGNvbnN0IGFkZElmVmFsaWQgPSAoa2V5OiBrZXlvZiBSZW5kZXJEYXRhLCBpdGVtPzogUmVuZGVyRGF0YUl0ZW0pID0+IHtcbiAgICBpZiAoaXRlbT8udmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuXG4gICAgYWxsSXRlbXMucHVzaChpdGVtKTtcbiAgfTtcblxuICBsZXQga2V5czogKGtleW9mIFJlbmRlckRhdGEpW10gPSBbXG4gICAgJ3Byb3RlY3Rpb25XaW5kb3cnLFxuICAgICdjdXJyZW50VVZMZXZlbCcsXG4gIF07XG4gIGtleXMuZm9yRWFjaCgoaykgPT4gYWRkSWZWYWxpZChrLCBkYXRhW2tdKSk7XG5cbiAgLy8gVVYgTGV2ZWwgY3VycmVudC9tYXggY29tYmluYXRhXG4gIGlmIChcbiAgICBkYXRhLmN1cnJlbnRVVkluZGV4Py52YWx1ZSAhPT0gdW5kZWZpbmVkICYmXG4gICAgZGF0YS5tYXhVVkluZGV4Py52YWx1ZSAhPT0gdW5kZWZpbmVkXG4gICkge1xuICAgIGFsbEl0ZW1zLnB1c2goe1xuICAgICAgaWNvbjogZGF0YS5jdXJyZW50VVZJbmRleC5pY29uIHx8IGRhdGEubWF4VVZJbmRleC5pY29uIHx8ICdtZGk6d2VhdGhlci1zdW5ueScsXG4gICAgICB2YWx1ZTogYCR7ZGF0YS5jdXJyZW50VVZJbmRleC52YWx1ZX0gLyAke2RhdGEubWF4VVZJbmRleC52YWx1ZX1gLFxuICAgICAgdW5pdDogZGF0YS5jdXJyZW50VVZJbmRleC51bml0IHx8IGRhdGEubWF4VVZJbmRleC51bml0LFxuICAgIH0pO1xuICB9XG5cbiAga2V5cyA9IFtcbiAgICAnY3VycmVudE96b25lTGV2ZWwnLFxuICBdO1xuICBrZXlzLmZvckVhY2goKGspID0+IGFkZElmVmFsaWQoaywgZGF0YVtrXSkpO1xuXG4gIGNvbnN0IHN1bW1hcnlSb3dzID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYWxsSXRlbXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICBjb25zdCBsZWZ0ID0gYWxsSXRlbXNbaV07XG4gICAgY29uc3QgcmlnaHQgPSBhbGxJdGVtc1tpICsgMV07XG4gICAgc3VtbWFyeVJvd3MucHVzaChodG1sYFxuICAgICAgPGRpdiBjbGFzcz1cInVsdHJhdmlvbGV0LXJvd1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidWx0cmF2aW9sZXQtbGVmdFwiPiR7bGVmdCA/IGJ1aWxkQmxvY2tMZWZ0KGxlZnQpIDogaHRtbGBgfTwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwidWx0cmF2aW9sZXQtcmlnaHRcIj4ke3JpZ2h0ID8gYnVpbGRCbG9ja1JpZ2h0KHJpZ2h0KSA6IGh0bWxgYH08L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIGApO1xuICB9XG5cbiAgY29uc3Qgc2tpblR5cGVzID0gW1xuICAgIHNraW5EYXRhLnNraW5UeXBlMSxcbiAgICBza2luRGF0YS5za2luVHlwZTIsXG4gICAgc2tpbkRhdGEuc2tpblR5cGUzLFxuICAgIHNraW5EYXRhLnNraW5UeXBlNCxcbiAgICBza2luRGF0YS5za2luVHlwZTUsXG4gICAgc2tpbkRhdGEuc2tpblR5cGU2LFxuICBdO1xuXG4gIGNvbnN0IHJlbmRlclNraW5HcmlkID0gaHRtbGBcbiAgPGRpdiBjbGFzcz1cInVsdHJhdmlvbGV0LXNraW4tdHlwZS1ncmlkXCI+XG4gICR7c2tpblR5cGVzLm1hcCgoaXRlbSwgaSkgPT4ge1xuICAgIGNvbnN0IGJnQ29sb3IgPSBjb2xvcnNbaV07XG4gICAgY29uc3QgdGV4dENvbG9yID0gZ2V0VGV4dENvbG9yKGJnQ29sb3IpO1xuICAgIHJldHVybiBodG1sYFxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cInVsdHJhdmlvbGV0LXNraW4tdHlwZS1jZWxsXCJcbiAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiAke2JnQ29sb3J9O1wiXG4gICAgICAgIHRpdGxlPVwiRm90b3RpcG8gJHtudW1baV19XCJcbiAgICAgID5cbiAgICAgICAgPGRpdiBjbGFzcz1cInVsdHJhdmlvbGV0LXNraW4tdHlwZS1sYWJlbFwiPiR7bnVtW2ldfTwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwidWx0cmF2aW9sZXQtZXhwb3N1cmUtdGltZVwiIHN0eWxlPVwiY29sb3I6ICR7dGV4dENvbG9yfTtcIj4ke2l0ZW0udmFsdWUgfHwgJy0tJ308L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIGA7XG4gIH0pfVxuICA8L2Rpdj5cbiAgYDtcblxuICByZXR1cm4gaHRtbGBcbiAgICA8ZGl2IGNsYXNzPVwidWx0cmF2aW9sZXQtZ3JpZC1jb250YWluZXJcIj5cbiAgICAgICR7c3VtbWFyeVJvd3N9XG4gICAgICAke3JlbmRlclNraW5HcmlkfVxuICAgIDwvZGl2PlxuICBgO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgcmVuZGVyVWx0cmF2aW9sZXQ7XG4iLCJpbXBvcnQgeyBIb21lQXNzaXN0YW50IH0gZnJvbSAnY3VzdG9tLWNhcmQtaGVscGVycy9kaXN0JztcblxuaW1wb3J0IHsgZ2V0RW50aXR5TnVtZXJpY1ZhbHVlLCBnZXRFbnRpdHlSYXdWYWx1ZSwgcGFkIH0gZnJvbSAnLi4vdXRpbHMvaGVscGVyJztcbmltcG9ydCByZW5kZXJVbHRyYXZpb2xldCBmcm9tICcuLi90ZW1wbGF0ZXMvdC11bHRyYXZpb2xldCc7XG5pbXBvcnQgeyBpVWx0cmF2aW9sZXQgfSBmcm9tICcuLi91dGlscy9jb25maWctc2NoZW1hJztcblxuLy8gY29uc3QgZ2V0UmF3VmFsdWUgPSAoaGFzczogSG9tZUFzc2lzdGFudCwgZW50aXR5SWQ/OiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4gZW50aXR5SWQgJiYgaGFzcy5zdGF0ZXNbZW50aXR5SWRdPy5zdGF0ZTtcbi8vIGNvbnN0IGdldFZhbHVlID0gKGhhc3M6IEhvbWVBc3Npc3RhbnQsIGVudGl0eUlkPzogc3RyaW5nLCBsYW5nOiBzdHJpbmcgPSAnZW4nLCBkZWNpbWFscyA9IDApOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4ge1xuLy8gICBjb25zdCBzdGF0ZSA9IGVudGl0eUlkICYmIGhhc3Muc3RhdGVzW2VudGl0eUlkXT8uc3RhdGU7XG4vLyAgIHJldHVybiBzdGF0ZSAhPT0gdW5kZWZpbmVkID8gZm9ybWF0TnVtYmVyKHN0YXRlLCBsYW5nLCBkZWNpbWFscykgOiB1bmRlZmluZWQ7XG4vLyB9O1xuXG5jb25zdCBnZXRUaW1lID0gKHN0YXRlPzogc3RyaW5nIHwgbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3QgdmFsdWUgPSB0eXBlb2Ygc3RhdGUgPT09ICdzdHJpbmcnICYmIHN0YXRlLnRvTG93ZXJDYXNlKCkgPT09ICd1bmtub3duJ1xuICAgID8gTmFOXG4gICAgOiBOdW1iZXIoc3RhdGUpO1xuICAvLyBjb25zb2xlLmRlYnVnKHN0YXRlKTtcbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUodmFsdWUpIHx8IHZhbHVlIDwgMCkgcmV0dXJuICctLSc7XG5cbiAgY29uc3QgaG91cnMgPSBNYXRoLmZsb29yKHZhbHVlIC8gNjApO1xuICBjb25zdCBtaW51dGVzID0gdmFsdWUgJSA2MDtcblxuICByZXR1cm4gaG91cnMgPiAwXG4gICAgPyBgJHtob3Vyc306JHtwYWQobWludXRlcywgMil9IGhgXG4gICAgOiBgJHttaW51dGVzfSBtYDtcbn07XG5cbmNvbnN0IHN1bW1hcnlEYXRhID0gKGhhc3M6IEhvbWVBc3Npc3RhbnQsIGxhbmc6IHN0cmluZywgdXY6IGlVbHRyYXZpb2xldCkgPT4gKHtcbiAgcHJvdGVjdGlvbldpbmRvdzoge1xuICAgIHZhbHVlOiAoIWdldEVudGl0eVJhd1ZhbHVlKGhhc3MsIHV2LnByb3RlY3Rpb25fd2luZG93KSB8fCBnZXRFbnRpdHlSYXdWYWx1ZShoYXNzLCB1di5wcm90ZWN0aW9uX3dpbmRvdykgPT09ICd1bmtub3duJyA/ICdvZmYnIDpcbiAgICAgIGdldEVudGl0eVJhd1ZhbHVlKGhhc3MsIHV2LnByb3RlY3Rpb25fd2luZG93KVxuICAgICksXG4gICAgaWNvbjogJ21kaTpzdW5nbGFzc2VzJyxcbiAgfSxcbiAgY3VycmVudFVWTGV2ZWw6IHsgdmFsdWU6IGdldEVudGl0eVJhd1ZhbHVlKGhhc3MsIHV2LnV2X2xldmVsKSwgaWNvbjogJ21kaTp3ZWF0aGVyLXN1bm55JyB9LFxuICBjdXJyZW50VVZJbmRleDogeyB2YWx1ZTogZ2V0RW50aXR5TnVtZXJpY1ZhbHVlKHsgZW50aXR5SWQ6IHV2LnV2X2luZGV4LCBoYXNzLCBsYW5nIH0pLCB1bml0OiAnVVYgSWR4JywgaWNvbjogJ21kaTp3ZWF0aGVyLXN1bm55JyB9LFxuICBtYXhVVkluZGV4OiB7IHZhbHVlOiBnZXRFbnRpdHlOdW1lcmljVmFsdWUoeyBlbnRpdHlJZDogdXYubWF4X3V2X2luZGV4LCBoYXNzLCBsYW5nIH0pLCB1bml0OiAnVVYgSWR4JywgaWNvbjogJ21kaTp3ZWF0aGVyLXN1bm55JyB9LFxuICBjdXJyZW50T3pvbmVMZXZlbDogeyB2YWx1ZTogZ2V0RW50aXR5TnVtZXJpY1ZhbHVlKHsgZW50aXR5SWQ6IHV2Lm96b25lX2xldmVsLCBoYXNzLCBsYW5nIH0pLCB1bml0OiAnRFUnLCBpY29uOiAnbWRpOnZlY3Rvci10cmlhbmdsZScgfSxcbn0pO1xuXG5jb25zdCBza2luRGF0YSA9IChoYXNzOiBIb21lQXNzaXN0YW50LCBsYW5nOiBzdHJpbmcsIHV2OiBpVWx0cmF2aW9sZXQpID0+ICh7XG4gIHNraW5UeXBlMTogeyB2YWx1ZTogZ2V0VGltZShnZXRFbnRpdHlOdW1lcmljVmFsdWUoeyBlbnRpdHlJZDogdXYuc2V0X3NraW5fdHlwZV8xLCBoYXNzLCBsYW5nIH0pKSB9LFxuICBza2luVHlwZTI6IHsgdmFsdWU6IGdldFRpbWUoZ2V0RW50aXR5TnVtZXJpY1ZhbHVlKHsgZW50aXR5SWQ6IHV2LnNldF9za2luX3R5cGVfMiwgaGFzcywgbGFuZyB9KSkgfSxcbiAgc2tpblR5cGUzOiB7IHZhbHVlOiBnZXRUaW1lKGdldEVudGl0eU51bWVyaWNWYWx1ZSh7IGVudGl0eUlkOiB1di5zZXRfc2tpbl90eXBlXzMsIGhhc3MsIGxhbmcgfSkpIH0sXG4gIHNraW5UeXBlNDogeyB2YWx1ZTogZ2V0VGltZShnZXRFbnRpdHlOdW1lcmljVmFsdWUoeyBlbnRpdHlJZDogdXYuc2V0X3NraW5fdHlwZV80LCBoYXNzLCBsYW5nIH0pKSB9LFxuICBza2luVHlwZTU6IHsgdmFsdWU6IGdldFRpbWUoZ2V0RW50aXR5TnVtZXJpY1ZhbHVlKHsgZW50aXR5SWQ6IHV2LnNldF9za2luX3R5cGVfNSwgaGFzcywgbGFuZyB9KSkgfSxcbiAgc2tpblR5cGU2OiB7IHZhbHVlOiBnZXRUaW1lKGdldEVudGl0eU51bWVyaWNWYWx1ZSh7IGVudGl0eUlkOiB1di5zZXRfc2tpbl90eXBlXzYsIGhhc3MsIGxhbmcgfSkpIH0sXG59KTtcblxuY29uc3QgYnVpbGRVbHRyYXZpb2xldCA9IChoYXNzOiBIb21lQXNzaXN0YW50LCBsYW5nOiBzdHJpbmcsIHV2OiBpVWx0cmF2aW9sZXQpID0+XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBsaWNpdC1hcnJvdy1saW5lYnJlYWtcbiAgcmVuZGVyVWx0cmF2aW9sZXQoeyAuLi5zdW1tYXJ5RGF0YShoYXNzLCBsYW5nLCB1dikgfSwgeyAuLi5za2luRGF0YShoYXNzLCBsYW5nLCB1dikgfSk7XG5cbmV4cG9ydCBkZWZhdWx0IGJ1aWxkVWx0cmF2aW9sZXQ7XG4iLCJpbXBvcnQgeyBodG1sIH0gZnJvbSAnbGl0JztcblxuZXhwb3J0IGludGVyZmFjZSBpUG9sbGVuRGF0YSB7XG4gIG5hbWU6IHN0cmluZztcbiAgdmFsdWU6IG51bWJlcjtcbn1cblxuY29uc3QgTEVWRUxfTkFNRVMgPSBbJ2Jhc3NvJywgJ21vZGVyYXRvJywgJ2FsdG8nLCAnbW9sdG8tYWx0bycsICdlc3RyZW1vJ107XG5cbmNvbnN0IGdldExldmVsSW5kZXggPSAodmFsdWU6IG51bWJlciwgbGV2ZWxNaW46IG51bWJlciwgbGV2ZWxNYXg6IG51bWJlcik6IG51bWJlciA9PiB7XG4gIGNvbnN0IHJhbmdlID0gbGV2ZWxNYXggLSBsZXZlbE1pbiArIDE7XG4gIGNvbnN0IHN0ZXAgPSByYW5nZSAvIExFVkVMX05BTUVTLmxlbmd0aDtcbiAgY29uc3QgaW5kZXggPSBNYXRoLmZsb29yKCh2YWx1ZSAtIGxldmVsTWluKSAvIHN0ZXApO1xuICByZXR1cm4gTWF0aC5taW4oaW5kZXgsIExFVkVMX05BTUVTLmxlbmd0aCAtIDEpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlbmRlclBvbGxlbiA9IChkYXRhOiBpUG9sbGVuRGF0YVtdLCBsZXZlbE1pbjogbnVtYmVyLCBsZXZlbE1heDogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IG51bUxldmVscyA9IGxldmVsTWF4IC0gbGV2ZWxNaW4gKyAxO1xuICBjb25zdCBsZXZlbHMgPSBMRVZFTF9OQU1FUy5zbGljZSgwLCBudW1MZXZlbHMpO1xuXG4gIGlmIChkYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBodG1sYGA7XG4gIH1cblxuICByZXR1cm4gaHRtbGBcbiAgICA8ZGl2IGNsYXNzPVwicG9sbGVuLWdyaWQtY29udGFpbmVyXCI+XG4gICAgICAke2RhdGEubWFwKChpdGVtKSA9PiB7XG4gICAgY29uc3QgYWN0aXZlSW5kZXggPSBnZXRMZXZlbEluZGV4KGl0ZW0udmFsdWUsIGxldmVsTWluLCBsZXZlbE1heCk7XG4gICAgcmV0dXJuIGh0bWxgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cInBvbGxlbi1zdGFja1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxldmVsc1wiPlxuICAgICAgICAgICAgICAke2xldmVscy5tYXAoKGxldmVsTmFtZSwgaW5kZXgpID0+IGh0bWxgXG4gICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJsZXZlbCAke2xldmVsTmFtZX0gJHtpbmRleCA9PT0gYWN0aXZlSW5kZXggPyAnYWN0aXZlJyA6ICcnfVwiXG4gICAgICAgICAgICAgICAgICB0aXRsZT1cIiR7bGV2ZWxOYW1lfVwiXG4gICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICBgKX1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBvbGxlbi1uYW1lXCI+JHtpdGVtLm5hbWV9PC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIGA7XG4gIH0pfVxuICAgIDwvZGl2PlxuICBgO1xufTtcbiIsImltcG9ydCB7IEhvbWVBc3Npc3RhbnQgfSBmcm9tICdjdXN0b20tY2FyZC1oZWxwZXJzL2Rpc3QnO1xuaW1wb3J0IHsgaVBvbGxlbiB9IGZyb20gJy4uL3V0aWxzL2NvbmZpZy1zY2hlbWEnO1xuaW1wb3J0IHsgZ2V0RW50aXR5UmF3VmFsdWUsIHN0cmluZzJOdW1iZXIgfSBmcm9tICcuLi91dGlscy9oZWxwZXInO1xuaW1wb3J0IHsgaVBvbGxlbkRhdGEsIHJlbmRlclBvbGxlbiB9IGZyb20gJy4uL3RlbXBsYXRlcy90LXBvbGxlbic7XG5cbmNvbnN0IGJ1aWxkUG9sbGVuID0gKGhhc3M6IEhvbWVBc3Npc3RhbnQsIGxhbmc6IHN0cmluZywgcG9sbGVuOiBpUG9sbGVuKSA9PiB7XG4gIGNvbnN0IGFsbEl0ZW1zOiBpUG9sbGVuRGF0YVtdID0gW107XG4gIGlmIChBcnJheS5pc0FycmF5KHBvbGxlbi5lbnRpdGllcykgJiYgcG9sbGVuLmVudGl0aWVzLmxlbmd0aCA+IDApIHtcbiAgICBwb2xsZW4uZW50aXRpZXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgY29uc3QgcmF3dmFsdWUgPSBnZXRFbnRpdHlSYXdWYWx1ZShoYXNzLCBpdGVtLmVudGl0eSk7XG4gICAgICBpZiAocmF3dmFsdWUgJiYgcmF3dmFsdWUgIT09ICd1bmtub3duJyAmJiByYXd2YWx1ZSAhPT0gJ3VuYXZhaWxhYmxlJykge1xuICAgICAgICBsZXQgdmFsdWU6IG51bWJlciA9IHN0cmluZzJOdW1iZXIoZ2V0RW50aXR5UmF3VmFsdWUoaGFzcywgaXRlbS5lbnRpdHkpKTtcblxuICAgICAgICBpZiAoTnVtYmVyLmlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA8IHBvbGxlbi5taW4gfHwgdmFsdWUgPiBwb2xsZW4ubWF4KSB7XG4gICAgICAgICAgdmFsdWUgPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgYWxsSXRlbXMucHVzaCh7XG4gICAgICAgICAgbmFtZTogaXRlbS5uYW1lLFxuICAgICAgICAgIHZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIC8vIGNvbnNvbGUubG9nKGBOb21lOiAke2l0ZW0ubmFtZX0sIEVudGl0w6A6ICR7aXRlbS5lbnRpdHl9YCk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcmVuZGVyUG9sbGVuKGFsbEl0ZW1zLCBwb2xsZW4ubWluLCBwb2xsZW4ubWF4KTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGJ1aWxkUG9sbGVuO1xuIiwiLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG5pbXBvcnQgeyBodG1sIH0gZnJvbSAnbGl0JztcblxuZXhwb3J0IGludGVyZmFjZSBpRm9yZWNhc3REYXRhSXRlbSB7XG4gIHZhbHVlPzogbnVtYmVyIHwgc3RyaW5nIHwgRGF0ZTtcbiAgdW5pdD86IHN0cmluZztcbiAgaW1nPzogc3RyaW5nO1xuICBpY29uPzogc3RyaW5nO1xuICBpY29uQ29sb3I/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjb25zdCByZW5kZXJXZWF0aGVyRm9yZWNhc3QgPSAoZm9yZWNhc3RUeXBlOiBudW1iZXIsIGRhdGE6IFJlY29yZDxzdHJpbmcsIGlGb3JlY2FzdERhdGFJdGVtPltdKSA9PiB7XG4gIGNvbnN0IHJvd3MgPSBkYXRhLm1hcCgoZGF5RGF0YSkgPT4ge1xuICAgIGNvbnN0IGRheSA9IGRheURhdGEucmVmZXJlbmNlPy52YWx1ZTtcbiAgICBjb25zdCBpbWcgPSBkYXlEYXRhLmNvbmRpdGlvbj8uaW1nO1xuICAgIGNvbnN0IGljb24gPSBkYXlEYXRhLmNvbmRpdGlvbj8uaWNvbjtcbiAgICBjb25zdCBpY29uQ29sb3IgPSBkYXlEYXRhLmNvbmRpdGlvbj8uaWNvbkNvbG9yO1xuICAgIGNvbnN0IHRlbXBMb3cgPSBkYXlEYXRhLnRlbXBlcmF0dXJlX2xvdz8udmFsdWU7XG4gICAgY29uc3QgdGVtcEhpZ2ggPSBkYXlEYXRhLnRlbXBlcmF0dXJlX2hpZ2g/LnZhbHVlO1xuICAgIGNvbnN0IHRlbXBITFVuaXQgPSBkYXlEYXRhLnRlbXBlcmF0dXJlX2hpZ2g/LnVuaXQgfHwgZGF5RGF0YS50ZW1wZXJhdHVyZV9sb3c/LnVuaXQ7XG4gICAgY29uc3QgcHJlY2lwUHJvYjogbnVtYmVyID0gTnVtYmVyKGRheURhdGEucHJlY2lwaXRhdGlvbl9wcm9iYWJpbGl0eT8udmFsdWUgPz8gMCk7XG4gICAgY29uc3QgcHJlY2lwSW50ID0gZGF5RGF0YS5wcmVjaXBpdGF0aW9uX2ludGVuc2l0eT8udmFsdWU7XG4gICAgY29uc3QgcHJlY2lwVW5pdCA9IGRheURhdGEucHJlY2lwaXRhdGlvbl9pbnRlbnNpdHk/LnVuaXQ7XG5cbiAgICBjb25zdCB0ZW1wID0gZGF5RGF0YS50ZW1wZXJhdHVyZT8udmFsdWU7XG4gICAgY29uc3QgdGVtcFVuaXQgPSBkYXlEYXRhLnRlbXBlcmF0dXJlPy51bml0IHx8IGRheURhdGEudGVtcGVyYXR1cmVfZmVlbHNsaWtlPy51bml0O1xuICAgIGNvbnN0IHRlbXBfZmVlbHNsaWtlID0gZGF5RGF0YS50ZW1wZXJhdHVyZV9mZWVsc2xpa2U/LnZhbHVlO1xuICAgIGNvbnN0IHdpbmRfc3BlZWQgPSBkYXlEYXRhLndpbmRfc3BlZWQ/LnZhbHVlO1xuICAgIGNvbnN0IHdpbmRfc3BlZWRVbml0ID0gZGF5RGF0YS53aW5kX3NwZWVkPy51bml0O1xuICAgIGNvbnN0IHdpbmRfYmVhcmluZyA9IGRheURhdGEud2luZF9iZWFyaW5nPy52YWx1ZTtcblxuICAgIGNvbnN0IHdpbmRfd2F2ZV9oZWlnaHRfbWF4ID0gZGF5RGF0YS53aW5kX3dhdmVfaGVpZ2h0X21heD8udmFsdWU7XG4gICAgY29uc3Qgc3dlbGxfd2F2ZV9oZWlnaHRfbWF4ID0gZGF5RGF0YS5zd2VsbF93YXZlX2hlaWdodF9tYXg/LnZhbHVlO1xuICAgIGNvbnN0IHdhdmVfaGVpZ2h0X21heCA9IGRheURhdGEud2F2ZV9oZWlnaHRfbWF4Py52YWx1ZTtcbiAgICBjb25zdCB3YXZlX2RpcmVjdGlvbiA9IGRheURhdGEud2F2ZV9kaXJlY3Rpb24/LnZhbHVlO1xuICAgIGNvbnN0IHdhdmVfZGlyZWN0aW9uX2RlZ3JlZXMgPSBkYXlEYXRhLndhdmVfZGlyZWN0aW9uPy5pY29uO1xuICAgIGNvbnN0IHdhdmVfaGVpZ2h0X21heF91bml0ID0gZGF5RGF0YS53YXZlX2hlaWdodF9tYXg/LnVuaXQ7XG5cbiAgICByZXR1cm4gaHRtbGBcbiAgICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLWZvcmVjYXN0LXNsb3RcIj5cbiAgICAgICAgJHtkYXkgPyBodG1sYDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLWZvcmVjYXN0LWxhYmVsLXNsb3RcIj4ke2RheX08L2Rpdj5gIDogJyd9XG4gICAgICAgICR7aW1nID8gaHRtbGA8aW1nIGNsYXNzPVwid2VhdGhlci1mb3JlY2FzdC1pY29uXCIgc3JjPVwiJHtpbWd9XCIgYWx0PVwiJHtpbWd9XCIgLz5gIDogJyd9XG4gICAgICAgICR7aWNvbiA/IGh0bWxgPGhhLWljb24gaWNvbj1cIiR7aWNvbn1cIiBzdHlsZT0ke2ljb25Db2xvciA/IGBjb2xvcjogJHtpY29uQ29sb3J9YCA6ICcnfT48L2hhLWljb24+YCA6ICcnfVxuICAgICAgICAke1xuICB0ZW1wTG93ICE9PSB1bmRlZmluZWQgJiYgdGVtcEhpZ2ggIT09IHVuZGVmaW5lZFxuICAgID8gaHRtbGBcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1mb3JlY2FzdC10ZW1wZXJhdHVyZVwiPlxuICAgICAgICAgICAgICAgICAgJHt0ZW1wTG93fSAvIDxzcGFuIGNsYXNzPVwiaGlnaFwiPiR7dGVtcEhpZ2h9JHt0ZW1wSExVbml0ID8gYCAke3RlbXBITFVuaXR9YCA6ICcnfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgYFxuICAgIDogJydcbn1cbiAgICAgICAgJHtcbiAgdGVtcCAhPT0gdW5kZWZpbmVkICYmIHRlbXBfZmVlbHNsaWtlICE9PSB1bmRlZmluZWRcbiAgICA/IGh0bWxgXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItZm9yZWNhc3QtdGVtcGVyYXR1cmVcIj5cbiAgICAgICAgICAgICAgICAgICR7dGVtcH0gLyA8c3BhbiBjbGFzcz1cImhpZ2hcIj4ke3RlbXBfZmVlbHNsaWtlfSR7dGVtcFVuaXQgPyBgICR7dGVtcFVuaXR9YCA6ICcnfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgYFxuICAgIDogJydcbn1cbiAgICAgICAgJHtcbiAgd2luZF9zcGVlZCAhPT0gdW5kZWZpbmVkICYmIHdpbmRfYmVhcmluZyAhPT0gdW5kZWZpbmVkXG4gICAgPyBodG1sYFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLWZvcmVjYXN0LXRlbXBlcmF0dXJlXCI+XG4gICAgICAgICAgICAgICAgICAke3dpbmRfc3BlZWR9ICR7d2luZF9zcGVlZFVuaXR9ICR7d2luZF9iZWFyaW5nfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgYFxuICAgIDogJydcbn1cbiAgICAgICAgJHtcbiAgd2F2ZV9oZWlnaHRfbWF4ICE9PSB1bmRlZmluZWRcbiAgICA/IGh0bWxgXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItZm9yZWNhc3QtdGVtcGVyYXR1cmVcIj5cbiAgICAgICAgICAgICAgICAgICR7d2F2ZV9oZWlnaHRfbWF4fSAke3dhdmVfaGVpZ2h0X21heF91bml0ID8gYCAke3dhdmVfaGVpZ2h0X21heF91bml0fWAgOiAnJ31cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgYFxuICAgIDogJydcbn1cbiAgICAgICAgJHtcbiAgd2F2ZV9kaXJlY3Rpb24gIT09IHVuZGVmaW5lZFxuICAgID8gaHRtbGBcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1mb3JlY2FzdC10ZW1wZXJhdHVyZVwiPlxuICAgICAgICAgICAgICAgICAgJHt3YXZlX2RpcmVjdGlvbl9kZWdyZWVzID8gaHRtbGA8aGEtaWNvblxuICAgICAgICAgICAgICAgICAgICAgICAgaWNvbj1cIm1kaTphcnJvdy11cC10aGluXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPVwiZGlzcGxheTppbmxpbmUtYmxvY2s7IHRyYW5zZm9ybTogcm90YXRlKCR7d2F2ZV9kaXJlY3Rpb25fZGVncmVlc31kZWcpO1wiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvaGEtaWNvbj5gIDogJyd9ICR7d2F2ZV9kaXJlY3Rpb259XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIGBcbiAgICA6ICcnXG59XG4gICAgICAgICR7XG4gIHdpbmRfd2F2ZV9oZWlnaHRfbWF4ICE9PSB1bmRlZmluZWQgJiYgc3dlbGxfd2F2ZV9oZWlnaHRfbWF4ICE9PSB1bmRlZmluZWRcbiAgICA/IGh0bWxgXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItZm9yZWNhc3QtdGVtcGVyYXR1cmVcIj5cbiAgICAgICAgICAgICAgICAgICR7c3dlbGxfd2F2ZV9oZWlnaHRfbWF4fSAvICR7d2luZF93YXZlX2hlaWdodF9tYXh9ICR7d2F2ZV9oZWlnaHRfbWF4X3VuaXQgPyBgICR7d2F2ZV9oZWlnaHRfbWF4X3VuaXR9YCA6ICcnfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBgXG4gICAgOiAnJ1xufVxuICAgICAgICAke1xuICBwcmVjaXBQcm9iICE9PSB1bmRlZmluZWQgJiYgcHJlY2lwSW50ICE9PSB1bmRlZmluZWQgJiYgcHJlY2lwUHJvYiAhPT0gMFxuICAgID8gaHRtbGBcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1mb3JlY2FzdC1wcmVjaXBpdGF0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAke3ByZWNpcFByb2J9ICUgLyA8c3BhbiBjbGFzcz1cIm1tXCI+JHtwcmVjaXBJbnR9JHtwcmVjaXBVbml0ID8gYCAke3ByZWNpcFVuaXR9YCA6ICcnfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgYFxuICAgIDogJydcbn1cbiAgICAgIDwvZGl2PlxuICAgIGA7XG4gIH0pO1xuXG4gIGxldCB0aXRsZSA9ICdEYWlseSc7XG4gIGlmIChmb3JlY2FzdFR5cGUgPT09IDEpIHtcbiAgICB0aXRsZSA9ICdIb3VybHknO1xuICB9IGVsc2UgaWYgKGZvcmVjYXN0VHlwZSA9PT0gMikge1xuICAgIHRpdGxlID0gJ01hcmluZSBkYWlseSc7XG4gIH0gZWxzZSBpZiAoZm9yZWNhc3RUeXBlID09PSAzKSB7XG4gICAgdGl0bGUgPSAnTWFyaW5lIGhvdXJseSc7XG4gIH1cblxuICByZXR1cm4gaHRtbGBcbiAgPGRpdiBjbGFzcz1cIndlYXRoZXItZm9yZWNhc3QtZ3JpZC13cmFwcGVyXCI+XG4gICAgPGRpdiBjbGFzcz1cIndlYXRoZXItZm9yZWNhc3QtdGl0bGVcIj4ke3RpdGxlfSBmb3JlY2FzdDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLWZvcmVjYXN0LWdyaWQtY29udGFpbmVyXCI+XG4gICAgICAke3Jvd3N9XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuICBgO1xufTtcbiIsImltcG9ydCB7IEhvbWVBc3Npc3RhbnQgfSBmcm9tICdjdXN0b20tY2FyZC1oZWxwZXJzL2Rpc3QnO1xuaW1wb3J0IHsgZ2V0V2VhdGhlckljb24gfSBmcm9tICcuLi91dGlscy9oZWxwZXItcmVuZGVyJztcbmltcG9ydCB7IGlJY29uc0NvbmZpZywgaVRlcm1zIH0gZnJvbSAnLi4vYmFzZS9sb3ZlbGFjZS1iYXNlJztcbmltcG9ydCB7XG4gIGdldEVudGl0eUljb24sXG4gIGdldEVudGl0eU51bWVyaWNWYWx1ZSxcbiAgZ2V0RW50aXR5UmF3QXR0cmlidXRlLFxuICBnZXRFbnRpdHlSYXdWYWx1ZSxcbiAgZ2V0RW50aXR5VW5pdCxcbiAgZ2V0TG9jYWxlSW5mbyxcbiAgZ2V0V2luZERpcmVjdGlvbnMsXG59IGZyb20gJy4uL3V0aWxzL2hlbHBlcic7XG5pbXBvcnQgeyBpY29uUHJlY2lwaXRhdGlvbiwgaWNvblRlbXBlcmF0dXJlIH0gZnJvbSAnLi4vdXRpbHMvY29uc3QnO1xuaW1wb3J0IHsgaUZvcmVjYXN0RGF0YUl0ZW0sIHJlbmRlcldlYXRoZXJGb3JlY2FzdCB9IGZyb20gJy4uL3RlbXBsYXRlcy90LXdlYXRoZXItZm9yZWNhc3QnO1xuaW1wb3J0IHtcbiAgaURhaWx5Rm9yZWNhc3QsXG4gIGlIb3VybHlGb3JlY2FzdCxcbiAgaU1hcmluZURhaWx5Rm9yZWNhc3QsXG4gIGlNYXJpbmVIb3VybHlGb3JlY2FzdCxcbn0gZnJvbSAnLi4vdXRpbHMvY29uZmlnLXNjaGVtYSc7XG5cbmNvbnN0IGdldERlZmF1bHRJY29uID0gKG1ldHJpYzogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgaWYgKG1ldHJpYy5pbmNsdWRlcygndGVtcGVyYXR1cmUnKSkgcmV0dXJuIGljb25UZW1wZXJhdHVyZTtcbiAgaWYgKG1ldHJpYy5pbmNsdWRlcygncHJlY2lwaXRhdGlvbicpKSByZXR1cm4gaWNvblByZWNpcGl0YXRpb247XG4gIHJldHVybiAnbWRpOmhlbHAtY2lyY2xlLW91dGxpbmUnO1xufTtcblxuY29uc3QgYnVpbGRIb3VybHlGb3JlY2FzdFNsb3QgPSAoXG4gIGhhc3M6IEhvbWVBc3Npc3RhbnQsXG4gIGxhbmc6IHN0cmluZyxcbiAgY3djTG9jV2luZERpcmVjdGlvbnMsXG4gIGZvcmVjYXN0OiBpSG91cmx5Rm9yZWNhc3QsXG4gIGZvcmVjYXN0VHlwZTogbnVtYmVyLFxuICBpY29uc0NvbmZpZzogaUljb25zQ29uZmlnLFxuICBzdW5TdGF0ZTogc3RyaW5nLFxuICBzbG90SWQ6IHN0cmluZyxcbikgPT4ge1xuICBjb25zdCByZWNvcmQ6IFJlY29yZDxzdHJpbmcsIGlGb3JlY2FzdERhdGFJdGVtPiA9IHt9O1xuICBjb25zdCBsb2NhbGVJbmZvID0gZ2V0TG9jYWxlSW5mbyhsYW5nKTtcblxuICBsZXQgZGF0ZXRpbWU6IERhdGU7XG5cbiAgLy8gQ29uZGl6aW9uZSBtZXRlb1xuICBpZiAoZm9yZWNhc3QuY29uZGl0aW9uICYmIGZvcmVjYXN0LmNvbmRpdGlvbltzbG90SWRdKSB7XG4gICAgcmVjb3JkWydjb25kaXRpb24nXSA9IHtcbiAgICAgIGltZzogZ2V0V2VhdGhlckljb24oZ2V0RW50aXR5UmF3VmFsdWUoaGFzcywgZm9yZWNhc3QuY29uZGl0aW9uW3Nsb3RJZF0pLCBpY29uc0NvbmZpZywgc3VuU3RhdGUpLFxuICAgIH07XG4gIH1cblxuICAvLyBXaW5kIEJlYXJpbmdcbiAgaWYgKGZvcmVjYXN0LndpbmRfYmVhcmluZyAmJiBmb3JlY2FzdC53aW5kX2JlYXJpbmdbc2xvdElkXSkge1xuICAgIHJlY29yZFsnd2luZF9iZWFyaW5nJ10gPSB7XG4gICAgICB2YWx1ZTogZ2V0V2luZERpcmVjdGlvbnMoZ2V0RW50aXR5UmF3VmFsdWUoaGFzcywgZm9yZWNhc3Qud2luZF9iZWFyaW5nW3Nsb3RJZF0pLCBjd2NMb2NXaW5kRGlyZWN0aW9ucyksXG4gICAgfTtcbiAgfVxuICAgXG4gIC8vIE1ldHJpY2hlIGRhIGdlc3RpcmVcbiAgY29uc3QgbWV0cmljcyA9IFtcbiAgICAndGVtcGVyYXR1cmUnLFxuICAgICd0ZW1wZXJhdHVyZV9mZWVsc2xpa2UnLFxuICAgICdwcmVjaXBpdGF0aW9uX2ludGVuc2l0eScsXG4gICAgJ3ByZWNpcGl0YXRpb25fcHJvYmFiaWxpdHknLFxuICAgICd3aW5kX3NwZWVkJyxcbiAgXTtcblxuICBtZXRyaWNzLmZvckVhY2goKG1ldHJpY0tleSkgPT4ge1xuICAgIGNvbnN0IG1ldHJpY1Nsb3RzID0gZm9yZWNhc3RbbWV0cmljS2V5XTtcbiAgICBjb25zdCBlbnRpdHlJZCA9IG1ldHJpY1Nsb3RzPy5bc2xvdElkXTtcbiAgICBsZXQgZGVjaW1hbHMgPSAwO1xuXG4gICAgaWYgKCFlbnRpdHlJZCkgcmV0dXJuO1xuXG4gICAgaWYgKG1ldHJpY0tleSA9PT0gJ3ByZWNpcGl0YXRpb25faW50ZW5zaXR5JykgZGVjaW1hbHMgPSAyO1xuXG4gICAgZGF0ZXRpbWUgPSBuZXcgRGF0ZShnZXRFbnRpdHlSYXdBdHRyaWJ1dGUoaGFzcywgZW50aXR5SWQsICdkYXRldGltZScpKTtcblxuICAgIHJlY29yZFttZXRyaWNLZXldID0ge1xuICAgICAgdmFsdWU6IGdldEVudGl0eU51bWVyaWNWYWx1ZSh7XG4gICAgICAgIGVudGl0eUlkLCBoYXNzLCBsYW5nLCBkZWNpbWFscyxcbiAgICAgIH0pLFxuICAgICAgdW5pdDogZ2V0RW50aXR5VW5pdChoYXNzLCBlbnRpdHlJZCksXG4gICAgICBpbWc6IGdldEVudGl0eUljb24oaGFzcywgZW50aXR5SWQpIHx8IGdldERlZmF1bHRJY29uKG1ldHJpY0tleSksXG4gICAgfTtcbiAgfSk7XG5cbiAgaWYgKGRhdGV0aW1lICYmIE9iamVjdC5rZXlzKHJlY29yZCkubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IGhvdXJUaW1lID0gZGF0ZXRpbWUudG9Mb2NhbGVUaW1lU3RyaW5nKGxvY2FsZUluZm8ubG9jYWxlLCB7XG4gICAgICBob3VyOiAnMi1kaWdpdCcsXG4gICAgICBtaW51dGU6ICcyLWRpZ2l0JyxcbiAgICAgIHRpbWVab25lOiBsb2NhbGVJbmZvLnRpbWV6b25lLFxuICAgIH0pO1xuXG4gICAgcmVjb3JkWydyZWZlcmVuY2UnXSA9IHtcbiAgICAgIHZhbHVlOiAoZm9yZWNhc3RUeXBlID09PSAwID8gaG91clRpbWUgOiBob3VyVGltZSksXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiByZWNvcmQ7XG59O1xuXG5jb25zdCBidWlsZERhaWx5Rm9yZWNhc3RTbG90ID0gKFxuICBoYXNzOiBIb21lQXNzaXN0YW50LFxuICBsYW5nOiBzdHJpbmcsXG4gIGZvcmVjYXN0OiBpRGFpbHlGb3JlY2FzdCxcbiAgZm9yZWNhc3RUeXBlOiBudW1iZXIsXG4gIGljb25zQ29uZmlnOiBpSWNvbnNDb25maWcsXG4gIHN1blN0YXRlOiBzdHJpbmcsXG4gIHNsb3RJZDogc3RyaW5nLFxuKSA9PiB7XG4gIGNvbnN0IHJlY29yZDogUmVjb3JkPHN0cmluZywgaUZvcmVjYXN0RGF0YUl0ZW0+ID0ge307XG4gIGNvbnN0IGxvY2FsZUluZm8gPSBnZXRMb2NhbGVJbmZvKGxhbmcpO1xuXG4gIGxldCBkYXRldGltZTogRGF0ZTtcblxuICAvLyBHZXN0aW9uZSBjb25kaXppb25lIG1ldGVvXG4gIGlmIChmb3JlY2FzdC5jb25kaXRpb24gJiYgZm9yZWNhc3QuY29uZGl0aW9uW3Nsb3RJZF0pIHtcbiAgICByZWNvcmRbJ2NvbmRpdGlvbiddID0ge1xuICAgICAgaW1nOiBnZXRXZWF0aGVySWNvbihnZXRFbnRpdHlSYXdWYWx1ZShoYXNzLCBmb3JlY2FzdC5jb25kaXRpb25bc2xvdElkXSksIGljb25zQ29uZmlnLCBzdW5TdGF0ZSksXG4gICAgfTtcbiAgfVxuXG4gIC8vIExpc3RhIGZpc3NhIGRlbGxlIG1ldHJpY2hlIGRhIGNvbnNpZGVyYXJlXG4gIGNvbnN0IG1ldHJpY3MgPSBbXG4gICAgJ3RlbXBlcmF0dXJlX2hpZ2gnLFxuICAgICd0ZW1wZXJhdHVyZV9sb3cnLFxuICAgICdwcmVjaXBpdGF0aW9uX2ludGVuc2l0eScsXG4gICAgJ3ByZWNpcGl0YXRpb25fcHJvYmFiaWxpdHknLFxuICBdO1xuXG4gIG1ldHJpY3MuZm9yRWFjaCgobWV0cmljS2V5KSA9PiB7XG4gICAgY29uc3QgbWV0cmljU2xvdHMgPSBmb3JlY2FzdFttZXRyaWNLZXldO1xuICAgIGNvbnN0IGVudGl0eUlkID0gbWV0cmljU2xvdHM/LltzbG90SWRdO1xuICAgIGxldCBkZWNpbWFscyA9IDA7XG5cbiAgICBpZiAoIWVudGl0eUlkKSByZXR1cm47XG5cbiAgICBpZiAobWV0cmljS2V5ID09PSAncHJlY2lwaXRhdGlvbl9pbnRlbnNpdHknKSB7XG4gICAgICBkZWNpbWFscyA9IDI7XG4gICAgfVxuXG4gICAgZGF0ZXRpbWUgPSBuZXcgRGF0ZShnZXRFbnRpdHlSYXdBdHRyaWJ1dGUoaGFzcywgZW50aXR5SWQsICdkYXRldGltZScpKTtcbiAgICAvLyBjb25zb2xlLmRlYnVnKGA+Pj4gJHtlbnRpdHlJZH0gJHtsYW5nfSAke2dldEVudGl0eU51bWVyaWNWYWx1ZSh7IGVudGl0eUlkLCBoYXNzLCBsYW5nIH0pfWApO1xuICAgIHJlY29yZFttZXRyaWNLZXldID0ge1xuICAgICAgdmFsdWU6IGdldEVudGl0eU51bWVyaWNWYWx1ZSh7XG4gICAgICAgIGVudGl0eUlkLCBoYXNzLCBsYW5nLCBkZWNpbWFscyxcbiAgICAgIH0pLFxuICAgICAgdW5pdDogZ2V0RW50aXR5VW5pdChoYXNzLCBlbnRpdHlJZCksXG4gICAgICBpbWc6IGdldEVudGl0eUljb24oaGFzcywgZW50aXR5SWQpIHx8IGdldERlZmF1bHRJY29uKG1ldHJpY0tleSksXG4gICAgfTtcbiAgfSk7XG5cbiAgaWYgKGRhdGV0aW1lICYmIE9iamVjdC5rZXlzKHJlY29yZCkubGVuZ3RoID4gMCkge1xuICAgIC8vIEdpb3JubyBkZWxsYSBzZXR0aW1hbmEgYWJicmV2aWF0byAoZXMuIFwiTHVuXCIpXG4gICAgY29uc3Qgd2Vla2RheSA9IGRhdGV0aW1lLnRvTG9jYWxlRGF0ZVN0cmluZyhsb2NhbGVJbmZvLmxvY2FsZSwge1xuICAgICAgd2Vla2RheTogJ3Nob3J0JyxcbiAgICAgIHRpbWVab25lOiAnVVRDJywgLy8gZm9yemEgbGEgbGV0dHVyYSBzZW56YSBjb252ZXJzaW9uZSBsb2NhbGVcbiAgICB9KTtcblxuICAgIC8vIE9yYSBlIG1pbnV0aSAoZXMuIFwiMTM6NDVcIilcbiAgICBjb25zdCBob3VyZGF5ID0gZGF0ZXRpbWUudG9Mb2NhbGVUaW1lU3RyaW5nKGxvY2FsZUluZm8ubG9jYWxlLCB7XG4gICAgICBob3VyOiAnMi1kaWdpdCcsXG4gICAgICBtaW51dGU6ICcyLWRpZ2l0JyxcbiAgICAgIHRpbWVab25lOiBsb2NhbGVJbmZvLnRpbWV6b25lLFxuICAgIH0pO1xuXG4gICAgcmVjb3JkWydyZWZlcmVuY2UnXSA9IHtcbiAgICAgIHZhbHVlOiAoZm9yZWNhc3RUeXBlID09PSAwID8gd2Vla2RheS50b1VwcGVyQ2FzZSgpIDogaG91cmRheSksXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiByZWNvcmQ7XG59O1xuXG5jb25zdCBidWlsZE1hcmluZURhaWx5Rm9yZWNhc3RTbG90ID0gKFxuICBoYXNzOiBIb21lQXNzaXN0YW50LFxuICBsYW5nOiBzdHJpbmcsXG4gIGN3Y0xvY1dpbmREaXJlY3Rpb25zLFxuICBmb3JlY2FzdDogaU1hcmluZURhaWx5Rm9yZWNhc3QsXG4gIGZvcmVjYXN0VHlwZTogbnVtYmVyLFxuICBpY29uc0NvbmZpZzogaUljb25zQ29uZmlnLFxuICBzdW5TdGF0ZTogc3RyaW5nLFxuICBzbG90SWQ6IHN0cmluZyxcbikgPT4ge1xuICBjb25zdCByZWNvcmQ6IFJlY29yZDxzdHJpbmcsIGlGb3JlY2FzdERhdGFJdGVtPiA9IHt9O1xuXG4gIGNvbnN0IGZpZWxkQ29sb3IgPSAoXG4gICAgd2F2ZUhlaWdodE1heDogbnVtYmVyLFxuICAgIHN3ZWxsV2F2ZUhlaWdodE1heDogbnVtYmVyLFxuICAgIHdpbmRXYXZlSGVpZ2h0TWF4OiBudW1iZXIsXG4gICkgPT4ge1xuICAgIC8vIPCfn6UgQmFuZGllcmEgcm9zc2Eg4oCTIGNvbmRpemlvbmkgcGVyaWNvbG9zZVxuICAgIGlmICh3YXZlSGVpZ2h0TWF4ID49IDEuOCkge1xuICAgICAgcmV0dXJuICdyZWQnO1xuICAgIH1cblxuICAgIGlmIChzd2VsbFdhdmVIZWlnaHRNYXggPj0gMS41ICYmIHdpbmRXYXZlSGVpZ2h0TWF4ID49IDAuOCkge1xuICAgICAgcmV0dXJuICdyZWQnO1xuICAgIH1cblxuICAgIC8vIPCfn6ggQmFuZGllcmEgZ2lhbGxhIOKAkyBjb25kaXppb25pIGRhIGF0dGVuemlvbmFyZVxuICAgIGlmICh3YXZlSGVpZ2h0TWF4ID49IDEuMCkge1xuICAgICAgcmV0dXJuICd5ZWxsb3cnO1xuICAgIH1cblxuICAgIGlmIChzd2VsbFdhdmVIZWlnaHRNYXggPj0gMC44KSB7XG4gICAgICByZXR1cm4gJ3llbGxvdyc7XG4gICAgfVxuXG4gICAgaWYgKHdpbmRXYXZlSGVpZ2h0TWF4ID49IDAuNikge1xuICAgICAgcmV0dXJuICd5ZWxsb3cnO1xuICAgIH1cblxuICAgIC8vIPCfn6kgQmFuZGllcmEgdmVyZGUg4oCTIGNvbmRpemlvbmkgc2ljdXJlXG4gICAgcmV0dXJuICdncmVlbic7XG4gIH07XG5cbiAgY29uc3QgbG9jYWxlSW5mbyA9IGdldExvY2FsZUluZm8obGFuZyk7XG5cbiAgbGV0IGRhdGV0aW1lOiBEYXRlO1xuXG4gIC8vIEdlc3Rpb25lIGNvbmRpemlvbmUgbWV0ZW9cbiAgaWYgKFxuICAgIGZvcmVjYXN0LndhdmVfaGVpZ2h0X21heCAmJlxuICAgIGZvcmVjYXN0LnN3ZWxsX3dhdmVfaGVpZ2h0X21heCAmJlxuICAgIGZvcmVjYXN0LndpbmRfd2F2ZV9oZWlnaHRfbWF4ICYmXG4gICAgZm9yZWNhc3Quc3dlbGxfd2F2ZV9oZWlnaHRfbWF4W3Nsb3RJZF0gJiZcbiAgICBmb3JlY2FzdC53aW5kX3dhdmVfaGVpZ2h0X21heFtzbG90SWRdXG4gICkge1xuICAgIHJlY29yZFsnY29uZGl0aW9uJ10gPSB7XG4gICAgICBpY29uOiAnbWRpOmZsYWctdmFyaWFudCcsXG4gICAgICBpY29uQ29sb3I6IGZpZWxkQ29sb3IoZm9yZWNhc3Qud2F2ZV9oZWlnaHRfbWF4W3Nsb3RJZF0sIGZvcmVjYXN0LnN3ZWxsX3dhdmVfaGVpZ2h0X21heFtzbG90SWRdLCBmb3JlY2FzdC53aW5kX3dhdmVfaGVpZ2h0X21heFtzbG90SWRdKSxcbiAgICB9O1xuICB9XG5cbiAgLy8gV2luZCBCZWFyaW5nXG4gIGlmIChmb3JlY2FzdC53YXZlX2RpcmVjdGlvbiAmJiBmb3JlY2FzdC53YXZlX2RpcmVjdGlvbltzbG90SWRdKSB7XG4gICAgcmVjb3JkWyd3YXZlX2RpcmVjdGlvbiddID0ge1xuICAgICAgdmFsdWU6IGdldFdpbmREaXJlY3Rpb25zKGdldEVudGl0eVJhd1ZhbHVlKGhhc3MsIGZvcmVjYXN0LndhdmVfZGlyZWN0aW9uW3Nsb3RJZF0pLCBjd2NMb2NXaW5kRGlyZWN0aW9ucyksXG4gICAgICBpY29uOiBnZXRFbnRpdHlSYXdWYWx1ZShoYXNzLCBmb3JlY2FzdC53YXZlX2RpcmVjdGlvbltzbG90SWRdKSxcbiAgICB9O1xuICB9XG5cbiAgLy8gTGlzdGEgZmlzc2EgZGVsbGUgbWV0cmljaGUgZGEgY29uc2lkZXJhcmVcbiAgY29uc3QgbWV0cmljcyA9IFtcbiAgICAnd2F2ZV9oZWlnaHRfbWF4JyxcbiAgICAnc3dlbGxfd2F2ZV9oZWlnaHRfbWF4JyxcbiAgICAnd2luZF93YXZlX2hlaWdodF9tYXgnLFxuICBdO1xuXG4gIG1ldHJpY3MuZm9yRWFjaCgobWV0cmljS2V5KSA9PiB7XG4gICAgY29uc3QgbWV0cmljU2xvdHMgPSBmb3JlY2FzdFttZXRyaWNLZXldO1xuICAgIGNvbnN0IGVudGl0eUlkID0gbWV0cmljU2xvdHM/LltzbG90SWRdO1xuICAgIGNvbnN0IGRlY2ltYWxzID0gMTtcblxuICAgIGlmICghZW50aXR5SWQpIHJldHVybjtcblxuICAgIGRhdGV0aW1lID0gbmV3IERhdGUoZ2V0RW50aXR5UmF3QXR0cmlidXRlKGhhc3MsIGVudGl0eUlkLCAnZGF0ZXRpbWUnKSk7XG4gICAgLy8gY29uc29sZS5kZWJ1ZyhgPj4+ICR7ZW50aXR5SWR9ICR7bGFuZ30gJHtnZXRFbnRpdHlOdW1lcmljVmFsdWUoeyBlbnRpdHlJZCwgaGFzcywgbGFuZyB9KX1gKTtcbiAgICByZWNvcmRbbWV0cmljS2V5XSA9IHtcbiAgICAgIHZhbHVlOiBnZXRFbnRpdHlOdW1lcmljVmFsdWUoe1xuICAgICAgICBlbnRpdHlJZCwgaGFzcywgbGFuZywgZGVjaW1hbHMsXG4gICAgICB9KSxcbiAgICAgIHVuaXQ6IGdldEVudGl0eVVuaXQoaGFzcywgZW50aXR5SWQpLFxuICAgICAgaW1nOiBnZXRFbnRpdHlJY29uKGhhc3MsIGVudGl0eUlkKSB8fCBnZXREZWZhdWx0SWNvbihtZXRyaWNLZXkpLFxuICAgIH07XG4gIH0pO1xuXG4gIGlmIChkYXRldGltZSAmJiBPYmplY3Qua2V5cyhyZWNvcmQpLmxlbmd0aCA+IDApIHtcbiAgICAvLyBHaW9ybm8gZGVsbGEgc2V0dGltYW5hIGFiYnJldmlhdG8gKGVzLiBcIkx1blwiKVxuICAgIGNvbnN0IHdlZWtkYXkgPSBkYXRldGltZS50b0xvY2FsZURhdGVTdHJpbmcobG9jYWxlSW5mby5sb2NhbGUsIHtcbiAgICAgIHdlZWtkYXk6ICdzaG9ydCcsXG4gICAgICB0aW1lWm9uZTogJ1VUQycsIC8vIGZvcnphIGxhIGxldHR1cmEgc2VuemEgY29udmVyc2lvbmUgbG9jYWxlXG4gICAgfSk7XG5cbiAgICAvLyBPcmEgZSBtaW51dGkgKGVzLiBcIjEzOjQ1XCIpXG4gICAgY29uc3QgaG91cmRheSA9IGRhdGV0aW1lLnRvTG9jYWxlVGltZVN0cmluZyhsb2NhbGVJbmZvLmxvY2FsZSwge1xuICAgICAgaG91cjogJzItZGlnaXQnLFxuICAgICAgbWludXRlOiAnMi1kaWdpdCcsXG4gICAgICB0aW1lWm9uZTogbG9jYWxlSW5mby50aW1lem9uZSxcbiAgICB9KTtcblxuICAgIHJlY29yZFsncmVmZXJlbmNlJ10gPSB7XG4gICAgICB2YWx1ZTogKGZvcmVjYXN0VHlwZSA9PT0gMiA/IHdlZWtkYXkudG9VcHBlckNhc2UoKSA6IGhvdXJkYXkpLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gcmVjb3JkO1xufTtcblxuY29uc3QgYnVpbGRXZWF0aGVyRm9yZWNhc3QgPSAoXG4gIGhhc3M6IEhvbWVBc3Npc3RhbnQsXG4gIGxhbmc6IHN0cmluZyxcbiAgdGVybXM6IGlUZXJtcyxcbiAgZGFpbHlGb3JlY2FzdDogaURhaWx5Rm9yZWNhc3QsXG4gIGhvdXJseUZvcmVjYXN0OiBpSG91cmx5Rm9yZWNhc3QsXG4gIG1hcmluZURhaWx5Rm9yZWNhc3RzOiBpTWFyaW5lRGFpbHlGb3JlY2FzdCxcbiAgbWFyaW5lSG91cmx5Rm9yZWNhc3RzOiBpTWFyaW5lSG91cmx5Rm9yZWNhc3QsXG4gIGZvcmVjYXN0VHlwZTogKDAgfCAxIHwgMiB8IDMpLFxuICBpY29uc0NvbmZpZzogaUljb25zQ29uZmlnLFxuICBzdW5FbnRpdHlJZDogc3RyaW5nLFxuKSA9PiB7XG4gIGNvbnN0IHZvaWRSZWNvcmQ6IFJlY29yZDxzdHJpbmcsIGlGb3JlY2FzdERhdGFJdGVtPltdID0gW107XG4gIFxuICBjb25zdCBzdW5TdGF0ZSA9IGdldEVudGl0eVJhd1ZhbHVlKGhhc3MsIHN1bkVudGl0eUlkKTtcblxuICBsZXQgZGFpbHlGb3JlY2FzdERhdGEgPSB2b2lkUmVjb3JkO1xuICBpZiAoZGFpbHlGb3JlY2FzdCkge1xuICAgIGNvbnN0IGRhaWx5U2xvdElkcyA9IE9iamVjdC5rZXlzKFxuICAgICAgZGFpbHlGb3JlY2FzdC5jb25kaXRpb24gfHxcbiAgICAgIGRhaWx5Rm9yZWNhc3QudGVtcGVyYXR1cmVfaGlnaCB8fCBkYWlseUZvcmVjYXN0LnRlbXBlcmF0dXJlX2xvdyB8fFxuICAgICAgZGFpbHlGb3JlY2FzdC5wcmVjaXBpdGF0aW9uX2ludGVuc2l0eSB8fCBkYWlseUZvcmVjYXN0LnByZWNpcGl0YXRpb25fcHJvYmFiaWxpdHkgfHxcbiAgICAgIHt9LFxuICAgICk7XG4gICAgZGFpbHlGb3JlY2FzdERhdGEgPSBkYWlseVNsb3RJZHMubWFwKChzbG90SWQpID0+IGJ1aWxkRGFpbHlGb3JlY2FzdFNsb3QoXG4gICAgICBoYXNzLFxuICAgICAgbGFuZyxcbiAgICAgIGRhaWx5Rm9yZWNhc3QsXG4gICAgICBmb3JlY2FzdFR5cGUsXG4gICAgICBpY29uc0NvbmZpZyxcbiAgICAgIHN1blN0YXRlLFxuICAgICAgc2xvdElkLFxuICAgICkpO1xuICB9XG5cbiAgbGV0IGhvdXJseWZvcmVjYXN0RGF0YSA9IHZvaWRSZWNvcmQ7XG4gIGlmIChob3VybHlGb3JlY2FzdCkge1xuICAgIGNvbnN0IGhvdXJseVNsb3RJZHMgPSBPYmplY3Qua2V5cyhcbiAgICAgIGhvdXJseUZvcmVjYXN0LmNvbmRpdGlvbiB8fFxuICAgICAgaG91cmx5Rm9yZWNhc3QudGVtcGVyYXR1cmUgfHwgaG91cmx5Rm9yZWNhc3QudGVtcGVyYXR1cmVfZmVlbHNsaWtlIHx8XG4gICAgICBob3VybHlGb3JlY2FzdC5wcmVjaXBpdGF0aW9uX2ludGVuc2l0eSB8fCBob3VybHlGb3JlY2FzdC5wcmVjaXBpdGF0aW9uX3Byb2JhYmlsaXR5IHx8XG4gICAgICB7fSxcbiAgICApO1xuICAgIGhvdXJseWZvcmVjYXN0RGF0YSA9IGhvdXJseVNsb3RJZHMubWFwKChzbG90SWQpID0+IGJ1aWxkSG91cmx5Rm9yZWNhc3RTbG90KFxuICAgICAgaGFzcyxcbiAgICAgIGxhbmcsXG4gICAgICB0ZXJtcy53aW5kRGlyZWN0aW9ucyxcbiAgICAgIGhvdXJseUZvcmVjYXN0LFxuICAgICAgZm9yZWNhc3RUeXBlLFxuICAgICAgaWNvbnNDb25maWcsXG4gICAgICBzdW5TdGF0ZSxcbiAgICAgIHNsb3RJZCxcbiAgICApKTtcbiAgfVxuXG4gIGxldCBtYXJpbmVEYWlseUZvcmVjYXN0RGF0YSA9IHZvaWRSZWNvcmQ7XG4gIGlmIChtYXJpbmVEYWlseUZvcmVjYXN0cykge1xuICAgIGNvbnN0IG1hcmluZURhaWx5U2xvdElkcyA9IE9iamVjdC5rZXlzKFxuICAgICAgbWFyaW5lRGFpbHlGb3JlY2FzdHMuc3dlbGxfd2F2ZV9oZWlnaHRfbWF4IHx8XG4gICAgICBtYXJpbmVEYWlseUZvcmVjYXN0cy53YXZlX2RpcmVjdGlvbiB8fCBtYXJpbmVEYWlseUZvcmVjYXN0cy53YXZlX2hlaWdodF9tYXggfHxcbiAgICAgIG1hcmluZURhaWx5Rm9yZWNhc3RzLndpbmRfd2F2ZV9oZWlnaHRfbWF4IHx8XG4gICAgICB7fSxcbiAgICApO1xuICAgIG1hcmluZURhaWx5Rm9yZWNhc3REYXRhID0gbWFyaW5lRGFpbHlTbG90SWRzLm1hcCgoc2xvdElkKSA9PiBidWlsZE1hcmluZURhaWx5Rm9yZWNhc3RTbG90KFxuICAgICAgaGFzcyxcbiAgICAgIGxhbmcsXG4gICAgICB0ZXJtcy53aW5kRGlyZWN0aW9ucyxcbiAgICAgIG1hcmluZURhaWx5Rm9yZWNhc3RzLFxuICAgICAgZm9yZWNhc3RUeXBlLFxuICAgICAgaWNvbnNDb25maWcsXG4gICAgICBzdW5TdGF0ZSxcbiAgICAgIHNsb3RJZCxcbiAgICApKTtcbiAgfVxuXG4gIHN3aXRjaCAoZm9yZWNhc3RUeXBlKSB7XG4gICAgY2FzZSAwOlxuICAgICAgcmV0dXJuIHJlbmRlcldlYXRoZXJGb3JlY2FzdChmb3JlY2FzdFR5cGUsIGRhaWx5Rm9yZWNhc3REYXRhKTtcbiAgICBjYXNlIDE6XG4gICAgICByZXR1cm4gcmVuZGVyV2VhdGhlckZvcmVjYXN0KGZvcmVjYXN0VHlwZSwgaG91cmx5Zm9yZWNhc3REYXRhKTtcbiAgICBjYXNlIDI6XG4gICAgICByZXR1cm4gcmVuZGVyV2VhdGhlckZvcmVjYXN0KGZvcmVjYXN0VHlwZSwgbWFyaW5lRGFpbHlGb3JlY2FzdERhdGEpO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gcmVuZGVyV2VhdGhlckZvcmVjYXN0KGZvcmVjYXN0VHlwZSwgdm9pZFJlY29yZCk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IGJ1aWxkV2VhdGhlckZvcmVjYXN0O1xuIiwiaW1wb3J0IHsgSG9tZUFzc2lzdGFudCB9IGZyb20gJ2N1c3RvbS1jYXJkLWhlbHBlcnMvZGlzdCc7XG5pbXBvcnQgeyBpVGVybXMgfSBmcm9tICcuLi9iYXNlL2xvdmVsYWNlLWJhc2UnO1xuaW1wb3J0IHJlbmRlckNhbWVyYSBmcm9tICcuLi90ZW1wbGF0ZXMvdC1jYW1lcmEnO1xuXG5jb25zdCBidWlsZENhbWVyYSA9IChcbiAgaGFzczogSG9tZUFzc2lzdGFudCxcbiAgbGFuZzogc3RyaW5nLFxuICB0ZXJtczogaVRlcm1zLFxuICBoYW5kbGVQb3B1cDogKGU6IEV2ZW50LCBlbnRpdHlJZDogc3RyaW5nKSA9PiB2b2lkLFxuICBjYW1lcmFJZDogc3RyaW5nLFxuKSA9PiB7XG4gIGNvbnN0IGNhbWVyYSA9IGNhbWVyYUlkICYmIGhhc3Muc3RhdGVzW2NhbWVyYUlkXTtcblxuICBjb25zdCBlbnRpdHlQaWN0dXJlID0gY2FtZXJhPy5hdHRyaWJ1dGVzPy5lbnRpdHlfcGljdHVyZTtcbiAgY29uc3QgZnJpZW5kbHlOYW1lID0gY2FtZXJhPy5hdHRyaWJ1dGVzPy5mcmllbmRseV9uYW1lID8/IGNhbWVyYUlkO1xuXG4gIHJldHVybiByZW5kZXJDYW1lcmEoaGFuZGxlUG9wdXAsIGNhbWVyYUlkLCBlbnRpdHlQaWN0dXJlLCBmcmllbmRseU5hbWUpO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgYnVpbGRDYW1lcmE7XG4iLCJpbXBvcnQgeyBodG1sIH0gZnJvbSAnbGl0JztcblxuY29uc3QgcmVuZGVyQ2FtZXJhID0gKFxuICBoYW5kbGVQb3B1cDogKGU6IEV2ZW50LCBlbnRpdHlJZDogc3RyaW5nKSA9PiB2b2lkLFxuICBjYW1lcmFJZDogc3RyaW5nLFxuICBjYW1lcmFQaWN0dXJlOiBzdHJpbmcsXG4gIGZyaWVuZGx5TmFtZTogc3RyaW5nLFxuKSA9PiB7XG4gIGlmICghY2FtZXJhUGljdHVyZSkgcmV0dXJuIGh0bWxgYDtcblxuICByZXR1cm4gaHRtbGBcbiAgICA8ZGl2IFxuICAgICAgY2xhc3M9XCJjYW1lcmEtY29udGFpbmVyXCJcbiAgICAgIEBjbGljaz0keyhlOiBFdmVudCkgPT4gaGFuZGxlUG9wdXAoZSwgY2FtZXJhSWQpfVxuICAgID5cbiAgICAgIDxkaXYgY2xhc3M9XCJjYW1lcmEtaW1hZ2VcIj5cbiAgICAgICAgPGltZyBcbiAgICAgICAgICBzcmM9XCIke2NhbWVyYVBpY3R1cmV9XCIgXG4gICAgICAgICAgYWx0PVwiJHtmcmllbmRseU5hbWV9XCJcbiAgICAgICAgICBsb2FkaW5nPVwibGF6eVwiXG4gICAgICAgIC8+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYDtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IHJlbmRlckNhbWVyYTtcbiIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tZWxzZS1yZXR1cm4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG9iamVjdC1jdXJseS1uZXdsaW5lICovXG5pbXBvcnQgeyBIb21lQXNzaXN0YW50IH0gZnJvbSAnY3VzdG9tLWNhcmQtaGVscGVycy9kaXN0JztcbmltcG9ydCB7IGlBaXJRdWFsaXR5IH0gZnJvbSAnLi4vdXRpbHMvY29uZmlnLXNjaGVtYSc7XG5pbXBvcnQgeyBnZXRFbnRpdHlOdW1lcmljVmFsdWUsIGdldEVudGl0eVJhd1ZhbHVlLCBnZXRFbnRpdHlVbml0IH0gZnJvbSAnLi4vdXRpbHMvaGVscGVyJztcbmltcG9ydCB7IHJlbmRlcldlYXRoZXJQcmVzZW50IH0gZnJvbSAnLi4vdGVtcGxhdGVzL3QtcHJlc2VudCc7XG5cbi8qKlxuICogUmVzdGl0dWlzY2UgdW4gY29sb3JlIChpbiBmb3JtYXRvIGhleCkgaW4gYmFzZSBhbCB2YWxvcmUgZGVsbCdpbmRpY2UgRVBBIEFRSS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBhcWkgLSBWYWxvcmUgQVFJIGNvbXByZXNvIHRyYSAwIGUgNTAwXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIENvbG9yZSBlc2FkZWNpbWFsZSBhc3NvY2lhdG8gYWxsYSBmYXNjaWEgQVFJXG4gKi9cbmZ1bmN0aW9uIGdldEFRSUNvbG9yKGFxaTogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKGFxaSA8PSA1MCkge1xuICAgIHJldHVybiAnIzAwOTk2Nic7IC8vIFZlcmRlIChCdW9uYSlcbiAgfSBlbHNlIGlmIChhcWkgPD0gMTAwKSB7XG4gICAgcmV0dXJuICcjZmZkZTMzJzsgLy8gR2lhbGxvIChNb2RlcmF0YSlcbiAgfSBlbHNlIGlmIChhcWkgPD0gMTUwKSB7XG4gICAgcmV0dXJuICcjZmY5OTMzJzsgLy8gQXJhbmNpb25lIChTZW5zaWJpbGkpXG4gIH0gZWxzZSBpZiAoYXFpIDw9IDIwMCkge1xuICAgIHJldHVybiAnI2NjMDAzMyc7IC8vIFJvc3NvIChOb24gc2FsdXRhcmUpXG4gIH0gZWxzZSBpZiAoYXFpIDw9IDMwMCkge1xuICAgIHJldHVybiAnIzY2MDA5OSc7IC8vIFZpb2xhIChNb2x0byBub24gc2FsdXRhcmUpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuICcjN2UwMDIzJzsgLy8gTWFycm9uZSBzY3VybyAoUGVyaWNvbG9zYSlcbiAgfVxufVxuXG5jb25zdCBidWlsZEFpclF1YWxpdHkgPSAoXG4gIGhhc3M6IEhvbWVBc3Npc3RhbnQsXG4gIGxhbmd1YWdlOiBzdHJpbmcsXG4gIGFpcnF1YWxpdHk6IGlBaXJRdWFsaXR5LFxuKSA9PiB7XG4gIGNvbnN0IGxhbmcgPSBsYW5ndWFnZSB8fCBoYXNzLnNlbGVjdGVkTGFuZ3VhZ2UgfHwgaGFzcy5sYW5ndWFnZTtcblxuICBjb25zdCBwbTI1ID0gZ2V0RW50aXR5TnVtZXJpY1ZhbHVlKHsgZW50aXR5SWQ6IGFpcnF1YWxpdHkucG0yNSwgaGFzcywgbGFuZzogbGFuZ3VhZ2UsIGRlY2ltYWxzOiAwIH0pO1xuICBjb25zdCBwbTEwID0gZ2V0RW50aXR5TnVtZXJpY1ZhbHVlKHsgZW50aXR5SWQ6IGFpcnF1YWxpdHkucG0xMCwgaGFzcywgbGFuZzogbGFuZ3VhZ2UsIGRlY2ltYWxzOiAwIH0pO1xuICBjb25zdCBvMyA9IGdldEVudGl0eU51bWVyaWNWYWx1ZSh7IGVudGl0eUlkOiBhaXJxdWFsaXR5Lm8zLCBoYXNzLCBsYW5nOiBsYW5ndWFnZSwgZGVjaW1hbHM6IDEgfSk7XG4gIGNvbnN0IG5vMiA9IGdldEVudGl0eU51bWVyaWNWYWx1ZSh7IGVudGl0eUlkOiBhaXJxdWFsaXR5Lm5vMiwgaGFzcywgbGFuZzogbGFuZ3VhZ2UsIGRlY2ltYWxzOiAwIH0pO1xuICBjb25zdCBjbyA9IGdldEVudGl0eU51bWVyaWNWYWx1ZSh7IGVudGl0eUlkOiBhaXJxdWFsaXR5LmNvLCBoYXNzLCBsYW5nOiBsYW5ndWFnZSwgZGVjaW1hbHM6IDEgfSk7XG4gIGNvbnN0IHNvMiA9IGdldEVudGl0eU51bWVyaWNWYWx1ZSh7IGVudGl0eUlkOiBhaXJxdWFsaXR5LnNvMiwgaGFzcywgbGFuZzogbGFuZ3VhZ2UsIGRlY2ltYWxzOiAwIH0pO1xuICBjb25zdCBlcGFfYXFpID0gZ2V0RW50aXR5TnVtZXJpY1ZhbHVlKHsgZW50aXR5SWQ6IGFpcnF1YWxpdHkuZXBhX2FxaSwgaGFzcywgbGFuZzogbGFuZ3VhZ2UsIGRlY2ltYWxzOiAwIH0pO1xuICBjb25zdCBlcGFfcHJpbWFyeV9wb2xsdXRhbnQgPSBnZXRFbnRpdHlSYXdWYWx1ZShoYXNzLCBhaXJxdWFsaXR5LmVwYV9wcmltYXJ5X3BvbGx1dGFudCk7XG5cbiAgY29uc3QgYWlyUXVhbGl0eURhdGEgPSB7XG4gICAgcG0yNToge1xuICAgICAgdmFsdWU6IChwbTI1ID8gYHBtMi41ICR7cG0yNX1gIDogcG0yNSksXG4gICAgICB1bml0OiBnZXRFbnRpdHlVbml0KGhhc3MsIGFpcnF1YWxpdHkucG0yNSkgfHwgJ8K1Zy9twrMnLFxuICAgICAgaWNvbjogJ21kaTp3ZWF0aGVyLWhhenknLFxuICAgIH0sXG4gICAgcG0xMDoge1xuICAgICAgdmFsdWU6IChwbTEwID8gYHBtMTAgJHtwbTEwfWAgOiBwbTEwKSxcbiAgICAgIHVuaXQ6IGdldEVudGl0eVVuaXQoaGFzcywgYWlycXVhbGl0eS5wbTEwKSB8fCAnwrVnL23CsycsXG4gICAgICBpY29uOiAnbWRpOndlYXRoZXItaGF6eScsXG4gICAgfSxcbiAgICBvMzoge1xuICAgICAgdmFsdWU6IChvMyA/IGBvMyAke28zfWAgOiBvMyksXG4gICAgICB1bml0OiBnZXRFbnRpdHlVbml0KGhhc3MsIGFpcnF1YWxpdHkubzMpIHx8ICfCtWcvbcKzJyxcbiAgICAgIGljb246ICdtZGk6bW9sZWN1bGUnLFxuICAgIH0sXG4gICAgbm8yOiB7XG4gICAgICB2YWx1ZTogKG5vMiA/IGBubzIgJHtubzJ9YCA6IG5vMiksXG4gICAgICB1bml0OiBnZXRFbnRpdHlVbml0KGhhc3MsIGFpcnF1YWxpdHkubm8yKSB8fCAnwrVnL23CsycsXG4gICAgICBpY29uOiAnbWRpOm1vbGVjdWxlJyxcbiAgICB9LFxuICAgIGNvOiB7XG4gICAgICB2YWx1ZTogKGNvID8gYGNvICR7Y299YCA6IGNvKSxcbiAgICAgIHVuaXQ6IGdldEVudGl0eVVuaXQoaGFzcywgYWlycXVhbGl0eS5jbykgfHwgJ8K1Zy9twrMnLFxuICAgICAgaWNvbjogJ21kaTptb2xlY3VsZScsXG4gICAgfSxcbiAgICBzbzI6IHtcbiAgICAgIHZhbHVlOiAoc28yID8gYHNvMiAke3NvMn1gIDogc28yKSxcbiAgICAgIHVuaXQ6IGdldEVudGl0eVVuaXQoaGFzcywgYWlycXVhbGl0eS5zbzIpIHx8ICfCtWcvbcKzJyxcbiAgICAgIGljb246ICdtZGk6bW9sZWN1bGUnLFxuICAgIH0sXG4gICAgZXBhX2FxaToge1xuICAgICAgdmFsdWU6IChlcGFfYXFpID8gYEFpciBRdWFsaXR5IEluZGV4ICR7ZXBhX2FxaX1gIDogZXBhX2FxaSksXG4gICAgICAvLyB1bml0OiBnZXRFbnRpdHlVbml0KGhhc3MsIGFpcnF1YWxpdHkuZXBhX2FxaSkgfHwgJ8K1Zy9twrMnLFxuICAgICAgaWNvbjogJ21kaTp3ZWF0aGVyLWhhenknLFxuICAgICAgaWNvbl9jb2xvcjogZ2V0QVFJQ29sb3IoTnVtYmVyKGdldEVudGl0eVJhd1ZhbHVlKGhhc3MsIGFpcnF1YWxpdHkuZXBhX2FxaSkpKSxcbiAgICB9LFxuICAgIGVwYV9wcmltYXJ5X3BvbGx1dGFudDoge1xuICAgICAgdmFsdWU6IChlcGFfcHJpbWFyeV9wb2xsdXRhbnQgPyBgUHJpbWFyeSAke2VwYV9wcmltYXJ5X3BvbGx1dGFudH1gIDogZXBhX3ByaW1hcnlfcG9sbHV0YW50KSxcbiAgICAgIC8vIHVuaXQ6IGdldEVudGl0eVVuaXQoaGFzcywgYWlycXVhbGl0eS5lcGFfYXFpKSB8fCAnwrVnL23CsycsXG4gICAgICBpY29uOiAnbWRpOndlYXRoZXItaGF6eScsXG4gICAgfSxcbiAgfTtcblxuICByZXR1cm4gcmVuZGVyV2VhdGhlclByZXNlbnQoYWlyUXVhbGl0eURhdGEsIGxhbmcpO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgYnVpbGRBaXJRdWFsaXR5O1xuIiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKiBlc2xpbnQtZGlzYWJsZSBxdW90ZS1wcm9wcyAqL1xuaW1wb3J0IHsgSG9tZUFzc2lzdGFudCB9IGZyb20gJ2N1c3RvbS1jYXJkLWhlbHBlcnMvZGlzdCc7XG5pbXBvcnQgeyBpVGVybXMgfSBmcm9tICcuLi9iYXNlL2xvdmVsYWNlLWJhc2UnO1xuaW1wb3J0IHsgaURQQ0FsZXJ0IH0gZnJvbSAnLi4vdXRpbHMvY29uZmlnLXNjaGVtYSc7XG5pbXBvcnQgcmVuZGVyTWV0ZW9EUENhbGFybSwgeyBpV2VhdGhlck1ldGVvRFBDQWxhcm1EYXRhSW50ZXJmYWNlIH0gZnJvbSAnLi4vdGVtcGxhdGVzL3QtbWV0ZW9hbGFybSc7XG5pbXBvcnQgeyBnZXRMb2NhbGVJbmZvIH0gZnJvbSAnLi4vdXRpbHMvaGVscGVyJztcblxuY29uc3QgZ2V0RWZmZWN0aXZlTGFiZWwgPSAoZWZmZWN0aXZlOiBzdHJpbmcpID0+IHtcbiAgY29uc3QgZWZmZWN0aXZlRGF0ZXRpbWUgPSBuZXcgRGF0ZShlZmZlY3RpdmUpO1xuICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuXG4gIC8vIFJlc2V0IGRlbGwnb3JhIHBlciBjb25mcm9udG8gc29sbyBhIGxpdmVsbG8gZGkgZ2lvcm5vXG4gIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUobm93LmdldEZ1bGxZZWFyKCksIG5vdy5nZXRNb250aCgpLCBub3cuZ2V0RGF0ZSgpKTtcbiAgY29uc3QgZWZmZWN0aXZlRGF0ZSA9IG5ldyBEYXRlKGVmZmVjdGl2ZURhdGV0aW1lLmdldEZ1bGxZZWFyKCksIGVmZmVjdGl2ZURhdGV0aW1lLmdldE1vbnRoKCksIGVmZmVjdGl2ZURhdGV0aW1lLmdldERhdGUoKSk7XG5cbiAgY29uc3QgbXNJbkRheSA9IDI0ICogNjAgKiA2MCAqIDEwMDA7XG4gIGNvbnN0IGRheURpZmZlcmVuY2UgPSBNYXRoLnJvdW5kKChlZmZlY3RpdmVEYXRlLmdldFRpbWUoKSAtIHRvZGF5LmdldFRpbWUoKSkgLyBtc0luRGF5KTtcblxuICBsZXQgZWZmZWN0aXZlTGFiZWw6ICdvZ2dpJyB8ICdkb21hbmknIHwgJ2RvcG9kb21hbmknIHwgdW5kZWZpbmVkO1xuXG4gIGlmIChkYXlEaWZmZXJlbmNlID09PSAwKSB7XG4gICAgZWZmZWN0aXZlTGFiZWwgPSAnb2dnaSc7XG4gIH0gZWxzZSBpZiAoZGF5RGlmZmVyZW5jZSA9PT0gMSkge1xuICAgIGVmZmVjdGl2ZUxhYmVsID0gJ2RvbWFuaSc7XG4gIH0gZWxzZSBpZiAoZGF5RGlmZmVyZW5jZSA9PT0gMikge1xuICAgIGVmZmVjdGl2ZUxhYmVsID0gJ2RvcG9kb21hbmknO1xuICB9IGVsc2Uge1xuICAgIGVmZmVjdGl2ZUxhYmVsID0gdW5kZWZpbmVkO1xuICB9XG4gIHJldHVybiBlZmZlY3RpdmVMYWJlbDtcbn07XG5cbmNvbnN0IGJ1aWxkTWV0ZW9BbGFybURhdGEgPSAoXG4gIGhhc3M6IEhvbWVBc3Npc3RhbnQsXG4gIGxhbmc6IHN0cmluZyxcbiAgdGVybXM6IGlUZXJtcyxcbiAgbWV0ZW9hbGFybUlkOiBzdHJpbmcsXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuKTogUmVjb3JkPHN0cmluZywgaVdlYXRoZXJNZXRlb0RQQ0FsYXJtRGF0YUludGVyZmFjZT4gPT4ge1xuICBjb25zdCBldmVudEljb246IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgJ3dpbmQnOiAnbWRpOndlYXRoZXItd2luZHknLFxuICAgICdzbm93LWljZSc6ICdtZGk6c25vd2ZsYWtlLWFsZXJ0JyxcbiAgICAndGh1bmRlcnN0b3JtJzogJ21kaTp3ZWF0aGVyLWxpZ2h0bmluZycsXG4gICAgJ2ZvZyc6ICdtZGk6d2VhdGhlci1mb2cnLFxuICAgICdoaWdoLXRlbXBlcmF0dXJlJzogJ21kaTp3ZWF0aGVyLXN1bm55LWFsZXJ0JyxcbiAgICAnbG93LXRlbXBlcmF0dXJlJzogJ21kaTp0aGVybW9tZXRlci1sb3cnLFxuICAgICdjb2FzdGFsLWV2ZW50JzogJ21kaTpob21lLWZsb29kJyxcbiAgICAnZm9yZXN0LWZpcmUnOiAnbWRpOnBpbmUtdHJlZS1maXJlJyxcbiAgICAnYXZhbGFuY2hlJzogJ21kaTppbWFnZS1maWx0ZXItaGRyJyxcbiAgICAncmFpbic6ICdtZGk6d2VhdGhlci1wb3VyaW5nJyxcbiAgICAnZmxvb2QnOiAnbWRpOmhvbWUtZmxvb2QnLFxuICAgICdyYWluLWZsb29kJzogJ21kaTp3ZWF0aGVyLXBvdXJpbmcnLFxuICAgICdtYXJpbmUtaGF6YXJkJzogJ21kaTp3ZWF0aGVyLWh1cnJpY2FuZScsXG4gICAgJ2Ryb3VnaHQnOiAnbWRpOndhdGVyLW9mZicsXG4gIH07XG5cbiAgY29uc3QgZXZlbnRJY29uQ29sb3I6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgZ3JlZW46ICdncmVlbicsXG4gICAgeWVsbG93OiAnI2ZmYTYwMCcsXG4gICAgb3JhbmdlOiAnb3JhbmdlJyxcbiAgICByZWQ6ICdyZWQnLFxuICB9O1xuXG4gIGNvbnN0IG1ldGVvYWxhcm0gPSBtZXRlb2FsYXJtSWQgJiYgaGFzcy5zdGF0ZXNbbWV0ZW9hbGFybUlkXTtcbiAgaWYgKCFtZXRlb2FsYXJtPy5hdHRyaWJ1dGVzKSByZXR1cm4ge307XG5cbiAgY29uc3QgZnBjRGF0YTogUmVjb3JkPHN0cmluZywgaVdlYXRoZXJNZXRlb0RQQ0FsYXJtRGF0YUludGVyZmFjZT4gPSB7fTtcblxuICBpZiAobWV0ZW9hbGFybS5zdGF0ZSA9PT0gJ29uJyAmJiBtZXRlb2FsYXJtLmF0dHJpYnV0ZXMpIHtcbiAgICBjb25zdCBsb2NhbGVJbmZvID0gZ2V0TG9jYWxlSW5mbyhsYW5nKTtcbiAgICBjb25zdCB7XG4gICAgICBldmVudCxcbiAgICAgIHNldmVyaXR5LFxuICAgICAgYXdhcmVuZXNzX3R5cGUsXG4gICAgICBhd2FyZW5lc3NfbGV2ZWwsXG4gICAgICBlZmZlY3RpdmUsXG4gICAgfSA9IG1ldGVvYWxhcm0uYXR0cmlidXRlcztcblxuICAgIGNvbnN0IGF3YXJlbmVzc1R5cGUgPSBhd2FyZW5lc3NfdHlwZT8uc3BsaXQoJzsnKVsxXT8udHJpbSgpLnRvTG93ZXJDYXNlKCkgfHwgJyc7XG4gICAgY29uc3QgYXdhcmVuZXNzTGV2ZWwgPSBhd2FyZW5lc3NfbGV2ZWw/LnNwbGl0KCc7JylbMV0/LnRyaW0oKS50b0xvd2VyQ2FzZSgpIHx8ICcnO1xuICAgIGNvbnN0IGV2ZW50TmFtZSA9IGV2ZW50IHx8ICcnO1xuICAgIGNvbnN0IHNldmVyaXR5TGV2ZWwgPSBzZXZlcml0eT8uc3BsaXQoJzsnKVsxXT8udHJpbSgpIHx8ICcnO1xuICAgIGNvbnN0IGVmZmVjdGl2ZURhdGV0aW1lID0gZ2V0RWZmZWN0aXZlTGFiZWwoZWZmZWN0aXZlKTtcblxuICAgIGZwY0RhdGFbJ21ldGVvYWxhcm0nXSA9IHtcbiAgICAgIGV2ZW50OiBldmVudE5hbWUsXG4gICAgICBzZXZlcml0eTogc2V2ZXJpdHlMZXZlbCxcbiAgICAgIGljb246IGV2ZW50SWNvblthd2FyZW5lc3NUeXBlXSB8fCAnbWRpOmFsZXJ0JyxcbiAgICAgIGljb25fY29sb3I6IGV2ZW50SWNvbkNvbG9yW2F3YXJlbmVzc0xldmVsXSB8fCAnZ3JleScsXG4gICAgICBkYXRldGltZTogKG5ldyBEYXRlKGVmZmVjdGl2ZSkpLnRvTG9jYWxlRGF0ZVN0cmluZyhsb2NhbGVJbmZvLmxvY2FsZSwge1xuICAgICAgICB3ZWVrZGF5OiAnc2hvcnQnLFxuICAgICAgICB0aW1lWm9uZTogbG9jYWxlSW5mby50aW1lem9uZSxcbiAgICAgIH0pLnRvTG9jYWxlVXBwZXJDYXNlKCksXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBmcGNEYXRhO1xufTtcblxuY29uc3QgYnVpbGREUENBbGFybURhdGEgPSAoXG4gIGhhc3M6IEhvbWVBc3Npc3RhbnQsXG4gIGxhbmc6IHN0cmluZyxcbiAgdGVybXM6IGlUZXJtcyxcbiAgZHBjYWxhcm06IGlEUENBbGVydCxcbikgPT4ge1xuICBpZiAoIWRwY2FsYXJtKSByZXR1cm4ge307XG5cbiAgY29uc3QgbG9jYWxlSW5mbyA9IGdldExvY2FsZUluZm8obGFuZyk7XG4gIGNvbnN0IGV2ZW50SWNvbkNvbG9yID0ge1xuICAgIDA6ICdncmF5JyxcbiAgICAxOiAnZ3JlZW4nLFxuICAgIDI6ICcjZmZhNjAwJyxcbiAgICAzOiAnb3JhbmdlJyxcbiAgICA0OiAncmVkJyxcbiAgfTtcblxuICBjb25zdCBzb3VyY2VzID0gWyd0aHVuZGVyc3Rvcm1zJywgJ2h5ZHJhdWxpYycsICdoeWRyb2dlb2xvZ2ljYWwnXTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgY29uc3QgZnBjRGF0YTogUmVjb3JkPHN0cmluZywgaVdlYXRoZXJNZXRlb0RQQ0FsYXJtRGF0YUludGVyZmFjZT4gPSB7fTtcblxuICBzb3VyY2VzLmZvckVhY2goKGtleSkgPT4ge1xuICAgIGNvbnN0IGVudGl0eUlkID0gZHBjYWxhcm1ba2V5IGFzIGtleW9mIGlEUENBbGVydF07XG4gICAgY29uc3QgZW50aXR5ID0gZW50aXR5SWQgJiYgaGFzcy5zdGF0ZXNbZW50aXR5SWRdO1xuXG4gICAgaWYgKGVudGl0eSAmJiBlbnRpdHkuc3RhdGUgPT09ICdvbicgJiYgZW50aXR5LmF0dHJpYnV0ZXMpIHtcbiAgICAgIGNvbnN0IHsgbGV2ZWwsIGluZm8sIGljb24gfSA9IGVudGl0eS5hdHRyaWJ1dGVzO1xuICAgICAgZnBjRGF0YVtrZXldID0ge1xuICAgICAgICBldmVudDogaW5mbyxcbiAgICAgICAgc2V2ZXJpdHk6IGxldmVsLFxuICAgICAgICBpY29uLFxuICAgICAgICBpY29uX2NvbG9yOiBldmVudEljb25Db2xvcltsZXZlbF0sXG4gICAgICAgIGRhdGV0aW1lOiAobmV3IERhdGUoKSkudG9Mb2NhbGVEYXRlU3RyaW5nKGxvY2FsZUluZm8ubG9jYWxlLCB7XG4gICAgICAgICAgd2Vla2RheTogJ3Nob3J0JyxcbiAgICAgICAgICB0aW1lWm9uZTogbG9jYWxlSW5mby50aW1lem9uZSxcbiAgICAgICAgfSkudG9Mb2NhbGVVcHBlckNhc2UoKSxcbiAgICAgIH07XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIGZwY0RhdGE7XG59O1xuXG5jb25zdCBidWlsZE1ldGVvRFBDYWxhcm0gPSAoXG4gIGhhc3M6IEhvbWVBc3Npc3RhbnQsXG4gIGxhbmc6IHN0cmluZyxcbiAgdGVybXM6IGlUZXJtcyxcbiAgbWV0ZW9hbGFybUlkOiBzdHJpbmcsXG4gIGRwY2FsYXJtOiBpRFBDQWxlcnQsIFxuKSA9PiB7XG4gIGNvbnN0IGFsYXJtc0RhdGEgPSB7IC4uLmJ1aWxkTWV0ZW9BbGFybURhdGEoaGFzcywgbGFuZywgdGVybXMsIG1ldGVvYWxhcm1JZCksIC4uLmJ1aWxkRFBDQWxhcm1EYXRhKGhhc3MsIGxhbmcsIHRlcm1zLCBkcGNhbGFybSkgfTtcbiAgLy8gY29uc29sZS5kZWJ1ZygnYnVpbGRNZXRlb0RQQ2FsYXJtJywgYWxhcm1zRGF0YSk7XG4gIHJldHVybiByZW5kZXJNZXRlb0RQQ2FsYXJtKGFsYXJtc0RhdGEpO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgYnVpbGRNZXRlb0RQQ2FsYXJtO1xuIiwiaW1wb3J0IHsgaHRtbCB9IGZyb20gJ2xpdCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgaVdlYXRoZXJNZXRlb0RQQ0FsYXJtRGF0YUludGVyZmFjZSB7XG4gIGV2ZW50Pzogc3RyaW5nLFxuICBzZXZlcml0eT86IHN0cmluZyxcbiAgaWNvbj86IHN0cmluZyxcbiAgaWNvbl9jb2xvcj86IHN0cmluZyxcbiAgZGF0ZXRpbWU/OiBzdHJpbmcsXG59XG5cbmNvbnN0IHJlbmRlck1ldGVvRFBDYWxhcm0gPSAoXG4gIG1ldGVvRFBDYWxhcm1EYXRhOiBSZWNvcmQ8c3RyaW5nLCBpV2VhdGhlck1ldGVvRFBDQWxhcm1EYXRhSW50ZXJmYWNlPiB8IG51bGwsXG4pID0+IHtcbiAgaWYgKCFtZXRlb0RQQ2FsYXJtRGF0YSB8fCBPYmplY3Qua2V5cyhtZXRlb0RQQ2FsYXJtRGF0YSkubGVuZ3RoID09PSAwKSByZXR1cm4gaHRtbGBgO1xuXG4gIHJldHVybiBodG1sYFxuICA8ZGl2IGNsYXNzPVwibWV0ZW9kY3BhbGFybS1ncmlkLWNvbnRhaW5lclwiPlxuICAgICR7T2JqZWN0LmVudHJpZXMobWV0ZW9EUENhbGFybURhdGEpLm1hcCgoW2tleSwgZGF0YV0pID0+IGh0bWxgXG4gICAgICA8ZGl2IGNsYXNzPVwibWV0ZW9kY3BhbGFybS1ncm91cFwiPlxuICAgICAgICA8aGEtaWNvbiBpY29uPVwiJHtkYXRhLmljb259XCIgc3R5bGU9XCJjb2xvcjogJHtkYXRhLmljb25fY29sb3J9O1wiPjwvaGEtaWNvbj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1ldGVvZGNwYWxhcm0tbGFiZWxcIj4ke2RhdGEuZGF0ZXRpbWV9PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtZXRlb2RjcGFsYXJtLWxhYmVsXCI+JHtkYXRhLmV2ZW50fTwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgYCl9XG4gIDwvZGl2PlxuICBgO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgcmVuZGVyTWV0ZW9EUENhbGFybTtcbiIsIi8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVyc2NvcmUtZGFuZ2xlICovXG5pbXBvcnQgeyBodG1sLCBUZW1wbGF0ZVJlc3VsdCB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgeyBjdXN0b21FbGVtZW50IH0gZnJvbSAnbGl0L2RlY29yYXRvcnMuanMnO1xuXG5pbXBvcnQgeyBMb3ZlbGFjZUJhc2VFbGVtZW50LCBwcmVsb2FkUmVzb3VyY2VzIH0gZnJvbSAnLi9iYXNlL2xvdmVsYWNlLWJhc2UnO1xuXG5pbXBvcnQgYnVpbGRXZWF0aGVyU3VtbWFyeSBmcm9tICcuL2J1aWxkZXIvYi1zdW1tYXJ5JztcbmltcG9ydCBidWlsZFdlYXRoZXJQcmVzZW50IGZyb20gJy4vYnVpbGRlci9iLXByZXNlbnQnO1xuaW1wb3J0IGJ1aWxkVWx0cmF2aW9sZXQgZnJvbSAnLi9idWlsZGVyL2ItdWx0cmF2aW9sZXQnO1xuaW1wb3J0IGJ1aWxkUG9sbGVuIGZyb20gJy4vYnVpbGRlci9iLXBvbGxlbic7XG5pbXBvcnQgYnVpbGRXZWF0aGVyRm9yZWNhc3QgZnJvbSAnLi9idWlsZGVyL2Itd2VhdGhlci1mb3JlY2FzdCc7XG5pbXBvcnQgYnVpbGRDYW1lcmEgZnJvbSAnLi9idWlsZGVyL2ItY2FtZXJhJztcbmltcG9ydCBidWlsZEFpclF1YWxpdHkgZnJvbSAnLi9idWlsZGVyL2ItYWlycXVhbGl0eSc7XG5pbXBvcnQgYnVpbGRNZXRlb0RQQ2FsYXJtIGZyb20gJy4vYnVpbGRlci9iLW1ldGVvYWxhcm0nO1xuXG5jb25zdCB7IHRyYW5zbGF0aW9ucywgaW1hZ2VQYXRoIH0gPSBhd2FpdCBwcmVsb2FkUmVzb3VyY2VzKCk7IC8vIGVzZWN1emlvbmUgaW1tZWRpYXRhXG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tIERFRklOSVpJT05FIENPTVBPTkVOVEUgLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuQGN1c3RvbUVsZW1lbnQoJ2hhLWNhcmQtd2VhdGhlci1jb25kaXRpb25zJylcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvcHJlZmVyLWRlZmF1bHQtZXhwb3J0XG5leHBvcnQgY2xhc3MgSGFDYXJkV2VhdGhlckNvbmRpdGlvbnMgZXh0ZW5kcyBMb3ZlbGFjZUJhc2VFbGVtZW50IHtcbiAgX3RyYW5zbGF0aW9ucyA9IHRyYW5zbGF0aW9ucztcblxuICBfaW1hZ2VzUGF0aCA9IGltYWdlUGF0aDtcblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2xhc3MtbWV0aG9kcy11c2UtdGhpc1xuICBwcm90ZWN0ZWQgX3JlbmRlcigpOiBUZW1wbGF0ZVJlc3VsdCB7XG4gICAgcmV0dXJuIGh0bWxgXG4gICAgICA8aGEtY2FyZCBjbGFzcz1cImhhLWNhcmQtd2VhdGhlci1jb25kaXRpb25zXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJuZC1jb250YWluZXJcIj5cbiAgICAgICAgICAke3RoaXMuX2J1aWxkVGVtcGxhdGUoKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2hhLWNhcmQ+XG4gICAgYDtcbiAgfVxuXG4gIHByaXZhdGUgX2J1aWxkVGVtcGxhdGUoKTogVGVtcGxhdGVSZXN1bHQge1xuICAgIGxldCBzdW1tYXJ5ID0gaHRtbGBgO1xuICAgIGxldCBwcmVzZW50ID0gaHRtbGBgO1xuICAgIGxldCBkYWlseVdlYXRoZXJGb3JlY2FzdCA9IGh0bWxgYDtcbiAgICBsZXQgaG91cmx5V2VhdGhlckZvcmVjYXN0ID0gaHRtbGBgO1xuICAgIGxldCBtYXJpbmVEYWlseVdlYXRoZXJGb3JlY2FzdCA9IGh0bWxgYDtcbiAgICBsZXQgbWFyaW5lSG91cmx5V2VhdGhlckZvcmVjYXN0ID0gaHRtbGBgO1xuICAgIGxldCBtZXRlb0RQQ2FsYXJtID0gaHRtbGBgO1xuICAgIGxldCB1bHRyYXZpb2xldCA9IGh0bWxgYDtcbiAgICBsZXQgcG9sbGVuID0gaHRtbGBgO1xuICAgIGxldCBhaXJRdWFsaXR5ID0gaHRtbGBgO1xuICAgIGxldCBjYW1lcmEgPSBodG1sYGA7XG5cbiAgICBjb25zdCBnZXRXZWF0aGVyRm9yZWNhc3QgPSAobW9kZTogMCB8IDEgfCAyIHwgMykgPT4gYnVpbGRXZWF0aGVyRm9yZWNhc3QoXG4gICAgICB0aGlzLmhhc3MsXG4gICAgICB0aGlzLl9sYW5ndWFnZSxcbiAgICAgIHRoaXMuX3Rlcm1zLFxuICAgICAgdGhpcy5fY29uZmlnLndlYXRoZXIuZGFpbHlfZm9yZWNhc3RzLFxuICAgICAgdGhpcy5fY29uZmlnLndlYXRoZXIuaG91cmx5X2ZvcmVjYXN0cyxcbiAgICAgIHRoaXMuX2NvbmZpZy53ZWF0aGVyLm1hcmluZV9kYWlseV9mb3JlY2FzdHMsXG4gICAgICB0aGlzLl9jb25maWcud2VhdGhlci5tYXJpbmVfaG91cmx5X2ZvcmVjYXN0cyxcbiAgICAgIG1vZGUsXG4gICAgICB0aGlzLl9pY29uc0NvbmZpZyxcbiAgICAgIHRoaXMuX2NvbmZpZy53ZWF0aGVyLnN1bixcbiAgICApO1xuXG4gICAgaWYgKHRoaXMuX2hhc1ByZXNlbnQpIHtcbiAgICAgIHN1bW1hcnkgPSBidWlsZFdlYXRoZXJTdW1tYXJ5KFxuICAgICAgICB0aGlzLmhhc3MsXG4gICAgICAgIHRoaXMuX2xhbmd1YWdlLFxuICAgICAgICB0aGlzLl90ZXJtcyxcbiAgICAgICAgdGhpcy5faWNvbnNDb25maWcsXG4gICAgICAgIHRoaXMuX2NvbmZpZy53ZWF0aGVyPy5uYW1lLFxuICAgICAgICB0aGlzLl9jb25maWc/LndlYXRoZXI/LnByZXNlbnQgfHwgbnVsbCxcbiAgICAgICAgdGhpcy5fY29uZmlnPy53ZWF0aGVyPy5zdW4sXG4gICAgICAgIHRoaXMuX2NvbmZpZz8ud2VhdGhlcj8ubW9vbnBoYXNlLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5faGFzUHJlc2VudCkge1xuICAgICAgcHJlc2VudCA9IGJ1aWxkV2VhdGhlclByZXNlbnQoXG4gICAgICAgIHRoaXMuaGFzcyxcbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2UsXG4gICAgICAgIHRoaXMuX3Rlcm1zLFxuICAgICAgICB0aGlzLl9jb25maWc/LndlYXRoZXI/LnByZXNlbnQgfHwge30sXG4gICAgICAgIHRoaXMuX2NvbmZpZz8ud2VhdGhlcj8uc3VuLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5faGFzTWV0ZWFsYXJtIHx8IHRoaXMuX2hhc0RQQ2FsYXJtKSB7XG4gICAgICBtZXRlb0RQQ2FsYXJtID0gYnVpbGRNZXRlb0RQQ2FsYXJtKFxuICAgICAgICB0aGlzLmhhc3MsXG4gICAgICAgIHRoaXMuX2xhbmd1YWdlLFxuICAgICAgICB0aGlzLl90ZXJtcyxcbiAgICAgICAgdGhpcy5fY29uZmlnPy53ZWF0aGVyPy5tZXRlb2FsYXJtLFxuICAgICAgICB0aGlzLl9jb25maWc/LndlYXRoZXI/LmRwY2FsYXJtLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5faGFzRGFpbHlGb3JlY2FzdHMpIHtcbiAgICAgIGRhaWx5V2VhdGhlckZvcmVjYXN0ID0gZ2V0V2VhdGhlckZvcmVjYXN0KDApO1xuICAgIH1cbiAgICBpZiAodGhpcy5faGFzSG91cmx5Rm9yZWNhc3RzKSB7XG4gICAgICBob3VybHlXZWF0aGVyRm9yZWNhc3QgPSBnZXRXZWF0aGVyRm9yZWNhc3QoMSk7XG4gICAgfVxuICAgIGlmICh0aGlzLl9oYXNNYXJpbmVEYWlseUZvcmVjYXN0cykge1xuICAgICAgbWFyaW5lRGFpbHlXZWF0aGVyRm9yZWNhc3QgPSBnZXRXZWF0aGVyRm9yZWNhc3QoMik7XG4gICAgfVxuICAgIGlmICh0aGlzLl9oYXNNYXJpbmVIb3VybHlGb3JlY2FzdHMpIHtcbiAgICAgIG1hcmluZUhvdXJseVdlYXRoZXJGb3JlY2FzdCA9IGdldFdlYXRoZXJGb3JlY2FzdCgzKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5faGFzVWx0cmF2aW9sZXQpIHtcbiAgICAgIHVsdHJhdmlvbGV0ID0gYnVpbGRVbHRyYXZpb2xldCh0aGlzLmhhc3MsIHRoaXMuX2xhbmd1YWdlLCB0aGlzLl9jb25maWcudWx0cmF2aW9sZXQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9oYXNQb2xsZW4pIHtcbiAgICAgIHBvbGxlbiA9IGJ1aWxkUG9sbGVuKHRoaXMuaGFzcywgdGhpcy5fbGFuZ3VhZ2UsIHRoaXMuX2NvbmZpZy5wb2xsZW4pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9oYXNBaXJRdWFsaXR5KSB7XG4gICAgICBhaXJRdWFsaXR5ID0gYnVpbGRBaXJRdWFsaXR5KHRoaXMuaGFzcywgdGhpcy5fbGFuZ3VhZ2UsIHRoaXMuX2NvbmZpZy5haXJxdWFsaXR5KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5faGFzQ2FtZXJhKSB7XG4gICAgICBjYW1lcmEgPSBidWlsZENhbWVyYSh0aGlzLmhhc3MsIHRoaXMuX2xhbmd1YWdlLCB0aGlzLl90ZXJtcywgdGhpcy5faGFuZGxlUG9wdXAuYmluZCh0aGlzKSwgdGhpcy5fY29uZmlnLmNhbWVyYSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGh0bWxgXG4gICAgJHtzdW1tYXJ5fVxuICAgICR7cHJlc2VudH1cbiAgICAke2hvdXJseVdlYXRoZXJGb3JlY2FzdH1cbiAgICAke2RhaWx5V2VhdGhlckZvcmVjYXN0fVxuICAgICR7bWFyaW5lSG91cmx5V2VhdGhlckZvcmVjYXN0fVxuICAgICR7bWFyaW5lRGFpbHlXZWF0aGVyRm9yZWNhc3R9XG4gICAgJHttZXRlb0RQQ2FsYXJtfVxuICAgICR7cG9sbGVufVxuICAgICR7dWx0cmF2aW9sZXR9XG4gICAgJHthaXJRdWFsaXR5fVxuICAgICR7Y2FtZXJhfWA7XG4gIH1cblxuICAvKipcbiAgICogQXByZSBpbCBwb3B1cCBkaSBkZXR0YWdsaW8gcGVyIGwnZW50aXTDoCBzcGVjaWZpY2F0YS5cbiAgICogQHBhcmFtIGUgTCdldmVudG8gY2xpY2sgb3JpZ2luYWxlLlxuICAgKiBAcGFyYW0gZW50aXR5SWQgTCdJRCBkZWxsJ2VudGl0w6AgSG9tZSBBc3Npc3RhbnQgZGEgbW9zdHJhcmUuXG4gICAqL1xuICBwcm90ZWN0ZWQgX2hhbmRsZVBvcHVwKGU6IEV2ZW50LCBlbnRpdHlJZDogc3RyaW5nKSB7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgbW9yZUluZm9FdmVudCA9IG5ldyBFdmVudCgnaGFzcy1tb3JlLWluZm8nLCB7IGNvbXBvc2VkOiB0cnVlIH0pIGFzIGFueTtcbiAgICBtb3JlSW5mb0V2ZW50LmRldGFpbCA9IHsgZW50aXR5SWQgfTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobW9yZUluZm9FdmVudCk7XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJfX2RlY29yYXRlIiwiZGVjb3JhdG9ycyIsInRhcmdldCIsImtleSIsImRlc2MiLCJkIiwiYyIsImFyZ3VtZW50cyIsImxlbmd0aCIsInIiLCJPYmplY3QiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJSZWZsZWN0IiwiZGVjb3JhdGUiLCJpIiwiZGVmaW5lUHJvcGVydHkiLCJTdXBwcmVzc2VkRXJyb3IiLCJ0IiwiZ2xvYmFsVGhpcyIsImUiLCJTaGFkb3dSb290IiwiU2hhZHlDU1MiLCJuYXRpdmVTaGFkb3ciLCJEb2N1bWVudCIsInByb3RvdHlwZSIsIkNTU1N0eWxlU2hlZXQiLCJzIiwiU3ltYm9sIiwibyIsIldlYWtNYXAiLCJuJDMiLCJjb25zdHJ1Y3RvciIsInRoaXMiLCJfJGNzc1Jlc3VsdCQiLCJFcnJvciIsImNzc1RleHQiLCJzdHlsZVNoZWV0IiwiZ2V0IiwicmVwbGFjZVN5bmMiLCJzZXQiLCJ0b1N0cmluZyIsInJlZHVjZSIsIm4iLCJjc3NSdWxlcyIsImlzIiwiaCIsImdldE93blByb3BlcnR5TmFtZXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJnZXRQcm90b3R5cGVPZiIsImEiLCJ0cnVzdGVkVHlwZXMiLCJsIiwiZW1wdHlTY3JpcHQiLCJwIiwicmVhY3RpdmVFbGVtZW50UG9seWZpbGxTdXBwb3J0IiwidSIsInRvQXR0cmlidXRlIiwiQm9vbGVhbiIsIkFycmF5IiwiSlNPTiIsInN0cmluZ2lmeSIsImZyb21BdHRyaWJ1dGUiLCJOdW1iZXIiLCJwYXJzZSIsImYiLCJiIiwiYXR0cmlidXRlIiwidHlwZSIsIlN0cmluZyIsImNvbnZlcnRlciIsInJlZmxlY3QiLCJ1c2VEZWZhdWx0IiwiaGFzQ2hhbmdlZCIsIm1ldGFkYXRhIiwibGl0UHJvcGVydHlNZXRhZGF0YSIsInkkMSIsIkhUTUxFbGVtZW50IiwiYWRkSW5pdGlhbGl6ZXIiLCJfJEVpIiwicHVzaCIsIm9ic2VydmVkQXR0cmlidXRlcyIsImZpbmFsaXplIiwiXyRFaCIsImtleXMiLCJjcmVhdGVQcm9wZXJ0eSIsInN0YXRlIiwiaGFzT3duUHJvcGVydHkiLCJjcmVhdGUiLCJ3cmFwcGVkIiwiZWxlbWVudFByb3BlcnRpZXMiLCJub0FjY2Vzc29yIiwiZ2V0UHJvcGVydHlEZXNjcmlwdG9yIiwiY2FsbCIsInJlcXVlc3RVcGRhdGUiLCJjb25maWd1cmFibGUiLCJlbnVtZXJhYmxlIiwiZ2V0UHJvcGVydHlPcHRpb25zIiwiTWFwIiwiZmluYWxpemVkIiwicHJvcGVydGllcyIsIl8kRXUiLCJlbGVtZW50U3R5bGVzIiwiZmluYWxpemVTdHlsZXMiLCJzdHlsZXMiLCJpc0FycmF5IiwiU2V0IiwiZmxhdCIsInJldmVyc2UiLCJ1bnNoaWZ0IiwidG9Mb3dlckNhc2UiLCJzdXBlciIsIl8kRXAiLCJpc1VwZGF0ZVBlbmRpbmciLCJoYXNVcGRhdGVkIiwiXyRFbSIsIl8kRXYiLCJfJEVTIiwiUHJvbWlzZSIsImVuYWJsZVVwZGF0aW5nIiwiXyRBTCIsIl8kRV8iLCJmb3JFYWNoIiwiYWRkQ29udHJvbGxlciIsIl8kRU8iLCJhZGQiLCJyZW5kZXJSb290IiwiaXNDb25uZWN0ZWQiLCJob3N0Q29ubmVjdGVkIiwicmVtb3ZlQ29udHJvbGxlciIsImRlbGV0ZSIsInNpemUiLCJjcmVhdGVSZW5kZXJSb290Iiwic2hhZG93Um9vdCIsImF0dGFjaFNoYWRvdyIsInNoYWRvd1Jvb3RPcHRpb25zIiwiYWRvcHRlZFN0eWxlU2hlZXRzIiwibWFwIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50IiwibGl0Tm9uY2UiLCJzZXRBdHRyaWJ1dGUiLCJ0ZXh0Q29udGVudCIsImFwcGVuZENoaWxkIiwiY29ubmVjdGVkQ2FsbGJhY2siLCJkaXNjb25uZWN0ZWRDYWxsYmFjayIsImhvc3REaXNjb25uZWN0ZWQiLCJhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2siLCJfJEFLIiwiXyRFVCIsInJlbW92ZUF0dHJpYnV0ZSIsIl8kRWoiLCJoYXNBdHRyaWJ1dGUiLCJDIiwiXyRFUCIsImhhcyIsIl8kRXEiLCJyZWplY3QiLCJzY2hlZHVsZVVwZGF0ZSIsInBlcmZvcm1VcGRhdGUiLCJzaG91bGRVcGRhdGUiLCJ3aWxsVXBkYXRlIiwiaG9zdFVwZGF0ZSIsInVwZGF0ZSIsIl8kRU0iLCJfJEFFIiwiaG9zdFVwZGF0ZWQiLCJmaXJzdFVwZGF0ZWQiLCJ1cGRhdGVkIiwidXBkYXRlQ29tcGxldGUiLCJnZXRVcGRhdGVDb21wbGV0ZSIsInkiLCJtb2RlIiwiUmVhY3RpdmVFbGVtZW50IiwicmVhY3RpdmVFbGVtZW50VmVyc2lvbnMiLCJjcmVhdGVQb2xpY3kiLCJjcmVhdGVIVE1MIiwiTWF0aCIsInJhbmRvbSIsInRvRml4ZWQiLCJzbGljZSIsImNyZWF0ZUNvbW1lbnQiLCJ2IiwiXyIsIm0iLCJSZWdFeHAiLCJnIiwiJCIsIngiLCJfJGxpdFR5cGUkIiwic3RyaW5ncyIsInZhbHVlcyIsIlQiLCJmb3IiLCJFIiwiQSIsImNyZWF0ZVRyZWVXYWxrZXIiLCJQIiwiViIsImxhc3RJbmRleCIsImV4ZWMiLCJ0ZXN0Iiwic3RhcnRzV2l0aCIsIk4iLCJwYXJ0cyIsImVsIiwiY3VycmVudE5vZGUiLCJjb250ZW50IiwiZmlyc3RDaGlsZCIsInJlcGxhY2VXaXRoIiwiY2hpbGROb2RlcyIsIm5leHROb2RlIiwibm9kZVR5cGUiLCJoYXNBdHRyaWJ1dGVzIiwiZ2V0QXR0cmlidXRlTmFtZXMiLCJlbmRzV2l0aCIsImdldEF0dHJpYnV0ZSIsInNwbGl0IiwiaW5kZXgiLCJuYW1lIiwiY3RvciIsIkgiLCJJIiwiTCIsImsiLCJ0YWdOYW1lIiwiYXBwZW5kIiwiZGF0YSIsImluZGV4T2YiLCJpbm5lckhUTUwiLCJTIiwiXyRDbyIsIl8kQ2wiLCJfJGxpdERpcmVjdGl2ZSQiLCJfJEFPIiwiXyRBVCIsIl8kQVMiLCJNIiwiXyRBViIsIl8kQU4iLCJfJEFEIiwiXyRBTSIsInBhcmVudE5vZGUiLCJfJEFVIiwiY3JlYXRpb25TY29wZSIsImltcG9ydE5vZGUiLCJSIiwibmV4dFNpYmxpbmciLCJ6IiwiXyRBSSIsIl8kQ3YiLCJfJEFIIiwiXyRBQSIsIl8kQUIiLCJvcHRpb25zIiwic3RhcnROb2RlIiwiZW5kTm9kZSIsIl8kQVIiLCJpdGVyYXRvciIsIk8iLCJpbnNlcnRCZWZvcmUiLCJjcmVhdGVUZXh0Tm9kZSIsIl8kQUMiLCJfJEFQIiwicmVtb3ZlIiwic2V0Q29ubmVjdGVkIiwiZWxlbWVudCIsImZpbGwiLCJqIiwidG9nZ2xlQXR0cmlidXRlIiwiY2FwdHVyZSIsIm9uY2UiLCJwYXNzaXZlIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsImFkZEV2ZW50TGlzdGVuZXIiLCJoYW5kbGVFdmVudCIsImhvc3QiLCJsaXRIdG1sUG9seWZpbGxTdXBwb3J0IiwibGl0SHRtbFZlcnNpb25zIiwicmVuZGVyT3B0aW9ucyIsIl8kRG8iLCJyZW5kZXJCZWZvcmUiLCJyZW5kZXIiLCJfJGxpdFBhcnQkIiwiXyRsaXRFbGVtZW50JCIsImxpdEVsZW1lbnRIeWRyYXRlU3VwcG9ydCIsIkxpdEVsZW1lbnQiLCJsaXRFbGVtZW50UG9seWZpbGxTdXBwb3J0IiwibGl0RWxlbWVudFZlcnNpb25zIiwia2luZCIsImluaXQiLCJkZWZhdWx0Q29sb3JDc3MiLCJjc3MiLCJkZWZhdWx0RGFya0NvbG9yQ3NzIiwibG9nbyIsImhhY3NJbWFnZVBhdGgiLCJtYW5JbWFnZVBhdGgiLCJvcHRDb25zb2xlUGFyYW0xIiwib3B0Q29uc29sZVBhcmFtMiIsIm9wdENvbnNvbGVQYXJhbTMiLCJjd2NMb2NhbGUiLCJlbiIsIml0IiwibmwiLCJlcyIsImRlIiwiZnIiLCJwdCIsImRhIiwiY3MiLCJydSIsImN3Y0J1aWVucmFkYXJEYXlJY29ucyIsInNub3d5IiwicmFpbnkiLCJjbG91ZHkiLCJwYXJ0bHljbG91ZHkiLCJsaWdodG5pbmciLCJjbGVhciIsImN3Y0J1aWVucmFkYXJOaWdodEljb25zIiwiY3djQ2xpbWFjZWxsRGF5SWNvbnMiLCJmcmVlemluZ19yYWluX2hlYXZ5IiwiZnJlZXppbmdfcmFpbiIsImZyZWV6aW5nX3JhaW5fbGlnaHQiLCJmcmVlemluZ19kcml6emxlIiwiaWNlX3BlbGxldHNfaGVhdnkiLCJpY2VfcGVsbGV0cyIsImljZV9wZWxsZXRzX2xpZ2h0Iiwic25vd19oZWF2eSIsInNub3ciLCJzbm93X2xpZ2h0IiwiZmx1cnJpZXMiLCJ0c3Rvcm0iLCJyYWluX2hlYXZ5IiwicmFpbl9saWdodCIsInJhaW4iLCJkcml6emxlIiwiZm9nX2xpZ2h0IiwiZm9nIiwibW9zdGx5X2Nsb3VkeSIsInBhcnRseV9jbG91ZHkiLCJtb3N0bHlfY2xlYXIiLCJjd2NDbGltYWNlbGxOaWdodEljb25zIiwic3VubnkiLCJjd2NEYXJrc2t5RGF5SWNvbnMiLCJzbGVldCIsIndpbmQiLCJjd2NEYXJrc2t5TmlnaHRJY29ucyIsImN3Y0RlZmF1bHRIYXNzRGF5SWNvbnMiLCJleGNlcHRpb25hbCIsImhhaWwiLCJwb3VyaW5nIiwid2luZHkiLCJjd2NEZWZhdWx0SGFzc05pZ2h0SWNvbnMiLCJjd2NPcGVuV2VhdGhlck1hcERheUljb25zIiwidGh1bmRlcnN0b3JtIiwibWlzdCIsImN3Y09wZW5XZWF0aGVyTWFwTmlnaHRJY29ucyIsImN3Y0RheXRpbWVQaXJhdGVXZWF0aGVySWNvbnMiLCJjd2NOaWdodGx5UGlyYXRlV2VhdGVySWNvbnMiLCJpY29uc01vZGVscyIsInBpcmF0ZXdlYXRoZXIiLCJpY29uc0RheSIsImljb25zTmlnaHQiLCJjbGltYWNlbGwiLCJkYXJrc2t5Iiwib3BlbndlYXRoZXJtYXAiLCJidWllbnJhZGFyIiwiZGVmYXVsdGhhc3MiLCJ0cmFuc2xhdGUiLCJ0ZXJtIiwiZGljdGlvbmFyeSIsImZpbmQiLCJnZXRMb2NhbGVJbmZvIiwibGFuZyIsImxvY2FsZSIsInRpbWV6b25lIiwiamEiLCJjd2MiLCJnZXRMb2NhbGUiLCJ6aCIsInRvVXBwZXJDYXNlIiwiZm9ybWF0TnVtYmVyIiwic3RyaW5nTnVtYmVyIiwiZnJhY3Rpb25EaWdpdHMiLCJ1c2VHcm91cGluZyIsIm51bWJlciIsInBhcnNlRmxvYXQiLCJpc05hTiIsImVmZmVjdGl2ZUZvcm1hdHRlciIsImdldEZvcm1hdHRlciIsIkludGwiLCJOdW1iZXJGb3JtYXQiLCJtaW5pbXVtRnJhY3Rpb25EaWdpdHMiLCJtYXhpbXVtRnJhY3Rpb25EaWdpdHMiLCJmb3JtYXQiLCJnZXRFbnRpdHlSYXdWYWx1ZSIsImhhc3MiLCJlbnRpdHlJZCIsInN0YXRlcyIsImdldEVudGl0eVJhd0F0dHJpYnV0ZSIsImF0dHJpYnV0ZXMiLCJnZXRFbnRpdHlOdW1lcmljVmFsdWUiLCJkZWNpbWFscyIsInVuZGVmaW5lZCIsImdldEVudGl0eVVuaXQiLCJ1bml0X29mX21lYXN1cmVtZW50IiwiZ2V0RW50aXR5SWNvbiIsImljb24iLCJnZXRXaW5kRGlyZWN0aW9ucyIsIndkIiwiY3djTG9jV2luZERpcmVjdGlvbnMiLCJ3ZE51bWJlciIsImNvbnNvbGUiLCJlcnJvciIsImZsb29yIiwiaW1hZ2VFeGlzdCIsImltYWdlU3JjIiwidGltZW91dCIsInJlc29sdmUiLCJpbWciLCJJbWFnZSIsInRpbWVyIiwic2V0VGltZW91dCIsInNyYyIsIm9ubG9hZCIsImNsZWFyVGltZW91dCIsIm9uZXJyb3IiLCJsb2dJbmZvIiwibWVzc2FnZSIsImluZm8iLCJwYXJzZUxvY2FsaXplZE51bWJlciIsInZhbHVlIiwibm9ybWFsaXplZCIsInJlcGxhY2UiLCJjd2NNb29uUGhhc2VJY29ucyIsIm5ld19tb29uIiwibmV3Iiwid2F4aW5nX2NyZXNjZW50IiwiZmlyc3RfcXVhcnRlciIsIndheGluZ19naWJib3VzIiwiZnVsbCIsImZ1bGxfbW9vbiIsIndhbmluZ19naWJib3VzIiwidGhpcmRfcXVhcnRlciIsImxhc3RfcXVhcnRlciIsIndhbmluZ19jcmVzY2VudCIsImNhcmRTdHlsZSIsInN1bW1hcnlTdHlsZSIsInByZXNlbnRTdHlsZSIsInVsdHJhdmlvbGV0U3R5bGUiLCJwb2xsZW5TdHlsZSIsImNhbWVyYVN0eWxlIiwid2VhdGhlckZvcmVjYXN0U3R5bGUiLCJtZXRlb2RjcGFsYXJtU3R5bGUiLCJnZXRXZWF0aGVySWNvbiIsImNvbmRpdGlvbiIsImljb25zQ29uZmlnIiwic3VuU3RhdGUiLCJpc05pZ2h0IiwiaWNvbk5hbWUiLCJwYXRoIiwiaWNvblR5cGUiLCJpY29uc19tb2RlbCIsImNvbXB1dGVEYXJrTW9kZSIsInRoZW1lcyIsImRhcmtNb2RlIiwiYXN5bmMiLCJwcmVsb2FkUmVzb3VyY2VzIiwiaGFjc1Jlc3VsdCIsIm1hblJlc3VsdCIsImFsbCIsImltYWdlUGF0aCIsInRyYW5zbGF0aW9ucyIsInRyYW5zbFBhdGgiLCJmdWxsX3BhdGhfZmlsZSIsInJlc3BvbnNlIiwiZmV0Y2giLCJvayIsImVyciIsInN0YXR1cyIsInN0YXR1c1RleHQiLCJ0ZXh0IiwibG9hZEpTT04iLCJMb3ZlbGFjZUJhc2VFbGVtZW50IiwiaXNQYW5lbCIsImVkaXRNb2RlIiwiaW52YWxpZENvbmZpZyIsIl9oYXNQcmVzZW50IiwiX2hhc0RhaWx5Rm9yZWNhc3RzIiwiX2hhc0hvdXJseUZvcmVjYXN0cyIsIl9oYXNNYXJpbmVEYWlseUZvcmVjYXN0cyIsIl9oYXNNYXJpbmVIb3VybHlGb3JlY2FzdHMiLCJfaGFzTWV0ZWFsYXJtIiwiX2hhc0RQQ2FsYXJtIiwiX2hhc01ldGVvZ3JhbSIsIl9oYXNBaXJRdWFsaXR5IiwiX2hhc1BvbGxlbiIsIl9oYXNVbHRyYXZpb2xldCIsIl9oYXNBbGVydCIsIl9oYXNTZWEiLCJfaGFzQ2FtZXJhIiwiY2hhbmdlZFByb3BzIiwiY3VycmVudERhcmtNb2RlIiwibmV3RGFya01vZGUiLCJzdW1tYXJ5U3R5bGVzIiwic2V0Q29uZmlnIiwiY29uZmlnIiwiX3RyYW5zbGF0aW9ucyIsIl9pbWFnZXNQYXRoIiwiX25hbWUiLCJ3ZWF0aGVyIiwiX2xhbmd1YWdlIiwibGFuZ3VhZ2UiLCJfbG9hZFRyYW5zbGF0aW9ucyIsIl9kZXRlY3REYXRhU2VjdGlvbnMiLCJfc2V0dXBJY29ucyIsIl9jb25maWciLCJnZXRDYXJkU2l6ZSIsInRyYW5zbHMiLCJfdGVybXMiLCJ3aW5kRGlyZWN0aW9ucyIsIndvcmRzIiwiY3djVGVybXMiLCJmYWxsYmFjayIsInByZXNlbnQiLCJkYWlseV9mb3JlY2FzdHMiLCJob3VybHlfZm9yZWNhc3RzIiwibWFyaW5lX2RhaWx5X2ZvcmVjYXN0cyIsIm1hcmluZV9ob3VybHlfZm9yZWNhc3RzIiwibWV0ZW9hbGFybSIsImRwY2FsYXJtIiwiYWlycXVhbGl0eSIsInBvbGxlbiIsImVudGl0aWVzIiwidWx0cmF2aW9sZXQiLCJjYW1lcmEiLCJpY29uc01vZGVsIiwiX2ljb25zQ29uZmlnIiwiYW5pbWF0aW9uIiwibW9kZWxEYXRhIiwibW9kZWxOYW1lIiwid2FybiIsImdldEljb25Nb2RlbERhdGEiLCJodG1sIiwiX3JlbmRlciIsInByb3BlcnR5IiwiYnVpbGRXZWF0aGVyU3VtbWFyeSIsInRlcm1zIiwicHJlc2VudERhdGEiLCJzdW5JZCIsIm1vb25waGFzZSIsIm1vb25QaGFzZSIsIm1vb25JY29uIiwic3VuIiwiY3VycmVudENvbmRpdGlvbnMiLCJ0ZW1wZXJhdHVyZSIsInRlbXBlcmF0dXJlRmVlbHNMaWtlIiwidGVtcGVyYXR1cmVfZmVlbHNsaWtlIiwidGVtcGVyYXR1cmVGZWVsc0xpa2VJY29uIiwicmVuZGVyV2VhdGhlclN1bW1hcnkiLCJ0aXRsZSIsIm1vb25UZXh0IiwiY29uZGl0aW9uVGV4dCIsImNvbmRpdGlvbkljb24iLCJ0ZW1wZXJhdHVyZVVuaXQiLCJmZWVsc0xpa2VUZXJtIiwibm90aGluZyIsImlzVmFsaWRJbnB1dCIsInZhbCIsInByZXBhcmVXZWF0aGVyUHJlc2VudCIsImFsbEl0ZW1zIiwicGkiLCJwcmVjaXBpdGF0aW9uSW50ZW5zaXR5IiwicHAiLCJwcmVjaXBpdGF0aW9uUHJvYmFiaWxpdHkiLCJwYXJzZWRQSSIsInBhcnNlZFBQIiwidW5pdCIsInRlbXBlcmF0dXJlTG93IiwidGVtcGVyYXR1cmVIaWdoIiwiYWRkSWZWYWxpZCIsIml0ZW0iLCJ3aW5kU3BlZWQiLCJ3aW5kQmVhcmluZyIsInByZXBhcmVBaXJRdWFsaXR5IiwicmVuZGVyV2VhdGhlclByZXNlbnQiLCJidWlsZEJsb2NrUmlnaHQiLCJpY29uX2NvbG9yIiwicm93cyIsImxlZnQiLCJyaWdodCIsImJ1aWxkV2VhdGhlclByZXNlbnQiLCJzZWxlY3RlZExhbmd1YWdlIiwicHJlc2VudE9iaiIsImxvY2FsZUluZm8iLCJzdW5FbnRpdHkiLCJuZXh0X3Jpc2luZyIsIm5leHRfc2V0dGluZyIsIm5leHRSaXNpbmciLCJEYXRlIiwidG9Mb2NhbGVUaW1lU3RyaW5nIiwiaG91ciIsIm1pbnV0ZSIsInNlY29uZCIsImhvdXIxMiIsInRpbWVab25lIiwibmV4dFNldHRpbmciLCJwcmVjaXBpdGF0aW9uX2ludGVuc2l0eSIsInByZWNpcGl0YXRpb25fcHJvYmFiaWxpdHkiLCJodW1pZGl0eSIsIndpbmRfYmVhcmluZyIsIndpbmRfc3BlZWQiLCJwcmVzc3VyZSIsInZpc2liaWxpdHkiLCJ0ZW1wZXJhdHVyZV9tYXgiLCJ0ZW1wZXJhdHVyZV9taW4iLCJudW0iLCJjb2xvcnMiLCJyZW5kZXJVbHRyYXZpb2xldCIsInNraW5EYXRhIiwiY3VycmVudFVWSW5kZXgiLCJtYXhVVkluZGV4Iiwic3VtbWFyeVJvd3MiLCJza2luVHlwZXMiLCJza2luVHlwZTEiLCJza2luVHlwZTIiLCJza2luVHlwZTMiLCJza2luVHlwZTQiLCJza2luVHlwZTUiLCJza2luVHlwZTYiLCJyZW5kZXJTa2luR3JpZCIsImJnQ29sb3IiLCJ0ZXh0Q29sb3IiLCJoZXgiLCJwYXJzZUludCIsInN1YnN0ciIsImdldFRleHRDb2xvciIsImdldFRpbWUiLCJOYU4iLCJpc0Zpbml0ZSIsImhvdXJzIiwibWludXRlcyIsIndpZHRoIiwicGFkU3RhcnQiLCJwYWQiLCJzdW1tYXJ5RGF0YSIsInV2IiwicHJvdGVjdGlvbldpbmRvdyIsInByb3RlY3Rpb25fd2luZG93IiwiY3VycmVudFVWTGV2ZWwiLCJ1dl9sZXZlbCIsInV2X2luZGV4IiwibWF4X3V2X2luZGV4IiwiY3VycmVudE96b25lTGV2ZWwiLCJvem9uZV9sZXZlbCIsInNldF9za2luX3R5cGVfMSIsInNldF9za2luX3R5cGVfMiIsInNldF9za2luX3R5cGVfMyIsInNldF9za2luX3R5cGVfNCIsInNldF9za2luX3R5cGVfNSIsInNldF9za2luX3R5cGVfNiIsIkxFVkVMX05BTUVTIiwicmVuZGVyUG9sbGVuIiwibGV2ZWxNaW4iLCJsZXZlbE1heCIsIm51bUxldmVscyIsImxldmVscyIsImFjdGl2ZUluZGV4IiwiZ2V0TGV2ZWxJbmRleCIsInN0ZXAiLCJtaW4iLCJsZXZlbE5hbWUiLCJidWlsZFBvbGxlbiIsInJhd3ZhbHVlIiwiZW50aXR5Iiwic3RyaW5nMk51bWJlciIsImlucHV0IiwiZm9ybWF0VG9QYXJ0cyIsImdyb3VwIiwicGFydCIsImRlY2ltYWwiLCJtYXgiLCJyZW5kZXJXZWF0aGVyRm9yZWNhc3QiLCJmb3JlY2FzdFR5cGUiLCJkYXlEYXRhIiwiZGF5IiwicmVmZXJlbmNlIiwiaWNvbkNvbG9yIiwidGVtcExvdyIsInRlbXBlcmF0dXJlX2xvdyIsInRlbXBIaWdoIiwidGVtcGVyYXR1cmVfaGlnaCIsInRlbXBITFVuaXQiLCJwcmVjaXBQcm9iIiwicHJlY2lwSW50IiwicHJlY2lwVW5pdCIsInRlbXAiLCJ0ZW1wVW5pdCIsInRlbXBfZmVlbHNsaWtlIiwid2luZF9zcGVlZFVuaXQiLCJ3aW5kX3dhdmVfaGVpZ2h0X21heCIsInN3ZWxsX3dhdmVfaGVpZ2h0X21heCIsIndhdmVfaGVpZ2h0X21heCIsIndhdmVfZGlyZWN0aW9uIiwid2F2ZV9kaXJlY3Rpb25fZGVncmVlcyIsIndhdmVfaGVpZ2h0X21heF91bml0IiwiZ2V0RGVmYXVsdEljb24iLCJtZXRyaWMiLCJpbmNsdWRlcyIsImJ1aWxkV2VhdGhlckZvcmVjYXN0IiwiZGFpbHlGb3JlY2FzdCIsImhvdXJseUZvcmVjYXN0IiwibWFyaW5lRGFpbHlGb3JlY2FzdHMiLCJtYXJpbmVIb3VybHlGb3JlY2FzdHMiLCJzdW5FbnRpdHlJZCIsInZvaWRSZWNvcmQiLCJkYWlseUZvcmVjYXN0RGF0YSIsInNsb3RJZCIsImJ1aWxkRGFpbHlGb3JlY2FzdFNsb3QiLCJmb3JlY2FzdCIsInJlY29yZCIsImRhdGV0aW1lIiwibWV0cmljS2V5IiwibWV0cmljU2xvdHMiLCJ3ZWVrZGF5IiwidG9Mb2NhbGVEYXRlU3RyaW5nIiwiaG91cmRheSIsImhvdXJseWZvcmVjYXN0RGF0YSIsImJ1aWxkSG91cmx5Rm9yZWNhc3RTbG90IiwiaG91clRpbWUiLCJtYXJpbmVEYWlseUZvcmVjYXN0RGF0YSIsImJ1aWxkTWFyaW5lRGFpbHlGb3JlY2FzdFNsb3QiLCJmaWVsZENvbG9yIiwid2F2ZUhlaWdodE1heCIsInN3ZWxsV2F2ZUhlaWdodE1heCIsIndpbmRXYXZlSGVpZ2h0TWF4IiwiYnVpbGRDYW1lcmEiLCJoYW5kbGVQb3B1cCIsImNhbWVyYUlkIiwiZW50aXR5UGljdHVyZSIsImVudGl0eV9waWN0dXJlIiwicmVuZGVyQ2FtZXJhIiwiY2FtZXJhUGljdHVyZSIsImZyaWVuZGx5TmFtZSIsImZyaWVuZGx5X25hbWUiLCJidWlsZE1ldGVvQWxhcm1EYXRhIiwibWV0ZW9hbGFybUlkIiwiZXZlbnRJY29uIiwiYXZhbGFuY2hlIiwiZmxvb2QiLCJkcm91Z2h0IiwiZXZlbnRJY29uQ29sb3IiLCJncmVlbiIsInllbGxvdyIsIm9yYW5nZSIsInJlZCIsImZwY0RhdGEiLCJldmVudCIsInNldmVyaXR5IiwiYXdhcmVuZXNzX3R5cGUiLCJhd2FyZW5lc3NfbGV2ZWwiLCJlZmZlY3RpdmUiLCJhd2FyZW5lc3NUeXBlIiwidHJpbSIsImF3YXJlbmVzc0xldmVsIiwiZXZlbnROYW1lIiwic2V2ZXJpdHlMZXZlbCIsImVmZmVjdGl2ZURhdGV0aW1lIiwibm93IiwidG9kYXkiLCJnZXRGdWxsWWVhciIsImdldE1vbnRoIiwiZ2V0RGF0ZSIsImVmZmVjdGl2ZURhdGUiLCJkYXlEaWZmZXJlbmNlIiwicm91bmQiLCJlZmZlY3RpdmVMYWJlbCIsImdldEVmZmVjdGl2ZUxhYmVsIiwidG9Mb2NhbGVVcHBlckNhc2UiLCJidWlsZERQQ0FsYXJtRGF0YSIsImxldmVsIiwiYnVpbGRNZXRlb0RQQ2FsYXJtIiwiYWxhcm1zRGF0YSIsIm1ldGVvRFBDYWxhcm1EYXRhIiwiZW50cmllcyIsIkhhQ2FyZFdlYXRoZXJDb25kaXRpb25zIiwiX2J1aWxkVGVtcGxhdGUiLCJzdW1tYXJ5IiwiZGFpbHlXZWF0aGVyRm9yZWNhc3QiLCJob3VybHlXZWF0aGVyRm9yZWNhc3QiLCJtYXJpbmVEYWlseVdlYXRoZXJGb3JlY2FzdCIsIm1hcmluZUhvdXJseVdlYXRoZXJGb3JlY2FzdCIsIm1ldGVvRFBDYWxhcm0iLCJhaXJRdWFsaXR5IiwiZ2V0V2VhdGhlckZvcmVjYXN0IiwiYnVpbGRVbHRyYXZpb2xldCIsImJ1aWxkQWlyUXVhbGl0eSIsInBtMjUiLCJwbTEwIiwibzMiLCJubzIiLCJjbyIsInNvMiIsImVwYV9hcWkiLCJlcGFfcHJpbWFyeV9wb2xsdXRhbnQiLCJhaXJRdWFsaXR5RGF0YSIsImFxaSIsIl9oYW5kbGVQb3B1cCIsImJpbmQiLCJzdG9wUHJvcGFnYXRpb24iLCJtb3JlSW5mb0V2ZW50IiwiRXZlbnQiLCJjb21wb3NlZCIsImRldGFpbCIsImRpc3BhdGNoRXZlbnQiLCJjdXN0b21FbGVtZW50cyIsImRlZmluZSIsImN1c3RvbUVsZW1lbnQiXSwibWFwcGluZ3MiOiJBQXNETyxTQUFTQSxFQUFXQyxFQUFZQyxFQUFRQyxFQUFLQyxHQUNoRCxJQUEySEMsRUFBdkhDLEVBQUlDLFVBQVVDLE9BQVFDLEVBQUlILEVBQUksRUFBSUosRUFBa0IsT0FBVEUsRUFBZ0JBLEVBQU9NLE9BQU9DLHlCQUF5QlQsRUFBUUMsR0FBT0MsRUFDckgsR0FBdUIsaUJBQVpRLFNBQW9ELG1CQUFyQkEsUUFBUUMsU0FBeUJKLEVBQUlHLFFBQVFDLFNBQVNaLEVBQVlDLEVBQVFDLEVBQUtDLFFBQ3BILElBQUssSUFBSVUsRUFBSWIsRUFBV08sT0FBUyxFQUFHTSxHQUFLLEVBQUdBLEtBQVNULEVBQUlKLEVBQVdhLE1BQUlMLEdBQUtILEVBQUksRUFBSUQsRUFBRUksR0FBS0gsRUFBSSxFQUFJRCxFQUFFSCxFQUFRQyxFQUFLTSxHQUFLSixFQUFFSCxFQUFRQyxLQUFTTSxHQUNoSixPQUFPSCxFQUFJLEdBQUtHLEdBQUtDLE9BQU9LLGVBQWViLEVBQVFDLEVBQUtNLEdBQUlBLENBQ2hFLENBNlFrRCxtQkFBcEJPLGlCQUFpQ0E7Ozs7OztBQ25VL0QsTUFBTUMsRUFBRUMsV0FBV0MsRUFBRUYsRUFBRUcsa0JBQWEsSUFBU0gsRUFBRUksVUFBVUosRUFBRUksU0FBU0MsZUFBZSx1QkFBdUJDLFNBQVNDLFdBQVcsWUFBWUMsY0FBY0QsVUFBVUUsRUFBRUMsU0FBU0MsRUFBRSxJQUFJQyxRQUFRLElBQUFD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QUVSd1ksR0FBSSxDQUNGaFgsTUFBUWdYLEVBQUssTUFBTUEsSUFBT0EsRUFDMUI5TixLQUFNN0ssR0FBY1IsRUFBTXVJLEVBQVc0USxLQUFPLFFBQzVDeFksS0FBTSxnQkFFUnlZLElBQUssQ0FDSGpYLE1BQVFpWCxFQUFNLE9BQU9BLElBQVFBLEVBQzdCL04sS0FBTTdLLEdBQWNSLEVBQU11SSxFQUFXNlEsTUFBUSxRQUM3Q3pZLEtBQU0sZ0JBRVIwWSxHQUFJLENBQ0ZsWCxNQUFRa1gsRUFBSyxNQUFNQSxJQUFPQSxFQUMxQmhPLEtBQU03SyxHQUFjUixFQUFNdUksRUFBVzhRLEtBQU8sUUFDNUMxWSxLQUFNLGdCQUVSMlksSUFBSyxDQUNIblgsTUFBUW1YLEVBQU0sT0FBT0EsSUFBUUEsRUFDN0JqTyxLQUFNN0ssR0FBY1IsRUFBTXVJLEVBQVcrUSxNQUFRLFFBQzdDM1ksS0FBTSxnQkFFUjRZLFFBQVMsQ0FDUHBYLE1BQVFvWCxFQUFVLHFCQUFxQkEsSUFBWUEsRUFFbkQ1WSxLQUFNLG1CQUNOb0wsWUFuRWUyTixFQW1FU3Z1QixPQUFPNFUsR0FBa0JDLEVBQU11SSxFQUFXZ1IsVUFsRWxFRyxHQUFPLEdBQ0YsVUFDRUEsR0FBTyxJQUNULFVBQ0VBLEdBQU8sSUFDVCxVQUNFQSxHQUFPLElBQ1QsVUFDRUEsR0FBTyxJQUNULFVBRUEsWUF5RFBGLHNCQUF1QixDQUNyQnJYLE1BQVFxWCxFQUF3QixXQUFXQSxJQUEwQkEsRUFFckU3WSxLQUFNLHFCQXhFWixJQUFxQitZLEVBNEVuQixPQUFPN04sR0FBcUI0TixFQUFnQmhiLEVBQUssRUc2QmhDdWEsQ0FBZ0IzdkIsS0FBSzJXLEtBQU0zVyxLQUFLOGQsVUFBVzlkLEtBQUttZSxRQUFRZSxhQUduRWxmLEtBQUttZCxhQUNQbUMsRUFBU3lNLEdBQVkvckIsS0FBSzJXLEtBQU0zVyxLQUFLOGQsVUFBVzlkLEtBQUtzZSxPQUFRdGUsS0FBS3N3QixhQUFhQyxLQUFLdndCLE1BQU9BLEtBQUttZSxRQUFRbUIsU0FHbkdRLENBQUk7TUFDVG9QO01BQ0F2UTtNQUNBeVE7TUFDQUQ7TUFDQUc7TUFDQUQ7TUFDQUU7TUFDQXBRO01BQ0FFO01BQ0FtUTtNQUNBbFEsR0FDSixDQU9VZ1IsWUFBQUEsQ0FBYW54QixFQUFVeVgsR0FDL0J6WCxFQUFFcXhCLGtCQUdGLE1BQU1DLEVBQWdCLElBQUlDLE1BQU0saUJBQWtCLENBQUVDLFVBQVUsSUFDOURGLEVBQWNHLE9BQVMsQ0FBRWhhLFlBQ3pCNVcsS0FBSzZ3QixjQUFjSixFQUNyQixHQWxJV3pCLEdBQXVCaHhCLEVBQUEsQ3RDaEI1QmlCLElBQUcsQ0FBQ0UsRUFBRVMsY0FBY0EsRUFBRUEsRUFBRWlELGdCQUFnQixLQUFLaXVCLGVBQWVDLE9BQU85eEIsRUFBRUUsRUFBRyxJQUFHMnhCLGVBQWVDLE9BQU85eEIsRUFBRUUsSXNDYzFHNnhCLENBQWMsK0JBRUZoQyIsInhfZ29vZ2xlX2lnbm9yZUxpc3QiOlswLDEsMiwzLDQsNSw2XX0=\n"
  },
  {
    "path": "dist/transl/cs.json",
    "content": "{\n  \"cwcLocWindDirections\": {\n    \"N\": \"S\",\n    \"NNE\": \"SSV\",\n    \"NE\": \"SV\",\n    \"ENE\": \"VSV\",\n    \"E\": \"V\",\n    \"ESE\": \"VJV\",\n    \"SE\": \"JV\",\n    \"SSE\": \"JJV\",\n    \"S\": \"J\",\n    \"SSW\": \"JJZ\",\n    \"SW\": \"JZ\",\n    \"WSW\": \"ZJZ\",\n    \"W\": \"Z\",\n    \"WNW\": \"ZSZ\",\n    \"NW\": \"SZ\",\n    \"NNW\": \"SSZ\"\n  },\n\n  \"cwcTerms\": {\n    \"Feels Like\" : \"Pocitová teplota\",\n    \"new_moon\": \"Nov\",\n    \"new\": \"Nov\",\n    \"waxing_crescent\": \"Dorůstající srpek\",\n    \"first_quarter\": \"První čtvrť\",\n    \"waxing_gibbous\": \"Dorůstající měsíc\",\n    \"full\": \"Úplněk\",\n    \"full_moon\": \"Úplněk\",\n    \"waning_gibbous\": \"Couvající měsíc\",\n    \"third_quarter\": \"Třetí čtvrť\",\n    \"last_quarter\": \"Poslední čtvrť\",\n    \"waning_crescent\": \"Ubývající srpek\"\n  }\n}"
  },
  {
    "path": "dist/transl/da.json",
    "content": "{\n  \"cwcLocWindDirections\": {\n    \"N\": \"N\",\n    \"NNE\": \"NNØ\",\n    \"NE\": \"NØ\",\n    \"ENE\": \"ØNØ\",\n    \"E\": \"Ø\",\n    \"ESE\": \"ØSØ\",\n    \"SE\": \"SØ\",\n    \"SSE\": \"SSØ\",\n    \"S\": \"S\",\n    \"SSW\": \"SSV\",\n    \"SW\": \"SV\",\n    \"WSW\": \"VSV\",\n    \"W\": \"V\",\n    \"WNW\": \"VNV\",\n    \"NW\": \"NV\",\n    \"NNW\": \"NNV\"\n  },\n\n  \"cwcTerms\": {\n    \"Feels Like\" : \"Føles som\",\n    \"new_moon\": \"Nymåne\",\n    \"new\": \"Nymåne\",\n    \"waxing_crescent\": \"Tiltagende halvmåne\",\n    \"first_quarter\": \"Første kvartal\",\n    \"waxing_gibbous\": \"Tiltagende måne\",\n    \"full\": \"Fuldmåne\",\n    \"full_moon\": \"Fuldmåne\",\n    \"waning_gibbous\": \"Aftagende måne\",\n    \"third_quarter\": \"Tredje kvartal\",\n    \"last_quarter\": \"Sidste kvartal\",\n    \"waning_crescent\": \"Aftagende halvmåne\"\n  }\n}"
  },
  {
    "path": "dist/transl/de.json",
    "content": "{\n  \"cwcLocWindDirections\": {\n    \"N\": \"N\", \n    \"NNE\": \"NNO\", \n    \"NE\": \"NO\",\n    \"ENE\": \"ONO\", \n    \"E\": \"O\", \n    \"ESE\": \"OSO\", \n    \"SE\": \"SO\",\n    \"SSE\": \"SSO\", \n    \"S\": \"S\", \n    \"SSW\": \"SSW\", \n    \"SW\": \"SW\", \n    \"WSW\": \"WSW\", \n    \"W\": \"W\",\n    \"WNW\": \"WNW\", \n    \"NW\": \"NW\",\n    \"NNW\": \"NNW\"\n  },\n\n  \"cwcTerms\": {\n    \"Feels Like\" : \"Gefühlt\",\n    \"new_moon\": \"Neumond\",\n    \"new\": \"Neumond\",\n    \"waxing_crescent\": \"Zunehmende Sichel\",\n    \"first_quarter\": \"Erstes Viertel\",\n    \"waxing_gibbous\": \"Zunehmender Halbmond\",\n    \"full\": \"Vollmond\",\n    \"full_moon\": \"Vollmond\",\n    \"waning_gibbous\": \"Abnehmender Halbmond\",\n    \"third_quarter\": \"Drittes Viertel\",\n    \"last_quarter\": \"Letztes Viertel\",\n    \"waning_crescent\": \"Abnehmende Sichel\"\n  }\n}"
  },
  {
    "path": "dist/transl/en.json",
    "content": "{\n  \"cwcLocWindDirections\": {\n    \"N\": \"N\",\n    \"NNE\": \"NNE\",\n    \"NE\": \"NE\",\n    \"ENE\": \"ENE\",\n    \"E\": \"E\",\n    \"ESE\": \"ESE\",\n    \"SE\": \"SE\",\n    \"SSE\": \"SSE\",\n    \"S\": \"S\",\n    \"SSW\": \"SSW\",\n    \"SW\": \"SW\",\n    \"WSW\": \"WSW\",\n    \"W\": \"W\",\n    \"WNW\": \"WNW\",\n    \"NW\": \"NW\",\n    \"NNW\": \"NNW\"\n  },\n\n  \"cwcTerms\": {\n    \"Feels Like\" : \"Feels Like\",\n    \"new_moon\": \"New moon\",\n    \"new\": \"New moon\",\n    \"waxing_crescent\": \"Waxing crescent\",\n    \"first_quarter\": \"First quarter\",\n    \"waxing_gibbous\": \"Waxing Gibbous\",\n    \"full\": \"Full\",\n    \"full_moon\": \"Full\",\n    \"waning_gibbous\": \"Waning Gibbous\",\n    \"third_quarter\": \"Third Quarter\",\n    \"last_quarter\": \"Last Quarter\",\n    \"waning_crescent\": \"Waning Crescent\"\n  }\n}"
  },
  {
    "path": "dist/transl/es.json",
    "content": "{\n\"cwcLocWindDirections\": {\n\"N\": \"N\",\n\"NNE\": \"NNE\",\n\"NE\": \"NE\",\n\"ENE\": \"ENE\",\n\"E\": \"E\",\n\"ESE\": \"ESE\",\n\"SE\": \"SE\",\n\"SSE\": \"SSE\",\n\"S\": \"S\",\n\"SSW\": \"SSO\",\n\"SW\": \"SO\",\n\"WSW\": \"OSO\",\n\"W\": \"O\",\n\"WNW\": \"ONO\",\n\"NW\": \"NO\",\n\"NNW\": \"NNO\"\n},\n\n\"cwcTerms\": {\n\"Feels Like\" : \"Sensación térmica\",\n\"new_moon\": \"Luna nueva\",\n\"new\": \"Luna nueva\",\n\"waxing_crescent\": \"Luna creciente\",\n\"first_quarter\": \"Cuarto creciente\",\n\"waxing_gibbous\": \"Luna menguante gibosa\",\n\"full\": \"Luna llena\",\n\"full_moon\": \"Luna llena\",\n\"waning_gibbous\": \"Luna menguante gibosa\",\n\"third_quarter\": \"Media luna\",\n\"last_quarter\": \"Cuarto menguante\",\n\"waning_crescent\": \"Luna menguante\"\n}\n}"
  },
  {
    "path": "dist/transl/fr.json",
    "content": "{\n  \"cwcLocWindDirections\": {\n    \"N\": \"N\",\n    \"NNE\": \"NNE\",\n    \"NE\": \"NE\",\n    \"ENE\": \"ENE\",\n    \"E\": \"E\",\n    \"ESE\": \"ESE\",\n    \"SE\": \"SE\",\n    \"SSE\": \"SSE\",\n    \"S\": \"S\",\n    \"SSW\": \"SSO\",\n    \"SW\": \"SO\",\n    \"WSW\": \"OSO\",\n    \"W\": \"O\",\n    \"WNW\": \"ONO\",\n    \"NW\": \"NO\",\n    \"NNW\": \"NNO\"\n  },\n\n  \"cwcTerms\": {\n    \"Feels Like\" : \"Ressentie\", \n    \"new_moon\": \"Nouvelle lune\", \n    \"new\": \"Nouvelle lune\", \n    \"waxing_crescent\": \"Premier croissant\", \n    \"first_quarter\": \"Premier quartier\",\n    \"waxing_gibbous\": \"Gibbeuse croissante\",\n    \"full\": \"Pleine lune\",\n    \"full_moon\": \"Pleine lune\",\n    \"waning_gibbous\": \"Gibbeuse décroissante\",\n    \"third_quarter\": \"Dernier quartier\",\n    \"last_quarter\": \"Dernier quartier\",\n    \"waning_crescent\": \"Lune décroissante\"\n  }\n}"
  },
  {
    "path": "dist/transl/it.json",
    "content": "{\n  \"cwcLocWindDirections\": {\n    \"N\": \"N\", \n    \"NNE\": \"NNE\",\n    \"NE\": \"NE\", \n    \"ENE\": \"ENE\", \n    \"E\": \"E\",\n    \"ESE\": \"ESE\", \n    \"SE\": \"SE\", \n    \"SSE\": \"SSE\",\n    \"S\": \"S\", \n    \"SSW\": \"SSO\", \n    \"SW\": \"SO\", \n    \"WSW\": \"OSO\", \n    \"W\": \"O\", \n    \"WNW\": \"ONO\", \n    \"NW\": \"NO\", \n    \"NNW\": \"NNO\"\n  },\n\n  \"cwcTerms\": {\n    \"Feels Like\" : \"Percepita\", \n    \"new_moon\": \"Novilunio\", \n    \"new\": \"Novilunio\", \n    \"waxing_crescent\": \"Luna crescente\", \n    \"first_quarter\": \"Primo Quarto\",\n    \"waxing_gibbous\": \"Gibbosa crescente\", \n    \"full\": \"Luna piena\",\n    \"full_moon\": \"Luna piena\",\n    \"waning_gibbous\": \"Gibbosa calante\", \n    \"third_quarter\": \"Ultimo quarto\", \n    \"last_quarter\": \"Ultimo quarto\", \n    \"waning_crescent\": \"Luna calante\"\n  }\n}"
  },
  {
    "path": "dist/transl/nl.json",
    "content": "{\n  \"cwcLocWindDirections\": {\n    \"N\": \"N\",\n    \"NNE\": \"NNO\",\n    \"NE\": \"NO\",\n    \"ENE\": \"ONO\",\n    \"E\": \"O\",\n    \"ESE\": \"OZO\",\n    \"SE\": \"ZO\",\n    \"SSE\": \"ZZO\",\n    \"S\": \"Z\",\n    \"SSW\": \"ZZW\",\n    \"SW\": \"ZW\",\n    \"WSW\": \"WZW\",\n    \"W\": \"W\",\n    \"WNW\":  \"WNW\",\n    \"NW\": \"NW\",\n    \"NNW\": \"NNW\"\n  },\n\n  \"cwcTerms\": {\n    \"Feels Like\": \"Voelt Als\",\n    \"new_moon\": \"Nieuwe maan\",\n    \"new\": \"Nieuwe maan\",\n    \"waxing_crescent\": \"Wassende halve maan\",\n    \"first_quarter\": \"Eerste kwartier\",\n    \"waxing_gibbous\": \"Wassende maan\",\n    \"full\": \"Volle maan\",\n    \"full_moon\": \"Volle maan\",\n    \"waning_gibbous\": \"Afnemende maan\",\n    \"third_quarter\": \"Derde Kwartier\",\n    \"last_quarter\": \"Laatste Kwartier\",\n    \"waning_crescent\": \"Afnemende halve maan\"\n  }\n}"
  },
  {
    "path": "dist/transl/no-NO.json",
    "content": "{\n  \"cwcLocWindDirections\": {\n    \"N\": \"N\",\n    \"NNE\": \"NNØ\",\n    \"NE\": \"NØ\",\n    \"ENE\": \"ØNØ\",\n    \"E\": \"Ø\",\n    \"ESE\": \"ØSØ\",\n    \"SE\": \"SØ\",\n    \"SSE\": \"SSØ\",\n    \"S\": \"S\",\n    \"SSW\": \"SSV\",\n    \"SW\": \"SV\",\n    \"WSW\": \"VSV\",\n    \"W\": \"V\",\n    \"WNW\": \"VNV\",\n    \"NW\": \"NV\",\n    \"NNW\": \"NNV\"\n  },\n\n  \"cwcTerms\": {\n    \"Feels Like\" : \"Føles som\",\n    \"new_moon\": \"Nymåne\",\n    \"new\": \"Nymåne\",\n    \"waxing_crescent\": \"Tiltagende halvmåne\",\n    \"first_quarter\": \"Første kvartal\",\n    \"waxing_gibbous\": \"Tiltagende måne\",\n    \"full\": \"Fullmåne\",\n    \"full_moon\": \"Fullmåne\",\n    \"waning_gibbous\": \"Avtagende måne\",\n    \"third_quarter\": \"Tredje kvartal\",\n    \"last_quarter\": \"Sidste kvartal\",\n    \"waning_crescent\": \"Avtagende halvmåne\"\n  }\n}"
  },
  {
    "path": "dist/transl/pt.json",
    "content": "{\n  \"cwcLocWindDirections\": {\n    \"N\": \"N\",\n    \"NNE\": \"NNE\",\n    \"NE\": \"NE\",\n    \"ENE\": \"ENE\",\n    \"E\": \"E\",\n    \"ESE\": \"ESE\",\n    \"SE\": \"SE\",\n    \"SSE\": \"SSE\",\n    \"S\": \"S\",\n    \"SSW\": \"SSW\",\n    \"SW\": \"SW\",\n    \"WSW\": \"WSW\",\n    \"W\": \"W\",\n    \"WNW\": \"WNW\",\n    \"NW\": \"NW\",\n    \"NNW\": \"NNW\"\n  },\n\n  \"cwcTerms\": {\n    \"Feels Like\" : \"Sentida\",\n    \"new_moon\": \"Lua Nova\",\n    \"new\": \"Lua nova\",\n    \"waxing_crescent\": \"Lua Crescente\",\n    \"first_quarter\": \"Quarto Crescente\",\n    \"waxing_gibbous\": \"Crescente Gibosa\",\n    \"full\": \"Lua Cheia\",\n    \"full_moon\": \"Lua Cheia\",\n    \"waning_gibbous\": \"Minguante Gibosa\",\n    \"third_quarter\": \"Quarto Minguante\",\n    \"last_quarter\": \"Quarto Minguante\",\n    \"waning_crescent\": \"Lua Minguante\"\n  }\n}"
  },
  {
    "path": "dist/transl/ru.json",
    "content": "{\n  \"cwcLocWindDirections\": {\n    \"N\": \"С\",\n    \"NNE\": \"ССВ\",\n    \"NE\": \"СВ\",\n    \"ENE\": \"ВСВ\",\n    \"E\": \"В\",\n    \"ESE\": \"ВЮВ\",\n    \"SE\": \"ЮВ\",\n    \"SSE\": \"ЮЮВ\",\n    \"S\": \"Ю\",\n    \"SSW\": \"ЮЮЗ\",\n    \"SW\": \"ЮЗ\",\n    \"WSW\": \"ЗЮЗ\",\n    \"W\": \"З\",\n    \"WNW\": \"ЗСЗ\",\n    \"NW\": \"СЗ\",\n    \"NNW\": \"ССЗ\"\n  },\n\n  \"cwcTerms\": {\n    \"Feels Like\" : \"Ощущается как\",\n    \"new_moon\": \"Новолуние\",\n    \"new\": \"Новолуние\",\n    \"waxing_crescent\": \"Растущий серп\",\n    \"first_quarter\": \"Первая четверть\",\n    \"waxing_gibbous\": \"Растущая луна\",\n    \"full\": \"Полнолуние\",\n    \"full_moon\": \"Полнолуние\",\n    \"waning_gibbous\": \"Убывающая луна\",\n    \"third_quarter\": \"Третья четверть\",\n    \"last_quarter\": \"Последняя четверть\",\n    \"waning_crescent\": \"Убывающая луна\"\n  }\n}"
  },
  {
    "path": "dist/transl/sr-latn.json",
    "content": "{\n  \"cwcLocWindDirections\": {\n    \"N\": \"S\",\n    \"NNE\": \"SSI\",\n    \"NE\": \"SI\",\n    \"ENE\": \"ISI\",\n    \"E\": \"I\",\n    \"ESE\": \"IJI\",\n    \"SE\": \"JI\",\n    \"SSE\": \"JJI\",\n    \"S\": \"J\",\n    \"SSW\": \"JJZ\",\n    \"SW\": \"JZ\",\n    \"WSW\": \"ZSZ\",\n    \"W\": \"Z\",\n    \"WNW\": \"ZSZ\",\n    \"NW\": \"SZ\",\n    \"NNW\": \"SSZ\"\n  },\n\n  \"cwcTerms\": {\n    \"Feels Like\" : \"Subjektivni osećaj\",\n    \"new_moon\": \"Mlad mesec\",\n    \"new\": \"Mlad mesec\",\n    \"waxing_crescent\": \"Prva osmina\",\n    \"first_quarter\": \"Prva četvrt\",\n    \"waxing_gibbous\": \"Treća osmina\",\n    \"full\": \"Pun mesec\",\n    \"full_moon\": \"Pun mesec\",\n    \"waning_gibbous\": \"Peta osmina\",\n    \"third_quarter\": \"Treća četvrtina\",\n    \"last_quarter\": \"Zadnja četvrtina\",\n    \"waning_crescent\": \"Sedma osmina\"\n  }\n}"
  },
  {
    "path": "hacs.json",
    "content": "{\n  \"name\": \"HA (Lovelace) Card Weather Conditions\",\n  \"domains\": [\"weather\"],\n  \"render_readme\": false,\n  \"filename\": \"ha-card-weather-conditions.js\"\n}"
  },
  {
    "path": "info.md",
    "content": "# Weather Conditions Card\nha-card-weather-conditions is a powerful and flexible Lovelace card for Home Assistant. It integrates a variety of weather-related data sources to present a comprehensive summary and forecast.<br>\n\n[![hacs_badge](https://img.shields.io/badge/HACS-Default-orange.svg)](https://github.com/hacs/integration)\n\n[![License][license-shield]](LICENSE)\n[![Total alerts](https://img.shields.io/lgtm/alerts/g/r-renato/ha-card-weather-conditions.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/r-renato/ha-card-weather-conditions/alerts/)\n[![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/r-renato/ha-card-weather-conditions.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/r-renato/ha-card-weather-conditions/context:javascript)\n\n[![BuyMeCoffee][buymecoffeebadge]][buymecoffee]\n\n## Features\n\n* Current and forecast weather conditions\n* Marine forecast (swell, wave, wind)\n* Ultraviolet radiation index and protection advice\n* Pollen level display (tree, weed, grass)\n* Air quality index with multiple pollutant types\n* Weather alerts (fire, storm, hydrogeological, hydraulic)\n* Meteogram and camera integration\n* Multilingual support\n* Display MeteoAlarm (Early Warnings for Europe) and Dipartimento Protezione Civile (Italy only) Alert\n\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-overview.png\" width=\"100%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n<!-- <p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-full.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-1.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-2.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>     -->\n\n## **Card Configuration**\n\nTo use the ```ha-card-weather-conditions``` card, add the following configuration to your ```lovelace``` dashboard:\n\n```yaml\nresources:\n  # Required: Load the card if installed via HACS\n  - url: /hacsfiles/ha-card-weather-conditions/ha-card-weather-conditions.js\n    type: module\n  # Optional: Load Card Mod to enable advanced styling/customization\n  - url: /hacsfiles/lovelace-card-mod/card-mod.js\n    type: module\n  # ...\n```\n\n## **Card Schema Summary**\n\n| **Parameter** | **Type**  | **Required** | **Default** | **Description**                                                                                            |\n| ------------- | --------- | ------------ | ----------- | ---------------------------------------------------------------------------------------------------------- |\n| `type`        | `string`  | Yes          | —           | Must be set to `custom:ha-card-weather-conditions`.                                                        |\n| `language`    | `string`  | No           | `en`        | Language for labels. Supported values: `en`, `it`, `nl`, `es`, `de`, `fr`, `sr-latn`, `pt`, `da`, `no-NO`, `cs`. |\n| `weather`     | `object`  | No           | —           | Configuration for main weather source. See dedicated section.                                              |\n| `ultraviolet` | `object`  | No           | —           | Configuration for UV index display. See dedicated section for details.                                     |\n| `pollen`      | `object`  | No           | —           | Configuration for pollen levels. See dedicated section.                                                    |\n| `airquality`  | `object`  | No           | —           | Configuration for air quality index. See dedicated section.                                                |\n| `camera`      | `string`  | No           | —           | Entity ID of the camera to display.                                                                        |\n\n## **1 `weather` Object Schema**\nThe following parameters configure the weather object to display current conditions, short-term and long-term forecasts, as well as related alerts.\nThis card has been tested with weather data provided by `pirateweather`, `climacell`, `darksky` and `openweathermap` integrations.\n| **Name**                  | **Type**  | **Required** | **Default**     | **Description**                                                                                                            |\n| ------------------------- | --------- | ------------ | --------------- | -------------------------------------------------------------------------------------------------------------------------- |\n| `name`                    | `string`  | No           | —               | Name of the location displayed in the summary section.                                                                     |\n| `sun`                     | `string`  | No           | —               | Entity ID for the sun sensor (used to adjust visuals for daylight, sunrise, and sunset).                                   |\n| `moonphase`               | `string`  | No           | —               | Entity ID for the moon phase sensor.                                                                                       |\n| `icons_model`             | `string`  | **Yes**      | `pirateweather` | Icon set to use. Supported values: `pirateweather`, `climacell`, `darksky`, `openweathermap`, `buienradar`, `defaulthass`. |\n| `animation`               | `boolean` | No           | `false`         | Enables visual effects like moving clouds, rain, or waves based on weather conditions.                                     |\n| `present`                 | `object`  | No           | —               | Object containing current weather data (e.g., temperature, humidity, pressure).                                            |\n| `daily_forecasts`         | `object`  | No           | —               | Object containing multi-day weather forecast data.                                                                         |\n| `hourly_forecasts`        | `object`  | No           | —               | Object containing hourly weather forecast data.                                                                            |\n| `marine_daily_forecasts`  | `object`  | No           | —               | Object with daily marine forecast data (e.g., wave height, wind, tides).                                                   |\n| `marine_hourly_forecasts` | `object`  | No           | —               | Object with hourly marine forecast data.                                                                                   |\n| `meteoalarm`              | `string`  | No           | —               | Entity ID from [Meteoalarm](https://meteoalarm.org/) integration for regional weather warnings.                            |\n| `dpcalarm`                | `object`  | No           | —               | Object providing DPC (Protezione Civile) alerts such as thunderstorm or flood risks.                                       |\n\n### **1.1 `present` Object Schema**\nThe present object defines the entities used to display the current weather conditions in the summary section of the card. Each property corresponds to a specific sensor or attribute providing real-time environmental data.\n| **Name**                    |  **Type**  | **Required** | **Default** | **Description**                                                               |\n| --------------------------- | ---------- | ------------ | ----------- | ----------------------------------------------------------------------------- |\n| `condition`                 | `string`   | No           | —           | Entity ID providing the current weather condition (e.g. sunny, cloudy, rain). |\n| `temperature`               | `string`   | No           | —           | Entity ID providing the current temperature.                                  |\n| `temperature_feelslike`     | `string`   | No           | —           | Entity ID providing the perceived (feels-like) temperature.                   |\n| `temperature_min`           | `string`   | No           | —           | Entity ID providing the minimum temperature of the day.                       |\n| `temperature_max`           | `string`   | No           | —           | Entity ID providing the maximum temperature of the day.                       |\n| `humidity`                  | `string`   | No           | —           | Entity ID providing the current humidity level (%).                           |\n| `pressure`                  | `string`   | No           | —           | Entity ID providing the current atmospheric pressure.                         |\n| `visibility`                | `string`   | No           | —           | Entity ID providing the current visibility level.                             |\n| `wind_bearing`              | `string`   | No           | —           | Entity ID providing the wind direction in degrees.                            |\n| `wind_speed`                | `string`   | No           | —           | Entity ID providing the wind speed.                                           |\n| `precipitation_intensity`   | `string`   | No           | —           | Entity ID providing the precipitation rate (e.g. mm/h).                       |\n| `precipitation_probability` | `string`   | No           | —           | Entity ID providing the probability of precipitation (%).                     |\n\n### **1.2 `daily_forecasts` Object Schema**\nThis object defines the structure for multi-day forecast data, where each property can include multiple time slots (e.g. day_1, day_2, day_3…).\n| **Name**                    | **Type**     | **Required** | **Default** | **Description**                                                            |\n| --------------------------- | ------------ | ------------ | ----------- | -------------------------------------------------------------------------- |\n| `condition`                 | `iTimeSlots` | No           | —           | Object containing the weather condition icons or states for each day slot. |\n| `temperature_high`          | `iTimeSlots` | No           | —           | Object containing the daily high temperature values per slot.              |\n| `temperature_low`           | `iTimeSlots` | No           | —           | Object containing the daily low temperature values per slot.               |\n| `precipitation_intensity`   | `iTimeSlots` | No           | —           | Object with the forecasted precipitation amount for each slot.             |\n| `precipitation_probability` | `iTimeSlots` | No           | —           | Object with the probability of precipitation (%) per slot.                 |\n\n### **1.3 `hourly_forecasts` Object Schema**\nThis object defines the structure for hourly weather forecast data. All fields are optional and do not have default values.\n| **Name**                    | **Type**     | **Required** | **Default** | **Description**                                                               |\n| --------------------------- | ------------ | ------------ | ----------- | ----------------------------------------------------------------------------- |\n| `condition`                 | `iTimeSlots` | No           | —           | Object containing the weather condition icons or states for each hourly slot. |\n| `temperature`               | `iTimeSlots` | No           | —           | Object containing the perceived ambient temperature for each hour.            |\n| `temperature_feelslike`     | `iTimeSlots` | No           | —           | Object containing the \"feels like\" temperature values for each hour.          |\n| `precipitation_intensity`   | `iTimeSlots` | No           | —           | Object with forecasted precipitation amount per hour.                         |\n| `precipitation_probability` | `iTimeSlots` | No           | —           | Object with probability of precipitation (%) per hour.                        |\n| `wind_bearing`              | `iTimeSlots` | No           | —           | Object with wind direction (in degrees or cardinal direction) per hour.       |\n| `wind_speed`                | `iTimeSlots` | No           | —           | Object with wind speed values per hour.                                       |\n\n### **1.3.1 `iTimeSlots` Object Schema**\nThis object represents a set of six time slots used to store sequential forecast data (e.g., hourly, daily, etc.).\n| **Name** | **Type** | **Required** | **Description**                                              |\n| -------- | -------- | ------------ | ------------------------------------------------------------ |\n| `slot1`  | `string` | No           | Value for the first time slot (e.g., current or first hour). |\n| `slot2`  | `string` | No           | Value for the second time slot.                              |\n| `slot3`  | `string` | No           | Value for the third time slot.                               |\n| `slot4`  | `string` | No           | Value for the fourth time slot.                              |\n| `slot5`  | `string` | No           | Value for the fifth time slot.                               |\n| `slot6`  | `string` | No           | Value for the sixth time slot.                               |\n\n### **1.4 `dpcalarm` Object Schema**\nThe `dpcalarm` object is used to configure weather-related alerts provided by the Italian Civil Protection Department (DPC), including thunderstorms, hydraulic, and hydrogeological risks. Each property should reference a specific sensor entity ID.\n| **Name**          | **Type** | **Required** | **Description**                                                              |\n| ----------------- | -------- | ------------ | ---------------------------------------------------------------------------- |\n| `thunderstorms`   | `string`   | No           | Entity ID providing thunderstorm alert information from DPC.                 |\n| `hydraulic`       | `string`   | No           | Entity ID providing hydraulic (river/stream flooding) alert information.     |\n| `hydrogeological` | `string`   | No           | Entity ID providing hydrogeological (landslide/soil instability) alert data. |\n\n## **2 `ultraviolet` Object Schema**\nThe ultraviolet object allows you to display UV-related data such as the current index, ozone level, protection window, and safe exposure times for different skin types (I–VI).\n| **Name**            | **Type** | **Required** | **Description**                                                                 |\n| ------------------- | -------- | ------------ | ------------------------------------------------------------------------------- |\n| `protection_window` | `string` | No           | Entity ID providing the time window during which sun protection is recommended. |\n| `ozone_level`       | `string` | No           | Entity ID providing the current atmospheric ozone level.                        |\n| `uv_index`          | `string` | No           | Entity ID providing the current UV index value.                                 |\n| `uv_level`          | `string` | No           | Entity ID describing the UV risk level (e.g. low, moderate, high).              |\n| `max_uv_index`      | `string` | No           | Entity ID providing the maximum forecasted UV index for the day.                |\n| `set_skin_type_1`   | `string` | No           | Entity ID providing sun exposure time recommendation for skin type I.           |\n| `set_skin_type_2`   | `string` | No           | Entity ID providing sun exposure time recommendation for skin type II.          |\n| `set_skin_type_3`   | `string` | No           | Entity ID providing sun exposure time recommendation for skin type III.         |\n| `set_skin_type_4`   | `string` | No           | Entity ID providing sun exposure time recommendation for skin type IV.          |\n| `set_skin_type_5`   | `string` | No           | Entity ID providing sun exposure time recommendation for skin type V.           |\n| `set_skin_type_6`   | `string` | No           | Entity ID providing sun exposure time recommendation for skin type VI.          |\n\n## **3 `pollen` Object Schema**\nThe pollen object provides information about airborne allergens. It defines the range of measured values (`min` and `max`) and includes a list of `entities` describing each pollen type.\n| **Name**   | **Type**        | **Required** | **Description**                                                         |\n| ---------- | --------------- | ------------ | ----------------------------------------------------------------------- |\n| `entities` | `iPollenItem[]` | Yes          | Array of pollen data objects, each representing a specific pollen type. |\n| `min`      | `number`        | Yes          | Minimum expected pollen concentration (used for scaling).               |\n| `max`      | `number`        | Yes          | Maximum expected pollen concentration (used for scaling).               |\n\n## **3.1 `iPollenItem` Object Schema**\nEach `iPollenItem` defines a specific pollen type to be tracked, including a name for display and the corresponding entity ID in Home Assistant.\n| **Name** | **Type** | **Required** | **Description**                                                   |\n| -------- | -------- | ------------ | ----------------------------------------------------------------- |\n| `name`   | `string`   | Yes        | Display name of the pollen type (e.g., “Grass”, “Birch”).         |\n| `entity` | `string`   | Yes        | Home Assistant entity ID providing the pollen concentration data. |\n\n## **4 `airquality` Object Schema**\nThe `airquality` object defines the Home Assistant entity IDs used to monitor various air pollution metrics and EPA health indicators. Each field corresponds to a specific air quality parameter.\n| **Name**                | **Type** | **Required** | **Description**                                                              |\n| ----------------------- | -------- | ------------ | ---------------------------------------------------------------------------- |\n| `pm25`                  | `string` | No           | Entity ID providing PM2.5 (fine particulate matter) concentration.           |\n| `pm10`                  | `string` | No           | Entity ID providing PM10 (coarse particulate matter) concentration.          |\n| `o3`                    | `string` | No           | Entity ID providing Ozone (O₃) concentration.                                |\n| `no2`                   | `string` | No           | Entity ID providing Nitrogen Dioxide (NO₂) concentration.                    |\n| `co`                    | `string` | No           | Entity ID providing Carbon Monoxide (CO) concentration.                      |\n| `so2`                   | `string` | No           | Entity ID providing Sulfur Dioxide (SO₂) concentration.                      |\n| `epa_aqi`               | `string` | No           | Entity ID providing the EPA-computed Air Quality Index.                      |\n| `epa_primary_pollutant` | `string` | No           | Entity ID providing the EPA-designated primary pollutant.                    |\n| `epa_health_concern`    | `string` | No           | Entity ID describing the EPA-assigned health concern level (e.g., moderate). |\n\n## **Card Layers Sample**\nThis section showcases a complete example of the different visual layers supported by the `ha-card-weather-conditions` card.\nEach layer such as summary, weather conditions, air quality, UV index, and alerts—can be configured independently, allowing full control over how and where data appears.\n\nUse this reference as a guide when designing your Lovelace configuration to build a fully personalized weather dashboard.\n\n### **Summary Layer**\nThe summary layers present a concise visual overview of current weather conditions.\n\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-summary.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nweather:\n  name: \"Acquafredda\" \n  icons_model: pirateweather\n  moonphase: sensor.moon_phase\n  present:\n    condition: sensor.home_condition\n    temperature: sensor.home_temperature\n    temperature_feelslike: sensor.home_apparent_temperature\n```\n\n### **Present Layer**\nThis layer displays the current weather conditions using entity data such as temperature, humidity, wind, and more.\n\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-present.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nweather:\n  icons_model: pirateweather\n  sun: sun.sun\n  present:\n    temperature_min: sensor.home_temperature_min\n    temperature_max: sensor.home_temperature_max\n    humidity: sensor.home_relative_humidity\n    pressure: sensor.home_pressure\n    wind_bearing: sensor.home_wind_bearing\n    wind_speed: sensor.home_wind_speed\n    precipitation_intensity: sensor.home_precipitation\n    precipitation_probability: sensor.home_precipitation_probability\n```\n### **Daily Forecast Layer**\nThis layer provides a multi-day weather overview, including expected temperature highs and lows, precipitation probability, and general conditions.\n\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-daily-forecast.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nweather:\n  icons_model: pirateweather\n  daily_forecasts:\n    condition:\n      slot1: sensor.home_daily_forecast_condition_d1\n      slot2: sensor.home_daily_forecast_condition_d2\n      slot3: sensor.home_daily_forecast_condition_d3\n      slot4: sensor.home_daily_forecast_condition_d4                         \n    temperature_high:\n      slot1: sensor.home_daily_forecast_temperature_max_d1\n      slot2: sensor.home_daily_forecast_temperature_max_d2\n      slot3: sensor.home_daily_forecast_temperature_max_d3\n      slot4: sensor.home_daily_forecast_temperature_max_d4\n    temperature_low:\n      slot1: sensor.home_daily_forecast_temperature_min_d1\n      slot2: sensor.home_daily_forecast_temperature_min_d2\n      slot3: sensor.home_daily_forecast_temperature_min_d3\n      slot4: sensor.home_daily_forecast_temperature_min_d4\n    precipitation_probability:\n      slot1: sensor.home_daily_forecast_precipitation_probability_d1\n      slot2: sensor.home_daily_forecast_precipitation_probability_d2\n      slot3: sensor.home_daily_forecast_precipitation_probability_d3\n      slot4: sensor.home_daily_forecast_precipitation_probability_d4\n    precipitation_intensity:\n      slot1: sensor.home_daily_forecast_precipitation_d1\n      slot2: sensor.home_daily_forecast_precipitation_d2\n      slot3: sensor.home_daily_forecast_precipitation_d3\n      slot4: sensor.home_daily_forecast_precipitation_d4\n```\n\n### **Hourly Forecast Layer**\nThis layer displays detailed weather data for the next several hours, including temperature, precipitation, and wind conditions.\n\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-hourly-forecast.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nweather:\n  icons_model: pirateweather\n  hourly_forecasts:\n    condition:\n      slot1: sensor.home_hourly_forecast_condition_h1\n      slot2: sensor.home_hourly_forecast_condition_h2\n      slot3: sensor.home_hourly_forecast_condition_h3\n      slot4: sensor.home_hourly_forecast_condition_h4\n    temperature:\n      slot1: sensor.home_hourly_forecast_temperature_h1\n      slot2: sensor.home_hourly_forecast_temperature_h2\n      slot3: sensor.home_hourly_forecast_temperature_h3\n      slot4: sensor.home_hourly_forecast_temperature_h4\n    temperature_feelslike:\n      slot1: sensor.home_hourly_forecast_apparent_temperature_h1\n      slot2: sensor.home_hourly_forecast_apparent_temperature_h2\n      slot3: sensor.home_hourly_forecast_apparent_temperature_h3\n      slot4: sensor.home_hourly_forecast_apparent_temperature_h4\n    precipitation_intensity:\n      slot1: sensor.home_hourly_forecast_precipitation_h1\n      slot2: sensor.home_hourly_forecast_precipitation_h2\n      slot3: sensor.home_hourly_forecast_precipitation_h3\n      slot4: sensor.home_hourly_forecast_precipitation_h4\n    precipitation_probability:\n      slot1: sensor.home_hourly_forecast_precipitation_probability_h1\n      slot2: sensor.home_hourly_forecast_precipitation_probability_h2\n      slot3: sensor.home_hourly_forecast_precipitation_probability_h3\n      slot4: sensor.home_hourly_forecast_precipitation_probability_h4\n    wind_bearing:\n      slot1: sensor.home_hourly_forecast_wind_bearing_h1\n      slot2: sensor.home_hourly_forecast_wind_bearing_h2\n      slot3: sensor.home_hourly_forecast_wind_bearing_h3\n      slot4: sensor.home_hourly_forecast_wind_bearing_h4\n    wind_speed:\n      slot1: sensor.home_hourly_forecast_wind_speed_h1\n      slot2: sensor.home_hourly_forecast_wind_speed_h2\n      slot3: sensor.home_hourly_forecast_wind_speed_h3\n      slot4: sensor.home_hourly_forecast_wind_speed_h4\n```\n### **Marine Daily Forecast Layer**\nThis layer provides daily marine weather forecasts, including information such as wave height, wind speed, and sea conditions.\n\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-marine-daily-forecast.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nweather:\n  icons_model: pirateweather\n  marine_daily_forecasts:\n    wave_height_max:\n      slot1: sensor.marine_wave_height_max_day_0\n      slot2: sensor.marine_wave_height_max_day_1\n      slot3: sensor.marine_wave_height_max_day_2\n      slot4: sensor.marine_wave_height_max_day_3\n    wave_direction:\n      slot1: sensor.marine_wave_direction_dominant_day_0\n      slot2: sensor.marine_wave_direction_dominant_day_1\n      slot3: sensor.marine_wave_direction_dominant_day_2\n      slot4: sensor.marine_wave_direction_dominant_day_3                            \n    swell_wave_height_max:\n      slot1: sensor.amarine_swell_wave_height_max_day_0\n      slot2: sensor.marine_swell_wave_height_max_day_1\n      slot3: sensor.marine_swell_wave_height_max_day_2\n      slot4: sensor.marine_swell_wave_height_max_day_3                              \n    wind_wave_height_max:\n      slot1: sensor.marine_wind_wave_height_max_day_0\n      slot2: sensor.marine_wind_wave_height_max_day_1\n      slot3: sensor.marine_wind_wave_height_max_day_2\n      slot4: sensor.marine_wind_wave_height_max_day_3 \n```\n### **Alarms Layer**\nThis layer displays weather alerts and warnings from official sources such as Meteoalarm and the Italian Civil Protection Department (DPC). \n\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-alarms.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nweather:\n  icons_model: pirateweather\n  meteoalarm: binary_sensor.italy_basilicata_meteo_alarm\n  dpcalarm:\n    thunderstorms: binary_sensor.dpc_basilicata_temporali_oggi\n    hydraulic: binary_sensor.dpc_basilicata_idraulico_oggi\n    hydrogeological: binary_sensor.dpc_basilicata_idrogeologico_oggi\n```\n### **Ultraviolet Layer**\nThis layer presents real-time ultraviolet (UV) radiation data, including UV index levels, ozone concentration, and skin protection recommendations.\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-ultraviolet.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nultraviolet:\n  protection_window: binary_sensor.openuv_protection_window\n  ozone_level: sensor.openuv_current_ozone_level\n  uv_index: sensor.openuv_current_uv_index\n  uv_level: sensor.openuv_current_uv_level\n  max_uv_index: sensor.openuv_max_uv_index\n\n  set_skin_type_1: sensor.openuv_skin_type_1_safe_exposure_time\n  set_skin_type_2: sensor.openuv_skin_type_2_safe_exposure_time\n  set_skin_type_3: sensor.openuv_skin_type_3_safe_exposure_time\n  set_skin_type_4: sensor.openuv_skin_type_4_safe_exposure_time\n  set_skin_type_5: sensor.openuv_skin_type_5_safe_exposure_time\n  set_skin_type_6: sensor.openuv_skin_type_6_safe_exposure_time\n```\n### **Pollen Layer**\nThis layer displays information about airborne pollen levels, helping users monitor potential allergen exposure.\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-pollen.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \npollen:\n  min: 1\n  max: 4\n  entities:\n    - name: Alder\n      entity: sensor.openmeteo_pollen_alder_level \n    - name: Birch\n      entity: sensor.openmeteo_pollen_birch_level\n    - name: Grass\n      entity: sensor.openmeteo_pollen_grass_level\n    - name: Mugwort\n      entity: sensor.openmeteo_pollen_mugwort_level\n    - name: Olive\n      entity: sensor.openmeteo_pollen_olive_level \n    - name: Ragweed\n      entity: sensor.openmeteo_pollen_ragweed_level  \n```\n### **Air Quality Layer**\nThis layer presents real-time data on key air quality indicators such as PM2.5, PM10, ozone, and nitrogen dioxide levels.\n<p float=\"left\">\n<img src=\"https://github.com/r-renato/ha-card-weather-conditions/raw/master/md.images/ha-card-weather-condition-air-quality.png\" width=\"40%\" height=\"auto\" alt=\"Home Assistant lovelace card\">\n</p>\n\n#### **YAML example**\n```yaml\ntype: custom:ha-card-weather-conditions\nlanguage: it \nairquality:\n  pm25: sensor.lazio_italy_pm2_5\n  pm10: sensor.lazio_italy_pm10\n  o3: sensor.roma_lazio_italy_ozone\n  co: sensor.roma_lazio_italy_carbon_monoxide\n  epa_aqi: sensor.lazio_italy_air_quality_index\n  epa_primary_pollutant: sensor.lazio_italy_dominant_pollutant\n```\n\n[license-shield]:https://img.shields.io/github/license/r-renato/ha-card-weather-conditions\n[buymecoffee]: https://www.buymeacoffee.com/0D3WbkKrn\n[buymecoffeebadge]: https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow?style=for-the-badge\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"ha-card-weather-conditions\",\n  \"version\": \"2.0.0\",\n  \"description\": \"Home Assistant lovelace card for display weather data.\",\n  \"keywords\": [\n    \"home-assistant\",\n    \"homeassistant\",\n    \"hass\",\n    \"automation\",\n    \"lovelace\",\n    \"custom-cards\",\n    \"weather\"\n  ],\n  \"homepage\": \"https://github.com/r-renato/ha-card-weather-conditions#readme\",\n  \"module\": \"ha-card-weather-conditions.js\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+ssh://git@github.com/r-renato/ha-card-weather-conditions.git\"\n  },\n  \"author\": \"Renato Rossi\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@material/mwc-select\": \"^0.27.0\",\n    \"@material/mwc-textfield\": \"^0.27.0\",\n    \"color\": \"^4.2.3\",\n    \"custom-card-helpers\": \"^1.0.8\",\n    \"hammerjs\": \"^2.0.8\",\n    \"home-assistant-js-websocket\": \"^9.4.0\",\n    \"lit\": \"^3.2.1\",\n    \"memoize-one\": \"^6.0.0\",\n    \"object-hash\": \"^3.0.0\",\n    \"sortablejs\": \"^1.15.6\",\n    \"superstruct\": \"^2.0.2\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.24.0\",\n    \"@rollup/plugin-babel\": \"^6.0.4\",\n    \"@rollup/plugin-commonjs\": \"^28.0.3\",\n    \"@rollup/plugin-json\": \"^6.1.0\",\n    \"@rollup/plugin-node-resolve\": \"^15.2.3\",\n    \"@rollup/plugin-terser\": \"^0.4.4\",\n    \"@rollup/plugin-typescript\": \"^11.1.5\",\n    \"@typescript-eslint/eslint-plugin\": \"^6.21.0\",\n    \"@typescript-eslint/parser\": \"^6.21.0\",\n    \"eslint\": \"^8.56.0\",\n    \"eslint-config-airbnb-base\": \"^15.0.0\",\n    \"eslint-plugin-import\": \"^2.29.1\",\n    \"prettier\": \"^3.2.5\",\n    \"rollup\": \"^4.12.0\",\n    \"rollup-plugin-execute\": \"^1.1.1\",\n    \"typescript\": \"5.3.3\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/r-renato/ha-card-weather-conditions/issues\"\n  },\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"watch\": \"rollup -c --watch\",\n    \"build\": \"npm run lint && npm run rollup -- --config rollup.config.mjs\",\n    \"build:new\": \"npm run lint && npm run rollup -- --config rollup.new.config.mjs\",\n    \"lint\": \"eslint src/*.ts\",\n    \"rollup\": \"rollup --no-compact \"\n  }\n}\n"
  },
  {
    "path": "rollup.new.config.mjs",
    "content": "import resolve from '@rollup/plugin-node-resolve'; // ✅ nuovo package\nimport typescript from '@rollup/plugin-typescript'; // ✅ moderno\nimport babel from '@rollup/plugin-babel';\nimport terser from '@rollup/plugin-terser'; // ✅ va destrutturato\nimport execute from 'rollup-plugin-execute'; // ancora valido\nimport commonjs from '@rollup/plugin-commonjs'; // 👈 nuovo import\n\nexport default {\n    input: 'src/ha-weather-ecard.ts',\n    output: {\n        //dir: './dist',\n        file: 'dist/ha-card-weather-conditions.js', // 👈 nome file forzato\n        format: 'esm',\n        sourcemap: 'inline',\n        banner: false,\n        // comments: false\n    },\n    plugins: [\n        resolve({\n            browser: true, // 👈 molto importante per card frontend\n            exportConditions: ['browser']\n        }),\n        commonjs(), // 👈 serve per convertire eventuali commonjs a es6\n        typescript({\n            tsconfig: './tsconfig.json'\n        }),\n        babel({\n            babelHelpers: 'bundled',\n            exclude: 'node_modules/**',\n            extensions: ['.js', '.ts']\n        }),\n        terser(),\n        execute([\n            `echo \"$(date '+%d/%m/%Y %H:%M:%S') rollup done.\" ; echo -e '\\\\007'`\n        ])\n    ]\n};\n"
  },
  {
    "path": "src/base/lovelace-base.ts",
    "content": "/* eslint-disable no-underscore-dangle */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n  css,\n  CSSResultGroup,\n  html,\n  LitElement,\n  PropertyValues,\n  TemplateResult,\n} from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { HomeAssistant } from 'custom-card-helpers';\n\nimport { defaultColorCss, defaultDarkColorCss } from '../utils/colors';\nimport { iCardConfig, iLovelaceCardConfig } from '../utils/config-schema';\nimport {\n  cwcLocale,\n  hacsImagePath,\n  logo,\n  manImagePath,\n  optConsoleParam1,\n  optConsoleParam2,\n  optConsoleParam3,\n} from '../utils/const';\nimport {\n  getIconModelData,\n  imageExist,\n  loadJSON,\n  logInfo,\n} from '../utils/helper';\nimport { cwcClimacellDayIcons, cwcClimacellNightIcons } from '../iconmodels/im-climacell';\nimport { getCardStyles } from '../utils/helper-render';\nimport { cwcDaytimePirateWeatherIcons, cwcNightlyPirateWeaterIcons } from '../iconmodels/im-pirateweather';\n\nexport interface iTerms {\n   windDirections: string;\n   words: Record<string, string>;\n}\n\nexport interface iIconsConfig {\n  path: string ;\n  iconType: string ;\n  icons_model: string ;\n  iconsDay: { [key: string]: string; } ;\n  iconsNight: { [key: string]: string; } ;\n}\n\nexport interface iLovelaceCard extends HTMLElement {\n  hass?: HomeAssistant;\n  isPanel?: boolean;\n  editMode?: boolean;\n  getCardSize(): number | Promise<number>;\n  setConfig(config: iLovelaceCardConfig): void;\n}\n\nexport function computeDarkMode(hass?: HomeAssistant): boolean {\n  if (!hass) return false;\n  return (hass.themes as any).darkMode as boolean;\n}\n\n/* -------------------- VARIABILI GLOBALI -------------------- */\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n// let loadedTranslations: any[] = [];\n// let resolvedImagePath: string | null = null;\n\nexport async function preloadResources(): Promise<{ translations: any[]; imagePath: string | null }> {\n  const [hacsResult, manResult] = await Promise.all([\n    imageExist(`${hacsImagePath}/static/cloudy.svg`),\n    imageExist(`${manImagePath}/static/cloudy.svg`),\n  ]);\n\n  let imagePath: string | null = null;\n\n  if (hacsResult) {\n    imagePath = hacsImagePath;\n  } else if (manResult) {\n    imagePath = manImagePath;\n  } else {\n    imagePath = null;\n  }\n\n  if (!imagePath) {\n    logInfo(`${logo} - Impossibile determinare il path immagini.`);\n    return { translations: [], imagePath: null };\n  }\n\n  const langs = ['en', 'it', 'nl', 'es', 'de', 'fr', 'sr-latn', 'pt', 'da', 'no-NO', 'cs'];\n  const translPath = `${imagePath}/../transl/`;\n  const translations = await Promise.all(langs.map((lang) => loadJSON(`${translPath}${lang}.json`)));\n\n  return { translations, imagePath };\n}\n\nexport abstract class LovelaceBaseElement extends LitElement {\n  @property({ attribute: false }) public hass!: HomeAssistant;\n\n  @property({ attribute: false }) protected _config?: iCardConfig;\n\n  public isPanel?: boolean = false;\n\n  public editMode?: boolean = false;\n\n  public invalidConfig: boolean = false;\n\n  protected _iconsConfig: iIconsConfig;\n\n  protected _imagesPath: string;\n\n  protected _name: string;\n\n  protected _language: string;\n\n  protected _translations: string[];\n\n  protected _terms: iTerms;\n\n  protected _hasPresent: boolean = false;\n\n  protected _hasDailyForecasts: boolean = false;\n\n  protected _hasHourlyForecasts: boolean = false;\n\n  protected _hasMarineDailyForecasts: boolean = false;\n\n  protected _hasMarineHourlyForecasts: boolean = false;\n\n  protected _hasMetealarm: boolean = false;\n\n  protected _hasDPCalarm: boolean = false;\n\n  protected _hasMeteogram: boolean = false;\n\n  protected _hasAirQuality: boolean = false;\n\n  protected _hasPollen: boolean = false;\n\n  protected _hasUltraviolet: boolean = false;\n\n  protected _hasAlert: boolean = false;\n\n  protected _hasSea: boolean = false;\n\n  protected _hasCamera: boolean = false;\n\n  protected updated(changedProps: PropertyValues): void {\n    super.updated(changedProps);\n    if (changedProps.has('hass') && this.hass) {\n      const currentDarkMode = computeDarkMode(changedProps.get('hass'));\n      const newDarkMode = computeDarkMode(this.hass);\n      if (currentDarkMode !== newDarkMode) {\n        this.toggleAttribute('dark-mode', newDarkMode);\n      }\n    }\n  }\n\n  static get styles(): CSSResultGroup {\n    return [\n      // animations,\n      css`\n        :host {\n          ${defaultColorCss}\n        }\n        :host([dark-mode]) {\n          ${defaultDarkColorCss}\n        }\n        ${getCardStyles()}\n      `,\n    ];\n  }\n\n  public async setConfig(config: iCardConfig) {\n    if (!config) {\n      this.invalidConfig = true;\n      throw new Error('Invalid configuration');\n    }\n\n    // console.log({ card_config: config });\n\n    if (!this._translations?.length || !this._imagesPath) {\n      const { translations, imagePath } = await preloadResources();\n      this._translations = translations;\n      this._imagesPath = imagePath;\n    }\n\n    this._name = config?.weather?.name ?? undefined;\n    this._language = config.language?.toLowerCase() || 'en';\n\n    this._loadTranslations(this._language);\n    // this._initNumberFormatters(this._language);\n\n    // this._setupDisplaySections(config.display ?? []);\n    this._detectDataSections(config);\n\n    this._setupIcons(config.weather?.icons_model);\n    this._config = config;\n\n    logInfo(`${logo} - Config loaded.`);\n  }\n\n  // eslint-disable-next-line class-methods-use-this\n  public getCardSize(): number | Promise<number> {\n    return 1;\n  }\n\n  private _loadTranslations(lang: string) {\n    try {\n      const transls = JSON.parse(this._translations[cwcLocale[lang]]);\n      this._terms = {\n        windDirections: transls.cwcLocWindDirections,\n        words: transls.cwcTerms,\n      };\n\n      logInfo(\n        `${logo}%c card \"${this._name}\", locale is '${lang}'.`,\n        optConsoleParam1,\n        optConsoleParam2,\n        optConsoleParam3,\n      );\n    } catch (e) {\n      const fallback = 'en';\n      const transls = JSON.parse(this._translations[cwcLocale[fallback]]);\n      this._terms = {\n        windDirections: transls.cwcLocWindDirections,\n        words: transls.cwcTerms,\n      };\n\n      logInfo(\n        `${logo}%c card \"${this._name}\" unable to use '${lang}' locale, set as default '${fallback}'.`,\n        optConsoleParam1,\n        optConsoleParam2,\n        optConsoleParam3,\n      );\n    }\n  }\n\n  private _detectDataSections(config: iCardConfig) {\n    this._hasPresent = !!config.weather?.present;\n    this._hasDailyForecasts = !!config.weather?.daily_forecasts;\n    this._hasHourlyForecasts = !!config.weather?.hourly_forecasts;\n    this._hasMarineDailyForecasts = !!config.weather?.marine_daily_forecasts;\n    this._hasMarineHourlyForecasts = !!config.weather?.marine_hourly_forecasts;\n    this._hasMetealarm = !!config.weather?.meteoalarm;\n    this._hasDPCalarm = !!config.weather?.dpcalarm;\n    // this._hasMeteogram = !!config.weather?.forecast?.meteogram;\n    this._hasAirQuality = !!config.airquality;\n    this._hasPollen = config.pollen && Array.isArray(config.pollen.entities) && config.pollen.entities.length > 0;\n    this._hasUltraviolet = !!config.ultraviolet;\n    this._hasCamera = !!config.camera;\n    // this._hasAlert = !!config.alert;\n  }\n\n  private _setupIcons(iconsModel?: string) {\n    this._iconsConfig = {\n      path: this._imagesPath,\n      iconType: this._config?.weather?.animation ? 'animated' : 'static',\n      icons_model: iconsModel || 'pirateweather',\n      iconsDay: cwcDaytimePirateWeatherIcons,\n      iconsNight: cwcNightlyPirateWeaterIcons,\n    };\n\n    if (iconsModel) {\n      const modelData = getIconModelData(iconsModel);\n      this._iconsConfig.icons_model = modelData.iconsModel;\n      this._iconsConfig.iconsDay = modelData.iconsDay;\n      this._iconsConfig.iconsNight = modelData.iconsNight;\n    }\n  }\n\n  /**\n   * generates the card HTML\n   * @return {TemplateResult}\n   */\n  public render(): TemplateResult {\n    if (this.invalidConfig) {\n      return html`\n        <ha-card class=\"ha-card-weather-conditions\">\n            <div class='banner'>\n                <div class=\"header\">ha-card-weather-conditions</div>\n            </div>\n            <div class='content'>\n                Configuration ERROR!\n            </div>\n        </ha-card>\n    `;\n    }\n\n    return this._render();\n  }\n\n  protected abstract _render(): TemplateResult;\n}\n"
  },
  {
    "path": "src/builder/b-airquality.ts",
    "content": "/* eslint-disable camelcase */\n/* eslint-disable no-else-return */\n/* eslint-disable object-curly-newline */\nimport { HomeAssistant } from 'custom-card-helpers/dist';\nimport { iAirQuality } from '../utils/config-schema';\nimport { getEntityNumericValue, getEntityRawValue, getEntityUnit } from '../utils/helper';\nimport { renderWeatherPresent } from '../templates/t-present';\n\n/**\n * Restituisce un colore (in formato hex) in base al valore dell'indice EPA AQI.\n * @param {number} aqi - Valore AQI compreso tra 0 e 500\n * @returns {string} - Colore esadecimale associato alla fascia AQI\n */\nfunction getAQIColor(aqi: number): string {\n  if (aqi <= 50) {\n    return '#009966'; // Verde (Buona)\n  } else if (aqi <= 100) {\n    return '#ffde33'; // Giallo (Moderata)\n  } else if (aqi <= 150) {\n    return '#ff9933'; // Arancione (Sensibili)\n  } else if (aqi <= 200) {\n    return '#cc0033'; // Rosso (Non salutare)\n  } else if (aqi <= 300) {\n    return '#660099'; // Viola (Molto non salutare)\n  } else {\n    return '#7e0023'; // Marrone scuro (Pericolosa)\n  }\n}\n\nconst buildAirQuality = (\n  hass: HomeAssistant,\n  language: string,\n  airquality: iAirQuality,\n) => {\n  const lang = language || hass.selectedLanguage || hass.language;\n\n  const pm25 = getEntityNumericValue({ entityId: airquality.pm25, hass, lang: language, decimals: 0 });\n  const pm10 = getEntityNumericValue({ entityId: airquality.pm10, hass, lang: language, decimals: 0 });\n  const o3 = getEntityNumericValue({ entityId: airquality.o3, hass, lang: language, decimals: 1 });\n  const no2 = getEntityNumericValue({ entityId: airquality.no2, hass, lang: language, decimals: 0 });\n  const co = getEntityNumericValue({ entityId: airquality.co, hass, lang: language, decimals: 1 });\n  const so2 = getEntityNumericValue({ entityId: airquality.so2, hass, lang: language, decimals: 0 });\n  const epa_aqi = getEntityNumericValue({ entityId: airquality.epa_aqi, hass, lang: language, decimals: 0 });\n  const epa_primary_pollutant = getEntityRawValue(hass, airquality.epa_primary_pollutant);\n\n  const airQualityData = {\n    pm25: {\n      value: (pm25 ? `pm2.5 ${pm25}` : pm25),\n      unit: getEntityUnit(hass, airquality.pm25) || 'µg/m³',\n      icon: 'mdi:weather-hazy',\n    },\n    pm10: {\n      value: (pm10 ? `pm10 ${pm10}` : pm10),\n      unit: getEntityUnit(hass, airquality.pm10) || 'µg/m³',\n      icon: 'mdi:weather-hazy',\n    },\n    o3: {\n      value: (o3 ? `o3 ${o3}` : o3),\n      unit: getEntityUnit(hass, airquality.o3) || 'µg/m³',\n      icon: 'mdi:molecule',\n    },\n    no2: {\n      value: (no2 ? `no2 ${no2}` : no2),\n      unit: getEntityUnit(hass, airquality.no2) || 'µg/m³',\n      icon: 'mdi:molecule',\n    },\n    co: {\n      value: (co ? `co ${co}` : co),\n      unit: getEntityUnit(hass, airquality.co) || 'µg/m³',\n      icon: 'mdi:molecule',\n    },\n    so2: {\n      value: (so2 ? `so2 ${so2}` : so2),\n      unit: getEntityUnit(hass, airquality.so2) || 'µg/m³',\n      icon: 'mdi:molecule',\n    },\n    epa_aqi: {\n      value: (epa_aqi ? `Air Quality Index ${epa_aqi}` : epa_aqi),\n      // unit: getEntityUnit(hass, airquality.epa_aqi) || 'µg/m³',\n      icon: 'mdi:weather-hazy',\n      icon_color: getAQIColor(Number(getEntityRawValue(hass, airquality.epa_aqi))),\n    },\n    epa_primary_pollutant: {\n      value: (epa_primary_pollutant ? `Primary ${epa_primary_pollutant}` : epa_primary_pollutant),\n      // unit: getEntityUnit(hass, airquality.epa_aqi) || 'µg/m³',\n      icon: 'mdi:weather-hazy',\n    },\n  };\n\n  return renderWeatherPresent(airQualityData, lang);\n};\n\nexport default buildAirQuality;\n"
  },
  {
    "path": "src/builder/b-camera.ts",
    "content": "import { HomeAssistant } from 'custom-card-helpers/dist';\nimport { iTerms } from '../base/lovelace-base';\nimport renderCamera from '../templates/t-camera';\n\nconst buildCamera = (\n  hass: HomeAssistant,\n  lang: string,\n  terms: iTerms,\n  handlePopup: (e: Event, entityId: string) => void,\n  cameraId: string,\n) => {\n  const camera = cameraId && hass.states[cameraId];\n\n  const entityPicture = camera?.attributes?.entity_picture;\n  const friendlyName = camera?.attributes?.friendly_name ?? cameraId;\n\n  return renderCamera(handlePopup, cameraId, entityPicture, friendlyName);\n};\n\nexport default buildCamera;\n"
  },
  {
    "path": "src/builder/b-meteoalarm.ts",
    "content": "/* eslint-disable camelcase */\n/* eslint-disable quote-props */\nimport { HomeAssistant } from 'custom-card-helpers/dist';\nimport { iTerms } from '../base/lovelace-base';\nimport { iDPCAlert } from '../utils/config-schema';\nimport renderMeteoDPCalarm, { iWeatherMeteoDPCAlarmDataInterface } from '../templates/t-meteoalarm';\nimport { getLocaleInfo } from '../utils/helper';\n\nconst getEffectiveLabel = (effective: string) => {\n  const effectiveDatetime = new Date(effective);\n  const now = new Date();\n\n  // Reset dell'ora per confronto solo a livello di giorno\n  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n  const effectiveDate = new Date(effectiveDatetime.getFullYear(), effectiveDatetime.getMonth(), effectiveDatetime.getDate());\n\n  const msInDay = 24 * 60 * 60 * 1000;\n  const dayDifference = Math.round((effectiveDate.getTime() - today.getTime()) / msInDay);\n\n  let effectiveLabel: 'oggi' | 'domani' | 'dopodomani' | undefined;\n\n  if (dayDifference === 0) {\n    effectiveLabel = 'oggi';\n  } else if (dayDifference === 1) {\n    effectiveLabel = 'domani';\n  } else if (dayDifference === 2) {\n    effectiveLabel = 'dopodomani';\n  } else {\n    effectiveLabel = undefined;\n  }\n  return effectiveLabel;\n};\n\nconst buildMeteoAlarmData = (\n  hass: HomeAssistant,\n  lang: string,\n  terms: iTerms,\n  meteoalarmId: string,\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Record<string, iWeatherMeteoDPCAlarmDataInterface> => {\n  const eventIcon: Record<string, string> = {\n    'wind': 'mdi:weather-windy',\n    'snow-ice': 'mdi:snowflake-alert',\n    'thunderstorm': 'mdi:weather-lightning',\n    'fog': 'mdi:weather-fog',\n    'high-temperature': 'mdi:weather-sunny-alert',\n    'low-temperature': 'mdi:thermometer-low',\n    'coastal-event': 'mdi:home-flood',\n    'forest-fire': 'mdi:pine-tree-fire',\n    'avalanche': 'mdi:image-filter-hdr',\n    'rain': 'mdi:weather-pouring',\n    'flood': 'mdi:home-flood',\n    'rain-flood': 'mdi:weather-pouring',\n    'marine-hazard': 'mdi:weather-hurricane',\n    'drought': 'mdi:water-off',\n  };\n\n  const eventIconColor: Record<string, string> = {\n    green: 'green',\n    yellow: '#ffa600',\n    orange: 'orange',\n    red: 'red',\n  };\n\n  const meteoalarm = meteoalarmId && hass.states[meteoalarmId];\n  if (!meteoalarm?.attributes) return {};\n\n  const fpcData: Record<string, iWeatherMeteoDPCAlarmDataInterface> = {};\n\n  if (meteoalarm.state === 'on' && meteoalarm.attributes) {\n    const localeInfo = getLocaleInfo(lang);\n    const {\n      event,\n      severity,\n      awareness_type,\n      awareness_level,\n      effective,\n    } = meteoalarm.attributes;\n\n    const awarenessType = awareness_type?.split(';')[1]?.trim().toLowerCase() || '';\n    const awarenessLevel = awareness_level?.split(';')[1]?.trim().toLowerCase() || '';\n    const eventName = event || '';\n    const severityLevel = severity?.split(';')[1]?.trim() || '';\n    const effectiveDatetime = getEffectiveLabel(effective);\n\n    fpcData['meteoalarm'] = {\n      event: eventName,\n      severity: severityLevel,\n      icon: eventIcon[awarenessType] || 'mdi:alert',\n      icon_color: eventIconColor[awarenessLevel] || 'grey',\n      datetime: (new Date(effective)).toLocaleDateString(localeInfo.locale, {\n        weekday: 'short',\n        timeZone: localeInfo.timezone,\n      }).toLocaleUpperCase(),\n    };\n  }\n\n  return fpcData;\n};\n\nconst buildDPCAlarmData = (\n  hass: HomeAssistant,\n  lang: string,\n  terms: iTerms,\n  dpcalarm: iDPCAlert,\n) => {\n  if (!dpcalarm) return {};\n\n  const localeInfo = getLocaleInfo(lang);\n  const eventIconColor = {\n    0: 'gray',\n    1: 'green',\n    2: '#ffa600',\n    3: 'orange',\n    4: 'red',\n  };\n\n  const sources = ['thunderstorms', 'hydraulic', 'hydrogeological'];\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const fpcData: Record<string, iWeatherMeteoDPCAlarmDataInterface> = {};\n\n  sources.forEach((key) => {\n    const entityId = dpcalarm[key as keyof iDPCAlert];\n    const entity = entityId && hass.states[entityId];\n\n    if (entity && entity.state === 'on' && entity.attributes) {\n      const { level, info, icon } = entity.attributes;\n      fpcData[key] = {\n        event: info,\n        severity: level,\n        icon,\n        icon_color: eventIconColor[level],\n        datetime: (new Date()).toLocaleDateString(localeInfo.locale, {\n          weekday: 'short',\n          timeZone: localeInfo.timezone,\n        }).toLocaleUpperCase(),\n      };\n    }\n  });\n  return fpcData;\n};\n\nconst buildMeteoDPCalarm = (\n  hass: HomeAssistant,\n  lang: string,\n  terms: iTerms,\n  meteoalarmId: string,\n  dpcalarm: iDPCAlert, \n) => {\n  const alarmsData = { ...buildMeteoAlarmData(hass, lang, terms, meteoalarmId), ...buildDPCAlarmData(hass, lang, terms, dpcalarm) };\n  // console.debug('buildMeteoDPCalarm', alarmsData);\n  return renderMeteoDPCalarm(alarmsData);\n};\n\nexport default buildMeteoDPCalarm;\n"
  },
  {
    "path": "src/builder/b-pollen.ts",
    "content": "import { HomeAssistant } from 'custom-card-helpers/dist';\nimport { iPollen } from '../utils/config-schema';\nimport { getEntityRawValue, string2Number } from '../utils/helper';\nimport { iPollenData, renderPollen } from '../templates/t-pollen';\n\nconst buildPollen = (hass: HomeAssistant, lang: string, pollen: iPollen) => {\n  const allItems: iPollenData[] = [];\n  if (Array.isArray(pollen.entities) && pollen.entities.length > 0) {\n    pollen.entities.forEach((item) => {\n      const rawvalue = getEntityRawValue(hass, item.entity);\n      if (rawvalue && rawvalue !== 'unknown' && rawvalue !== 'unavailable') {\n        let value: number = string2Number(getEntityRawValue(hass, item.entity));\n\n        if (Number.isNaN(value) || value < pollen.min || value > pollen.max) {\n          value = 0;\n        }\n\n        allItems.push({\n          name: item.name,\n          value,\n        });\n      }\n      // console.log(`Nome: ${item.name}, Entità: ${item.entity}`);\n    });\n  }\n\n  return renderPollen(allItems, pollen.min, pollen.max);\n};\n\nexport default buildPollen;\n"
  },
  {
    "path": "src/builder/b-present.ts",
    "content": "/* eslint-disable camelcase */\nimport { HomeAssistant } from 'custom-card-helpers/dist';\nimport {\n  getEntityNumericValue,\n  getEntityRawValue,\n  getEntityUnit,\n  getLocaleInfo,\n  getWindDirections,\n} from '../utils/helper';\n// import { getSensorUnit } from '../utils/helper-render';\nimport { renderWeatherPresent } from '../templates/t-present';\nimport { iPresentData } from '../utils/config-schema';\nimport { iTerms } from '../base/lovelace-base';\n\nconst present = (hass: HomeAssistant, language: string, cwcLocWindDirections, presentData: iPresentData, sunId: string) => {\n  const localeInfo = getLocaleInfo(language);\n  const sunEntity = sunId ? hass.states[sunId] : undefined;\n  const { next_rising, next_setting } = sunEntity?.attributes ?? {};\n\n  const next_rising_formatted = next_rising ? new Date(next_rising).toLocaleTimeString(localeInfo.locale, {\n    hour: '2-digit',\n    minute: '2-digit',\n    second: '2-digit',\n    hour12: false,\n    timeZone: localeInfo.timezone,\n  }) : undefined;\n\n  const next_setting_formatted = next_rising ? new Date(next_setting).toLocaleTimeString(localeInfo.locale, {\n    hour: '2-digit',\n    minute: '2-digit',\n    second: '2-digit',\n    hour12: false,\n    timeZone: localeInfo.timezone,\n  }) : undefined;\n\n  return {\n    nextRising: { value: next_rising_formatted, icon: 'mdi:weather-sunset-up' },\n    nextSetting: { value: next_setting_formatted, icon: 'mdi:weather-sunset-down' },\n\n    precipitationIntensity: {\n      // eslint-disable-next-line object-curly-newline\n      value: getEntityNumericValue({ entityId: presentData.precipitation_intensity, hass, lang: language, decimals: 2 }),\n      unit: getEntityUnit(hass, presentData.precipitation_intensity),\n      icon: 'mdi:weather-rainy',\n    },\n    precipitationProbability: {\n      // eslint-disable-next-line object-curly-newline\n      value: getEntityNumericValue({ entityId: presentData.precipitation_probability, hass, lang: language, decimals: 0 }),\n      unit: getEntityUnit(hass, presentData.precipitation_probability),\n      icon: 'mdi:weather-rainy',\n    },\n    humidity: {\n      // eslint-disable-next-line object-curly-newline\n      value: getEntityNumericValue({ entityId: presentData.humidity, hass, lang: language, decimals: 0 }),\n      unit: getEntityUnit(hass, presentData.humidity),\n      icon: 'mdi:water-percent',\n    },\n    windBearing: { value: getWindDirections(getEntityRawValue(hass, presentData.wind_bearing), cwcLocWindDirections) },\n    windSpeed: {\n      // eslint-disable-next-line object-curly-newline\n      value: getEntityNumericValue({ entityId: presentData.wind_speed, hass, lang: language, decimals: 0 }),\n      unit: getEntityUnit(hass, presentData.wind_speed),\n      icon: 'mdi:weather-windy',\n    },\n    pressure: {\n      // eslint-disable-next-line object-curly-newline\n      value: getEntityNumericValue({ entityId: presentData.pressure, hass, lang: language, decimals: 0 }),\n      unit: getEntityUnit(hass, presentData.pressure),\n      icon: 'mdi:gauge',\n    },\n    visibility: {\n      // eslint-disable-next-line object-curly-newline\n      value: getEntityNumericValue({ entityId: presentData.visibility, hass, lang: language, decimals: 0 }),\n      unit: getEntityUnit(hass, presentData.visibility),\n      icon: 'mdi:weather-fog',\n    },\n    temperatureHigh: {\n      // eslint-disable-next-line object-curly-newline\n      value: getEntityNumericValue({ entityId: presentData.temperature_max, hass, lang: language, decimals: 0 }),\n      unit: getEntityUnit(hass, presentData.temperature_max),\n      icon: 'mdi:thermometer',\n    },\n    temperatureLow: {\n      // eslint-disable-next-line object-curly-newline\n      value: getEntityNumericValue({ entityId: presentData.temperature_min, hass, lang: language, decimals: 0 }),\n      unit: getEntityUnit(hass, presentData.temperature_min),\n      icon: 'mdi:thermometer',\n    },\n  };\n};\n\n// const presentFromForecastData = (hass: HomeAssistant, language: string, forecastCfg: Forecast) => {\n//   const getValue = (obj: Record<string, string>) => {\n//     const [key, entityId] = Object.entries(obj)[0] ?? [];\n//     const state = entityId && hass.states[entityId]?.state;\n//     return state !== undefined ? formatNumber({ stringNumber: state, lang: language, fractionDigits: 0 }) : undefined;\n//   };\n\n//   const {\n//     temperature_high = {},\n//     temperature_low = {},\n//     precipitation_probability = {},\n//     precipitation_intensity = {},\n//   } = forecastCfg;\n\n//   return {\n//     temperatureHigh: { value: getValue(temperature_high), unit: getEntityUnit(hass, temperature_high), icon: 'mdi:thermometer' },\n//     temperatureLow: { value: getValue(temperature_low), unit: getEntityUnit(hass, 'temperature'), icon: 'mdi:thermometer' },\n//     precipitationProbability: { value: getValue(precipitation_probability), unit: '%', icon: 'mdi:weather-rainy' },\n//     precipitationIntensity: { value: getValue(precipitation_intensity), unit: getEntityUnit(hass, 'precipitation'), icon: 'mdi:weather-rainy' },\n//   };\n// };\n\nconst buildWeatherPresent = (\n  hass: HomeAssistant,\n  language: string,\n  terms: iTerms,\n  presentData: iPresentData,\n  sunId: string,\n) => {\n  const lang = language || hass.selectedLanguage || hass.language;\n\n  const presentObj = present(hass, lang, terms.windDirections, presentData, sunId);\n  // const presentFromForecastObj = presentFromForecastData(hass, language, forecastCfg);\n\n  // console.debug('buildWeatherPresent', { presentObj });\n  return renderWeatherPresent({ ...presentObj }, lang);\n};\n\nexport default buildWeatherPresent;\n"
  },
  {
    "path": "src/builder/b-summary.ts",
    "content": "import { HomeAssistant } from 'custom-card-helpers/dist';\n\nimport renderWeatherSummary from '../templates/t-summary';\nimport {\n  getEntityNumericValue,\n  getEntityRawValue,\n  getEntityUnit,\n  translate,\n} from '../utils/helper';\n\nimport { getMoonIcon, getWeatherIcon } from '../utils/helper-render';\nimport { iPresentData } from '../utils/config-schema';\nimport { iIconsConfig, iTerms } from '../base/lovelace-base';\n\nconst buildWeatherSummary = (\n  hass: HomeAssistant,\n  language: string,\n  terms: iTerms,\n  iconsConfig: iIconsConfig,\n  name: string,\n  presentData: iPresentData,\n  sunId: string,\n  moonphase: string,\n) => {\n  const moonPhase = getEntityRawValue(hass, moonphase);\n  const moonIcon: string = moonPhase ? getMoonIcon(moonPhase) : '';\n  const sun = getEntityRawValue(hass, sunId);\n  const currentConditions = getEntityRawValue(hass, presentData.condition)?.toLowerCase() || 'na';\n  // eslint-disable-next-line max-len\n  const temperature = presentData.temperature ? getEntityNumericValue({ entityId: presentData.temperature, hass, lang: language }) ?? undefined : undefined;\n  // eslint-disable-next-line max-len\n  const temperatureFeelsLike = presentData.temperature_feelslike ? getEntityNumericValue({ entityId: presentData.temperature_feelslike, hass, lang: language }) ?? undefined : undefined;\n  const temperatureFeelsLikeIcon = hass.states[presentData.temperature_feelslike]?.attributes.icon ?? '';\n\n  return renderWeatherSummary({\n    title: name ?? undefined, // 'Verkhnenovokutlumbetyevo',\n    moonText: (moonphase ? translate(moonPhase, terms.words) : undefined),\n    moonIcon,\n    conditionText: currentConditions,\n    conditionIcon: getWeatherIcon(currentConditions, iconsConfig, sun),\n    temperature,\n    temperatureUnit: getEntityUnit(hass, presentData.temperature),\n    feelsLikeTerm: translate('Feels Like', terms.words),\n    temperatureFeelsLike,\n    temperatureFeelsLikeIcon,\n  });\n};\n\nexport default buildWeatherSummary;\n"
  },
  {
    "path": "src/builder/b-ultraviolet.ts",
    "content": "import { HomeAssistant } from 'custom-card-helpers/dist';\n\nimport { getEntityNumericValue, getEntityRawValue, pad } from '../utils/helper';\nimport renderUltraviolet from '../templates/t-ultraviolet';\nimport { iUltraviolet } from '../utils/config-schema';\n\n// const getRawValue = (hass: HomeAssistant, entityId?: string): string | undefined => entityId && hass.states[entityId]?.state;\n// const getValue = (hass: HomeAssistant, entityId?: string, lang: string = 'en', decimals = 0): string | undefined => {\n//   const state = entityId && hass.states[entityId]?.state;\n//   return state !== undefined ? formatNumber(state, lang, decimals) : undefined;\n// };\n\nconst getTime = (state?: string | number): string => {\n  const value = typeof state === 'string' && state.toLowerCase() === 'unknown'\n    ? NaN\n    : Number(state);\n  // console.debug(state);\n  if (!Number.isFinite(value) || value < 0) return '--';\n\n  const hours = Math.floor(value / 60);\n  const minutes = value % 60;\n\n  return hours > 0\n    ? `${hours}:${pad(minutes, 2)} h`\n    : `${minutes} m`;\n};\n\nconst summaryData = (hass: HomeAssistant, lang: string, uv: iUltraviolet) => ({\n  protectionWindow: {\n    value: (!getEntityRawValue(hass, uv.protection_window) || getEntityRawValue(hass, uv.protection_window) === 'unknown' ? 'off' :\n      getEntityRawValue(hass, uv.protection_window)\n    ),\n    icon: 'mdi:sunglasses',\n  },\n  currentUVLevel: { value: getEntityRawValue(hass, uv.uv_level), icon: 'mdi:weather-sunny' },\n  currentUVIndex: { value: getEntityNumericValue({ entityId: uv.uv_index, hass, lang }), unit: 'UV Idx', icon: 'mdi:weather-sunny' },\n  maxUVIndex: { value: getEntityNumericValue({ entityId: uv.max_uv_index, hass, lang }), unit: 'UV Idx', icon: 'mdi:weather-sunny' },\n  currentOzoneLevel: { value: getEntityNumericValue({ entityId: uv.ozone_level, hass, lang }), unit: 'DU', icon: 'mdi:vector-triangle' },\n});\n\nconst skinData = (hass: HomeAssistant, lang: string, uv: iUltraviolet) => ({\n  skinType1: { value: getTime(getEntityNumericValue({ entityId: uv.set_skin_type_1, hass, lang })) },\n  skinType2: { value: getTime(getEntityNumericValue({ entityId: uv.set_skin_type_2, hass, lang })) },\n  skinType3: { value: getTime(getEntityNumericValue({ entityId: uv.set_skin_type_3, hass, lang })) },\n  skinType4: { value: getTime(getEntityNumericValue({ entityId: uv.set_skin_type_4, hass, lang })) },\n  skinType5: { value: getTime(getEntityNumericValue({ entityId: uv.set_skin_type_5, hass, lang })) },\n  skinType6: { value: getTime(getEntityNumericValue({ entityId: uv.set_skin_type_6, hass, lang })) },\n});\n\nconst buildUltraviolet = (hass: HomeAssistant, lang: string, uv: iUltraviolet) =>\n  // eslint-disable-next-line implicit-arrow-linebreak\n  renderUltraviolet({ ...summaryData(hass, lang, uv) }, { ...skinData(hass, lang, uv) });\n\nexport default buildUltraviolet;\n"
  },
  {
    "path": "src/builder/b-weather-forecast.ts",
    "content": "import { HomeAssistant } from 'custom-card-helpers/dist';\nimport { getWeatherIcon } from '../utils/helper-render';\nimport { iIconsConfig, iTerms } from '../base/lovelace-base';\nimport {\n  getEntityIcon,\n  getEntityNumericValue,\n  getEntityRawAttribute,\n  getEntityRawValue,\n  getEntityUnit,\n  getLocaleInfo,\n  getWindDirections,\n} from '../utils/helper';\nimport { iconPrecipitation, iconTemperature } from '../utils/const';\nimport { iForecastDataItem, renderWeatherForecast } from '../templates/t-weather-forecast';\nimport {\n  iDailyForecast,\n  iHourlyForecast,\n  iMarineDailyForecast,\n  iMarineHourlyForecast,\n} from '../utils/config-schema';\n\nconst getDefaultIcon = (metric: string): string => {\n  if (metric.includes('temperature')) return iconTemperature;\n  if (metric.includes('precipitation')) return iconPrecipitation;\n  return 'mdi:help-circle-outline';\n};\n\nconst buildHourlyForecastSlot = (\n  hass: HomeAssistant,\n  lang: string,\n  cwcLocWindDirections,\n  forecast: iHourlyForecast,\n  forecastType: number,\n  iconsConfig: iIconsConfig,\n  sunState: string,\n  slotId: string,\n) => {\n  const record: Record<string, iForecastDataItem> = {};\n  const localeInfo = getLocaleInfo(lang);\n\n  let datetime: Date;\n\n  // Condizione meteo\n  if (forecast.condition && forecast.condition[slotId]) {\n    record['condition'] = {\n      img: getWeatherIcon(getEntityRawValue(hass, forecast.condition[slotId]), iconsConfig, sunState),\n    };\n  }\n\n  // Wind Bearing\n  if (forecast.wind_bearing && forecast.wind_bearing[slotId]) {\n    record['wind_bearing'] = {\n      value: getWindDirections(getEntityRawValue(hass, forecast.wind_bearing[slotId]), cwcLocWindDirections),\n    };\n  }\n   \n  // Metriche da gestire\n  const metrics = [\n    'temperature',\n    'temperature_feelslike',\n    'precipitation_intensity',\n    'precipitation_probability',\n    'wind_speed',\n  ];\n\n  metrics.forEach((metricKey) => {\n    const metricSlots = forecast[metricKey];\n    const entityId = metricSlots?.[slotId];\n    let decimals = 0;\n\n    if (!entityId) return;\n\n    if (metricKey === 'precipitation_intensity') decimals = 2;\n\n    datetime = new Date(getEntityRawAttribute(hass, entityId, 'datetime'));\n\n    record[metricKey] = {\n      value: getEntityNumericValue({\n        entityId, hass, lang, decimals,\n      }),\n      unit: getEntityUnit(hass, entityId),\n      img: getEntityIcon(hass, entityId) || getDefaultIcon(metricKey),\n    };\n  });\n\n  if (datetime && Object.keys(record).length > 0) {\n    const hourTime = datetime.toLocaleTimeString(localeInfo.locale, {\n      hour: '2-digit',\n      minute: '2-digit',\n      timeZone: localeInfo.timezone,\n    });\n\n    record['reference'] = {\n      value: (forecastType === 0 ? hourTime : hourTime),\n    };\n  }\n\n  return record;\n};\n\nconst buildDailyForecastSlot = (\n  hass: HomeAssistant,\n  lang: string,\n  forecast: iDailyForecast,\n  forecastType: number,\n  iconsConfig: iIconsConfig,\n  sunState: string,\n  slotId: string,\n) => {\n  const record: Record<string, iForecastDataItem> = {};\n  const localeInfo = getLocaleInfo(lang);\n\n  let datetime: Date;\n\n  // Gestione condizione meteo\n  if (forecast.condition && forecast.condition[slotId]) {\n    record['condition'] = {\n      img: getWeatherIcon(getEntityRawValue(hass, forecast.condition[slotId]), iconsConfig, sunState),\n    };\n  }\n\n  // Lista fissa delle metriche da considerare\n  const metrics = [\n    'temperature_high',\n    'temperature_low',\n    'precipitation_intensity',\n    'precipitation_probability',\n  ];\n\n  metrics.forEach((metricKey) => {\n    const metricSlots = forecast[metricKey];\n    const entityId = metricSlots?.[slotId];\n    let decimals = 0;\n\n    if (!entityId) return;\n\n    if (metricKey === 'precipitation_intensity') {\n      decimals = 2;\n    }\n\n    datetime = new Date(getEntityRawAttribute(hass, entityId, 'datetime'));\n    // console.debug(`>>> ${entityId} ${lang} ${getEntityNumericValue({ entityId, hass, lang })}`);\n    record[metricKey] = {\n      value: getEntityNumericValue({\n        entityId, hass, lang, decimals,\n      }),\n      unit: getEntityUnit(hass, entityId),\n      img: getEntityIcon(hass, entityId) || getDefaultIcon(metricKey),\n    };\n  });\n\n  if (datetime && Object.keys(record).length > 0) {\n    // Giorno della settimana abbreviato (es. \"Lun\")\n    const weekday = datetime.toLocaleDateString(localeInfo.locale, {\n      weekday: 'short',\n      timeZone: 'UTC', // forza la lettura senza conversione locale\n    });\n\n    // Ora e minuti (es. \"13:45\")\n    const hourday = datetime.toLocaleTimeString(localeInfo.locale, {\n      hour: '2-digit',\n      minute: '2-digit',\n      timeZone: localeInfo.timezone,\n    });\n\n    record['reference'] = {\n      value: (forecastType === 0 ? weekday.toUpperCase() : hourday),\n    };\n  }\n\n  return record;\n};\n\nconst buildMarineDailyForecastSlot = (\n  hass: HomeAssistant,\n  lang: string,\n  cwcLocWindDirections,\n  forecast: iMarineDailyForecast,\n  forecastType: number,\n  iconsConfig: iIconsConfig,\n  sunState: string,\n  slotId: string,\n) => {\n  const record: Record<string, iForecastDataItem> = {};\n\n  const fieldColor = (\n    waveHeightMax: number,\n    swellWaveHeightMax: number,\n    windWaveHeightMax: number,\n  ) => {\n    // 🟥 Bandiera rossa – condizioni pericolose\n    if (waveHeightMax >= 1.8) {\n      return 'red';\n    }\n\n    if (swellWaveHeightMax >= 1.5 && windWaveHeightMax >= 0.8) {\n      return 'red';\n    }\n\n    // 🟨 Bandiera gialla – condizioni da attenzionare\n    if (waveHeightMax >= 1.0) {\n      return 'yellow';\n    }\n\n    if (swellWaveHeightMax >= 0.8) {\n      return 'yellow';\n    }\n\n    if (windWaveHeightMax >= 0.6) {\n      return 'yellow';\n    }\n\n    // 🟩 Bandiera verde – condizioni sicure\n    return 'green';\n  };\n\n  const localeInfo = getLocaleInfo(lang);\n\n  let datetime: Date;\n\n  // Gestione condizione meteo\n  if (\n    forecast.wave_height_max &&\n    forecast.swell_wave_height_max &&\n    forecast.wind_wave_height_max &&\n    forecast.swell_wave_height_max[slotId] &&\n    forecast.wind_wave_height_max[slotId]\n  ) {\n    record['condition'] = {\n      icon: 'mdi:flag-variant',\n      iconColor: fieldColor(forecast.wave_height_max[slotId], forecast.swell_wave_height_max[slotId], forecast.wind_wave_height_max[slotId]),\n    };\n  }\n\n  // Wind Bearing\n  if (forecast.wave_direction && forecast.wave_direction[slotId]) {\n    record['wave_direction'] = {\n      value: getWindDirections(getEntityRawValue(hass, forecast.wave_direction[slotId]), cwcLocWindDirections),\n      icon: getEntityRawValue(hass, forecast.wave_direction[slotId]),\n    };\n  }\n\n  // Lista fissa delle metriche da considerare\n  const metrics = [\n    'wave_height_max',\n    'swell_wave_height_max',\n    'wind_wave_height_max',\n  ];\n\n  metrics.forEach((metricKey) => {\n    const metricSlots = forecast[metricKey];\n    const entityId = metricSlots?.[slotId];\n    const decimals = 1;\n\n    if (!entityId) return;\n\n    datetime = new Date(getEntityRawAttribute(hass, entityId, 'datetime'));\n    // console.debug(`>>> ${entityId} ${lang} ${getEntityNumericValue({ entityId, hass, lang })}`);\n    record[metricKey] = {\n      value: getEntityNumericValue({\n        entityId, hass, lang, decimals,\n      }),\n      unit: getEntityUnit(hass, entityId),\n      img: getEntityIcon(hass, entityId) || getDefaultIcon(metricKey),\n    };\n  });\n\n  if (datetime && Object.keys(record).length > 0) {\n    // Giorno della settimana abbreviato (es. \"Lun\")\n    const weekday = datetime.toLocaleDateString(localeInfo.locale, {\n      weekday: 'short',\n      timeZone: 'UTC', // forza la lettura senza conversione locale\n    });\n\n    // Ora e minuti (es. \"13:45\")\n    const hourday = datetime.toLocaleTimeString(localeInfo.locale, {\n      hour: '2-digit',\n      minute: '2-digit',\n      timeZone: localeInfo.timezone,\n    });\n\n    record['reference'] = {\n      value: (forecastType === 2 ? weekday.toUpperCase() : hourday),\n    };\n  }\n\n  return record;\n};\n\nconst buildWeatherForecast = (\n  hass: HomeAssistant,\n  lang: string,\n  terms: iTerms,\n  dailyForecast: iDailyForecast,\n  hourlyForecast: iHourlyForecast,\n  marineDailyForecasts: iMarineDailyForecast,\n  marineHourlyForecasts: iMarineHourlyForecast,\n  forecastType: (0 | 1 | 2 | 3),\n  iconsConfig: iIconsConfig,\n  sunEntityId: string,\n) => {\n  const voidRecord: Record<string, iForecastDataItem>[] = [];\n  \n  const sunState = getEntityRawValue(hass, sunEntityId);\n\n  let dailyForecastData = voidRecord;\n  if (dailyForecast) {\n    const dailySlotIds = Object.keys(\n      dailyForecast.condition ||\n      dailyForecast.temperature_high || dailyForecast.temperature_low ||\n      dailyForecast.precipitation_intensity || dailyForecast.precipitation_probability ||\n      {},\n    );\n    dailyForecastData = dailySlotIds.map((slotId) => buildDailyForecastSlot(\n      hass,\n      lang,\n      dailyForecast,\n      forecastType,\n      iconsConfig,\n      sunState,\n      slotId,\n    ));\n  }\n\n  let hourlyforecastData = voidRecord;\n  if (hourlyForecast) {\n    const hourlySlotIds = Object.keys(\n      hourlyForecast.condition ||\n      hourlyForecast.temperature || hourlyForecast.temperature_feelslike ||\n      hourlyForecast.precipitation_intensity || hourlyForecast.precipitation_probability ||\n      {},\n    );\n    hourlyforecastData = hourlySlotIds.map((slotId) => buildHourlyForecastSlot(\n      hass,\n      lang,\n      terms.windDirections,\n      hourlyForecast,\n      forecastType,\n      iconsConfig,\n      sunState,\n      slotId,\n    ));\n  }\n\n  let marineDailyForecastData = voidRecord;\n  if (marineDailyForecasts) {\n    const marineDailySlotIds = Object.keys(\n      marineDailyForecasts.swell_wave_height_max ||\n      marineDailyForecasts.wave_direction || marineDailyForecasts.wave_height_max ||\n      marineDailyForecasts.wind_wave_height_max ||\n      {},\n    );\n    marineDailyForecastData = marineDailySlotIds.map((slotId) => buildMarineDailyForecastSlot(\n      hass,\n      lang,\n      terms.windDirections,\n      marineDailyForecasts,\n      forecastType,\n      iconsConfig,\n      sunState,\n      slotId,\n    ));\n  }\n\n  switch (forecastType) {\n    case 0:\n      return renderWeatherForecast(forecastType, dailyForecastData);\n    case 1:\n      return renderWeatherForecast(forecastType, hourlyforecastData);\n    case 2:\n      return renderWeatherForecast(forecastType, marineDailyForecastData);\n    default:\n      return renderWeatherForecast(forecastType, voidRecord);\n  }\n};\n\nexport default buildWeatherForecast;\n"
  },
  {
    "path": "src/css/css-base-card.ts",
    "content": "import { css } from 'lit';\n\nconst cardStyle = css`\n  ha-card {\n    cursor: pointer;\n    position: relative;\n    width: 100%;\n  }\n\n  .ha-card-weather-conditions {\n    width: 100%;\n    box-sizing: border-box;\n    background-color: var(--card-background-color, #1c1c1c);\n    color: var(--primary-text-color, #ffffff);\n    border-radius: var(--ha-card-border-radius, 12px);\n    box-shadow: var(--ha-card-box-shadow, 0 2px 6px rgba(0, 0, 0, 0.2));\n    overflow: hidden;\n    padding: 0;\n    display: flex;\n    flex-direction: column;\n  }\n\n  .nd-container {\n    width: 100%;\n    box-sizing: border-box;\n    display: flex;\n    flex-direction: column;\n    padding: 16px 20px; /* ← padding orizzontale più ampio */\n    gap: 12px;\n    background-size: cover;\n    background-position: center;\n    transition: background-image 0.3s ease-in-out;\n  }\n\n  /* Esempio di stile dinamico aggiuntivo se habgImage è una classe */\n  .nd-container.sunny {\n    background-image: url('/local/images/sunny-bg.jpg');\n  }\n\n  .nd-container.rainy {\n    background-image: url('/local/images/rainy-bg.jpg');\n  }\n\n  /* -------------- */\n\n`;\n\nexport default cardStyle;\n"
  },
  {
    "path": "src/css/css-camera.ts",
    "content": "import { css } from 'lit';\n\nconst cameraStyle = css`\n  .camera-container {\n    margin-top: 10px;\n    width: 100%;\n    display: flex;\n    align-items: stretch;\n  }\n\n  .camera-image {\n    aspect-ratio: 16 / 9;\n    width: 100%;\n    position: relative;\n    overflow: hidden;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n  }\n\n  .camera-image > img {\n    width: 100%;\n    height: 100%;\n    object-fit: cover;\n  }\n`;\n\nexport default cameraStyle;\n"
  },
  {
    "path": "src/css/css-meteoalarm.ts",
    "content": "import { css } from 'lit';\n\nconst meteodcpalarmStyle = css`\n.meteodcpalarm-grid-container {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: center;\n  gap: 16px;\n  padding: 12px;\n}\n\n.meteodcpalarm-group {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  flex: 1 1 72px;     /* 👈 cresce, ma non scende sotto i 72px */\n  max-width: 220px;   /* 👈 opzionale: previene allargamento eccessivo */\n  text-align: center;\n}\n\n.meteodcpalarm-group ha-icon {\n  --mdc-icon-size: 36px;\n}\n\n.meteodcpalarm-label {\n  margin-top: 6px;\n  font-size: 0.85em;\n  color: var(--primary-text-color);\n}\n\n\n`;\n\nexport default meteodcpalarmStyle;\n"
  },
  {
    "path": "src/css/css-pollen.ts",
    "content": "import { css } from 'lit';\n\nconst pollenStyle = css`\n.pollen-grid-container {\n  display: grid;\n  grid-template-columns: repeat(auto-fit, minmax(48px, 1fr));\n  gap: 8px 12px;\n  width: 100%;\n  justify-items: center;\n  align-items: end;\n  padding: 8px 4px;\n  box-sizing: border-box;\n}\n\n\n.pollen-stack {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 4px;\n  min-width: 48px;\n}\n\n\n  .levels {\n    display: flex;\n    flex-direction: column-reverse;\n    gap: clamp(1px, 0.2vw, 2px);\n  }\n\n  .level {\n    width: clamp(16px, 3.5vw, 24px);\n    height: clamp(5px, 0.7vw, 8px);     /* 👈 anche in altezza */\n    border-radius: 3px;\n    opacity: 0.3;\n    transition: opacity 0.2s ease;\n  }\n\n  .level.active {\n    opacity: 1;\n    outline: 1px solid #333;\n  }\n\n  .molto-alto {\n    background-color: #f44336;\n  }\n\n  .alto {\n    background-color: #ff9800;\n  }\n\n  .moderato {\n    background-color: #ffeb3b;\n  }\n\n  .basso {\n    background-color: #4caf50;\n  }\n\n  .pollen-name {\n    font-size: clamp(0.55em, 1.3vw, 0.85em); /* 👈 stringe di più */\n    // font-weight: 500;\n    text-align: center;\n    // color: #333;\n    white-space: nowrap;\n  }\n\n  .label {\n    width: 100%;\n    text-align: center;\n    font-size: clamp(0.55em, 1.3vw, 0.85em);\n    // font-weight: 500;\n    margin-top: clamp(4px, 0.5vw, 8px);\n  }\n`;\n\nexport default pollenStyle;\n"
  },
  {
    "path": "src/css/css-present.ts",
    "content": "import { css } from 'lit';\n\nconst presentStyle = css`\n.present-grid-container {\n  display: flex;\n  flex-direction: column;\n  gap: 4px;\n}\n\n.present-row {\n  display: flex;\n  justify-content: space-between;\n  gap: 16px;\n}\n\n.present-left,\n.present-right {\n  flex: 1;\n}\n\n.present-left {\n  display: flex;\n  justify-content: flex-start;\n}\n\n.present-right {\n  display: flex;\n  justify-content: flex-end;\n}\n\n.present-value-block {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n}\n\n.present-unit {\n  font-size: 0.9em;\n  opacity: 0.8;\n}\n`;\n\nexport default presentStyle;\n"
  },
  {
    "path": "src/css/css-summary.ts",
    "content": "import { css } from 'lit';\n\nconst summaryStyle = css`\n\n.summary-grid-container {\n  position: relative;\n  z-index: 1;\n  display: grid;\n  grid-template-columns: 1fr 1fr 1fr; /* <-- 3 colonne reali */\n  grid-template-rows: auto auto;\n  width: 100%;\n  max-width: 600px;\n  // background: #1c1c1c;\n  // color: white;\n  gap: 4px;\n  padding: 0px;\n  box-sizing: border-box;\n  // border: 1px solid #444; /* debug */\n}\n\n.summary-col-left {\n  grid-column: 1;\n  grid-row: 1 / span 2;\n  // background: #2c2c2c;\n  padding-top: 0px;\n  padding-right: 0px;\n  padding-bottom: 0px;\n  padding-left: 0px;\n  \n  display: flex;                 /* Attiva Flexbox */\n  justify-content: center;      /* Centra orizzontalmente */\n  align-items: center;          /* Centra verticalmente */\n\n  width: 100%;\n  max-width: 100%;\n  aspect-ratio: 1 / 1; /* opzionale: mantiene forma quadrata */\n  overflow: hidden;\n}\n\n.summary-top-right {\n  grid-column: 2 / span 2; /* occupa colonne 2 e 3 */\n  grid-row: 1;\n  // background: #3c3c3c;\n  padding-top: 0px;\n  padding-right: 8px;\n  padding-bottom: 0px;\n  padding-left: 8px;\n  display: flex;            /* aggiunto */\n  align-items: center;      /* centra verticalmente */\n  justify-content: flex-start; /* allinea a sinistra */\n}\n\n.summary-bottom-right-left {\n  grid-column: 2;\n  grid-row: 2;\n  // background: #4c4c4c;\n  padding-top: 0px;\n  padding-right: 8px;\n  padding-bottom: 0px;\n  padding-left: 8px;\n\n  display: flex;                 /* Attiva Flexbox */\n  justify-content: center;      /* Centra orizzontalmente */\n  align-items: center;          /* Centra verticalmente */\n}\n\n.summary-bottom-right-right {\n  grid-column: 3;\n  grid-row: 2;\n  // background: #5c5c5c;\n  padding-top: 0px;\n  padding-right: 8px;\n  padding-bottom: 0px;\n  padding-left: 8px;\n}\n\n.weather-condition-icon {\n  width: 100%;\n  height: auto;\n  max-width: 100%;\n  max-height: 100%;\n  object-fit: contain;\n  // max-width: 100%;\n  // max-height: 100%;\n  // width: 72px;\n  // height: 72px;\n  // object-fit: contain;\n\n  transition: transform 0.2s ease;\n}\n  \n.summary-col-left:hover .weather-condition-icon {\n  transform: scale(1.05);\n}\n\n.weather-city-name {\n  font-size: clamp(1em, 2vw, 1.2em);\n  text-align: left;\n}\n\n.moon-row {\n  display: flex;\n  align-items: center;\n  gap: 6px;\n  // font-size: 0.95em;\n  // color: #eeeeee;\n}\n\n.summary-moon-icon {\n  font-size: 1.8em;\n  display: inline-block;\n}\n\n.temperature-block {\n  display: flex;\n  flex-direction: column;\n  align-items: flex-end;\n  text-align: right;\n}\n\n.temperature {\n  font-size: 1.6em;\n  font-weight: bold;\n}\n\n.temp-unit {\n  font-size: 0.95em;\n  vertical-align: super;\n  margin-left: 2px;\n}\n\n.feels-like {\n  font-size: 0.85em;\n  // color: #aaaaaa;\n}\n\n.summary-wrapper {\n  position: relative;\n  width: 100%;\n  height: 100%;\n  min-height: 100px; /* oppure clamp() dinamico */\n  overflow: visible;\n}\n\n.lightning-background {\n  position: absolute;\n  inset: 0; /* top: 0; right: 0; bottom: 0; left: 0 */\n  pointer-events: none;\n  z-index: 0;\n}\n\n.lightning-flash {\n  position: absolute;\n  width: 2px;\n  background: white;\n  opacity: 0.7;\n  transform: translate(-50%, -50%);\n  animation-name: flash-blink;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n  border-radius: 1px;\n  filter: blur(0.5px);\n  box-shadow: 0 0 4px rgba(255,255,255,0.6);\n\n  z-index: 0;\n}\n\n@keyframes flash-blink {\n  0%, 100% {\n    opacity: 0.1;\n  }\n  50% {\n    opacity: 0.9;\n  }\n}\n\n.lightning-flash-zigzag {\n  position: absolute;\n  width: 2px;\n  height: 0;\n  background: linear-gradient(to bottom, yellow, white);\n  clip-path: polygon(var(--points));\n  animation: flash-zigzag linear forwards;\n  z-index: 3;\n}\n\n@keyframes flash-zigzag {\n  0% {\n    opacity: 1;\n    transform: scaleY(1);\n  }\n  100% {\n    opacity: 0;\n    transform: scaleY(1.2);\n  }\n}\n\n.lightning-svg {\n  position: absolute;\n  transform: translate(-50%, 0);\n  opacity: 0;\n  filter: drop-shadow(0 0 4px rgba(98, 61, 173, 0.6));\n  animation-name: flash-zigzag-svg;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: 1;\n  z-index: 3;\n}\n\n@keyframes flash-zigzag-svg {\n  0%, 100% {\n    opacity: 0;\n  }\n  40% {\n    opacity: 1;\n  }\n  60% {\n    opacity: 0.5;\n  }\n}\n`;\n\nexport default summaryStyle;\n"
  },
  {
    "path": "src/css/css-ultraviolet.ts",
    "content": "import { css } from 'lit';\n\nconst ultravioletStyle = css`\n.ultraviolet-grid-container {\n  display: flex;\n  flex-direction: column;\n  gap: 4px;\n}\n\n.ultraviolet-row {\n  display: flex;\n  justify-content: space-between;\n  gap: 16px;\n}\n\n.ultraviolet-left,\n.present-right {\n  flex: 1;\n}\n\n.ultraviolet-left {\n  display: flex;\n  justify-content: flex-start;\n}\n\n.ultraviolet-right {\n  display: flex;\n  justify-content: flex-end;\n}\n\n.ultraviolet-value-block {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n}\n\n.ultraviolet-unit {\n  font-size: 0.9em;\n  opacity: 0.8;\n}\n\n------------------------------------------------------------------\n\n// .ultraviolet-grid-container {\n//   display: flex;\n//   flex-direction: column;\n//   gap: 12px;\n// }\n\n// .ultraviolet-row {\n//   display: flex;\n//   justify-content: space-between;\n//   padding: 4px 0;\n// }\n\n// .ultraviolet-value-block {\n//   display: flex;\n//   align-items: center;\n//   gap: 4px;\n// }\n\n// .ultraviolet-unit {\n//   font-size: 0.9em;\n//   opacity: 0.7;\n// }\n\n.ultraviolet-skin-type-grid {\n  display: grid;\n  grid-template-columns: repeat(auto-fit, minmax(48px, 1fr));\n  gap: 8px;\n  margin-top: 8px;\n}\n\n.ultraviolet-skin-type-cell {\n  flex: 1;\n  min-width: 48px;\n  height: 48px;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  border-radius: 6px;\n  font-family: 'Segoe UI', sans-serif;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n  color: black;\n}\n\n.ultraviolet-skin-type-label {\n  font-weight: bold;\n  font-size: 0.95em;\n  line-height: 1em;\n}\n\n.ultraviolet-exposure-time {\n  font-size: 0.75em;\n  margin-top: 2px;\n  color: #222;\n  opacity: 0.85;\n}\n\n\n\n\n\n\n`;\n\nexport default ultravioletStyle;\n"
  },
  {
    "path": "src/css/css-weather-forecast.ts",
    "content": "import { css } from 'lit';\n\nconst weatherForecastStyle = css`\n\n.weather-forecast-grid-container {\n  display: grid;\n  grid-template-columns: repeat(auto-fit, minmax(78px, 1fr));\n  column-gap: 2px; /* spazio orizzontale tra i giorni */\n  row-gap: 6px;    /* spazio verticale tra righe, se ci sono */\n  align-items: stretch;\n  font-family: 'Segoe UI', sans-serif;\n  width: 100%;\n}\n  \n.weather-forecast-grid-wrapper {\n  display: flex;\n  flex-direction: column;\n  align-items: center; /* centrare il titolo orizzontalmente */\n}\n\n.weather-forecast-title {\n  font-size: clamp(0.85em, 1vw, 0.95em);\n  font-weight: bold;\n  // margin-bottom: 0.5em;\n  text-align: center;\n}\n\n.weather-forecast-slot {\n  text-align: center;\n  padding: 8px 4px;\n  min-width: 0;\n  overflow: hidden;\n}\n\n.weather-forecast-slot:last-child {\n  border-right: none;\n}\n\n.weather-forecast-label-slot {\n  font-size: 0.9em;\n  font-weight: bold;\n  margin-bottom: 6px; /* ridotto */\n}\n\n.weather-forecast-icon {\n  font-size: 1.6rem; /* ridotto */\n  /* margin: 6px 0; ridotto */\n  height: 32px;\n}\n\n.weather-forecast-temperature {\n  font-size: clamp(0.8em, 1vw, 0.9em); /* leggermente più piccolo */\n  margin: 4px 0; /* meno margine */\n}\n\n.weather-forecast-temperature .high {\n  font-weight: bold;\n}\n\n.weather-forecast-precipitation {\n  font-size: clamp(0.65em, 1vw, 0.75em);\n  line-height: 1.2; /* compatta verticalmente */\n}\n\n.weather-forecast-precipitation .mm {\n  font-weight: bold;\n}\n`;\n\nexport default weatherForecastStyle;\n"
  },
  {
    "path": "src/ha-weather-ecard.ts",
    "content": "/* eslint-disable no-underscore-dangle */\nimport { html, TemplateResult } from 'lit';\nimport { customElement } from 'lit/decorators.js';\n\nimport { LovelaceBaseElement, preloadResources } from './base/lovelace-base';\n\nimport buildWeatherSummary from './builder/b-summary';\nimport buildWeatherPresent from './builder/b-present';\nimport buildUltraviolet from './builder/b-ultraviolet';\nimport buildPollen from './builder/b-pollen';\nimport buildWeatherForecast from './builder/b-weather-forecast';\nimport buildCamera from './builder/b-camera';\nimport buildAirQuality from './builder/b-airquality';\nimport buildMeteoDPCalarm from './builder/b-meteoalarm';\n\nconst { translations, imagePath } = await preloadResources(); // esecuzione immediata\n\n/* -------------------- DEFINIZIONE COMPONENTE -------------------- */\n\n@customElement('ha-card-weather-conditions')\n// eslint-disable-next-line import/prefer-default-export\nexport class HaCardWeatherConditions extends LovelaceBaseElement {\n  _translations = translations;\n\n  _imagesPath = imagePath;\n\n  // eslint-disable-next-line class-methods-use-this\n  protected _render(): TemplateResult {\n    return html`\n      <ha-card class=\"ha-card-weather-conditions\">\n        <div class=\"nd-container\">\n          ${this._buildTemplate()}\n        </div>\n      </ha-card>\n    `;\n  }\n\n  private _buildTemplate(): TemplateResult {\n    let summary = html``;\n    let present = html``;\n    let dailyWeatherForecast = html``;\n    let hourlyWeatherForecast = html``;\n    let marineDailyWeatherForecast = html``;\n    let marineHourlyWeatherForecast = html``;\n    let meteoDPCalarm = html``;\n    let ultraviolet = html``;\n    let pollen = html``;\n    let airQuality = html``;\n    let camera = html``;\n\n    const getWeatherForecast = (mode: 0 | 1 | 2 | 3) => buildWeatherForecast(\n      this.hass,\n      this._language,\n      this._terms,\n      this._config.weather.daily_forecasts,\n      this._config.weather.hourly_forecasts,\n      this._config.weather.marine_daily_forecasts,\n      this._config.weather.marine_hourly_forecasts,\n      mode,\n      this._iconsConfig,\n      this._config.weather.sun,\n    );\n\n    if (this._hasPresent) {\n      summary = buildWeatherSummary(\n        this.hass,\n        this._language,\n        this._terms,\n        this._iconsConfig,\n        this._config.weather?.name,\n        this._config?.weather?.present || null,\n        this._config?.weather?.sun,\n        this._config?.weather?.moonphase,\n      );\n    }\n\n    if (this._hasPresent) {\n      present = buildWeatherPresent(\n        this.hass,\n        this._language,\n        this._terms,\n        this._config?.weather?.present || {},\n        this._config?.weather?.sun,\n      );\n    }\n\n    if (this._hasMetealarm || this._hasDPCalarm) {\n      meteoDPCalarm = buildMeteoDPCalarm(\n        this.hass,\n        this._language,\n        this._terms,\n        this._config?.weather?.meteoalarm,\n        this._config?.weather?.dpcalarm,\n      );\n    }\n\n    if (this._hasDailyForecasts) {\n      dailyWeatherForecast = getWeatherForecast(0);\n    }\n    if (this._hasHourlyForecasts) {\n      hourlyWeatherForecast = getWeatherForecast(1);\n    }\n    if (this._hasMarineDailyForecasts) {\n      marineDailyWeatherForecast = getWeatherForecast(2);\n    }\n    if (this._hasMarineHourlyForecasts) {\n      marineHourlyWeatherForecast = getWeatherForecast(3);\n    }\n\n    if (this._hasUltraviolet) {\n      ultraviolet = buildUltraviolet(this.hass, this._language, this._config.ultraviolet);\n    }\n\n    if (this._hasPollen) {\n      pollen = buildPollen(this.hass, this._language, this._config.pollen);\n    }\n\n    if (this._hasAirQuality) {\n      airQuality = buildAirQuality(this.hass, this._language, this._config.airquality);\n    }\n\n    if (this._hasCamera) {\n      camera = buildCamera(this.hass, this._language, this._terms, this._handlePopup.bind(this), this._config.camera);\n    }\n\n    return html`\n    ${summary}\n    ${present}\n    ${hourlyWeatherForecast}\n    ${dailyWeatherForecast}\n    ${marineHourlyWeatherForecast}\n    ${marineDailyWeatherForecast}\n    ${meteoDPCalarm}\n    ${pollen}\n    ${ultraviolet}\n    ${airQuality}\n    ${camera}`;\n  }\n\n  /**\n   * Apre il popup di dettaglio per l'entità specificata.\n   * @param e L'evento click originale.\n   * @param entityId L'ID dell'entità Home Assistant da mostrare.\n   */\n  protected _handlePopup(e: Event, entityId: string) {\n    e.stopPropagation();\n\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    const moreInfoEvent = new Event('hass-more-info', { composed: true }) as any;\n    moreInfoEvent.detail = { entityId };\n    this.dispatchEvent(moreInfoEvent);\n  }\n}\n"
  },
  {
    "path": "src/iconmodels/im-buienradar.ts",
    "content": "// clear=ok, partlycloudy=ok, cloudy=ok, partlycloudy-fog=ok, partlycloudy-light-rain=ok, partlycloudy-rain=ok,\n// light-rain=ok, rainy=ok, snowy-rainy=ok, partlycloudy-light-snow=ok, partlycloudy-snow=ok, light-snow=ok, snowy=ok,\n// partlycloudy-lightning=ok or lightning\n\nexport const cwcBuienradarDayIcons: { [key: string]: string; } = {\n  // freezing_rain_heavy: 'rainy-3',\n  // freezing_rain: 'rainy-2',\n  // freezing_rain_light: 'rainy-1',\n  // freezing_drizzle: 'rain-and-sleet-mix',\n  // ice_pellets_heavy: 'rain-and-snow-mix',\n  // ice_pellets: 'rain-and-snow-mix',\n  // ice_pellets_light: 'rain-and-snow-mix',\n  snowy: 'snowy-3',\n  'light-snow': 'snowy-2',\n  'snowy-rainy': 'snowy-1',\n  'partlycloudy-light-snow': 'snowy-1',\n  'partlycloudy-snow': 'snowy-1',\n  // flurries: 'wind',\n  // tstorm: 'tropical-storm',\n  // rain_heavy: 'rainy-3',\n  'partlycloudy-light-rain': 'rainy-1',\n  'light-rain': 'rainy-1',\n  rainy: 'rainy-2',\n  'partlycloudy-rain': 'rainy-1',\n  // fog_light: 'haze',\n  'partlycloudy-fog': 'fog',\n  cloudy: 'cloudy-original',\n  // mostly_cloudy: 'cloudy-day-3',\n  partlycloudy: 'cloudy-day-2',\n  'partlycloudy-lightning': 'cloudy-day-1',\n  lightning: 'cloudy-day-1',\n  // mostly_clear: 'cloudy-day-1',\n  clear: 'day',\n};\n\nexport const cwcBuienradarNightIcons: { [key: string]: string; } = {\n  ...cwcBuienradarDayIcons,\n  // freezing_rain_heavy: 'rainy-6',\n  // freezing_rain: 'rainy-5',\n  // freezing_rain_light: 'rainy-4',\n  // freezing_drizzle: 'rain-and-sleet-mix',\n  // ice_pellets_heavy: 'rain-and-snow-mix',\n  // ice_pellets: 'rain-and-snow-mix',\n  // ice_pellets_light: 'rain-and-snow-mix',\n  // snow_heavy: 'snowy-6',\n  // snow: 'nowy-5',\n  // snow_light: 'nowy-4',\n  // flurries: 'wind',\n  // tstorm: 'tropical-storm',\n  // rain_heavy: 'rainy-6',\n  // rain_light: 'rainy-4',\n  // rain: 'rainy-5',\n  // drizzle: 'rainy-4',\n  // fog_light: 'haze',\n  // fog: 'fog',\n  // cloudy: 'cloudy',\n  // mostly_cloudy: 'cloudy-night-3',\n  // partly_cloudy: 'cloudy-night-2',\n  // mostly_clear: 'cloudy-night-1',\n  // clear: 'night'\n};\n"
  },
  {
    "path": "src/iconmodels/im-climacell.ts",
    "content": "export const cwcClimacellDayIcons: { [key: string]: string; } = {\n  freezing_rain_heavy: 'rainy-3',\n  'heavy freezing rain': 'rainy-3',\n  freezing_rain: 'rainy-2',\n  'freezing rain': 'rainy-2',\n  freezing_rain_light: 'rainy-1',\n  'light freezing rain': 'rainy-1',\n  freezing_drizzle: 'rain-and-sleet-mix',\n  'freezing drizzle': 'rain-and-sleet-mix',\n  ice_pellets_heavy: 'rain-and-snow-mix',\n  'heavy ice pellets': 'rain-and-snow-mix',\n  ice_pellets: 'rain-and-snow-mix',\n  'ice pellets': 'rain-and-snow-mix',\n  ice_pellets_light: 'rain-and-snow-mix',\n  'light ice pellets': 'rain-and-snow-mix',\n  snow_heavy: 'snowy-3',\n  'heavy snow': 'snowy-3',\n  snow: 'snowy-2',\n  snow_light: 'snowy-1',\n  'light snow': 'snowy-1',\n  flurries: 'wind',\n  tstorm: 'tropical-storm',\n  rain_heavy: 'rainy-3',\n  'heavy rain': 'rainy-3',\n  rain_light: 'rainy-1',\n  'light rain': 'rainy-1',\n  rain: 'rainy-2',\n  drizzle: 'rainy-1',\n  fog_light: 'haze',\n  'light fog': 'haze',\n  fog: 'fog',\n  cloudy: 'cloudy-original',\n  mostly_cloudy: 'cloudy-day-3',\n  'mostly cloudy': 'cloudy-day-3',\n  partly_cloudy: 'cloudy-day-2',\n  'partly cloudy': 'cloudy-day-2',\n  mostly_clear: 'cloudy-day-1',\n  'mostly clear': 'cloudy-day-1',\n  clear: 'day',\n};\n\nexport const cwcClimacellNightIcons: { [key: string]: string; } = {\n  ...cwcClimacellDayIcons,\n  freezing_rain_heavy: 'rainy-6',\n  'heavy freezing rain': 'rainy-6',\n  freezing_rain: 'rainy-5',\n  'freezing rain': 'rainy-5',\n  freezing_rain_light: 'rainy-4',\n  'light freezing rain': 'rainy-4',\n  // freezing_drizzle: 'rain-and-sleet-mix',\n  // ice_pellets_heavy: 'rain-and-snow-mix',\n  // ice_pellets: 'rain-and-snow-mix',\n  // ice_pellets_light: 'rain-and-snow-mix',\n  snow_heavy: 'snowy-6',\n  'heavy snow': 'snowy-6',\n  snow: 'snowy-5',\n  snow_light: 'snowy-4',\n  'light snow': 'snowy-4',\n  // flurries: 'wind',\n  // tstorm: 'tropical-storm',\n  rain_heavy: 'rainy-6',\n  'heavy rain': 'rainy-6',\n  rain_light: 'rainy-4',\n  'light rain': 'rainy-4',\n  rain: 'rainy-5',\n  drizzle: 'rainy-4',\n  // fog_light: 'haze',\n  // fog: 'fog',\n  // cloudy: 'cloudy',\n  mostly_cloudy: 'cloudy-night-3',\n  'mostly cloudy': 'cloudy-night-3',\n  partly_cloudy: 'cloudy-night-2',\n  'partly cloudy': 'cloudy-night-2',\n  mostly_clear: 'cloudy-night-1',\n  'mostly clear': 'cloudy-night-1',\n  clear: 'night',\n  sunny: 'night',\n};\n\nexport const cwcClimacellDayBg: { [key: string]: string; } = {\n  freezing_rain_heavy: 'rainy-3',\n  freezing_rain: 'rainy-2',\n  freezing_rain_light: 'rainy-1',\n  freezing_drizzle: 'rain-and-sleet-mix',\n  ice_pellets_heavy: 'rain-and-snow-mix',\n  ice_pellets: 'rain-and-snow-mix',\n  ice_pellets_light: 'rain-and-snow-mix',\n  snow_heavy: 'snowy-3',\n  snow: 'snowy-2',\n  snow_light: 'snowy-1',\n  flurries: 'wind',\n  tstorm: 'tropical-storm',\n  rain_heavy: 'rainy-3',\n  rain_light: 'rainy-1',\n  rain: 'rainy-2',\n  drizzle: 'rainy-1',\n  fog_light: 'haze',\n  fog: 'fog',\n  cloudy: 'cloudy-original',\n  mostly_cloudy: 'day-cloud-3.jpg',\n  partly_cloudy: 'day-cloud-2.jpg',\n  mostly_clear: 'day-cloud-1.jpg',\n  clear: 'day-clear.jpg',\n};\n"
  },
  {
    "path": "src/iconmodels/im-darksky.ts",
    "content": "export const cwcDarkskyDayIcons: { [key: string]: string; } = {\n  clear: 'day',\n  'clear-day': 'day',\n  rain: 'rainy-2',\n  snow: 'snowy-2',\n  sleet: 'rain-and-sleet-mix',\n  wind: 'cloudy-day-1',\n  fog: 'fog',\n  cloudy: 'cloudy-original',\n  'partly-cloudy-day': 'cloudy-day-2',\n};\n\nexport const cwcDarkskyNightIcons: { [key: string]: string; } = {\n  ...cwcDarkskyDayIcons,\n  clear: 'night',\n  'clear-night': 'night',\n  wind: 'cloudy-night-1',\n  'partly-cloudy-day': 'cloudy-night-2',\n  'partly-cloudy-night': 'cloudy-night-2',\n};\n"
  },
  {
    "path": "src/iconmodels/im-hass.ts",
    "content": "export const cwcDefaultHassDayIcons: { [key: string]: string } = {\n  cloudy: 'cloudy-day-3',\n  exceptional: 'severe-thunderstorm',\n  fog: 'fog',\n  hail: 'snow-and-sleet-mix',\n  lightning: 'severe-thunderstorm',\n  'lightning-rainy': 'scattered-thunderstorms',\n  partlycloudy: 'cloudy-day-3',\n  pouring: 'rainy-6',\n  rainy: 'rainy-5',\n  snowy: 'snowy-6',\n  'snowy-rainy': 'snow-and-sleet-mix',\n  sunny: 'clear-day',\n  windy: 'wind',\n  'windy-variant': 'wind',\n};\n\nexport const cwcDefaultHassNightIcons: { [key: string]: string } = {\n  ...cwcDefaultHassDayIcons,\n  'clear-night': 'clear-night',\n};\n"
  },
  {
    "path": "src/iconmodels/im-openweathermap.ts",
    "content": "export const cwcOpenWeatherMapDayIcons: { [key: string]: string; } = {\n  'clear sky': 'day',\n  'few clouds': 'cloudy-day-1',\n  'scattered clouds': 'cloudy-day-2',\n  'broken clouds': 'cloudy-day-3',\n  'shower rain': 'rainy-3',\n  rain: 'rainy-2',\n  thunderstorm: 'tropical-storm',\n  snow: 'snowy-2',\n  mist: 'fog',\n};\n\nexport const cwcOpenWeatherMapNightIcons: { [key: string]: string; } = {\n  ...cwcOpenWeatherMapDayIcons,\n  'clear sky': 'day-night',\n  'few clouds': 'cloudy-night-1',\n  'scattered clouds': 'cloudy-night-2',\n  'broken clouds': 'cloudy-night-3',\n};\n"
  },
  {
    "path": "src/iconmodels/im-pirateweather.ts",
    "content": "// Pirate Weather Icons\n// clear-day, clear-night, rain, snow, sleet, wind, fog, cloudy, partly-cloudy-day and partly-cloudy-night\n// mostly-clear-day, mostly-clear-night, mostly-cloudy-day, mostly-cloudy-night, possible-rain-day, possible-rain-night\n// possible-snow-day, possible-snow-night, possible-sleet-day, possible-sleet-night, possible-precipitation-day\n// possible-precipitation-night, precipitation, drizzle, light-rain, heavy-rain, flurries, light-snow, heavy-snow\n// very-light-sleet, light-sleet, heavy-sleet, breezy, dangerous-wind\n\nexport const cwcDaytimePirateWeatherIcons: { [key: string]: string; } = {\n  freezing_rain_heavy: 'rainy-3',\n  'heavy freezing rain': 'rainy-3',\n  freezing_rain: 'rainy-2',\n  'freezing rain': 'rainy-2',\n  freezing_rain_light: 'rainy-1',\n  'light freezing rain': 'rainy-1',\n  freezing_drizzle: 'rain-and-sleet-mix',\n  sleet: 'rain-and-sleet-mix',\n  'freezing drizzle': 'rain-and-sleet-mix',\n  ice_pellets_heavy: 'rain-and-snow-mix',\n  'heavy ice pellets': 'rain-and-snow-mix',\n  ice_pellets: 'rain-and-snow-mix',\n  'ice pellets': 'rain-and-snow-mix',\n  ice_pellets_light: 'rain-and-snow-mix',\n  'light ice pellets': 'rain-and-snow-mix',\n  snow_heavy: 'snowy-3',\n  'heavy snow': 'snowy-3',\n  snow: 'snowy-2',\n  snow_light: 'snowy-1',\n  'light snow': 'snowy-1',\n  flurries: 'wind',\n  tstorm: 'tropical-storm',\n  rain_heavy: 'rainy-3',\n  'heavy rain': 'rainy-3',\n  rain_light: 'rainy-1',\n  rainy: 'rainy-1',\n  'light rain': 'rainy-1',\n  rain: 'rainy-2',\n  drizzle: 'rainy-1',\n  fog_light: 'haze',\n  'light fog': 'haze',\n  fog: 'fog',\n  cloudy: 'cloudy-original',\n  mostly_cloudy: 'cloudy-day-3',\n  'mostly cloudy': 'cloudy-day-3',\n  partly_cloudy: 'cloudy-day-2',\n  partlycloudy: 'cloudy-day-2',\n  'partly-cloudy-day': 'cloudy-day-2',\n  'partly cloudy': 'cloudy-day-2',\n  mostly_clear: 'cloudy-day-1',\n  'mostly clear': 'cloudy-day-1',\n  clear: 'day',\n  'clear-day': 'day',\n  wind: 'wind',\n  windy: 'wind',\n  sunny: 'day',\n  'clear-night': 'day',\n};\n\nexport const cwcNightlyPirateWeaterIcons: { [key: string]: string; } = {\n  ...cwcDaytimePirateWeatherIcons,\n  freezing_rain_heavy: 'rainy-6',\n  'heavy freezing rain': 'rainy-6',\n  freezing_rain: 'rainy-5',\n  'freezing rain': 'rainy-5',\n  freezing_rain_light: 'rainy-4',\n  'light freezing rain': 'rainy-4',\n  // freezing_drizzle: 'rain-and-sleet-mix',\n  // ice_pellets_heavy: 'rain-and-snow-mix',\n  // ice_pellets: 'rain-and-snow-mix',\n  // ice_pellets_light: 'rain-and-snow-mix',\n  snow_heavy: 'snowy-6',\n  'heavy snow': 'snowy-6',\n  snow: 'snowy-5',\n  snow_light: 'snowy-4',\n  'light snow': 'snowy-4',\n  // flurries: 'wind',\n  // tstorm: 'tropical-storm',\n  rain_heavy: 'rainy-6',\n  'heavy rain': 'rainy-6',\n  rain_light: 'rainy-4',\n  'light rain': 'rainy-4',\n  rain: 'rainy-5',\n  drizzle: 'rainy-4',\n  // fog_light: 'haze',\n  // fog: 'fog',\n  // cloudy: 'cloudy',\n  mostly_cloudy: 'cloudy-night-3',\n  'mostly cloudy': 'cloudy-night-3',\n  partly_cloudy: 'cloudy-night-2',\n  partlycloudy: 'cloudy-night-2',\n  'partly-cloudy-night': 'cloudy-night-2',\n  'partly cloudy': 'cloudy-night-2',\n  mostly_clear: 'cloudy-night-1',\n  'mostly clear': 'cloudy-night-1',\n  clear: 'night',\n  'clear-night': 'night',\n  sunny: 'night',\n};\n"
  },
  {
    "path": "src/templates/t-camera.ts",
    "content": "import { html } from 'lit';\n\nconst renderCamera = (\n  handlePopup: (e: Event, entityId: string) => void,\n  cameraId: string,\n  cameraPicture: string,\n  friendlyName: string,\n) => {\n  if (!cameraPicture) return html``;\n\n  return html`\n    <div \n      class=\"camera-container\"\n      @click=${(e: Event) => handlePopup(e, cameraId)}\n    >\n      <div class=\"camera-image\">\n        <img \n          src=\"${cameraPicture}\" \n          alt=\"${friendlyName}\"\n          loading=\"lazy\"\n        />\n      </div>\n    </div>\n  `;\n};\n\nexport default renderCamera;\n"
  },
  {
    "path": "src/templates/t-meteoalarm.ts",
    "content": "import { html } from 'lit';\n\nexport interface iWeatherMeteoDPCAlarmDataInterface {\n  event?: string,\n  severity?: string,\n  icon?: string,\n  icon_color?: string,\n  datetime?: string,\n}\n\nconst renderMeteoDPCalarm = (\n  meteoDPCalarmData: Record<string, iWeatherMeteoDPCAlarmDataInterface> | null,\n) => {\n  if (!meteoDPCalarmData || Object.keys(meteoDPCalarmData).length === 0) return html``;\n\n  return html`\n  <div class=\"meteodcpalarm-grid-container\">\n    ${Object.entries(meteoDPCalarmData).map(([key, data]) => html`\n      <div class=\"meteodcpalarm-group\">\n        <ha-icon icon=\"${data.icon}\" style=\"color: ${data.icon_color};\"></ha-icon>\n        <div class=\"meteodcpalarm-label\">${data.datetime}</div>\n        <div class=\"meteodcpalarm-label\">${data.event}</div>\n      </div>\n    `)}\n  </div>\n  `;\n};\n\nexport default renderMeteoDPCalarm;\n"
  },
  {
    "path": "src/templates/t-pollen.ts",
    "content": "import { html } from 'lit';\n\nexport interface iPollenData {\n  name: string;\n  value: number;\n}\n\nconst LEVEL_NAMES = ['basso', 'moderato', 'alto', 'molto-alto', 'estremo'];\n\nconst getLevelIndex = (value: number, levelMin: number, levelMax: number): number => {\n  const range = levelMax - levelMin + 1;\n  const step = range / LEVEL_NAMES.length;\n  const index = Math.floor((value - levelMin) / step);\n  return Math.min(index, LEVEL_NAMES.length - 1);\n};\n\nexport const renderPollen = (data: iPollenData[], levelMin: number, levelMax: number) => {\n  const numLevels = levelMax - levelMin + 1;\n  const levels = LEVEL_NAMES.slice(0, numLevels);\n\n  if (data.length === 0) {\n    return html``;\n  }\n\n  return html`\n    <div class=\"pollen-grid-container\">\n      ${data.map((item) => {\n    const activeIndex = getLevelIndex(item.value, levelMin, levelMax);\n    return html`\n          <div class=\"pollen-stack\">\n            <div class=\"levels\">\n              ${levels.map((levelName, index) => html`\n                <div\n                  class=\"level ${levelName} ${index === activeIndex ? 'active' : ''}\"\n                  title=\"${levelName}\"\n                ></div>\n              `)}\n            </div>\n            <div class=\"pollen-name\">${item.name}</div>\n          </div>\n        `;\n  })}\n    </div>\n  `;\n};\n"
  },
  {
    "path": "src/templates/t-present.ts",
    "content": "import { html } from 'lit';\nimport { getLocale, parseLocalizedNumber } from '../utils/helper';\n\nexport interface iRenderDataItem {\n  value?: number | string | Date;\n  unit?: string;\n  icon?: string;\n  icon_color?: string;\n}\n\nexport interface WeatherData {\n  temperatureHigh?: iRenderDataItem;\n  temperatureLow?: iRenderDataItem;\n  precipitationProbability?: iRenderDataItem;\n  precipitationIntensity?: iRenderDataItem;\n  nextRising?: iRenderDataItem;\n  nextSetting?: iRenderDataItem;\n\n  // precipitation?: iRenderDataItem;\n  humidity?: iRenderDataItem;\n  windBearing?: iRenderDataItem;\n  windSpeed?: iRenderDataItem;\n  pressure?: iRenderDataItem;\n  visibility?: iRenderDataItem;\n}\n\nexport interface iAirQualityData {\n  pm25: iRenderDataItem,\n  pm10:iRenderDataItem,\n  o3: iRenderDataItem,\n  no2: iRenderDataItem,\n  co: iRenderDataItem,\n  so2: iRenderDataItem,\n  epa_aqi: iRenderDataItem,\n  epa_primary_pollutant: iRenderDataItem,\n}\n\nconst isValidInput = (val: unknown): val is string | number => typeof val === 'string' || typeof val === 'number';\n\nconst prepareWeatherPresent = (data: WeatherData, language: string) => {\n  const allItems: iRenderDataItem[] = [];\n\n  const addIfValid = (key: keyof WeatherData, item?: iRenderDataItem) => {\n    if (item?.value === undefined) return;\n\n    allItems.push(item);\n  };\n\n  const pi = data.precipitationIntensity?.value;\n  const pp = data.precipitationProbability?.value;\n\n  if (isValidInput(pi) && isValidInput(pp)) {\n    const locale = getLocale(language);\n    const parsedPI = parseLocalizedNumber(pi, locale);\n    const parsedPP = parseLocalizedNumber(pp, locale);\n\n    if (!Number.isNaN(Number(parsedPI)) && !Number.isNaN(Number(parsedPP)) && parsedPI > 0 && parsedPP > 0) {\n      allItems.push({\n        icon:\n          data.precipitationIntensity.icon ||\n          data.precipitationProbability.icon ||\n          'mdi:weather-rainy',\n        // eslint-disable-next-line max-len\n        value: `${data.precipitationIntensity.value} ${data.precipitationIntensity.unit} / ${data.precipitationProbability.value} ${data.precipitationProbability.unit}`,\n      });\n    }\n  }\n\n  // Temperatura min/max combinata\n  if (\n    data.temperatureLow?.value !== undefined &&\n    data.temperatureHigh?.value !== undefined\n  ) {\n    allItems.push({\n      icon: data.temperatureLow.icon || data.temperatureHigh.icon || 'mdi:thermometer',\n      value: `${data.temperatureLow.value} / ${data.temperatureHigh.value}`,\n      unit: data.temperatureLow.unit || data.temperatureHigh.unit,\n    });\n  }\n\n  const keys: (keyof WeatherData)[] = [\n    'humidity',\n    'pressure',\n    'visibility',\n  ];\n  keys.forEach((k) => addIfValid(k, data[k]));\n\n  // Wind (bearing + speed)\n  // eslint-disable-next-line max-len\n  if (data.windSpeed?.value !== undefined || data.windBearing?.value !== undefined) {\n    allItems.push({\n      icon: data.windSpeed?.icon || 'mdi:weather-windy',\n      value: `${data.windBearing?.value ? `${data.windBearing.value} ` : ''}${data.windSpeed?.value ?? ''}`,\n      unit: data.windSpeed?.unit ? `${data.windSpeed.unit}` : '',\n    });\n  }\n\n  // Sun times\n  ['nextRising', 'nextSetting'].forEach((k) => {\n    const item = data[k as keyof WeatherData];\n    if (item?.value) {\n      allItems.push({\n        icon: item.icon,\n        value: item.value,\n        unit: '',\n      });\n    }\n  });\n\n  return allItems;\n};\n\nconst prepareAirQuality = (data: iAirQualityData, language: string) => {\n  const allItems: iRenderDataItem[] = [];\n\n  const addIfValid = (key: keyof iAirQualityData, item?: iRenderDataItem) => {\n    if (item?.value === undefined) return;\n\n    allItems.push(item);\n  };\n\n  const keys: (keyof iAirQualityData)[] = [\n    'epa_aqi',\n    'epa_primary_pollutant',\n    'pm25',\n    'pm10',\n    'o3',\n    'no2',\n    'co',\n    'so2',\n  ];\n  keys.forEach((k) => addIfValid(k, data[k]));\n\n  return allItems;\n};\n\nexport const renderWeatherPresent = (data, language: string) => {\n  const allItems: iRenderDataItem[] = [];\n\n  const buildBlockLeft = (item: iRenderDataItem) => html`\n    <span class=\"present-value-block\">\n      <ha-icon icon=\"${item.icon}\" style=${item.icon_color ? `color: ${item.icon_color}` : ''}></ha-icon>\n      ${item.value}${item.unit ? html`<span class=\"present-unit\">${item.unit}</span>` : ''}\n    </span>\n  `;\n\n  const buildBlockRight = (item: iRenderDataItem) => html`\n    <span class=\"present-value-block\">\n      ${item.value}${item.unit ? html`<span class=\"present-unit\">${item.unit}</span>` : ''}\n      <ha-icon icon=\"${item.icon}\" style=${item.icon_color ? `color: ${item.icon_color}` : ''}></ha-icon>\n    </span>\n  `;\n\n  allItems.push(...prepareWeatherPresent(data, language), ...prepareAirQuality(data, language));\n\n  const rows = [];\n  for (let i = 0; i < allItems.length; i += 2) {\n    const left = allItems[i];\n    const right = allItems[i + 1];\n\n    if ((left && left.value) || (right && right.value)) {\n      rows.push(html`\n        <div class=\"present-row\">\n          <div class=\"present-left\">${left ? buildBlockLeft(left) : html``}</div>\n          <div class=\"present-right\">${right ? buildBlockRight(right) : html``}</div>\n        </div>\n      `);\n    }\n  }\n\n  return rows.length > 0 ? html`\n    <div class=\"present-grid-container\">\n      ${rows}\n    </div>\n  ` : html``;\n};\n"
  },
  {
    "path": "src/templates/t-summary.ts",
    "content": "import { html, nothing } from 'lit';\n\nexport interface WeatherSummaryInterface {\n  title?: string;\n  moonText?: string | undefined;\n  moonIcon?: string;\n  conditionText: string;\n  conditionIcon: string;\n  temperature?: string;\n  temperatureUnit?: string;\n  feelsLikeTerm?: string;\n  temperatureFeelsLike?: string;\n  temperatureFeelsLikeIcon?: string;\n}\n\nconst renderLightningFlashZigzag = (xPercent: number, yPercent: number, segments: number = 7) => {\n  const width = 10; // larghezza in pixel della viewport SVG\n  const height = 20 + Math.random() * 50;\n\n  const points = [];\n  let x = width / 2;\n  let y = 0;\n\n  for (let i = 0; i < segments; i += 1) {\n    // x += (Math.random() * width - width / 2);\n    // y += height / segments;\n    x += (Math.random() * width * 1.5 - width * 0.75); // maggiore zigzag\n    y += (height / segments) * (0.7 + Math.random() * 0.6); // lunghezza variabile\n    points.push(`${x},${y}`);\n  }\n\n  const pathD = `M${width / 2},0 ${points.map((p) => `L${p}`).join(' ')}`;\n\n  const delay = Math.random() * 15.5;\n  const duration = 0.2 + Math.random() * 0.3 * 33;\n\n  return html`\n    <svg\n      class=\"lightning-svg\"\n      style=\"\n        top: ${yPercent}%;\n        left: ${xPercent}%;\n        animation-delay: ${delay}s;\n        animation-duration: ${duration}s;\n      \"\n      width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\">\n      <path d=\"${pathD}\" stroke=\"white\" stroke-width=\"1.5\" fill=\"none\" />\n    </svg>\n  `;\n};\n\nconst renderLightningFlashes = (azimuth: number, distance: number, strikes: number) => {\n  const flashes = [];\n  for (let i = 0; i < strikes; i += 1) {\n    const x = Math.random() * 100;\n    const y = Math.random() * 20;\n    flashes.push(renderLightningFlashZigzag(x, y));\n  }\n  return flashes;\n};\n\nconst renderWeatherSummary = ({\n  title,\n  moonText,\n  moonIcon,\n  conditionText,\n  conditionIcon,\n  temperature,\n  temperatureUnit,\n  feelsLikeTerm,\n  temperatureFeelsLike,\n  temperatureFeelsLikeIcon,\n}: WeatherSummaryInterface) => {\n  const lightningAzimuth = 0; // Replace with actual data\n  const lightningDistanceKm = 0; // Replace with actual data\n  const lightningStrikes = 0; // Replace with actual data\n\n  const showLightning =\n  lightningStrikes > 0 &&\n  typeof lightningAzimuth === 'number' &&\n  typeof lightningDistanceKm === 'number';\n\n  if (conditionIcon || moonText || temperature) {\n    return html`\n    <div class=\"summary-wrapper\">\n      ${showLightning ? html`\n        <div class=\"lightning-background\">\n          ${renderLightningFlashes(lightningAzimuth!, lightningDistanceKm!, lightningStrikes)}\n        </div>\n      ` : nothing}\n      <div class=\"summary-grid-container\">\n        ${conditionIcon ? html`\n          <div class=\"summary-col-left\">\n            <img class=\"weather-condition-icon\" src=\"${conditionIcon}\" alt=\"${conditionText}\" />\n          </div>\n        ` : nothing}\n        ${title ? html`\n          <div class=\"summary-top-right\">\n            <span class=\"weather-city-name\">${title}</span>\n          </div>    \n        ` : nothing}\n        ${moonText ? html`\n          <div class=\"summary-bottom-right-left\">\n            <div class=\"moon-row\">\n              <span class=\"summary-moon-icon\">${moonIcon}</span>\n              <span class=\"summary-moon-text\">${moonText}</span>\n            </div>  \n          </div>   \n        ` : nothing}\n        ${temperature ? html`\n          <div class=\"summary-bottom-right-right\">\n            <div class=\"temperature-block\">\n              <div>\n                <span class=\"temperature\">${temperature}</span>\n                <span class=\"temp-unit\">${temperatureUnit}</span>\n              </div>\n              ${temperatureFeelsLike && html`<div class=\"feels-like\">${feelsLikeTerm} <div>${temperatureFeelsLike} ${temperatureUnit}</div></div>`}\n            </div>  \n          </div>\n          ` : nothing}\n      </div>\n    </div>\n    `;\n  }\n\n  return html``;\n};\n\nexport default renderWeatherSummary;\n"
  },
  {
    "path": "src/templates/t-ultraviolet.ts",
    "content": "import { html } from 'lit';\n\nexport interface RenderDataItem {\n  value?: number | string | Date;\n  unit?: string;\n  icon?: string;\n}\nexport interface RenderData {\n  protectionWindow?: RenderDataItem,\n  currentUVLevel?: RenderDataItem,\n  currentUVIndex?: RenderDataItem,\n  maxUVIndex?: RenderDataItem,\n  currentOzoneLevel?: RenderDataItem,\n}\n\nexport interface RenderSkinData {\n  skinType1: RenderDataItem,\n  skinType2: RenderDataItem,\n  skinType3: RenderDataItem,\n  skinType4: RenderDataItem,\n  skinType5: RenderDataItem,\n  skinType6: RenderDataItem,\n}\n\nconst num = ['I', 'II', 'III', 'IV', 'V', 'VI'];\nconst colors = ['#F1D1B1', '#E4B590', '#CF9F7D', '#B67851', '#A15E2D', '#513938'];\n\nconst getTextColor = (hex: string): string => {\n  const c = hex.replace('#', '');\n  const r = parseInt(c.substr(0, 2), 16);\n  const g = parseInt(c.substr(2, 2), 16);\n  const b = parseInt(c.substr(4, 2), 16);\n  const brightness = (r * 299 + g * 587 + b * 114) / 1000;\n  return brightness > 125 ? '#000' : '#fff';\n};\n\nconst renderUltraviolet = (data: RenderData, skinData: RenderSkinData) => {\n  const allItems: RenderDataItem[] = [];\n\n  const buildBlockLeft = (item: RenderDataItem) => html`\n    <span class=\"ultraviolet-value-block\">\n      <ha-icon icon=\"${item.icon}\" style=\"${item.value === 'on' ? 'color: red;' : ''}\"></ha-icon>\n      ${item.value}${item.unit ? html`<span class=\"ultraviolet-unit\">${item.unit}</span>` : ''}\n    </span>\n  `;\n\n  const buildBlockRight = (item: RenderDataItem) => html`\n    <span class=\"ultraviolet-value-block\">\n      ${item.value}${item.unit ? html`<span class=\"ultraviolet-unit\">${item.unit}</span>` : ''}\n      <ha-icon icon=\"${item.icon}\" style=\"${item.value === 'on' ? 'color: red;' : ''}\"></ha-icon>\n    </span>\n  `;\n  \n  const addIfValid = (key: keyof RenderData, item?: RenderDataItem) => {\n    if (item?.value === undefined) return;\n\n    allItems.push(item);\n  };\n\n  let keys: (keyof RenderData)[] = [\n    'protectionWindow',\n    'currentUVLevel',\n  ];\n  keys.forEach((k) => addIfValid(k, data[k]));\n\n  // UV Level current/max combinata\n  if (\n    data.currentUVIndex?.value !== undefined &&\n    data.maxUVIndex?.value !== undefined\n  ) {\n    allItems.push({\n      icon: data.currentUVIndex.icon || data.maxUVIndex.icon || 'mdi:weather-sunny',\n      value: `${data.currentUVIndex.value} / ${data.maxUVIndex.value}`,\n      unit: data.currentUVIndex.unit || data.maxUVIndex.unit,\n    });\n  }\n\n  keys = [\n    'currentOzoneLevel',\n  ];\n  keys.forEach((k) => addIfValid(k, data[k]));\n\n  const summaryRows = [];\n  for (let i = 0; i < allItems.length; i += 2) {\n    const left = allItems[i];\n    const right = allItems[i + 1];\n    summaryRows.push(html`\n      <div class=\"ultraviolet-row\">\n        <div class=\"ultraviolet-left\">${left ? buildBlockLeft(left) : html``}</div>\n        <div class=\"ultraviolet-right\">${right ? buildBlockRight(right) : html``}</div>\n      </div>\n    `);\n  }\n\n  const skinTypes = [\n    skinData.skinType1,\n    skinData.skinType2,\n    skinData.skinType3,\n    skinData.skinType4,\n    skinData.skinType5,\n    skinData.skinType6,\n  ];\n\n  const renderSkinGrid = html`\n  <div class=\"ultraviolet-skin-type-grid\">\n  ${skinTypes.map((item, i) => {\n    const bgColor = colors[i];\n    const textColor = getTextColor(bgColor);\n    return html`\n      <div\n        class=\"ultraviolet-skin-type-cell\"\n        style=\"background: ${bgColor};\"\n        title=\"Fototipo ${num[i]}\"\n      >\n        <div class=\"ultraviolet-skin-type-label\">${num[i]}</div>\n        <div class=\"ultraviolet-exposure-time\" style=\"color: ${textColor};\">${item.value || '--'}</div>\n      </div>\n    `;\n  })}\n  </div>\n  `;\n\n  return html`\n    <div class=\"ultraviolet-grid-container\">\n      ${summaryRows}\n      ${renderSkinGrid}\n    </div>\n  `;\n};\n\nexport default renderUltraviolet;\n"
  },
  {
    "path": "src/templates/t-weather-forecast.ts",
    "content": "/* eslint-disable max-len */\n/* eslint-disable camelcase */\nimport { html } from 'lit';\n\nexport interface iForecastDataItem {\n  value?: number | string | Date;\n  unit?: string;\n  img?: string;\n  icon?: string;\n  iconColor?: string;\n}\n\nexport const renderWeatherForecast = (forecastType: number, data: Record<string, iForecastDataItem>[]) => {\n  const rows = data.map((dayData) => {\n    const day = dayData.reference?.value;\n    const img = dayData.condition?.img;\n    const icon = dayData.condition?.icon;\n    const iconColor = dayData.condition?.iconColor;\n    const tempLow = dayData.temperature_low?.value;\n    const tempHigh = dayData.temperature_high?.value;\n    const tempHLUnit = dayData.temperature_high?.unit || dayData.temperature_low?.unit;\n    const precipProb: number = Number(dayData.precipitation_probability?.value ?? 0);\n    const precipInt = dayData.precipitation_intensity?.value;\n    const precipUnit = dayData.precipitation_intensity?.unit;\n\n    const temp = dayData.temperature?.value;\n    const tempUnit = dayData.temperature?.unit || dayData.temperature_feelslike?.unit;\n    const temp_feelslike = dayData.temperature_feelslike?.value;\n    const wind_speed = dayData.wind_speed?.value;\n    const wind_speedUnit = dayData.wind_speed?.unit;\n    const wind_bearing = dayData.wind_bearing?.value;\n\n    const wind_wave_height_max = dayData.wind_wave_height_max?.value;\n    const swell_wave_height_max = dayData.swell_wave_height_max?.value;\n    const wave_height_max = dayData.wave_height_max?.value;\n    const wave_direction = dayData.wave_direction?.value;\n    const wave_direction_degrees = dayData.wave_direction?.icon;\n    const wave_height_max_unit = dayData.wave_height_max?.unit;\n\n    return html`\n      <div class=\"weather-forecast-slot\">\n        ${day ? html`<div class=\"weather-forecast-label-slot\">${day}</div>` : ''}\n        ${img ? html`<img class=\"weather-forecast-icon\" src=\"${img}\" alt=\"${img}\" />` : ''}\n        ${icon ? html`<ha-icon icon=\"${icon}\" style=${iconColor ? `color: ${iconColor}` : ''}></ha-icon>` : ''}\n        ${\n  tempLow !== undefined && tempHigh !== undefined\n    ? html`\n                <div class=\"weather-forecast-temperature\">\n                  ${tempLow} / <span class=\"high\">${tempHigh}${tempHLUnit ? ` ${tempHLUnit}` : ''}</span>\n                </div>\n              `\n    : ''\n}\n        ${\n  temp !== undefined && temp_feelslike !== undefined\n    ? html`\n                <div class=\"weather-forecast-temperature\">\n                  ${temp} / <span class=\"high\">${temp_feelslike}${tempUnit ? ` ${tempUnit}` : ''}</span>\n                </div>\n              `\n    : ''\n}\n        ${\n  wind_speed !== undefined && wind_bearing !== undefined\n    ? html`\n                <div class=\"weather-forecast-temperature\">\n                  ${wind_speed} ${wind_speedUnit} ${wind_bearing}</span>\n                </div>\n              `\n    : ''\n}\n        ${\n  wave_height_max !== undefined\n    ? html`\n                <div class=\"weather-forecast-temperature\">\n                  ${wave_height_max} ${wave_height_max_unit ? ` ${wave_height_max_unit}` : ''}\n                </div>\n              `\n    : ''\n}\n        ${\n  wave_direction !== undefined\n    ? html`\n                <div class=\"weather-forecast-temperature\">\n                  ${wave_direction_degrees ? html`<ha-icon\n                        icon=\"mdi:arrow-up-thin\"\n                        style=\"display:inline-block; transform: rotate(${wave_direction_degrees}deg);\"\n                      ></ha-icon>` : ''} ${wave_direction}\n                </div>\n              `\n    : ''\n}\n        ${\n  wind_wave_height_max !== undefined && swell_wave_height_max !== undefined\n    ? html`\n                <div class=\"weather-forecast-temperature\">\n                  ${swell_wave_height_max} / ${wind_wave_height_max} ${wave_height_max_unit ? ` ${wave_height_max_unit}` : ''}\n                </div>\n              `\n    : ''\n}\n        ${\n  precipProb !== undefined && precipInt !== undefined && precipProb !== 0\n    ? html`\n                <div class=\"weather-forecast-precipitation\">\n                  ${precipProb} % / <span class=\"mm\">${precipInt}${precipUnit ? ` ${precipUnit}` : ''}</span>\n                </div>\n              `\n    : ''\n}\n      </div>\n    `;\n  });\n\n  let title = 'Daily';\n  if (forecastType === 1) {\n    title = 'Hourly';\n  } else if (forecastType === 2) {\n    title = 'Marine daily';\n  } else if (forecastType === 3) {\n    title = 'Marine hourly';\n  }\n\n  return html`\n  <div class=\"weather-forecast-grid-wrapper\">\n    <div class=\"weather-forecast-title\">${title} forecast</div>\n    <div class=\"weather-forecast-grid-container\">\n      ${rows}\n    </div>\n  </div>\n  `;\n};\n"
  },
  {
    "path": "src/utils/colors.ts",
    "content": "import { css } from 'lit';\nimport * as Color from 'color';\n\nexport const COLORS = [\n  'primary',\n  'accent',\n  'red',\n  'pink',\n  'purple',\n  'deep-purple',\n  'indigo',\n  'blue',\n  'light-blue',\n  'cyan',\n  'teal',\n  'green',\n  'light-green',\n  'lime',\n  'yellow',\n  'amber',\n  'orange',\n  'deep-orange',\n  'brown',\n  'light-grey',\n  'grey',\n  'dark-grey',\n  'blue-grey',\n  'black',\n  'white',\n  'disabled',\n];\n\nexport function computeRgbColor(color: string): string {\n  if (color === 'primary' || color === 'accent') {\n    return `var(--rgb-${color}-color)`;\n  }\n  if (COLORS.includes(color)) {\n    return `var(--rgb-${color})`;\n  // eslint-disable-next-line no-else-return\n  } else if (color.startsWith('#')) {\n    try {\n      return Color.rgb(color).rgb().array().join(', ');\n    } catch (err) {\n      return '';\n    }\n  }\n  return color;\n}\n\nfunction capitalizeFirstLetter(string) {\n  return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nexport function computeColorName(color: string): string {\n  return color\n    .split('-')\n    .map((s) => capitalizeFirstLetter(s))\n    .join(' ');\n}\n\nexport const defaultColorCss = css`\n  --default-red: 244, 67, 54;\n  --default-pink: 233, 30, 99;\n  --default-purple: 146, 107, 199;\n  --default-deep-purple: 110, 65, 171;\n  --default-indigo: 63, 81, 181;\n  --default-blue: 33, 150, 243;\n  --default-light-blue: 3, 169, 244;\n  --default-cyan: 0, 188, 212;\n  --default-teal: 0, 150, 136;\n  --default-green: 76, 175, 80;\n  --default-light-green: 139, 195, 74;\n  --default-lime: 205, 220, 57;\n  --default-yellow: 255, 235, 59;\n  --default-amber: 255, 193, 7;\n  --default-orange: 255, 152, 0;\n  --default-deep-orange: 255, 111, 34;\n  --default-brown: 121, 85, 72;\n  --default-light-grey: 189, 189, 189;\n  --default-grey: 158, 158, 158;\n  --default-dark-grey: 96, 96, 96;\n  --default-blue-grey: 96, 125, 139;\n  --default-black: 0, 0, 0;\n  --default-white: 255, 255, 255;\n  --default-disabled: 189, 189, 189;\n`;\n\nexport const defaultDarkColorCss = css`\n  --default-disabled: 111, 111, 111;\n`;\n"
  },
  {
    "path": "src/utils/config-schema.ts",
    "content": "export interface iLovelaceCardConfig {\n  index?: number; // Indice della card all'interno della vista (opzionale).\n  view_index?: number; // Indice della vista in cui si trova la card (opzionale).\n  view_layout?: unknown; // Informazioni di layout (griglia, posizione, ecc.) per l'editor UI.\n  type: string; // Obbligatorio. Indica il tipo di card\n  [key: string]: unknown; // Permette di aggiungere parametri arbitrari, cioè supporta proprietà dinamiche definite dall’utente.\n}\n\nexport interface iPresentData {\n  // sun?: string;\n  // moonphase?: string;\n  condition?: string;\n  temperature?: string;\n  temperature_feelslike?: string;\n\n  temperature_min?: string;\n  temperature_max?: string;\n\n  humidity?: string;\n  pressure?: string;\n  visibility?: string;\n  wind_bearing?: string;\n  wind_speed?: string;\n  precipitation_intensity?: string;\n  precipitation_probability?: string;\n}\n\nexport interface iTimeSlots {\n  slot1: string;\n  slot2: string;\n  slot3: string;\n  slot4: string;\n  slot5: string;\n  slot6: string;\n}\n\nexport interface iDailyForecast {\n  condition?: iTimeSlots;\n  temperature_high?: iTimeSlots;\n  temperature_low?: iTimeSlots;\n  precipitation_intensity?: iTimeSlots;\n  precipitation_probability?: iTimeSlots;\n\n  meteogram?: string ;\n}\n\nexport interface iHourlyForecast {\n  condition?: iTimeSlots;\n  temperature?: iTimeSlots;\n  temperature_feelslike?: iTimeSlots;\n  precipitation_intensity?: iTimeSlots;\n  precipitation_probability?: iTimeSlots;\n  wind_bearing?: iTimeSlots;\n  wind_speed?: iTimeSlots;\n}\n\nexport interface iMarineHourlyForecast {\n  swell_direction?: iTimeSlots ;\n  swell_height?: iTimeSlots ;\n  swell_period?: iTimeSlots ;\n  wind_direction: iTimeSlots ;\n  wind_speed: iTimeSlots ;\n  air_temperature: iTimeSlots ;\n  water_temperature: iTimeSlots ;\n}\n\nexport interface iMarineDailyForecast {\n  wave_height_max?: iTimeSlots ;\n  wave_direction?: iTimeSlots ;\n  swell_wave_height_max?: iTimeSlots ;\n  wind_wave_height_max?: iTimeSlots ;\n}\n\nexport interface iDPCAlert {\n  thunderstorms?: string;\n  hydraulic?: string;\n  hydrogeological?: string;\n}\n\nexport interface iWeather {\n  name?: string; // location name, in summary\n  sun?: string;\n  moonphase?: string;\n  icons_model: string;\n  animation?: boolean;\n  present?: iPresentData ;\n  daily_forecasts?: iDailyForecast;\n  hourly_forecasts?: iHourlyForecast;\n  marine_daily_forecasts?: iMarineDailyForecast;\n  marine_hourly_forecasts?: iMarineHourlyForecast;\n  meteoalarm?: string; // Meteoalarm alert\n  dpcalarm?: iDPCAlert; // DPC alert\n}\n\nexport interface iUltraviolet {\n  protection_window?: string ;\n  ozone_level?: string ;\n  uv_index?: string ;\n  uv_level?: string ;\n  max_uv_index?: string ;\n  set_skin_type_1?: string ;\n  set_skin_type_2?: string ;\n  set_skin_type_3?: string ;\n  set_skin_type_4?: string ;\n  set_skin_type_5?: string ;\n  set_skin_type_6?: string ;\n}\n\nexport interface iPollenItem {\n  name: string;\n  entity: string;\n}\n\nexport interface iPollen {\n  entities: iPollenItem[];\n  min: number;\n  max: number;\n}\n\nexport interface iAirQuality {\n  pm25?: string ;\n  pm10?: string ;\n  o3?: string ;\n  no2?: string ;\n  co?: string ;\n  so2?: string ;\n  epa_aqi?: string ;\n  epa_primary_pollutant?: string ;\n  epa_health_concern?: string ;\n}\n\nexport interface iCardConfig {\n  type: string; // ha-card-weather-conditions\n  language?: string ; // Card language\n\n  weather: iWeather;\n  ultraviolet?: iUltraviolet;\n\n  pollen?: iPollen;\n  airquality?: iAirQuality ;\n\n  camera?: string;\n\n  // display: string[]\n\n  // alert: Alert ;\n  // sea: Sea ;\n}\n"
  },
  {
    "path": "src/utils/const.ts",
    "content": "export const logo: string = '%c WEATHER-CONDITION-CARD %c 2.0.0';\n\nexport const hacsImagePath: string = '/local/community/ha-card-weather-conditions/icons';\nexport const manImagePath: string = '/local/ha-card-weather-conditions/icons';\n\nexport const optConsoleParam1: string = 'color: white; background: green; font-weight: 700;';\nexport const optConsoleParam2: string = 'color: green; background: white; font-weight: 700;';\nexport const optConsoleParam3: string = 'color: black; background: white; font-weight: 700;';\n\nexport const iconTemperature: string = 'mdi:thermometer';\nexport const iconPrecipitation: string = 'mdi:weather-rainy';\n\nexport const cwcLocale = {\n  en: 0,\n  it: 1,\n  nl: 2,\n  es: 3,\n  de: 4,\n  fr: 5,\n  'sr-latn': 6,\n  pt: 7,\n  da: 8,\n  'no-no': 9,\n  cs: 10,\n  ru: 11,\n};\n\n// 🌑 🌒 🌓 🌔 🌕 🌖 🌗 🌘 🌑\nexport const cwcMoonPhaseIcons = {\n  new_moon: '🌑',\n  new: '🌑',\n  waxing_crescent: '🌒',\n  first_quarter: '🌓',\n  waxing_gibbous: '🌔',\n  full: '🌕',\n  full_moon: '🌕',\n  waning_gibbous: '🌖',\n  third_quarter: '🌗',\n  last_quarter: '🌗',\n  waning_crescent: '🌘',\n};\n"
  },
  {
    "path": "src/utils/helper-render.ts",
    "content": "import { css } from 'lit';\n// import { HomeAssistant } from 'custom-card-helpers/dist';\n\nimport { cwcMoonPhaseIcons } from '../../backup/ha-cwc-consts';\n\nimport cardStyle from '../css/css-base-card';\nimport summaryStyles from '../css/css-summary';\nimport presentStyle from '../css/css-present';\nimport ultravioletStyle from '../css/css-ultraviolet';\nimport pollenStyle from '../css/css-pollen';\nimport cameraStyle from '../css/css-camera';\nimport { iIconsConfig } from '../base/lovelace-base';\nimport weatherForecastStyle from '../css/css-weather-forecast';\nimport meteodcpalarmStyle from '../css/css-meteoalarm';\n\nexport const getMoonIcon = (phase: string): string => cwcMoonPhaseIcons[phase.toLowerCase()];\n\nexport const getWeatherIcon = (\n  condition: string,\n  iconsConfig: iIconsConfig,\n  sunState: string,\n): string => {\n  const isNight = sunState === 'below_horizon';\n  const iconMap = isNight ? iconsConfig.iconsNight : iconsConfig.iconsDay;\n  const iconName = iconMap[condition];\n\n  if (!iconsConfig.path) {\n    console.info('Image path not found.');\n  }\n\n  if (!iconName) {\n    console.info(\n      `Icons issue. Model=${iconsConfig.icons_model}, Time=${isNight ? 'night' : 'day'}, Condition=${condition}`,\n    );\n    return '';\n  }\n\n  return `${iconsConfig.path}/${iconsConfig.iconType}/${iconName}.svg`;\n};\n\n// export const getSensorUnit = (hass: HomeAssistant, measure: string): string => {\n//   const lengthUnit = hass.config.unit_system.length;\n\n//   const unitOverrides: Record<string, string> = {\n//     air_pressure: lengthUnit === 'km' ? 'hPa' : 'inHg',\n//     precipitation: lengthUnit === 'km' ? 'mm' : 'in',\n//     length: lengthUnit,\n//   };\n\n//   if (measure in unitOverrides) {\n//     return unitOverrides[measure];\n//   }\n\n//   const unit = (hass.config.unit_system as Record<string, string>)[measure];\n\n//   if (unit !== undefined) {\n//     return unit;\n//   }\n\n//   console.warn(`Unit for '${measure}' not found in hass.config.unit_system.`);\n//   return '';\n// };\n\nexport const getCardStyles = () => css`\n${cardStyle}\n${summaryStyles}\n${presentStyle}\n${weatherForecastStyle}\n${ultravioletStyle}\n${pollenStyle}\n${cameraStyle}\n${meteodcpalarmStyle}\n`;\n"
  },
  {
    "path": "src/utils/helper.ts",
    "content": "/* eslint-disable camelcase */\nimport { HomeAssistant } from 'custom-card-helpers/dist';\nimport { iconsModels } from '../../backup/types';\n\nexport interface IconsConfigResult {\n  iconsModel: string;\n  iconsDay: Record<string, string>;\n  iconsNight: Record<string, string>;\n}\n\n// export const getEntityState = (hass: HomeAssistant, entityId?: string) => (\n//   entityId ? hass.states[entityId]?.state : undefined\n// );\n\n/**\n * Restituisce la traduzione di un termine usando un dizionario, in modo case-insensitive.\n * Se il termine non è trovato, restituisce l'originale.\n */\nexport const translate = (term: string, dictionary: Record<string, string>): string => {\n  const key = Object.keys(dictionary).find((k) => k.toLowerCase() === term.toLowerCase());\n  return key ? dictionary[key] : term;\n};\n\ntype LocaleInfo = {\n  locale: string;\n  timezone: string;\n  cwc?: number;\n};\n\nexport const getLocaleInfo = (lang: string): LocaleInfo => {\n  const localeMap: Record<string, string> = {\n    en: 'en-US',\n    it: 'it-IT',\n    nl: 'nl-NL',\n    es: 'es-ES',\n    de: 'de-DE',\n    fr: 'fr-FR',\n    'sr-latn': 'sr-Latn',\n    pt: 'pt-PT',\n    da: 'da-DK',\n    'no-no': 'nb-NO',\n    cs: 'cs-CZ',\n    ru: 'ru-RU',\n  };\n\n  const timezoneMap: Record<string, string> = {\n    en: 'America/New_York',\n    it: 'Europe/Rome',\n    nl: 'Europe/Amsterdam',\n    es: 'Europe/Madrid',\n    de: 'Europe/Berlin',\n    fr: 'Europe/Paris',\n    'sr-latn': 'Europe/Belgrade',\n    ja: 'Asia/Tokyo',\n    pt: 'Europe/Lisbon',\n    da: 'Europe/Copenhagen',\n    'no-no': 'Europe/Oslo',\n    cs: 'Europe/Prague',\n    ru: 'Europe/Moscow',\n  };\n\n  const cwcLocale: Record<string, number> = {\n    en: 0,\n    it: 1,\n    nl: 2,\n    es: 3,\n    de: 4,\n    fr: 5,\n    'sr-latn': 6,\n    pt: 7,\n    da: 8,\n    'no-no': 9,\n    cs: 10,\n    ru: 11,\n  };\n\n  return {\n    locale: localeMap[lang] || lang,\n    timezone: timezoneMap[lang] || 'UTC',\n    ...(lang in cwcLocale && { cwc: cwcLocale[lang] }),\n  };\n};\n\nexport const getLocale = (lang: string) => {\n  const map = {\n    it: 'it-IT',\n    en: 'en-US',\n    fr: 'fr-FR',\n    de: 'de-DE',\n    es: 'es-ES',\n    ja: 'ja-JP',\n    zh: 'zh-CN',\n    // Aggiungi altri se servono\n  };\n  return map[lang] || `${lang}-${lang.toUpperCase()}`; // fallback generico\n};\n\nexport const getFormatter = (\n  locale: string = 'en-US',\n  fractionDigits: number = 1,\n  useGrouping: boolean = false,\n): Intl.NumberFormat => new Intl.NumberFormat(locale, {\n  minimumFractionDigits: fractionDigits,\n  maximumFractionDigits: fractionDigits,\n  useGrouping,\n});\n\nexport const formatNumber = (\n  {\n    stringNumber,\n    lang = 'en',\n    fractionDigits = 1,\n    useGrouping = false,\n  }: {\n    stringNumber: string;\n    lang?: string;\n    fractionDigits?: number;\n    useGrouping?: boolean;\n  },\n): string => {\n  const number = parseFloat(stringNumber);\n  if (Number.isNaN(number)) return '';\n\n  const effectiveFormatter = getFormatter(getLocale(lang), fractionDigits, useGrouping);\n  // console.debug(`>>>|| ${number} ${effectiveFormatter.format(number)}`);\n  return effectiveFormatter.format(number);\n};\n\nexport const getIconModelData = (iconsModel: string): IconsConfigResult => {\n  const modelName = iconsModel.toLowerCase() ?? 'climacell';\n\n  if (modelName in iconsModels) {\n    const { iconsDay, iconsNight } = iconsModels[modelName];\n    return {\n      iconsModel: modelName,\n      iconsDay,\n      iconsNight,\n    };\n  }\n\n  console.warn(`Unknown icons model: ${modelName}. Falling back to 'climacell'.`);\n\n  const fallback = iconsModels['climacell'];\n  return {\n    iconsModel: 'climacell',\n    iconsDay: fallback.iconsDay,\n    iconsNight: fallback.iconsNight,\n  };\n};\n\nexport function pad(n: number | string, width: number, z = '0'): string {\n  return n.toString().padStart(width, z);\n}\n\n/**\n * Converte una stringa numerica localizzata in un numero.\n * Esempio: '1.234,56' (it-IT) → 1234.56\n * @param input - La stringa o numero da convertire.\n * @param locale - Il locale da utilizzare per determinare i separatori.\n * @returns Il numero convertito o NaN se la conversione fallisce.\n */\nexport const string2Number = (input: string | number, locale: string = 'en-US'): number => {\n  if (typeof input === 'number') return input;\n\n  const formatter = new Intl.NumberFormat(locale);\n  const parts = formatter.formatToParts(1234567.89);\n\n  const group = parts.find((part) => part.type === 'group')?.value || '';\n  const decimal = parts.find((part) => part.type === 'decimal')?.value || '.';\n\n  // Rimuove i separatori delle migliaia e sostituisce il separatore decimale con '.'\n  const normalized = input\n    .replace(new RegExp(`\\\\${group}`, 'g'), '')\n    .replace(new RegExp(`\\\\${decimal}`), '.');\n\n  return Number(normalized);\n};\n\nexport const getEntityRawValue = (hass: HomeAssistant, entityId?: string): string | undefined => (\n  entityId && hass.states[entityId]?.state\n);\n\nexport const getEntityRawAttribute = (hass: HomeAssistant, entityId: string, attribute: string): string | undefined => (\n  entityId && hass.states[entityId]?.attributes[attribute]\n);\n\nexport const getEntityNumericValue = (\n  {\n    entityId,\n    hass,\n    lang = 'en',\n    decimals = 0,\n  }: {\n    entityId?: string;\n    hass?: HomeAssistant;\n    lang?: string;\n    decimals?: number;\n  } = {},\n): string | undefined => {\n  const state = hass && entityId && hass.states[entityId]?.state;\n  return state !== undefined ? formatNumber({ stringNumber: state, fractionDigits: decimals, lang }) : undefined;\n};\n\nexport const getEntityUnit = (hass: HomeAssistant, entityId?: string): string | undefined => (\n  entityId && hass.states[entityId]?.attributes?.unit_of_measurement\n);\n\nexport const getEntityIcon = (hass: HomeAssistant, entityId?: string): string | undefined => (\n  entityId && hass.states[entityId]?.attributes?.icon\n);\n\nexport const getWindDirections = (\n  wd: number | string,\n  cwcLocWindDirections,\n): string | null => {\n  const wdNumber = typeof wd === 'number' ? wd : parseFloat(wd);\n\n  if (Number.isNaN(wdNumber)) {\n    return cwcLocWindDirections[wd] ?? null;\n  }\n\n  if (wdNumber < 0 || wdNumber > 360) {\n    console.error(`Invalid wind direction: '${wd}'. Valid values are between 0 and 360 degrees.`);\n    return null;\n  }\n\n  const directions = [\n    'N', 'NNE', 'NE', 'ENE', 'E', 'ESE',\n    'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW',\n    'W', 'WNW', 'NW', 'NNW',\n  ];\n\n  const index = Math.floor(((wdNumber + 11.25) % 360) / 22.5);\n\n  const dirKey = directions[index];\n\n  return cwcLocWindDirections[dirKey] ?? null;\n};\n\nexport function imageExist(imageSrc: string, timeout = 5000): Promise<boolean> {\n  return new Promise<boolean>((resolve) => {\n    const img = new Image();\n    const timer = setTimeout(() => {\n      img.src = ''; // forza stop\n      resolve(false);\n    }, timeout);\n\n    img.onload = () => {\n      clearTimeout(timer);\n      resolve(true);\n    };\n    img.onerror = () => {\n      clearTimeout(timer);\n      resolve(false);\n    };\n    img.src = imageSrc;\n  });\n}\n\nexport async function loadJSON(full_path_file: string): Promise<string> {\n  try {\n    const response = await fetch(full_path_file);\n    if (!response.ok) {\n      const err = `ERROR retrieving JSON file: '${full_path_file}', status: ${response.status} ${response.statusText}`;\n      console.info(err);\n      throw new Error(err);\n    }\n    console.info(`Locale '${full_path_file}' loaded`);\n    return await response.text();\n  } catch (error) {\n    console.info(`Fetch failed for '${full_path_file}':`, error);\n    throw error;\n  }\n}\n\nexport function logInfo(message: string, ...styles: unknown[]) {\n  console.info(message, ...(styles.length ? styles : []));\n}\n\nexport function parseLocalizedNumber(value: string | number, locale = 'en-US'): number {\n  if (typeof value === 'number') return value;\n\n  // Semplificazione solo per 'it-IT': usa virgola come separatore decimale\n  const normalized = value.replace(/\\./g, '').replace(',', '.');\n  return Number(normalized);\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es2020\",\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"lib\": [\"es2020\", \"dom\", \"dom.iterable\"],\n    \"noEmit\": true,\n    \"noUnusedLocals\": false,\n    \"noUnusedParameters\": false,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"strict\": true,\n    \"noImplicitAny\": false,\n    \"skipLibCheck\": true,\n    \"resolveJsonModule\": true,\n    \"experimentalDecorators\": true,\n    \"strictNullChecks\": false\n  },\n  \n  \"include\": [\"src/**/*.ts\"],\n  \"exclude\": [\"node_modules\"],\n\n  \"scripts\": {\n    \"start\": \"rollup -c --watch\",\n    \"build\": \"npm run lint && npm run rollup\",\n    \"lint\": \"eslint src/*.ts\",\n    \"rollup\": \"rollup -c\"\n  }\n}"
  }
]