Using CQL with FHIR
1.0.0-ballot - Ballot International flag

This page is part of the Using CQL with FHIR Implementation Guide (v1.0.0-ballot: STU1 Ballot 1) based on FHIR (HL7® FHIR® Standard) R4. . For a full list of available versions, see the Directory of published versions

: FHIR Common (Source CQL Example) - JSON Representation

Active as of 2022-11-16

Raw json | Download


{
  "resourceType" : "Library",
  "id" : "CQLExample",
  "meta" : {
    "profile" : [
      🔗 "http://hl7.org/fhir/uv/cql/StructureDefinition/cql-library"
    ]
  },
  "language" : "en",
  "text" : {
    "status" : "generated",
    "div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\"><h2>Contents</h2><p><code>text/cql</code></p><pre><code class=\"language-sql\">library FHIRCommon version '4.1.000'\r\n\r\nusing FHIR version '4.0.1'\r\n\r\ninclude FHIRHelpers version '4.1.000'\r\n\r\n\r\ncodesystem &quot;LOINC&quot;: 'http://loinc.org'\r\ncodesystem &quot;SNOMEDCT&quot;: 'http://snomed.info/sct'\r\ncodesystem &quot;RoleCode&quot;: 'http://terminology.hl7.org/CodeSystem/v3-RoleCode'\r\ncodesystem &quot;Diagnosis Role&quot;: 'http://terminology.hl7.org/CodeSystem/diagnosis-role'\r\ncodesystem &quot;RequestIntent&quot;: 'http://terminology.hl7.org/CodeSystem/request-intent'\r\ncodesystem &quot;MedicationRequestCategory&quot;: 'http://terminology.hl7.org/CodeSystem/medicationrequest-category'\r\ncodesystem &quot;ConditionClinicalStatusCodes&quot;: 'http://terminology.hl7.org/CodeSystem/condition-clinical'\r\ncodesystem &quot;ConditionVerificationStatusCodes&quot;: 'http://terminology.hl7.org/CodeSystem/condition-ver-status'\r\ncodesystem &quot;AllergyIntoleranceClinicalStatusCodes&quot;: 'http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical'\r\ncodesystem &quot;AllergyIntoleranceVerificationStatusCodes&quot;: 'http://terminology.hl7.org/CodeSystem/allergyintolerance-verification'\r\n\r\n//Currently unresolveable in VSAC:\r\n//valueset &quot;Active Condition&quot;: 'http://fhir.org/guides/cqf/common/ValueSet/active-condition'\r\n//valueset &quot;Inactive Condition&quot;: 'http://fhir.org/guides/cqf/common/ValueSet/inactive-condition'\r\n\r\ncode &quot;Birthdate&quot;: '21112-8' from &quot;LOINC&quot; display 'Birth date'\r\ncode &quot;Dead&quot;: '419099009' from &quot;SNOMEDCT&quot; display 'Dead'\r\ncode &quot;ER&quot;: 'ER' from &quot;RoleCode&quot; display 'Emergency room'\r\ncode &quot;ICU&quot;: 'ICU' from &quot;RoleCode&quot; display 'Intensive care unit'\r\ncode &quot;Billing&quot;: 'billing' from &quot;Diagnosis Role&quot; display 'Billing'\r\n\r\n// Condition Clinical Status Codes - Consider value sets for these\r\ncode &quot;active&quot;: 'active' from &quot;ConditionClinicalStatusCodes&quot;\r\ncode &quot;recurrence&quot;: 'recurrence' from &quot;ConditionClinicalStatusCodes&quot;\r\ncode &quot;relapse&quot;: 'relapse' from &quot;ConditionClinicalStatusCodes&quot;\r\ncode &quot;inactive&quot;: 'inactive' from &quot;ConditionClinicalStatusCodes&quot;\r\ncode &quot;remission&quot;: 'remission' from &quot;ConditionClinicalStatusCodes&quot;\r\ncode &quot;resolved&quot;: 'resolved' from &quot;ConditionClinicalStatusCodes&quot;\r\n\r\n// Condition Verification Status Codes - Consider value sets for these\r\ncode &quot;unconfirmed&quot;: 'unconfirmed' from ConditionVerificationStatusCodes\r\ncode &quot;provisional&quot;: 'provisional' from ConditionVerificationStatusCodes\r\ncode &quot;differential&quot;: 'differential' from ConditionVerificationStatusCodes\r\ncode &quot;confirmed&quot;: 'confirmed' from ConditionVerificationStatusCodes\r\ncode &quot;refuted&quot;: 'refuted' from ConditionVerificationStatusCodes\r\ncode &quot;entered-in-error&quot;: 'entered-in-error' from ConditionVerificationStatusCodes\r\n\r\ncode &quot;allergy-active&quot;: 'active' from &quot;AllergyIntoleranceClinicalStatusCodes&quot;\r\ncode &quot;allergy-inactive&quot;: 'inactive' from &quot;AllergyIntoleranceClinicalStatusCodes&quot;\r\ncode &quot;allergy-resolved&quot;: 'resolved' from &quot;AllergyIntoleranceClinicalStatusCodes&quot;\r\n\r\n// Allergy/Intolerance Verification Status Codes - Consider value sets for these\r\ncode &quot;allergy-unconfirmed&quot;: 'unconfirmed' from AllergyIntoleranceVerificationStatusCodes\r\ncode &quot;allergy-confirmed&quot;: 'confirmed' from AllergyIntoleranceVerificationStatusCodes\r\ncode &quot;allergy-refuted&quot;: 'refuted' from AllergyIntoleranceVerificationStatusCodes\r\n\r\n// MedicationRequest Category Codes\r\ncode &quot;Community&quot;: 'community' from &quot;MedicationRequestCategory&quot; display 'Community'\r\ncode &quot;Discharge&quot;: 'discharge' from &quot;MedicationRequestCategory&quot; display 'Discharge'\r\n\r\n// Diagnosis Role Codes\r\ncode &quot;AD&quot;: 'AD' from &quot;Diagnosis Role&quot; display 'Admission diagnosis'\r\ncode &quot;DD&quot;: 'DD' from &quot;Diagnosis Role&quot; display 'Discharge diagnosis'\r\ncode &quot;CC&quot;: 'CC' from &quot;Diagnosis Role&quot; display 'Chief complaint'\r\ncode &quot;CM&quot;: 'CM' from &quot;Diagnosis Role&quot; display 'Comorbidity diagnosis'\r\ncode &quot;pre-op&quot;: 'pre-op' from &quot;Diagnosis Role&quot; display 'pre-op diagnosis'\r\ncode &quot;post-op&quot;: 'post-op' from &quot;Diagnosis Role&quot; display 'post-op diagnosis'\r\ncode &quot;billing&quot;: 'billing' from &quot;Diagnosis Role&quot; display 'billing diagnosis'\r\n\r\ncontext Patient\r\n\r\n/*\r\n@description: Normalizes a value that is a choice of timing-valued types to an equivalent interval\r\n@comment: Normalizes a choice type of FHIR.dateTime, FHIR.Period, FHIR.Timing, FHIR.instance, FHIR.string, FHIR.Age, or FHIR.Range types\r\nto an equivalent interval. This selection of choice types is a superset of the majority of choice types that are used as possible\r\nrepresentations for timing-valued elements in FHIR, allowing this function to be used across any resource. NOTE: Due to the\r\ncomplexity of determining a single interval from a Timing or String type, this function will throw a run-time exception if it is used\r\nwith a Timing or String.\r\n*/\r\ndefine function ToInterval(choice Choice&lt;FHIR.dateTime, FHIR.Period, FHIR.Timing, FHIR.instant, FHIR.string, FHIR.Age, FHIR.Range&gt;):\r\n  case\r\n\t  when choice is FHIR.dateTime then\r\n    \tInterval[FHIRHelpers.ToDateTime(choice as FHIR.dateTime), FHIRHelpers.ToDateTime(choice as FHIR.dateTime)]\r\n\t\twhen choice is FHIR.Period then\r\n  \t\tFHIRHelpers.ToInterval(choice as FHIR.Period)\r\n\t\twhen choice is FHIR.instant then\r\n\t\t\tInterval[FHIRHelpers.ToDateTime(choice as FHIR.instant), FHIRHelpers.ToDateTime(choice as FHIR.instant)]\r\n\t\twhen choice is FHIR.Age then\r\n\t\t  Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(choice as FHIR.Age),\r\n\t\t\t  FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(choice as FHIR.Age) + 1 year)\r\n\t\twhen choice is FHIR.Range then\r\n\t\t  Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((choice as FHIR.Range).low),\r\n\t\t\t  FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((choice as FHIR.Range).high) + 1 year)\r\n\t\twhen choice is FHIR.Timing then\r\n\t\t  Message(null as Interval&lt;DateTime&gt;, true, '1', 'Error', 'Cannot compute a single interval from a Timing type')\r\n    when choice is FHIR.string then\r\n      Message(null as Interval&lt;DateTime&gt;, true, '1', 'Error', 'Cannot compute an interval from a String value')\r\n\t\telse\r\n\t\t\tnull as Interval&lt;DateTime&gt;\r\n\tend\r\n\r\n/*\r\n@description: Returns an interval representing the normalized Abatement of a given Condition resource.\r\n@comment: NOTE: Due to the complexity of determining an interval from a String, this function will throw\r\na run-time exception if used with a Condition instance that has a String as the abatement value.\r\n*/\r\ndefine function ToAbatementInterval(condition Condition):\r\n\tif condition.abatement is FHIR.dateTime then\r\n\t  Interval[FHIRHelpers.ToDateTime(condition.abatement as FHIR.dateTime), FHIRHelpers.ToDateTime(condition.abatement as FHIR.dateTime)]\r\n\telse if condition.abatement is FHIR.Period then\r\n\t  FHIRHelpers.ToInterval(condition.abatement as FHIR.Period)\r\n\telse if condition.abatement is FHIR.string then\r\n    Message(null as Interval&lt;DateTime&gt;, true, '1', 'Error', 'Cannot compute an interval from a String value')\r\n\telse if condition.abatement is FHIR.Age then\r\n\t\tInterval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(condition.abatement as FHIR.Age),\r\n\t\t\tFHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(condition.abatement as FHIR.Age) + 1 year)\r\n\telse if condition.abatement is FHIR.Range then\r\n\t  Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((condition.abatement as FHIR.Range).low),\r\n\t\t  FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((condition.abatement as FHIR.Range).high) + 1 year)\r\n\telse if condition.abatement is FHIR.boolean then\r\n\t  Interval[end of ToInterval(condition.onset), condition.recordedDate)\r\n\telse null\r\n\r\n/*\r\n@description: Returns an interval representing the normalized prevalence period of a given Condition resource.\r\n@comment: Uses the ToInterval and ToAbatementInterval functions to determine the widest potential interval from\r\nonset to abatement as specified in the given Condition.\r\n*/\r\ndefine function ToPrevalenceInterval(condition Condition):\r\nif condition.clinicalStatus ~ &quot;active&quot;\r\n  or condition.clinicalStatus ~ &quot;recurrence&quot;\r\n  or condition.clinicalStatus ~ &quot;relapse&quot; then\r\n  Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)]\r\nelse\r\n  Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition))\r\n\r\n/*\r\n@description: Returns any extensions defined on the given resource with the specified url.\r\n@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access\r\ncontent that is defined by extensions but not yet surfaced in the\r\nCQL model info.\r\n*/\r\ndefine function Extensions(domainResource DomainResource, url String):\r\n  domainResource.extension E\r\n\t  where E.url = url\r\n\t\treturn E\r\n\r\n/*\r\n@description: Returns the single extension (if present) on the given resource with the specified url.\r\n@comment: This function uses singleton from to ensure that a run-time exception is thrown if there\r\nis more than one extension on the given resource with the specified url.\r\n*/\r\ndefine function Extension(domainResource DomainResource, url String):\r\n  singleton from &quot;Extensions&quot;(domainResource, url)\r\n\r\n/*\r\n@description: Returns any extensions defined on the given element with the specified url.\r\n@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access\r\ncontent that is defined by extensions but not yet surfaced in the CQL model info.\r\n*/\r\ndefine function Extensions(element Element, url String):\r\n  element.extension E\r\n\t  where E.url = url\r\n\t\treturn E\r\n\r\n/*\r\n@description: Returns the single extension (if present) on the given element with the specified url.\r\n@comment: This function uses singleton from to ensure that a run-time exception is thrown if there\r\nis more than one extension on the given resource with the specified url.\r\n*/\r\ndefine function Extension(element Element, url String):\r\n  singleton from Extensions(element, url)\r\n\r\n/*\r\n@description: Returns any modifier extensions defined on the given resource with the specified url.\r\n@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access\r\ncontent that is defined by extensions but not yet surfaced in the\r\nCQL model info.\r\n*/\r\ndefine function ModifierExtensions(domainResource DomainResource, url String):\r\n  domainResource.modifierExtension E\r\n\t  where E.url = url\r\n\t\treturn E\r\n\r\n/*\r\n@description: Returns the single modifier extension (if present) on the given resource with the specified url.\r\n@comment: This function uses singleton from to ensure that a run-time exception is thrown if there\r\nis more than one extension on the given resource with the specified url.\r\n*/\r\ndefine function ModifierExtension(domainResource DomainResource, url String):\r\n  singleton from ModifierExtensions(domainResource, url)\r\n\r\n/*\r\n@description: Returns any modifier extensions defined on the given element with the specified url.\r\n@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access\r\ncontent that is defined by extensions but not yet surfaced in the CQL model info.\r\n*/\r\ndefine function ModifierExtensions(element BackboneElement, url String):\r\n  element.modifierExtension E\r\n\t  where E.url = url\r\n\t\treturn E\r\n\r\n/*\r\n@description: Returns the single modifier extension (if present) on the given element with the specified url.\r\n@comment: This function uses singleton from to ensure that a run-time exception is thrown if there\r\nis more than one extension on the given resource with the specified url.\r\n*/\r\ndefine function ModifierExtension(element BackboneElement, url String):\r\n  singleton from ModifierExtensions(element, url)\r\n\r\n/*\r\n@description: Returns any base-FHIR extensions defined on the given resource with the specified id.\r\n@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access\r\ncontent that is defined by extensions but not yet surfaced in the CQL model info.\r\n*/\r\ndefine function BaseExtensions(domainResource DomainResource, id String):\r\n  domainResource.extension E\r\n\t  where E.url = ('http://hl7.org/fhir/StructureDefinition/' + id)\r\n\t\treturn E\r\n\r\n/*\r\n@description: Returns the single base-FHIR extension (if present) on the given resource with the specified id.\r\n@comment: This function uses singleton from to ensure that a run-time exception is thrown if there\r\nis more than one extension on the given resource with the specified url.\r\n*/\r\ndefine function BaseExtension(domainResource DomainResource, id String):\r\n  singleton from BaseExtensions(domainResource, id)\r\n\r\n/*\r\n@description: Returns any base-FHIR extensions defined on the given element with the specified id.\r\n@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access\r\ncontent that is defined by extensions but not yet surfaced in the CQL model info.\r\n*/\r\ndefine function BaseExtensions(element Element, id String):\r\n  element.extension E\r\n\t  where E.url = ('http://hl7.org/fhir/StructureDefinition/' + id)\r\n\t\treturn E\r\n\r\n/*\r\n@description: Returns the single base-FHIR extension (if present) on the given element with the specified id.\r\n@comment: This function uses singleton from to ensure that a run-time exception is thrown if there\r\nis more than one extension on the given resource with the specified url.\r\n*/\r\ndefine function BaseExtension(element Element, id String):\r\n  singleton from BaseExtensions(element, id)\r\n\r\n/*\r\n@description: Returns any base-FHIR modifier extensions defined on the given resource with the specified id.\r\n@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access\r\ncontent that is defined by extensions but not yet surfaced in the CQL model info.\r\n*/\r\ndefine function BaseModifierExtensions(domainResource DomainResource, id String):\r\n  domainResource.modifierExtension E\r\n\t  where E.url = ('http://hl7.org/fhir/StructureDefinition/' + id)\r\n\t\treturn E\r\n\r\n/*\r\n@description: Returns the single base-FHIR modifier extension (if present) on the given resource with the specified id.\r\n@comment: This function uses singleton from to ensure that a run-time exception is thrown if there\r\nis more than one extension on the given resource with the specified url.\r\n*/\r\ndefine function BaseModifierExtension(domainResource DomainResource, id String):\r\n  singleton from BaseModifierExtensions(domainResource, id)\r\n\r\n/*\r\n@description: Returns any base-FHIR modifier extensions defined on the given element with the specified id.\r\n@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access\r\ncontent that is defined by extensions but not yet surfaced in the CQL model info.\r\n*/\r\ndefine function BaseModifierExtensions(element BackboneElement, id String):\r\n  element.modifierExtension E\r\n\t  where E.url = ('http://hl7.org/fhir/StructureDefinition/' + id)\r\n\t\treturn E\r\n\r\n/*\r\n@description: Returns the single base-FHIR extension (if present) on the given element with the specified id.\r\n@comment: This function uses singleton from to ensure that a run-time exception is thrown if there\r\nis more than one extension on the given resource with the specified url.\r\n*/\r\ndefine function BaseModifierExtension(element BackboneElement, id String):\r\n  singleton from BaseModifierExtensions(element, id)</code></pre></div>"
  },
  "contained" : [
    {
      "resourceType" : "Parameters",
      "id" : "options",
      "parameter" : [
        {
          "name" : "translatorVersion",
          "valueString" : "2.9.0-SNAPSHOT"
        },
        {
          "name" : "option",
          "valueString" : "EnableAnnotations"
        },
        {
          "name" : "option",
          "valueString" : "EnableLocators"
        },
        {
          "name" : "option",
          "valueString" : "DisableListDemotion"
        },
        {
          "name" : "option",
          "valueString" : "DisableListPromotion"
        },
        {
          "name" : "format",
          "valueString" : "XML"
        },
        {
          "name" : "format",
          "valueString" : "JSON"
        },
        {
          "name" : "analyzeDataRequirements",
          "valueBoolean" : true
        },
        {
          "name" : "collapseDataRequirements",
          "valueBoolean" : true
        },
        {
          "name" : "compatibilityLevel",
          "valueString" : "1.5"
        },
        {
          "name" : "enableCqlOnly",
          "valueBoolean" : false
        },
        {
          "name" : "errorLevel",
          "valueString" : "Info"
        },
        {
          "name" : "signatureLevel",
          "valueString" : "None"
        },
        {
          "name" : "validateUnits",
          "valueBoolean" : true
        },
        {
          "name" : "verifyOnly",
          "valueBoolean" : false
        }
      ]
    }
  ],
  "extension" : [
    {
      "url" : "http://hl7.org/fhir/StructureDefinition/cqf-cqlOptions",
      "valueReference" : {
        "reference" : "#options"
      }
    },
    {
      "url" : "http://hl7.org/fhir/StructureDefinition/structuredefinition-wg",
      "valueCode" : "cds"
    }
  ],
  "url" : "http://hl7.org/fhir/uv/cql/Library/CQLExample",
  "version" : "1.0.0-ballot",
  "name" : "CQLExample",
  "title" : "FHIR Common (Source CQL Example)",
  "status" : "active",
  "experimental" : false,
  "type" : {
    "coding" : [
      {
        "system" : "http://terminology.hl7.org/CodeSystem/library-type",
        "code" : "logic-library"
      }
    ]
  },
  "date" : "2022-11-16T17:19:08+00:00",
  "publisher" : "HL7 International / Clinical Decision Support",
  "contact" : [
    {
      "telecom" : [
        {
          "system" : "url",
          "value" : "http://www.hl7.org/Special/committees/dss"
        }
      ]
    }
  ],
  "description" : "This library defines terminologies and functions commonly used in FHIR-based CQL artifacts.\n",
  "jurisdiction" : [
    {
      "coding" : [
        {
          "system" : "http://unstats.un.org/unsd/methods/m49/m49.htm",
          "code" : "001",
          "display" : "World"
        }
      ]
    }
  ],
  "content" : [
    {
      "contentType" : "text/cql",
      "data" : "bGlicmFyeSBGSElSQ29tbW9uIHZlcnNpb24gJzQuMS4wMDAnDQoNCnVzaW5nIEZISVIgdmVyc2lvbiAnNC4wLjEnDQoNCmluY2x1ZGUgRkhJUkhlbHBlcnMgdmVyc2lvbiAnNC4xLjAwMCcNCg0KDQpjb2Rlc3lzdGVtICJMT0lOQyI6ICdodHRwOi8vbG9pbmMub3JnJw0KY29kZXN5c3RlbSAiU05PTUVEQ1QiOiAnaHR0cDovL3Nub21lZC5pbmZvL3NjdCcNCmNvZGVzeXN0ZW0gIlJvbGVDb2RlIjogJ2h0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vdjMtUm9sZUNvZGUnDQpjb2Rlc3lzdGVtICJEaWFnbm9zaXMgUm9sZSI6ICdodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2RpYWdub3Npcy1yb2xlJw0KY29kZXN5c3RlbSAiUmVxdWVzdEludGVudCI6ICdodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL3JlcXVlc3QtaW50ZW50Jw0KY29kZXN5c3RlbSAiTWVkaWNhdGlvblJlcXVlc3RDYXRlZ29yeSI6ICdodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL21lZGljYXRpb25yZXF1ZXN0LWNhdGVnb3J5Jw0KY29kZXN5c3RlbSAiQ29uZGl0aW9uQ2xpbmljYWxTdGF0dXNDb2RlcyI6ICdodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi1jbGluaWNhbCcNCmNvZGVzeXN0ZW0gIkNvbmRpdGlvblZlcmlmaWNhdGlvblN0YXR1c0NvZGVzIjogJ2h0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vY29uZGl0aW9uLXZlci1zdGF0dXMnDQpjb2Rlc3lzdGVtICJBbGxlcmd5SW50b2xlcmFuY2VDbGluaWNhbFN0YXR1c0NvZGVzIjogJ2h0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vYWxsZXJneWludG9sZXJhbmNlLWNsaW5pY2FsJw0KY29kZXN5c3RlbSAiQWxsZXJneUludG9sZXJhbmNlVmVyaWZpY2F0aW9uU3RhdHVzQ29kZXMiOiAnaHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9hbGxlcmd5aW50b2xlcmFuY2UtdmVyaWZpY2F0aW9uJw0KDQovL0N1cnJlbnRseSB1bnJlc29sdmVhYmxlIGluIFZTQUM6DQovL3ZhbHVlc2V0ICJBY3RpdmUgQ29uZGl0aW9uIjogJ2h0dHA6Ly9maGlyLm9yZy9ndWlkZXMvY3FmL2NvbW1vbi9WYWx1ZVNldC9hY3RpdmUtY29uZGl0aW9uJw0KLy92YWx1ZXNldCAiSW5hY3RpdmUgQ29uZGl0aW9uIjogJ2h0dHA6Ly9maGlyLm9yZy9ndWlkZXMvY3FmL2NvbW1vbi9WYWx1ZVNldC9pbmFjdGl2ZS1jb25kaXRpb24nDQoNCmNvZGUgIkJpcnRoZGF0ZSI6ICcyMTExMi04JyBmcm9tICJMT0lOQyIgZGlzcGxheSAnQmlydGggZGF0ZScNCmNvZGUgIkRlYWQiOiAnNDE5MDk5MDA5JyBmcm9tICJTTk9NRURDVCIgZGlzcGxheSAnRGVhZCcNCmNvZGUgIkVSIjogJ0VSJyBmcm9tICJSb2xlQ29kZSIgZGlzcGxheSAnRW1lcmdlbmN5IHJvb20nDQpjb2RlICJJQ1UiOiAnSUNVJyBmcm9tICJSb2xlQ29kZSIgZGlzcGxheSAnSW50ZW5zaXZlIGNhcmUgdW5pdCcNCmNvZGUgIkJpbGxpbmciOiAnYmlsbGluZycgZnJvbSAiRGlhZ25vc2lzIFJvbGUiIGRpc3BsYXkgJ0JpbGxpbmcnDQoNCi8vIENvbmRpdGlvbiBDbGluaWNhbCBTdGF0dXMgQ29kZXMgLSBDb25zaWRlciB2YWx1ZSBzZXRzIGZvciB0aGVzZQ0KY29kZSAiYWN0aXZlIjogJ2FjdGl2ZScgZnJvbSAiQ29uZGl0aW9uQ2xpbmljYWxTdGF0dXNDb2RlcyINCmNvZGUgInJlY3VycmVuY2UiOiAncmVjdXJyZW5jZScgZnJvbSAiQ29uZGl0aW9uQ2xpbmljYWxTdGF0dXNDb2RlcyINCmNvZGUgInJlbGFwc2UiOiAncmVsYXBzZScgZnJvbSAiQ29uZGl0aW9uQ2xpbmljYWxTdGF0dXNDb2RlcyINCmNvZGUgImluYWN0aXZlIjogJ2luYWN0aXZlJyBmcm9tICJDb25kaXRpb25DbGluaWNhbFN0YXR1c0NvZGVzIg0KY29kZSAicmVtaXNzaW9uIjogJ3JlbWlzc2lvbicgZnJvbSAiQ29uZGl0aW9uQ2xpbmljYWxTdGF0dXNDb2RlcyINCmNvZGUgInJlc29sdmVkIjogJ3Jlc29sdmVkJyBmcm9tICJDb25kaXRpb25DbGluaWNhbFN0YXR1c0NvZGVzIg0KDQovLyBDb25kaXRpb24gVmVyaWZpY2F0aW9uIFN0YXR1cyBDb2RlcyAtIENvbnNpZGVyIHZhbHVlIHNldHMgZm9yIHRoZXNlDQpjb2RlICJ1bmNvbmZpcm1lZCI6ICd1bmNvbmZpcm1lZCcgZnJvbSBDb25kaXRpb25WZXJpZmljYXRpb25TdGF0dXNDb2Rlcw0KY29kZSAicHJvdmlzaW9uYWwiOiAncHJvdmlzaW9uYWwnIGZyb20gQ29uZGl0aW9uVmVyaWZpY2F0aW9uU3RhdHVzQ29kZXMNCmNvZGUgImRpZmZlcmVudGlhbCI6ICdkaWZmZXJlbnRpYWwnIGZyb20gQ29uZGl0aW9uVmVyaWZpY2F0aW9uU3RhdHVzQ29kZXMNCmNvZGUgImNvbmZpcm1lZCI6ICdjb25maXJtZWQnIGZyb20gQ29uZGl0aW9uVmVyaWZpY2F0aW9uU3RhdHVzQ29kZXMNCmNvZGUgInJlZnV0ZWQiOiAncmVmdXRlZCcgZnJvbSBDb25kaXRpb25WZXJpZmljYXRpb25TdGF0dXNDb2Rlcw0KY29kZSAiZW50ZXJlZC1pbi1lcnJvciI6ICdlbnRlcmVkLWluLWVycm9yJyBmcm9tIENvbmRpdGlvblZlcmlmaWNhdGlvblN0YXR1c0NvZGVzDQoNCmNvZGUgImFsbGVyZ3ktYWN0aXZlIjogJ2FjdGl2ZScgZnJvbSAiQWxsZXJneUludG9sZXJhbmNlQ2xpbmljYWxTdGF0dXNDb2RlcyINCmNvZGUgImFsbGVyZ3ktaW5hY3RpdmUiOiAnaW5hY3RpdmUnIGZyb20gIkFsbGVyZ3lJbnRvbGVyYW5jZUNsaW5pY2FsU3RhdHVzQ29kZXMiDQpjb2RlICJhbGxlcmd5LXJlc29sdmVkIjogJ3Jlc29sdmVkJyBmcm9tICJBbGxlcmd5SW50b2xlcmFuY2VDbGluaWNhbFN0YXR1c0NvZGVzIg0KDQovLyBBbGxlcmd5L0ludG9sZXJhbmNlIFZlcmlmaWNhdGlvbiBTdGF0dXMgQ29kZXMgLSBDb25zaWRlciB2YWx1ZSBzZXRzIGZvciB0aGVzZQ0KY29kZSAiYWxsZXJneS11bmNvbmZpcm1lZCI6ICd1bmNvbmZpcm1lZCcgZnJvbSBBbGxlcmd5SW50b2xlcmFuY2VWZXJpZmljYXRpb25TdGF0dXNDb2Rlcw0KY29kZSAiYWxsZXJneS1jb25maXJtZWQiOiAnY29uZmlybWVkJyBmcm9tIEFsbGVyZ3lJbnRvbGVyYW5jZVZlcmlmaWNhdGlvblN0YXR1c0NvZGVzDQpjb2RlICJhbGxlcmd5LXJlZnV0ZWQiOiAncmVmdXRlZCcgZnJvbSBBbGxlcmd5SW50b2xlcmFuY2VWZXJpZmljYXRpb25TdGF0dXNDb2Rlcw0KDQovLyBNZWRpY2F0aW9uUmVxdWVzdCBDYXRlZ29yeSBDb2Rlcw0KY29kZSAiQ29tbXVuaXR5IjogJ2NvbW11bml0eScgZnJvbSAiTWVkaWNhdGlvblJlcXVlc3RDYXRlZ29yeSIgZGlzcGxheSAnQ29tbXVuaXR5Jw0KY29kZSAiRGlzY2hhcmdlIjogJ2Rpc2NoYXJnZScgZnJvbSAiTWVkaWNhdGlvblJlcXVlc3RDYXRlZ29yeSIgZGlzcGxheSAnRGlzY2hhcmdlJw0KDQovLyBEaWFnbm9zaXMgUm9sZSBDb2Rlcw0KY29kZSAiQUQiOiAnQUQnIGZyb20gIkRpYWdub3NpcyBSb2xlIiBkaXNwbGF5ICdBZG1pc3Npb24gZGlhZ25vc2lzJw0KY29kZSAiREQiOiAnREQnIGZyb20gIkRpYWdub3NpcyBSb2xlIiBkaXNwbGF5ICdEaXNjaGFyZ2UgZGlhZ25vc2lzJw0KY29kZSAiQ0MiOiAnQ0MnIGZyb20gIkRpYWdub3NpcyBSb2xlIiBkaXNwbGF5ICdDaGllZiBjb21wbGFpbnQnDQpjb2RlICJDTSI6ICdDTScgZnJvbSAiRGlhZ25vc2lzIFJvbGUiIGRpc3BsYXkgJ0NvbW9yYmlkaXR5IGRpYWdub3NpcycNCmNvZGUgInByZS1vcCI6ICdwcmUtb3AnIGZyb20gIkRpYWdub3NpcyBSb2xlIiBkaXNwbGF5ICdwcmUtb3AgZGlhZ25vc2lzJw0KY29kZSAicG9zdC1vcCI6ICdwb3N0LW9wJyBmcm9tICJEaWFnbm9zaXMgUm9sZSIgZGlzcGxheSAncG9zdC1vcCBkaWFnbm9zaXMnDQpjb2RlICJiaWxsaW5nIjogJ2JpbGxpbmcnIGZyb20gIkRpYWdub3NpcyBSb2xlIiBkaXNwbGF5ICdiaWxsaW5nIGRpYWdub3NpcycNCg0KY29udGV4dCBQYXRpZW50DQoNCi8qDQpAZGVzY3JpcHRpb246IE5vcm1hbGl6ZXMgYSB2YWx1ZSB0aGF0IGlzIGEgY2hvaWNlIG9mIHRpbWluZy12YWx1ZWQgdHlwZXMgdG8gYW4gZXF1aXZhbGVudCBpbnRlcnZhbA0KQGNvbW1lbnQ6IE5vcm1hbGl6ZXMgYSBjaG9pY2UgdHlwZSBvZiBGSElSLmRhdGVUaW1lLCBGSElSLlBlcmlvZCwgRkhJUi5UaW1pbmcsIEZISVIuaW5zdGFuY2UsIEZISVIuc3RyaW5nLCBGSElSLkFnZSwgb3IgRkhJUi5SYW5nZSB0eXBlcw0KdG8gYW4gZXF1aXZhbGVudCBpbnRlcnZhbC4gVGhpcyBzZWxlY3Rpb24gb2YgY2hvaWNlIHR5cGVzIGlzIGEgc3VwZXJzZXQgb2YgdGhlIG1ham9yaXR5IG9mIGNob2ljZSB0eXBlcyB0aGF0IGFyZSB1c2VkIGFzIHBvc3NpYmxlDQpyZXByZXNlbnRhdGlvbnMgZm9yIHRpbWluZy12YWx1ZWQgZWxlbWVudHMgaW4gRkhJUiwgYWxsb3dpbmcgdGhpcyBmdW5jdGlvbiB0byBiZSB1c2VkIGFjcm9zcyBhbnkgcmVzb3VyY2UuIE5PVEU6IER1ZSB0byB0aGUNCmNvbXBsZXhpdHkgb2YgZGV0ZXJtaW5pbmcgYSBzaW5nbGUgaW50ZXJ2YWwgZnJvbSBhIFRpbWluZyBvciBTdHJpbmcgdHlwZSwgdGhpcyBmdW5jdGlvbiB3aWxsIHRocm93IGEgcnVuLXRpbWUgZXhjZXB0aW9uIGlmIGl0IGlzIHVzZWQNCndpdGggYSBUaW1pbmcgb3IgU3RyaW5nLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBUb0ludGVydmFsKGNob2ljZSBDaG9pY2U8RkhJUi5kYXRlVGltZSwgRkhJUi5QZXJpb2QsIEZISVIuVGltaW5nLCBGSElSLmluc3RhbnQsIEZISVIuc3RyaW5nLCBGSElSLkFnZSwgRkhJUi5SYW5nZT4pOg0KICBjYXNlDQoJICB3aGVuIGNob2ljZSBpcyBGSElSLmRhdGVUaW1lIHRoZW4NCiAgICAJSW50ZXJ2YWxbRkhJUkhlbHBlcnMuVG9EYXRlVGltZShjaG9pY2UgYXMgRkhJUi5kYXRlVGltZSksIEZISVJIZWxwZXJzLlRvRGF0ZVRpbWUoY2hvaWNlIGFzIEZISVIuZGF0ZVRpbWUpXQ0KCQl3aGVuIGNob2ljZSBpcyBGSElSLlBlcmlvZCB0aGVuDQogIAkJRkhJUkhlbHBlcnMuVG9JbnRlcnZhbChjaG9pY2UgYXMgRkhJUi5QZXJpb2QpDQoJCXdoZW4gY2hvaWNlIGlzIEZISVIuaW5zdGFudCB0aGVuDQoJCQlJbnRlcnZhbFtGSElSSGVscGVycy5Ub0RhdGVUaW1lKGNob2ljZSBhcyBGSElSLmluc3RhbnQpLCBGSElSSGVscGVycy5Ub0RhdGVUaW1lKGNob2ljZSBhcyBGSElSLmluc3RhbnQpXQ0KCQl3aGVuIGNob2ljZSBpcyBGSElSLkFnZSB0aGVuDQoJCSAgSW50ZXJ2YWxbRkhJUkhlbHBlcnMuVG9EYXRlKFBhdGllbnQuYmlydGhEYXRlKSArIEZISVJIZWxwZXJzLlRvUXVhbnRpdHkoY2hvaWNlIGFzIEZISVIuQWdlKSwNCgkJCSAgRkhJUkhlbHBlcnMuVG9EYXRlKFBhdGllbnQuYmlydGhEYXRlKSArIEZISVJIZWxwZXJzLlRvUXVhbnRpdHkoY2hvaWNlIGFzIEZISVIuQWdlKSArIDEgeWVhcikNCgkJd2hlbiBjaG9pY2UgaXMgRkhJUi5SYW5nZSB0aGVuDQoJCSAgSW50ZXJ2YWxbRkhJUkhlbHBlcnMuVG9EYXRlKFBhdGllbnQuYmlydGhEYXRlKSArIEZISVJIZWxwZXJzLlRvUXVhbnRpdHkoKGNob2ljZSBhcyBGSElSLlJhbmdlKS5sb3cpLA0KCQkJICBGSElSSGVscGVycy5Ub0RhdGUoUGF0aWVudC5iaXJ0aERhdGUpICsgRkhJUkhlbHBlcnMuVG9RdWFudGl0eSgoY2hvaWNlIGFzIEZISVIuUmFuZ2UpLmhpZ2gpICsgMSB5ZWFyKQ0KCQl3aGVuIGNob2ljZSBpcyBGSElSLlRpbWluZyB0aGVuDQoJCSAgTWVzc2FnZShudWxsIGFzIEludGVydmFsPERhdGVUaW1lPiwgdHJ1ZSwgJzEnLCAnRXJyb3InLCAnQ2Fubm90IGNvbXB1dGUgYSBzaW5nbGUgaW50ZXJ2YWwgZnJvbSBhIFRpbWluZyB0eXBlJykNCiAgICB3aGVuIGNob2ljZSBpcyBGSElSLnN0cmluZyB0aGVuDQogICAgICBNZXNzYWdlKG51bGwgYXMgSW50ZXJ2YWw8RGF0ZVRpbWU+LCB0cnVlLCAnMScsICdFcnJvcicsICdDYW5ub3QgY29tcHV0ZSBhbiBpbnRlcnZhbCBmcm9tIGEgU3RyaW5nIHZhbHVlJykNCgkJZWxzZQ0KCQkJbnVsbCBhcyBJbnRlcnZhbDxEYXRlVGltZT4NCgllbmQNCg0KLyoNCkBkZXNjcmlwdGlvbjogUmV0dXJucyBhbiBpbnRlcnZhbCByZXByZXNlbnRpbmcgdGhlIG5vcm1hbGl6ZWQgQWJhdGVtZW50IG9mIGEgZ2l2ZW4gQ29uZGl0aW9uIHJlc291cmNlLg0KQGNvbW1lbnQ6IE5PVEU6IER1ZSB0byB0aGUgY29tcGxleGl0eSBvZiBkZXRlcm1pbmluZyBhbiBpbnRlcnZhbCBmcm9tIGEgU3RyaW5nLCB0aGlzIGZ1bmN0aW9uIHdpbGwgdGhyb3cNCmEgcnVuLXRpbWUgZXhjZXB0aW9uIGlmIHVzZWQgd2l0aCBhIENvbmRpdGlvbiBpbnN0YW5jZSB0aGF0IGhhcyBhIFN0cmluZyBhcyB0aGUgYWJhdGVtZW50IHZhbHVlLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBUb0FiYXRlbWVudEludGVydmFsKGNvbmRpdGlvbiBDb25kaXRpb24pOg0KCWlmIGNvbmRpdGlvbi5hYmF0ZW1lbnQgaXMgRkhJUi5kYXRlVGltZSB0aGVuDQoJICBJbnRlcnZhbFtGSElSSGVscGVycy5Ub0RhdGVUaW1lKGNvbmRpdGlvbi5hYmF0ZW1lbnQgYXMgRkhJUi5kYXRlVGltZSksIEZISVJIZWxwZXJzLlRvRGF0ZVRpbWUoY29uZGl0aW9uLmFiYXRlbWVudCBhcyBGSElSLmRhdGVUaW1lKV0NCgllbHNlIGlmIGNvbmRpdGlvbi5hYmF0ZW1lbnQgaXMgRkhJUi5QZXJpb2QgdGhlbg0KCSAgRkhJUkhlbHBlcnMuVG9JbnRlcnZhbChjb25kaXRpb24uYWJhdGVtZW50IGFzIEZISVIuUGVyaW9kKQ0KCWVsc2UgaWYgY29uZGl0aW9uLmFiYXRlbWVudCBpcyBGSElSLnN0cmluZyB0aGVuDQogICAgTWVzc2FnZShudWxsIGFzIEludGVydmFsPERhdGVUaW1lPiwgdHJ1ZSwgJzEnLCAnRXJyb3InLCAnQ2Fubm90IGNvbXB1dGUgYW4gaW50ZXJ2YWwgZnJvbSBhIFN0cmluZyB2YWx1ZScpDQoJZWxzZSBpZiBjb25kaXRpb24uYWJhdGVtZW50IGlzIEZISVIuQWdlIHRoZW4NCgkJSW50ZXJ2YWxbRkhJUkhlbHBlcnMuVG9EYXRlKFBhdGllbnQuYmlydGhEYXRlKSArIEZISVJIZWxwZXJzLlRvUXVhbnRpdHkoY29uZGl0aW9uLmFiYXRlbWVudCBhcyBGSElSLkFnZSksDQoJCQlGSElSSGVscGVycy5Ub0RhdGUoUGF0aWVudC5iaXJ0aERhdGUpICsgRkhJUkhlbHBlcnMuVG9RdWFudGl0eShjb25kaXRpb24uYWJhdGVtZW50IGFzIEZISVIuQWdlKSArIDEgeWVhcikNCgllbHNlIGlmIGNvbmRpdGlvbi5hYmF0ZW1lbnQgaXMgRkhJUi5SYW5nZSB0aGVuDQoJICBJbnRlcnZhbFtGSElSSGVscGVycy5Ub0RhdGUoUGF0aWVudC5iaXJ0aERhdGUpICsgRkhJUkhlbHBlcnMuVG9RdWFudGl0eSgoY29uZGl0aW9uLmFiYXRlbWVudCBhcyBGSElSLlJhbmdlKS5sb3cpLA0KCQkgIEZISVJIZWxwZXJzLlRvRGF0ZShQYXRpZW50LmJpcnRoRGF0ZSkgKyBGSElSSGVscGVycy5Ub1F1YW50aXR5KChjb25kaXRpb24uYWJhdGVtZW50IGFzIEZISVIuUmFuZ2UpLmhpZ2gpICsgMSB5ZWFyKQ0KCWVsc2UgaWYgY29uZGl0aW9uLmFiYXRlbWVudCBpcyBGSElSLmJvb2xlYW4gdGhlbg0KCSAgSW50ZXJ2YWxbZW5kIG9mIFRvSW50ZXJ2YWwoY29uZGl0aW9uLm9uc2V0KSwgY29uZGl0aW9uLnJlY29yZGVkRGF0ZSkNCgllbHNlIG51bGwNCg0KLyoNCkBkZXNjcmlwdGlvbjogUmV0dXJucyBhbiBpbnRlcnZhbCByZXByZXNlbnRpbmcgdGhlIG5vcm1hbGl6ZWQgcHJldmFsZW5jZSBwZXJpb2Qgb2YgYSBnaXZlbiBDb25kaXRpb24gcmVzb3VyY2UuDQpAY29tbWVudDogVXNlcyB0aGUgVG9JbnRlcnZhbCBhbmQgVG9BYmF0ZW1lbnRJbnRlcnZhbCBmdW5jdGlvbnMgdG8gZGV0ZXJtaW5lIHRoZSB3aWRlc3QgcG90ZW50aWFsIGludGVydmFsIGZyb20NCm9uc2V0IHRvIGFiYXRlbWVudCBhcyBzcGVjaWZpZWQgaW4gdGhlIGdpdmVuIENvbmRpdGlvbi4NCiovDQpkZWZpbmUgZnVuY3Rpb24gVG9QcmV2YWxlbmNlSW50ZXJ2YWwoY29uZGl0aW9uIENvbmRpdGlvbik6DQppZiBjb25kaXRpb24uY2xpbmljYWxTdGF0dXMgfiAiYWN0aXZlIg0KICBvciBjb25kaXRpb24uY2xpbmljYWxTdGF0dXMgfiAicmVjdXJyZW5jZSINCiAgb3IgY29uZGl0aW9uLmNsaW5pY2FsU3RhdHVzIH4gInJlbGFwc2UiIHRoZW4NCiAgSW50ZXJ2YWxbc3RhcnQgb2YgVG9JbnRlcnZhbChjb25kaXRpb24ub25zZXQpLCBlbmQgb2YgVG9BYmF0ZW1lbnRJbnRlcnZhbChjb25kaXRpb24pXQ0KZWxzZQ0KICBJbnRlcnZhbFtzdGFydCBvZiBUb0ludGVydmFsKGNvbmRpdGlvbi5vbnNldCksIGVuZCBvZiBUb0FiYXRlbWVudEludGVydmFsKGNvbmRpdGlvbikpDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgYW55IGV4dGVuc2lvbnMgZGVmaW5lZCBvbiB0aGUgZ2l2ZW4gcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHVybC4NCkBjb21tZW50OiBOT1RFOiBFeHRlbnNpb25zIGFyZSBub3QgdGhlIHByZWZlcnJlZCBhcHByb2FjaCwgYnV0IGFyZSB1c2VkIGFzIGEgd2F5IHRvIGFjY2Vzcw0KY29udGVudCB0aGF0IGlzIGRlZmluZWQgYnkgZXh0ZW5zaW9ucyBidXQgbm90IHlldCBzdXJmYWNlZCBpbiB0aGUNCkNRTCBtb2RlbCBpbmZvLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBFeHRlbnNpb25zKGRvbWFpblJlc291cmNlIERvbWFpblJlc291cmNlLCB1cmwgU3RyaW5nKToNCiAgZG9tYWluUmVzb3VyY2UuZXh0ZW5zaW9uIEUNCgkgIHdoZXJlIEUudXJsID0gdXJsDQoJCXJldHVybiBFDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgdGhlIHNpbmdsZSBleHRlbnNpb24gKGlmIHByZXNlbnQpIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgdXJsLg0KQGNvbW1lbnQ6IFRoaXMgZnVuY3Rpb24gdXNlcyBzaW5nbGV0b24gZnJvbSB0byBlbnN1cmUgdGhhdCBhIHJ1bi10aW1lIGV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgdGhlcmUNCmlzIG1vcmUgdGhhbiBvbmUgZXh0ZW5zaW9uIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgdXJsLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBFeHRlbnNpb24oZG9tYWluUmVzb3VyY2UgRG9tYWluUmVzb3VyY2UsIHVybCBTdHJpbmcpOg0KICBzaW5nbGV0b24gZnJvbSAiRXh0ZW5zaW9ucyIoZG9tYWluUmVzb3VyY2UsIHVybCkNCg0KLyoNCkBkZXNjcmlwdGlvbjogUmV0dXJucyBhbnkgZXh0ZW5zaW9ucyBkZWZpbmVkIG9uIHRoZSBnaXZlbiBlbGVtZW50IHdpdGggdGhlIHNwZWNpZmllZCB1cmwuDQpAY29tbWVudDogTk9URTogRXh0ZW5zaW9ucyBhcmUgbm90IHRoZSBwcmVmZXJyZWQgYXBwcm9hY2gsIGJ1dCBhcmUgdXNlZCBhcyBhIHdheSB0byBhY2Nlc3MNCmNvbnRlbnQgdGhhdCBpcyBkZWZpbmVkIGJ5IGV4dGVuc2lvbnMgYnV0IG5vdCB5ZXQgc3VyZmFjZWQgaW4gdGhlIENRTCBtb2RlbCBpbmZvLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBFeHRlbnNpb25zKGVsZW1lbnQgRWxlbWVudCwgdXJsIFN0cmluZyk6DQogIGVsZW1lbnQuZXh0ZW5zaW9uIEUNCgkgIHdoZXJlIEUudXJsID0gdXJsDQoJCXJldHVybiBFDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgdGhlIHNpbmdsZSBleHRlbnNpb24gKGlmIHByZXNlbnQpIG9uIHRoZSBnaXZlbiBlbGVtZW50IHdpdGggdGhlIHNwZWNpZmllZCB1cmwuDQpAY29tbWVudDogVGhpcyBmdW5jdGlvbiB1c2VzIHNpbmdsZXRvbiBmcm9tIHRvIGVuc3VyZSB0aGF0IGEgcnVuLXRpbWUgZXhjZXB0aW9uIGlzIHRocm93biBpZiB0aGVyZQ0KaXMgbW9yZSB0aGFuIG9uZSBleHRlbnNpb24gb24gdGhlIGdpdmVuIHJlc291cmNlIHdpdGggdGhlIHNwZWNpZmllZCB1cmwuDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIEV4dGVuc2lvbihlbGVtZW50IEVsZW1lbnQsIHVybCBTdHJpbmcpOg0KICBzaW5nbGV0b24gZnJvbSBFeHRlbnNpb25zKGVsZW1lbnQsIHVybCkNCg0KLyoNCkBkZXNjcmlwdGlvbjogUmV0dXJucyBhbnkgbW9kaWZpZXIgZXh0ZW5zaW9ucyBkZWZpbmVkIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgdXJsLg0KQGNvbW1lbnQ6IE5PVEU6IEV4dGVuc2lvbnMgYXJlIG5vdCB0aGUgcHJlZmVycmVkIGFwcHJvYWNoLCBidXQgYXJlIHVzZWQgYXMgYSB3YXkgdG8gYWNjZXNzDQpjb250ZW50IHRoYXQgaXMgZGVmaW5lZCBieSBleHRlbnNpb25zIGJ1dCBub3QgeWV0IHN1cmZhY2VkIGluIHRoZQ0KQ1FMIG1vZGVsIGluZm8uDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIE1vZGlmaWVyRXh0ZW5zaW9ucyhkb21haW5SZXNvdXJjZSBEb21haW5SZXNvdXJjZSwgdXJsIFN0cmluZyk6DQogIGRvbWFpblJlc291cmNlLm1vZGlmaWVyRXh0ZW5zaW9uIEUNCgkgIHdoZXJlIEUudXJsID0gdXJsDQoJCXJldHVybiBFDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgdGhlIHNpbmdsZSBtb2RpZmllciBleHRlbnNpb24gKGlmIHByZXNlbnQpIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgdXJsLg0KQGNvbW1lbnQ6IFRoaXMgZnVuY3Rpb24gdXNlcyBzaW5nbGV0b24gZnJvbSB0byBlbnN1cmUgdGhhdCBhIHJ1bi10aW1lIGV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgdGhlcmUNCmlzIG1vcmUgdGhhbiBvbmUgZXh0ZW5zaW9uIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgdXJsLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBNb2RpZmllckV4dGVuc2lvbihkb21haW5SZXNvdXJjZSBEb21haW5SZXNvdXJjZSwgdXJsIFN0cmluZyk6DQogIHNpbmdsZXRvbiBmcm9tIE1vZGlmaWVyRXh0ZW5zaW9ucyhkb21haW5SZXNvdXJjZSwgdXJsKQ0KDQovKg0KQGRlc2NyaXB0aW9uOiBSZXR1cm5zIGFueSBtb2RpZmllciBleHRlbnNpb25zIGRlZmluZWQgb24gdGhlIGdpdmVuIGVsZW1lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIHVybC4NCkBjb21tZW50OiBOT1RFOiBFeHRlbnNpb25zIGFyZSBub3QgdGhlIHByZWZlcnJlZCBhcHByb2FjaCwgYnV0IGFyZSB1c2VkIGFzIGEgd2F5IHRvIGFjY2Vzcw0KY29udGVudCB0aGF0IGlzIGRlZmluZWQgYnkgZXh0ZW5zaW9ucyBidXQgbm90IHlldCBzdXJmYWNlZCBpbiB0aGUgQ1FMIG1vZGVsIGluZm8uDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIE1vZGlmaWVyRXh0ZW5zaW9ucyhlbGVtZW50IEJhY2tib25lRWxlbWVudCwgdXJsIFN0cmluZyk6DQogIGVsZW1lbnQubW9kaWZpZXJFeHRlbnNpb24gRQ0KCSAgd2hlcmUgRS51cmwgPSB1cmwNCgkJcmV0dXJuIEUNCg0KLyoNCkBkZXNjcmlwdGlvbjogUmV0dXJucyB0aGUgc2luZ2xlIG1vZGlmaWVyIGV4dGVuc2lvbiAoaWYgcHJlc2VudCkgb24gdGhlIGdpdmVuIGVsZW1lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIHVybC4NCkBjb21tZW50OiBUaGlzIGZ1bmN0aW9uIHVzZXMgc2luZ2xldG9uIGZyb20gdG8gZW5zdXJlIHRoYXQgYSBydW4tdGltZSBleGNlcHRpb24gaXMgdGhyb3duIGlmIHRoZXJlDQppcyBtb3JlIHRoYW4gb25lIGV4dGVuc2lvbiBvbiB0aGUgZ2l2ZW4gcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHVybC4NCiovDQpkZWZpbmUgZnVuY3Rpb24gTW9kaWZpZXJFeHRlbnNpb24oZWxlbWVudCBCYWNrYm9uZUVsZW1lbnQsIHVybCBTdHJpbmcpOg0KICBzaW5nbGV0b24gZnJvbSBNb2RpZmllckV4dGVuc2lvbnMoZWxlbWVudCwgdXJsKQ0KDQovKg0KQGRlc2NyaXB0aW9uOiBSZXR1cm5zIGFueSBiYXNlLUZISVIgZXh0ZW5zaW9ucyBkZWZpbmVkIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgaWQuDQpAY29tbWVudDogTk9URTogRXh0ZW5zaW9ucyBhcmUgbm90IHRoZSBwcmVmZXJyZWQgYXBwcm9hY2gsIGJ1dCBhcmUgdXNlZCBhcyBhIHdheSB0byBhY2Nlc3MNCmNvbnRlbnQgdGhhdCBpcyBkZWZpbmVkIGJ5IGV4dGVuc2lvbnMgYnV0IG5vdCB5ZXQgc3VyZmFjZWQgaW4gdGhlIENRTCBtb2RlbCBpbmZvLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBCYXNlRXh0ZW5zaW9ucyhkb21haW5SZXNvdXJjZSBEb21haW5SZXNvdXJjZSwgaWQgU3RyaW5nKToNCiAgZG9tYWluUmVzb3VyY2UuZXh0ZW5zaW9uIEUNCgkgIHdoZXJlIEUudXJsID0gKCdodHRwOi8vaGw3Lm9yZy9maGlyL1N0cnVjdHVyZURlZmluaXRpb24vJyArIGlkKQ0KCQlyZXR1cm4gRQ0KDQovKg0KQGRlc2NyaXB0aW9uOiBSZXR1cm5zIHRoZSBzaW5nbGUgYmFzZS1GSElSIGV4dGVuc2lvbiAoaWYgcHJlc2VudCkgb24gdGhlIGdpdmVuIHJlc291cmNlIHdpdGggdGhlIHNwZWNpZmllZCBpZC4NCkBjb21tZW50OiBUaGlzIGZ1bmN0aW9uIHVzZXMgc2luZ2xldG9uIGZyb20gdG8gZW5zdXJlIHRoYXQgYSBydW4tdGltZSBleGNlcHRpb24gaXMgdGhyb3duIGlmIHRoZXJlDQppcyBtb3JlIHRoYW4gb25lIGV4dGVuc2lvbiBvbiB0aGUgZ2l2ZW4gcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHVybC4NCiovDQpkZWZpbmUgZnVuY3Rpb24gQmFzZUV4dGVuc2lvbihkb21haW5SZXNvdXJjZSBEb21haW5SZXNvdXJjZSwgaWQgU3RyaW5nKToNCiAgc2luZ2xldG9uIGZyb20gQmFzZUV4dGVuc2lvbnMoZG9tYWluUmVzb3VyY2UsIGlkKQ0KDQovKg0KQGRlc2NyaXB0aW9uOiBSZXR1cm5zIGFueSBiYXNlLUZISVIgZXh0ZW5zaW9ucyBkZWZpbmVkIG9uIHRoZSBnaXZlbiBlbGVtZW50IHdpdGggdGhlIHNwZWNpZmllZCBpZC4NCkBjb21tZW50OiBOT1RFOiBFeHRlbnNpb25zIGFyZSBub3QgdGhlIHByZWZlcnJlZCBhcHByb2FjaCwgYnV0IGFyZSB1c2VkIGFzIGEgd2F5IHRvIGFjY2Vzcw0KY29udGVudCB0aGF0IGlzIGRlZmluZWQgYnkgZXh0ZW5zaW9ucyBidXQgbm90IHlldCBzdXJmYWNlZCBpbiB0aGUgQ1FMIG1vZGVsIGluZm8uDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIEJhc2VFeHRlbnNpb25zKGVsZW1lbnQgRWxlbWVudCwgaWQgU3RyaW5nKToNCiAgZWxlbWVudC5leHRlbnNpb24gRQ0KCSAgd2hlcmUgRS51cmwgPSAoJ2h0dHA6Ly9obDcub3JnL2ZoaXIvU3RydWN0dXJlRGVmaW5pdGlvbi8nICsgaWQpDQoJCXJldHVybiBFDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgdGhlIHNpbmdsZSBiYXNlLUZISVIgZXh0ZW5zaW9uIChpZiBwcmVzZW50KSBvbiB0aGUgZ2l2ZW4gZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgaWQuDQpAY29tbWVudDogVGhpcyBmdW5jdGlvbiB1c2VzIHNpbmdsZXRvbiBmcm9tIHRvIGVuc3VyZSB0aGF0IGEgcnVuLXRpbWUgZXhjZXB0aW9uIGlzIHRocm93biBpZiB0aGVyZQ0KaXMgbW9yZSB0aGFuIG9uZSBleHRlbnNpb24gb24gdGhlIGdpdmVuIHJlc291cmNlIHdpdGggdGhlIHNwZWNpZmllZCB1cmwuDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIEJhc2VFeHRlbnNpb24oZWxlbWVudCBFbGVtZW50LCBpZCBTdHJpbmcpOg0KICBzaW5nbGV0b24gZnJvbSBCYXNlRXh0ZW5zaW9ucyhlbGVtZW50LCBpZCkNCg0KLyoNCkBkZXNjcmlwdGlvbjogUmV0dXJucyBhbnkgYmFzZS1GSElSIG1vZGlmaWVyIGV4dGVuc2lvbnMgZGVmaW5lZCBvbiB0aGUgZ2l2ZW4gcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGlkLg0KQGNvbW1lbnQ6IE5PVEU6IEV4dGVuc2lvbnMgYXJlIG5vdCB0aGUgcHJlZmVycmVkIGFwcHJvYWNoLCBidXQgYXJlIHVzZWQgYXMgYSB3YXkgdG8gYWNjZXNzDQpjb250ZW50IHRoYXQgaXMgZGVmaW5lZCBieSBleHRlbnNpb25zIGJ1dCBub3QgeWV0IHN1cmZhY2VkIGluIHRoZSBDUUwgbW9kZWwgaW5mby4NCiovDQpkZWZpbmUgZnVuY3Rpb24gQmFzZU1vZGlmaWVyRXh0ZW5zaW9ucyhkb21haW5SZXNvdXJjZSBEb21haW5SZXNvdXJjZSwgaWQgU3RyaW5nKToNCiAgZG9tYWluUmVzb3VyY2UubW9kaWZpZXJFeHRlbnNpb24gRQ0KCSAgd2hlcmUgRS51cmwgPSAoJ2h0dHA6Ly9obDcub3JnL2ZoaXIvU3RydWN0dXJlRGVmaW5pdGlvbi8nICsgaWQpDQoJCXJldHVybiBFDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgdGhlIHNpbmdsZSBiYXNlLUZISVIgbW9kaWZpZXIgZXh0ZW5zaW9uIChpZiBwcmVzZW50KSBvbiB0aGUgZ2l2ZW4gcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGlkLg0KQGNvbW1lbnQ6IFRoaXMgZnVuY3Rpb24gdXNlcyBzaW5nbGV0b24gZnJvbSB0byBlbnN1cmUgdGhhdCBhIHJ1bi10aW1lIGV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgdGhlcmUNCmlzIG1vcmUgdGhhbiBvbmUgZXh0ZW5zaW9uIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgdXJsLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBCYXNlTW9kaWZpZXJFeHRlbnNpb24oZG9tYWluUmVzb3VyY2UgRG9tYWluUmVzb3VyY2UsIGlkIFN0cmluZyk6DQogIHNpbmdsZXRvbiBmcm9tIEJhc2VNb2RpZmllckV4dGVuc2lvbnMoZG9tYWluUmVzb3VyY2UsIGlkKQ0KDQovKg0KQGRlc2NyaXB0aW9uOiBSZXR1cm5zIGFueSBiYXNlLUZISVIgbW9kaWZpZXIgZXh0ZW5zaW9ucyBkZWZpbmVkIG9uIHRoZSBnaXZlbiBlbGVtZW50IHdpdGggdGhlIHNwZWNpZmllZCBpZC4NCkBjb21tZW50OiBOT1RFOiBFeHRlbnNpb25zIGFyZSBub3QgdGhlIHByZWZlcnJlZCBhcHByb2FjaCwgYnV0IGFyZSB1c2VkIGFzIGEgd2F5IHRvIGFjY2Vzcw0KY29udGVudCB0aGF0IGlzIGRlZmluZWQgYnkgZXh0ZW5zaW9ucyBidXQgbm90IHlldCBzdXJmYWNlZCBpbiB0aGUgQ1FMIG1vZGVsIGluZm8uDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIEJhc2VNb2RpZmllckV4dGVuc2lvbnMoZWxlbWVudCBCYWNrYm9uZUVsZW1lbnQsIGlkIFN0cmluZyk6DQogIGVsZW1lbnQubW9kaWZpZXJFeHRlbnNpb24gRQ0KCSAgd2hlcmUgRS51cmwgPSAoJ2h0dHA6Ly9obDcub3JnL2ZoaXIvU3RydWN0dXJlRGVmaW5pdGlvbi8nICsgaWQpDQoJCXJldHVybiBFDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgdGhlIHNpbmdsZSBiYXNlLUZISVIgZXh0ZW5zaW9uIChpZiBwcmVzZW50KSBvbiB0aGUgZ2l2ZW4gZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgaWQuDQpAY29tbWVudDogVGhpcyBmdW5jdGlvbiB1c2VzIHNpbmdsZXRvbiBmcm9tIHRvIGVuc3VyZSB0aGF0IGEgcnVuLXRpbWUgZXhjZXB0aW9uIGlzIHRocm93biBpZiB0aGVyZQ0KaXMgbW9yZSB0aGFuIG9uZSBleHRlbnNpb24gb24gdGhlIGdpdmVuIHJlc291cmNlIHdpdGggdGhlIHNwZWNpZmllZCB1cmwuDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIEJhc2VNb2RpZmllckV4dGVuc2lvbihlbGVtZW50IEJhY2tib25lRWxlbWVudCwgaWQgU3RyaW5nKToNCiAgc2luZ2xldG9uIGZyb20gQmFzZU1vZGlmaWVyRXh0ZW5zaW9ucyhlbGVtZW50LCBpZCk="
    }
  ]
}