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) - XML Representation

Active as of 2022-11-16

Raw xml | Download



<Library xmlns="http://hl7.org/fhir">
  <id value="CQLExample"/>
  <meta>
    <profile
             value="http://hl7.org/fhir/uv/cql/StructureDefinition/cql-library"/>
  </meta>
  <language value="en"/>
  <text>
    <status value="generated"/>
    <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'

using FHIR version '4.0.1'

include FHIRHelpers version '4.1.000'


codesystem &quot;LOINC&quot;: 'http://loinc.org'
codesystem &quot;SNOMEDCT&quot;: 'http://snomed.info/sct'
codesystem &quot;RoleCode&quot;: 'http://terminology.hl7.org/CodeSystem/v3-RoleCode'
codesystem &quot;Diagnosis Role&quot;: 'http://terminology.hl7.org/CodeSystem/diagnosis-role'
codesystem &quot;RequestIntent&quot;: 'http://terminology.hl7.org/CodeSystem/request-intent'
codesystem &quot;MedicationRequestCategory&quot;: 'http://terminology.hl7.org/CodeSystem/medicationrequest-category'
codesystem &quot;ConditionClinicalStatusCodes&quot;: 'http://terminology.hl7.org/CodeSystem/condition-clinical'
codesystem &quot;ConditionVerificationStatusCodes&quot;: 'http://terminology.hl7.org/CodeSystem/condition-ver-status'
codesystem &quot;AllergyIntoleranceClinicalStatusCodes&quot;: 'http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical'
codesystem &quot;AllergyIntoleranceVerificationStatusCodes&quot;: 'http://terminology.hl7.org/CodeSystem/allergyintolerance-verification'

//Currently unresolveable in VSAC:
//valueset &quot;Active Condition&quot;: 'http://fhir.org/guides/cqf/common/ValueSet/active-condition'
//valueset &quot;Inactive Condition&quot;: 'http://fhir.org/guides/cqf/common/ValueSet/inactive-condition'

code &quot;Birthdate&quot;: '21112-8' from &quot;LOINC&quot; display 'Birth date'
code &quot;Dead&quot;: '419099009' from &quot;SNOMEDCT&quot; display 'Dead'
code &quot;ER&quot;: 'ER' from &quot;RoleCode&quot; display 'Emergency room'
code &quot;ICU&quot;: 'ICU' from &quot;RoleCode&quot; display 'Intensive care unit'
code &quot;Billing&quot;: 'billing' from &quot;Diagnosis Role&quot; display 'Billing'

// Condition Clinical Status Codes - Consider value sets for these
code &quot;active&quot;: 'active' from &quot;ConditionClinicalStatusCodes&quot;
code &quot;recurrence&quot;: 'recurrence' from &quot;ConditionClinicalStatusCodes&quot;
code &quot;relapse&quot;: 'relapse' from &quot;ConditionClinicalStatusCodes&quot;
code &quot;inactive&quot;: 'inactive' from &quot;ConditionClinicalStatusCodes&quot;
code &quot;remission&quot;: 'remission' from &quot;ConditionClinicalStatusCodes&quot;
code &quot;resolved&quot;: 'resolved' from &quot;ConditionClinicalStatusCodes&quot;

// Condition Verification Status Codes - Consider value sets for these
code &quot;unconfirmed&quot;: 'unconfirmed' from ConditionVerificationStatusCodes
code &quot;provisional&quot;: 'provisional' from ConditionVerificationStatusCodes
code &quot;differential&quot;: 'differential' from ConditionVerificationStatusCodes
code &quot;confirmed&quot;: 'confirmed' from ConditionVerificationStatusCodes
code &quot;refuted&quot;: 'refuted' from ConditionVerificationStatusCodes
code &quot;entered-in-error&quot;: 'entered-in-error' from ConditionVerificationStatusCodes

code &quot;allergy-active&quot;: 'active' from &quot;AllergyIntoleranceClinicalStatusCodes&quot;
code &quot;allergy-inactive&quot;: 'inactive' from &quot;AllergyIntoleranceClinicalStatusCodes&quot;
code &quot;allergy-resolved&quot;: 'resolved' from &quot;AllergyIntoleranceClinicalStatusCodes&quot;

// Allergy/Intolerance Verification Status Codes - Consider value sets for these
code &quot;allergy-unconfirmed&quot;: 'unconfirmed' from AllergyIntoleranceVerificationStatusCodes
code &quot;allergy-confirmed&quot;: 'confirmed' from AllergyIntoleranceVerificationStatusCodes
code &quot;allergy-refuted&quot;: 'refuted' from AllergyIntoleranceVerificationStatusCodes

// MedicationRequest Category Codes
code &quot;Community&quot;: 'community' from &quot;MedicationRequestCategory&quot; display 'Community'
code &quot;Discharge&quot;: 'discharge' from &quot;MedicationRequestCategory&quot; display 'Discharge'

// Diagnosis Role Codes
code &quot;AD&quot;: 'AD' from &quot;Diagnosis Role&quot; display 'Admission diagnosis'
code &quot;DD&quot;: 'DD' from &quot;Diagnosis Role&quot; display 'Discharge diagnosis'
code &quot;CC&quot;: 'CC' from &quot;Diagnosis Role&quot; display 'Chief complaint'
code &quot;CM&quot;: 'CM' from &quot;Diagnosis Role&quot; display 'Comorbidity diagnosis'
code &quot;pre-op&quot;: 'pre-op' from &quot;Diagnosis Role&quot; display 'pre-op diagnosis'
code &quot;post-op&quot;: 'post-op' from &quot;Diagnosis Role&quot; display 'post-op diagnosis'
code &quot;billing&quot;: 'billing' from &quot;Diagnosis Role&quot; display 'billing diagnosis'

context Patient

/*
@description: Normalizes a value that is a choice of timing-valued types to an equivalent interval
@comment: Normalizes a choice type of FHIR.dateTime, FHIR.Period, FHIR.Timing, FHIR.instance, FHIR.string, FHIR.Age, or FHIR.Range types
to an equivalent interval. This selection of choice types is a superset of the majority of choice types that are used as possible
representations for timing-valued elements in FHIR, allowing this function to be used across any resource. NOTE: Due to the
complexity of determining a single interval from a Timing or String type, this function will throw a run-time exception if it is used
with a Timing or String.
*/
define function ToInterval(choice Choice&lt;FHIR.dateTime, FHIR.Period, FHIR.Timing, FHIR.instant, FHIR.string, FHIR.Age, FHIR.Range&gt;):
  case
	  when choice is FHIR.dateTime then
    	Interval[FHIRHelpers.ToDateTime(choice as FHIR.dateTime), FHIRHelpers.ToDateTime(choice as FHIR.dateTime)]
		when choice is FHIR.Period then
  		FHIRHelpers.ToInterval(choice as FHIR.Period)
		when choice is FHIR.instant then
			Interval[FHIRHelpers.ToDateTime(choice as FHIR.instant), FHIRHelpers.ToDateTime(choice as FHIR.instant)]
		when choice is FHIR.Age then
		  Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(choice as FHIR.Age),
			  FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(choice as FHIR.Age) + 1 year)
		when choice is FHIR.Range then
		  Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((choice as FHIR.Range).low),
			  FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((choice as FHIR.Range).high) + 1 year)
		when choice is FHIR.Timing then
		  Message(null as Interval&lt;DateTime&gt;, true, '1', 'Error', 'Cannot compute a single interval from a Timing type')
    when choice is FHIR.string then
      Message(null as Interval&lt;DateTime&gt;, true, '1', 'Error', 'Cannot compute an interval from a String value')
		else
			null as Interval&lt;DateTime&gt;
	end

/*
@description: Returns an interval representing the normalized Abatement of a given Condition resource.
@comment: NOTE: Due to the complexity of determining an interval from a String, this function will throw
a run-time exception if used with a Condition instance that has a String as the abatement value.
*/
define function ToAbatementInterval(condition Condition):
	if condition.abatement is FHIR.dateTime then
	  Interval[FHIRHelpers.ToDateTime(condition.abatement as FHIR.dateTime), FHIRHelpers.ToDateTime(condition.abatement as FHIR.dateTime)]
	else if condition.abatement is FHIR.Period then
	  FHIRHelpers.ToInterval(condition.abatement as FHIR.Period)
	else if condition.abatement is FHIR.string then
    Message(null as Interval&lt;DateTime&gt;, true, '1', 'Error', 'Cannot compute an interval from a String value')
	else if condition.abatement is FHIR.Age then
		Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(condition.abatement as FHIR.Age),
			FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(condition.abatement as FHIR.Age) + 1 year)
	else if condition.abatement is FHIR.Range then
	  Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((condition.abatement as FHIR.Range).low),
		  FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((condition.abatement as FHIR.Range).high) + 1 year)
	else if condition.abatement is FHIR.boolean then
	  Interval[end of ToInterval(condition.onset), condition.recordedDate)
	else null

/*
@description: Returns an interval representing the normalized prevalence period of a given Condition resource.
@comment: Uses the ToInterval and ToAbatementInterval functions to determine the widest potential interval from
onset to abatement as specified in the given Condition.
*/
define function ToPrevalenceInterval(condition Condition):
if condition.clinicalStatus ~ &quot;active&quot;
  or condition.clinicalStatus ~ &quot;recurrence&quot;
  or condition.clinicalStatus ~ &quot;relapse&quot; then
  Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)]
else
  Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition))

/*
@description: Returns any extensions defined on the given resource with the specified url.
@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access
content that is defined by extensions but not yet surfaced in the
CQL model info.
*/
define function Extensions(domainResource DomainResource, url String):
  domainResource.extension E
	  where E.url = url
		return E

/*
@description: Returns the single extension (if present) on the given resource with the specified url.
@comment: This function uses singleton from to ensure that a run-time exception is thrown if there
is more than one extension on the given resource with the specified url.
*/
define function Extension(domainResource DomainResource, url String):
  singleton from &quot;Extensions&quot;(domainResource, url)

/*
@description: Returns any extensions defined on the given element with the specified url.
@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access
content that is defined by extensions but not yet surfaced in the CQL model info.
*/
define function Extensions(element Element, url String):
  element.extension E
	  where E.url = url
		return E

/*
@description: Returns the single extension (if present) on the given element with the specified url.
@comment: This function uses singleton from to ensure that a run-time exception is thrown if there
is more than one extension on the given resource with the specified url.
*/
define function Extension(element Element, url String):
  singleton from Extensions(element, url)

/*
@description: Returns any modifier extensions defined on the given resource with the specified url.
@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access
content that is defined by extensions but not yet surfaced in the
CQL model info.
*/
define function ModifierExtensions(domainResource DomainResource, url String):
  domainResource.modifierExtension E
	  where E.url = url
		return E

/*
@description: Returns the single modifier extension (if present) on the given resource with the specified url.
@comment: This function uses singleton from to ensure that a run-time exception is thrown if there
is more than one extension on the given resource with the specified url.
*/
define function ModifierExtension(domainResource DomainResource, url String):
  singleton from ModifierExtensions(domainResource, url)

/*
@description: Returns any modifier extensions defined on the given element with the specified url.
@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access
content that is defined by extensions but not yet surfaced in the CQL model info.
*/
define function ModifierExtensions(element BackboneElement, url String):
  element.modifierExtension E
	  where E.url = url
		return E

/*
@description: Returns the single modifier extension (if present) on the given element with the specified url.
@comment: This function uses singleton from to ensure that a run-time exception is thrown if there
is more than one extension on the given resource with the specified url.
*/
define function ModifierExtension(element BackboneElement, url String):
  singleton from ModifierExtensions(element, url)

/*
@description: Returns any base-FHIR extensions defined on the given resource with the specified id.
@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access
content that is defined by extensions but not yet surfaced in the CQL model info.
*/
define function BaseExtensions(domainResource DomainResource, id String):
  domainResource.extension E
	  where E.url = ('http://hl7.org/fhir/StructureDefinition/' + id)
		return E

/*
@description: Returns the single base-FHIR extension (if present) on the given resource with the specified id.
@comment: This function uses singleton from to ensure that a run-time exception is thrown if there
is more than one extension on the given resource with the specified url.
*/
define function BaseExtension(domainResource DomainResource, id String):
  singleton from BaseExtensions(domainResource, id)

/*
@description: Returns any base-FHIR extensions defined on the given element with the specified id.
@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access
content that is defined by extensions but not yet surfaced in the CQL model info.
*/
define function BaseExtensions(element Element, id String):
  element.extension E
	  where E.url = ('http://hl7.org/fhir/StructureDefinition/' + id)
		return E

/*
@description: Returns the single base-FHIR extension (if present) on the given element with the specified id.
@comment: This function uses singleton from to ensure that a run-time exception is thrown if there
is more than one extension on the given resource with the specified url.
*/
define function BaseExtension(element Element, id String):
  singleton from BaseExtensions(element, id)

/*
@description: Returns any base-FHIR modifier extensions defined on the given resource with the specified id.
@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access
content that is defined by extensions but not yet surfaced in the CQL model info.
*/
define function BaseModifierExtensions(domainResource DomainResource, id String):
  domainResource.modifierExtension E
	  where E.url = ('http://hl7.org/fhir/StructureDefinition/' + id)
		return E

/*
@description: Returns the single base-FHIR modifier extension (if present) on the given resource with the specified id.
@comment: This function uses singleton from to ensure that a run-time exception is thrown if there
is more than one extension on the given resource with the specified url.
*/
define function BaseModifierExtension(domainResource DomainResource, id String):
  singleton from BaseModifierExtensions(domainResource, id)

/*
@description: Returns any base-FHIR modifier extensions defined on the given element with the specified id.
@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access
content that is defined by extensions but not yet surfaced in the CQL model info.
*/
define function BaseModifierExtensions(element BackboneElement, id String):
  element.modifierExtension E
	  where E.url = ('http://hl7.org/fhir/StructureDefinition/' + id)
		return E

/*
@description: Returns the single base-FHIR extension (if present) on the given element with the specified id.
@comment: This function uses singleton from to ensure that a run-time exception is thrown if there
is more than one extension on the given resource with the specified url.
*/
define function BaseModifierExtension(element BackboneElement, id String):
  singleton from BaseModifierExtensions(element, id)</code></pre></div>
  </text>
  <contained>
    <Parameters>
      <id value="options"/>
      <parameter>
        <name value="translatorVersion"/>
        <valueString value="2.9.0-SNAPSHOT"/>
      </parameter>
      <parameter>
        <name value="option"/>
        <valueString value="EnableAnnotations"/>
      </parameter>
      <parameter>
        <name value="option"/>
        <valueString value="EnableLocators"/>
      </parameter>
      <parameter>
        <name value="option"/>
        <valueString value="DisableListDemotion"/>
      </parameter>
      <parameter>
        <name value="option"/>
        <valueString value="DisableListPromotion"/>
      </parameter>
      <parameter>
        <name value="format"/>
        <valueString value="XML"/>
      </parameter>
      <parameter>
        <name value="format"/>
        <valueString value="JSON"/>
      </parameter>
      <parameter>
        <name value="analyzeDataRequirements"/>
        <valueBoolean value="true"/>
      </parameter>
      <parameter>
        <name value="collapseDataRequirements"/>
        <valueBoolean value="true"/>
      </parameter>
      <parameter>
        <name value="compatibilityLevel"/>
        <valueString value="1.5"/>
      </parameter>
      <parameter>
        <name value="enableCqlOnly"/>
        <valueBoolean value="false"/>
      </parameter>
      <parameter>
        <name value="errorLevel"/>
        <valueString value="Info"/>
      </parameter>
      <parameter>
        <name value="signatureLevel"/>
        <valueString value="None"/>
      </parameter>
      <parameter>
        <name value="validateUnits"/>
        <valueBoolean value="true"/>
      </parameter>
      <parameter>
        <name value="verifyOnly"/>
        <valueBoolean value="false"/>
      </parameter>
    </Parameters>
  </contained>
  <extension url="http://hl7.org/fhir/StructureDefinition/cqf-cqlOptions">
    <valueReference>
      <reference value="#options"/>
    </valueReference>
  </extension>
  <extension
             url="http://hl7.org/fhir/StructureDefinition/structuredefinition-wg">
    <valueCode value="cds"/>
  </extension>
  <url value="http://hl7.org/fhir/uv/cql/Library/CQLExample"/>
  <version value="1.0.0-ballot"/>
  <name value="CQLExample"/>
  <title value="FHIR Common (Source CQL Example)"/>
  <status value="active"/>
  <experimental value="false"/>
  <type>
    <coding>
      <system value="http://terminology.hl7.org/CodeSystem/library-type"/>
      <code value="logic-library"/>
    </coding>
  </type>
  <date value="2022-11-16T17:19:08+00:00"/>
  <publisher value="HL7 International / Clinical Decision Support"/>
  <contact>
    <telecom>
      <system value="url"/>
      <value value="http://www.hl7.org/Special/committees/dss"/>
    </telecom>
  </contact>
  <description
               value="This library defines terminologies and functions commonly used in FHIR-based CQL artifacts.
"/>
  <jurisdiction>
    <coding>
      <system value="http://unstats.un.org/unsd/methods/m49/m49.htm"/>
      <code value="001"/>
      <display value="World"/>
    </coding>
  </jurisdiction>
  <content>
    <contentType value="text/cql"/>
    <data
          value="bGlicmFyeSBGSElSQ29tbW9uIHZlcnNpb24gJzQuMS4wMDAnDQoNCnVzaW5nIEZISVIgdmVyc2lvbiAnNC4wLjEnDQoNCmluY2x1ZGUgRkhJUkhlbHBlcnMgdmVyc2lvbiAnNC4xLjAwMCcNCg0KDQpjb2Rlc3lzdGVtICJMT0lOQyI6ICdodHRwOi8vbG9pbmMub3JnJw0KY29kZXN5c3RlbSAiU05PTUVEQ1QiOiAnaHR0cDovL3Nub21lZC5pbmZvL3NjdCcNCmNvZGVzeXN0ZW0gIlJvbGVDb2RlIjogJ2h0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vdjMtUm9sZUNvZGUnDQpjb2Rlc3lzdGVtICJEaWFnbm9zaXMgUm9sZSI6ICdodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2RpYWdub3Npcy1yb2xlJw0KY29kZXN5c3RlbSAiUmVxdWVzdEludGVudCI6ICdodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL3JlcXVlc3QtaW50ZW50Jw0KY29kZXN5c3RlbSAiTWVkaWNhdGlvblJlcXVlc3RDYXRlZ29yeSI6ICdodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL21lZGljYXRpb25yZXF1ZXN0LWNhdGVnb3J5Jw0KY29kZXN5c3RlbSAiQ29uZGl0aW9uQ2xpbmljYWxTdGF0dXNDb2RlcyI6ICdodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi1jbGluaWNhbCcNCmNvZGVzeXN0ZW0gIkNvbmRpdGlvblZlcmlmaWNhdGlvblN0YXR1c0NvZGVzIjogJ2h0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vY29uZGl0aW9uLXZlci1zdGF0dXMnDQpjb2Rlc3lzdGVtICJBbGxlcmd5SW50b2xlcmFuY2VDbGluaWNhbFN0YXR1c0NvZGVzIjogJ2h0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vYWxsZXJneWludG9sZXJhbmNlLWNsaW5pY2FsJw0KY29kZXN5c3RlbSAiQWxsZXJneUludG9sZXJhbmNlVmVyaWZpY2F0aW9uU3RhdHVzQ29kZXMiOiAnaHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9hbGxlcmd5aW50b2xlcmFuY2UtdmVyaWZpY2F0aW9uJw0KDQovL0N1cnJlbnRseSB1bnJlc29sdmVhYmxlIGluIFZTQUM6DQovL3ZhbHVlc2V0ICJBY3RpdmUgQ29uZGl0aW9uIjogJ2h0dHA6Ly9maGlyLm9yZy9ndWlkZXMvY3FmL2NvbW1vbi9WYWx1ZVNldC9hY3RpdmUtY29uZGl0aW9uJw0KLy92YWx1ZXNldCAiSW5hY3RpdmUgQ29uZGl0aW9uIjogJ2h0dHA6Ly9maGlyLm9yZy9ndWlkZXMvY3FmL2NvbW1vbi9WYWx1ZVNldC9pbmFjdGl2ZS1jb25kaXRpb24nDQoNCmNvZGUgIkJpcnRoZGF0ZSI6ICcyMTExMi04JyBmcm9tICJMT0lOQyIgZGlzcGxheSAnQmlydGggZGF0ZScNCmNvZGUgIkRlYWQiOiAnNDE5MDk5MDA5JyBmcm9tICJTTk9NRURDVCIgZGlzcGxheSAnRGVhZCcNCmNvZGUgIkVSIjogJ0VSJyBmcm9tICJSb2xlQ29kZSIgZGlzcGxheSAnRW1lcmdlbmN5IHJvb20nDQpjb2RlICJJQ1UiOiAnSUNVJyBmcm9tICJSb2xlQ29kZSIgZGlzcGxheSAnSW50ZW5zaXZlIGNhcmUgdW5pdCcNCmNvZGUgIkJpbGxpbmciOiAnYmlsbGluZycgZnJvbSAiRGlhZ25vc2lzIFJvbGUiIGRpc3BsYXkgJ0JpbGxpbmcnDQoNCi8vIENvbmRpdGlvbiBDbGluaWNhbCBTdGF0dXMgQ29kZXMgLSBDb25zaWRlciB2YWx1ZSBzZXRzIGZvciB0aGVzZQ0KY29kZSAiYWN0aXZlIjogJ2FjdGl2ZScgZnJvbSAiQ29uZGl0aW9uQ2xpbmljYWxTdGF0dXNDb2RlcyINCmNvZGUgInJlY3VycmVuY2UiOiAncmVjdXJyZW5jZScgZnJvbSAiQ29uZGl0aW9uQ2xpbmljYWxTdGF0dXNDb2RlcyINCmNvZGUgInJlbGFwc2UiOiAncmVsYXBzZScgZnJvbSAiQ29uZGl0aW9uQ2xpbmljYWxTdGF0dXNDb2RlcyINCmNvZGUgImluYWN0aXZlIjogJ2luYWN0aXZlJyBmcm9tICJDb25kaXRpb25DbGluaWNhbFN0YXR1c0NvZGVzIg0KY29kZSAicmVtaXNzaW9uIjogJ3JlbWlzc2lvbicgZnJvbSAiQ29uZGl0aW9uQ2xpbmljYWxTdGF0dXNDb2RlcyINCmNvZGUgInJlc29sdmVkIjogJ3Jlc29sdmVkJyBmcm9tICJDb25kaXRpb25DbGluaWNhbFN0YXR1c0NvZGVzIg0KDQovLyBDb25kaXRpb24gVmVyaWZpY2F0aW9uIFN0YXR1cyBDb2RlcyAtIENvbnNpZGVyIHZhbHVlIHNldHMgZm9yIHRoZXNlDQpjb2RlICJ1bmNvbmZpcm1lZCI6ICd1bmNvbmZpcm1lZCcgZnJvbSBDb25kaXRpb25WZXJpZmljYXRpb25TdGF0dXNDb2Rlcw0KY29kZSAicHJvdmlzaW9uYWwiOiAncHJvdmlzaW9uYWwnIGZyb20gQ29uZGl0aW9uVmVyaWZpY2F0aW9uU3RhdHVzQ29kZXMNCmNvZGUgImRpZmZlcmVudGlhbCI6ICdkaWZmZXJlbnRpYWwnIGZyb20gQ29uZGl0aW9uVmVyaWZpY2F0aW9uU3RhdHVzQ29kZXMNCmNvZGUgImNvbmZpcm1lZCI6ICdjb25maXJtZWQnIGZyb20gQ29uZGl0aW9uVmVyaWZpY2F0aW9uU3RhdHVzQ29kZXMNCmNvZGUgInJlZnV0ZWQiOiAncmVmdXRlZCcgZnJvbSBDb25kaXRpb25WZXJpZmljYXRpb25TdGF0dXNDb2Rlcw0KY29kZSAiZW50ZXJlZC1pbi1lcnJvciI6ICdlbnRlcmVkLWluLWVycm9yJyBmcm9tIENvbmRpdGlvblZlcmlmaWNhdGlvblN0YXR1c0NvZGVzDQoNCmNvZGUgImFsbGVyZ3ktYWN0aXZlIjogJ2FjdGl2ZScgZnJvbSAiQWxsZXJneUludG9sZXJhbmNlQ2xpbmljYWxTdGF0dXNDb2RlcyINCmNvZGUgImFsbGVyZ3ktaW5hY3RpdmUiOiAnaW5hY3RpdmUnIGZyb20gIkFsbGVyZ3lJbnRvbGVyYW5jZUNsaW5pY2FsU3RhdHVzQ29kZXMiDQpjb2RlICJhbGxlcmd5LXJlc29sdmVkIjogJ3Jlc29sdmVkJyBmcm9tICJBbGxlcmd5SW50b2xlcmFuY2VDbGluaWNhbFN0YXR1c0NvZGVzIg0KDQovLyBBbGxlcmd5L0ludG9sZXJhbmNlIFZlcmlmaWNhdGlvbiBTdGF0dXMgQ29kZXMgLSBDb25zaWRlciB2YWx1ZSBzZXRzIGZvciB0aGVzZQ0KY29kZSAiYWxsZXJneS11bmNvbmZpcm1lZCI6ICd1bmNvbmZpcm1lZCcgZnJvbSBBbGxlcmd5SW50b2xlcmFuY2VWZXJpZmljYXRpb25TdGF0dXNDb2Rlcw0KY29kZSAiYWxsZXJneS1jb25maXJtZWQiOiAnY29uZmlybWVkJyBmcm9tIEFsbGVyZ3lJbnRvbGVyYW5jZVZlcmlmaWNhdGlvblN0YXR1c0NvZGVzDQpjb2RlICJhbGxlcmd5LXJlZnV0ZWQiOiAncmVmdXRlZCcgZnJvbSBBbGxlcmd5SW50b2xlcmFuY2VWZXJpZmljYXRpb25TdGF0dXNDb2Rlcw0KDQovLyBNZWRpY2F0aW9uUmVxdWVzdCBDYXRlZ29yeSBDb2Rlcw0KY29kZSAiQ29tbXVuaXR5IjogJ2NvbW11bml0eScgZnJvbSAiTWVkaWNhdGlvblJlcXVlc3RDYXRlZ29yeSIgZGlzcGxheSAnQ29tbXVuaXR5Jw0KY29kZSAiRGlzY2hhcmdlIjogJ2Rpc2NoYXJnZScgZnJvbSAiTWVkaWNhdGlvblJlcXVlc3RDYXRlZ29yeSIgZGlzcGxheSAnRGlzY2hhcmdlJw0KDQovLyBEaWFnbm9zaXMgUm9sZSBDb2Rlcw0KY29kZSAiQUQiOiAnQUQnIGZyb20gIkRpYWdub3NpcyBSb2xlIiBkaXNwbGF5ICdBZG1pc3Npb24gZGlhZ25vc2lzJw0KY29kZSAiREQiOiAnREQnIGZyb20gIkRpYWdub3NpcyBSb2xlIiBkaXNwbGF5ICdEaXNjaGFyZ2UgZGlhZ25vc2lzJw0KY29kZSAiQ0MiOiAnQ0MnIGZyb20gIkRpYWdub3NpcyBSb2xlIiBkaXNwbGF5ICdDaGllZiBjb21wbGFpbnQnDQpjb2RlICJDTSI6ICdDTScgZnJvbSAiRGlhZ25vc2lzIFJvbGUiIGRpc3BsYXkgJ0NvbW9yYmlkaXR5IGRpYWdub3NpcycNCmNvZGUgInByZS1vcCI6ICdwcmUtb3AnIGZyb20gIkRpYWdub3NpcyBSb2xlIiBkaXNwbGF5ICdwcmUtb3AgZGlhZ25vc2lzJw0KY29kZSAicG9zdC1vcCI6ICdwb3N0LW9wJyBmcm9tICJEaWFnbm9zaXMgUm9sZSIgZGlzcGxheSAncG9zdC1vcCBkaWFnbm9zaXMnDQpjb2RlICJiaWxsaW5nIjogJ2JpbGxpbmcnIGZyb20gIkRpYWdub3NpcyBSb2xlIiBkaXNwbGF5ICdiaWxsaW5nIGRpYWdub3NpcycNCg0KY29udGV4dCBQYXRpZW50DQoNCi8qDQpAZGVzY3JpcHRpb246IE5vcm1hbGl6ZXMgYSB2YWx1ZSB0aGF0IGlzIGEgY2hvaWNlIG9mIHRpbWluZy12YWx1ZWQgdHlwZXMgdG8gYW4gZXF1aXZhbGVudCBpbnRlcnZhbA0KQGNvbW1lbnQ6IE5vcm1hbGl6ZXMgYSBjaG9pY2UgdHlwZSBvZiBGSElSLmRhdGVUaW1lLCBGSElSLlBlcmlvZCwgRkhJUi5UaW1pbmcsIEZISVIuaW5zdGFuY2UsIEZISVIuc3RyaW5nLCBGSElSLkFnZSwgb3IgRkhJUi5SYW5nZSB0eXBlcw0KdG8gYW4gZXF1aXZhbGVudCBpbnRlcnZhbC4gVGhpcyBzZWxlY3Rpb24gb2YgY2hvaWNlIHR5cGVzIGlzIGEgc3VwZXJzZXQgb2YgdGhlIG1ham9yaXR5IG9mIGNob2ljZSB0eXBlcyB0aGF0IGFyZSB1c2VkIGFzIHBvc3NpYmxlDQpyZXByZXNlbnRhdGlvbnMgZm9yIHRpbWluZy12YWx1ZWQgZWxlbWVudHMgaW4gRkhJUiwgYWxsb3dpbmcgdGhpcyBmdW5jdGlvbiB0byBiZSB1c2VkIGFjcm9zcyBhbnkgcmVzb3VyY2UuIE5PVEU6IER1ZSB0byB0aGUNCmNvbXBsZXhpdHkgb2YgZGV0ZXJtaW5pbmcgYSBzaW5nbGUgaW50ZXJ2YWwgZnJvbSBhIFRpbWluZyBvciBTdHJpbmcgdHlwZSwgdGhpcyBmdW5jdGlvbiB3aWxsIHRocm93IGEgcnVuLXRpbWUgZXhjZXB0aW9uIGlmIGl0IGlzIHVzZWQNCndpdGggYSBUaW1pbmcgb3IgU3RyaW5nLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBUb0ludGVydmFsKGNob2ljZSBDaG9pY2U8RkhJUi5kYXRlVGltZSwgRkhJUi5QZXJpb2QsIEZISVIuVGltaW5nLCBGSElSLmluc3RhbnQsIEZISVIuc3RyaW5nLCBGSElSLkFnZSwgRkhJUi5SYW5nZT4pOg0KICBjYXNlDQoJICB3aGVuIGNob2ljZSBpcyBGSElSLmRhdGVUaW1lIHRoZW4NCiAgICAJSW50ZXJ2YWxbRkhJUkhlbHBlcnMuVG9EYXRlVGltZShjaG9pY2UgYXMgRkhJUi5kYXRlVGltZSksIEZISVJIZWxwZXJzLlRvRGF0ZVRpbWUoY2hvaWNlIGFzIEZISVIuZGF0ZVRpbWUpXQ0KCQl3aGVuIGNob2ljZSBpcyBGSElSLlBlcmlvZCB0aGVuDQogIAkJRkhJUkhlbHBlcnMuVG9JbnRlcnZhbChjaG9pY2UgYXMgRkhJUi5QZXJpb2QpDQoJCXdoZW4gY2hvaWNlIGlzIEZISVIuaW5zdGFudCB0aGVuDQoJCQlJbnRlcnZhbFtGSElSSGVscGVycy5Ub0RhdGVUaW1lKGNob2ljZSBhcyBGSElSLmluc3RhbnQpLCBGSElSSGVscGVycy5Ub0RhdGVUaW1lKGNob2ljZSBhcyBGSElSLmluc3RhbnQpXQ0KCQl3aGVuIGNob2ljZSBpcyBGSElSLkFnZSB0aGVuDQoJCSAgSW50ZXJ2YWxbRkhJUkhlbHBlcnMuVG9EYXRlKFBhdGllbnQuYmlydGhEYXRlKSArIEZISVJIZWxwZXJzLlRvUXVhbnRpdHkoY2hvaWNlIGFzIEZISVIuQWdlKSwNCgkJCSAgRkhJUkhlbHBlcnMuVG9EYXRlKFBhdGllbnQuYmlydGhEYXRlKSArIEZISVJIZWxwZXJzLlRvUXVhbnRpdHkoY2hvaWNlIGFzIEZISVIuQWdlKSArIDEgeWVhcikNCgkJd2hlbiBjaG9pY2UgaXMgRkhJUi5SYW5nZSB0aGVuDQoJCSAgSW50ZXJ2YWxbRkhJUkhlbHBlcnMuVG9EYXRlKFBhdGllbnQuYmlydGhEYXRlKSArIEZISVJIZWxwZXJzLlRvUXVhbnRpdHkoKGNob2ljZSBhcyBGSElSLlJhbmdlKS5sb3cpLA0KCQkJICBGSElSSGVscGVycy5Ub0RhdGUoUGF0aWVudC5iaXJ0aERhdGUpICsgRkhJUkhlbHBlcnMuVG9RdWFudGl0eSgoY2hvaWNlIGFzIEZISVIuUmFuZ2UpLmhpZ2gpICsgMSB5ZWFyKQ0KCQl3aGVuIGNob2ljZSBpcyBGSElSLlRpbWluZyB0aGVuDQoJCSAgTWVzc2FnZShudWxsIGFzIEludGVydmFsPERhdGVUaW1lPiwgdHJ1ZSwgJzEnLCAnRXJyb3InLCAnQ2Fubm90IGNvbXB1dGUgYSBzaW5nbGUgaW50ZXJ2YWwgZnJvbSBhIFRpbWluZyB0eXBlJykNCiAgICB3aGVuIGNob2ljZSBpcyBGSElSLnN0cmluZyB0aGVuDQogICAgICBNZXNzYWdlKG51bGwgYXMgSW50ZXJ2YWw8RGF0ZVRpbWU+LCB0cnVlLCAnMScsICdFcnJvcicsICdDYW5ub3QgY29tcHV0ZSBhbiBpbnRlcnZhbCBmcm9tIGEgU3RyaW5nIHZhbHVlJykNCgkJZWxzZQ0KCQkJbnVsbCBhcyBJbnRlcnZhbDxEYXRlVGltZT4NCgllbmQNCg0KLyoNCkBkZXNjcmlwdGlvbjogUmV0dXJucyBhbiBpbnRlcnZhbCByZXByZXNlbnRpbmcgdGhlIG5vcm1hbGl6ZWQgQWJhdGVtZW50IG9mIGEgZ2l2ZW4gQ29uZGl0aW9uIHJlc291cmNlLg0KQGNvbW1lbnQ6IE5PVEU6IER1ZSB0byB0aGUgY29tcGxleGl0eSBvZiBkZXRlcm1pbmluZyBhbiBpbnRlcnZhbCBmcm9tIGEgU3RyaW5nLCB0aGlzIGZ1bmN0aW9uIHdpbGwgdGhyb3cNCmEgcnVuLXRpbWUgZXhjZXB0aW9uIGlmIHVzZWQgd2l0aCBhIENvbmRpdGlvbiBpbnN0YW5jZSB0aGF0IGhhcyBhIFN0cmluZyBhcyB0aGUgYWJhdGVtZW50IHZhbHVlLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBUb0FiYXRlbWVudEludGVydmFsKGNvbmRpdGlvbiBDb25kaXRpb24pOg0KCWlmIGNvbmRpdGlvbi5hYmF0ZW1lbnQgaXMgRkhJUi5kYXRlVGltZSB0aGVuDQoJICBJbnRlcnZhbFtGSElSSGVscGVycy5Ub0RhdGVUaW1lKGNvbmRpdGlvbi5hYmF0ZW1lbnQgYXMgRkhJUi5kYXRlVGltZSksIEZISVJIZWxwZXJzLlRvRGF0ZVRpbWUoY29uZGl0aW9uLmFiYXRlbWVudCBhcyBGSElSLmRhdGVUaW1lKV0NCgllbHNlIGlmIGNvbmRpdGlvbi5hYmF0ZW1lbnQgaXMgRkhJUi5QZXJpb2QgdGhlbg0KCSAgRkhJUkhlbHBlcnMuVG9JbnRlcnZhbChjb25kaXRpb24uYWJhdGVtZW50IGFzIEZISVIuUGVyaW9kKQ0KCWVsc2UgaWYgY29uZGl0aW9uLmFiYXRlbWVudCBpcyBGSElSLnN0cmluZyB0aGVuDQogICAgTWVzc2FnZShudWxsIGFzIEludGVydmFsPERhdGVUaW1lPiwgdHJ1ZSwgJzEnLCAnRXJyb3InLCAnQ2Fubm90IGNvbXB1dGUgYW4gaW50ZXJ2YWwgZnJvbSBhIFN0cmluZyB2YWx1ZScpDQoJZWxzZSBpZiBjb25kaXRpb24uYWJhdGVtZW50IGlzIEZISVIuQWdlIHRoZW4NCgkJSW50ZXJ2YWxbRkhJUkhlbHBlcnMuVG9EYXRlKFBhdGllbnQuYmlydGhEYXRlKSArIEZISVJIZWxwZXJzLlRvUXVhbnRpdHkoY29uZGl0aW9uLmFiYXRlbWVudCBhcyBGSElSLkFnZSksDQoJCQlGSElSSGVscGVycy5Ub0RhdGUoUGF0aWVudC5iaXJ0aERhdGUpICsgRkhJUkhlbHBlcnMuVG9RdWFudGl0eShjb25kaXRpb24uYWJhdGVtZW50IGFzIEZISVIuQWdlKSArIDEgeWVhcikNCgllbHNlIGlmIGNvbmRpdGlvbi5hYmF0ZW1lbnQgaXMgRkhJUi5SYW5nZSB0aGVuDQoJICBJbnRlcnZhbFtGSElSSGVscGVycy5Ub0RhdGUoUGF0aWVudC5iaXJ0aERhdGUpICsgRkhJUkhlbHBlcnMuVG9RdWFudGl0eSgoY29uZGl0aW9uLmFiYXRlbWVudCBhcyBGSElSLlJhbmdlKS5sb3cpLA0KCQkgIEZISVJIZWxwZXJzLlRvRGF0ZShQYXRpZW50LmJpcnRoRGF0ZSkgKyBGSElSSGVscGVycy5Ub1F1YW50aXR5KChjb25kaXRpb24uYWJhdGVtZW50IGFzIEZISVIuUmFuZ2UpLmhpZ2gpICsgMSB5ZWFyKQ0KCWVsc2UgaWYgY29uZGl0aW9uLmFiYXRlbWVudCBpcyBGSElSLmJvb2xlYW4gdGhlbg0KCSAgSW50ZXJ2YWxbZW5kIG9mIFRvSW50ZXJ2YWwoY29uZGl0aW9uLm9uc2V0KSwgY29uZGl0aW9uLnJlY29yZGVkRGF0ZSkNCgllbHNlIG51bGwNCg0KLyoNCkBkZXNjcmlwdGlvbjogUmV0dXJucyBhbiBpbnRlcnZhbCByZXByZXNlbnRpbmcgdGhlIG5vcm1hbGl6ZWQgcHJldmFsZW5jZSBwZXJpb2Qgb2YgYSBnaXZlbiBDb25kaXRpb24gcmVzb3VyY2UuDQpAY29tbWVudDogVXNlcyB0aGUgVG9JbnRlcnZhbCBhbmQgVG9BYmF0ZW1lbnRJbnRlcnZhbCBmdW5jdGlvbnMgdG8gZGV0ZXJtaW5lIHRoZSB3aWRlc3QgcG90ZW50aWFsIGludGVydmFsIGZyb20NCm9uc2V0IHRvIGFiYXRlbWVudCBhcyBzcGVjaWZpZWQgaW4gdGhlIGdpdmVuIENvbmRpdGlvbi4NCiovDQpkZWZpbmUgZnVuY3Rpb24gVG9QcmV2YWxlbmNlSW50ZXJ2YWwoY29uZGl0aW9uIENvbmRpdGlvbik6DQppZiBjb25kaXRpb24uY2xpbmljYWxTdGF0dXMgfiAiYWN0aXZlIg0KICBvciBjb25kaXRpb24uY2xpbmljYWxTdGF0dXMgfiAicmVjdXJyZW5jZSINCiAgb3IgY29uZGl0aW9uLmNsaW5pY2FsU3RhdHVzIH4gInJlbGFwc2UiIHRoZW4NCiAgSW50ZXJ2YWxbc3RhcnQgb2YgVG9JbnRlcnZhbChjb25kaXRpb24ub25zZXQpLCBlbmQgb2YgVG9BYmF0ZW1lbnRJbnRlcnZhbChjb25kaXRpb24pXQ0KZWxzZQ0KICBJbnRlcnZhbFtzdGFydCBvZiBUb0ludGVydmFsKGNvbmRpdGlvbi5vbnNldCksIGVuZCBvZiBUb0FiYXRlbWVudEludGVydmFsKGNvbmRpdGlvbikpDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgYW55IGV4dGVuc2lvbnMgZGVmaW5lZCBvbiB0aGUgZ2l2ZW4gcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHVybC4NCkBjb21tZW50OiBOT1RFOiBFeHRlbnNpb25zIGFyZSBub3QgdGhlIHByZWZlcnJlZCBhcHByb2FjaCwgYnV0IGFyZSB1c2VkIGFzIGEgd2F5IHRvIGFjY2Vzcw0KY29udGVudCB0aGF0IGlzIGRlZmluZWQgYnkgZXh0ZW5zaW9ucyBidXQgbm90IHlldCBzdXJmYWNlZCBpbiB0aGUNCkNRTCBtb2RlbCBpbmZvLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBFeHRlbnNpb25zKGRvbWFpblJlc291cmNlIERvbWFpblJlc291cmNlLCB1cmwgU3RyaW5nKToNCiAgZG9tYWluUmVzb3VyY2UuZXh0ZW5zaW9uIEUNCgkgIHdoZXJlIEUudXJsID0gdXJsDQoJCXJldHVybiBFDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgdGhlIHNpbmdsZSBleHRlbnNpb24gKGlmIHByZXNlbnQpIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgdXJsLg0KQGNvbW1lbnQ6IFRoaXMgZnVuY3Rpb24gdXNlcyBzaW5nbGV0b24gZnJvbSB0byBlbnN1cmUgdGhhdCBhIHJ1bi10aW1lIGV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgdGhlcmUNCmlzIG1vcmUgdGhhbiBvbmUgZXh0ZW5zaW9uIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgdXJsLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBFeHRlbnNpb24oZG9tYWluUmVzb3VyY2UgRG9tYWluUmVzb3VyY2UsIHVybCBTdHJpbmcpOg0KICBzaW5nbGV0b24gZnJvbSAiRXh0ZW5zaW9ucyIoZG9tYWluUmVzb3VyY2UsIHVybCkNCg0KLyoNCkBkZXNjcmlwdGlvbjogUmV0dXJucyBhbnkgZXh0ZW5zaW9ucyBkZWZpbmVkIG9uIHRoZSBnaXZlbiBlbGVtZW50IHdpdGggdGhlIHNwZWNpZmllZCB1cmwuDQpAY29tbWVudDogTk9URTogRXh0ZW5zaW9ucyBhcmUgbm90IHRoZSBwcmVmZXJyZWQgYXBwcm9hY2gsIGJ1dCBhcmUgdXNlZCBhcyBhIHdheSB0byBhY2Nlc3MNCmNvbnRlbnQgdGhhdCBpcyBkZWZpbmVkIGJ5IGV4dGVuc2lvbnMgYnV0IG5vdCB5ZXQgc3VyZmFjZWQgaW4gdGhlIENRTCBtb2RlbCBpbmZvLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBFeHRlbnNpb25zKGVsZW1lbnQgRWxlbWVudCwgdXJsIFN0cmluZyk6DQogIGVsZW1lbnQuZXh0ZW5zaW9uIEUNCgkgIHdoZXJlIEUudXJsID0gdXJsDQoJCXJldHVybiBFDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgdGhlIHNpbmdsZSBleHRlbnNpb24gKGlmIHByZXNlbnQpIG9uIHRoZSBnaXZlbiBlbGVtZW50IHdpdGggdGhlIHNwZWNpZmllZCB1cmwuDQpAY29tbWVudDogVGhpcyBmdW5jdGlvbiB1c2VzIHNpbmdsZXRvbiBmcm9tIHRvIGVuc3VyZSB0aGF0IGEgcnVuLXRpbWUgZXhjZXB0aW9uIGlzIHRocm93biBpZiB0aGVyZQ0KaXMgbW9yZSB0aGFuIG9uZSBleHRlbnNpb24gb24gdGhlIGdpdmVuIHJlc291cmNlIHdpdGggdGhlIHNwZWNpZmllZCB1cmwuDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIEV4dGVuc2lvbihlbGVtZW50IEVsZW1lbnQsIHVybCBTdHJpbmcpOg0KICBzaW5nbGV0b24gZnJvbSBFeHRlbnNpb25zKGVsZW1lbnQsIHVybCkNCg0KLyoNCkBkZXNjcmlwdGlvbjogUmV0dXJucyBhbnkgbW9kaWZpZXIgZXh0ZW5zaW9ucyBkZWZpbmVkIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgdXJsLg0KQGNvbW1lbnQ6IE5PVEU6IEV4dGVuc2lvbnMgYXJlIG5vdCB0aGUgcHJlZmVycmVkIGFwcHJvYWNoLCBidXQgYXJlIHVzZWQgYXMgYSB3YXkgdG8gYWNjZXNzDQpjb250ZW50IHRoYXQgaXMgZGVmaW5lZCBieSBleHRlbnNpb25zIGJ1dCBub3QgeWV0IHN1cmZhY2VkIGluIHRoZQ0KQ1FMIG1vZGVsIGluZm8uDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIE1vZGlmaWVyRXh0ZW5zaW9ucyhkb21haW5SZXNvdXJjZSBEb21haW5SZXNvdXJjZSwgdXJsIFN0cmluZyk6DQogIGRvbWFpblJlc291cmNlLm1vZGlmaWVyRXh0ZW5zaW9uIEUNCgkgIHdoZXJlIEUudXJsID0gdXJsDQoJCXJldHVybiBFDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgdGhlIHNpbmdsZSBtb2RpZmllciBleHRlbnNpb24gKGlmIHByZXNlbnQpIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgdXJsLg0KQGNvbW1lbnQ6IFRoaXMgZnVuY3Rpb24gdXNlcyBzaW5nbGV0b24gZnJvbSB0byBlbnN1cmUgdGhhdCBhIHJ1bi10aW1lIGV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgdGhlcmUNCmlzIG1vcmUgdGhhbiBvbmUgZXh0ZW5zaW9uIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgdXJsLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBNb2RpZmllckV4dGVuc2lvbihkb21haW5SZXNvdXJjZSBEb21haW5SZXNvdXJjZSwgdXJsIFN0cmluZyk6DQogIHNpbmdsZXRvbiBmcm9tIE1vZGlmaWVyRXh0ZW5zaW9ucyhkb21haW5SZXNvdXJjZSwgdXJsKQ0KDQovKg0KQGRlc2NyaXB0aW9uOiBSZXR1cm5zIGFueSBtb2RpZmllciBleHRlbnNpb25zIGRlZmluZWQgb24gdGhlIGdpdmVuIGVsZW1lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIHVybC4NCkBjb21tZW50OiBOT1RFOiBFeHRlbnNpb25zIGFyZSBub3QgdGhlIHByZWZlcnJlZCBhcHByb2FjaCwgYnV0IGFyZSB1c2VkIGFzIGEgd2F5IHRvIGFjY2Vzcw0KY29udGVudCB0aGF0IGlzIGRlZmluZWQgYnkgZXh0ZW5zaW9ucyBidXQgbm90IHlldCBzdXJmYWNlZCBpbiB0aGUgQ1FMIG1vZGVsIGluZm8uDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIE1vZGlmaWVyRXh0ZW5zaW9ucyhlbGVtZW50IEJhY2tib25lRWxlbWVudCwgdXJsIFN0cmluZyk6DQogIGVsZW1lbnQubW9kaWZpZXJFeHRlbnNpb24gRQ0KCSAgd2hlcmUgRS51cmwgPSB1cmwNCgkJcmV0dXJuIEUNCg0KLyoNCkBkZXNjcmlwdGlvbjogUmV0dXJucyB0aGUgc2luZ2xlIG1vZGlmaWVyIGV4dGVuc2lvbiAoaWYgcHJlc2VudCkgb24gdGhlIGdpdmVuIGVsZW1lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIHVybC4NCkBjb21tZW50OiBUaGlzIGZ1bmN0aW9uIHVzZXMgc2luZ2xldG9uIGZyb20gdG8gZW5zdXJlIHRoYXQgYSBydW4tdGltZSBleGNlcHRpb24gaXMgdGhyb3duIGlmIHRoZXJlDQppcyBtb3JlIHRoYW4gb25lIGV4dGVuc2lvbiBvbiB0aGUgZ2l2ZW4gcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHVybC4NCiovDQpkZWZpbmUgZnVuY3Rpb24gTW9kaWZpZXJFeHRlbnNpb24oZWxlbWVudCBCYWNrYm9uZUVsZW1lbnQsIHVybCBTdHJpbmcpOg0KICBzaW5nbGV0b24gZnJvbSBNb2RpZmllckV4dGVuc2lvbnMoZWxlbWVudCwgdXJsKQ0KDQovKg0KQGRlc2NyaXB0aW9uOiBSZXR1cm5zIGFueSBiYXNlLUZISVIgZXh0ZW5zaW9ucyBkZWZpbmVkIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgaWQuDQpAY29tbWVudDogTk9URTogRXh0ZW5zaW9ucyBhcmUgbm90IHRoZSBwcmVmZXJyZWQgYXBwcm9hY2gsIGJ1dCBhcmUgdXNlZCBhcyBhIHdheSB0byBhY2Nlc3MNCmNvbnRlbnQgdGhhdCBpcyBkZWZpbmVkIGJ5IGV4dGVuc2lvbnMgYnV0IG5vdCB5ZXQgc3VyZmFjZWQgaW4gdGhlIENRTCBtb2RlbCBpbmZvLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBCYXNlRXh0ZW5zaW9ucyhkb21haW5SZXNvdXJjZSBEb21haW5SZXNvdXJjZSwgaWQgU3RyaW5nKToNCiAgZG9tYWluUmVzb3VyY2UuZXh0ZW5zaW9uIEUNCgkgIHdoZXJlIEUudXJsID0gKCdodHRwOi8vaGw3Lm9yZy9maGlyL1N0cnVjdHVyZURlZmluaXRpb24vJyArIGlkKQ0KCQlyZXR1cm4gRQ0KDQovKg0KQGRlc2NyaXB0aW9uOiBSZXR1cm5zIHRoZSBzaW5nbGUgYmFzZS1GSElSIGV4dGVuc2lvbiAoaWYgcHJlc2VudCkgb24gdGhlIGdpdmVuIHJlc291cmNlIHdpdGggdGhlIHNwZWNpZmllZCBpZC4NCkBjb21tZW50OiBUaGlzIGZ1bmN0aW9uIHVzZXMgc2luZ2xldG9uIGZyb20gdG8gZW5zdXJlIHRoYXQgYSBydW4tdGltZSBleGNlcHRpb24gaXMgdGhyb3duIGlmIHRoZXJlDQppcyBtb3JlIHRoYW4gb25lIGV4dGVuc2lvbiBvbiB0aGUgZ2l2ZW4gcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHVybC4NCiovDQpkZWZpbmUgZnVuY3Rpb24gQmFzZUV4dGVuc2lvbihkb21haW5SZXNvdXJjZSBEb21haW5SZXNvdXJjZSwgaWQgU3RyaW5nKToNCiAgc2luZ2xldG9uIGZyb20gQmFzZUV4dGVuc2lvbnMoZG9tYWluUmVzb3VyY2UsIGlkKQ0KDQovKg0KQGRlc2NyaXB0aW9uOiBSZXR1cm5zIGFueSBiYXNlLUZISVIgZXh0ZW5zaW9ucyBkZWZpbmVkIG9uIHRoZSBnaXZlbiBlbGVtZW50IHdpdGggdGhlIHNwZWNpZmllZCBpZC4NCkBjb21tZW50OiBOT1RFOiBFeHRlbnNpb25zIGFyZSBub3QgdGhlIHByZWZlcnJlZCBhcHByb2FjaCwgYnV0IGFyZSB1c2VkIGFzIGEgd2F5IHRvIGFjY2Vzcw0KY29udGVudCB0aGF0IGlzIGRlZmluZWQgYnkgZXh0ZW5zaW9ucyBidXQgbm90IHlldCBzdXJmYWNlZCBpbiB0aGUgQ1FMIG1vZGVsIGluZm8uDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIEJhc2VFeHRlbnNpb25zKGVsZW1lbnQgRWxlbWVudCwgaWQgU3RyaW5nKToNCiAgZWxlbWVudC5leHRlbnNpb24gRQ0KCSAgd2hlcmUgRS51cmwgPSAoJ2h0dHA6Ly9obDcub3JnL2ZoaXIvU3RydWN0dXJlRGVmaW5pdGlvbi8nICsgaWQpDQoJCXJldHVybiBFDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgdGhlIHNpbmdsZSBiYXNlLUZISVIgZXh0ZW5zaW9uIChpZiBwcmVzZW50KSBvbiB0aGUgZ2l2ZW4gZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgaWQuDQpAY29tbWVudDogVGhpcyBmdW5jdGlvbiB1c2VzIHNpbmdsZXRvbiBmcm9tIHRvIGVuc3VyZSB0aGF0IGEgcnVuLXRpbWUgZXhjZXB0aW9uIGlzIHRocm93biBpZiB0aGVyZQ0KaXMgbW9yZSB0aGFuIG9uZSBleHRlbnNpb24gb24gdGhlIGdpdmVuIHJlc291cmNlIHdpdGggdGhlIHNwZWNpZmllZCB1cmwuDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIEJhc2VFeHRlbnNpb24oZWxlbWVudCBFbGVtZW50LCBpZCBTdHJpbmcpOg0KICBzaW5nbGV0b24gZnJvbSBCYXNlRXh0ZW5zaW9ucyhlbGVtZW50LCBpZCkNCg0KLyoNCkBkZXNjcmlwdGlvbjogUmV0dXJucyBhbnkgYmFzZS1GSElSIG1vZGlmaWVyIGV4dGVuc2lvbnMgZGVmaW5lZCBvbiB0aGUgZ2l2ZW4gcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGlkLg0KQGNvbW1lbnQ6IE5PVEU6IEV4dGVuc2lvbnMgYXJlIG5vdCB0aGUgcHJlZmVycmVkIGFwcHJvYWNoLCBidXQgYXJlIHVzZWQgYXMgYSB3YXkgdG8gYWNjZXNzDQpjb250ZW50IHRoYXQgaXMgZGVmaW5lZCBieSBleHRlbnNpb25zIGJ1dCBub3QgeWV0IHN1cmZhY2VkIGluIHRoZSBDUUwgbW9kZWwgaW5mby4NCiovDQpkZWZpbmUgZnVuY3Rpb24gQmFzZU1vZGlmaWVyRXh0ZW5zaW9ucyhkb21haW5SZXNvdXJjZSBEb21haW5SZXNvdXJjZSwgaWQgU3RyaW5nKToNCiAgZG9tYWluUmVzb3VyY2UubW9kaWZpZXJFeHRlbnNpb24gRQ0KCSAgd2hlcmUgRS51cmwgPSAoJ2h0dHA6Ly9obDcub3JnL2ZoaXIvU3RydWN0dXJlRGVmaW5pdGlvbi8nICsgaWQpDQoJCXJldHVybiBFDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgdGhlIHNpbmdsZSBiYXNlLUZISVIgbW9kaWZpZXIgZXh0ZW5zaW9uIChpZiBwcmVzZW50KSBvbiB0aGUgZ2l2ZW4gcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGlkLg0KQGNvbW1lbnQ6IFRoaXMgZnVuY3Rpb24gdXNlcyBzaW5nbGV0b24gZnJvbSB0byBlbnN1cmUgdGhhdCBhIHJ1bi10aW1lIGV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgdGhlcmUNCmlzIG1vcmUgdGhhbiBvbmUgZXh0ZW5zaW9uIG9uIHRoZSBnaXZlbiByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgdXJsLg0KKi8NCmRlZmluZSBmdW5jdGlvbiBCYXNlTW9kaWZpZXJFeHRlbnNpb24oZG9tYWluUmVzb3VyY2UgRG9tYWluUmVzb3VyY2UsIGlkIFN0cmluZyk6DQogIHNpbmdsZXRvbiBmcm9tIEJhc2VNb2RpZmllckV4dGVuc2lvbnMoZG9tYWluUmVzb3VyY2UsIGlkKQ0KDQovKg0KQGRlc2NyaXB0aW9uOiBSZXR1cm5zIGFueSBiYXNlLUZISVIgbW9kaWZpZXIgZXh0ZW5zaW9ucyBkZWZpbmVkIG9uIHRoZSBnaXZlbiBlbGVtZW50IHdpdGggdGhlIHNwZWNpZmllZCBpZC4NCkBjb21tZW50OiBOT1RFOiBFeHRlbnNpb25zIGFyZSBub3QgdGhlIHByZWZlcnJlZCBhcHByb2FjaCwgYnV0IGFyZSB1c2VkIGFzIGEgd2F5IHRvIGFjY2Vzcw0KY29udGVudCB0aGF0IGlzIGRlZmluZWQgYnkgZXh0ZW5zaW9ucyBidXQgbm90IHlldCBzdXJmYWNlZCBpbiB0aGUgQ1FMIG1vZGVsIGluZm8uDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIEJhc2VNb2RpZmllckV4dGVuc2lvbnMoZWxlbWVudCBCYWNrYm9uZUVsZW1lbnQsIGlkIFN0cmluZyk6DQogIGVsZW1lbnQubW9kaWZpZXJFeHRlbnNpb24gRQ0KCSAgd2hlcmUgRS51cmwgPSAoJ2h0dHA6Ly9obDcub3JnL2ZoaXIvU3RydWN0dXJlRGVmaW5pdGlvbi8nICsgaWQpDQoJCXJldHVybiBFDQoNCi8qDQpAZGVzY3JpcHRpb246IFJldHVybnMgdGhlIHNpbmdsZSBiYXNlLUZISVIgZXh0ZW5zaW9uIChpZiBwcmVzZW50KSBvbiB0aGUgZ2l2ZW4gZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgaWQuDQpAY29tbWVudDogVGhpcyBmdW5jdGlvbiB1c2VzIHNpbmdsZXRvbiBmcm9tIHRvIGVuc3VyZSB0aGF0IGEgcnVuLXRpbWUgZXhjZXB0aW9uIGlzIHRocm93biBpZiB0aGVyZQ0KaXMgbW9yZSB0aGFuIG9uZSBleHRlbnNpb24gb24gdGhlIGdpdmVuIHJlc291cmNlIHdpdGggdGhlIHNwZWNpZmllZCB1cmwuDQoqLw0KZGVmaW5lIGZ1bmN0aW9uIEJhc2VNb2RpZmllckV4dGVuc2lvbihlbGVtZW50IEJhY2tib25lRWxlbWVudCwgaWQgU3RyaW5nKToNCiAgc2luZ2xldG9uIGZyb20gQmFzZU1vZGlmaWVyRXh0ZW5zaW9ucyhlbGVtZW50LCBpZCk="/>
  </content>
</Library>