1. Introduction

\(~\)

This document was inspired from sitting in a ton of meetings with the federal and state natural resource agencies, and noticing that their is a big issue with how agencies manage the data they receive from consultant companies and licensee holders. From those out of the loop and coming across this document, most natural resource agencies don’t typically go out and do all the surveying for threatened, endangered, or special interest species, but provide opportunity for biological consultants, academics, and different agency biologists to go out and perform surveys under direction and with license/permit from both federal and state agencies. Those licenses/permits typically have a clause in them to report surveying data back to the agencies. The issue here is that it seems that the responsibility to submit data to the agencies falls heavily on the licensee holder, which in a way I agree since agencies are giving out these licenses with requirements, however, because different levels of agencies require different formats to submit their data it creates a cumbersome task on the licensee holder that typically causes a lesser quality of submitted data. When agencies have differences in their submission of data, this creates a duplication of effort on the licensee holders to take their survey results and have to write it into different reports multiple times for each agency, submit data in different excel sheets, through applications, with all opening up the opportunity for errors to enter submitted data. In addition, another cause for creating errors in data is that each agency also want different fields of data to be collected during surveys. On the agencies side, their is a disparity for how data is managed once received from the licensee holders.

\(~\)

Finally, we may be able to correct this problemed relationship between the licensees and the agencies with adopting some of the techniques used by the large tech companies of today. My suggested solution to the problem is to create a standard field-biology-workflow from the consultants to the agencies using a little bit of ESRI (The standard GIS Applications) and a playbook with R (My preferred coding language). Since most biologists today are familiar with using ESRI products, especially with surveyors and their collecting applications, I am going to use these applications as the starting point for this document. In addition, since most biologist joining the workforce from academia now days are coming out of college with a strong background in the R coding language with Rstudio, this standard should be more easily adopted.

\(~\)

If you are one who is not familiar with R & Rstudio, I suggest you watch this quick video.🤩

\(~\)

2. The Framework

\(~\)

  1. Create your collecting application templates easily with Survey123 or Field Maps

  2. Share the geodatabase online through ArcGIS Online

  3. Import the geodatabase into R using the r package arc-binding

  4. Use standard data management techniques with r and tidyverse one can easily format the geodatabase into a variety of formats from excel spreadsheet, to any GIS file (i.e. shp, kml, ,gpkg, gbd), or even write the data into a document

  5. Files written out can then be sent to the appropriate agencies with exact file specifications, and/or being implemented easily into the appropriate agencies databases

\(~\)

3. Proof of Concept

\(~\)

A) Collecting application

\(~\)

\(~\)

To start this proof of concept here is the collecting application I created based on the needed values for the SCL-App for the Arizona Game & Fish Scientific Collecting License requirements. If you are not familiar with the SCL-App it is the new way to submit your species observation data to complete the requirements needed for the AZGFD Scientific Collecting License. Basically, you fill out the excel template and import the information to the app, go through some formatting checks, and the data is submitted to the AZGFD Heritage Database Management System. Pretty easy process, but it could be improved on since there can be a disconnect from the information collected by the licensee and the information needed to be turned in. Since there is a growing demand of biologists using these field collecting application, I decided I should create a template. The idea here is to have templates available from each agency, and licensee holders download the contents of the templates to create their own with all the different fields agencies want them to collect.

\(~\)

Here is the LINK of a survey123 template of for the SCL-App. Because this is only a template I will provide the excel information used to create it within the field-biologist-workflow repository under the survey123_connect folder.

[Please only look through the application and DO NOT submit any actual observations!!]

\(~\)

I) R-arcgis-binding

\(~\)

With the r Package arcbinding, users of ESRI products (i.e. Collector, Survey123, and anything hosted on ArcGIS Online) are now available and can be easily download with the built in R package API. What this means, is that we can import data from ArcGIS Online and format it to be used in a variety of other applications and easily be imported to addition databases with various requirements.

\(~\)

  1. Let’s call in arcgisbinding library hosted on CRAN and have it check our ESRI licensing!
library(arcgisbinding)
arc.check_product()
## product: ArcGIS Pro (12.6.0.24783)
## license: Advanced
## version: 1.0.1.244

\(~\)

  1. Let’s connect to ArcGIS Online, specifically my own agencies, where we have I have hosted the Survey123 Feature Service.

    If you are unaware of what feature services are with ArcGIS Online CLICK HERE

\(~\)

# This is an R script that just has my username and password
source("code/private_creds.R")

# These two functions are to check which AGO account you are linked to and then link to the correct one for the entire R session
#arc.check_portal()
arc.portal_connect("https://www.arcgis.com", username, password)
## *** Current
##   url        : https://www.arcgis.com/
##   version    : 8.4
##   user       : hdms_azgfd
##   organization   : Arizona Game and Fish Department 
## *** Not signed in
##   'https://apsu-gis.maps.arcgis.com/'

\(~\)

  1. Now, I will connect to the specific Survey123 Feature service URL

\(~\)

survey123<-arc.open("https://services2.arcgis.com/os1CphwIyxBDDUGn/arcgis/rest/services/service_e01fa7de2a984533be6ebf7c7b02e412/FeatureServer/0")

\(~\)

  1. With the arcbinding package we can correct the data into a standard R spatial dataframe, so we can format it into any parameters we need!

\(~\)

scl_arc <- arc.select(survey123) 
survey_data <- arc.data2sf(scl_arc)

datatable(survey_data, rownames = F, options = list(pageLength = 5, scrollX=T))

\(~\)

B) R Data Management

\(~\)

Utilizing the power of R to format the imported spatial dataframe from the ArcGIS Feature Service, we can easily split up the data into the appropriate file types or remove and maybe add more columns if needed.

\(~\)

I) Writing the data to xlsx template

\(~\)

Let’s do an example of R data management by converting our collected data into an xlsx template. Since, I work for the HDMS Division and am running development for the AZGFD SCL app, I am going to show you how to format our survey123 app data into the SCL app xlsx template.

\(~\)

# Read in the Template
xlsx_template <-read_excel("scl-template/scl-report-template.xlsx", sheet = "Report Form") 

# Filter and correct the survey_data to fit the template
xlsx_prep <- survey_data[, c("observer", "scientific_name", "common_name", "count_obs", "date_observered", "County_", 
                            "longitude", "latitude", "Lifestage", "Sex", "Disposition", "Museum", "Marked", 
                           "Field_Tag", "Habitat_Description", "other_locality_data", "Comments")] %>% st_drop_geometry()

# Make sure they have the correct value types

xlsx_template <- xlsx_template %>% mutate(across(everything(), as.character))
xlsx_prep <- xlsx_prep %>% mutate(across(everything(), as.character))
# Correct the names to the template

colnames(xlsx_prep)<- c("Observer (collecting, handling and/or surveying)",
                        "Scientific Name",
                        "Common Name",
                        "Count",
                        "Date\r\n(YYYY-MM-DD)",
                        "County",
                        "EXACT LOCATION\r\nX coordinate - easting or longitude (e.g., -111.1234)",
                        "EXACT LOCATION\r\nY coordinate - northing or latitude (e.g., 33.1234)",
                        "Lifestage",
                        "Sex",
                        "Disposition",
                        "Museum",
                        "Marked",
                        "Field Tag",
                        "Habitat Description",
                        "Other locality data",
                        "Comments (reproductive status, behavior, etc.)")
                        

# Now just Append the prepared data to the template
xlsx_final <- bind_rows(xlsx_template,xlsx_prep)

# Add in the other needed info missing from the survey_data
xlsx_final <- xlsx_final %>% mutate(Datum = "WGS84") %>% 
  mutate(`Coorindate Type (DD, DMS, DDM, UTM, or SP)` = "DD")

# Now Lets Append this new data collected by the survey123 app to the scl-app template
scl_xlsx_template <- readWorkbook("scl-template/scl-report-template.xlsx", sheet = "Report Form")
new.data <- rbind(scl_xlsx_template, xlsx_final)

#write updated data frame to existing worksheet
wb = loadWorkbook("scl-template/scl-report-template.xlsx")
writeData(wb, "Report Form", new.data)

# Save file to finished product
saveWorkbook(wb, "scl-template/scl-report-final.xlsx", overwrite = TRUE)

\(~\)

After, this code chunk is run you can see it spits out the final xlsx into the designated folder. From there, you can simply take the spreadsheet and upload it the the Arizona Game & Fish Dept. SCL-App and Voilà you have finished your compliance with your AZGFD license requirements!!!😍

\(~\)

II) Writing the data to a document

\(~\)

What if you need to use that data collected and create a report for the requirements of your permitting, well R can do that too! Now, if you didn’t know Survey123 also has that capability, and if you want to know more about how to do that here is the LINK . Trust me though, it’s not as intuitive as ESRI claims it to be and you have to use Microsoft Word to make these reports which can cause more issues then it solves and it is very limiting!! Anywho, the more automated and free to play move is to use Rmarkdown and write out the template and Rmarkdown will write out the data collected to it!! So, let me show you how this can be structured.

\(~\)

Now a quick disclaimer is that I am still learning all about the licensee requirement processes with the states and feds, so I am more showing how this is possible than writing to a particular formatted document like a NEPA Environmental Assessment.

\(~\)

Rmarkdown is a file format for making dynamic documents that can be used to create updating documents with new data to increasingly complex documents with html widgets and coding demos. To give you a quick idea of how complex you can make these documents, technically the document you are reading right now is made with rmarkdown. What I’m suggesting us to use is the html function of Rmarkdown to create a report out of the survey123 data we collected without actually adding in the information besides calling in to the table. Now, Rmarkdown can create pdf documents, but these pose to be forever limiting and you have to go down the rabbit hole of LATEX to get it to look the way you want it to. The benefits of Rmarkdown is once the document is structured all you need to do is knit the .Rmd file and you have your report to send to any of the agencies requiring documentation, and never have to waste the extensive time to write out a report over and over again. The drawback is you need to get familiar with the Rstudio environment and to make it look pretty you have to dip your feet into html and css.

\(~\)

So, within this tutorial documentation, I created a .Rmd file within the rmarkdown-template folder titled “species_account_template.Rmd”, which all content in this folder will give you a quick tutorial of how to structure the data within the document format. Obviously, this document isn’t the most pretty, but if you take the time to structure the css and html you can get a very appealing document. And remember you only need to structure it once, because you can reproduce the template with new data with a click of the knit button.

\(~\)

Below, is my example of how you can quick write out these reports!!

\(~\)

If you are still nervous about creating html becasue you rather have a pdf document, its much easier to convert an html document to a pdf then it is to actually knit an rmarkdown doc, you can even do it through R if the html doc is hosted like mine was. Here is the code below, and you can find the pdf output in the img folder in this repository.

\(~\)

# Here is the example of how you would turn that live html to a pdf doc
##webshot("https://jkauphus.github.io/species_account_template/", "img/doc-template.pdf")

\(~\)

III) Writing the data to a database

\(~\)

This section of the document will attempt to explain a quick overview of a better way for both agencies and licensee holders to collect data and store it to be better organized, easily searchable, and quickly able to grab and send out data. What I have seen throughout my career from both the academic side and agency side is there is a huge disjunct of how groups manage and view databases. Now from my perspective, most people try to avoid learning any coding language and pay for services that honestly don’t do a great job of keeping an organized database. Specifically, I’m talking about ESRI geodatabases, Microsoft Access, and I’ve even seen agencies use a folder system locally or on a cloud service as a “database”, which all lack the ability to easily search and quickly grab and send out data. If we want to create a simpler workflow for field-biologists we should as a group use Open Source SQL databases.

\(~\)

I propose both licensees, consultants, academics, and agencies to adapt this standardized idea of creating your own Open source SQL database. Below, I will outline the steps to create these databases, and show how R can integrate into these databases to easily pull, push, and send out data. From there, all you need to do is set up the infrastructure, and life with adding and sending out data gets so much easier since all you will need to do is manage it with R.

\(~\)

  • Pick a Open source SQL database that works with the DBI R package, I prefer to use Postgresql with pgAdmin, however, DBI also uses SQLite, Microsoft ODBC, and Google BigQuery

    • Wanna learn about Postgresql and pgAdmin check out this video 👋

\(~\)

  • In Rstudio, download the DBI package along with the sub-package of the database you selected and walk through how to link them to your databases

\(~\)

# This example is using the Arizona HDMS Postgresql setup

# Simply download the DBI package in Rstudio

##install.packages("DBI")

# Then go through and download your sub package

##install.packages("RPostgres")

# From there Go through this set up

library(DBI)

db <- 'DATABASE'  #provide the name of your db

host_db <- ‘HOST’ #i.e. # i.e. 'ec2-54-83-201-96.compute-1.amazonaws.com'  

db_port <- '98939'  # or any other port specified by the DBA

db_user <- USERNAME  

db_password <- ‘PASSWORD’

con <- dbConnect(RPostgres::Postgres(), dbname = db, host=host_db, port=db_port, user=db_user, password=db_password) 

# Then you can check if it's connected with the list of tablesyou have in the database

dbListTables(con) 

\(~\)

  • Now, you can easily pull in data to R or push data up into the database.

\(~\)

# Pull data from the SQL database to R
dbGetQuery(con, ‘SELECT * FROM table’)  # see the SQL statements you can get very precise with this one

# Push data from R that you doctored up to the database
dbWriteTable(con, "newdata", newdata)

# Note these databases can take a variety of data including shapefiles so if we wanted to move our survey123 data to the database we can easily append it to an existing table or create a new one. 

dbWriteTable(con, "existing-table", survey123, append = TRUE)

\(~\)

Hopefully, you can see the utility of using these databases to stay organized and easily push and pull data for R to do some data-management, but you are probably thinking as a licensee holder, “how can these databases be used to help me with submitting my data to the agencies?”

\(~\)

Well, if and hopefully when more and more agencies adopt these SQL open source databases, they can set up a system for you to directly upload your permit data into a temporary table in their databases, via maybe a self created R package, and the agencies can then double check the data with some sort of version control system like an rShiny App and file it into their preferred database table with documenting that you have submitted data.

\(~\)

Of course, this last section of the proof of concept is to hopefully show that the sky is the limit when it comes to coding with R and using open source software over the standard subscription licenses. In addition, I hope this last section on databases can create a more productive dialogue of where agencies should look to for standardizing and organizing their data better, so it is easier for licensee holders to submit the data once in the correct way. This should reduce the confusion between the two and reduce the hassle of having to send emails back and forth trying to piece together who needs to submit, who didn’t submit correctly, or why is submitting to all these agencies such a huge process!!

\(~\)

4. Conclusion

\(~\)

By now, I hope I have at least given you a good plan of action, or at the very least set up a needed discussion, of how to make the relationship with licensee holders and agencies better. Since, all agencies and most licensee holders love these collector applications from ESRI, I figured we need to as a biologist community jump on and help support these applications to be more easily integrated into our licensing requirements with submitting data, because the whole entire purpose of this submission of data is to be used to make inferences to help conservation of our countries species!!😃

\(~\)

With that, I would like to thank anyone who has taken the time to go though this document in its entirety, and if you have any questions about anything that was mentioned or went over in this document to please email me at jkauphusman@azgfd.gov. For the rest of the documentation, you can download or clone the git repository at Field-Biology-Workflow.

\(~\)

Thank You!!

LS0tDQp0aXRsZTogIlRoZSBGaWVsZCBCaW9sb2d5IFdvcmtmbG93Ig0KYXV0aG9yOiB8DQogICFbXShpbWcvaGV4LUhETVMucG5nKXtoZWlnaHQ9MmluLCB3aWR0aD0yaW59ICANCiAgW0J5OiBKYWNrIEthdXBodXNtYW5dKGh0dHBzOi8vZ2l0aHViLmNvbS9qa2F1cGh1cykNCmRhdGU6ICJMYXN0IHVwZGF0ZWQ6IGByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICBjc3M6IGNzcy9zdHlsZS5jc3MNCiAgICB0aGVtZTogcmVhZGFibGUNCiAgICBoaWdobGlnaHQ6IHplbmJ1cm4NCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogeWVzDQogICAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlDQogICAgY29kZV9mb2xkaW5nOiANCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBkZl9wcmludDogdGliYmxlDQotLS0NCg0KYGBge3IgUGFja2FnZXMgVXNlZCwgaW5jbHVkZT1GQUxTRX0NCiMgUGFja2FnZXMgVXNlZA0KbGlicmFyeShrbml0cikNCmxpYnJhcnkod2Vic2hvdCkNCmxpYnJhcnkoRFQpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkob3Blbnhsc3gpDQpsaWJyYXJ5KGV4Y2VsUikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShzZikNCmBgYA0KDQojIyMgMS4gSW50cm9kdWN0aW9uDQoNCiR+JA0KDQpUaGlzIGRvY3VtZW50IHdhcyBpbnNwaXJlZCBmcm9tIHNpdHRpbmcgaW4gYSB0b24gb2YgbWVldGluZ3Mgd2l0aCB0aGUgZmVkZXJhbCBhbmQgc3RhdGUgbmF0dXJhbCByZXNvdXJjZSBhZ2VuY2llcywgYW5kIG5vdGljaW5nIHRoYXQgdGhlaXIgaXMgYSBiaWcgaXNzdWUgd2l0aCBob3cgYWdlbmNpZXMgbWFuYWdlIHRoZSBkYXRhIHRoZXkgcmVjZWl2ZSBmcm9tIGNvbnN1bHRhbnQgY29tcGFuaWVzIGFuZCBsaWNlbnNlZSBob2xkZXJzLiBGcm9tIHRob3NlIG91dCBvZiB0aGUgbG9vcCBhbmQgY29taW5nIGFjcm9zcyB0aGlzIGRvY3VtZW50LCBtb3N0IG5hdHVyYWwgcmVzb3VyY2UgYWdlbmNpZXMgZG9uJ3QgdHlwaWNhbGx5IGdvIG91dCBhbmQgZG8gYWxsIHRoZSBzdXJ2ZXlpbmcgZm9yIHRocmVhdGVuZWQsIGVuZGFuZ2VyZWQsIG9yIHNwZWNpYWwgaW50ZXJlc3Qgc3BlY2llcywgYnV0IHByb3ZpZGUgb3Bwb3J0dW5pdHkgZm9yIGJpb2xvZ2ljYWwgY29uc3VsdGFudHMsIGFjYWRlbWljcywgYW5kIGRpZmZlcmVudCBhZ2VuY3kgYmlvbG9naXN0cyB0byBnbyBvdXQgYW5kIHBlcmZvcm0gc3VydmV5cyB1bmRlciBkaXJlY3Rpb24gYW5kIHdpdGggbGljZW5zZS9wZXJtaXQgZnJvbSBib3RoIGZlZGVyYWwgYW5kIHN0YXRlIGFnZW5jaWVzLiBUaG9zZSBsaWNlbnNlcy9wZXJtaXRzIHR5cGljYWxseSBoYXZlIGEgY2xhdXNlIGluIHRoZW0gdG8gcmVwb3J0IHN1cnZleWluZyBkYXRhIGJhY2sgdG8gdGhlIGFnZW5jaWVzLiBUaGUgaXNzdWUgaGVyZSBpcyB0aGF0IGl0IHNlZW1zIHRoYXQgdGhlIHJlc3BvbnNpYmlsaXR5IHRvIHN1Ym1pdCBkYXRhIHRvIHRoZSBhZ2VuY2llcyBmYWxscyBoZWF2aWx5IG9uIHRoZSBsaWNlbnNlZSBob2xkZXIsIHdoaWNoIGluIGEgd2F5IEkgYWdyZWUgc2luY2UgYWdlbmNpZXMgYXJlIGdpdmluZyBvdXQgdGhlc2UgbGljZW5zZXMgd2l0aCByZXF1aXJlbWVudHMsIGhvd2V2ZXIsIGJlY2F1c2UgZGlmZmVyZW50IGxldmVscyBvZiBhZ2VuY2llcyByZXF1aXJlIGRpZmZlcmVudCBmb3JtYXRzIHRvIHN1Ym1pdCB0aGVpciBkYXRhIGl0IGNyZWF0ZXMgYSBjdW1iZXJzb21lIHRhc2sgb24gdGhlIGxpY2Vuc2VlIGhvbGRlciB0aGF0IHR5cGljYWxseSBjYXVzZXMgYSBsZXNzZXIgcXVhbGl0eSBvZiBzdWJtaXR0ZWQgZGF0YS4gV2hlbiBhZ2VuY2llcyBoYXZlIGRpZmZlcmVuY2VzIGluIHRoZWlyIHN1Ym1pc3Npb24gb2YgZGF0YSwgdGhpcyBjcmVhdGVzIGEgZHVwbGljYXRpb24gb2YgZWZmb3J0IG9uIHRoZSBsaWNlbnNlZSBob2xkZXJzIHRvIHRha2UgdGhlaXIgc3VydmV5IHJlc3VsdHMgYW5kIGhhdmUgdG8gd3JpdGUgaXQgaW50byBkaWZmZXJlbnQgcmVwb3J0cyBtdWx0aXBsZSB0aW1lcyBmb3IgZWFjaCBhZ2VuY3ksIHN1Ym1pdCBkYXRhIGluIGRpZmZlcmVudCBleGNlbCBzaGVldHMsIHRocm91Z2ggYXBwbGljYXRpb25zLCB3aXRoIGFsbCBvcGVuaW5nIHVwIHRoZSBvcHBvcnR1bml0eSBmb3IgZXJyb3JzIHRvIGVudGVyIHN1Ym1pdHRlZCBkYXRhLiBJbiBhZGRpdGlvbiwgYW5vdGhlciBjYXVzZSBmb3IgY3JlYXRpbmcgZXJyb3JzIGluIGRhdGEgaXMgdGhhdCBlYWNoIGFnZW5jeSBhbHNvIHdhbnQgZGlmZmVyZW50IGZpZWxkcyBvZiBkYXRhIHRvIGJlIGNvbGxlY3RlZCBkdXJpbmcgc3VydmV5cy4gT24gdGhlIGFnZW5jaWVzIHNpZGUsIHRoZWlyIGlzIGEgZGlzcGFyaXR5IGZvciBob3cgZGF0YSBpcyBtYW5hZ2VkIG9uY2UgcmVjZWl2ZWQgZnJvbSB0aGUgbGljZW5zZWUgaG9sZGVycy4NCg0KJH4kDQoNCkZpbmFsbHksIHdlIG1heSBiZSBhYmxlIHRvIGNvcnJlY3QgdGhpcyBwcm9ibGVtZWQgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIGxpY2Vuc2VlcyBhbmQgdGhlIGFnZW5jaWVzIHdpdGggYWRvcHRpbmcgc29tZSBvZiB0aGUgdGVjaG5pcXVlcyB1c2VkIGJ5IHRoZSBsYXJnZSB0ZWNoIGNvbXBhbmllcyBvZiB0b2RheS4gTXkgc3VnZ2VzdGVkIHNvbHV0aW9uIHRvIHRoZSBwcm9ibGVtIGlzIHRvIGNyZWF0ZSBhIHN0YW5kYXJkIGZpZWxkLWJpb2xvZ3ktd29ya2Zsb3cgZnJvbSB0aGUgY29uc3VsdGFudHMgdG8gdGhlIGFnZW5jaWVzIHVzaW5nIGEgbGl0dGxlIGJpdCBvZiBFU1JJIChUaGUgc3RhbmRhcmQgR0lTIEFwcGxpY2F0aW9ucykgYW5kIGEgcGxheWJvb2sgd2l0aCBSIChNeSBwcmVmZXJyZWQgY29kaW5nIGxhbmd1YWdlKS4gU2luY2UgbW9zdCBiaW9sb2dpc3RzIHRvZGF5IGFyZSBmYW1pbGlhciB3aXRoIHVzaW5nIEVTUkkgcHJvZHVjdHMsIGVzcGVjaWFsbHkgd2l0aCBzdXJ2ZXlvcnMgYW5kIHRoZWlyIGNvbGxlY3RpbmcgYXBwbGljYXRpb25zLCBJIGFtIGdvaW5nIHRvIHVzZSB0aGVzZSBhcHBsaWNhdGlvbnMgYXMgdGhlIHN0YXJ0aW5nIHBvaW50IGZvciB0aGlzIGRvY3VtZW50LiBJbiBhZGRpdGlvbiwgc2luY2UgbW9zdCBiaW9sb2dpc3Qgam9pbmluZyB0aGUgd29ya2ZvcmNlIGZyb20gYWNhZGVtaWEgbm93IGRheXMgYXJlIGNvbWluZyBvdXQgb2YgY29sbGVnZSB3aXRoIGEgc3Ryb25nIGJhY2tncm91bmQgaW4gdGhlIFIgY29kaW5nIGxhbmd1YWdlIHdpdGggUnN0dWRpbywgdGhpcyBzdGFuZGFyZCBzaG91bGQgYmUgbW9yZSBlYXNpbHkgYWRvcHRlZC4NCg0KJH4kDQoNCklmIHlvdSBhcmUgb25lIHdobyBpcyBub3QgZmFtaWxpYXIgd2l0aCBSICYgUnN0dWRpbywgSSBzdWdnZXN0IHlvdSB3YXRjaCBbWyoqdGhpcyBxdWljayB2aWRlby4qKl17LnVsfV0oaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1sVktNc2FXanU4dyZhbXA7dD01MnMp8J+kqQ0KDQokfiQNCg0KIyMjIDIuIFRoZSBGcmFtZXdvcmsNCg0KOjo6IHsuY2VudGVyfQ0KIVtdKGltZy93b3JrZmxvdy5wbmcpe3dpZHRoPSI2NzcifQ0KOjo6DQoNCiR+JA0KDQoxLiAgQ3JlYXRlIHlvdXIgY29sbGVjdGluZyBhcHBsaWNhdGlvbiB0ZW1wbGF0ZXMgZWFzaWx5IHdpdGggPGEgaHJlZj0iaHR0cHM6Ly9zdXJ2ZXkxMjMuYXJjZ2lzLmNvbS8iPiBTdXJ2ZXkxMjM8L2E+IG9yIDxhIGhyZWYgPSAiaHR0cHM6Ly93d3cuZXNyaS5jb20vZW4tdXMvYXJjZ2lzL3Byb2R1Y3RzL2FyY2dpcy1maWVsZC1tYXBzL292ZXJ2aWV3Ij4gRmllbGQgTWFwczwvYT4NCg0KMi4gIFNoYXJlIHRoZSBnZW9kYXRhYmFzZSBvbmxpbmUgdGhyb3VnaCA8YSBocmVmPSJodHRwczovL3d3dy5hcmNnaXMuY29tLyI+IEFyY0dJUyBPbmxpbmU8L2E+DQoNCjMuICBJbXBvcnQgdGhlIGdlb2RhdGFiYXNlIGludG8gUiB1c2luZyB0aGUgciBwYWNrYWdlIDxhIGhyZWY9Imh0dHBzOi8vci5lc3JpLmNvbS9hc3NldHMvYXJjZ2lzYmluZGluZy12aWduZXR0ZS5odG1sIj4gYXJjLWJpbmRpbmcgPC9hPg0KDQo0LiAgVXNlIHN0YW5kYXJkIGRhdGEgbWFuYWdlbWVudCB0ZWNobmlxdWVzIHdpdGggciBhbmQgdGlkeXZlcnNlIG9uZSBjYW4gZWFzaWx5IGZvcm1hdCB0aGUgZ2VvZGF0YWJhc2UgaW50byBhIHZhcmlldHkgb2YgZm9ybWF0cyBmcm9tIGV4Y2VsIHNwcmVhZHNoZWV0LCB0byBhbnkgR0lTIGZpbGUgKGkuZS4gc2hwLCBrbWwsICxncGtnLCBnYmQpLCBvciBldmVuIHdyaXRlIHRoZSBkYXRhIGludG8gYSBkb2N1bWVudA0KDQo1LiAgRmlsZXMgd3JpdHRlbiBvdXQgY2FuIHRoZW4gYmUgc2VudCB0byB0aGUgYXBwcm9wcmlhdGUgYWdlbmNpZXMgd2l0aCBleGFjdCBmaWxlIHNwZWNpZmljYXRpb25zLCBhbmQvb3IgYmVpbmcgaW1wbGVtZW50ZWQgZWFzaWx5IGludG8gdGhlIGFwcHJvcHJpYXRlIGFnZW5jaWVzIGRhdGFiYXNlcw0KDQokfiQNCg0KIyMjIDMuIFByb29mIG9mIENvbmNlcHQNCg0KJH4kDQoNCiMjIyMgQSkgQ29sbGVjdGluZyBhcHBsaWNhdGlvbg0KDQokfiQNCg0KOjo6IHsuY2VudGVyfQ0KIVtdKGltZy9zdXJ2ZXkxMjMucG5nKXt3aWR0aD0iMjU1In0NCjo6Og0KDQokfiQNCg0KVG8gc3RhcnQgdGhpcyBwcm9vZiBvZiBjb25jZXB0IGhlcmUgaXMgdGhlIGNvbGxlY3RpbmcgYXBwbGljYXRpb24gSSBjcmVhdGVkIGJhc2VkIG9uIHRoZSBuZWVkZWQgdmFsdWVzIGZvciB0aGUgU0NMLUFwcCBmb3IgdGhlIEFyaXpvbmEgR2FtZSAmIEZpc2ggU2NpZW50aWZpYyBDb2xsZWN0aW5nIExpY2Vuc2UgcmVxdWlyZW1lbnRzLiBJZiB5b3UgYXJlIG5vdCBmYW1pbGlhciB3aXRoIHRoZSBTQ0wtQXBwIGl0IGlzIHRoZSBuZXcgd2F5IHRvIHN1Ym1pdCB5b3VyIHNwZWNpZXMgb2JzZXJ2YXRpb24gZGF0YSB0byBjb21wbGV0ZSB0aGUgcmVxdWlyZW1lbnRzIG5lZWRlZCBmb3IgdGhlIEFaR0ZEIFNjaWVudGlmaWMgQ29sbGVjdGluZyBMaWNlbnNlLiBCYXNpY2FsbHksIHlvdSBmaWxsIG91dCB0aGUgZXhjZWwgdGVtcGxhdGUgYW5kIGltcG9ydCB0aGUgaW5mb3JtYXRpb24gdG8gdGhlIGFwcCwgZ28gdGhyb3VnaCBzb21lIGZvcm1hdHRpbmcgY2hlY2tzLCBhbmQgdGhlIGRhdGEgaXMgc3VibWl0dGVkIHRvIHRoZSBBWkdGRCBIZXJpdGFnZSBEYXRhYmFzZSBNYW5hZ2VtZW50IFN5c3RlbS4gUHJldHR5IGVhc3kgcHJvY2VzcywgYnV0IGl0IGNvdWxkIGJlIGltcHJvdmVkIG9uIHNpbmNlIHRoZXJlIGNhbiBiZSBhIGRpc2Nvbm5lY3QgZnJvbSB0aGUgaW5mb3JtYXRpb24gY29sbGVjdGVkIGJ5IHRoZSBsaWNlbnNlZSBhbmQgdGhlIGluZm9ybWF0aW9uIG5lZWRlZCB0byBiZSB0dXJuZWQgaW4uIFNpbmNlIHRoZXJlIGlzIGEgZ3Jvd2luZyBkZW1hbmQgb2YgYmlvbG9naXN0cyB1c2luZyB0aGVzZSBmaWVsZCBjb2xsZWN0aW5nIGFwcGxpY2F0aW9uLCBJIGRlY2lkZWQgSSBzaG91bGQgY3JlYXRlIGEgdGVtcGxhdGUuIFRoZSBpZGVhIGhlcmUgaXMgdG8gaGF2ZSB0ZW1wbGF0ZXMgYXZhaWxhYmxlIGZyb20gZWFjaCBhZ2VuY3ksIGFuZCBsaWNlbnNlZSBob2xkZXJzIGRvd25sb2FkIHRoZSBjb250ZW50cyBvZiB0aGUgdGVtcGxhdGVzIHRvIGNyZWF0ZSB0aGVpciBvd24gd2l0aCBhbGwgdGhlIGRpZmZlcmVudCBmaWVsZHMgYWdlbmNpZXMgd2FudCB0aGVtIHRvIGNvbGxlY3QuDQoNCiR+JA0KDQpIZXJlIGlzIHRoZSA8YSBocmVmPSJodHRwczovL3N1cnZleTEyMy5hcmNnaXMuY29tL3NoYXJlLzNhNTVhNWZkZWJmMDQ1NDA5M2YwNDRiM2E1MDY2NGRmIj4gKipMSU5LKio8L2E+IG9mIGEgc3VydmV5MTIzIHRlbXBsYXRlIG9mIGZvciB0aGUgU0NMLUFwcC4gQmVjYXVzZSB0aGlzIGlzIG9ubHkgYSB0ZW1wbGF0ZSBJIHdpbGwgcHJvdmlkZSB0aGUgZXhjZWwgaW5mb3JtYXRpb24gdXNlZCB0byBjcmVhdGUgaXQgd2l0aGluIHRoZSBmaWVsZC1iaW9sb2dpc3Qtd29ya2Zsb3cgcmVwb3NpdG9yeSB1bmRlciB0aGUgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2prYXVwaHVzL2ZpZWxkLWJpb2xvZ3ktd29ya2Zsb3ciPnN1cnZleTEyM19jb25uZWN0IGZvbGRlcjwvYT4uDQoNClsqKlBsZWFzZSBvbmx5IGxvb2sgdGhyb3VnaCB0aGUgYXBwbGljYXRpb24gYW5kIERPIE5PVCBzdWJtaXQgYW55IGFjdHVhbCBvYnNlcnZhdGlvbnMhISoqXQ0KDQokfiQNCg0KIyMjIyMgSSkgUi1hcmNnaXMtYmluZGluZw0KDQo6Ojogey5jZW50ZXJ9DQohW10oaW1nL2FyYy1yLmpwZyl7d2lkdGg9IjI1NCJ9DQo6OjoNCg0KJH4kDQoNCldpdGggdGhlIHIgUGFja2FnZSBhcmNiaW5kaW5nLCB1c2VycyBvZiBFU1JJIHByb2R1Y3RzIChpLmUuIENvbGxlY3RvciwgU3VydmV5MTIzLCBhbmQgYW55dGhpbmcgaG9zdGVkIG9uIEFyY0dJUyBPbmxpbmUpIGFyZSBub3cgYXZhaWxhYmxlIGFuZCBjYW4gYmUgZWFzaWx5IGRvd25sb2FkIHdpdGggdGhlIGJ1aWx0IGluIFIgcGFja2FnZSBBUEkuIFdoYXQgdGhpcyBtZWFucywgaXMgdGhhdCB3ZSBjYW4gaW1wb3J0IGRhdGEgZnJvbSBBcmNHSVMgT25saW5lIGFuZCBmb3JtYXQgaXQgdG8gYmUgdXNlZCBpbiBhIHZhcmlldHkgb2Ygb3RoZXIgYXBwbGljYXRpb25zIGFuZCBlYXNpbHkgYmUgaW1wb3J0ZWQgdG8gYWRkaXRpb24gZGF0YWJhc2VzIHdpdGggdmFyaW91cyByZXF1aXJlbWVudHMuDQoNCiR+JA0KDQoxLiAgTGV0J3MgY2FsbCBpbiBhcmNnaXNiaW5kaW5nIGxpYnJhcnkgaG9zdGVkIG9uIENSQU4gYW5kIGhhdmUgaXQgY2hlY2sgb3VyIEVTUkkgbGljZW5zaW5nIQ0KDQpgYGB7ciBwYWNrYWdlIGRvd25sb2FkLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KGFyY2dpc2JpbmRpbmcpDQphcmMuY2hlY2tfcHJvZHVjdCgpDQpgYGANCg0KJH4kDQoNCjIuICBMZXQncyBjb25uZWN0IHRvIEFyY0dJUyBPbmxpbmUsIHNwZWNpZmljYWxseSBteSBvd24gYWdlbmNpZXMsIHdoZXJlIHdlIGhhdmUgSSBoYXZlIGhvc3RlZCB0aGUgU3VydmV5MTIzIEZlYXR1cmUgU2VydmljZS4NCg0KICAgICoqSWYgeW91IGFyZSB1bmF3YXJlIG9mIHdoYXQgZmVhdHVyZSBzZXJ2aWNlcyBhcmUgd2l0aCBBcmNHSVMgT25saW5lKiogPGEgaHJlZj0iaHR0cHM6Ly9lbnRlcnByaXNlLmFyY2dpcy5jb20vZW4vc2VydmVyLzEwLjUvcHVibGlzaC1zZXJ2aWNlcy93aW5kb3dzL3doYXQtaXMtYS1mZWF0dXJlLXNlcnZpY2UtLmh0bSI+KipDTElDSyBIRVJFKio8L2E+DQogICAgDQokfiQNCg0KYGBge3IgY29ubmVjdGluZyB0byBBR08sIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIFRoaXMgaXMgYW4gUiBzY3JpcHQgdGhhdCBqdXN0IGhhcyBteSB1c2VybmFtZSBhbmQgcGFzc3dvcmQNCnNvdXJjZSgiY29kZS9wcml2YXRlX2NyZWRzLlIiKQ0KDQojIFRoZXNlIHR3byBmdW5jdGlvbnMgYXJlIHRvIGNoZWNrIHdoaWNoIEFHTyBhY2NvdW50IHlvdSBhcmUgbGlua2VkIHRvIGFuZCB0aGVuIGxpbmsgdG8gdGhlIGNvcnJlY3Qgb25lIGZvciB0aGUgZW50aXJlIFIgc2Vzc2lvbg0KI2FyYy5jaGVja19wb3J0YWwoKQ0KYXJjLnBvcnRhbF9jb25uZWN0KCJodHRwczovL3d3dy5hcmNnaXMuY29tIiwgdXNlcm5hbWUsIHBhc3N3b3JkKQ0KYGBgDQoNCiR+JA0KDQozLiAgTm93LCBJIHdpbGwgY29ubmVjdCB0byB0aGUgc3BlY2lmaWMgU3VydmV5MTIzIEZlYXR1cmUgc2VydmljZSBVUkwNCg0KJH4kDQoNCmBgYHtyIFNDTCBGaWVsZCBBcHAgVGVtcGxhdGUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpzdXJ2ZXkxMjM8LWFyYy5vcGVuKCJodHRwczovL3NlcnZpY2VzMi5hcmNnaXMuY29tL29zMUNwaHdJeXhCRERVR24vYXJjZ2lzL3Jlc3Qvc2VydmljZXMvc2VydmljZV9lMDFmYTdkZTJhOTg0NTMzYmU2ZWJmN2M3YjAyZTQxMi9GZWF0dXJlU2VydmVyLzAiKQ0KYGBgDQoNCiR+JA0KDQo0LiAgV2l0aCB0aGUgYXJjYmluZGluZyBwYWNrYWdlIHdlIGNhbiBjb3JyZWN0IHRoZSBkYXRhIGludG8gYSBzdGFuZGFyZCBSIHNwYXRpYWwgZGF0YWZyYW1lLCBzbyB3ZSBjYW4gZm9ybWF0IGl0IGludG8gYW55IHBhcmFtZXRlcnMgd2UgbmVlZCENCg0KJH4kDQoNCmBgYHtyIERvd25sb2FkaW5nIFN1cnZleSBEYXRhLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpzY2xfYXJjIDwtIGFyYy5zZWxlY3Qoc3VydmV5MTIzKSANCnN1cnZleV9kYXRhIDwtIGFyYy5kYXRhMnNmKHNjbF9hcmMpDQoNCmRhdGF0YWJsZShzdXJ2ZXlfZGF0YSwgcm93bmFtZXMgPSBGLCBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gNSwgc2Nyb2xsWD1UKSkNCmBgYA0KDQokfiQNCg0KIyMjIyBCKSBSIERhdGEgTWFuYWdlbWVudA0KDQokfiQNCg0KVXRpbGl6aW5nIHRoZSBwb3dlciBvZiBSIHRvIGZvcm1hdCB0aGUgaW1wb3J0ZWQgc3BhdGlhbCBkYXRhZnJhbWUgZnJvbSB0aGUgQXJjR0lTIEZlYXR1cmUgU2VydmljZSwgd2UgY2FuIGVhc2lseSBzcGxpdCB1cCB0aGUgZGF0YSBpbnRvIHRoZSBhcHByb3ByaWF0ZSBmaWxlIHR5cGVzIG9yIHJlbW92ZSBhbmQgbWF5YmUgYWRkIG1vcmUgY29sdW1ucyBpZiBuZWVkZWQuDQoNCiR+JA0KDQojIyMjIyBJKSBXcml0aW5nIHRoZSBkYXRhIHRvIHhsc3ggdGVtcGxhdGUNCg0KOjo6IHsuY2VudGVyfQ0KIVtdKGltZy9leGNlbF9yLnBuZyl7d2lkdGg9IjQ1MSJ9DQo6OjoNCg0KJH4kDQoNCkxldCdzIGRvIGFuIGV4YW1wbGUgb2YgUiBkYXRhIG1hbmFnZW1lbnQgYnkgY29udmVydGluZyBvdXIgY29sbGVjdGVkIGRhdGEgaW50byBhbiB4bHN4IHRlbXBsYXRlLiBTaW5jZSwgSSB3b3JrIGZvciB0aGUgSERNUyBEaXZpc2lvbiBhbmQgYW0gcnVubmluZyBkZXZlbG9wbWVudCBmb3IgdGhlIEFaR0ZEIFNDTCBhcHAsIEkgYW0gZ29pbmcgdG8gc2hvdyB5b3UgaG93IHRvIGZvcm1hdCBvdXIgc3VydmV5MTIzIGFwcCBkYXRhIGludG8gdGhlIFNDTCBhcHAgeGxzeCB0ZW1wbGF0ZS4NCg0KJH4kDQoNCmBgYHtyIGV4Y2VsIHRlbXBsYXRlLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBSZWFkIGluIHRoZSBUZW1wbGF0ZQ0KeGxzeF90ZW1wbGF0ZSA8LXJlYWRfZXhjZWwoInNjbC10ZW1wbGF0ZS9zY2wtcmVwb3J0LXRlbXBsYXRlLnhsc3giLCBzaGVldCA9ICJSZXBvcnQgRm9ybSIpIA0KDQojIEZpbHRlciBhbmQgY29ycmVjdCB0aGUgc3VydmV5X2RhdGEgdG8gZml0IHRoZSB0ZW1wbGF0ZQ0KeGxzeF9wcmVwIDwtIHN1cnZleV9kYXRhWywgYygib2JzZXJ2ZXIiLCAic2NpZW50aWZpY19uYW1lIiwgImNvbW1vbl9uYW1lIiwgImNvdW50X29icyIsICJkYXRlX29ic2VydmVyZWQiLCAiQ291bnR5XyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsb25naXR1ZGUiLCAibGF0aXR1ZGUiLCAiTGlmZXN0YWdlIiwgIlNleCIsICJEaXNwb3NpdGlvbiIsICJNdXNldW0iLCAiTWFya2VkIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiRmllbGRfVGFnIiwgIkhhYml0YXRfRGVzY3JpcHRpb24iLCAib3RoZXJfbG9jYWxpdHlfZGF0YSIsICJDb21tZW50cyIpXSAlPiUgc3RfZHJvcF9nZW9tZXRyeSgpDQoNCiMgTWFrZSBzdXJlIHRoZXkgaGF2ZSB0aGUgY29ycmVjdCB2YWx1ZSB0eXBlcw0KDQp4bHN4X3RlbXBsYXRlIDwtIHhsc3hfdGVtcGxhdGUgJT4lIG11dGF0ZShhY3Jvc3MoZXZlcnl0aGluZygpLCBhcy5jaGFyYWN0ZXIpKQ0KeGxzeF9wcmVwIDwtIHhsc3hfcHJlcCAlPiUgbXV0YXRlKGFjcm9zcyhldmVyeXRoaW5nKCksIGFzLmNoYXJhY3RlcikpDQojIENvcnJlY3QgdGhlIG5hbWVzIHRvIHRoZSB0ZW1wbGF0ZQ0KDQpjb2xuYW1lcyh4bHN4X3ByZXApPC0gYygiT2JzZXJ2ZXIgKGNvbGxlY3RpbmcsIGhhbmRsaW5nIGFuZC9vciBzdXJ2ZXlpbmcpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJTY2llbnRpZmljIE5hbWUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgIkNvbW1vbiBOYW1lIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJDb3VudCIsDQogICAgICAgICAgICAgICAgICAgICAgICAiRGF0ZVxyXG4oWVlZWS1NTS1ERCkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgIkNvdW50eSIsDQogICAgICAgICAgICAgICAgICAgICAgICAiRVhBQ1QgTE9DQVRJT05cclxuWCBjb29yZGluYXRlIC0gZWFzdGluZyBvciBsb25naXR1ZGUgKGUuZy4sIC0xMTEuMTIzNCkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgIkVYQUNUIExPQ0FUSU9OXHJcblkgY29vcmRpbmF0ZSAtIG5vcnRoaW5nIG9yIGxhdGl0dWRlIChlLmcuLCAzMy4xMjM0KSIsDQogICAgICAgICAgICAgICAgICAgICAgICAiTGlmZXN0YWdlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJTZXgiLA0KICAgICAgICAgICAgICAgICAgICAgICAgIkRpc3Bvc2l0aW9uIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJNdXNldW0iLA0KICAgICAgICAgICAgICAgICAgICAgICAgIk1hcmtlZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAiRmllbGQgVGFnIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJIYWJpdGF0IERlc2NyaXB0aW9uIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJPdGhlciBsb2NhbGl0eSBkYXRhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJDb21tZW50cyAocmVwcm9kdWN0aXZlIHN0YXR1cywgYmVoYXZpb3IsIGV0Yy4pIikNCiAgICAgICAgICAgICAgICAgICAgICAgIA0KDQojIE5vdyBqdXN0IEFwcGVuZCB0aGUgcHJlcGFyZWQgZGF0YSB0byB0aGUgdGVtcGxhdGUNCnhsc3hfZmluYWwgPC0gYmluZF9yb3dzKHhsc3hfdGVtcGxhdGUseGxzeF9wcmVwKQ0KDQojIEFkZCBpbiB0aGUgb3RoZXIgbmVlZGVkIGluZm8gbWlzc2luZyBmcm9tIHRoZSBzdXJ2ZXlfZGF0YQ0KeGxzeF9maW5hbCA8LSB4bHN4X2ZpbmFsICU+JSBtdXRhdGUoRGF0dW0gPSAiV0dTODQiKSAlPiUgDQogIG11dGF0ZShgQ29vcmluZGF0ZSBUeXBlIChERCwgRE1TLCBERE0sIFVUTSwgb3IgU1ApYCA9ICJERCIpDQoNCiMgTm93IExldHMgQXBwZW5kIHRoaXMgbmV3IGRhdGEgY29sbGVjdGVkIGJ5IHRoZSBzdXJ2ZXkxMjMgYXBwIHRvIHRoZSBzY2wtYXBwIHRlbXBsYXRlDQpzY2xfeGxzeF90ZW1wbGF0ZSA8LSByZWFkV29ya2Jvb2soInNjbC10ZW1wbGF0ZS9zY2wtcmVwb3J0LXRlbXBsYXRlLnhsc3giLCBzaGVldCA9ICJSZXBvcnQgRm9ybSIpDQpuZXcuZGF0YSA8LSByYmluZChzY2xfeGxzeF90ZW1wbGF0ZSwgeGxzeF9maW5hbCkNCg0KI3dyaXRlIHVwZGF0ZWQgZGF0YSBmcmFtZSB0byBleGlzdGluZyB3b3Jrc2hlZXQNCndiID0gbG9hZFdvcmtib29rKCJzY2wtdGVtcGxhdGUvc2NsLXJlcG9ydC10ZW1wbGF0ZS54bHN4IikNCndyaXRlRGF0YSh3YiwgIlJlcG9ydCBGb3JtIiwgbmV3LmRhdGEpDQoNCiMgU2F2ZSBmaWxlIHRvIGZpbmlzaGVkIHByb2R1Y3QNCnNhdmVXb3JrYm9vayh3YiwgInNjbC10ZW1wbGF0ZS9zY2wtcmVwb3J0LWZpbmFsLnhsc3giLCBvdmVyd3JpdGUgPSBUUlVFKQ0KYGBgDQoNCiR+JA0KDQpBZnRlciwgdGhpcyBjb2RlIGNodW5rIGlzIHJ1biB5b3UgY2FuIHNlZSBpdCBzcGl0cyBvdXQgdGhlIGZpbmFsIHhsc3ggaW50byB0aGUgZGVzaWduYXRlZCBmb2xkZXIuIEZyb20gdGhlcmUsIHlvdSBjYW4gc2ltcGx5IHRha2UgdGhlIHNwcmVhZHNoZWV0IGFuZCB1cGxvYWQgaXQgdGhlIHRoZSBBcml6b25hIEdhbWUgJiBGaXNoIERlcHQuIFNDTC1BcHAgYW5kICoqVm9pbMOgKiogeW91IGhhdmUgZmluaXNoZWQgeW91ciBjb21wbGlhbmNlIHdpdGggeW91ciBBWkdGRCBsaWNlbnNlIHJlcXVpcmVtZW50cyEhIfCfmI0NCg0KJH4kDQoNCiMjIyMjIElJKSBXcml0aW5nIHRoZSBkYXRhIHRvIGEgZG9jdW1lbnQNCg0KOjo6IHsuY2VudGVyfQ0KIVtdKGltZy9ybWFya2Rvd24ucG5nKXt3aWR0aD0iMjQ2In0NCjo6Og0KDQoNCiR+JA0KDQpXaGF0IGlmIHlvdSBuZWVkIHRvIHVzZSB0aGF0IGRhdGEgY29sbGVjdGVkIGFuZCBjcmVhdGUgYSByZXBvcnQgZm9yIHRoZSByZXF1aXJlbWVudHMgb2YgeW91ciBwZXJtaXR0aW5nLCB3ZWxsIFIgY2FuIGRvIHRoYXQgdG9vISBOb3csIGlmIHlvdSBkaWRuJ3Qga25vdyBTdXJ2ZXkxMjMgYWxzbyBoYXMgdGhhdCBjYXBhYmlsaXR5LCBhbmQgaWYgeW91IHdhbnQgdG8ga25vdyBtb3JlIGFib3V0IGhvdyB0byBkbyB0aGF0IGhlcmUgaXMgdGhlIDxhIGhyZWY9ICJodHRwczovL2RvYy5hcmNnaXMuY29tL2VuL3N1cnZleTEyMy9icm93c2VyL2FuYWx5emUtcmVzdWx0cy9mZWF0dXJlcmVwb3J0dGVtcGxhdGVzLmh0bSI+ICoqTElOSyoqIDwvYT4uIFRydXN0IG1lIHRob3VnaCwgaXQncyBub3QgYXMgaW50dWl0aXZlIGFzIEVTUkkgY2xhaW1zIGl0IHRvIGJlIGFuZCB5b3UgaGF2ZSB0byB1c2UgTWljcm9zb2Z0IFdvcmQgdG8gbWFrZSB0aGVzZSByZXBvcnRzIHdoaWNoIGNhbiBjYXVzZSBtb3JlIGlzc3VlcyB0aGVuIGl0IHNvbHZlcyBhbmQgaXQgaXMgdmVyeSBsaW1pdGluZyEhIEFueXdobywgdGhlIG1vcmUgYXV0b21hdGVkIGFuZCBmcmVlIHRvIHBsYXkgbW92ZSBpcyB0byB1c2UgUm1hcmtkb3duIGFuZCB3cml0ZSBvdXQgdGhlIHRlbXBsYXRlIGFuZCBSbWFya2Rvd24gd2lsbCB3cml0ZSBvdXQgdGhlIGRhdGEgY29sbGVjdGVkIHRvIGl0ISEgU28sIGxldCBtZSBzaG93IHlvdSBob3cgdGhpcyBjYW4gYmUgc3RydWN0dXJlZC4NCg0KJH4kDQoNCk5vdyBhIHF1aWNrIGRpc2NsYWltZXIgaXMgdGhhdCBJIGFtIHN0aWxsIGxlYXJuaW5nIGFsbCBhYm91dCB0aGUgbGljZW5zZWUgcmVxdWlyZW1lbnQgcHJvY2Vzc2VzIHdpdGggdGhlIHN0YXRlcyBhbmQgZmVkcywgc28gSSBhbSBtb3JlIHNob3dpbmcgaG93IHRoaXMgaXMgcG9zc2libGUgdGhhbiB3cml0aW5nIHRvIGEgcGFydGljdWxhciBmb3JtYXR0ZWQgZG9jdW1lbnQgbGlrZSBhIE5FUEEgRW52aXJvbm1lbnRhbCBBc3Nlc3NtZW50Lg0KDQokfiQNCg0KUm1hcmtkb3duIGlzIGEgZmlsZSBmb3JtYXQgZm9yIG1ha2luZyBkeW5hbWljIGRvY3VtZW50cyB0aGF0IGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSB1cGRhdGluZyBkb2N1bWVudHMgd2l0aCBuZXcgZGF0YSB0byBpbmNyZWFzaW5nbHkgY29tcGxleCBkb2N1bWVudHMgd2l0aCBodG1sIHdpZGdldHMgYW5kIGNvZGluZyBkZW1vcy4gVG8gZ2l2ZSB5b3UgYSBxdWljayBpZGVhIG9mIGhvdyBjb21wbGV4IHlvdSBjYW4gbWFrZSB0aGVzZSBkb2N1bWVudHMsIHRlY2huaWNhbGx5IHRoZSBkb2N1bWVudCB5b3UgYXJlIHJlYWRpbmcgcmlnaHQgbm93IGlzIG1hZGUgd2l0aCBybWFya2Rvd24uIFdoYXQgSSdtIHN1Z2dlc3RpbmcgdXMgdG8gdXNlIGlzIHRoZSBodG1sIGZ1bmN0aW9uIG9mIFJtYXJrZG93biB0byBjcmVhdGUgYSByZXBvcnQgb3V0IG9mIHRoZSBzdXJ2ZXkxMjMgZGF0YSB3ZSBjb2xsZWN0ZWQgd2l0aG91dCBhY3R1YWxseSBhZGRpbmcgaW4gdGhlIGluZm9ybWF0aW9uIGJlc2lkZXMgY2FsbGluZyBpbiB0byB0aGUgdGFibGUuIE5vdywgUm1hcmtkb3duIGNhbiBjcmVhdGUgcGRmIGRvY3VtZW50cywgYnV0IHRoZXNlIHBvc2UgdG8gYmUgZm9yZXZlciBsaW1pdGluZyBhbmQgeW91IGhhdmUgdG8gZ28gZG93biB0aGUgcmFiYml0IGhvbGUgb2YgW1sqKkxBVEVYKipdey51bH1dKGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi9wZGYtZG9jdW1lbnQuaHRtbCkgdG8gZ2V0IGl0IHRvIGxvb2sgdGhlIHdheSB5b3Ugd2FudCBpdCB0by4gVGhlIGJlbmVmaXRzIG9mIFJtYXJrZG93biBpcyBvbmNlIHRoZSBkb2N1bWVudCBpcyBzdHJ1Y3R1cmVkIGFsbCB5b3UgbmVlZCB0byBkbyBpcyBrbml0IHRoZSAuUm1kIGZpbGUgYW5kIHlvdSBoYXZlIHlvdXIgcmVwb3J0IHRvIHNlbmQgdG8gYW55IG9mIHRoZSBhZ2VuY2llcyByZXF1aXJpbmcgZG9jdW1lbnRhdGlvbiwgYW5kIG5ldmVyIGhhdmUgdG8gd2FzdGUgdGhlIGV4dGVuc2l2ZSB0aW1lIHRvIHdyaXRlIG91dCBhIHJlcG9ydCBvdmVyIGFuZCBvdmVyIGFnYWluLiBUaGUgZHJhd2JhY2sgaXMgeW91IG5lZWQgdG8gZ2V0IGZhbWlsaWFyIHdpdGggdGhlIFJzdHVkaW8gZW52aXJvbm1lbnQgYW5kIHRvIG1ha2UgaXQgbG9vayBwcmV0dHkgeW91IGhhdmUgdG8gZGlwIHlvdXIgZmVldCBpbnRvIGh0bWwgYW5kIGNzcy4NCg0KJH4kDQoNClNvLCB3aXRoaW4gdGhpcyB0dXRvcmlhbCBkb2N1bWVudGF0aW9uLCBJIGNyZWF0ZWQgYSAuUm1kIGZpbGUgd2l0aGluIHRoZSBybWFya2Rvd24tdGVtcGxhdGUgZm9sZGVyIHRpdGxlZCAic3BlY2llc19hY2NvdW50X3RlbXBsYXRlLlJtZCIsIHdoaWNoIGFsbCBjb250ZW50IGluIHRoaXMgZm9sZGVyIHdpbGwgZ2l2ZSB5b3UgYSBxdWljayB0dXRvcmlhbCBvZiBob3cgdG8gc3RydWN0dXJlIHRoZSBkYXRhIHdpdGhpbiB0aGUgZG9jdW1lbnQgZm9ybWF0LiBPYnZpb3VzbHksIHRoaXMgZG9jdW1lbnQgaXNuJ3QgdGhlIG1vc3QgcHJldHR5LCBidXQgaWYgeW91IHRha2UgdGhlIHRpbWUgdG8gc3RydWN0dXJlIHRoZSBjc3MgYW5kIGh0bWwgeW91IGNhbiBnZXQgYSB2ZXJ5IGFwcGVhbGluZyBkb2N1bWVudC4gQW5kIHJlbWVtYmVyIHlvdSBvbmx5IG5lZWQgdG8gc3RydWN0dXJlIGl0IG9uY2UsIGJlY2F1c2UgeW91IGNhbiByZXByb2R1Y2UgdGhlIHRlbXBsYXRlIHdpdGggbmV3IGRhdGEgd2l0aCBhIGNsaWNrIG9mIHRoZSBrbml0IGJ1dHRvbi4NCg0KJH4kDQoNCioqQmVsb3csIGlzIG15IGV4YW1wbGUgb2YgaG93IHlvdSBjYW4gcXVpY2sgd3JpdGUgb3V0IHRoZXNlIHJlcG9ydHMhISoqDQoNCjo6OiB7LmNlbnRlcn0NCjxpZnJhbWUgc3JjPSJodHRwczovL2prYXVwaHVzLmdpdGh1Yi5pby9zcGVjaWVzX2FjY291bnRfdGVtcGxhdGUvIiBoZWlnaHQ9IjUwMCIgd2lkdGg9IjYwMCIgdGl0bGU9IlNwZWNpZXMgQWNjb3VudCBUZW1wbGF0ZSI+DQoNCjwvaWZyYW1lPg0KOjo6DQoNCiR+JA0KDQpJZiB5b3UgYXJlIHN0aWxsIG5lcnZvdXMgYWJvdXQgY3JlYXRpbmcgaHRtbCBiZWNhc3VlIHlvdSByYXRoZXIgaGF2ZSBhIHBkZiBkb2N1bWVudCwgaXRzIG11Y2ggZWFzaWVyIHRvIGNvbnZlcnQgYW4gaHRtbCBkb2N1bWVudCB0byBhIHBkZiB0aGVuIGl0IGlzIHRvIGFjdHVhbGx5IGtuaXQgYW4gcm1hcmtkb3duIGRvYywgeW91IGNhbiBldmVuIGRvIGl0IHRocm91Z2ggUiBpZiB0aGUgaHRtbCBkb2MgaXMgaG9zdGVkIGxpa2UgbWluZSB3YXMuIEhlcmUgaXMgdGhlIGNvZGUgYmVsb3csIGFuZCB5b3UgY2FuIGZpbmQgdGhlIHBkZiBvdXRwdXQgaW4gdGhlIGltZyBmb2xkZXIgaW4gdGhpcyByZXBvc2l0b3J5Lg0KDQokfiQNCg0KYGBge3IgZG9jdW1lbnQgdGVtcGxhdGUgdG8gcGRmLCBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTB9DQojIEhlcmUgaXMgdGhlIGV4YW1wbGUgb2YgaG93IHlvdSB3b3VsZCB0dXJuIHRoYXQgbGl2ZSBodG1sIHRvIGEgcGRmIGRvYw0KIyN3ZWJzaG90KCJodHRwczovL2prYXVwaHVzLmdpdGh1Yi5pby9zcGVjaWVzX2FjY291bnRfdGVtcGxhdGUvIiwgImltZy9kb2MtdGVtcGxhdGUucGRmIikNCmBgYA0KDQokfiQNCg0KIyMjIyMgSUlJKSBXcml0aW5nIHRoZSBkYXRhIHRvIGEgZGF0YWJhc2UNCg0KOjo6IHsuY2VudGVyfQ0KIVtdKGltZy9kYXRhYmFzZS5wbmcpe3dpZHRoPSIyNjkifQ0KOjo6DQoNCiR+JA0KDQpUaGlzIHNlY3Rpb24gb2YgdGhlIGRvY3VtZW50IHdpbGwgYXR0ZW1wdCB0byBleHBsYWluIGEgcXVpY2sgb3ZlcnZpZXcgb2YgYSBiZXR0ZXIgd2F5IGZvciBib3RoIGFnZW5jaWVzIGFuZCBsaWNlbnNlZSBob2xkZXJzIHRvIGNvbGxlY3QgZGF0YSBhbmQgc3RvcmUgaXQgdG8gYmUgYmV0dGVyIG9yZ2FuaXplZCwgZWFzaWx5IHNlYXJjaGFibGUsIGFuZCBxdWlja2x5IGFibGUgdG8gZ3JhYiBhbmQgc2VuZCBvdXQgZGF0YS4gV2hhdCBJIGhhdmUgc2VlbiB0aHJvdWdob3V0IG15IGNhcmVlciBmcm9tIGJvdGggdGhlIGFjYWRlbWljIHNpZGUgYW5kIGFnZW5jeSBzaWRlIGlzIHRoZXJlIGlzIGEgaHVnZSBkaXNqdW5jdCBvZiBob3cgZ3JvdXBzIG1hbmFnZSBhbmQgdmlldyBkYXRhYmFzZXMuIE5vdyBmcm9tIG15IHBlcnNwZWN0aXZlLCBtb3N0IHBlb3BsZSB0cnkgdG8gYXZvaWQgbGVhcm5pbmcgYW55IGNvZGluZyBsYW5ndWFnZSBhbmQgcGF5IGZvciBzZXJ2aWNlcyB0aGF0IGhvbmVzdGx5IGRvbid0IGRvIGEgZ3JlYXQgam9iIG9mIGtlZXBpbmcgYW4gb3JnYW5pemVkIGRhdGFiYXNlLiBTcGVjaWZpY2FsbHksIEknbSB0YWxraW5nIGFib3V0IEVTUkkgZ2VvZGF0YWJhc2VzLCBNaWNyb3NvZnQgQWNjZXNzLCBhbmQgSSd2ZSBldmVuIHNlZW4gYWdlbmNpZXMgdXNlIGEgZm9sZGVyIHN5c3RlbSBsb2NhbGx5IG9yIG9uIGEgY2xvdWQgc2VydmljZSBhcyBhICJkYXRhYmFzZSIsIHdoaWNoIGFsbCBsYWNrIHRoZSBhYmlsaXR5IHRvIGVhc2lseSBzZWFyY2ggYW5kIHF1aWNrbHkgZ3JhYiBhbmQgc2VuZCBvdXQgZGF0YS4gSWYgd2Ugd2FudCB0byBjcmVhdGUgYSBzaW1wbGVyIHdvcmtmbG93IGZvciBmaWVsZC1iaW9sb2dpc3RzIHdlIHNob3VsZCBhcyBhIGdyb3VwIHVzZSBPcGVuIFNvdXJjZSBTUUwgZGF0YWJhc2VzLg0KDQokfiQNCg0KSSBwcm9wb3NlIGJvdGggbGljZW5zZWVzLCBjb25zdWx0YW50cywgYWNhZGVtaWNzLCBhbmQgYWdlbmNpZXMgdG8gYWRhcHQgdGhpcyBzdGFuZGFyZGl6ZWQgaWRlYSBvZiBjcmVhdGluZyB5b3VyIG93biBPcGVuIHNvdXJjZSBTUUwgZGF0YWJhc2UuIEJlbG93LCBJIHdpbGwgb3V0bGluZSB0aGUgc3RlcHMgdG8gY3JlYXRlIHRoZXNlIGRhdGFiYXNlcywgYW5kIHNob3cgaG93IFIgY2FuIGludGVncmF0ZSBpbnRvIHRoZXNlIGRhdGFiYXNlcyB0byBlYXNpbHkgcHVsbCwgcHVzaCwgYW5kIHNlbmQgb3V0IGRhdGEuIEZyb20gdGhlcmUsIGFsbCB5b3UgbmVlZCB0byBkbyBpcyBzZXQgdXAgdGhlIGluZnJhc3RydWN0dXJlLCBhbmQgbGlmZSB3aXRoIGFkZGluZyBhbmQgc2VuZGluZyBvdXQgZGF0YSBnZXRzIHNvIG11Y2ggZWFzaWVyIHNpbmNlIGFsbCB5b3Ugd2lsbCBuZWVkIHRvIGRvIGlzIG1hbmFnZSBpdCB3aXRoIFIuDQoNCiR+JA0KDQotICAgUGljayBhIE9wZW4gc291cmNlIFNRTCBkYXRhYmFzZSB0aGF0IHdvcmtzIHdpdGggdGhlIFtEQkkgUiBwYWNrYWdlXShodHRwczovL2RiaS5yLWRiaS5vcmcvKSwgSSBwcmVmZXIgdG8gdXNlIFtQb3N0Z3Jlc3FsXShodHRwczovL3d3dy5wb3N0Z3Jlc3FsLm9yZy8pIHdpdGggW3BnQWRtaW5dKGh0dHBzOi8vd3d3LnBnYWRtaW4ub3JnLyksIGhvd2V2ZXIsIERCSSBhbHNvIHVzZXMgU1FMaXRlLCBNaWNyb3NvZnQgT0RCQywgYW5kIEdvb2dsZSBCaWdRdWVyeQ0KDQogICAgLSAgIFdhbm5hIGxlYXJuIGFib3V0IFBvc3RncmVzcWwgYW5kIHBnQWRtaW4gY2hlY2sgb3V0IFtbKip0aGlzIHZpZGVvKipdey51bH1dKGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9RGQyZWotUUtyV1kpIPCfkYsNCg0KJH4kDQoNCi0gICBJbiBSc3R1ZGlvLCBkb3dubG9hZCB0aGUgREJJIHBhY2thZ2UgYWxvbmcgd2l0aCB0aGUgc3ViLXBhY2thZ2Ugb2YgdGhlIGRhdGFiYXNlIHlvdSBzZWxlY3RlZCBhbmQgd2FsayB0aHJvdWdoIGhvdyB0byBsaW5rIHRoZW0gdG8geW91ciBkYXRhYmFzZXMNCg0KJH4kDQoNCmBgYHtyIERCSSBhbmQgU1FMIHBhY2thZ2VzLCBldmFsPUZBTFNFLCBlY2hvPVRSVUV9DQojIFRoaXMgZXhhbXBsZSBpcyB1c2luZyB0aGUgQXJpem9uYSBIRE1TIFBvc3RncmVzcWwgc2V0dXANCg0KIyBTaW1wbHkgZG93bmxvYWQgdGhlIERCSSBwYWNrYWdlIGluIFJzdHVkaW8NCg0KIyNpbnN0YWxsLnBhY2thZ2VzKCJEQkkiKQ0KDQojIFRoZW4gZ28gdGhyb3VnaCBhbmQgZG93bmxvYWQgeW91ciBzdWIgcGFja2FnZQ0KDQojI2luc3RhbGwucGFja2FnZXMoIlJQb3N0Z3JlcyIpDQoNCiMgRnJvbSB0aGVyZSBHbyB0aHJvdWdoIHRoaXMgc2V0IHVwDQoNCmxpYnJhcnkoREJJKQ0KDQpkYiA8LSAnREFUQUJBU0UnICAjcHJvdmlkZSB0aGUgbmFtZSBvZiB5b3VyIGRiDQoNCmhvc3RfZGIgPC0g4oCYSE9TVOKAmSAjaS5lLiAjIGkuZS4gJ2VjMi01NC04My0yMDEtOTYuY29tcHV0ZS0xLmFtYXpvbmF3cy5jb20nICANCg0KZGJfcG9ydCA8LSAnOTg5MzknICAjIG9yIGFueSBvdGhlciBwb3J0IHNwZWNpZmllZCBieSB0aGUgREJBDQoNCmRiX3VzZXIgPC0gVVNFUk5BTUUgIA0KDQpkYl9wYXNzd29yZCA8LSDigJhQQVNTV09SROKAmQ0KDQpjb24gPC0gZGJDb25uZWN0KFJQb3N0Z3Jlczo6UG9zdGdyZXMoKSwgZGJuYW1lID0gZGIsIGhvc3Q9aG9zdF9kYiwgcG9ydD1kYl9wb3J0LCB1c2VyPWRiX3VzZXIsIHBhc3N3b3JkPWRiX3Bhc3N3b3JkKSANCg0KIyBUaGVuIHlvdSBjYW4gY2hlY2sgaWYgaXQncyBjb25uZWN0ZWQgd2l0aCB0aGUgbGlzdCBvZiB0YWJsZXN5b3UgaGF2ZSBpbiB0aGUgZGF0YWJhc2UNCg0KZGJMaXN0VGFibGVzKGNvbikgDQoNCg0KYGBgDQoNCiR+JA0KDQotICAgTm93LCB5b3UgY2FuIGVhc2lseSBwdWxsIGluIGRhdGEgdG8gUiBvciBwdXNoIGRhdGEgdXAgaW50byB0aGUgZGF0YWJhc2UuDQoNCiR+JA0KDQpgYGB7ciBScG9zdGdyZXMgcHVzaCBhbmQgcHVsbCwgZXZhbD1GQUxTRSwgZWNobz1UUlVFfQ0KIyBQdWxsIGRhdGEgZnJvbSB0aGUgU1FMIGRhdGFiYXNlIHRvIFINCmRiR2V0UXVlcnkoY29uLCDigJhTRUxFQ1QgKiBGUk9NIHRhYmxl4oCZKSAgIyBzZWUgdGhlIFNRTCBzdGF0ZW1lbnRzIHlvdSBjYW4gZ2V0IHZlcnkgcHJlY2lzZSB3aXRoIHRoaXMgb25lDQoNCiMgUHVzaCBkYXRhIGZyb20gUiB0aGF0IHlvdSBkb2N0b3JlZCB1cCB0byB0aGUgZGF0YWJhc2UNCmRiV3JpdGVUYWJsZShjb24sICJuZXdkYXRhIiwgbmV3ZGF0YSkNCg0KIyBOb3RlIHRoZXNlIGRhdGFiYXNlcyBjYW4gdGFrZSBhIHZhcmlldHkgb2YgZGF0YSBpbmNsdWRpbmcgc2hhcGVmaWxlcyBzbyBpZiB3ZSB3YW50ZWQgdG8gbW92ZSBvdXIgc3VydmV5MTIzIGRhdGEgdG8gdGhlIGRhdGFiYXNlIHdlIGNhbiBlYXNpbHkgYXBwZW5kIGl0IHRvIGFuIGV4aXN0aW5nIHRhYmxlIG9yIGNyZWF0ZSBhIG5ldyBvbmUuIA0KDQpkYldyaXRlVGFibGUoY29uLCAiZXhpc3RpbmctdGFibGUiLCBzdXJ2ZXkxMjMsIGFwcGVuZCA9IFRSVUUpDQpgYGANCg0KJH4kDQoNCkhvcGVmdWxseSwgeW91IGNhbiBzZWUgdGhlIHV0aWxpdHkgb2YgdXNpbmcgdGhlc2UgZGF0YWJhc2VzIHRvIHN0YXkgb3JnYW5pemVkIGFuZCBlYXNpbHkgcHVzaCBhbmQgcHVsbCBkYXRhIGZvciBSIHRvIGRvIHNvbWUgZGF0YS1tYW5hZ2VtZW50LCBidXQgeW91IGFyZSBwcm9iYWJseSB0aGlua2luZyBhcyBhIGxpY2Vuc2VlIGhvbGRlciwgImhvdyBjYW4gdGhlc2UgZGF0YWJhc2VzIGJlIHVzZWQgdG8gaGVscCBtZSB3aXRoIHN1Ym1pdHRpbmcgbXkgZGF0YSB0byB0aGUgYWdlbmNpZXM/Ig0KDQokfiQNCg0KV2VsbCwgaWYgYW5kIGhvcGVmdWxseSB3aGVuIG1vcmUgYW5kIG1vcmUgYWdlbmNpZXMgYWRvcHQgdGhlc2UgU1FMIG9wZW4gc291cmNlIGRhdGFiYXNlcywgdGhleSBjYW4gc2V0IHVwIGEgc3lzdGVtIGZvciB5b3UgdG8gZGlyZWN0bHkgdXBsb2FkIHlvdXIgcGVybWl0IGRhdGEgaW50byBhIHRlbXBvcmFyeSB0YWJsZSBpbiB0aGVpciBkYXRhYmFzZXMsIHZpYSBtYXliZSBhIHNlbGYgY3JlYXRlZCBbWyoqUiBwYWNrYWdlKipdey51bH1dKGh0dHBzOi8vc3VwcG9ydC5yc3R1ZGlvLmNvbS9oYy9lbi11cy9hcnRpY2xlcy8yMDA0ODY0ODgtRGV2ZWxvcGluZy1QYWNrYWdlcy13aXRoLVJTdHVkaW8pLCBhbmQgdGhlIGFnZW5jaWVzIGNhbiB0aGVuIGRvdWJsZSBjaGVjayB0aGUgZGF0YSB3aXRoIHNvbWUgc29ydCBvZiB2ZXJzaW9uIGNvbnRyb2wgc3lzdGVtIGxpa2UgYW4gW1sqKnJTaGlueSBBcHAqKl17LnVsfV0oaHR0cHM6Ly9zaGlueS5yc3R1ZGlvLmNvbS8pIGFuZCBmaWxlIGl0IGludG8gdGhlaXIgcHJlZmVycmVkIGRhdGFiYXNlIHRhYmxlIHdpdGggZG9jdW1lbnRpbmcgdGhhdCB5b3UgaGF2ZSBzdWJtaXR0ZWQgZGF0YS4NCg0KJH4kDQoNCk9mIGNvdXJzZSwgdGhpcyBsYXN0IHNlY3Rpb24gb2YgdGhlIHByb29mIG9mIGNvbmNlcHQgaXMgdG8gaG9wZWZ1bGx5IHNob3cgdGhhdCB0aGUgc2t5IGlzIHRoZSBsaW1pdCB3aGVuIGl0IGNvbWVzIHRvIGNvZGluZyB3aXRoIFIgYW5kIHVzaW5nIG9wZW4gc291cmNlIHNvZnR3YXJlIG92ZXIgdGhlIHN0YW5kYXJkIHN1YnNjcmlwdGlvbiBsaWNlbnNlcy4gSW4gYWRkaXRpb24sIEkgaG9wZSB0aGlzIGxhc3Qgc2VjdGlvbiBvbiBkYXRhYmFzZXMgY2FuIGNyZWF0ZSBhIG1vcmUgcHJvZHVjdGl2ZSBkaWFsb2d1ZSBvZiB3aGVyZSBhZ2VuY2llcyBzaG91bGQgbG9vayB0byBmb3Igc3RhbmRhcmRpemluZyBhbmQgb3JnYW5pemluZyB0aGVpciBkYXRhIGJldHRlciwgc28gaXQgaXMgZWFzaWVyIGZvciBsaWNlbnNlZSBob2xkZXJzIHRvIHN1Ym1pdCB0aGUgZGF0YSBvbmNlIGluIHRoZSBjb3JyZWN0IHdheS4gVGhpcyBzaG91bGQgcmVkdWNlIHRoZSBjb25mdXNpb24gYmV0d2VlbiB0aGUgdHdvIGFuZCByZWR1Y2UgdGhlIGhhc3NsZSBvZiBoYXZpbmcgdG8gc2VuZCBlbWFpbHMgYmFjayBhbmQgZm9ydGggdHJ5aW5nIHRvIHBpZWNlIHRvZ2V0aGVyIHdobyBuZWVkcyB0byBzdWJtaXQsIHdobyBkaWRuJ3Qgc3VibWl0IGNvcnJlY3RseSwgb3Igd2h5IGlzIHN1Ym1pdHRpbmcgdG8gYWxsIHRoZXNlIGFnZW5jaWVzIHN1Y2ggYSBodWdlIHByb2Nlc3MhIQ0KDQokfiQNCg0KIyMjIDQuIENvbmNsdXNpb24NCg0KJH4kDQoNCkJ5IG5vdywgSSBob3BlIEkgaGF2ZSBhdCBsZWFzdCBnaXZlbiB5b3UgYSBnb29kIHBsYW4gb2YgYWN0aW9uLCBvciBhdCB0aGUgdmVyeSBsZWFzdCBzZXQgdXAgYSBuZWVkZWQgZGlzY3Vzc2lvbiwgb2YgaG93IHRvIG1ha2UgdGhlIHJlbGF0aW9uc2hpcCB3aXRoIGxpY2Vuc2VlIGhvbGRlcnMgYW5kIGFnZW5jaWVzIGJldHRlci4gU2luY2UsIGFsbCBhZ2VuY2llcyBhbmQgbW9zdCBsaWNlbnNlZSBob2xkZXJzIGxvdmUgdGhlc2UgY29sbGVjdG9yIGFwcGxpY2F0aW9ucyBmcm9tIEVTUkksIEkgZmlndXJlZCB3ZSBuZWVkIHRvIGFzIGEgYmlvbG9naXN0IGNvbW11bml0eSBqdW1wIG9uIGFuZCBoZWxwIHN1cHBvcnQgdGhlc2UgYXBwbGljYXRpb25zIHRvIGJlIG1vcmUgZWFzaWx5IGludGVncmF0ZWQgaW50byBvdXIgbGljZW5zaW5nIHJlcXVpcmVtZW50cyB3aXRoIHN1Ym1pdHRpbmcgZGF0YSwgYmVjYXVzZSB0aGUgd2hvbGUgZW50aXJlIHB1cnBvc2Ugb2YgdGhpcyBzdWJtaXNzaW9uIG9mIGRhdGEgaXMgdG8gYmUgdXNlZCB0byBtYWtlIGluZmVyZW5jZXMgdG8gaGVscCBjb25zZXJ2YXRpb24gb2Ygb3VyIGNvdW50cmllcyBzcGVjaWVzISHwn5iDDQoNCiR+JA0KDQpXaXRoIHRoYXQsIEkgd291bGQgbGlrZSB0byB0aGFuayBhbnlvbmUgd2hvIGhhcyB0YWtlbiB0aGUgdGltZSB0byBnbyB0aG91Z2ggdGhpcyBkb2N1bWVudCBpbiBpdHMgZW50aXJldHksIGFuZCBpZiB5b3UgaGF2ZSBhbnkgcXVlc3Rpb25zIGFib3V0IGFueXRoaW5nIHRoYXQgd2FzIG1lbnRpb25lZCBvciB3ZW50IG92ZXIgaW4gdGhpcyBkb2N1bWVudCB0byBwbGVhc2UgZW1haWwgbWUgYXQgamthdXBodXNtYW5cQGF6Z2ZkLmdvdi4gRm9yIHRoZSByZXN0IG9mIHRoZSBkb2N1bWVudGF0aW9uLCB5b3UgY2FuIGRvd25sb2FkIG9yIGNsb25lIHRoZSBnaXQgcmVwb3NpdG9yeSBhdCBbRmllbGQtQmlvbG9neS1Xb3JrZmxvd10oaHR0cHM6Ly9naXRodWIuY29tL2prYXVwaHVzL2ZpZWxkLWJpb2xvZ3ktd29ya2Zsb3cpLg0KDQokfiQNCg0KOjo6IHsuY2VudGVyfQ0KIyMjIFRoYW5rIFlvdSEhDQohW10oaW1nL2dpdGh1Yi5wbmcpe3dpZHRoPSI0NTkifQ0KOjo6DQo=