🔙 Home

All work associated with the Centre for Behaviour and Evolution, including this documentation, is supported by a Wellcome Trust Capital Award to Newcastle (grant ref: 092504).

Purpose

This notebook goes through pre-processing data from an EyeLink 1000 running EyeTrack.

Technical Specifications

fix_align_v0p92.R

This section takes the prose information from Cohen (2013) and puts in it lists for quick accessibility.

Cohen, Andrew L. (2013). Software for the automatic correction of recorded eye fixation locations in reading experiments. Behavior research methods, 45(3), 679–683. Accessed from: https://people.umass.edu/eyelab/CohenBRM.pdf

Understanding the function

In order to use fix_align properly, it’s good to understand what arguments it takes and what it does with those arguments. I present information condensed from Cohen (2013) and my own interpretations and experiences with using it.

library(knitr)
source('fix_align_v0p92.R')
fix_align <- function(start_pts,                      # where does each line start
                      asc_files         = '.',        # where are the files
                      xy_bounds         = NULL,       # remove points before calculating regression
                      keep_y_var        = FALSE,      # TRUE: residual for its regression is kept
                      use_run_rule      = TRUE,       # 
                      trial_plots       = TRUE,       # 
                      save_trial_plots  = FALSE,      # .tiff plots saved in directory “Trial_Plots”
                      summary_file      = TRUE,       # TRUE: a .fas is saved in fa_dir
                      show_image        = FALSE,      # TRUE: trials on top of background images
                      fa_dir            = 'FA_Dir',   # where are the .asc files?
                      start_flag        = 'TRIALID',  # what do trials start with?
                      den_sd_cutoff     = Inf,        # remove outliers
                      den_ratio_cutoff  = 1,          # remove outliers
                      k_bounds          = c(-.1, .1), # NULL = 0; min/max of regression slope
                      o_bounds          = c(-50, 50), # NULL = 0; min/max of vertical offset
                      s_bounds          = c(1, 20))   # min/max of sd

Input

Taken directly from Cohen (2013):

  • start_pts is an n × 2 matrix that defines the x and y locations of the start of each text line, where n is the number of text lines.
  • asc_files is a vector of .asc file names and/or folders containing .asc files.
  • Any points outside the rectangles provided by xy_bounds are considered out of bounds and are removed from the analysis before the regression lines are determined.
  • xy_bounds provides a way to remove points from analysis a priori.
    • Any points outside the rectangles provided by xy_bounds are considered out of bounds and are removed from analysis before the regression lines are determined.
    • All other points are included in the creation of the regression lines.
    • The bounds can be set to no bounds (NULL), a single rectangle for the entire experiment (a 1 × 4 vector: x-min, x-max, ymin, and y-max), or one rectangle per trial (an n × 4 matrix of rectangles).
  • If keep_y_var is set as TRUE, the residual of each fixation around its assigned regression line is kept when the y location is changed; otherwise, it is removed.
  • If use_run_rule is set as TRUE, ambiguous fixations are potentially reclassified by their surrounding fixations as described above; otherwise, they remain ambiguous.
  • If trial_plots is set as TRUE, trial-by-trial plots of the original and reformatted fixations are shown.
  • If save_trial_plots is set as TRUE, the trial plots are saved as .tiff files, in a subdirectory called “Trial_Plots” in the directory defined by fa_dir
    • In this case, the plots will only be saved—that is, they will not be shown on the screen.
    • These files are massive, so do not use this option unless you are processing a small amount of data or have a lot of storage space.
  • If summary_file is set as TRUE, a .fas (fix align summary) file is created
    • It saves the slope, vertical offset, standard deviation, regression fit, and the numbers of total, kept, out-of-bounds, ambiguous, outlier, and other fixations for each participant and each trial.
  • If show_image is set as TRUE, the trial plots are shown on top of background images.
    • These background images are .tiff files located in the same directory as the data files.
    • One image can be used per .asc file, or one image per trial per .asc file, and images must be saved as .tiff files with the same name as the .asc file and the .tiff ending.
    • If one image is used per trial, the end of the name must have an underscore followed by a trial number (e.g., “_1” for Trial 1).
  • fa_dir is the name of the directory used to store the reformatted .asc files, .fas files, and trial plots.
    • The .asc files are marked by having “_fa” (fix align) at the ends of their names.
    • This is hard-coded as FA_Dir thus should be set to the name of the actual directory.
  • start_flag is the text that marks the start of data collection in the .asc file, which will typically be either “TRIALID” or “SYNCTIME.”
  • den_sd_cutoff defines the number of standard deviations from a regression line that determines an outlier.
  • den_ratio_cutoff defines the ratio (in density) that determines ambiguous fixations.
  • k_bounds, o_bounds, and s_bounds are 1×2 vectors that define the minimum and maximum values that the regression line slope, vertical offset, and standard deviation, respectively, can take.
    • If set to NULL, k_bounds and o_bounds have values of 0.

An example input directly from Figure 2:

fix_align <- function(start_pts = rbind(c(27, 436), c(27, 556)),
                      asc_files = 'Data/23_50H_B.asc',
                      save_trial_plots = TRUE,
                      start_flag = 'SYNC_TIME',
                      den_sd_cutoff = 4.5,
                      den_ratio_cutoff = 55000)

If you don’t want to remove any points:

den_sd_cutoff = Inf,
den_ratio_cutoff = 0

Output

Adapted from Cohen (2013):

  • A .tiff file
    • The trial-by-trial visualization of the fixation adjustment and classifications.
  • A .fas (fix align summary) file
    • Saves the slope, vertical offset, standard deviation, regression fit, and the numbers of total, kept, out-of-bounds, ambiguous, outlier, not-in-trial, and partial fixations for each participant and trial.
  • The reformatted .asc file
    • This file is a copy of the original .asc file, with the y locations of the fixations changed to reflect the regression analysis and fixation removal process.
    • This file has the same name as the original .asc file, with “_fa” (fix align) added to the end.

Practical application

In my .asc file, this is what the first few lines of a sample trial look like (the sentence-initial word “The”).

INPUT   3589590 127
MSG 3589610 TRIALID E16I77D0
MSG 3589628 DISPLAY TEXT 1
MSG 3589628 REGION CHAR 0 1 T 67 267 79 319
MSG 3589629 DELAY 1 MS
MSG 3589629 REGION CHAR 1 1 h 79 267 91 319
MSG 3589631 DELAY 1 MS
MSG 3589631 REGION CHAR 2 1 e 91 267 103 319
MSG 3589632 DELAY 1 MS
MSG 3589633 REGION CHAR 3 1   103 267 115 319
MSG 3589634 DELAY 1 MS

It looks like 67 indicates the leftmost edge of the T and the 79 is the right most edge, since 79 is also the leftmost edge of h. That means values in these columns are the x-axis value. That makes 267 the top edge and 319 the bottom edge of the y-axis.

The break between the first and second line of text from this trial looks like this:

MSG 3589750 REGION CHAR 57 1 t 751 267 763 319
MSG 3589752 DELAY 1 MS
MSG 3589752 REGION CHAR 58 1 h 763 267 775 319
MSG 3589754 DELAY 1 MS
MSG 3589755 REGION CHAR 59 1 e 775 267 787 319
MSG 3589756 DELAY 1 MS
MSG 3589756 REGION CHAR 60 1   787 267 799 319
MSG 3589759 DELAY 1 MS
MSG 3589760 REGION CHAR 62 1 a 67 329 79 381
MSG 3589762 DELAY 1 MS
MSG 3589763 REGION CHAR 63 1 n 79 329 91 381
MSG 3589764 DELAY 1 MS
MSG 3589765 REGION CHAR 64 1 n 91 329 103 381
MSG 3589767 DELAY 1 MS
MSG 3589768 REGION CHAR 65 1 u 103 329 115 381
MSG 3589770 DELAY 1 MS
MSG 3589771 REGION CHAR 66 1 a 115 329 127 381
MSG 3589772 DELAY 1 MS
MSG 3589773 REGION CHAR 67 1 l 127 329 139 381
MSG 3589775 DELAY 1 MS

It looks like the x-axis values for the second line are the same as the first line, so our y-axis top edge is at 329 and the bottom edge is at 381.

Testing it out

Now I’ll put in custom values for my files. I’m not sure which y-axis edges to use, so I’ll go with the most extreme ones for each line. The x-axis will be the leftmost edge for both.

fix_align(start_pts = rbind(c(67, 267), c(67, 381)),
          asc_files = 'asc/PR02.asc',
          save_trial_plots = TRUE,
          fa_dir = 'asc',
          start_flag = 'TRIALID',
          den_sd_cutoff = Inf,
          den_ratio_cutoff = 0)

Processing all files

Okay, that actually worked, but since it was one of the messier files, I want to try it with the average y-axis value.

  • line 1 = 293
  • line 2 = 355

I’ve also set den_sd_cutoff to 3, which has a slightly narrower band that’s acceptable, and den_ratio_cutoff is set to 5 because large numbers throw out a LOT of points that are correctly categorized with small numbers. These numbers work fairly well with PR02.asc, so I will add in all the other files now. I’ve also set some xy_bound cutoff points to ignore outliers that are definitely outliers before calculating regression lines.

fix_align(start_pts = rbind(c(67, 293), c(67, 355)),
          asc_files = c(#'asc/PR01inc.asc',
                      'asc/PR02.asc',
                      'asc/PR03-1b.asc',
                      'asc/PR04.asc',
                      'asc/PR05.asc',
                      'asc/PR06.asc',
                      'asc/PR07.asc',
                      'asc/PR08.asc',
                      'asc/PR09.asc',
                      'asc/PR10.asc',
                      'asc/PR11.asc',
                      'asc/PR12.asc',
                      'asc/PR13.asc',
                      'asc/PR14.asc',
                      'asc/PR15.asc',
                      'asc/PR16.asc',
                      'asc/PR17.asc',
#                     'asc/PR18.asc',
                      'asc/PR19.asc',
                      'asc/PR20.asc',
                      'asc/PR21.asc',
                      'asc/PR22.asc',
                      'asc/PR23.asc',
                      'asc/PR25.asc',
                      'asc/PR27.asc',
                      'asc/PR28.asc',
                      'asc/PR29.asc',
                      'asc/PR30.asc',
#                     'asc/PR31.asc',
                      'asc/PR32.asc',
                      'asc/PR33.asc',
                      'asc/PR34.asc',
                      'asc/PR35.asc',
#                     'asc/PR36.asc',
                      'asc/PR38.asc',
                      'asc/PR39.asc',
#                     'asc/PR40.asc',
                      'asc/PR41.asc',
                      'asc/PR42.asc',
#                     'asc/PR43.asc', # Error in trial_fix[[i]] : subscript out of bounds
#                     'asc/PR44.asc', # Error in trial_id_start[t]:trial_end[t] : NA/NaN argument
                      'asc/PR45.asc',
                      'asc/PR46.asc',
                      'asc/PR47.asc',
#                     'asc/PR48.asc', # Error in trial_fix[[i]] : subscript out of bounds
                      'asc/PR49.asc',
                      'asc/PR50.asc',
                      'asc/PR51.asc',
                      'asc/PR52.asc',
                      'asc/PR53.asc'),
          xy_bounds = c(20, 1000, 200, 600), # c(x-min, x-max, ymin, y-max)
          trial_plots = FALSE, # i can't get this to do anything except spin its wheels?
          save_trial_plots = FALSE, # wow that takes up a LOT of space
          fa_dir = 'asc',
          start_flag = 'TRIALID',
          den_sd_cutoff = 3, # not sure what's best, but this seems to work okay
          den_ratio_cutoff = 5) # small numbers seem to do fine…?

There seemed to be some issues with PR09 when I was still creating .tiff files, but a spot check make it look like ‘weird’ trials were mostly rejected rather than miscategorized (more often than not).

Debugging problem files

These files throw errors and I’d like to know why. To do: follow up with Jesse Harris et al.

fix_align(start_pts = rbind(c(67, 293), c(67, 355)),
          asc_files = c(#'asc/PR01inc.asc', # Error in trial_id_start[t]:trial_end[t] : NA/NaN argument
#                     'asc/PR18.asc'#,  Error in trial_id_start[t]:trial_end[t] : NA/NaN argument
#                     'asc/PR31.asc'#,  Error in trial_id_start[t]:trial_end[t] : NA/NaN argument
#                     'asc/PR36.asc'#,  Error in trial_id_start[t]:trial_end[t] : NA/NaN argument
#                     'asc/PR40.asc'#,  Error in if (trial_id_start[start_index + 1] < trial_end[end_index]) { : missing value where TRUE/FALSE needed
#                     'asc/PR43.asc'#,  Error in trial_fix[[i]] : subscript out of bounds
#                     'asc/PR44.asc'#,  Error in trial_id_start[t]:trial_end[t] : NA/NaN argument
#                     'asc/PR48.asc'#   Error in trial_fix[[i]] : subscript out of bounds
                      ),
          xy_bounds = c(20, 1000, 200, 600), # c(x-min, x-max, ymin, y-max)
          trial_plots = FALSE, # i can't get this to do anything except spin its wheels?
          save_trial_plots = FALSE, # wow that takes up a LOT of space
          fa_dir = 'asc',
          start_flag = 'TRIALID',
          den_sd_cutoff = 3, # not sure what's best, but this seems to work okay
          den_ratio_cutoff = 5) # small numbers seem to do fine…?

Robodoc.py and friends

Now it’s time to run Robodoc.py and associated scripts.

We need a parameter.txt file set up, which requires the coordinates for the line(s) of text that will be analysed.

make_cnt.py

Here’s what it looks like when you use make_cnt.py in Terminal:

Last login: Thu Apr 12 00:25:52 on console
MacBook-Pro-2:~ username$ cd /Users/username/Documents/Research/…/asc/GOOD_ASC
MacBook-Pro-2:GOOD_ASC username$ python3 make_cnt.py
What is the name of your delimited script file?"progen-make_cnt.script"
Your delimited script file could not be found.
MacBook-Pro-2:GOOD_ASC username$ python3 make_cnt.py
What is the name of your delimited script file?progen-make_cnt.script
What character do you use as your region delimiter?/
What is the lowest condition number to be analyzed?1
What is the highest condition number to be analyzed?16

This doesn’t seem to be working properly, so we’ll have to try something else.

reg.txt

The make_cnt.py script isn’t actually outputting proper regions info, and it seems to not be working with multi-line stimuli. I’ll go through making a .reg.txt file in case that is a helpful alternative.

From the (deprecated) UMD EyeLink wiki (Accessed from the Internet Wayback Machine on 19 April 2018; archived on 22 August 2012):

This step in the process requires that you have your EyeTrack .script file, and the getQuestions.py, getSentences.py and makeRegions.py script in the same directory. You will use these materials to generate the question/answer key for your data, as well as the regions file used in compiling your data.

Generating an Items List

By generating an items list, you can extract all the stimuli and manually annotate regions.

  • Use getSentences.py to extract the items that EyeTrack used (with the condition and item numbers it assigned).
  • Make sure you have a copy of getSentences.py in the same directory with the .script file you run in EyeTrack.
  • Open the command prompt and naviage to that directory. Type:
python getSentences.py studyname.script

Enter the starting condition number for the experiment you’re working on within the study, and the total number of conditions in that experiment. You’ll get two .txt files as the output (allsentences.txt with all items from all experiments, expsentences.txt will the items of the experiment you intended to extract).

Note: If you have already generated a delimited .script file for make_cnt.py, you can use that file instead of your original .script file and it will include your delimited characters. This means you will not have to hand-delimit a second time and thus you can skip the following section.

Making a .DEL file

A .del file is a file delimiting the regions of interest for each sentence. You need to make this by hand, because you’re the one who has to decide which parts of the sentence are interesting for your experiment. Once you have your sentence list generated from getSentences.py, add forward slashes to delimit the regions. You can import the text file into Excel to partially automate this process.

  • There should be a space at the beginning of each region, if possible. (Obviously this won’t be possible for the first region of the item.)
  • Include a slash at the end of the last region. (but make sure it does not include any unnecessary line change)
  • Save the text file as studyname.del

The resulting file should look like this:

1 2 /The housemaids/ encountered the/ serf/ in the/ local park. \n/They laughed /at his/ jokes/ on the/ way home./
2 2 /The housemaids/ encountered the/ lord/ in the/ local park. \n/They laughed /at his/ jokes/ on the/ way home./
3 2 /The housemaids/ encountered/ Bert/ in the/ local park. \n/They laughed /at his/ jokes/ on the/ way home./
4 2 /The housemaids/ encountered/ Eric/ in the/ local park. \n/They laughed /at his/ jokes/ on the/ way home./
1 3 /The girls/ asked the/ serf/ for the/ latest gossip. \n/They gasped /at his/ sordid/ stories/ about the aristocracy./
2 3 /The girls/ asked the/ lord/ for the/ latest gossip. \n/They gasped /at his/ sordid/ stories/ about the aristocracy./
...

Importantly, you need to be careful about the carriage return encoding, at least if you use a Mac. The python script might not read the .del file correctly if it has Classic Mac CR encoding, and it will give you a .reg file that is incorrectly all on one line. It is easy to check the encoding of the .del file if you use the TextWrangler text editor. Just open the file there and look at the very bottom of the window at the fifth tab from the left. It should read ‘Unix LF’. If it reads ‘Classic Mac CR’ you need to toggle to the ‘Unix LF’ option and re-save the file.

Making a. REG file

A .reg file (formally known as a .CNT file) is a file that contains the x-y coordinates of the regions of interest for each item in each condition. You can create this with the script makeRegions.py.

  • Make sure your .del file is in the same as the copy of make_reg_file.py
  • Open the command prompt, and navigate to that directory.
  • To run the script, type:
python makeRegions.py studyname.del

The output will be a file called output.reg.txt in the same directory. Currently, the encoding of this file cannot be .txt. On a Mac, using TextWrangler or BBEdit, you can change the encoding by opening the file and navigating to the bottom of the window.

If you see something like this:

You must change it to something like this:

Remember to save the new file with .reg at the end of the name.

question_acc.py

Next it’s time to use question_acc.py. It seems like the script file you need for parameters.txt might be the full script, not the one altered for make_cnt.py. Here’s what it looks like in the Terminal.

MacBook-Pro-2:GOOD_ASC username$ python3 question_acc.py
What is the name of your parameter file?parameters.txt
PR17_fa.asc
PR17_fa.asc 50 18 0.36
PR09_fa.asc
PR09_fa.asc 50 33 0.66
PR05_fa.asc
PR05_fa.asc 50 19 0.38
PR33_fa.asc
PR33_fa.asc 50 21 0.42
… etc

Robodoc.py

Finally, here’s what Robodoc.py does.

MacBook-Pro-2:GOOD_ASC username$ python3 Robodoc.py parameters.txt
PR17_fa.asc
PR09_fa.asc
PR05_fa.asc
PR33_fa.asc
PR50_fa.asc

side-eye (beta)

Brian Dillon has given me access to side-eye as a beta tester.

Set up

Local installation:

pip install /Applications/Gitcetera/side-eye

Pre-alpha testing

Adapted from documentation:

The examples directory contains sample.py, which is an example of the simplest way to use the package. To run on a folder of DA1 files:

  1. Copy sample.py and sample_config.json into the directory containing a folder of DA1 files and a .cnt or .reg region file.
  2. Open both files in a text editor.
  3. Replace the file paths in sample.py with paths to your DA1 and region files.
  4. Replace examples/sample_output.csv with whatever you want the output file to be named.
  5. Edit sample_config.json to match the parameters needed for your experiment, according to the instructions in The Configuration File.

DA1 fields

Sample .DA1 file from ION set-up (using EyeTrack):

1 1 1 35977 4 166 -1 -1 0 7 -1 -1 57 213 41 0 265 673 -1 -1 723 885 -1 -1 909 1089 -1 -1 1119 1273…
2 1 1 5754 5 23 2 0 0 336 11 0 360 554 19 0 578 760 23 0 778 1092 25 0 1104 1182 31 0 1206 1382 37…
3 1 1 2118 5 9 -1 -1 37 107 -1 -1 117 199 -1 -1 249 395 -1 -1 409 559 -1 -1 579 735 -1 -1 759 1045…
4 1 1 3907 4 14 0 0 0 290 8 0 314 454 16 0 478 628 25 0 650 918 33 0 944 1102 39 0 1122 1288 50 0…
5 1 1 1813 4 7 -1 0 0 178 -1 -1 224 368 -1 -1 390 620 -1 -1 646 816 -1 -1 840 980 -1 -1 1038 1344…

To me, this looks like the following code for sample_config.json should be appropriate (where -1 indicates the last index of a line):

"da1_fields" : {
    "index": 0,
    "condition": 1,
    "number": 2,
    "time": 3,
    "fixation_start": 6

I suspect index[4] is button press. Since I struggled to get a consistent mapping between the Gravis Destroyer’s 5 buttons and the EyeTrack code, I am operating under the assumption that 5 is consistently purple (i.e., left, a.k.a. “Yes”), and all other numbers (2,3,4 are most common) are from the righthand buttons (a.k.a. “No”). Since any button could be used to proceed to the next sentence if no question were presented, I’m not sure how to interpret any of these button presses at the moment. I’m also not sure whether it matters right now.

In fact fixation_start must be index[6], since index[5] is the total number of fixations in the trial! Cool!

Region fields

Here is the first bit of a .reg file, which corresponds with the first two items, each with four conditions.

1 2 7 0 0 7 0 7 1 15 1 24 1 31 1 49 1
2 2 7 0 0 6 0 7 1 15 1 24 1 31 1 49 1
3 2 7 0 0 8 0 7 1 15 1 24 1 31 1 49 1
4 2 7 0 0 7 0 7 1 15 1 24 1 31 1 49 1
1 3 7 0 0 8 0 8 1 19 1 28 1 34 1 54 1
2 3 7 0 0 6 0 8 1 19 1 28 1 34 1 54 1
3 3 7 0 0 9 0 8 1 19 1 28 1 34 1 54 1
4 3 7 0 0 8 0 8 1 19 1 28 1 34 1 54 1
…
  • index[0] seems to be the condition number
  • index[1] is the item number
  • index[2] is the number of regions in the item
  • index[3] is ???
  • index[4] is ???
  • index[5] is ???
  • index[6] must be where the boundaries start
"region_fields": {
  "number": 0,
  "condition": 1,
  "boundaries_start": 6,
  "includes_y": true

Notably, there are x- and y-coordinates in this dataset, which are some of the 0s and 1s interspersed in the other numbers. Not sure how to identify them, and this caused issues in previous attempts.

And the rest…

I don’t know what numbers are appropriate for cutoffs, region measures or trial measures.

Region output and trial output seem fine as is.

I’ve changed a few things:

  • For calculating region length: region_start and region_end = TRUE
  • For information: region_text = TRUE

Running side-eye

In Terminal, run the following.

cd asc/GOOD_ASC/side-eye
python3 sample.py
MacBook-Pro-2:side-eye username$ python3 sample-LMA.py
Item number 1 , condition 1 does not exist. It was not added to the Experiment object.
Item number 1 , condition 1 does not exist. It was not added to the Experiment object.

This output means item 1 (which happens to be the instructions and practice questions, thus not a real item) is excluded from this dataset. The output is a .csv file. Brian says: [Regions listed as NA are] used for the region field for trial level calculations (total viewing time, for example).

Data set

After all this, what does the data set actually look like? What does it contain? The following dataset has issues, but they can easily be resolved through find-and-replace functions outside of R. For instance, region_start and region_end encode the coordinates incorrectly, which pushes all information two cells to the right. This is why skip is under experiment_name in the first column.

#library(dplyr)
df.eyetrack <- read.csv(file.choose(), header=TRUE)
df.eyetrack %>%
  as_tibble() %>%
  group_by(experiment_name)

Once it’s been properly edited (by hand or text processing), this is what we might see. In the below output, the region coordinates have been fixed and I’ve changed some of the column names to suit me. I’ve also excluded some columns that I don’t find useful (e.g., filename). However, notice how $value is a factor and contains both python booleans (True) and numerics. This can be recoded once measure type is subsetted out.

df.eyetrack <- read.csv(file.choose(), header=TRUE)
df.eyetrack %>%
  as_tibble() %>%
  group_by(subj)

Failed attempts

Regions from make_cnt.py

I am having a difficult time interpreting the .cnt file. Here is the first bit, which seems to maybe correspond with the first five items (to parallel the previous sample). If so, index[0] seems to be the item identifier, index[1] would be the condition number, index[2] seems to be a value either 1 or 3, and index[3] must be where the boundaries start.

2 1 3 0 0 7
2 1 1 0
2 2 3 0 0 6
2 2 1 0
2 3 3 0 0 8
2 3 1 0
2 4 3 0 0 7
2 4 1 0
3 1 3 0 0 8
3 2 3 0 0 6
3 3 3 0 0 9
3 4 3 0 0 8
4 1 3 0 0 8
4 1 1 0
4 2 3 0 0 6
4 2 1 0
4 3 3 0 0 8
4 3 1 0
4 4 3 0 0 9
4 4 1 0
5 1 3 0 0 9
5 2 3 0 0 6
5 3 3 0 0 12
5 4 3 0 0 8

However, the boundaries don’t make any sense to me.
|/Joseph /might expect to learn \nhow to /express /themself /better /in a poetry class./
Would the boundaries for this item (E1I2D0) not be 0 7 (\n) 7 15 24 31 49?

"region_fields": {
  "number": 0,
  "condition": 1,
  "boundaries_start": 3,
  "includes_y": false

eyeDataToR.py

This is adapted from the deprecated UMD EyeLink wiki (Accessed from the Internet Wayback Machine on 19 April 2018; archived on 22 August 2012).

Run eyeDataToR.py which is supposed to prompt you for the following input:

  1. name of the regions file (.reg or .cnt)
  2. ~name of the question key~ (not sure what this is, possibly replaced with question_acc.py)
  3. name of the folder containing sentence data
  4. name of the folder containing question data
  5. name of the output file you want to create

I’ve hard-coded the file names for some reason (or they came that way?), but it’s still not working…

MacBook-Pro-2:GOOD_ASC username$ python eyeDataToR.py
fixation time settings:
low cutoff: 40ms
high cutoff: 2000ms
computing all measures
('processing', '9_f')
no question data for 9_f
Traceback (most recent call last):
  File "eyeDataToR.py", line 119, in <module>
    regXend = str(reg[1][0])
TypeError: 'int' object has no attribute '__getitem__'

Running side-eye

cd asc/GOOD_ASC/side-eye
python3 sample.py
MacBook-Pro-2:side-eye username$ python3 sample-LMA.py
Traceback (most recent call last):
  File "sample-LMA.py", line 17, in <module>
    experiments = sideeye.parser.experiment.parse_dir('da1_files', 'progen.reg.txt', 'sample_config.json')
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sideeye/parser/experiment.py", line 75, in parse_dir
    verbose=verbose)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sideeye/parser/region.py", line 59, in file
    validate_region_file(filename)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sideeye/parser/region.py", line 38, in validate_region_file
    raise ValueError('%s Failed validation: Not a region file' % filename)
ValueError: progen.reg.txt Failed validation: Not a region file

Nope.
After testing out a few alterations, I suspect there are a few things going wrong:

  1. The file must be encoded as a .cnt or .reg, not .txt.
  2. Previous code to make a .reg.txt file specified line number in a way that .cnt files do not, and thus are incompatible
  3. This seems to be the case because the reg.txt file ends each line in a 1, which seems to indicate the second line of the stimulus.
1 2 7 0 0 7 0 7 1 15 1 24 1 31 1 49 1
2 2 7 0 0 6 0 7 1 15 1 24 1 31 1 49 1
3 2 7 0 0 8 0 7 1 15 1 24 1 31 1 49 1
4 2 7 0 0 7 0 7 1 15 1 24 1 31 1 49 1

I hand-altered this file to be of a form I thought looked appropriate:

1 2 7 0 7 7 15 24 31 49
2 2 7 0 6 7 15 24 31 49
3 2 7 0 8 7 15 24 31 49
4 2 7 0 7 7 15 24 31 49

But then I still get this error, which is the same as when the line ended with a 1:

Laurens-MacBook-Pro-2:side-eye lmackerman$ python3 sample-LMA.py
Traceback (most recent call last):
  File "sample-LMA.py", line 17, in <module>
    experiments = sideeye.parser.experiment.parse_dir('da1_files', 'test.cnt', 'sample_config.json')
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sideeye/parser/experiment.py", line 75, in parse_dir
    verbose=verbose)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sideeye/parser/region.py", line 88, in file
    line_to_regions(line[boundaries_start:]))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sideeye/parser/region.py", line 75, in line_to_regions
    regions += [Region(Point(x_start, 0), Point(x_end, 0))]
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sideeye/data/region.py", line 29, in __init__
    raise ValueError('End of region must be after start of region.')
LS0tCnRpdGxlOiAiVHVybmluZyAuRURGcyBpbnRvIGEgZGF0YXNldCIKYXV0aG9yOiAiTGF1cmVuIE0gQWNrZXJtYW4iCmRhdGU6ICJsYXN0IGVkaXRlZDogMjIgTWF5IDIwMTgiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDIKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgaW5jbHVkZXM6IAogICAgICBpbl9oZWFkZXI6IGdvb2dsZV9hbmFseXRpY3MuaHRtbAotLS0KClvwn5SZIEhvbWVdKGh0dHBzOi8vdmVyYmluZ25vdW5zLmdpdGh1Yi5pby9ub3RlYm9va3MvKQoKQWxsIHdvcmsgYXNzb2NpYXRlZCB3aXRoIHRoZSBbQ2VudHJlIGZvciBCZWhhdmlvdXIgYW5kIEV2b2x1dGlvbl0oaHR0cDovL3d3dy5uY2wuYWMudWsvY2JlLyksIGluY2x1ZGluZyB0aGlzIGRvY3VtZW50YXRpb24sIGlzIHN1cHBvcnRlZCBieSBhIFdlbGxjb21lIFRydXN0IENhcGl0YWwgQXdhcmQgdG8gTmV3Y2FzdGxlIChncmFudCByZWY6IDA5MjUwNCkuCgpgYGBge3IsIGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KbGlicmFyeShyZXRpY3VsYXRlKQp1c2VfcHl0aG9uKHB5dGhvbj0iL3Vzci9sb2NhbC9iaW4vcHl0aG9uMyIsIHJlcXVpcmVkID0gVFJVRSkgIyB0aGlzIG5lZWRzIHRvIGJlIEZJUlNUIGJlY2F1c2Ugb25seSBvbmUgdmVyc2lvbiBjYW4gYmUgbG9hZGVkIHBlciBSIHNlc3Npb24KYGBgYAoKIyBQdXJwb3NlCgpUaGlzIG5vdGVib29rIGdvZXMgdGhyb3VnaCBwcmUtcHJvY2Vzc2luZyBkYXRhIGZyb20gYW4gRXllTGluayAxMDAwIHJ1bm5pbmcgW0V5ZVRyYWNrXShodHRwczovL2Jsb2dzLnVtYXNzLmVkdS9leWVsYWIvc29mdHdhcmUvKS4gCgojIyBUZWNobmljYWwgU3BlY2lmaWNhdGlvbnMKCiogW0V5ZUxpbmsgMTAwMF0oaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZG9jdW1lbnQvZC8xSHMyWWIwNndQNU85cUw0M01wRTRneWFjTHp3N29IYUljMTh4QzRmSzZNdy9lZGl0P3VzcD1zaGFyaW5nKSBsb2NhdGlvbiBpbiB0aGUgW0luc3RpdHV0ZSBvZiBOZXVyb3NjaWVuY2VdKGh0dHA6Ly93d3cubmNsLmFjLnVrL2lvbi8pIGluIHRoZSBIZW5yeSBXZWxsY29tZSBCdWlsZGluZywgTmV3Y2FzdGxlIFVuaXZlcnNpdHkKKiBbRXllVHJhY2tdKGh0dHBzOi8vYmxvZ3MudW1hc3MuZWR1L2V5ZWxhYi9zb2Z0d2FyZS8pIHNvZnR3YXJlIGRldmVsb3BlZCBhbmQgaG9zdGVkIGJ5IFVNYXNzIEFtaGVyc3QKICAgIC0gdXNpbmcgYSBHcmF2aXMgRGVzdHJveWVyIGNvbnRyb2wgcGFkIChbYWRkaXRpb25hbCBzcGVjc10oaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZG9jdW1lbnQvZC8xWXZJV3h6UHBpUVVaRGxBMVJqQ1BPZTRxaElOejloUEVKcjlsSDZaMmFsTS9lZGl0P3VzcD1zaGFyaW5nKSkKCiMgZml4X2FsaWduX3YwcDkyLlIKClRoaXMgc2VjdGlvbiB0YWtlcyB0aGUgcHJvc2UgaW5mb3JtYXRpb24gZnJvbSBDb2hlbiAoMjAxMykgYW5kIHB1dHMgaW4gaXQgbGlzdHMgZm9yIHF1aWNrIGFjY2Vzc2liaWxpdHkuIAoKPiBDb2hlbiwgQW5kcmV3IEwuICgyMDEzKS4gU29mdHdhcmUgZm9yIHRoZSBhdXRvbWF0aWMgY29ycmVjdGlvbiBvZiByZWNvcmRlZCBleWUgZml4YXRpb24gbG9jYXRpb25zIGluIHJlYWRpbmcgZXhwZXJpbWVudHMuICpCZWhhdmlvciByZXNlYXJjaCBtZXRob2RzKiwgNDUoMyksIDY3OS0tNjgzLiBBY2Nlc3NlZCBmcm9tOiBbaHR0cHM6Ly9wZW9wbGUudW1hc3MuZWR1L2V5ZWxhYi9Db2hlbkJSTS5wZGZdKGh0dHBzOi8vcGVvcGxlLnVtYXNzLmVkdS9leWVsYWIvQ29oZW5CUk0ucGRmKQoKCiMjIFVuZGVyc3RhbmRpbmcgdGhlIGZ1bmN0aW9uCgpJbiBvcmRlciB0byB1c2UgZml4X2FsaWduIHByb3Blcmx5LCBpdCdzIGdvb2QgdG8gdW5kZXJzdGFuZCB3aGF0IGFyZ3VtZW50cyBpdCB0YWtlcyBhbmQgd2hhdCBpdCBkb2VzIHdpdGggdGhvc2UgYXJndW1lbnRzLiBJIHByZXNlbnQgaW5mb3JtYXRpb24gY29uZGVuc2VkIGZyb20gQ29oZW4gKDIwMTMpIGFuZCBteSBvd24gaW50ZXJwcmV0YXRpb25zIGFuZCBleHBlcmllbmNlcyB3aXRoIHVzaW5nIGl0LgoKYGBgYHtyfQpsaWJyYXJ5KGtuaXRyKQpzb3VyY2UoJ2ZpeF9hbGlnbl92MHA5Mi5SJykKYGBgYAoKYGBgYApmaXhfYWxpZ24gPC0gZnVuY3Rpb24oc3RhcnRfcHRzLCAgICAgICAgICAgICAgICAgICAgICAjIHdoZXJlIGRvZXMgZWFjaCBsaW5lIHN0YXJ0CiAgICAgICAgICAgICAgICAgICAgICBhc2NfZmlsZXMgICAgICAgICA9ICcuJywgICAgICAgICMgd2hlcmUgYXJlIHRoZSBmaWxlcwogICAgICAgICAgICAgICAgICAgICAgeHlfYm91bmRzICAgICAgICAgPSBOVUxMLCAgICAgICAjIHJlbW92ZSBwb2ludHMgYmVmb3JlIGNhbGN1bGF0aW5nIHJlZ3Jlc3Npb24KICAgICAgICAgICAgICAgICAgICAgIGtlZXBfeV92YXIgICAgICAgID0gRkFMU0UsICAgICAgIyBUUlVFOiByZXNpZHVhbCBmb3IgaXRzIHJlZ3Jlc3Npb24gaXMga2VwdAogICAgICAgICAgICAgICAgICAgICAgdXNlX3J1bl9ydWxlICAgICAgPSBUUlVFLCAgICAgICAjIAogICAgICAgICAgICAgICAgICAgICAgdHJpYWxfcGxvdHMgICAgICAgPSBUUlVFLCAgICAgICAjIAogICAgICAgICAgICAgICAgICAgICAgc2F2ZV90cmlhbF9wbG90cyAgPSBGQUxTRSwgICAgICAjIC50aWZmIHBsb3RzIHNhdmVkIGluIGRpcmVjdG9yeSDigJxUcmlhbF9QbG90c+KAnQogICAgICAgICAgICAgICAgICAgICAgc3VtbWFyeV9maWxlICAgICAgPSBUUlVFLCAgICAgICAjIFRSVUU6IGEgLmZhcyBpcyBzYXZlZCBpbiBmYV9kaXIKICAgICAgICAgICAgICAgICAgICAgIHNob3dfaW1hZ2UgICAgICAgID0gRkFMU0UsICAgICAgIyBUUlVFOiB0cmlhbHMgb24gdG9wIG9mIGJhY2tncm91bmQgaW1hZ2VzCiAgICAgICAgICAgICAgICAgICAgICBmYV9kaXIgICAgICAgICAgICA9ICdGQV9EaXInLCAgICMgd2hlcmUgYXJlIHRoZSAuYXNjIGZpbGVzPwogICAgICAgICAgICAgICAgICAgICAgc3RhcnRfZmxhZyAgICAgICAgPSAnVFJJQUxJRCcsICAjIHdoYXQgZG8gdHJpYWxzIHN0YXJ0IHdpdGg/CiAgICAgICAgICAgICAgICAgICAgICBkZW5fc2RfY3V0b2ZmICAgICA9IEluZiwgICAgICAgICMgcmVtb3ZlIG91dGxpZXJzCiAgICAgICAgICAgICAgICAgICAgICBkZW5fcmF0aW9fY3V0b2ZmICA9IDEsICAgICAgICAgICMgcmVtb3ZlIG91dGxpZXJzCiAgICAgICAgICAgICAgICAgICAgICBrX2JvdW5kcyAgICAgICAgICA9IGMoLS4xLCAuMSksICMgTlVMTCA9IDA7IG1pbi9tYXggb2YgcmVncmVzc2lvbiBzbG9wZQogICAgICAgICAgICAgICAgICAgICAgb19ib3VuZHMgICAgICAgICAgPSBjKC01MCwgNTApLCAjIE5VTEwgPSAwOyBtaW4vbWF4IG9mIHZlcnRpY2FsIG9mZnNldAogICAgICAgICAgICAgICAgICAgICAgc19ib3VuZHMgICAgICAgICAgPSBjKDEsIDIwKSkgICAjIG1pbi9tYXggb2Ygc2QKYGBgYAoKIyMjIElucHV0CgpUYWtlbiBkaXJlY3RseSBmcm9tIENvaGVuICgyMDEzKToKCiogYHN0YXJ0X3B0c2AgaXMgYW4gbiDDlyAyIG1hdHJpeCB0aGF0IGRlZmluZXMgdGhlIHggYW5kIHkgbG9jYXRpb25zIG9mIHRoZSBzdGFydCBvZiBlYWNoIHRleHQgbGluZSwgd2hlcmUgbiBpcyB0aGUgbnVtYmVyIG9mIHRleHQgbGluZXMuCiogYGFzY19maWxlc2AgaXMgYSB2ZWN0b3Igb2YgLmFzYyBmaWxlIG5hbWVzIGFuZC9vciBmb2xkZXJzIGNvbnRhaW5pbmcgLmFzYyBmaWxlcy4KKiBBbnkgcG9pbnRzIG91dHNpZGUgdGhlIHJlY3RhbmdsZXMgcHJvdmlkZWQgYnkgYHh5X2JvdW5kc2AgYXJlIGNvbnNpZGVyZWQgb3V0IG9mIGJvdW5kcyBhbmQgYXJlIHJlbW92ZWQgZnJvbSB0aGUgYW5hbHlzaXMgYmVmb3JlIHRoZSByZWdyZXNzaW9uIGxpbmVzIGFyZSBkZXRlcm1pbmVkLgoqIGB4eV9ib3VuZHNgIHByb3ZpZGVzIGEgd2F5IHRvIHJlbW92ZSBwb2ludHMgZnJvbSBhbmFseXNpcyBhIHByaW9yaS4gCiAgICAtIEFueSBwb2ludHMgb3V0c2lkZSB0aGUgcmVjdGFuZ2xlcyBwcm92aWRlZCBieSBgeHlfYm91bmRzYCBhcmUgY29uc2lkZXJlZCBvdXQgb2YgYm91bmRzIGFuZCBhcmUgcmVtb3ZlZCBmcm9tIGFuYWx5c2lzIGJlZm9yZSB0aGUgcmVncmVzc2lvbiBsaW5lcyBhcmUgZGV0ZXJtaW5lZC4gCiAgICAtIEFsbCBvdGhlciBwb2ludHMgYXJlIGluY2x1ZGVkIGluIHRoZSBjcmVhdGlvbiBvZiB0aGUgcmVncmVzc2lvbiBsaW5lcy4gCiAgICAtIFRoZSBib3VuZHMgY2FuIGJlIHNldCB0byBubyBib3VuZHMgKGBOVUxMYCksIGEgc2luZ2xlIHJlY3RhbmdsZSBmb3IgdGhlIGVudGlyZSBleHBlcmltZW50IChhIDEgw5cgNCB2ZWN0b3I6IHgtbWluLCB4LW1heCwgeW1pbiwgYW5kIHktbWF4KSwgb3Igb25lIHJlY3RhbmdsZSBwZXIgdHJpYWwgKGFuIG4gw5cgNCBtYXRyaXggb2YgcmVjdGFuZ2xlcykuCiogSWYgYGtlZXBfeV92YXJgIGlzIHNldCBhcyBgVFJVRWAsIHRoZSByZXNpZHVhbCBvZiBlYWNoIGZpeGF0aW9uIGFyb3VuZCBpdHMgYXNzaWduZWQgcmVncmVzc2lvbiBsaW5lIGlzIGtlcHQgd2hlbiB0aGUgeSBsb2NhdGlvbiBpcyBjaGFuZ2VkOyBvdGhlcndpc2UsIGl0IGlzIHJlbW92ZWQuCiogIElmIGB1c2VfcnVuX3J1bGVgIGlzIHNldCBhcyBgVFJVRWAsIGFtYmlndW91cyBmaXhhdGlvbnMgYXJlIHBvdGVudGlhbGx5IHJlY2xhc3NpZmllZCBieSB0aGVpciBzdXJyb3VuZGluZyBmaXhhdGlvbnMgYXMgZGVzY3JpYmVkIGFib3ZlOyBvdGhlcndpc2UsIHRoZXkgcmVtYWluIGFtYmlndW91cy4KKiBJZiBgdHJpYWxfcGxvdHNgIGlzIHNldCBhcyBgVFJVRWAsIHRyaWFsLWJ5LXRyaWFsIHBsb3RzIG9mIHRoZSBvcmlnaW5hbCBhbmQgcmVmb3JtYXR0ZWQgZml4YXRpb25zIGFyZSBzaG93bi4KKiBJZiBgc2F2ZV90cmlhbF9wbG90c2AgaXMgc2V0IGFzIGBUUlVFYCwgdGhlIHRyaWFsIHBsb3RzIGFyZSBzYXZlZCBhcyAudGlmZiBmaWxlcywgaW4gYSBzdWJkaXJlY3RvcnkgY2FsbGVkIOKAnFRyaWFsX1Bsb3Rz4oCdIGluIHRoZSBkaXJlY3RvcnkgZGVmaW5lZCBieSBgZmFfZGlyYAogICAgLSBJbiB0aGlzIGNhc2UsIHRoZSBwbG90cyB3aWxsIG9ubHkgYmUgc2F2ZWTigJR0aGF0IGlzLCB0aGV5IHdpbGwgbm90IGJlIHNob3duIG9uIHRoZSBzY3JlZW4uCiAgICAtIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj5UaGVzZSBmaWxlcyBhcmUgbWFzc2l2ZSwgc28gZG8gbm90IHVzZSB0aGlzIG9wdGlvbiB1bmxlc3MgeW91IGFyZSBwcm9jZXNzaW5nIGEgc21hbGwgYW1vdW50IG9mIGRhdGEgb3IgaGF2ZSBhIGxvdCBvZiBzdG9yYWdlIHNwYWNlLjwvc3Bhbj4KKiBJZiBgc3VtbWFyeV9maWxlYCBpcyBzZXQgYXMgYFRSVUVgLCBhIC5mYXMgKGZpeCBhbGlnbiBzdW1tYXJ5KSBmaWxlIGlzIGNyZWF0ZWQgCiAgICAtIEl0IHNhdmVzIHRoZSBzbG9wZSwgdmVydGljYWwgb2Zmc2V0LCBzdGFuZGFyZCBkZXZpYXRpb24sIHJlZ3Jlc3Npb24gZml0LCBhbmQgdGhlIG51bWJlcnMgb2YgdG90YWwsIGtlcHQsIG91dC1vZi1ib3VuZHMsIGFtYmlndW91cywgb3V0bGllciwgYW5kIG90aGVyIGZpeGF0aW9ucyBmb3IgZWFjaCBwYXJ0aWNpcGFudCBhbmQgZWFjaCB0cmlhbC4KKiBJZiBgc2hvd19pbWFnZWAgaXMgc2V0IGFzIGBUUlVFYCwgdGhlIHRyaWFsIHBsb3RzIGFyZSBzaG93biBvbiB0b3Agb2YgYmFja2dyb3VuZCBpbWFnZXMuCiAgICAtIFRoZXNlIGJhY2tncm91bmQgaW1hZ2VzIGFyZSAudGlmZiBmaWxlcyBsb2NhdGVkIGluIHRoZSBzYW1lIGRpcmVjdG9yeSBhcyB0aGUgZGF0YSBmaWxlcy4gCiAgICAtIE9uZSBpbWFnZSBjYW4gYmUgdXNlZCBwZXIgLmFzYyBmaWxlLCBvciBvbmUgaW1hZ2UgcGVyIHRyaWFsIHBlciAuYXNjIGZpbGUsIGFuZCBpbWFnZXMgbXVzdCBiZSBzYXZlZCBhcyAudGlmZiBmaWxlcyB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgdGhlIC5hc2MgZmlsZSBhbmQgdGhlIC50aWZmIGVuZGluZy4gCiAgICAtIElmIG9uZSBpbWFnZSBpcyB1c2VkIHBlciB0cmlhbCwgdGhlIGVuZCBvZiB0aGUgbmFtZSBtdXN0IGhhdmUgYW4gdW5kZXJzY29yZSBmb2xsb3dlZCBieSBhIHRyaWFsIG51bWJlciAoZS5nLiwg4oCcXzHigJ0gZm9yIFRyaWFsIDEpLgoqIGBmYV9kaXJgIGlzIHRoZSBuYW1lIG9mIHRoZSBkaXJlY3RvcnkgdXNlZCB0byBzdG9yZSB0aGUgcmVmb3JtYXR0ZWQgLmFzYyBmaWxlcywgLmZhcyBmaWxlcywgYW5kIHRyaWFsIHBsb3RzLiAKICAgIC0gVGhlIC5hc2MgZmlsZXMgYXJlIG1hcmtlZCBieSBoYXZpbmcg4oCcX2Zh4oCdIChmaXggYWxpZ24pIGF0IHRoZSBlbmRzIG9mIHRoZWlyIG5hbWVzLgogICAgLSA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+VGhpcyBpcyBoYXJkLWNvZGVkIGFzIGBGQV9EaXJgIHRodXMgc2hvdWxkIGJlIHNldCB0byB0aGUgbmFtZSBvZiB0aGUgYWN0dWFsIGRpcmVjdG9yeS48L3NwYW4+CiogYHN0YXJ0X2ZsYWdgIGlzIHRoZSB0ZXh0IHRoYXQgbWFya3MgdGhlIHN0YXJ0IG9mIGRhdGEgY29sbGVjdGlvbiBpbiB0aGUgLmFzYyBmaWxlLCB3aGljaCB3aWxsIHR5cGljYWxseSBiZSBlaXRoZXIg4oCcVFJJQUxJROKAnSBvciDigJxTWU5DVElNRS7igJ0KKiBgZGVuX3NkX2N1dG9mZmAgZGVmaW5lcyB0aGUgbnVtYmVyIG9mIHN0YW5kYXJkIGRldmlhdGlvbnMgZnJvbSBhIHJlZ3Jlc3Npb24gbGluZSB0aGF0IGRldGVybWluZXMgYW4gb3V0bGllci4KKiBgZGVuX3JhdGlvX2N1dG9mZmAgZGVmaW5lcyB0aGUgcmF0aW8gKGluIGRlbnNpdHkpIHRoYXQgZGV0ZXJtaW5lcyBhbWJpZ3VvdXMgZml4YXRpb25zLgoqIGBrX2JvdW5kc2AsIGBvX2JvdW5kc2AsIGFuZCBgc19ib3VuZHNgIGFyZSAxw5cyIHZlY3RvcnMgdGhhdCBkZWZpbmUgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gdmFsdWVzIHRoYXQgdGhlIHJlZ3Jlc3Npb24gbGluZSBzbG9wZSwgdmVydGljYWwgb2Zmc2V0LCBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uLCByZXNwZWN0aXZlbHksIGNhbiB0YWtlLiAKICAgIC0gSWYgc2V0IHRvIGBOVUxMYCwgYGtfYm91bmRzYCBhbmQgYG9fYm91bmRzYCBoYXZlIHZhbHVlcyBvZiAwLgoKQW4gZXhhbXBsZSBpbnB1dCBkaXJlY3RseSBmcm9tIEZpZ3VyZSAyOgoKYGBgYApmaXhfYWxpZ24gPC0gZnVuY3Rpb24oc3RhcnRfcHRzID0gcmJpbmQoYygyNywgNDM2KSwgYygyNywgNTU2KSksCiAgICAgICAgICAgICAgICAgICAgICBhc2NfZmlsZXMgPSAnRGF0YS8yM181MEhfQi5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgc2F2ZV90cmlhbF9wbG90cyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICBzdGFydF9mbGFnID0gJ1NZTkNfVElNRScsCiAgICAgICAgICAgICAgICAgICAgICBkZW5fc2RfY3V0b2ZmID0gNC41LAogICAgICAgICAgICAgICAgICAgICAgZGVuX3JhdGlvX2N1dG9mZiA9IDU1MDAwKQpgYGBgCgpJZiB5b3UgZG9uJ3Qgd2FudCB0byByZW1vdmUgYW55IHBvaW50czoKCmBgYGAKZGVuX3NkX2N1dG9mZiA9IEluZiwKZGVuX3JhdGlvX2N1dG9mZiA9IDAKYGBgYAoKIyMjIE91dHB1dAoKQWRhcHRlZCBmcm9tIENvaGVuICgyMDEzKToKCiogQSAudGlmZiBmaWxlCiAgICAtIFRoZSB0cmlhbC1ieS10cmlhbCB2aXN1YWxpemF0aW9uIG9mIHRoZSBmaXhhdGlvbiBhZGp1c3RtZW50IGFuZCBjbGFzc2lmaWNhdGlvbnMuCiogQSAuZmFzIChmaXggYWxpZ24gc3VtbWFyeSkgZmlsZSAKICAgIC0gU2F2ZXMgdGhlIHNsb3BlLCB2ZXJ0aWNhbCBvZmZzZXQsIHN0YW5kYXJkIGRldmlhdGlvbiwgcmVncmVzc2lvbiBmaXQsIGFuZCB0aGUgbnVtYmVycyBvZiB0b3RhbCwga2VwdCwgb3V0LW9mLWJvdW5kcywgYW1iaWd1b3VzLCBvdXRsaWVyLCBub3QtaW4tdHJpYWwsIGFuZCBwYXJ0aWFsIGZpeGF0aW9ucyBmb3IgZWFjaCBwYXJ0aWNpcGFudCBhbmQgdHJpYWwuCiogVGhlIHJlZm9ybWF0dGVkIC5hc2MgZmlsZQogICAgLSAgVGhpcyBmaWxlIGlzIGEgY29weSBvZiB0aGUgb3JpZ2luYWwgLmFzYyBmaWxlLCB3aXRoIHRoZSB5IGxvY2F0aW9ucyBvZiB0aGUgZml4YXRpb25zIGNoYW5nZWQgdG8gcmVmbGVjdCB0aGUgcmVncmVzc2lvbiBhbmFseXNpcyBhbmQgZml4YXRpb24gcmVtb3ZhbCBwcm9jZXNzLgogICAgLSAgVGhpcyBmaWxlIGhhcyB0aGUgc2FtZSBuYW1lIGFzIHRoZSBvcmlnaW5hbCAuYXNjIGZpbGUsIHdpdGgg4oCcX2Zh4oCdIChmaXggYWxpZ24pIGFkZGVkIHRvIHRoZSBlbmQuCgojIyBQcmFjdGljYWwgYXBwbGljYXRpb24KCkluIG15IC5hc2MgZmlsZSwgdGhpcyBpcyB3aGF0IHRoZSBmaXJzdCBmZXcgbGluZXMgb2YgYSBzYW1wbGUgdHJpYWwgbG9vayBsaWtlICh0aGUgc2VudGVuY2UtaW5pdGlhbCB3b3JkICJUaGUiKS4KCmBgYGAKSU5QVVQJMzU4OTU5MAkxMjcKTVNHCTM1ODk2MTAgVFJJQUxJRCBFMTZJNzdEMApNU0cJMzU4OTYyOCBESVNQTEFZIFRFWFQgMQpNU0cJMzU4OTYyOCBSRUdJT04gQ0hBUiAwIDEgVCA2NyAyNjcgNzkgMzE5Ck1TRwkzNTg5NjI5IERFTEFZIDEgTVMKTVNHCTM1ODk2MjkgUkVHSU9OIENIQVIgMSAxIGggNzkgMjY3IDkxIDMxOQpNU0cJMzU4OTYzMSBERUxBWSAxIE1TCk1TRwkzNTg5NjMxIFJFR0lPTiBDSEFSIDIgMSBlIDkxIDI2NyAxMDMgMzE5Ck1TRwkzNTg5NjMyIERFTEFZIDEgTVMKTVNHCTM1ODk2MzMgUkVHSU9OIENIQVIgMyAxICAgMTAzIDI2NyAxMTUgMzE5Ck1TRwkzNTg5NjM0IERFTEFZIDEgTVMKYGBgYAoKSXQgbG9va3MgbGlrZSBgNjdgIGluZGljYXRlcyB0aGUgbGVmdG1vc3QgZWRnZSBvZiB0aGUgYFRgIGFuZCB0aGUgYDc5YCBpcyB0aGUgcmlnaHQgbW9zdCBlZGdlLCBzaW5jZSBgNzlgIGlzIGFsc28gdGhlIGxlZnRtb3N0IGVkZ2Ugb2YgYGhgLiBUaGF0IG1lYW5zIHZhbHVlcyBpbiB0aGVzZSBjb2x1bW5zIGFyZSB0aGUgeC1heGlzIHZhbHVlLiBUaGF0IG1ha2VzIGAyNjdgIHRoZSB0b3AgZWRnZSBhbmQgYDMxOWAgdGhlIGJvdHRvbSBlZGdlIG9mIHRoZSB5LWF4aXMuCgpUaGUgYnJlYWsgYmV0d2VlbiB0aGUgZmlyc3QgYW5kIHNlY29uZCBsaW5lIG9mIHRleHQgZnJvbSB0aGlzIHRyaWFsIGxvb2tzIGxpa2UgdGhpczoKCmBgYGAKTVNHCTM1ODk3NTAgUkVHSU9OIENIQVIgNTcgMSB0IDc1MSAyNjcgNzYzIDMxOQpNU0cJMzU4OTc1MiBERUxBWSAxIE1TCk1TRwkzNTg5NzUyIFJFR0lPTiBDSEFSIDU4IDEgaCA3NjMgMjY3IDc3NSAzMTkKTVNHCTM1ODk3NTQgREVMQVkgMSBNUwpNU0cJMzU4OTc1NSBSRUdJT04gQ0hBUiA1OSAxIGUgNzc1IDI2NyA3ODcgMzE5Ck1TRwkzNTg5NzU2IERFTEFZIDEgTVMKTVNHCTM1ODk3NTYgUkVHSU9OIENIQVIgNjAgMSAgIDc4NyAyNjcgNzk5IDMxOQpNU0cJMzU4OTc1OSBERUxBWSAxIE1TCk1TRwkzNTg5NzYwIFJFR0lPTiBDSEFSIDYyIDEgYSA2NyAzMjkgNzkgMzgxCk1TRwkzNTg5NzYyIERFTEFZIDEgTVMKTVNHCTM1ODk3NjMgUkVHSU9OIENIQVIgNjMgMSBuIDc5IDMyOSA5MSAzODEKTVNHCTM1ODk3NjQgREVMQVkgMSBNUwpNU0cJMzU4OTc2NSBSRUdJT04gQ0hBUiA2NCAxIG4gOTEgMzI5IDEwMyAzODEKTVNHCTM1ODk3NjcgREVMQVkgMSBNUwpNU0cJMzU4OTc2OCBSRUdJT04gQ0hBUiA2NSAxIHUgMTAzIDMyOSAxMTUgMzgxCk1TRwkzNTg5NzcwIERFTEFZIDEgTVMKTVNHCTM1ODk3NzEgUkVHSU9OIENIQVIgNjYgMSBhIDExNSAzMjkgMTI3IDM4MQpNU0cJMzU4OTc3MiBERUxBWSAxIE1TCk1TRwkzNTg5NzczIFJFR0lPTiBDSEFSIDY3IDEgbCAxMjcgMzI5IDEzOSAzODEKTVNHCTM1ODk3NzUgREVMQVkgMSBNUwpgYGBgCgpJdCBsb29rcyBsaWtlIHRoZSB4LWF4aXMgdmFsdWVzIGZvciB0aGUgc2Vjb25kIGxpbmUgYXJlIHRoZSBzYW1lIGFzIHRoZSBmaXJzdCBsaW5lLCBzbyBvdXIgeS1heGlzIHRvcCBlZGdlIGlzIGF0IGAzMjlgIGFuZCB0aGUgYm90dG9tIGVkZ2UgaXMgYXQgYDM4MWAuCgojIyMgVGVzdGluZyBpdCBvdXQKCk5vdyBJJ2xsIHB1dCBpbiBjdXN0b20gdmFsdWVzIGZvciBteSBmaWxlcy4gSSdtIG5vdCBzdXJlIHdoaWNoIHktYXhpcyBlZGdlcyB0byB1c2UsIHNvIEknbGwgZ28gd2l0aCB0aGUgbW9zdCBleHRyZW1lIG9uZXMgZm9yIGVhY2ggbGluZS4gVGhlIHgtYXhpcyB3aWxsIGJlIHRoZSBsZWZ0bW9zdCBlZGdlIGZvciBib3RoLgoKYGBge3IsIG1lc3NhZ2U9VFJVRX0KZml4X2FsaWduKHN0YXJ0X3B0cyA9IHJiaW5kKGMoNjcsIDI2NyksIGMoNjcsIDM4MSkpLAogICAgICAgICAgYXNjX2ZpbGVzID0gJ2FzYy9QUjAyLmFzYycsCiAgICAgICAgICBzYXZlX3RyaWFsX3Bsb3RzID0gVFJVRSwKICAgICAgICAgIGZhX2RpciA9ICdhc2MnLAogICAgICAgICAgc3RhcnRfZmxhZyA9ICdUUklBTElEJywKICAgICAgICAgIGRlbl9zZF9jdXRvZmYgPSBJbmYsCiAgICAgICAgICBkZW5fcmF0aW9fY3V0b2ZmID0gMCkKYGBgCgojIyMgUHJvY2Vzc2luZyBhbGwgZmlsZXMKCk9rYXksIHRoYXQgYWN0dWFsbHkgd29ya2VkLCBidXQgc2luY2UgaXQgd2FzIG9uZSBvZiB0aGUgbWVzc2llciBmaWxlcywgSSB3YW50IHRvIHRyeSBpdCB3aXRoIHRoZSBhdmVyYWdlIHktYXhpcyB2YWx1ZS4KCiogbGluZSAxID0gYHIgbWVhbihjKDI2NywzMTkpKWAKKiBsaW5lIDIgPSBgciBtZWFuKGMoMzI5LDM4MSkpYAoKSSd2ZSBhbHNvIHNldCBgZGVuX3NkX2N1dG9mZmAgdG8gMywgd2hpY2ggaGFzIGEgc2xpZ2h0bHkgbmFycm93ZXIgYmFuZCB0aGF0J3MgYWNjZXB0YWJsZSwgYW5kIGBkZW5fcmF0aW9fY3V0b2ZmYCBpcyBzZXQgdG8gNSBiZWNhdXNlIGxhcmdlIG51bWJlcnMgdGhyb3cgb3V0IGEgTE9UIG9mIHBvaW50cyB0aGF0IGFyZSBjb3JyZWN0bHkgY2F0ZWdvcml6ZWQgd2l0aCBzbWFsbCBudW1iZXJzLiBUaGVzZSBudW1iZXJzIHdvcmsgZmFpcmx5IHdlbGwgd2l0aCBQUjAyLmFzYywgc28gSSB3aWxsIGFkZCBpbiBhbGwgdGhlIG90aGVyIGZpbGVzIG5vdy4gSSd2ZSBhbHNvIHNldCBzb21lIGB4eV9ib3VuZGAgY3V0b2ZmIHBvaW50cyB0byBpZ25vcmUgb3V0bGllcnMgdGhhdCBhcmUgKmRlZmluaXRlbHkqIG91dGxpZXJzIGJlZm9yZSBjYWxjdWxhdGluZyByZWdyZXNzaW9uIGxpbmVzLgoKYGBge3IsIG1lc3NhZ2U9VFJVRX0KZml4X2FsaWduKHN0YXJ0X3B0cyA9IHJiaW5kKGMoNjcsIDI5MyksIGMoNjcsIDM1NSkpLAogICAgICAgICAgYXNjX2ZpbGVzID0gYygjJ2FzYy9QUjAxaW5jLmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMDIuYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIwMy0xYi5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjA0LmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMDUuYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIwNi5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjA3LmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMDguYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIwOS5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjEwLmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMTEuYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIxMi5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjEzLmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMTQuYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIxNS5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjE2LmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMTcuYXNjJywKIyAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIxOC5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjE5LmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMjAuYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIyMS5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjIyLmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMjMuYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIyNS5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjI3LmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMjguYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIyOS5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjMwLmFzYycsCiMgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMzEuYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIzMi5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjMzLmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMzQuYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIzNS5hc2MnLAojICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjM2LmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMzguYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIzOS5hc2MnLAojICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjQwLmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSNDEuYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFI0Mi5hc2MnLAojICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjQzLmFzYycsICMgRXJyb3IgaW4gdHJpYWxfZml4W1tpXV0gOiBzdWJzY3JpcHQgb3V0IG9mIGJvdW5kcwojICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjQ0LmFzYycsICMgRXJyb3IgaW4gdHJpYWxfaWRfc3RhcnRbdF06dHJpYWxfZW5kW3RdIDogTkEvTmFOIGFyZ3VtZW50CiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSNDUuYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFI0Ni5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjQ3LmFzYycsCiMgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSNDguYXNjJywgIyBFcnJvciBpbiB0cmlhbF9maXhbW2ldXSA6IHN1YnNjcmlwdCBvdXQgb2YgYm91bmRzCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSNDkuYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFI1MC5hc2MnLAogICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjUxLmFzYycsCiAgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSNTIuYXNjJywKICAgICAgICAgICAgICAgICAgICAgICdhc2MvUFI1My5hc2MnKSwKICAgICAgICAgIHh5X2JvdW5kcyA9IGMoMjAsIDEwMDAsIDIwMCwgNjAwKSwgIyBjKHgtbWluLCB4LW1heCwgeW1pbiwgeS1tYXgpCiAgICAgICAgICB0cmlhbF9wbG90cyA9IEZBTFNFLCAjIGkgY2FuJ3QgZ2V0IHRoaXMgdG8gZG8gYW55dGhpbmcgZXhjZXB0IHNwaW4gaXRzIHdoZWVscz8KICAgICAgICAgIHNhdmVfdHJpYWxfcGxvdHMgPSBGQUxTRSwgIyB3b3cgdGhhdCB0YWtlcyB1cCBhIExPVCBvZiBzcGFjZQogICAgICAgICAgZmFfZGlyID0gJ2FzYycsCiAgICAgICAgICBzdGFydF9mbGFnID0gJ1RSSUFMSUQnLAogICAgICAgICAgZGVuX3NkX2N1dG9mZiA9IDMsICMgbm90IHN1cmUgd2hhdCdzIGJlc3QsIGJ1dCB0aGlzIHNlZW1zIHRvIHdvcmsgb2theQogICAgICAgICAgZGVuX3JhdGlvX2N1dG9mZiA9IDUpICMgc21hbGwgbnVtYmVycyBzZWVtIHRvIGRvIGZpbmXigKY/CmBgYAoKVGhlcmUgc2VlbWVkIHRvIGJlIHNvbWUgaXNzdWVzIHdpdGggYFBSMDlgIHdoZW4gSSB3YXMgc3RpbGwgY3JlYXRpbmcgLnRpZmYgZmlsZXMsIGJ1dCBhIHNwb3QgY2hlY2sgbWFrZSBpdCBsb29rIGxpa2UgJ3dlaXJkJyB0cmlhbHMgd2VyZSBtb3N0bHkgcmVqZWN0ZWQgcmF0aGVyIHRoYW4gbWlzY2F0ZWdvcml6ZWQgKG1vcmUgb2Z0ZW4gdGhhbiBub3QpLgoKIyMjIERlYnVnZ2luZyBwcm9ibGVtIGZpbGVzCgpUaGVzZSBmaWxlcyB0aHJvdyBlcnJvcnMgYW5kIEknZCBsaWtlIHRvIGtub3cgd2h5LiA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5UbyBkbzogZm9sbG93IHVwIHdpdGggSmVzc2UgSGFycmlzIGV0IGFsLjwvc3Bhbj4KCmBgYHtyLCBtZXNzYWdlPVRSVUV9CmZpeF9hbGlnbihzdGFydF9wdHMgPSByYmluZChjKDY3LCAyOTMpLCBjKDY3LCAzNTUpKSwKICAgICAgICAgIGFzY19maWxlcyA9IGMoIydhc2MvUFIwMWluYy5hc2MnLCAjIEVycm9yIGluIHRyaWFsX2lkX3N0YXJ0W3RdOnRyaWFsX2VuZFt0XSA6IE5BL05hTiBhcmd1bWVudAojICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjE4LmFzYycjLCAgRXJyb3IgaW4gdHJpYWxfaWRfc3RhcnRbdF06dHJpYWxfZW5kW3RdIDogTkEvTmFOIGFyZ3VtZW50CiMgICAgICAgICAgICAgICAgICAgICAnYXNjL1BSMzEuYXNjJyMsICBFcnJvciBpbiB0cmlhbF9pZF9zdGFydFt0XTp0cmlhbF9lbmRbdF0gOiBOQS9OYU4gYXJndW1lbnQKIyAgICAgICAgICAgICAgICAgICAgICdhc2MvUFIzNi5hc2MnIywgIEVycm9yIGluIHRyaWFsX2lkX3N0YXJ0W3RdOnRyaWFsX2VuZFt0XSA6IE5BL05hTiBhcmd1bWVudAojICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjQwLmFzYycjLCAgRXJyb3IgaW4gaWYgKHRyaWFsX2lkX3N0YXJ0W3N0YXJ0X2luZGV4ICsgMV0gPCB0cmlhbF9lbmRbZW5kX2luZGV4XSkgeyA6IG1pc3NpbmcgdmFsdWUgd2hlcmUgVFJVRS9GQUxTRSBuZWVkZWQKIyAgICAgICAgICAgICAgICAgICAgICdhc2MvUFI0My5hc2MnIywgIEVycm9yIGluIHRyaWFsX2ZpeFtbaV1dIDogc3Vic2NyaXB0IG91dCBvZiBib3VuZHMKIyAgICAgICAgICAgICAgICAgICAgICdhc2MvUFI0NC5hc2MnIywgIEVycm9yIGluIHRyaWFsX2lkX3N0YXJ0W3RdOnRyaWFsX2VuZFt0XSA6IE5BL05hTiBhcmd1bWVudAojICAgICAgICAgICAgICAgICAgICAgJ2FzYy9QUjQ4LmFzYycjICAgRXJyb3IgaW4gdHJpYWxfZml4W1tpXV0gOiBzdWJzY3JpcHQgb3V0IG9mIGJvdW5kcwogICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgIHh5X2JvdW5kcyA9IGMoMjAsIDEwMDAsIDIwMCwgNjAwKSwgIyBjKHgtbWluLCB4LW1heCwgeW1pbiwgeS1tYXgpCiAgICAgICAgICB0cmlhbF9wbG90cyA9IEZBTFNFLCAjIGkgY2FuJ3QgZ2V0IHRoaXMgdG8gZG8gYW55dGhpbmcgZXhjZXB0IHNwaW4gaXRzIHdoZWVscz8KICAgICAgICAgIHNhdmVfdHJpYWxfcGxvdHMgPSBGQUxTRSwgIyB3b3cgdGhhdCB0YWtlcyB1cCBhIExPVCBvZiBzcGFjZQogICAgICAgICAgZmFfZGlyID0gJ2FzYycsCiAgICAgICAgICBzdGFydF9mbGFnID0gJ1RSSUFMSUQnLAogICAgICAgICAgZGVuX3NkX2N1dG9mZiA9IDMsICMgbm90IHN1cmUgd2hhdCdzIGJlc3QsIGJ1dCB0aGlzIHNlZW1zIHRvIHdvcmsgb2theQogICAgICAgICAgZGVuX3JhdGlvX2N1dG9mZiA9IDUpICMgc21hbGwgbnVtYmVycyBzZWVtIHRvIGRvIGZpbmXigKY/CmBgYAoKCiMgUm9ib2RvYy5weSBhbmQgZnJpZW5kcwoKTm93IGl0J3MgdGltZSB0byBydW4gW1JvYm9kb2MucHldKGh0dHBzOi8vYmxvZ3MudW1hc3MuZWR1L2V5ZWxhYi9zb2Z0d2FyZS8pIGFuZCBhc3NvY2lhdGVkIHNjcmlwdHMuCgpXZSBuZWVkIGEgYHBhcmFtZXRlci50eHRgIGZpbGUgc2V0IHVwLCB3aGljaCByZXF1aXJlcyB0aGUgY29vcmRpbmF0ZXMgZm9yIHRoZSBsaW5lKHMpIG9mIHRleHQgdGhhdCB3aWxsIGJlIGFuYWx5c2VkLgoKIyMgbWFrZV9jbnQucHkKCkhlcmUncyB3aGF0IGl0IGxvb2tzIGxpa2Ugd2hlbiB5b3UgdXNlIGBtYWtlX2NudC5weWAgaW4gVGVybWluYWw6CgpgYGBgCkxhc3QgbG9naW46IFRodSBBcHIgMTIgMDA6MjU6NTIgb24gY29uc29sZQpNYWNCb29rLVByby0yOn4gdXNlcm5hbWUkIGNkIC9Vc2Vycy91c2VybmFtZS9Eb2N1bWVudHMvUmVzZWFyY2gv4oCmL2FzYy9HT09EX0FTQwpNYWNCb29rLVByby0yOkdPT0RfQVNDIHVzZXJuYW1lJCBweXRob24zIG1ha2VfY250LnB5CldoYXQgaXMgdGhlIG5hbWUgb2YgeW91ciBkZWxpbWl0ZWQgc2NyaXB0IGZpbGU/InByb2dlbi1tYWtlX2NudC5zY3JpcHQiCllvdXIgZGVsaW1pdGVkIHNjcmlwdCBmaWxlIGNvdWxkIG5vdCBiZSBmb3VuZC4KTWFjQm9vay1Qcm8tMjpHT09EX0FTQyB1c2VybmFtZSQgcHl0aG9uMyBtYWtlX2NudC5weQpXaGF0IGlzIHRoZSBuYW1lIG9mIHlvdXIgZGVsaW1pdGVkIHNjcmlwdCBmaWxlP3Byb2dlbi1tYWtlX2NudC5zY3JpcHQKV2hhdCBjaGFyYWN0ZXIgZG8geW91IHVzZSBhcyB5b3VyIHJlZ2lvbiBkZWxpbWl0ZXI/LwpXaGF0IGlzIHRoZSBsb3dlc3QgY29uZGl0aW9uIG51bWJlciB0byBiZSBhbmFseXplZD8xCldoYXQgaXMgdGhlIGhpZ2hlc3QgY29uZGl0aW9uIG51bWJlciB0byBiZSBhbmFseXplZD8xNgpgYGBgCgo8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+VGhpcyBkb2Vzbid0IHNlZW0gdG8gYmUgd29ya2luZyBwcm9wZXJseSwgc28gd2UnbGwgaGF2ZSB0byB0cnkgc29tZXRoaW5nIGVsc2UuPC9zcGFuPgoKIyMgcmVnLnR4dAoKVGhlIGBtYWtlX2NudC5weWAgc2NyaXB0IGlzbid0IGFjdHVhbGx5IG91dHB1dHRpbmcgcHJvcGVyIHJlZ2lvbnMgaW5mbywgYW5kIGl0IHNlZW1zIHRvIG5vdCBiZSB3b3JraW5nIHdpdGggbXVsdGktbGluZSBzdGltdWxpLiBJJ2xsIGdvIHRocm91Z2ggbWFraW5nIGEgLnJlZy50eHQgZmlsZSBpbiBjYXNlIHRoYXQgaXMgYSBoZWxwZnVsIGFsdGVybmF0aXZlLgoKRnJvbSB0aGUgKGRlcHJlY2F0ZWQpIFtVTUQgRXllTGluayB3aWtpXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxMjA4MjIxNTQzMzkvaHR0cDovL2xhbmd1YWdlc2NpZW5jZS51bWQuZWR1L3dpa2kvRXllbGluayUyMDEwMDAlMjBFeWV0cmFja2VyKSAoQWNjZXNzZWQgZnJvbSB0aGUgSW50ZXJuZXQgV2F5YmFjayBNYWNoaW5lIG9uIDE5IEFwcmlsIDIwMTg7IGFyY2hpdmVkIG9uIDIyIEF1Z3VzdCAyMDEyKToKClRoaXMgc3RlcCBpbiB0aGUgcHJvY2VzcyByZXF1aXJlcyB0aGF0IHlvdSBoYXZlIHlvdXIgRXllVHJhY2sgYC5zY3JpcHRgIGZpbGUsIGFuZCB0aGUgYGdldFF1ZXN0aW9ucy5weWAsIGBnZXRTZW50ZW5jZXMucHlgIGFuZCBgbWFrZVJlZ2lvbnMucHlgIHNjcmlwdCBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuIFlvdSB3aWxsIHVzZSB0aGVzZSBtYXRlcmlhbHMgdG8gZ2VuZXJhdGUgdGhlIHF1ZXN0aW9uL2Fuc3dlciBrZXkgZm9yIHlvdXIgZGF0YSwgYXMgd2VsbCBhcyB0aGUgcmVnaW9ucyBmaWxlIHVzZWQgaW4gY29tcGlsaW5nIHlvdXIgZGF0YS4KCiMjIyBHZW5lcmF0aW5nIGFuIEl0ZW1zIExpc3QKCkJ5IGdlbmVyYXRpbmcgYW4gaXRlbXMgbGlzdCwgeW91IGNhbiBleHRyYWN0IGFsbCB0aGUgc3RpbXVsaSBhbmQgbWFudWFsbHkgYW5ub3RhdGUgcmVnaW9ucy4KCiogVXNlIGBnZXRTZW50ZW5jZXMucHlgIHRvIGV4dHJhY3QgdGhlIGl0ZW1zIHRoYXQgRXllVHJhY2sgdXNlZCAod2l0aCB0aGUgY29uZGl0aW9uIGFuZCBpdGVtIG51bWJlcnMgaXQgYXNzaWduZWQpLgoqIE1ha2Ugc3VyZSB5b3UgaGF2ZSBhIGNvcHkgb2YgYGdldFNlbnRlbmNlcy5weWAgaW4gdGhlIHNhbWUgZGlyZWN0b3J5IHdpdGggdGhlIGAuc2NyaXB0YCBmaWxlIHlvdSBydW4gaW4gRXllVHJhY2suCiogT3BlbiB0aGUgY29tbWFuZCBwcm9tcHQgYW5kIG5hdmlhZ2UgdG8gdGhhdCBkaXJlY3RvcnkuIFR5cGU6CgpgYGBgCnB5dGhvbiBnZXRTZW50ZW5jZXMucHkgc3R1ZHluYW1lLnNjcmlwdApgYGBgCgpFbnRlciB0aGUgc3RhcnRpbmcgY29uZGl0aW9uIG51bWJlciAqKmZvciB0aGUgZXhwZXJpbWVudCB5b3UncmUgd29ya2luZyBvbiB3aXRoaW4gdGhlIHN0dWR5KiosIGFuZCB0aGUgdG90YWwgbnVtYmVyIG9mIGNvbmRpdGlvbnMgaW4gKnRoYXQqIGV4cGVyaW1lbnQuIFlvdeKAmWxsIGdldCB0d28gYC50eHRgIGZpbGVzIGFzIHRoZSBvdXRwdXQgKGBhbGxzZW50ZW5jZXMudHh0YCB3aXRoIGFsbCBpdGVtcyBmcm9tIGFsbCBleHBlcmltZW50cywgYGV4cHNlbnRlbmNlcy50eHRgIHdpbGwgdGhlIGl0ZW1zIG9mIHRoZSBleHBlcmltZW50IHlvdSBpbnRlbmRlZCB0byBleHRyYWN0KS4KCioqTm90ZToqKiBJZiB5b3UgaGF2ZSBhbHJlYWR5IGdlbmVyYXRlZCBhIGRlbGltaXRlZCAuc2NyaXB0IGZpbGUgZm9yIGBtYWtlX2NudC5weWAsIHlvdSBjYW4gdXNlIHRoYXQgZmlsZSBpbnN0ZWFkIG9mIHlvdXIgb3JpZ2luYWwgLnNjcmlwdCBmaWxlIGFuZCBpdCB3aWxsIGluY2x1ZGUgeW91ciBkZWxpbWl0ZWQgY2hhcmFjdGVycy4gVGhpcyBtZWFucyB5b3Ugd2lsbCBub3QgaGF2ZSB0byBoYW5kLWRlbGltaXQgYSBzZWNvbmQgdGltZSBhbmQgdGh1cyB5b3UgY2FuIHNraXAgdGhlIGZvbGxvd2luZyBzZWN0aW9uLgoKIyMjIE1ha2luZyBhIC5ERUwgZmlsZQoKQSBgLmRlbGAgZmlsZSBpcyBhIGZpbGUgZGVsaW1pdGluZyB0aGUgcmVnaW9ucyBvZiBpbnRlcmVzdCBmb3IgZWFjaCBzZW50ZW5jZS4gWW91IG5lZWQgdG8gbWFrZSB0aGlzIGJ5IGhhbmQsIGJlY2F1c2UgeW91J3JlIHRoZSBvbmUgd2hvIGhhcyB0byBkZWNpZGUgd2hpY2ggcGFydHMgb2YgdGhlIHNlbnRlbmNlIGFyZSBpbnRlcmVzdGluZyBmb3IgeW91ciBleHBlcmltZW50LiBPbmNlIHlvdSBoYXZlIHlvdXIgc2VudGVuY2UgbGlzdCBnZW5lcmF0ZWQgZnJvbSBgZ2V0U2VudGVuY2VzLnB5YCwgYWRkIGZvcndhcmQgc2xhc2hlcyB0byBkZWxpbWl0IHRoZSByZWdpb25zLiBZb3UgY2FuIGltcG9ydCB0aGUgdGV4dCBmaWxlIGludG8gRXhjZWwgdG8gcGFydGlhbGx5IGF1dG9tYXRlIHRoaXMgcHJvY2Vzcy4KCiogVGhlcmUgc2hvdWxkIGJlIGEgc3BhY2UgYXQgdGhlIGJlZ2lubmluZyBvZiBlYWNoIHJlZ2lvbiwgaWYgcG9zc2libGUuIChPYnZpb3VzbHkgdGhpcyB3b24ndCBiZSBwb3NzaWJsZSBmb3IgdGhlIGZpcnN0IHJlZ2lvbiBvZiB0aGUgaXRlbS4pCiogSW5jbHVkZSBhIHNsYXNoIGF0IHRoZSBlbmQgb2YgdGhlIGxhc3QgcmVnaW9uLiAoYnV0IG1ha2Ugc3VyZSBpdCBkb2VzIG5vdCBpbmNsdWRlIGFueSB1bm5lY2Vzc2FyeSBsaW5lIGNoYW5nZSkKKiBTYXZlIHRoZSB0ZXh0IGZpbGUgYXMgYHN0dWR5bmFtZS5kZWxgCgpUaGUgcmVzdWx0aW5nIGZpbGUgc2hvdWxkIGxvb2sgbGlrZSB0aGlzOgoKYGBgYAoxIDIgL1RoZSBob3VzZW1haWRzLyBlbmNvdW50ZXJlZCB0aGUvIHNlcmYvIGluIHRoZS8gbG9jYWwgcGFyay4gXG4vVGhleSBsYXVnaGVkIC9hdCBoaXMvIGpva2VzLyBvbiB0aGUvIHdheSBob21lLi8KMiAyIC9UaGUgaG91c2VtYWlkcy8gZW5jb3VudGVyZWQgdGhlLyBsb3JkLyBpbiB0aGUvIGxvY2FsIHBhcmsuIFxuL1RoZXkgbGF1Z2hlZCAvYXQgaGlzLyBqb2tlcy8gb24gdGhlLyB3YXkgaG9tZS4vCjMgMiAvVGhlIGhvdXNlbWFpZHMvIGVuY291bnRlcmVkLyBCZXJ0LyBpbiB0aGUvIGxvY2FsIHBhcmsuIFxuL1RoZXkgbGF1Z2hlZCAvYXQgaGlzLyBqb2tlcy8gb24gdGhlLyB3YXkgaG9tZS4vCjQgMiAvVGhlIGhvdXNlbWFpZHMvIGVuY291bnRlcmVkLyBFcmljLyBpbiB0aGUvIGxvY2FsIHBhcmsuIFxuL1RoZXkgbGF1Z2hlZCAvYXQgaGlzLyBqb2tlcy8gb24gdGhlLyB3YXkgaG9tZS4vCjEgMyAvVGhlIGdpcmxzLyBhc2tlZCB0aGUvIHNlcmYvIGZvciB0aGUvIGxhdGVzdCBnb3NzaXAuIFxuL1RoZXkgZ2FzcGVkIC9hdCBoaXMvIHNvcmRpZC8gc3Rvcmllcy8gYWJvdXQgdGhlIGFyaXN0b2NyYWN5Li8KMiAzIC9UaGUgZ2lybHMvIGFza2VkIHRoZS8gbG9yZC8gZm9yIHRoZS8gbGF0ZXN0IGdvc3NpcC4gXG4vVGhleSBnYXNwZWQgL2F0IGhpcy8gc29yZGlkLyBzdG9yaWVzLyBhYm91dCB0aGUgYXJpc3RvY3JhY3kuLwouLi4KYGBgYAoKSW1wb3J0YW50bHksIHlvdSBuZWVkIHRvIGJlIGNhcmVmdWwgYWJvdXQgdGhlIGNhcnJpYWdlIHJldHVybiBlbmNvZGluZywgYXQgbGVhc3QgaWYgeW91IHVzZSBhIE1hYy4gVGhlIHB5dGhvbiBzY3JpcHQgbWlnaHQgbm90IHJlYWQgdGhlIGAuZGVsYCBmaWxlIGNvcnJlY3RseSBpZiBpdCBoYXMgQ2xhc3NpYyBNYWMgQ1IgZW5jb2RpbmcsIGFuZCBpdCB3aWxsIGdpdmUgeW91IGEgYC5yZWdgIGZpbGUgdGhhdCBpcyBpbmNvcnJlY3RseSBhbGwgb24gb25lIGxpbmUuIEl0IGlzIGVhc3kgdG8gY2hlY2sgdGhlIGVuY29kaW5nIG9mIHRoZSBgLmRlbGAgZmlsZSBpZiB5b3UgdXNlIHRoZSBUZXh0V3JhbmdsZXIgdGV4dCBlZGl0b3IuIEp1c3Qgb3BlbiB0aGUgZmlsZSB0aGVyZSBhbmQgbG9vayBhdCB0aGUgdmVyeSBib3R0b20gb2YgdGhlIHdpbmRvdyBhdCB0aGUgZmlmdGggdGFiIGZyb20gdGhlIGxlZnQuIEl0IHNob3VsZCByZWFkICdVbml4IExGJy4gSWYgaXQgcmVhZHMgJ0NsYXNzaWMgTWFjIENSJyB5b3UgbmVlZCB0byB0b2dnbGUgdG8gdGhlICdVbml4IExGJyBvcHRpb24gYW5kIHJlLXNhdmUgdGhlIGZpbGUuCgojIyMgTWFraW5nIGEuIFJFRyBmaWxlCgpBIGAucmVnYCBmaWxlIChmb3JtYWxseSBrbm93biBhcyBhIGAuQ05UYCBmaWxlKSBpcyBhIGZpbGUgdGhhdCBjb250YWlucyB0aGUgeC15IGNvb3JkaW5hdGVzIG9mIHRoZSByZWdpb25zIG9mIGludGVyZXN0IGZvciBlYWNoIGl0ZW0gaW4gZWFjaCBjb25kaXRpb24uIFlvdSBjYW4gY3JlYXRlIHRoaXMgd2l0aCB0aGUgc2NyaXB0IGBtYWtlUmVnaW9ucy5weWAuCgoqIE1ha2Ugc3VyZSB5b3VyIGAuZGVsYCBmaWxlIGlzIGluIHRoZSBzYW1lIGFzIHRoZSBjb3B5IG9mIGBtYWtlX3JlZ19maWxlLnB5YAoqIE9wZW4gdGhlIGNvbW1hbmQgcHJvbXB0LCBhbmQgbmF2aWdhdGUgdG8gdGhhdCBkaXJlY3RvcnkuCiogVG8gcnVuIHRoZSBzY3JpcHQsIHR5cGU6CgoKYGBgYApweXRob24gbWFrZVJlZ2lvbnMucHkgc3R1ZHluYW1lLmRlbApgYGBgCgpUaGUgb3V0cHV0IHdpbGwgYmUgYSBmaWxlIGNhbGxlZCBgb3V0cHV0LnJlZy50eHRgIGluIHRoZSBzYW1lIGRpcmVjdG9yeS4gQ3VycmVudGx5LCB0aGUgZW5jb2Rpbmcgb2YgdGhpcyBmaWxlIGNhbm5vdCBiZSBgLnR4dGAuIE9uIGEgTWFjLCB1c2luZyBUZXh0V3JhbmdsZXIgb3IgQkJFZGl0LCB5b3UgY2FuIGNoYW5nZSB0aGUgZW5jb2RpbmcgYnkgb3BlbmluZyB0aGUgZmlsZSBhbmQgbmF2aWdhdGluZyB0byB0aGUgYm90dG9tIG9mIHRoZSB3aW5kb3cuCgpJZiB5b3Ugc2VlIHNvbWV0aGluZyBsaWtlIHRoaXM6ICFbXSh0eHQtZW5jb2RpbmcucG5nKQoKWW91IG11c3QgY2hhbmdlIGl0IHRvIHNvbWV0aGluZyBsaWtlIHRoaXM6ICFbXShuby1lbmNvZGluZy5wbmcpCgpSZW1lbWJlciB0byBzYXZlIHRoZSBuZXcgZmlsZSB3aXRoIGAucmVnYCBhdCB0aGUgZW5kIG9mIHRoZSBuYW1lLgoKIyMgcXVlc3Rpb25fYWNjLnB5CgpOZXh0IGl0J3MgdGltZSB0byB1c2UgYHF1ZXN0aW9uX2FjYy5weWAuIEl0IHNlZW1zIGxpa2UgdGhlIHNjcmlwdCBmaWxlIHlvdSBuZWVkIGZvciBgcGFyYW1ldGVycy50eHRgICptaWdodCogYmUgdGhlIGZ1bGwgc2NyaXB0LCBub3QgdGhlIG9uZSBhbHRlcmVkIGZvciBgbWFrZV9jbnQucHlgLiBIZXJlJ3Mgd2hhdCBpdCBsb29rcyBsaWtlIGluIHRoZSBUZXJtaW5hbC4gCgpgYGBgCk1hY0Jvb2stUHJvLTI6R09PRF9BU0MgdXNlcm5hbWUkIHB5dGhvbjMgcXVlc3Rpb25fYWNjLnB5CldoYXQgaXMgdGhlIG5hbWUgb2YgeW91ciBwYXJhbWV0ZXIgZmlsZT9wYXJhbWV0ZXJzLnR4dApQUjE3X2ZhLmFzYwpQUjE3X2ZhLmFzYyA1MCAxOCAwLjM2ClBSMDlfZmEuYXNjClBSMDlfZmEuYXNjIDUwIDMzIDAuNjYKUFIwNV9mYS5hc2MKUFIwNV9mYS5hc2MgNTAgMTkgMC4zOApQUjMzX2ZhLmFzYwpQUjMzX2ZhLmFzYyA1MCAyMSAwLjQyCuKApiBldGMKYGBgYAoKIyMgUm9ib2RvYy5weQoKRmluYWxseSwgaGVyZSdzIHdoYXQgYFJvYm9kb2MucHlgIGRvZXMuCgpgYGBgCk1hY0Jvb2stUHJvLTI6R09PRF9BU0MgdXNlcm5hbWUkIHB5dGhvbjMgUm9ib2RvYy5weSBwYXJhbWV0ZXJzLnR4dApQUjE3X2ZhLmFzYwpQUjA5X2ZhLmFzYwpQUjA1X2ZhLmFzYwpQUjMzX2ZhLmFzYwpQUjUwX2ZhLmFzYwpgYGBgCgojIHNpZGUtZXllIChiZXRhKQoKW0JyaWFuIERpbGxvbl0oaHR0cHM6Ly9naXRodWIuY29tL2JkaWxsb24vKSBoYXMgZ2l2ZW4gbWUgYWNjZXNzIHRvIFtzaWRlLWV5ZV0oaHR0cHM6Ly9naXRodWIuY29tL2JkaWxsb24vc2lkZS1leWUpIGFzIGEgYmV0YSB0ZXN0ZXIuCgojIyBTZXQgdXAKCiMjIyMgTG9jYWwgaW5zdGFsbGF0aW9uOgoKYGBge2Jhc2gsIGV2YWw9RkFMU0V9CnBpcCBpbnN0YWxsIC9BcHBsaWNhdGlvbnMvR2l0Y2V0ZXJhL3NpZGUtZXllCmBgYAoKIyMjIFByZS1hbHBoYSB0ZXN0aW5nCgpBZGFwdGVkIGZyb20gZG9jdW1lbnRhdGlvbjoKClRoZSBleGFtcGxlcyBkaXJlY3RvcnkgY29udGFpbnMgYHNhbXBsZS5weWAsIHdoaWNoIGlzIGFuIGV4YW1wbGUgb2YgdGhlIHNpbXBsZXN0IHdheSB0byB1c2UgdGhlIHBhY2thZ2UuIFRvIHJ1biBvbiBhIGZvbGRlciBvZiBEQTEgZmlsZXM6CgoxLiBDb3B5IGBzYW1wbGUucHlgIGFuZCBgc2FtcGxlX2NvbmZpZy5qc29uYCBpbnRvIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyBhIGZvbGRlciBvZiBEQTEgZmlsZXMgYW5kIGEgYC5jbnRgIG9yIGAucmVnYCByZWdpb24gZmlsZS4gCjIuIE9wZW4gYm90aCBmaWxlcyBpbiBhIHRleHQgZWRpdG9yLgozLiBSZXBsYWNlIHRoZSBmaWxlIHBhdGhzIGluIGBzYW1wbGUucHlgIHdpdGggcGF0aHMgdG8geW91ciBEQTEgYW5kIHJlZ2lvbiBmaWxlcy4KNC4gUmVwbGFjZSBgZXhhbXBsZXMvc2FtcGxlX291dHB1dC5jc3ZgIHdpdGggd2hhdGV2ZXIgeW91IHdhbnQgdGhlIG91dHB1dCBmaWxlIHRvIGJlIG5hbWVkLgo1LiBFZGl0IGBzYW1wbGVfY29uZmlnLmpzb25gIHRvIG1hdGNoIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBmb3IgeW91ciBleHBlcmltZW50LCBhY2NvcmRpbmcgdG8gdGhlIGluc3RydWN0aW9ucyBpbiBUaGUgW0NvbmZpZ3VyYXRpb24gRmlsZV0oaHR0cHM6Ly9naXRodWIuY29tL2JkaWxsb24vc2lkZS1leWUjdGhlLWNvbmZpZ3VyYXRpb24tZmlsZSkuCgojIyMjIERBMSBmaWVsZHMKClNhbXBsZSAuREExIGZpbGUgZnJvbSBJT04gc2V0LXVwICh1c2luZyBFeWVUcmFjayk6CgpgYGAKMSAxIDEgMzU5NzcgNCAxNjYgLTEgLTEgMCA3IC0xIC0xIDU3IDIxMyA0MSAwIDI2NSA2NzMgLTEgLTEgNzIzIDg4NSAtMSAtMSA5MDkgMTA4OSAtMSAtMSAxMTE5IDEyNzPigKYKMiAxIDEgNTc1NCA1IDIzIDIgMCAwIDMzNiAxMSAwIDM2MCA1NTQgMTkgMCA1NzggNzYwIDIzIDAgNzc4IDEwOTIgMjUgMCAxMTA0IDExODIgMzEgMCAxMjA2IDEzODIgMzfigKYKMyAxIDEgMjExOCA1IDkgLTEgLTEgMzcgMTA3IC0xIC0xIDExNyAxOTkgLTEgLTEgMjQ5IDM5NSAtMSAtMSA0MDkgNTU5IC0xIC0xIDU3OSA3MzUgLTEgLTEgNzU5IDEwNDXigKYKNCAxIDEgMzkwNyA0IDE0IDAgMCAwIDI5MCA4IDAgMzE0IDQ1NCAxNiAwIDQ3OCA2MjggMjUgMCA2NTAgOTE4IDMzIDAgOTQ0IDExMDIgMzkgMCAxMTIyIDEyODggNTAgMOKApgo1IDEgMSAxODEzIDQgNyAtMSAwIDAgMTc4IC0xIC0xIDIyNCAzNjggLTEgLTEgMzkwIDYyMCAtMSAtMSA2NDYgODE2IC0xIC0xIDg0MCA5ODAgLTEgLTEgMTAzOCAxMzQ04oCmCgpgYGAKClRvIG1lLCB0aGlzIGxvb2tzIGxpa2UgdGhlIGZvbGxvd2luZyBjb2RlIGZvciBgc2FtcGxlX2NvbmZpZy5qc29uYCBzaG91bGQgYmUgYXBwcm9wcmlhdGUgKHdoZXJlIC0xIGluZGljYXRlcyB0aGUgbGFzdCBpbmRleCBvZiBhIGxpbmUpOgoKYGBgCiJkYTFfZmllbGRzIiA6IHsKICAgICJpbmRleCI6IDAsCiAgICAiY29uZGl0aW9uIjogMSwKICAgICJudW1iZXIiOiAyLAogICAgInRpbWUiOiAzLAogICAgImZpeGF0aW9uX3N0YXJ0IjogNgpgYGAKCkkgc3VzcGVjdCBpbmRleFs0XSBpcyBidXR0b24gcHJlc3MuIFNpbmNlIEkgc3RydWdnbGVkIHRvIGdldCBhIGNvbnNpc3RlbnQgbWFwcGluZyBiZXR3ZWVuIHRoZSBHcmF2aXMgRGVzdHJveWVyJ3MgNSBidXR0b25zIGFuZCB0aGUgRXllVHJhY2sgY29kZSwgSSBhbSBvcGVyYXRpbmcgdW5kZXIgdGhlIGFzc3VtcHRpb24gdGhhdCBgNWAgaXMgY29uc2lzdGVudGx5IGBwdXJwbGVgIChpLmUuLCBsZWZ0LCBhLmsuYS4gIlllcyIpLCBhbmQgYWxsIG90aGVyIG51bWJlcnMgKGAyYCxgM2AsYDRgIGFyZSBtb3N0IGNvbW1vbikgYXJlIGZyb20gdGhlIHJpZ2h0aGFuZCBidXR0b25zIChhLmsuYS4gIk5vIikuIFNpbmNlIGFueSBidXR0b24gY291bGQgYmUgdXNlZCB0byBwcm9jZWVkIHRvIHRoZSBuZXh0IHNlbnRlbmNlIGlmIG5vIHF1ZXN0aW9uIHdlcmUgcHJlc2VudGVkLCBJJ20gbm90IHN1cmUgaG93IHRvIGludGVycHJldCBhbnkgb2YgdGhlc2UgYnV0dG9uIHByZXNzZXMgYXQgdGhlIG1vbWVudC4gSSdtIGFsc28gbm90IHN1cmUgd2hldGhlciBpdCBtYXR0ZXJzIHJpZ2h0IG5vdy4KCioqSW4gZmFjdCoqIGBmaXhhdGlvbl9zdGFydGAgbXVzdCBiZSBpbmRleFs2XSwgc2luY2UgaW5kZXhbNV0gaXMgdGhlIHRvdGFsIG51bWJlciBvZiBmaXhhdGlvbnMgaW4gdGhlIHRyaWFsISBDb29sIQoKIyMjIyBSZWdpb24gZmllbGRzCgpIZXJlIGlzIHRoZSBmaXJzdCBiaXQgb2YgYSBgLnJlZ2AgZmlsZSwgd2hpY2ggY29ycmVzcG9uZHMgd2l0aCB0aGUgZmlyc3QgdHdvIGl0ZW1zLCBlYWNoIHdpdGggZm91ciBjb25kaXRpb25zLgoKYGBgCjEgMiA3IDAgMCA3IDAgNyAxIDE1IDEgMjQgMSAzMSAxIDQ5IDEKMiAyIDcgMCAwIDYgMCA3IDEgMTUgMSAyNCAxIDMxIDEgNDkgMQozIDIgNyAwIDAgOCAwIDcgMSAxNSAxIDI0IDEgMzEgMSA0OSAxCjQgMiA3IDAgMCA3IDAgNyAxIDE1IDEgMjQgMSAzMSAxIDQ5IDEKMSAzIDcgMCAwIDggMCA4IDEgMTkgMSAyOCAxIDM0IDEgNTQgMQoyIDMgNyAwIDAgNiAwIDggMSAxOSAxIDI4IDEgMzQgMSA1NCAxCjMgMyA3IDAgMCA5IDAgOCAxIDE5IDEgMjggMSAzNCAxIDU0IDEKNCAzIDcgMCAwIDggMCA4IDEgMTkgMSAyOCAxIDM0IDEgNTQgMQrigKYKYGBgCgoqIGluZGV4WzBdIHNlZW1zIHRvIGJlIHRoZSBjb25kaXRpb24gbnVtYmVyCiogaW5kZXhbMV0gaXMgdGhlIGl0ZW0gbnVtYmVyCiogaW5kZXhbMl0gaXMgdGhlIG51bWJlciBvZiByZWdpb25zIGluIHRoZSBpdGVtCiogPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+aW5kZXhbM10gaXMgPz8/PC9zcGFuPgoqIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPmluZGV4WzRdIGlzID8/Pzwvc3Bhbj4KKiA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5pbmRleFs1XSBpcyA/Pz88L3NwYW4+CiogaW5kZXhbNl0gbXVzdCBiZSB3aGVyZSB0aGUgYm91bmRhcmllcyBzdGFydAoKYGBgCiJyZWdpb25fZmllbGRzIjogewogICJudW1iZXIiOiAwLAogICJjb25kaXRpb24iOiAxLAogICJib3VuZGFyaWVzX3N0YXJ0IjogNiwKICAiaW5jbHVkZXNfeSI6IHRydWUKYGBgCgpOb3RhYmx5LCB0aGVyZSBhcmUgeC0gYW5kIHktY29vcmRpbmF0ZXMgaW4gdGhpcyBkYXRhc2V0LCB3aGljaCBhcmUgc29tZSBvZiB0aGUgYDBgcyBhbmQgYDFgcyBpbnRlcnNwZXJzZWQgaW4gdGhlIG90aGVyIG51bWJlcnMuIE5vdCBzdXJlIGhvdyB0byBpZGVudGlmeSB0aGVtLCBhbmQgdGhpcyBjYXVzZWQgaXNzdWVzIGluIHByZXZpb3VzIGF0dGVtcHRzLgoKIyMjIyBBbmQgdGhlIHJlc3TigKYKCkkgZG9uJ3Qga25vdyB3aGF0IG51bWJlcnMgYXJlIGFwcHJvcHJpYXRlIGZvciBjdXRvZmZzLCByZWdpb24gbWVhc3VyZXMgb3IgdHJpYWwgbWVhc3VyZXMuCgpSZWdpb24gb3V0cHV0IGFuZCB0cmlhbCBvdXRwdXQgc2VlbSBmaW5lIGFzIGlzLgoKSSd2ZSBjaGFuZ2VkIGEgZmV3IHRoaW5nczoKCiogRm9yIGNhbGN1bGF0aW5nIHJlZ2lvbiBsZW5ndGg6IGByZWdpb25fc3RhcnRgIGFuZCBgcmVnaW9uX2VuZGAgPSBgVFJVRWAgIAoqIEZvciBpbmZvcm1hdGlvbjogYHJlZ2lvbl90ZXh0YCA9IGBUUlVFYAoKIyMgUnVubmluZyBzaWRlLWV5ZQoKSW4gVGVybWluYWwsIHJ1biB0aGUgZm9sbG93aW5nLgoKYGBge2Jhc2h9CmNkIGFzYy9HT09EX0FTQy9zaWRlLWV5ZQpweXRob24zIHNhbXBsZS5weQpgYGAKCmBgYApNYWNCb29rLVByby0yOnNpZGUtZXllIHVzZXJuYW1lJCBweXRob24zIHNhbXBsZS1MTUEucHkKSXRlbSBudW1iZXIgMSAsIGNvbmRpdGlvbiAxIGRvZXMgbm90IGV4aXN0LiBJdCB3YXMgbm90IGFkZGVkIHRvIHRoZSBFeHBlcmltZW50IG9iamVjdC4KSXRlbSBudW1iZXIgMSAsIGNvbmRpdGlvbiAxIGRvZXMgbm90IGV4aXN0LiBJdCB3YXMgbm90IGFkZGVkIHRvIHRoZSBFeHBlcmltZW50IG9iamVjdC4KYGBgCgpUaGlzIG91dHB1dCBtZWFucyBpdGVtIDEgKHdoaWNoIGhhcHBlbnMgdG8gYmUgdGhlIGluc3RydWN0aW9ucyBhbmQgcHJhY3RpY2UgcXVlc3Rpb25zLCB0aHVzIG5vdCBhIHJlYWwgaXRlbSkgaXMgZXhjbHVkZWQgZnJvbSB0aGlzIGRhdGFzZXQuIFRoZSBvdXRwdXQgaXMgYSBgLmNzdmAgZmlsZS4gQnJpYW4gc2F5czogW1JlZ2lvbnMgbGlzdGVkIGFzIGBOQWAgYXJlXSB1c2VkIGZvciB0aGUgcmVnaW9uIGZpZWxkIGZvciB0cmlhbCBsZXZlbCBjYWxjdWxhdGlvbnMgKHRvdGFsIHZpZXdpbmcgdGltZSwgZm9yIGV4YW1wbGUpLgoKIyBEYXRhIHNldAoKQWZ0ZXIgYWxsIHRoaXMsIHdoYXQgZG9lcyB0aGUgZGF0YSBzZXQgYWN0dWFsbHkgbG9vayBsaWtlPyBXaGF0IGRvZXMgaXQgY29udGFpbj8gVGhlIGZvbGxvd2luZyBkYXRhc2V0IGhhcyBpc3N1ZXMsIGJ1dCB0aGV5IGNhbiBlYXNpbHkgYmUgcmVzb2x2ZWQgdGhyb3VnaCBmaW5kLWFuZC1yZXBsYWNlIGZ1bmN0aW9ucyBvdXRzaWRlIG9mIFIuIEZvciBpbnN0YW5jZSwgYHJlZ2lvbl9zdGFydGAgYW5kIGByZWdpb25fZW5kYCBlbmNvZGUgdGhlIGNvb3JkaW5hdGVzIGluY29ycmVjdGx5LCB3aGljaCBwdXNoZXMgYWxsIGluZm9ybWF0aW9uIHR3byBjZWxscyB0byB0aGUgcmlnaHQuIFRoaXMgaXMgd2h5IGBza2lwYCBpcyB1bmRlciBgZXhwZXJpbWVudF9uYW1lYCBpbiB0aGUgZmlyc3QgY29sdW1uLgoKYGBgYHtyfQojbGlicmFyeShkcGx5cikKZGYuZXlldHJhY2sgPC0gcmVhZC5jc3YoZmlsZS5jaG9vc2UoKSwgaGVhZGVyPVRSVUUpCmRmLmV5ZXRyYWNrICU+JQogIGFzX3RpYmJsZSgpICU+JQogIGdyb3VwX2J5KGV4cGVyaW1lbnRfbmFtZSkKYGBgYAoKT25jZSBpdCdzIGJlZW4gcHJvcGVybHkgZWRpdGVkIChieSBoYW5kIG9yIHRleHQgcHJvY2Vzc2luZyksIHRoaXMgaXMgd2hhdCB3ZSBtaWdodCBzZWUuIEluIHRoZSBiZWxvdyBvdXRwdXQsIHRoZSByZWdpb24gY29vcmRpbmF0ZXMgaGF2ZSBiZWVuIGZpeGVkIGFuZCBJJ3ZlIGNoYW5nZWQgc29tZSBvZiB0aGUgY29sdW1uIG5hbWVzIHRvIHN1aXQgbWUuIEkndmUgYWxzbyBleGNsdWRlZCBzb21lIGNvbHVtbnMgdGhhdCBJIGRvbid0IGZpbmQgdXNlZnVsIChlLmcuLCBgZmlsZW5hbWVgKS4gSG93ZXZlciwgbm90aWNlIGhvdyBgJHZhbHVlYCBpcyBhIGZhY3RvciBhbmQgY29udGFpbnMgYm90aCBweXRob24gYm9vbGVhbnMgKGBUcnVlYCkgYW5kIG51bWVyaWNzLiBUaGlzIGNhbiBiZSByZWNvZGVkIG9uY2UgbWVhc3VyZSB0eXBlIGlzIHN1YnNldHRlZCBvdXQuCgpgYGB7cn0KZGYuZXlldHJhY2sgPC0gcmVhZC5jc3YoZmlsZS5jaG9vc2UoKSwgaGVhZGVyPVRSVUUpCmRmLmV5ZXRyYWNrICU+JQogIGFzX3RpYmJsZSgpICU+JQogIGdyb3VwX2J5KHN1YmopCmBgYAoKCgoqKioKCiMgRmFpbGVkIGF0dGVtcHRzCgojIyBSZWdpb25zIGZyb20gYG1ha2VfY250LnB5YAoKSSBhbSBoYXZpbmcgYSBkaWZmaWN1bHQgdGltZSBpbnRlcnByZXRpbmcgdGhlIC5jbnQgZmlsZS4gSGVyZSBpcyB0aGUgZmlyc3QgYml0LCB3aGljaCBzZWVtcyB0byBtYXliZSBjb3JyZXNwb25kIHdpdGggdGhlIGZpcnN0IGZpdmUgaXRlbXMgKHRvIHBhcmFsbGVsIHRoZSBwcmV2aW91cyBzYW1wbGUpLiBJZiBzbywgaW5kZXhbMF0gc2VlbXMgdG8gYmUgdGhlIGl0ZW0gaWRlbnRpZmllciwgaW5kZXhbMV0gd291bGQgYmUgdGhlIGNvbmRpdGlvbiBudW1iZXIsIGluZGV4WzJdIHNlZW1zIHRvIGJlIGEgdmFsdWUgZWl0aGVyIDEgb3IgMywgYW5kIGluZGV4WzNdIG11c3QgYmUgd2hlcmUgdGhlIGJvdW5kYXJpZXMgc3RhcnQuCgpgYGAKMiAxIDMgMCAwIDcKMiAxIDEgMAoyIDIgMyAwIDAgNgoyIDIgMSAwCjIgMyAzIDAgMCA4CjIgMyAxIDAKMiA0IDMgMCAwIDcKMiA0IDEgMAozIDEgMyAwIDAgOAozIDIgMyAwIDAgNgozIDMgMyAwIDAgOQozIDQgMyAwIDAgOAo0IDEgMyAwIDAgOAo0IDEgMSAwCjQgMiAzIDAgMCA2CjQgMiAxIDAKNCAzIDMgMCAwIDgKNCAzIDEgMAo0IDQgMyAwIDAgOQo0IDQgMSAwCjUgMSAzIDAgMCA5CjUgMiAzIDAgMCA2CjUgMyAzIDAgMCAxMgo1IDQgMyAwIDAgOApgYGAKSG93ZXZlciwgdGhlIGJvdW5kYXJpZXMgZG9uJ3QgbWFrZSBhbnkgc2Vuc2UgdG8gbWUuICAKYHwvSm9zZXBoIC9taWdodCBleHBlY3QgdG8gbGVhcm4gXG5ob3cgdG8gL2V4cHJlc3MgL3RoZW1zZWxmIC9iZXR0ZXIgL2luIGEgcG9ldHJ5IGNsYXNzLi9gICAKV291bGQgdGhlIGJvdW5kYXJpZXMgZm9yIHRoaXMgaXRlbSAoRTFJMkQwKSBub3QgYmUgMCA3IChcXG4pIDcgMTUgMjQgMzEgNDk/CgpgYGAKInJlZ2lvbl9maWVsZHMiOiB7CiAgIm51bWJlciI6IDAsCiAgImNvbmRpdGlvbiI6IDEsCiAgImJvdW5kYXJpZXNfc3RhcnQiOiAzLAogICJpbmNsdWRlc195IjogZmFsc2UKYGBgCgojIyBleWVEYXRhVG9SLnB5CgpUaGlzIGlzIGFkYXB0ZWQgZnJvbSB0aGUgZGVwcmVjYXRlZCBbVU1EIEV5ZUxpbmsgd2lraV0oaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTIwODIyMTU0MzM5L2h0dHA6Ly9sYW5ndWFnZXNjaWVuY2UudW1kLmVkdS93aWtpL0V5ZWxpbmslMjAxMDAwJTIwRXlldHJhY2tlcikgKEFjY2Vzc2VkIGZyb20gdGhlIEludGVybmV0IFdheWJhY2sgTWFjaGluZSBvbiAxOSBBcHJpbCAyMDE4OyBhcmNoaXZlZCBvbiAyMiBBdWd1c3QgMjAxMikuCgpSdW4gYGV5ZURhdGFUb1IucHlgIHdoaWNoIGlzIHN1cHBvc2VkIHRvIHByb21wdCB5b3UgZm9yIHRoZSBmb2xsb3dpbmcgaW5wdXQ6CgoxLiBuYW1lIG9mIHRoZSByZWdpb25zIGZpbGUgKGAucmVnYCBvciBgLmNudGApCjIuIH5uYW1lIG9mIHRoZSBxdWVzdGlvbiBrZXl+IChub3Qgc3VyZSB3aGF0IHRoaXMgaXMsIHBvc3NpYmx5IHJlcGxhY2VkIHdpdGggYHF1ZXN0aW9uX2FjYy5weWApCjMuIG5hbWUgb2YgdGhlIGZvbGRlciBjb250YWluaW5nIHNlbnRlbmNlIGRhdGEKNC4gbmFtZSBvZiB0aGUgZm9sZGVyIGNvbnRhaW5pbmcgcXVlc3Rpb24gZGF0YQo1LiBuYW1lIG9mIHRoZSBvdXRwdXQgZmlsZSB5b3Ugd2FudCB0byBjcmVhdGUKCkkndmUgaGFyZC1jb2RlZCB0aGUgZmlsZSBuYW1lcyBmb3Igc29tZSByZWFzb24gKG9yIHRoZXkgY2FtZSB0aGF0IHdheT8pLCBidXQgaXQncyBzdGlsbCBub3Qgd29ya2luZ+KApgoKYGBgCk1hY0Jvb2stUHJvLTI6R09PRF9BU0MgdXNlcm5hbWUkIHB5dGhvbiBleWVEYXRhVG9SLnB5CmZpeGF0aW9uIHRpbWUgc2V0dGluZ3M6CmxvdyBjdXRvZmY6IDQwbXMKaGlnaCBjdXRvZmY6IDIwMDBtcwpjb21wdXRpbmcgYWxsIG1lYXN1cmVzCigncHJvY2Vzc2luZycsICc5X2YnKQpubyBxdWVzdGlvbiBkYXRhIGZvciA5X2YKVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOgogIEZpbGUgImV5ZURhdGFUb1IucHkiLCBsaW5lIDExOSwgaW4gPG1vZHVsZT4KICAgIHJlZ1hlbmQgPSBzdHIocmVnWzFdWzBdKQpUeXBlRXJyb3I6ICdpbnQnIG9iamVjdCBoYXMgbm8gYXR0cmlidXRlICdfX2dldGl0ZW1fXycKYGBgCgojIyBSdW5uaW5nIHNpZGUtZXllCgoKYGBge2Jhc2h9CmNkIGFzYy9HT09EX0FTQy9zaWRlLWV5ZQpweXRob24zIHNhbXBsZS5weQpgYGAKCgpgYGAKTWFjQm9vay1Qcm8tMjpzaWRlLWV5ZSB1c2VybmFtZSQgcHl0aG9uMyBzYW1wbGUtTE1BLnB5ClRyYWNlYmFjayAobW9zdCByZWNlbnQgY2FsbCBsYXN0KToKICBGaWxlICJzYW1wbGUtTE1BLnB5IiwgbGluZSAxNywgaW4gPG1vZHVsZT4KICAgIGV4cGVyaW1lbnRzID0gc2lkZWV5ZS5wYXJzZXIuZXhwZXJpbWVudC5wYXJzZV9kaXIoJ2RhMV9maWxlcycsICdwcm9nZW4ucmVnLnR4dCcsICdzYW1wbGVfY29uZmlnLmpzb24nKQogIEZpbGUgIi9MaWJyYXJ5L0ZyYW1ld29ya3MvUHl0aG9uLmZyYW1ld29yay9WZXJzaW9ucy8zLjYvbGliL3B5dGhvbjMuNi9zaXRlLXBhY2thZ2VzL3NpZGVleWUvcGFyc2VyL2V4cGVyaW1lbnQucHkiLCBsaW5lIDc1LCBpbiBwYXJzZV9kaXIKICAgIHZlcmJvc2U9dmVyYm9zZSkKICBGaWxlICIvTGlicmFyeS9GcmFtZXdvcmtzL1B5dGhvbi5mcmFtZXdvcmsvVmVyc2lvbnMvMy42L2xpYi9weXRob24zLjYvc2l0ZS1wYWNrYWdlcy9zaWRlZXllL3BhcnNlci9yZWdpb24ucHkiLCBsaW5lIDU5LCBpbiBmaWxlCiAgICB2YWxpZGF0ZV9yZWdpb25fZmlsZShmaWxlbmFtZSkKICBGaWxlICIvTGlicmFyeS9GcmFtZXdvcmtzL1B5dGhvbi5mcmFtZXdvcmsvVmVyc2lvbnMvMy42L2xpYi9weXRob24zLjYvc2l0ZS1wYWNrYWdlcy9zaWRlZXllL3BhcnNlci9yZWdpb24ucHkiLCBsaW5lIDM4LCBpbiB2YWxpZGF0ZV9yZWdpb25fZmlsZQogICAgcmFpc2UgVmFsdWVFcnJvcignJXMgRmFpbGVkIHZhbGlkYXRpb246IE5vdCBhIHJlZ2lvbiBmaWxlJyAlIGZpbGVuYW1lKQpWYWx1ZUVycm9yOiBwcm9nZW4ucmVnLnR4dCBGYWlsZWQgdmFsaWRhdGlvbjogTm90IGEgcmVnaW9uIGZpbGUKYGBgCgpOb3BlLiAgCkFmdGVyIHRlc3Rpbmcgb3V0IGEgZmV3IGFsdGVyYXRpb25zLCBJIHN1c3BlY3QgdGhlcmUgYXJlIGEgZmV3IHRoaW5ncyBnb2luZyB3cm9uZzoKCjEuIFRoZSBmaWxlIG11c3QgYmUgZW5jb2RlZCBhcyBhIGAuY250YCBvciBgLnJlZ2AsIG5vdCBgLnR4dGAuCjIuIFByZXZpb3VzIGNvZGUgdG8gbWFrZSBhIGAucmVnLnR4dGAgZmlsZSBzcGVjaWZpZWQgbGluZSBudW1iZXIgaW4gYSB3YXkgdGhhdCBgLmNudGAgZmlsZXMgZG8gbm90LCBhbmQgdGh1cyBhcmUgaW5jb21wYXRpYmxlCjMuIFRoaXMgc2VlbXMgdG8gYmUgdGhlIGNhc2UgYmVjYXVzZSB0aGUgYHJlZy50eHRgIGZpbGUgZW5kcyBlYWNoIGxpbmUgaW4gYSAxLCB3aGljaCBzZWVtcyB0byBpbmRpY2F0ZSB0aGUgc2Vjb25kIGxpbmUgb2YgdGhlIHN0aW11bHVzLgoKYGBgCjEgMiA3IDAgMCA3IDAgNyAxIDE1IDEgMjQgMSAzMSAxIDQ5IDEKMiAyIDcgMCAwIDYgMCA3IDEgMTUgMSAyNCAxIDMxIDEgNDkgMQozIDIgNyAwIDAgOCAwIDcgMSAxNSAxIDI0IDEgMzEgMSA0OSAxCjQgMiA3IDAgMCA3IDAgNyAxIDE1IDEgMjQgMSAzMSAxIDQ5IDEKYGBgCgpJIGhhbmQtYWx0ZXJlZCB0aGlzIGZpbGUgdG8gYmUgb2YgYSBmb3JtIEkgdGhvdWdodCBsb29rZWQgYXBwcm9wcmlhdGU6CgpgYGAKMSAyIDcgMCA3IDcgMTUgMjQgMzEgNDkKMiAyIDcgMCA2IDcgMTUgMjQgMzEgNDkKMyAyIDcgMCA4IDcgMTUgMjQgMzEgNDkKNCAyIDcgMCA3IDcgMTUgMjQgMzEgNDkKYGBgCgpCdXQgdGhlbiBJIHN0aWxsIGdldCB0aGlzIGVycm9yLCB3aGljaCBpcyB0aGUgc2FtZSBhcyB3aGVuIHRoZSBsaW5lIGVuZGVkIHdpdGggYSAxOgoKYGBgCkxhdXJlbnMtTWFjQm9vay1Qcm8tMjpzaWRlLWV5ZSBsbWFja2VybWFuJCBweXRob24zIHNhbXBsZS1MTUEucHkKVHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOgogIEZpbGUgInNhbXBsZS1MTUEucHkiLCBsaW5lIDE3LCBpbiA8bW9kdWxlPgogICAgZXhwZXJpbWVudHMgPSBzaWRlZXllLnBhcnNlci5leHBlcmltZW50LnBhcnNlX2RpcignZGExX2ZpbGVzJywgJ3Rlc3QuY250JywgJ3NhbXBsZV9jb25maWcuanNvbicpCiAgRmlsZSAiL0xpYnJhcnkvRnJhbWV3b3Jrcy9QeXRob24uZnJhbWV3b3JrL1ZlcnNpb25zLzMuNi9saWIvcHl0aG9uMy42L3NpdGUtcGFja2FnZXMvc2lkZWV5ZS9wYXJzZXIvZXhwZXJpbWVudC5weSIsIGxpbmUgNzUsIGluIHBhcnNlX2RpcgogICAgdmVyYm9zZT12ZXJib3NlKQogIEZpbGUgIi9MaWJyYXJ5L0ZyYW1ld29ya3MvUHl0aG9uLmZyYW1ld29yay9WZXJzaW9ucy8zLjYvbGliL3B5dGhvbjMuNi9zaXRlLXBhY2thZ2VzL3NpZGVleWUvcGFyc2VyL3JlZ2lvbi5weSIsIGxpbmUgODgsIGluIGZpbGUKICAgIGxpbmVfdG9fcmVnaW9ucyhsaW5lW2JvdW5kYXJpZXNfc3RhcnQ6XSkpCiAgRmlsZSAiL0xpYnJhcnkvRnJhbWV3b3Jrcy9QeXRob24uZnJhbWV3b3JrL1ZlcnNpb25zLzMuNi9saWIvcHl0aG9uMy42L3NpdGUtcGFja2FnZXMvc2lkZWV5ZS9wYXJzZXIvcmVnaW9uLnB5IiwgbGluZSA3NSwgaW4gbGluZV90b19yZWdpb25zCiAgICByZWdpb25zICs9IFtSZWdpb24oUG9pbnQoeF9zdGFydCwgMCksIFBvaW50KHhfZW5kLCAwKSldCiAgRmlsZSAiL0xpYnJhcnkvRnJhbWV3b3Jrcy9QeXRob24uZnJhbWV3b3JrL1ZlcnNpb25zLzMuNi9saWIvcHl0aG9uMy42L3NpdGUtcGFja2FnZXMvc2lkZWV5ZS9kYXRhL3JlZ2lvbi5weSIsIGxpbmUgMjksIGluIF9faW5pdF9fCiAgICByYWlzZSBWYWx1ZUVycm9yKCdFbmQgb2YgcmVnaW9uIG11c3QgYmUgYWZ0ZXIgc3RhcnQgb2YgcmVnaW9uLicpCmBgYAo=