US Situational Awareness Framework for Reporting (US SAFR) Implementation Guide, published by HL7 International / Public Health. This guide is not an authorized publication; it is the continuous build for version 1.0.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/HL7/us-safr/ and changes regularly. See the Directory of published versions
| Page standards status: Trial-use | Maturity Level: 1 |
<Library xmlns="http://hl7.org/fhir">
<id value="HRDMeasure"/>
<text>
<status value="extensions"/>
<div xmlns="http://www.w3.org/1999/xhtml">
<div>
<table class="grid dict">
<tr>
<th scope="row"><b>Id: </b></th>
<td style="padding-left: 4px;">HRDMeasure</td>
</tr>
<tr>
<th scope="row"><b>Version: </b></th>
<td style="padding-left: 4px;">1.0.0</td>
</tr>
<tr>
<th scope="row"><b>Url: </b></th>
<td style="padding-left: 4px;"><a href="Library-HRDMeasure.html">HRDMeasure</a></td>
</tr>
<tr>
<th scope="row"><b>Status: </b></th>
<td style="padding-left: 4px;">draft</td>
</tr>
<tr>
<th scope="row"><b>Type: </b></th>
<td style="padding-left: 4px;">
<p style="margin-bottom: 5px;">
<b>system: </b> <span><a href="http://terminology.hl7.org/7.0.1/CodeSystem-library-type.html">http://terminology.hl7.org/CodeSystem/library-type</a></span>
</p>
<p style="margin-bottom: 5px;">
<b>code: </b> <span>logic-library</span>
</p>
</td>
</tr>
<tr>
<th scope="row"><b>Date: </b></th>
<td style="padding-left: 4px;">2025-12-23 19:38:58+0000</td>
</tr>
<tr>
<th scope="row"><b>Publisher: </b></th>
<td style="padding-left: 4px;">HL7 International / Public Health</td>
</tr>
<tr>
<th scope="row"><b>Jurisdiction: </b></th>
<td style="padding-left: 4px;">US</td>
</tr>
<tr>
<td colspan="2">
<table>
<tr><th><a id="cql-content"><b>Content: </b></a> text/cql</th></tr>
<tr><td><pre><code class="language-cql">library HRDMeasure version '1.0.0'
using FHIR version '4.0.1'
include FHIRHelpers version '4.0.1' called FHIRHelpers
// Terminology definitions
codesystem "SNOMEDCT": 'http://snomed.info/sct'
codesystem "LocationPhysicalType": 'http://terminology.hl7.org/CodeSystem/location-physical-type'
codesystem "HealthcareCapacity": 'http://hl7.org/fhir/us/safr/CodeSystem/us-safr-bed-capacity-example-codes'
codesystem "Observation Category": 'http://terminology.hl7.org/CodeSystem/observation-category'
// Value sets
valueset "COVID_19 (Tests for SARS_CoV_2 Nucleic Acid)": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1146.1142'
valueset "COVID_19 (Tests for SARS_CoV_2 Antigen)": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1146.1158'
valueset "Influenza (Tests for influenza A or B virus Nucleic Acid)": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1146.336'
valueset "Influenza (Tests for influenza A or B virus Antigen)": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1146.337'
valueset "RSV (Tests for RSV Antigen)": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1146.1311'
valueset "RSV (Tests for RSV Nucleic Acid)": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1146.1312'
//Codes
code "Bed": 'bd' from "LocationPhysicalType" display 'Bed'
code "HOSP": 'HOSP' from "HealthcareCapacity" display 'Hospital'
code "IRF": 'IRF' from "HealthcareCapacity" display 'Inpatient Rehabilitation'
code "IPF": 'IPF' from "HealthcareCapacity" display 'Inpatient Psychiatric'
code "CHLD": 'CHLD' from "HealthcareCapacity" display 'Children\'s or Pediatric'
code "OTH": 'OTH' from "HealthcareCapacity" display 'Other facility-within-facility or subunit'
code "laboratory": 'laboratory' from "Observation Category" display 'Laboratory'
code "detected": '260373001' from "SNOMEDCT" display 'Detected'
code "N95 mask": '409533008' from "SNOMEDCT" display 'Air-purifying respirator (physical object)'
code "Surgical mask": '409528009' from "SNOMEDCT" display 'Surgical face mask (physical object)'
code "Face shield": '706724001' from "SNOMEDCT" display 'Face shield (physical object)'
code "Patient gown": '1141676007' from "SNOMEDCT" display 'Patient gown (physical object)'
code "Surgical glove": '462245005' from "SNOMEDCT" display 'Nitrile surgical glove, powdered (physical object)'
// Parameter for measurement period
parameter "Measurement Period" Interval<Date>
default Interval[@2025-03-01, @2025-03-07]
context Location
//Initial Populations
define "Inpatient Beds Initial Population":
IsBedLocation
and LocationIsHOSP
and (
LocationIsIPF
or LocationIsIRF
or LocationIsCHLD
)
define "Occupied Inpatient Beds Initial Population":
"Inpatient Beds Initial Population"
and EncounterCheck
define "Adult Inpatient Beds Initial Population":
IsBedLocation
and LocationIsHOSP
and (
LocationIsIPF
or LocationIsIRF
)
and not LocationIsCHLD
define "Occupied Adult Inpatient Beds Initial Population":
"Adult Inpatient Beds Initial Population"
and EncounterCheck
define "Pediatric Inpatient Beds Initial Population":
IsBedLocation
and LocationIsHOSP
and LocationIsCHLD
and not (
LocationIsIPF
or LocationIsIRF
)
define "Occupied Pediatric Inpatient Beds Initial Population":
"Pediatric Inpatient Beds Initial Population"
and EncounterCheck
define "ICU Beds Initial Population":
IsBedLocation
and (
LocationIsHOSP
or LocationIsOTH
)
define "Occupied ICU Beds Initial Population":
"ICU Beds Initial Population"
and EncounterCheck
define "Adult ICU Beds Initial Population":
IsBedLocation
and (
LocationIsHOSP
or LocationIsOTH
)
and not LocationIsCHLD
define "Occupied Adult ICU Beds Initial Population":
"Adult ICU Beds Initial Population"
and EncounterCheck
define "Pediatric ICU Beds Initial Population":
IsBedLocation
and LocationIsCHLD
and (
LocationIsHOSP
or LocationIsOTH
)
define "Occupied Pediatric ICU Beds Initial Population":
"Pediatric ICU Beds Initial Population"
and EncounterCheck
//Stratifiers
//COVID_19
define "Adult Inpatient COVID_19 Patients Stratifier":
if "Occupied Adult Inpatient Beds Initial Population" then
"Count Confirmed COVID_19 Patients in Bed Location"
else 0
define "Pediatric Inpatient COVID_19 Patients Stratifier":
if "Occupied Pediatric Inpatient Beds Initial Population" then
"Count Confirmed COVID_19 Patients in Bed Location"
else 0
define "Adult ICU COVID_19 Patients Stratifier":
if "Occupied Adult ICU Beds Initial Population" then
"Count Confirmed COVID_19 Patients in Bed Location"
else 0
define "Pediatric ICU COVID_19 Patients Stratifier":
if "Occupied Pediatric ICU Beds Initial Population" then
"Count Confirmed COVID_19 Patients in Bed Location"
else 0
define "New Pediatric COVID_19 Patients Between 0 to 4 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted COVID_19 Patient IDs" , 0, 4 )
)
define "New Pediatric COVID_19 Patients Between 5 to 17 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted COVID_19 Patient IDs", 5, 17 )
)
define "New Adult COVID_19 Patients Between 18 to 49 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted COVID_19 Patient IDs", 18, 49 )
)
define "New Adult COVID_19 Patients Between 50 to 64 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted COVID_19 Patient IDs", 50, 64 )
)
define "New Adult COVID_19 Patients Between 65 to 74 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted COVID_19 Patient IDs", 65, 74 )
)
define "New Adult COVID_19 Patients 75 and Above Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Above Specified Age"( "Newly Admitted COVID_19 Patient IDs", 75 )
)
define "New COVID_19 Patients with Unknown Age Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location and Unknown Age"( "Newly Admitted COVID_19 Patient IDs" )
)
//Influenza
define "Adult Inpatient Influenza Patients Stratifier":
if "Occupied Adult Inpatient Beds Initial Population" then
"Count Confirmed Influenza Patients in Bed Location"
else 0
define "Pediatric Inpatient Influenza Patients Stratifier":
if "Occupied Pediatric Inpatient Beds Initial Population" then
"Count Confirmed Influenza Patients in Bed Location"
else 0
define "Adult ICU Influenza Patients Stratifier":
if "Occupied Adult ICU Beds Initial Population" then
"Count Confirmed Influenza Patients in Bed Location"
else 0
define "Pediatric ICU Influenza Patients Stratifier":
if "Occupied Pediatric ICU Beds Initial Population" then
"Count Confirmed Influenza Patients in Bed Location"
else 0
define "New Pediatric Influenza Patients Between 0 to 4 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted Influenza Patient IDs" , 0, 4 )
)
define "New Pediatric Influenza Patients Between 5 to 17 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted Influenza Patient IDs", 5, 17 )
)
define "New Adult Influenza Patients Between 18 to 49 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted Influenza Patient IDs", 18, 49 )
)
define "New Adult Influenza Patients Between 50 to 64 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted Influenza Patient IDs", 50, 64 )
)
define "New Adult Influenza Patients Between 65 to 74 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted Influenza Patient IDs", 65, 74 )
)
define "New Adult Influenza Patients 75 and Above Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Above Specified Age"( "Newly Admitted Influenza Patient IDs", 75 )
)
define "New Influenza Patients with Unknown Age Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location and Unknown Age"( "Newly Admitted Influenza Patient IDs" )
)
//RSV
define "Adult Inpatient RSV Patients Stratifier":
if "Occupied Adult Inpatient Beds Initial Population" then
"Count Confirmed RSV Patients in Bed Location"
else 0
define "Pediatric Inpatient RSV Patients Stratifier":
if "Occupied Pediatric Inpatient Beds Initial Population" then
"Count Confirmed RSV Patients in Bed Location"
else 0
define "Adult ICU RSV Patients Stratifier":
if "Occupied Adult ICU Beds Initial Population" then
"Count Confirmed RSV Patients in Bed Location"
else 0
define "Pediatric ICU RSV Patients Stratifier":
if "Occupied Pediatric ICU Beds Initial Population" then
"Count Confirmed RSV Patients in Bed Location"
else 0
define "New Pediatric RSV Patients Between 0 to 4 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted RSV Patient IDs" , 0, 4 )
)
define "New Pediatric RSV Patients Between 5 to 17 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted RSV Patient IDs", 5, 17 )
)
define "New Adult RSV Patients Between 18 to 49 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted RSV Patient IDs", 18, 49 )
)
define "New Adult RSV Patients Between 50 to 64 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted RSV Patient IDs", 50, 64 )
)
define "New Adult RSV Patients Between 65 to 74 Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Between Specified Ages"( "Newly Admitted RSV Patient IDs", 65, 74 )
)
define "New Adult RSV Patients 75 and Above Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location Above Specified Age"( "Newly Admitted RSV Patient IDs", 75 )
)
define "New RSV Patients with Unknown Age Stratifier":
Count(
"Get Confirmed Patient IDs in Bed Location and Unknown Age"( "Newly Admitted RSV Patient IDs" )
)
//Devices (Supply is divided by average used per day (estimated))
define "N95 Mask Supply in Days Stratifier":
Floor( Count(
"Devices" Devices
where Devices.type ~ "N95 mask"
) / 10 )
define "N95 Mask 3 Day Supply Initial Population":
"N95 Mask Supply in Days Stratifier" > 3
define "OR Surgical Mask Supply in Days Stratifier":
Floor( Count(
"Devices" Devices
where Devices.type ~ "Surgical mask"
) / 10 )
define "OR Surgical Mask 3 Day Supply Initial Population":
"OR Surgical Mask Supply in Days Stratifier" > 3
define "Face Shield Supply in Days Stratifier":
Floor( Count(
"Devices" Devices
where Devices.type ~ "Face shield"
) / 10 )
define "Face Shield 3 Day Supply Initial Population":
"Face Shield Supply in Days Stratifier" > 3
define "Gown Supply in Days Stratifier":
Floor( Count(
"Devices" Devices
where Devices.type ~ "Patient gown"
) / 5 )
define "Gown 3 Day Supply Initial Population":
"Gown Supply in Days Stratifier" > 3
define "Glove Supply in Days Stratifier":
Floor( Count(
"Devices" Devices
where Devices.type ~ "Surgical glove"
) / 15 )
define "Glove 3 Day Supply Initial Population":
"Glove Supply in Days Stratifier" > 3
//Functions and Helpers
define "COVID_19 Observations":
[Observation: "COVID_19 (Tests for SARS_CoV_2 Nucleic Acid)"]
union [Observation: "COVID_19 (Tests for SARS_CoV_2 Antigen)"]
define "Newly Admitted COVID_19 Patient IDs":
"Get Confirmed Patient IDs"( "Newly Admitted Encounters", "COVID_19 Observations" )
define "Count Confirmed COVID_19 Patients in Bed Location":
Count(
"Get Confirmed Patient IDs"( "Encounters", "COVID_19 Observations" )
)
define "Influenza Observations":
[Observation: "Influenza (Tests for influenza A or B virus Nucleic Acid)"]
union [Observation: "Influenza (Tests for influenza A or B virus Antigen)"]
define "Newly Admitted Influenza Patient IDs":
"Get Confirmed Patient IDs"( "Newly Admitted Encounters", "Influenza Observations" )
define "Count Confirmed Influenza Patients in Bed Location":
Count(
"Get Confirmed Patient IDs"( "Encounters", "Influenza Observations" )
)
define "RSV Observations":
[Observation: "RSV (Tests for RSV Antigen)"]
union [Observation: "RSV (Tests for RSV Nucleic Acid)"]
define "Newly Admitted RSV Patient IDs":
"Get Confirmed Patient IDs"( "Newly Admitted Encounters", "RSV Observations" )
define "Count Confirmed RSV Patients in Bed Location":
Count(
"Get Confirmed Patient IDs"( "Encounters", "RSV Observations" )
)
define "IsBedLocation":
Location.physicalType ~ "Bed"
define "Encounters":
[Encounter]
define "Devices":
[Device]
define "Newly Admitted Encounters":
"Encounters" Encounters
where Encounters.status in { 'in-progress', 'arrived', 'triaged' }
define "Patients":
[Patient]
define function "Get Confirmed Patient IDs"( Encounters List<FHIR.Encounter>, Observations List<FHIR.Observation> ):
Distinct(
Encounters Encounter
where exists(
Observations Labs
where exists(
Labs.category category
where category ~ "laboratory"
)
and Encounter.subject = Labs.subject
and Labs.value ~ "detected"
and "Normalize Interval"( Labs.effective ) overlaps Encounter.period
)
return Encounter.subject
)
define function "Get Confirmed Patient IDs in Bed Location Between Specified Ages"( PatientIDs List<FHIR.Reference>, low System.Integer, high System.Integer ):
PatientIDs PatientID
where exists(
"Patients" Patients
let PatientAge: CalculateAgeInYearsAt( Patients.birthDate, start of "Measurement Period" )
where Patients.id = GetId( PatientID.reference )
and PatientAge >= low
and PatientAge <= high
)
define function "Get Confirmed Patient IDs in Bed Location Above Specified Age"( PatientIDs List<FHIR.Reference>, age System.Integer ):
PatientIDs PatientID
where exists(
"Patients" Patients
let PatientAge: CalculateAgeInYearsAt( Patients.birthDate, start of "Measurement Period" )
where Patients.id = GetId( PatientID.reference )
and PatientAge >= age
)
define function "Get Confirmed Patient IDs in Bed Location and Unknown Age"( PatientIDs List<FHIR.Reference> ):
PatientIDs PatientID
where exists(
"Patients" Patients
where Patients.id = GetId( PatientID.reference )
and Patients.birthDate = null
)
define function "GetCondition"( reference Reference ):
singleton from (
[Condition] Conditions
where Conditions.id = GetId( reference.reference )
)
define function "GetId"( uri String ):
Last(Split(uri, '/'))
define function "Normalize Interval"( choice Choice<FHIR.dateTime, FHIR.Period, FHIR.Timing, FHIR.instant> ):
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.Timing then
Message(null as Interval<DateTime>, true, '1', 'Error', 'Cannot compute a single interval from a Timing type')
else
null as Interval<DateTime>
end
define "EncounterCheck":
exists("Encounters" Encounters
where Encounters.period overlaps "Measurement Period")
define "LocationIsHOSP":
exists(
Location.type types
where types ~ "HOSP"
)
define "LocationIsIPF":
exists(
Location.type types
where types ~ "IPF"
)
define "LocationIsIRF":
exists(
Location.type types
where types ~ "IRF"
)
define "LocationIsCHLD":
exists(
Location.type types
where types ~ "CHLD"
)
define "LocationIsOTH":
exists(
Location.type types
where types ~ "OTH"
)</code></pre></td></tr>
</table>
</td>
</tr>
</table>
</div>
</div>
</text>
<extension
url="http://hl7.org/fhir/StructureDefinition/structuredefinition-wg">
<valueCode value="pher"/>
</extension>
<url value="http://hl7.org/fhir/us/safr/Library/HRDMeasure"/>
<version value="1.0.0"/>
<name value="HRDMeasure"/>
<status value="draft"/>
<type>
<coding>
<system value="http://terminology.hl7.org/CodeSystem/library-type"/>
<code value="logic-library"/>
</coding>
</type>
<date value="2025-12-23T19:38:58+00:00"/>
<publisher value="HL7 International / Public Health"/>
<contact>
<name value="HL7 International / Public Health"/>
<telecom>
<system value="url"/>
<value value="http://www.hl7.org/Special/committees/pher"/>
</telecom>
</contact>
<jurisdiction>
<coding>
<system value="urn:iso:std:iso:3166"/>
<code value="US"/>
<display value="United States of America"/>
</coding>
</jurisdiction>
<content>
<contentType value="text/cql"/>
<data
value="bGlicmFyeSBIUkRNZWFzdXJlIHZlcnNpb24gJzEuMC4wJw0KDQp1c2luZyBGSElSIHZlcnNpb24gJzQuMC4xJw0KDQppbmNsdWRlIEZISVJIZWxwZXJzIHZlcnNpb24gJzQuMC4xJyBjYWxsZWQgRkhJUkhlbHBlcnMNCg0KLy8gVGVybWlub2xvZ3kgZGVmaW5pdGlvbnMNCmNvZGVzeXN0ZW0gIlNOT01FRENUIjogJ2h0dHA6Ly9zbm9tZWQuaW5mby9zY3QnDQpjb2Rlc3lzdGVtICJMb2NhdGlvblBoeXNpY2FsVHlwZSI6ICdodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2xvY2F0aW9uLXBoeXNpY2FsLXR5cGUnDQpjb2Rlc3lzdGVtICJIZWFsdGhjYXJlQ2FwYWNpdHkiOiAnaHR0cDovL2hsNy5vcmcvZmhpci91cy9zYWZyL0NvZGVTeXN0ZW0vdXMtc2Fmci1iZWQtY2FwYWNpdHktZXhhbXBsZS1jb2RlcycNCmNvZGVzeXN0ZW0gIk9ic2VydmF0aW9uIENhdGVnb3J5IjogJ2h0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vb2JzZXJ2YXRpb24tY2F0ZWdvcnknDQoNCi8vIFZhbHVlIHNldHMNCnZhbHVlc2V0ICJDT1ZJRF8xOSAoVGVzdHMgZm9yIFNBUlNfQ29WXzIgTnVjbGVpYyBBY2lkKSI6ICdodHRwOi8vY3RzLm5sbS5uaWguZ292L2ZoaXIvVmFsdWVTZXQvMi4xNi44NDAuMS4xMTM3NjIuMS40LjExNDYuMTE0MicNCnZhbHVlc2V0ICJDT1ZJRF8xOSAoVGVzdHMgZm9yIFNBUlNfQ29WXzIgQW50aWdlbikiOiAnaHR0cDovL2N0cy5ubG0ubmloLmdvdi9maGlyL1ZhbHVlU2V0LzIuMTYuODQwLjEuMTEzNzYyLjEuNC4xMTQ2LjExNTgnDQp2YWx1ZXNldCAiSW5mbHVlbnphIChUZXN0cyBmb3IgaW5mbHVlbnphIEEgb3IgQiB2aXJ1cyBOdWNsZWljIEFjaWQpIjogJ2h0dHA6Ly9jdHMubmxtLm5paC5nb3YvZmhpci9WYWx1ZVNldC8yLjE2Ljg0MC4xLjExMzc2Mi4xLjQuMTE0Ni4zMzYnDQp2YWx1ZXNldCAiSW5mbHVlbnphIChUZXN0cyBmb3IgaW5mbHVlbnphIEEgb3IgQiB2aXJ1cyBBbnRpZ2VuKSI6ICdodHRwOi8vY3RzLm5sbS5uaWguZ292L2ZoaXIvVmFsdWVTZXQvMi4xNi44NDAuMS4xMTM3NjIuMS40LjExNDYuMzM3Jw0KdmFsdWVzZXQgIlJTViAoVGVzdHMgZm9yIFJTViBBbnRpZ2VuKSI6ICdodHRwOi8vY3RzLm5sbS5uaWguZ292L2ZoaXIvVmFsdWVTZXQvMi4xNi44NDAuMS4xMTM3NjIuMS40LjExNDYuMTMxMScNCnZhbHVlc2V0ICJSU1YgKFRlc3RzIGZvciBSU1YgTnVjbGVpYyBBY2lkKSI6ICdodHRwOi8vY3RzLm5sbS5uaWguZ292L2ZoaXIvVmFsdWVTZXQvMi4xNi44NDAuMS4xMTM3NjIuMS40LjExNDYuMTMxMicNCg0KLy9Db2Rlcw0KY29kZSAiQmVkIjogJ2JkJyBmcm9tICJMb2NhdGlvblBoeXNpY2FsVHlwZSIgZGlzcGxheSAnQmVkJw0KDQpjb2RlICJIT1NQIjogJ0hPU1AnIGZyb20gIkhlYWx0aGNhcmVDYXBhY2l0eSIgZGlzcGxheSAnSG9zcGl0YWwnDQpjb2RlICJJUkYiOiAnSVJGJyBmcm9tICJIZWFsdGhjYXJlQ2FwYWNpdHkiIGRpc3BsYXkgJ0lucGF0aWVudCBSZWhhYmlsaXRhdGlvbicNCmNvZGUgIklQRiI6ICdJUEYnIGZyb20gIkhlYWx0aGNhcmVDYXBhY2l0eSIgZGlzcGxheSAnSW5wYXRpZW50IFBzeWNoaWF0cmljJw0KY29kZSAiQ0hMRCI6ICdDSExEJyBmcm9tICJIZWFsdGhjYXJlQ2FwYWNpdHkiIGRpc3BsYXkgJ0NoaWxkcmVuXCdzIG9yIFBlZGlhdHJpYycNCmNvZGUgIk9USCI6ICdPVEgnIGZyb20gIkhlYWx0aGNhcmVDYXBhY2l0eSIgZGlzcGxheSAnT3RoZXIgZmFjaWxpdHktd2l0aGluLWZhY2lsaXR5IG9yIHN1YnVuaXQnDQoNCmNvZGUgImxhYm9yYXRvcnkiOiAnbGFib3JhdG9yeScgZnJvbSAiT2JzZXJ2YXRpb24gQ2F0ZWdvcnkiIGRpc3BsYXkgJ0xhYm9yYXRvcnknDQoNCmNvZGUgImRldGVjdGVkIjogJzI2MDM3MzAwMScgZnJvbSAiU05PTUVEQ1QiIGRpc3BsYXkgJ0RldGVjdGVkJw0KY29kZSAiTjk1IG1hc2siOiAnNDA5NTMzMDA4JyBmcm9tICJTTk9NRURDVCIgZGlzcGxheSAnQWlyLXB1cmlmeWluZyByZXNwaXJhdG9yIChwaHlzaWNhbCBvYmplY3QpJw0KY29kZSAiU3VyZ2ljYWwgbWFzayI6ICc0MDk1MjgwMDknIGZyb20gIlNOT01FRENUIiBkaXNwbGF5ICdTdXJnaWNhbCBmYWNlIG1hc2sgKHBoeXNpY2FsIG9iamVjdCknDQpjb2RlICJGYWNlIHNoaWVsZCI6ICc3MDY3MjQwMDEnIGZyb20gIlNOT01FRENUIiBkaXNwbGF5ICdGYWNlIHNoaWVsZCAocGh5c2ljYWwgb2JqZWN0KScNCmNvZGUgIlBhdGllbnQgZ293biI6ICcxMTQxNjc2MDA3JyBmcm9tICJTTk9NRURDVCIgZGlzcGxheSAnUGF0aWVudCBnb3duIChwaHlzaWNhbCBvYmplY3QpJw0KY29kZSAiU3VyZ2ljYWwgZ2xvdmUiOiAnNDYyMjQ1MDA1JyBmcm9tICJTTk9NRURDVCIgZGlzcGxheSAnTml0cmlsZSBzdXJnaWNhbCBnbG92ZSwgcG93ZGVyZWQgKHBoeXNpY2FsIG9iamVjdCknDQoNCi8vIFBhcmFtZXRlciBmb3IgbWVhc3VyZW1lbnQgcGVyaW9kDQpwYXJhbWV0ZXIgIk1lYXN1cmVtZW50IFBlcmlvZCIgSW50ZXJ2YWw8RGF0ZT4NCiAgZGVmYXVsdCBJbnRlcnZhbFtAMjAyNS0wMy0wMSwgQDIwMjUtMDMtMDddDQoNCmNvbnRleHQgTG9jYXRpb24NCg0KLy9Jbml0aWFsIFBvcHVsYXRpb25zDQpkZWZpbmUgIklucGF0aWVudCBCZWRzIEluaXRpYWwgUG9wdWxhdGlvbiI6DQogIElzQmVkTG9jYXRpb24NCiAgYW5kIExvY2F0aW9uSXNIT1NQDQogIGFuZCAoDQogICAgTG9jYXRpb25Jc0lQRg0KICAgIG9yIExvY2F0aW9uSXNJUkYNCiAgICBvciBMb2NhdGlvbklzQ0hMRA0KICApDQoNCmRlZmluZSAiT2NjdXBpZWQgSW5wYXRpZW50IEJlZHMgSW5pdGlhbCBQb3B1bGF0aW9uIjoNCiAgIklucGF0aWVudCBCZWRzIEluaXRpYWwgUG9wdWxhdGlvbiINCiAgYW5kIEVuY291bnRlckNoZWNrDQogIA0KZGVmaW5lICJBZHVsdCBJbnBhdGllbnQgQmVkcyBJbml0aWFsIFBvcHVsYXRpb24iOg0KICBJc0JlZExvY2F0aW9uDQogIGFuZCBMb2NhdGlvbklzSE9TUA0KICBhbmQgKA0KICAgIExvY2F0aW9uSXNJUEYNCiAgICBvciBMb2NhdGlvbklzSVJGDQogICkNCiAgYW5kIG5vdCBMb2NhdGlvbklzQ0hMRA0KDQpkZWZpbmUgIk9jY3VwaWVkIEFkdWx0IElucGF0aWVudCBCZWRzIEluaXRpYWwgUG9wdWxhdGlvbiI6DQogICJBZHVsdCBJbnBhdGllbnQgQmVkcyBJbml0aWFsIFBvcHVsYXRpb24iDQogIGFuZCBFbmNvdW50ZXJDaGVjaw0KDQpkZWZpbmUgIlBlZGlhdHJpYyBJbnBhdGllbnQgQmVkcyBJbml0aWFsIFBvcHVsYXRpb24iOg0KICBJc0JlZExvY2F0aW9uDQogIGFuZCBMb2NhdGlvbklzSE9TUA0KICBhbmQgTG9jYXRpb25Jc0NITEQNCiAgYW5kIG5vdCAoDQogICAgTG9jYXRpb25Jc0lQRg0KICAgIG9yIExvY2F0aW9uSXNJUkYNCiAgKQ0KDQpkZWZpbmUgIk9jY3VwaWVkIFBlZGlhdHJpYyBJbnBhdGllbnQgQmVkcyBJbml0aWFsIFBvcHVsYXRpb24iOg0KICAiUGVkaWF0cmljIElucGF0aWVudCBCZWRzIEluaXRpYWwgUG9wdWxhdGlvbiINCiAgYW5kIEVuY291bnRlckNoZWNrDQoNCmRlZmluZSAiSUNVIEJlZHMgSW5pdGlhbCBQb3B1bGF0aW9uIjoNCiAgSXNCZWRMb2NhdGlvbg0KICBhbmQgKA0KICAgIExvY2F0aW9uSXNIT1NQDQogICAgb3IgTG9jYXRpb25Jc09USA0KICApDQoNCmRlZmluZSAiT2NjdXBpZWQgSUNVIEJlZHMgSW5pdGlhbCBQb3B1bGF0aW9uIjoNCiAgIklDVSBCZWRzIEluaXRpYWwgUG9wdWxhdGlvbiINCiAgYW5kIEVuY291bnRlckNoZWNrDQoNCmRlZmluZSAiQWR1bHQgSUNVIEJlZHMgSW5pdGlhbCBQb3B1bGF0aW9uIjoNCiAgSXNCZWRMb2NhdGlvbg0KICBhbmQgKA0KICAgIExvY2F0aW9uSXNIT1NQDQogICAgb3IgTG9jYXRpb25Jc09USA0KICApDQogIGFuZCBub3QgTG9jYXRpb25Jc0NITEQNCg0KZGVmaW5lICJPY2N1cGllZCBBZHVsdCBJQ1UgQmVkcyBJbml0aWFsIFBvcHVsYXRpb24iOg0KICAiQWR1bHQgSUNVIEJlZHMgSW5pdGlhbCBQb3B1bGF0aW9uIg0KICBhbmQgRW5jb3VudGVyQ2hlY2sNCg0KZGVmaW5lICJQZWRpYXRyaWMgSUNVIEJlZHMgSW5pdGlhbCBQb3B1bGF0aW9uIjoNCiAgSXNCZWRMb2NhdGlvbg0KICBhbmQgTG9jYXRpb25Jc0NITEQNCiAgYW5kICgNCiAgICBMb2NhdGlvbklzSE9TUA0KICAgIG9yIExvY2F0aW9uSXNPVEgNCiAgKQ0KDQpkZWZpbmUgIk9jY3VwaWVkIFBlZGlhdHJpYyBJQ1UgQmVkcyBJbml0aWFsIFBvcHVsYXRpb24iOg0KICAiUGVkaWF0cmljIElDVSBCZWRzIEluaXRpYWwgUG9wdWxhdGlvbiINCiAgYW5kIEVuY291bnRlckNoZWNrDQoNCi8vU3RyYXRpZmllcnMNCi8vQ09WSURfMTkNCmRlZmluZSAiQWR1bHQgSW5wYXRpZW50IENPVklEXzE5IFBhdGllbnRzIFN0cmF0aWZpZXIiOg0KICBpZiAiT2NjdXBpZWQgQWR1bHQgSW5wYXRpZW50IEJlZHMgSW5pdGlhbCBQb3B1bGF0aW9uIiB0aGVuDQogICAgIkNvdW50IENvbmZpcm1lZCBDT1ZJRF8xOSBQYXRpZW50cyBpbiBCZWQgTG9jYXRpb24iDQogIGVsc2UgMA0KDQpkZWZpbmUgIlBlZGlhdHJpYyBJbnBhdGllbnQgQ09WSURfMTkgUGF0aWVudHMgU3RyYXRpZmllciI6DQogIGlmICJPY2N1cGllZCBQZWRpYXRyaWMgSW5wYXRpZW50IEJlZHMgSW5pdGlhbCBQb3B1bGF0aW9uIiB0aGVuDQogICAgIkNvdW50IENvbmZpcm1lZCBDT1ZJRF8xOSBQYXRpZW50cyBpbiBCZWQgTG9jYXRpb24iDQogIGVsc2UgMA0KDQpkZWZpbmUgIkFkdWx0IElDVSBDT1ZJRF8xOSBQYXRpZW50cyBTdHJhdGlmaWVyIjoNCiAgaWYgIk9jY3VwaWVkIEFkdWx0IElDVSBCZWRzIEluaXRpYWwgUG9wdWxhdGlvbiIgdGhlbg0KICAgICJDb3VudCBDb25maXJtZWQgQ09WSURfMTkgUGF0aWVudHMgaW4gQmVkIExvY2F0aW9uIg0KICBlbHNlIDANCg0KZGVmaW5lICJQZWRpYXRyaWMgSUNVIENPVklEXzE5IFBhdGllbnRzIFN0cmF0aWZpZXIiOg0KICBpZiAiT2NjdXBpZWQgUGVkaWF0cmljIElDVSBCZWRzIEluaXRpYWwgUG9wdWxhdGlvbiIgdGhlbg0KICAgICJDb3VudCBDb25maXJtZWQgQ09WSURfMTkgUGF0aWVudHMgaW4gQmVkIExvY2F0aW9uIg0KICBlbHNlIDANCg0KZGVmaW5lICJOZXcgUGVkaWF0cmljIENPVklEXzE5IFBhdGllbnRzIEJldHdlZW4gMCB0byA0IFN0cmF0aWZpZXIiOg0KICBDb3VudCgNCiAgICAiR2V0IENvbmZpcm1lZCBQYXRpZW50IElEcyBpbiBCZWQgTG9jYXRpb24gQmV0d2VlbiBTcGVjaWZpZWQgQWdlcyIoICJOZXdseSBBZG1pdHRlZCBDT1ZJRF8xOSBQYXRpZW50IElEcyIgLCAwLCA0ICkNCiAgKQ0KDQpkZWZpbmUgIk5ldyBQZWRpYXRyaWMgQ09WSURfMTkgUGF0aWVudHMgQmV0d2VlbiA1IHRvIDE3IFN0cmF0aWZpZXIiOg0KICBDb3VudCgNCiAgICAiR2V0IENvbmZpcm1lZCBQYXRpZW50IElEcyBpbiBCZWQgTG9jYXRpb24gQmV0d2VlbiBTcGVjaWZpZWQgQWdlcyIoICJOZXdseSBBZG1pdHRlZCBDT1ZJRF8xOSBQYXRpZW50IElEcyIsIDUsIDE3ICkNCiAgKQ0KDQpkZWZpbmUgIk5ldyBBZHVsdCBDT1ZJRF8xOSBQYXRpZW50cyBCZXR3ZWVuIDE4IHRvIDQ5IFN0cmF0aWZpZXIiOg0KICBDb3VudCgNCiAgICAiR2V0IENvbmZpcm1lZCBQYXRpZW50IElEcyBpbiBCZWQgTG9jYXRpb24gQmV0d2VlbiBTcGVjaWZpZWQgQWdlcyIoICJOZXdseSBBZG1pdHRlZCBDT1ZJRF8xOSBQYXRpZW50IElEcyIsIDE4LCA0OSApDQogICkNCg0KZGVmaW5lICJOZXcgQWR1bHQgQ09WSURfMTkgUGF0aWVudHMgQmV0d2VlbiA1MCB0byA2NCBTdHJhdGlmaWVyIjoNCiAgQ291bnQoDQogICAgIkdldCBDb25maXJtZWQgUGF0aWVudCBJRHMgaW4gQmVkIExvY2F0aW9uIEJldHdlZW4gU3BlY2lmaWVkIEFnZXMiKCAiTmV3bHkgQWRtaXR0ZWQgQ09WSURfMTkgUGF0aWVudCBJRHMiLCA1MCwgNjQgKQ0KICApDQoNCmRlZmluZSAiTmV3IEFkdWx0IENPVklEXzE5IFBhdGllbnRzIEJldHdlZW4gNjUgdG8gNzQgU3RyYXRpZmllciI6DQogIENvdW50KA0KICAgICJHZXQgQ29uZmlybWVkIFBhdGllbnQgSURzIGluIEJlZCBMb2NhdGlvbiBCZXR3ZWVuIFNwZWNpZmllZCBBZ2VzIiggIk5ld2x5IEFkbWl0dGVkIENPVklEXzE5IFBhdGllbnQgSURzIiwgNjUsIDc0ICkNCiAgKQ0KDQpkZWZpbmUgIk5ldyBBZHVsdCBDT1ZJRF8xOSBQYXRpZW50cyA3NSBhbmQgQWJvdmUgU3RyYXRpZmllciI6DQogIENvdW50KA0KICAgICJHZXQgQ29uZmlybWVkIFBhdGllbnQgSURzIGluIEJlZCBMb2NhdGlvbiBBYm92ZSBTcGVjaWZpZWQgQWdlIiggIk5ld2x5IEFkbWl0dGVkIENPVklEXzE5IFBhdGllbnQgSURzIiwgNzUgKQ0KICApDQoNCmRlZmluZSAiTmV3IENPVklEXzE5IFBhdGllbnRzIHdpdGggVW5rbm93biBBZ2UgU3RyYXRpZmllciI6DQogIENvdW50KA0KICAgICJHZXQgQ29uZmlybWVkIFBhdGllbnQgSURzIGluIEJlZCBMb2NhdGlvbiBhbmQgVW5rbm93biBBZ2UiKCAiTmV3bHkgQWRtaXR0ZWQgQ09WSURfMTkgUGF0aWVudCBJRHMiICkNCiAgKQ0KICANCi8vSW5mbHVlbnphDQpkZWZpbmUgIkFkdWx0IElucGF0aWVudCBJbmZsdWVuemEgUGF0aWVudHMgU3RyYXRpZmllciI6DQogIGlmICJPY2N1cGllZCBBZHVsdCBJbnBhdGllbnQgQmVkcyBJbml0aWFsIFBvcHVsYXRpb24iIHRoZW4NCiAgICAiQ291bnQgQ29uZmlybWVkIEluZmx1ZW56YSBQYXRpZW50cyBpbiBCZWQgTG9jYXRpb24iDQogIGVsc2UgMA0KDQpkZWZpbmUgIlBlZGlhdHJpYyBJbnBhdGllbnQgSW5mbHVlbnphIFBhdGllbnRzIFN0cmF0aWZpZXIiOg0KICBpZiAiT2NjdXBpZWQgUGVkaWF0cmljIElucGF0aWVudCBCZWRzIEluaXRpYWwgUG9wdWxhdGlvbiIgdGhlbg0KICAgICJDb3VudCBDb25maXJtZWQgSW5mbHVlbnphIFBhdGllbnRzIGluIEJlZCBMb2NhdGlvbiINCiAgZWxzZSAwDQoNCmRlZmluZSAiQWR1bHQgSUNVIEluZmx1ZW56YSBQYXRpZW50cyBTdHJhdGlmaWVyIjoNCiAgaWYgIk9jY3VwaWVkIEFkdWx0IElDVSBCZWRzIEluaXRpYWwgUG9wdWxhdGlvbiIgdGhlbg0KICAgICJDb3VudCBDb25maXJtZWQgSW5mbHVlbnphIFBhdGllbnRzIGluIEJlZCBMb2NhdGlvbiINCiAgZWxzZSAwDQoNCmRlZmluZSAiUGVkaWF0cmljIElDVSBJbmZsdWVuemEgUGF0aWVudHMgU3RyYXRpZmllciI6DQogIGlmICJPY2N1cGllZCBQZWRpYXRyaWMgSUNVIEJlZHMgSW5pdGlhbCBQb3B1bGF0aW9uIiB0aGVuDQogICAgIkNvdW50IENvbmZpcm1lZCBJbmZsdWVuemEgUGF0aWVudHMgaW4gQmVkIExvY2F0aW9uIg0KICBlbHNlIDANCg0KZGVmaW5lICJOZXcgUGVkaWF0cmljIEluZmx1ZW56YSBQYXRpZW50cyBCZXR3ZWVuIDAgdG8gNCBTdHJhdGlmaWVyIjoNCiAgQ291bnQoDQogICAgIkdldCBDb25maXJtZWQgUGF0aWVudCBJRHMgaW4gQmVkIExvY2F0aW9uIEJldHdlZW4gU3BlY2lmaWVkIEFnZXMiKCAiTmV3bHkgQWRtaXR0ZWQgSW5mbHVlbnphIFBhdGllbnQgSURzIiAsIDAsIDQgKQ0KICApDQoNCmRlZmluZSAiTmV3IFBlZGlhdHJpYyBJbmZsdWVuemEgUGF0aWVudHMgQmV0d2VlbiA1IHRvIDE3IFN0cmF0aWZpZXIiOg0KICBDb3VudCgNCiAgICAiR2V0IENvbmZpcm1lZCBQYXRpZW50IElEcyBpbiBCZWQgTG9jYXRpb24gQmV0d2VlbiBTcGVjaWZpZWQgQWdlcyIoICJOZXdseSBBZG1pdHRlZCBJbmZsdWVuemEgUGF0aWVudCBJRHMiLCA1LCAxNyApDQogICkNCg0KZGVmaW5lICJOZXcgQWR1bHQgSW5mbHVlbnphIFBhdGllbnRzIEJldHdlZW4gMTggdG8gNDkgU3RyYXRpZmllciI6DQogIENvdW50KA0KICAgICJHZXQgQ29uZmlybWVkIFBhdGllbnQgSURzIGluIEJlZCBMb2NhdGlvbiBCZXR3ZWVuIFNwZWNpZmllZCBBZ2VzIiggIk5ld2x5IEFkbWl0dGVkIEluZmx1ZW56YSBQYXRpZW50IElEcyIsIDE4LCA0OSApDQogICkNCg0KZGVmaW5lICJOZXcgQWR1bHQgSW5mbHVlbnphIFBhdGllbnRzIEJldHdlZW4gNTAgdG8gNjQgU3RyYXRpZmllciI6DQogIENvdW50KA0KICAgICJHZXQgQ29uZmlybWVkIFBhdGllbnQgSURzIGluIEJlZCBMb2NhdGlvbiBCZXR3ZWVuIFNwZWNpZmllZCBBZ2VzIiggIk5ld2x5IEFkbWl0dGVkIEluZmx1ZW56YSBQYXRpZW50IElEcyIsIDUwLCA2NCApDQogICkNCg0KZGVmaW5lICJOZXcgQWR1bHQgSW5mbHVlbnphIFBhdGllbnRzIEJldHdlZW4gNjUgdG8gNzQgU3RyYXRpZmllciI6DQogIENvdW50KA0KICAgICJHZXQgQ29uZmlybWVkIFBhdGllbnQgSURzIGluIEJlZCBMb2NhdGlvbiBCZXR3ZWVuIFNwZWNpZmllZCBBZ2VzIiggIk5ld2x5IEFkbWl0dGVkIEluZmx1ZW56YSBQYXRpZW50IElEcyIsIDY1LCA3NCApDQogICkNCg0KZGVmaW5lICJOZXcgQWR1bHQgSW5mbHVlbnphIFBhdGllbnRzIDc1IGFuZCBBYm92ZSBTdHJhdGlmaWVyIjoNCiAgQ291bnQoDQogICAgIkdldCBDb25maXJtZWQgUGF0aWVudCBJRHMgaW4gQmVkIExvY2F0aW9uIEFib3ZlIFNwZWNpZmllZCBBZ2UiKCAiTmV3bHkgQWRtaXR0ZWQgSW5mbHVlbnphIFBhdGllbnQgSURzIiwgNzUgKQ0KICApDQoNCmRlZmluZSAiTmV3IEluZmx1ZW56YSBQYXRpZW50cyB3aXRoIFVua25vd24gQWdlIFN0cmF0aWZpZXIiOg0KICBDb3VudCgNCiAgICAiR2V0IENvbmZpcm1lZCBQYXRpZW50IElEcyBpbiBCZWQgTG9jYXRpb24gYW5kIFVua25vd24gQWdlIiggIk5ld2x5IEFkbWl0dGVkIEluZmx1ZW56YSBQYXRpZW50IElEcyIgKQ0KICApDQoNCi8vUlNWDQpkZWZpbmUgIkFkdWx0IElucGF0aWVudCBSU1YgUGF0aWVudHMgU3RyYXRpZmllciI6DQogIGlmICJPY2N1cGllZCBBZHVsdCBJbnBhdGllbnQgQmVkcyBJbml0aWFsIFBvcHVsYXRpb24iIHRoZW4NCiAgICAiQ291bnQgQ29uZmlybWVkIFJTViBQYXRpZW50cyBpbiBCZWQgTG9jYXRpb24iDQogIGVsc2UgMA0KDQpkZWZpbmUgIlBlZGlhdHJpYyBJbnBhdGllbnQgUlNWIFBhdGllbnRzIFN0cmF0aWZpZXIiOg0KICBpZiAiT2NjdXBpZWQgUGVkaWF0cmljIElucGF0aWVudCBCZWRzIEluaXRpYWwgUG9wdWxhdGlvbiIgdGhlbg0KICAgICJDb3VudCBDb25maXJtZWQgUlNWIFBhdGllbnRzIGluIEJlZCBMb2NhdGlvbiINCiAgZWxzZSAwDQoNCmRlZmluZSAiQWR1bHQgSUNVIFJTViBQYXRpZW50cyBTdHJhdGlmaWVyIjoNCiAgaWYgIk9jY3VwaWVkIEFkdWx0IElDVSBCZWRzIEluaXRpYWwgUG9wdWxhdGlvbiIgdGhlbg0KICAgICJDb3VudCBDb25maXJtZWQgUlNWIFBhdGllbnRzIGluIEJlZCBMb2NhdGlvbiINCiAgZWxzZSAwDQoNCmRlZmluZSAiUGVkaWF0cmljIElDVSBSU1YgUGF0aWVudHMgU3RyYXRpZmllciI6DQogIGlmICJPY2N1cGllZCBQZWRpYXRyaWMgSUNVIEJlZHMgSW5pdGlhbCBQb3B1bGF0aW9uIiB0aGVuDQogICAgIkNvdW50IENvbmZpcm1lZCBSU1YgUGF0aWVudHMgaW4gQmVkIExvY2F0aW9uIg0KICBlbHNlIDANCg0KZGVmaW5lICJOZXcgUGVkaWF0cmljIFJTViBQYXRpZW50cyBCZXR3ZWVuIDAgdG8gNCBTdHJhdGlmaWVyIjoNCiAgQ291bnQoDQogICAgIkdldCBDb25maXJtZWQgUGF0aWVudCBJRHMgaW4gQmVkIExvY2F0aW9uIEJldHdlZW4gU3BlY2lmaWVkIEFnZXMiKCAiTmV3bHkgQWRtaXR0ZWQgUlNWIFBhdGllbnQgSURzIiAsIDAsIDQgKQ0KICApDQoNCmRlZmluZSAiTmV3IFBlZGlhdHJpYyBSU1YgUGF0aWVudHMgQmV0d2VlbiA1IHRvIDE3IFN0cmF0aWZpZXIiOg0KICBDb3VudCgNCiAgICAiR2V0IENvbmZpcm1lZCBQYXRpZW50IElEcyBpbiBCZWQgTG9jYXRpb24gQmV0d2VlbiBTcGVjaWZpZWQgQWdlcyIoICJOZXdseSBBZG1pdHRlZCBSU1YgUGF0aWVudCBJRHMiLCA1LCAxNyApDQogICkNCg0KZGVmaW5lICJOZXcgQWR1bHQgUlNWIFBhdGllbnRzIEJldHdlZW4gMTggdG8gNDkgU3RyYXRpZmllciI6DQogIENvdW50KA0KICAgICJHZXQgQ29uZmlybWVkIFBhdGllbnQgSURzIGluIEJlZCBMb2NhdGlvbiBCZXR3ZWVuIFNwZWNpZmllZCBBZ2VzIiggIk5ld2x5IEFkbWl0dGVkIFJTViBQYXRpZW50IElEcyIsIDE4LCA0OSApDQogICkNCg0KZGVmaW5lICJOZXcgQWR1bHQgUlNWIFBhdGllbnRzIEJldHdlZW4gNTAgdG8gNjQgU3RyYXRpZmllciI6DQogIENvdW50KA0KICAgICJHZXQgQ29uZmlybWVkIFBhdGllbnQgSURzIGluIEJlZCBMb2NhdGlvbiBCZXR3ZWVuIFNwZWNpZmllZCBBZ2VzIiggIk5ld2x5IEFkbWl0dGVkIFJTViBQYXRpZW50IElEcyIsIDUwLCA2NCApDQogICkNCg0KZGVmaW5lICJOZXcgQWR1bHQgUlNWIFBhdGllbnRzIEJldHdlZW4gNjUgdG8gNzQgU3RyYXRpZmllciI6DQogIENvdW50KA0KICAgICJHZXQgQ29uZmlybWVkIFBhdGllbnQgSURzIGluIEJlZCBMb2NhdGlvbiBCZXR3ZWVuIFNwZWNpZmllZCBBZ2VzIiggIk5ld2x5IEFkbWl0dGVkIFJTViBQYXRpZW50IElEcyIsIDY1LCA3NCApDQogICkNCg0KZGVmaW5lICJOZXcgQWR1bHQgUlNWIFBhdGllbnRzIDc1IGFuZCBBYm92ZSBTdHJhdGlmaWVyIjoNCiAgQ291bnQoDQogICAgIkdldCBDb25maXJtZWQgUGF0aWVudCBJRHMgaW4gQmVkIExvY2F0aW9uIEFib3ZlIFNwZWNpZmllZCBBZ2UiKCAiTmV3bHkgQWRtaXR0ZWQgUlNWIFBhdGllbnQgSURzIiwgNzUgKQ0KICApDQoNCmRlZmluZSAiTmV3IFJTViBQYXRpZW50cyB3aXRoIFVua25vd24gQWdlIFN0cmF0aWZpZXIiOg0KICBDb3VudCgNCiAgICAiR2V0IENvbmZpcm1lZCBQYXRpZW50IElEcyBpbiBCZWQgTG9jYXRpb24gYW5kIFVua25vd24gQWdlIiggIk5ld2x5IEFkbWl0dGVkIFJTViBQYXRpZW50IElEcyIgKQ0KICApDQoNCi8vRGV2aWNlcyAoU3VwcGx5IGlzIGRpdmlkZWQgYnkgYXZlcmFnZSB1c2VkIHBlciBkYXkgKGVzdGltYXRlZCkpDQpkZWZpbmUgIk45NSBNYXNrIFN1cHBseSBpbiBEYXlzIFN0cmF0aWZpZXIiOg0KICBGbG9vciggQ291bnQoDQogICAgIkRldmljZXMiIERldmljZXMNCiAgICB3aGVyZSBEZXZpY2VzLnR5cGUgfiAiTjk1IG1hc2siDQogICkgLyAxMCApDQoNCmRlZmluZSAiTjk1IE1hc2sgMyBEYXkgU3VwcGx5IEluaXRpYWwgUG9wdWxhdGlvbiI6DQogICJOOTUgTWFzayBTdXBwbHkgaW4gRGF5cyBTdHJhdGlmaWVyIiA+IDMNCg0KZGVmaW5lICJPUiBTdXJnaWNhbCBNYXNrIFN1cHBseSBpbiBEYXlzIFN0cmF0aWZpZXIiOg0KICBGbG9vciggQ291bnQoDQogICAgIkRldmljZXMiIERldmljZXMNCiAgICB3aGVyZSBEZXZpY2VzLnR5cGUgfiAiU3VyZ2ljYWwgbWFzayINCiAgKSAvIDEwICkNCg0KZGVmaW5lICJPUiBTdXJnaWNhbCBNYXNrIDMgRGF5IFN1cHBseSBJbml0aWFsIFBvcHVsYXRpb24iOg0KICAiT1IgU3VyZ2ljYWwgTWFzayBTdXBwbHkgaW4gRGF5cyBTdHJhdGlmaWVyIiA+IDMNCg0KZGVmaW5lICJGYWNlIFNoaWVsZCBTdXBwbHkgaW4gRGF5cyBTdHJhdGlmaWVyIjoNCiAgRmxvb3IoIENvdW50KA0KICAgICJEZXZpY2VzIiBEZXZpY2VzDQogICAgd2hlcmUgRGV2aWNlcy50eXBlIH4gIkZhY2Ugc2hpZWxkIg0KICApIC8gMTAgKQ0KDQpkZWZpbmUgIkZhY2UgU2hpZWxkIDMgRGF5IFN1cHBseSBJbml0aWFsIFBvcHVsYXRpb24iOg0KICAiRmFjZSBTaGllbGQgU3VwcGx5IGluIERheXMgU3RyYXRpZmllciIgPiAzDQoNCmRlZmluZSAiR293biBTdXBwbHkgaW4gRGF5cyBTdHJhdGlmaWVyIjoNCiAgRmxvb3IoIENvdW50KA0KICAgICJEZXZpY2VzIiBEZXZpY2VzDQogICAgd2hlcmUgRGV2aWNlcy50eXBlIH4gIlBhdGllbnQgZ293biINCiAgKSAvIDUgKQ0KDQpkZWZpbmUgIkdvd24gMyBEYXkgU3VwcGx5IEluaXRpYWwgUG9wdWxhdGlvbiI6DQogICJHb3duIFN1cHBseSBpbiBEYXlzIFN0cmF0aWZpZXIiID4gMw0KDQpkZWZpbmUgIkdsb3ZlIFN1cHBseSBpbiBEYXlzIFN0cmF0aWZpZXIiOg0KICBGbG9vciggQ291bnQoDQogICAgIkRldmljZXMiIERldmljZXMNCiAgICB3aGVyZSBEZXZpY2VzLnR5cGUgfiAiU3VyZ2ljYWwgZ2xvdmUiDQogICkgLyAxNSApDQoNCmRlZmluZSAiR2xvdmUgMyBEYXkgU3VwcGx5IEluaXRpYWwgUG9wdWxhdGlvbiI6DQogICJHbG92ZSBTdXBwbHkgaW4gRGF5cyBTdHJhdGlmaWVyIiA+IDMNCg0KLy9GdW5jdGlvbnMgYW5kIEhlbHBlcnMNCmRlZmluZSAiQ09WSURfMTkgT2JzZXJ2YXRpb25zIjoNCiAgW09ic2VydmF0aW9uOiAiQ09WSURfMTkgKFRlc3RzIGZvciBTQVJTX0NvVl8yIE51Y2xlaWMgQWNpZCkiXSANCiAgICB1bmlvbiBbT2JzZXJ2YXRpb246ICJDT1ZJRF8xOSAoVGVzdHMgZm9yIFNBUlNfQ29WXzIgQW50aWdlbikiXQ0KDQpkZWZpbmUgIk5ld2x5IEFkbWl0dGVkIENPVklEXzE5IFBhdGllbnQgSURzIjoNCiAgIkdldCBDb25maXJtZWQgUGF0aWVudCBJRHMiKCAiTmV3bHkgQWRtaXR0ZWQgRW5jb3VudGVycyIsICJDT1ZJRF8xOSBPYnNlcnZhdGlvbnMiICkNCg0KZGVmaW5lICJDb3VudCBDb25maXJtZWQgQ09WSURfMTkgUGF0aWVudHMgaW4gQmVkIExvY2F0aW9uIjoNCiAgQ291bnQoDQogICAgIkdldCBDb25maXJtZWQgUGF0aWVudCBJRHMiKCAiRW5jb3VudGVycyIsICJDT1ZJRF8xOSBPYnNlcnZhdGlvbnMiICkNCiAgKQ0KDQpkZWZpbmUgIkluZmx1ZW56YSBPYnNlcnZhdGlvbnMiOg0KICBbT2JzZXJ2YXRpb246ICJJbmZsdWVuemEgKFRlc3RzIGZvciBpbmZsdWVuemEgQSBvciBCIHZpcnVzIE51Y2xlaWMgQWNpZCkiXSANCiAgICB1bmlvbiBbT2JzZXJ2YXRpb246ICJJbmZsdWVuemEgKFRlc3RzIGZvciBpbmZsdWVuemEgQSBvciBCIHZpcnVzIEFudGlnZW4pIl0NCg0KZGVmaW5lICJOZXdseSBBZG1pdHRlZCBJbmZsdWVuemEgUGF0aWVudCBJRHMiOg0KICAiR2V0IENvbmZpcm1lZCBQYXRpZW50IElEcyIoICJOZXdseSBBZG1pdHRlZCBFbmNvdW50ZXJzIiwgIkluZmx1ZW56YSBPYnNlcnZhdGlvbnMiICkNCg0KZGVmaW5lICJDb3VudCBDb25maXJtZWQgSW5mbHVlbnphIFBhdGllbnRzIGluIEJlZCBMb2NhdGlvbiI6DQogIENvdW50KA0KICAgICJHZXQgQ29uZmlybWVkIFBhdGllbnQgSURzIiggIkVuY291bnRlcnMiLCAiSW5mbHVlbnphIE9ic2VydmF0aW9ucyIgKQ0KICApDQoNCmRlZmluZSAiUlNWIE9ic2VydmF0aW9ucyI6DQogIFtPYnNlcnZhdGlvbjogIlJTViAoVGVzdHMgZm9yIFJTViBBbnRpZ2VuKSJdIA0KICAgIHVuaW9uIFtPYnNlcnZhdGlvbjogIlJTViAoVGVzdHMgZm9yIFJTViBOdWNsZWljIEFjaWQpIl0NCg0KZGVmaW5lICJOZXdseSBBZG1pdHRlZCBSU1YgUGF0aWVudCBJRHMiOg0KICAiR2V0IENvbmZpcm1lZCBQYXRpZW50IElEcyIoICJOZXdseSBBZG1pdHRlZCBFbmNvdW50ZXJzIiwgIlJTViBPYnNlcnZhdGlvbnMiICkNCg0KZGVmaW5lICJDb3VudCBDb25maXJtZWQgUlNWIFBhdGllbnRzIGluIEJlZCBMb2NhdGlvbiI6DQogIENvdW50KA0KICAgICJHZXQgQ29uZmlybWVkIFBhdGllbnQgSURzIiggIkVuY291bnRlcnMiLCAiUlNWIE9ic2VydmF0aW9ucyIgKQ0KICApDQoNCmRlZmluZSAiSXNCZWRMb2NhdGlvbiI6DQogIExvY2F0aW9uLnBoeXNpY2FsVHlwZSB+ICJCZWQiDQoNCmRlZmluZSAiRW5jb3VudGVycyI6DQogIFtFbmNvdW50ZXJdDQoNCmRlZmluZSAiRGV2aWNlcyI6DQogIFtEZXZpY2VdDQoNCmRlZmluZSAiTmV3bHkgQWRtaXR0ZWQgRW5jb3VudGVycyI6DQogICJFbmNvdW50ZXJzIiBFbmNvdW50ZXJzDQogIHdoZXJlIEVuY291bnRlcnMuc3RhdHVzIGluIHsgJ2luLXByb2dyZXNzJywgJ2Fycml2ZWQnLCAndHJpYWdlZCcgfQ0KDQpkZWZpbmUgIlBhdGllbnRzIjoNCiAgW1BhdGllbnRdDQoNCmRlZmluZSBmdW5jdGlvbiAiR2V0IENvbmZpcm1lZCBQYXRpZW50IElEcyIoIEVuY291bnRlcnMgTGlzdDxGSElSLkVuY291bnRlcj4sIE9ic2VydmF0aW9ucyBMaXN0PEZISVIuT2JzZXJ2YXRpb24+ICk6DQogIERpc3RpbmN0KA0KICAgIEVuY291bnRlcnMgRW5jb3VudGVyDQogICAgd2hlcmUgZXhpc3RzKA0KICAgICAgT2JzZXJ2YXRpb25zIExhYnMNCiAgICAgIHdoZXJlIGV4aXN0cygNCiAgICAgICAgTGFicy5jYXRlZ29yeSBjYXRlZ29yeQ0KICAgICAgICB3aGVyZSBjYXRlZ29yeSB+ICJsYWJvcmF0b3J5Ig0KICAgICAgKQ0KICAgICAgYW5kIEVuY291bnRlci5zdWJqZWN0ID0gTGFicy5zdWJqZWN0DQogICAgICBhbmQgTGFicy52YWx1ZSB+ICJkZXRlY3RlZCINCiAgICAgIGFuZCAiTm9ybWFsaXplIEludGVydmFsIiggTGFicy5lZmZlY3RpdmUgKSBvdmVybGFwcyBFbmNvdW50ZXIucGVyaW9kDQogICAgKQ0KICAgIHJldHVybiBFbmNvdW50ZXIuc3ViamVjdA0KICApDQoNCmRlZmluZSBmdW5jdGlvbiAiR2V0IENvbmZpcm1lZCBQYXRpZW50IElEcyBpbiBCZWQgTG9jYXRpb24gQmV0d2VlbiBTcGVjaWZpZWQgQWdlcyIoIFBhdGllbnRJRHMgTGlzdDxGSElSLlJlZmVyZW5jZT4sIGxvdyBTeXN0ZW0uSW50ZWdlciwgaGlnaCBTeXN0ZW0uSW50ZWdlciApOg0KICBQYXRpZW50SURzIFBhdGllbnRJRA0KICB3aGVyZSBleGlzdHMoDQogICAgIlBhdGllbnRzIiBQYXRpZW50cw0KICAgIGxldCBQYXRpZW50QWdlOiBDYWxjdWxhdGVBZ2VJblllYXJzQXQoIFBhdGllbnRzLmJpcnRoRGF0ZSwgc3RhcnQgb2YgIk1lYXN1cmVtZW50IFBlcmlvZCIgKQ0KICAgIHdoZXJlIFBhdGllbnRzLmlkID0gR2V0SWQoIFBhdGllbnRJRC5yZWZlcmVuY2UgKQ0KICAgIGFuZCBQYXRpZW50QWdlID49IGxvdw0KICAgIGFuZCBQYXRpZW50QWdlIDw9IGhpZ2gNCiAgKQ0KDQpkZWZpbmUgZnVuY3Rpb24gIkdldCBDb25maXJtZWQgUGF0aWVudCBJRHMgaW4gQmVkIExvY2F0aW9uIEFib3ZlIFNwZWNpZmllZCBBZ2UiKCBQYXRpZW50SURzIExpc3Q8RkhJUi5SZWZlcmVuY2U+LCBhZ2UgU3lzdGVtLkludGVnZXIgKToNCiAgUGF0aWVudElEcyBQYXRpZW50SUQNCiAgd2hlcmUgZXhpc3RzKA0KICAgICJQYXRpZW50cyIgUGF0aWVudHMNCiAgICBsZXQgUGF0aWVudEFnZTogQ2FsY3VsYXRlQWdlSW5ZZWFyc0F0KCBQYXRpZW50cy5iaXJ0aERhdGUsIHN0YXJ0IG9mICJNZWFzdXJlbWVudCBQZXJpb2QiICkNCiAgICB3aGVyZSBQYXRpZW50cy5pZCA9IEdldElkKCBQYXRpZW50SUQucmVmZXJlbmNlICkNCiAgICBhbmQgUGF0aWVudEFnZSA+PSBhZ2UNCiAgKQ0KDQpkZWZpbmUgZnVuY3Rpb24gIkdldCBDb25maXJtZWQgUGF0aWVudCBJRHMgaW4gQmVkIExvY2F0aW9uIGFuZCBVbmtub3duIEFnZSIoIFBhdGllbnRJRHMgTGlzdDxGSElSLlJlZmVyZW5jZT4gKToNCiAgUGF0aWVudElEcyBQYXRpZW50SUQNCiAgd2hlcmUgZXhpc3RzKA0KICAgICJQYXRpZW50cyIgUGF0aWVudHMNCiAgICB3aGVyZSBQYXRpZW50cy5pZCA9IEdldElkKCBQYXRpZW50SUQucmVmZXJlbmNlICkNCiAgICBhbmQgUGF0aWVudHMuYmlydGhEYXRlID0gbnVsbA0KICApDQoNCmRlZmluZSBmdW5jdGlvbiAiR2V0Q29uZGl0aW9uIiggcmVmZXJlbmNlIFJlZmVyZW5jZSApOg0KICBzaW5nbGV0b24gZnJvbSAoDQoJW0NvbmRpdGlvbl0gQ29uZGl0aW9ucw0KCQl3aGVyZSBDb25kaXRpb25zLmlkID0gR2V0SWQoIHJlZmVyZW5jZS5yZWZlcmVuY2UgKQ0KICApDQoNCmRlZmluZSBmdW5jdGlvbiAiR2V0SWQiKCB1cmkgU3RyaW5nICk6DQogIExhc3QoU3BsaXQodXJpLCAnLycpKQ0KDQpkZWZpbmUgZnVuY3Rpb24gIk5vcm1hbGl6ZSBJbnRlcnZhbCIoIGNob2ljZSBDaG9pY2U8RkhJUi5kYXRlVGltZSwgRkhJUi5QZXJpb2QsIEZISVIuVGltaW5nLCBGSElSLmluc3RhbnQ+ICk6DQogIGNhc2UNCgkgIHdoZW4gY2hvaWNlIGlzIEZISVIuZGF0ZVRpbWUgdGhlbg0KICAgIAlJbnRlcnZhbFtGSElSSGVscGVycy5Ub0RhdGVUaW1lKGNob2ljZSBhcyBGSElSLmRhdGVUaW1lKSwgRkhJUkhlbHBlcnMuVG9EYXRlVGltZShjaG9pY2UgYXMgRkhJUi5kYXRlVGltZSldDQoJCXdoZW4gY2hvaWNlIGlzIEZISVIuUGVyaW9kIHRoZW4NCiAgCQlGSElSSGVscGVycy5Ub0ludGVydmFsKGNob2ljZSBhcyBGSElSLlBlcmlvZCkNCgkJd2hlbiBjaG9pY2UgaXMgRkhJUi5pbnN0YW50IHRoZW4NCgkJCUludGVydmFsW0ZISVJIZWxwZXJzLlRvRGF0ZVRpbWUoY2hvaWNlIGFzIEZISVIuaW5zdGFudCksIEZISVJIZWxwZXJzLlRvRGF0ZVRpbWUoY2hvaWNlIGFzIEZISVIuaW5zdGFudCldDQoJCXdoZW4gY2hvaWNlIGlzIEZISVIuVGltaW5nIHRoZW4NCgkJICBNZXNzYWdlKG51bGwgYXMgSW50ZXJ2YWw8RGF0ZVRpbWU+LCB0cnVlLCAnMScsICdFcnJvcicsICdDYW5ub3QgY29tcHV0ZSBhIHNpbmdsZSBpbnRlcnZhbCBmcm9tIGEgVGltaW5nIHR5cGUnKQ0KCQllbHNlDQoJCQludWxsIGFzIEludGVydmFsPERhdGVUaW1lPg0KCWVuZA0KDQpkZWZpbmUgIkVuY291bnRlckNoZWNrIjoNCiAgZXhpc3RzKCJFbmNvdW50ZXJzIiBFbmNvdW50ZXJzDQogIHdoZXJlIEVuY291bnRlcnMucGVyaW9kIG92ZXJsYXBzICJNZWFzdXJlbWVudCBQZXJpb2QiKQ0KDQpkZWZpbmUgIkxvY2F0aW9uSXNIT1NQIjoNCiAgZXhpc3RzKA0KICAgIExvY2F0aW9uLnR5cGUgdHlwZXMNCiAgICB3aGVyZSB0eXBlcyB+ICJIT1NQIg0KICApDQoNCmRlZmluZSAiTG9jYXRpb25Jc0lQRiI6DQogIGV4aXN0cygNCiAgICBMb2NhdGlvbi50eXBlIHR5cGVzDQogICAgd2hlcmUgdHlwZXMgfiAiSVBGIg0KICApDQoNCmRlZmluZSAiTG9jYXRpb25Jc0lSRiI6DQogIGV4aXN0cygNCiAgICBMb2NhdGlvbi50eXBlIHR5cGVzDQogICAgd2hlcmUgdHlwZXMgfiAiSVJGIg0KICApDQoNCmRlZmluZSAiTG9jYXRpb25Jc0NITEQiOg0KICBleGlzdHMoDQogICAgTG9jYXRpb24udHlwZSB0eXBlcw0KICAgIHdoZXJlIHR5cGVzIH4gIkNITEQiDQogICkNCg0KZGVmaW5lICJMb2NhdGlvbklzT1RIIjoNCiAgZXhpc3RzKA0KICAgIExvY2F0aW9uLnR5cGUgdHlwZXMNCiAgICB3aGVyZSB0eXBlcyB+ICJPVEgiDQogICk="/>
</content>
</Library>