This R Markdown file contains code which assists in the visualization of particular samples in a dendrochronologic set in a restricted time range. This is meant to assist cross-dating by identifying missing rings in individual series via the comparison of the target sample with its sister sample or a strong master chronology of the dendrochronological series by efficiently moving around the focal sample to see how it visually matches. Additionally the resulting graphs will indicate the pearson correlation coefficient of the overlapped sections. Note that any results gleamed from this type of visualization should be compared to the actual dendrochronologic sample as to avoid falsifying data and violating academic integrity. Currently “The Dendro Visual-inator” only supports the comparison of two samples at a time, but if you need to compare more than just two samples than just add more code to the fifth code chunk where the visualizations occur following the naming conventions/code outlined in throughout the chunk though how this will work for the correlation coefficients is still unknown. This was code was written and created by Benjamin A. C. MacNeill on 27/02/2026 and is the first version of “The Dendro Visual-inator”. The core idea of “The Dendro Visual-inator” is based on a coded Excel file called “TREE Viewer_V0.8” which was created by Greg Jonah that performs the same task except for the display of the correlation coefficient. Anyone can feel free to use, modify, and experiment with “The Dendro Visual-inator” and if you have any questions, suggestions, or issues please feel free to reach out to . Warning spelling mistakes ahead!

##Install the Required Packages

install.packages("tidyverse")
#Note that dplR is only here to read rwl files so if you are importing a txt or csv you don't need it
install.packages("dplR")

##Load the Required Packages

library(tidyverse)
library(dplR)

##Import your Chronology Data

Listed below are some common file types and the code to import them, though the txt and rwl are more experimental and may need to be fiddled with.

#Import your Chronology Data (csv)

#Note you can change what type of data files you import but this may require the installation of more packages
Imported_Chronology_Data <- read_csv(file.choose())
#the following line will display the data and can be used to help understand if there was any issues with the import
Imported_Chronology_Data

#Import your Chronology Data (txt)

Imported_Chronology_Data <- read.delim(file.choose(), header = T)
Imported_Chronology_Data

#Import your Chronology Data (rwl)

Imported_Chronology_Data <- read.rwl(file.choose(), header = T)
Imported_Chronology_Data

##Format your Imported Data: Requires an Input

#Input the number of columns that are currently in the data
C <- 85

Full_Dendrochronologic_Set <- pivot_longer(Imported_Chronology_Data, #Select data
                    col = 2:C, #select columns to merge and convert
                    names_to = "Sample", #determines the name of the new column where the old column names will go
                    values_to = "Measure") #determines the name of the column where the old column values will go
#The following code will display the newly transformed data to see if anything when wrong
Full_Dendrochronologic_Set

##Visualizer

#Input the Object which corresponds to the imported long format chronology data
Target_Chronology <- Full_Dendrochronologic_Set
#Input the start and end years of the desired section to be visualized. Note that you should try to minimize the time range >100 or >150 year as it can impact the resolution of the chronology. Additionally, try to insure that the ranges will include sufficient data to capture where the chronologies may match and not match to allow for easier identification of missing rings.
Start <- 1800
End <- 1949

#Input the name of the series/sample or chronology which will be visualized 
id1 <- "16TL512A"
id2 <- "16TL512B"

#Input the amount of years you want each series/sample or chronology to move. Note that the mvmt_ID objects en with a number that corresponds to the id# of the previously imputed chronology. Note that that positive values will make the chronology move to the right while negative numbers will move them to the left and 0 means no change.

mvmt_ID1 <- 0
mvmt_ID2 <- 0

#This Marks the end of the imputable sections what follows is the code that generates the graph. Note that the resulting graph will have a number in the left hand corner which is the pearson correlation coefficient of where the two segments overlap. Also not that you can click the "show in new window" button to allow for you to efficiently adjust then view the positions of the segments on the graph.

###############################################################################################


#This code is filtering the Target_Chronology so that it falls within the time range which was previously inputted, attaching the result to a new object called TROC (Time Range Of Chronology).
TROC <- Target_Chronology %>% 
  filter(Year >= Start, 
         Year <= End)
#The following code is filtering the newly created TROC to isolate the desired sample/series/Chronology and attaching the result to a new objects which follow the naming convention D#Temp (Data #[corresponds to id#] Temporary). 
D1Temp <- TROC %>% 
  filter(Sample == id1)
D2Temp <- TROC %>% 
  filter(Sample == id2)
#The following code is creating sets of objects which are modifying the range values of the chronologies according to the previously imputed movements, resulting in two objects per set StD# (Start Data # [corresponds to id#]) and EdD# (End Data # [corresponds to id#]). Note that
StD1 <- Start + mvmt_ID1
EdD1 <- End + mvmt_ID1
StD2 <- Start + mvmt_ID2
EdD2 <- End + mvmt_ID2
#The following code is creating the data frames of each selected series with two variables time (created from the moved time ranges (StD#:EdD#)) and measure (extracted from the temporary data (D#Temp), attaching the the result to an object which follows the naming scheme `Data #` (the number corresponds to the id#). 
`Data 1` <- data.frame(Year = StD1:EdD1,
                      Measure = D1Temp$Measure)
`Data 2` <- data.frame(Year = StD2:EdD2,
                      Measure = D2Temp$Measure)
#The following code is joining the measures of the `Data #` but only the rows with overlaping years, attaching the resulting data frame to an object called Correlation.df.
Correlation.df <- `Data 1` %>% 
  inner_join(`Data 2`, 
             by = "Year")
#The following code is calculating the Pearsons Correlation coefficent between both measures, attatching the result to an object called Correlation_Value. Note that you can change what type of correlation you are doing by writing its name (all lowercase) into the "" in the "method = "pearson"" section of the code. Additionally if you are comparing three segments at once you would want to add another line which calls the new data measure though I have not tested this yet.
Correlation_Value <- cor(Correlation.df$Measure.x, 
                         Correlation.df$Measure.y,
                         method = "pearson")
#The following code creates the graph and notes will be annotated throughout
ggplot(D1Temp) + #this data was chosen as it matches the number of year present in the `Data #`
  labs(y = "Radial Ring Growth (mm)", #generates the axis and legend labels
       x = "Year",
       colour = "Series",
       caption = Correlation_Value) + #This adds the Correlation_Value to the graph
  geom_line(aes(x = `Data 1`$Year, #generates the id1 chronology specifies the use of data from `Data 1` and adds its definition to the legend
            y = `Data 1`$Measure,
            colour = id1)) +
  geom_line(aes(x = `Data 2`$Year, #generates the id2 chronology specifies the use of data from `Data 2` and adds its definition to the legend
                y = `Data 2`$Measure,
                colour = id2)) +
  scale_x_continuous(breaks = seq(Start, End, by = 10)) + # customizes the breaks in the x axis
  theme_classic() + #Sets the theme this can be changed or modified
  theme(legend.position = "top") #dictates the legends position
LS0tDQp0aXRsZTogIlRoZSBEZW5kcm8gVmlzdWFsLWluYXRvciINCmF1dGhvcjogIkJlbmphbWluIEEuIEMuIE1hY05laWxsIg0KZGF0ZTogIjIwMjYtMDItMjgiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIFIgTWFya2Rvd24gZmlsZSBjb250YWlucyBjb2RlIHdoaWNoIGFzc2lzdHMgaW4gdGhlIHZpc3VhbGl6YXRpb24gb2YgcGFydGljdWxhciBzYW1wbGVzIGluIGEgZGVuZHJvY2hyb25vbG9naWMgc2V0IGluIGEgcmVzdHJpY3RlZCB0aW1lIHJhbmdlLiBUaGlzIGlzIG1lYW50IHRvIGFzc2lzdCBjcm9zcy1kYXRpbmcgYnkgaWRlbnRpZnlpbmcgbWlzc2luZyByaW5ncyBpbiBpbmRpdmlkdWFsIHNlcmllcyB2aWEgdGhlIGNvbXBhcmlzb24gb2YgdGhlIHRhcmdldCBzYW1wbGUgd2l0aCBpdHMgc2lzdGVyIHNhbXBsZSBvciBhIHN0cm9uZyBtYXN0ZXIgY2hyb25vbG9neSBvZiB0aGUgZGVuZHJvY2hyb25vbG9naWNhbCBzZXJpZXMgYnkgZWZmaWNpZW50bHkgbW92aW5nIGFyb3VuZCB0aGUgZm9jYWwgc2FtcGxlIHRvIHNlZSBob3cgaXQgdmlzdWFsbHkgbWF0Y2hlcy4gQWRkaXRpb25hbGx5IHRoZSByZXN1bHRpbmcgZ3JhcGhzIHdpbGwgaW5kaWNhdGUgdGhlIHBlYXJzb24gY29ycmVsYXRpb24gY29lZmZpY2llbnQgb2YgdGhlIG92ZXJsYXBwZWQgc2VjdGlvbnMuIE5vdGUgdGhhdCBhbnkgcmVzdWx0cyBnbGVhbWVkIGZyb20gdGhpcyB0eXBlIG9mIHZpc3VhbGl6YXRpb24gc2hvdWxkIGJlIGNvbXBhcmVkIHRvIHRoZSBhY3R1YWwgZGVuZHJvY2hyb25vbG9naWMgc2FtcGxlIGFzIHRvIGF2b2lkIGZhbHNpZnlpbmcgZGF0YSBhbmQgdmlvbGF0aW5nIGFjYWRlbWljIGludGVncml0eS4gQ3VycmVudGx5ICJUaGUgRGVuZHJvIFZpc3VhbC1pbmF0b3IiIG9ubHkgc3VwcG9ydHMgdGhlIGNvbXBhcmlzb24gb2YgdHdvIHNhbXBsZXMgYXQgYSB0aW1lLCBidXQgaWYgeW91IG5lZWQgdG8gY29tcGFyZSBtb3JlIHRoYW4ganVzdCB0d28gc2FtcGxlcyB0aGFuIGp1c3QgYWRkIG1vcmUgY29kZSB0byB0aGUgZmlmdGggY29kZSBjaHVuayB3aGVyZSB0aGUgdmlzdWFsaXphdGlvbnMgb2NjdXIgZm9sbG93aW5nIHRoZSBuYW1pbmcgY29udmVudGlvbnMvY29kZSBvdXRsaW5lZCBpbiB0aHJvdWdob3V0IHRoZSBjaHVuayB0aG91Z2ggaG93IHRoaXMgd2lsbCB3b3JrIGZvciB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnRzIGlzIHN0aWxsIHVua25vd24uIFRoaXMgd2FzIGNvZGUgd2FzIHdyaXR0ZW4gYW5kIGNyZWF0ZWQgYnkgQmVuamFtaW4gQS4gQy4gTWFjTmVpbGwgb24gMjcvMDIvMjAyNiBhbmQgaXMgdGhlIGZpcnN0IHZlcnNpb24gb2YgIlRoZSBEZW5kcm8gVmlzdWFsLWluYXRvciIuIFRoZSBjb3JlIGlkZWEgb2YgIlRoZSBEZW5kcm8gVmlzdWFsLWluYXRvciIgaXMgYmFzZWQgb24gYSBjb2RlZCBFeGNlbCBmaWxlIGNhbGxlZCAiVFJFRSBWaWV3ZXJfVjAuOCIgd2hpY2ggd2FzIGNyZWF0ZWQgYnkgR3JlZyBKb25haCB0aGF0IHBlcmZvcm1zIHRoZSBzYW1lIHRhc2sgZXhjZXB0IGZvciB0aGUgZGlzcGxheSBvZiB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQuIEFueW9uZSBjYW4gZmVlbCBmcmVlIHRvIHVzZSwgbW9kaWZ5LCBhbmQgZXhwZXJpbWVudCB3aXRoICJUaGUgRGVuZHJvIFZpc3VhbC1pbmF0b3IiIGFuZCBpZiB5b3UgaGF2ZSBhbnkgcXVlc3Rpb25zLCBzdWdnZXN0aW9ucywgb3IgaXNzdWVzIHBsZWFzZSBmZWVsIGZyZWUgdG8gcmVhY2ggb3V0IHRvIGJhbWFjbmVpbGxAbXRhLmNhLiBXYXJuaW5nIHNwZWxsaW5nIG1pc3Rha2VzIGFoZWFkIQ0KDQojI0luc3RhbGwgdGhlIFJlcXVpcmVkIFBhY2thZ2VzDQoNCmBgYHtyfQ0KaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCiNOb3RlIHRoYXQgZHBsUiBpcyBvbmx5IGhlcmUgdG8gcmVhZCByd2wgZmlsZXMgc28gaWYgeW91IGFyZSBpbXBvcnRpbmcgYSB0eHQgb3IgY3N2IHlvdSBkb24ndCBuZWVkIGl0DQppbnN0YWxsLnBhY2thZ2VzKCJkcGxSIikNCmBgYA0KDQojI0xvYWQgdGhlIFJlcXVpcmVkIFBhY2thZ2VzDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGRwbFIpDQpgYGANCg0KIyNJbXBvcnQgeW91ciBDaHJvbm9sb2d5IERhdGENCg0KTGlzdGVkIGJlbG93IGFyZSBzb21lIGNvbW1vbiBmaWxlIHR5cGVzIGFuZCB0aGUgY29kZSB0byBpbXBvcnQgdGhlbSwgdGhvdWdoIHRoZSB0eHQgYW5kIHJ3bCBhcmUgbW9yZSBleHBlcmltZW50YWwgYW5kIG1heSBuZWVkIHRvIGJlIGZpZGRsZWQgd2l0aC4NCg0KI0ltcG9ydCB5b3VyIENocm9ub2xvZ3kgRGF0YSAoY3N2KQ0KDQpgYGB7cn0NCiNOb3RlIHlvdSBjYW4gY2hhbmdlIHdoYXQgdHlwZSBvZiBkYXRhIGZpbGVzIHlvdSBpbXBvcnQgYnV0IHRoaXMgbWF5IHJlcXVpcmUgdGhlIGluc3RhbGxhdGlvbiBvZiBtb3JlIHBhY2thZ2VzDQpJbXBvcnRlZF9DaHJvbm9sb2d5X0RhdGEgPC0gcmVhZF9jc3YoZmlsZS5jaG9vc2UoKSkNCiN0aGUgZm9sbG93aW5nIGxpbmUgd2lsbCBkaXNwbGF5IHRoZSBkYXRhIGFuZCBjYW4gYmUgdXNlZCB0byBoZWxwIHVuZGVyc3RhbmQgaWYgdGhlcmUgd2FzIGFueSBpc3N1ZXMgd2l0aCB0aGUgaW1wb3J0DQpJbXBvcnRlZF9DaHJvbm9sb2d5X0RhdGENCmBgYA0KDQojSW1wb3J0IHlvdXIgQ2hyb25vbG9neSBEYXRhICh0eHQpDQoNCmBgYHtyfQ0KSW1wb3J0ZWRfQ2hyb25vbG9neV9EYXRhIDwtIHJlYWQuZGVsaW0oZmlsZS5jaG9vc2UoKSwgaGVhZGVyID0gVCkNCkltcG9ydGVkX0Nocm9ub2xvZ3lfRGF0YQ0KYGBgDQoNCiNJbXBvcnQgeW91ciBDaHJvbm9sb2d5IERhdGEgKHJ3bCkNCg0KYGBge3J9DQpJbXBvcnRlZF9DaHJvbm9sb2d5X0RhdGEgPC0gcmVhZC5yd2woZmlsZS5jaG9vc2UoKSwgaGVhZGVyID0gVCkNCkltcG9ydGVkX0Nocm9ub2xvZ3lfRGF0YQ0KYGBgDQoNCiMjRm9ybWF0IHlvdXIgSW1wb3J0ZWQgRGF0YTogUmVxdWlyZXMgYW4gSW5wdXQNCg0KYGBge3J9DQojSW5wdXQgdGhlIG51bWJlciBvZiBjb2x1bW5zIHRoYXQgYXJlIGN1cnJlbnRseSBpbiB0aGUgZGF0YQ0KQyA8LSA4NQ0KDQpGdWxsX0RlbmRyb2Nocm9ub2xvZ2ljX1NldCA8LSBwaXZvdF9sb25nZXIoSW1wb3J0ZWRfQ2hyb25vbG9neV9EYXRhLCAjU2VsZWN0IGRhdGENCiAgICAgICAgICAgICAgICAgICAgY29sID0gMjpDLCAjc2VsZWN0IGNvbHVtbnMgdG8gbWVyZ2UgYW5kIGNvbnZlcnQNCiAgICAgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiU2FtcGxlIiwgI2RldGVybWluZXMgdGhlIG5hbWUgb2YgdGhlIG5ldyBjb2x1bW4gd2hlcmUgdGhlIG9sZCBjb2x1bW4gbmFtZXMgd2lsbCBnbw0KICAgICAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiTWVhc3VyZSIpICNkZXRlcm1pbmVzIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gd2hlcmUgdGhlIG9sZCBjb2x1bW4gdmFsdWVzIHdpbGwgZ28NCiNUaGUgZm9sbG93aW5nIGNvZGUgd2lsbCBkaXNwbGF5IHRoZSBuZXdseSB0cmFuc2Zvcm1lZCBkYXRhIHRvIHNlZSBpZiBhbnl0aGluZyB3aGVuIHdyb25nDQpGdWxsX0RlbmRyb2Nocm9ub2xvZ2ljX1NldA0KYGBgDQoNCiMjVmlzdWFsaXplcg0KDQpgYGB7cn0NCiNJbnB1dCB0aGUgT2JqZWN0IHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSBpbXBvcnRlZCBsb25nIGZvcm1hdCBjaHJvbm9sb2d5IGRhdGENClRhcmdldF9DaHJvbm9sb2d5IDwtIEZ1bGxfRGVuZHJvY2hyb25vbG9naWNfU2V0DQojSW5wdXQgdGhlIHN0YXJ0IGFuZCBlbmQgeWVhcnMgb2YgdGhlIGRlc2lyZWQgc2VjdGlvbiB0byBiZSB2aXN1YWxpemVkLiBOb3RlIHRoYXQgeW91IHNob3VsZCB0cnkgdG8gbWluaW1pemUgdGhlIHRpbWUgcmFuZ2UgPjEwMCBvciA+MTUwIHllYXIgYXMgaXQgY2FuIGltcGFjdCB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgY2hyb25vbG9neS4gQWRkaXRpb25hbGx5LCB0cnkgdG8gaW5zdXJlIHRoYXQgdGhlIHJhbmdlcyB3aWxsIGluY2x1ZGUgc3VmZmljaWVudCBkYXRhIHRvIGNhcHR1cmUgd2hlcmUgdGhlIGNocm9ub2xvZ2llcyBtYXkgbWF0Y2ggYW5kIG5vdCBtYXRjaCB0byBhbGxvdyBmb3IgZWFzaWVyIGlkZW50aWZpY2F0aW9uIG9mIG1pc3NpbmcgcmluZ3MuDQpTdGFydCA8LSAxODAwDQpFbmQgPC0gMTk0OQ0KDQojSW5wdXQgdGhlIG5hbWUgb2YgdGhlIHNlcmllcy9zYW1wbGUgb3IgY2hyb25vbG9neSB3aGljaCB3aWxsIGJlIHZpc3VhbGl6ZWQgDQppZDEgPC0gIjE2VEw1MTJBIg0KaWQyIDwtICIxNlRMNTEyQiINCg0KI0lucHV0IHRoZSBhbW91bnQgb2YgeWVhcnMgeW91IHdhbnQgZWFjaCBzZXJpZXMvc2FtcGxlIG9yIGNocm9ub2xvZ3kgdG8gbW92ZS4gTm90ZSB0aGF0IHRoZSBtdm10X0lEIG9iamVjdHMgZW4gd2l0aCBhIG51bWJlciB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBpZCMgb2YgdGhlIHByZXZpb3VzbHkgaW1wdXRlZCBjaHJvbm9sb2d5LiBOb3RlIHRoYXQgdGhhdCBwb3NpdGl2ZSB2YWx1ZXMgd2lsbCBtYWtlIHRoZSBjaHJvbm9sb2d5IG1vdmUgdG8gdGhlIHJpZ2h0IHdoaWxlIG5lZ2F0aXZlIG51bWJlcnMgd2lsbCBtb3ZlIHRoZW0gdG8gdGhlIGxlZnQgYW5kIDAgbWVhbnMgbm8gY2hhbmdlLg0KDQptdm10X0lEMSA8LSAwDQptdm10X0lEMiA8LSAwDQoNCiNUaGlzIE1hcmtzIHRoZSBlbmQgb2YgdGhlIGltcHV0YWJsZSBzZWN0aW9ucyB3aGF0IGZvbGxvd3MgaXMgdGhlIGNvZGUgdGhhdCBnZW5lcmF0ZXMgdGhlIGdyYXBoLiBOb3RlIHRoYXQgdGhlIHJlc3VsdGluZyBncmFwaCB3aWxsIGhhdmUgYSBudW1iZXIgaW4gdGhlIGxlZnQgaGFuZCBjb3JuZXIgd2hpY2ggaXMgdGhlIHBlYXJzb24gY29ycmVsYXRpb24gY29lZmZpY2llbnQgb2Ygd2hlcmUgdGhlIHR3byBzZWdtZW50cyBvdmVybGFwLiBBbHNvIG5vdCB0aGF0IHlvdSBjYW4gY2xpY2sgdGhlICJzaG93IGluIG5ldyB3aW5kb3ciIGJ1dHRvbiB0byBhbGxvdyBmb3IgeW91IHRvIGVmZmljaWVudGx5IGFkanVzdCB0aGVuIHZpZXcgdGhlIHBvc2l0aW9ucyBvZiB0aGUgc2VnbWVudHMgb24gdGhlIGdyYXBoLg0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQoNCiNUaGlzIGNvZGUgaXMgZmlsdGVyaW5nIHRoZSBUYXJnZXRfQ2hyb25vbG9neSBzbyB0aGF0IGl0IGZhbGxzIHdpdGhpbiB0aGUgdGltZSByYW5nZSB3aGljaCB3YXMgcHJldmlvdXNseSBpbnB1dHRlZCwgYXR0YWNoaW5nIHRoZSByZXN1bHQgdG8gYSBuZXcgb2JqZWN0IGNhbGxlZCBUUk9DIChUaW1lIFJhbmdlIE9mIENocm9ub2xvZ3kpLg0KVFJPQyA8LSBUYXJnZXRfQ2hyb25vbG9neSAlPiUgDQogIGZpbHRlcihZZWFyID49IFN0YXJ0LCANCiAgICAgICAgIFllYXIgPD0gRW5kKQ0KI1RoZSBmb2xsb3dpbmcgY29kZSBpcyBmaWx0ZXJpbmcgdGhlIG5ld2x5IGNyZWF0ZWQgVFJPQyB0byBpc29sYXRlIHRoZSBkZXNpcmVkIHNhbXBsZS9zZXJpZXMvQ2hyb25vbG9neSBhbmQgYXR0YWNoaW5nIHRoZSByZXN1bHQgdG8gYSBuZXcgb2JqZWN0cyB3aGljaCBmb2xsb3cgdGhlIG5hbWluZyBjb252ZW50aW9uIEQjVGVtcCAoRGF0YSAjW2NvcnJlc3BvbmRzIHRvIGlkI10gVGVtcG9yYXJ5KS4gDQpEMVRlbXAgPC0gVFJPQyAlPiUgDQogIGZpbHRlcihTYW1wbGUgPT0gaWQxKQ0KRDJUZW1wIDwtIFRST0MgJT4lIA0KICBmaWx0ZXIoU2FtcGxlID09IGlkMikNCiNUaGUgZm9sbG93aW5nIGNvZGUgaXMgY3JlYXRpbmcgc2V0cyBvZiBvYmplY3RzIHdoaWNoIGFyZSBtb2RpZnlpbmcgdGhlIHJhbmdlIHZhbHVlcyBvZiB0aGUgY2hyb25vbG9naWVzIGFjY29yZGluZyB0byB0aGUgcHJldmlvdXNseSBpbXB1dGVkIG1vdmVtZW50cywgcmVzdWx0aW5nIGluIHR3byBvYmplY3RzIHBlciBzZXQgU3REIyAoU3RhcnQgRGF0YSAjIFtjb3JyZXNwb25kcyB0byBpZCNdKSBhbmQgRWREIyAoRW5kIERhdGEgIyBbY29ycmVzcG9uZHMgdG8gaWQjXSkuIE5vdGUgdGhhdA0KU3REMSA8LSBTdGFydCArIG12bXRfSUQxDQpFZEQxIDwtIEVuZCArIG12bXRfSUQxDQpTdEQyIDwtIFN0YXJ0ICsgbXZtdF9JRDINCkVkRDIgPC0gRW5kICsgbXZtdF9JRDINCiNUaGUgZm9sbG93aW5nIGNvZGUgaXMgY3JlYXRpbmcgdGhlIGRhdGEgZnJhbWVzIG9mIGVhY2ggc2VsZWN0ZWQgc2VyaWVzIHdpdGggdHdvIHZhcmlhYmxlcyB0aW1lIChjcmVhdGVkIGZyb20gdGhlIG1vdmVkIHRpbWUgcmFuZ2VzIChTdEQjOkVkRCMpKSBhbmQgbWVhc3VyZSAoZXh0cmFjdGVkIGZyb20gdGhlIHRlbXBvcmFyeSBkYXRhIChEI1RlbXApLCBhdHRhY2hpbmcgdGhlIHRoZSByZXN1bHQgdG8gYW4gb2JqZWN0IHdoaWNoIGZvbGxvd3MgdGhlIG5hbWluZyBzY2hlbWUgYERhdGEgI2AgKHRoZSBudW1iZXIgY29ycmVzcG9uZHMgdG8gdGhlIGlkIykuIA0KYERhdGEgMWAgPC0gZGF0YS5mcmFtZShZZWFyID0gU3REMTpFZEQxLA0KICAgICAgICAgICAgICAgICAgICAgIE1lYXN1cmUgPSBEMVRlbXAkTWVhc3VyZSkNCmBEYXRhIDJgIDwtIGRhdGEuZnJhbWUoWWVhciA9IFN0RDI6RWREMiwNCiAgICAgICAgICAgICAgICAgICAgICBNZWFzdXJlID0gRDJUZW1wJE1lYXN1cmUpDQojVGhlIGZvbGxvd2luZyBjb2RlIGlzIGpvaW5pbmcgdGhlIG1lYXN1cmVzIG9mIHRoZSBgRGF0YSAjYCBidXQgb25seSB0aGUgcm93cyB3aXRoIG92ZXJsYXBpbmcgeWVhcnMsIGF0dGFjaGluZyB0aGUgcmVzdWx0aW5nIGRhdGEgZnJhbWUgdG8gYW4gb2JqZWN0IGNhbGxlZCBDb3JyZWxhdGlvbi5kZi4NCkNvcnJlbGF0aW9uLmRmIDwtIGBEYXRhIDFgICU+JSANCiAgaW5uZXJfam9pbihgRGF0YSAyYCwgDQogICAgICAgICAgICAgYnkgPSAiWWVhciIpDQojVGhlIGZvbGxvd2luZyBjb2RlIGlzIGNhbGN1bGF0aW5nIHRoZSBQZWFyc29ucyBDb3JyZWxhdGlvbiBjb2VmZmljZW50IGJldHdlZW4gYm90aCBtZWFzdXJlcywgYXR0YXRjaGluZyB0aGUgcmVzdWx0IHRvIGFuIG9iamVjdCBjYWxsZWQgQ29ycmVsYXRpb25fVmFsdWUuIE5vdGUgdGhhdCB5b3UgY2FuIGNoYW5nZSB3aGF0IHR5cGUgb2YgY29ycmVsYXRpb24geW91IGFyZSBkb2luZyBieSB3cml0aW5nIGl0cyBuYW1lIChhbGwgbG93ZXJjYXNlKSBpbnRvIHRoZSAiIiBpbiB0aGUgIm1ldGhvZCA9ICJwZWFyc29uIiIgc2VjdGlvbiBvZiB0aGUgY29kZS4gQWRkaXRpb25hbGx5IGlmIHlvdSBhcmUgY29tcGFyaW5nIHRocmVlIHNlZ21lbnRzIGF0IG9uY2UgeW91IHdvdWxkIHdhbnQgdG8gYWRkIGFub3RoZXIgbGluZSB3aGljaCBjYWxscyB0aGUgbmV3IGRhdGEgbWVhc3VyZSB0aG91Z2ggSSBoYXZlIG5vdCB0ZXN0ZWQgdGhpcyB5ZXQuDQpDb3JyZWxhdGlvbl9WYWx1ZSA8LSBjb3IoQ29ycmVsYXRpb24uZGYkTWVhc3VyZS54LCANCiAgICAgICAgICAgICAgICAgICAgICAgICBDb3JyZWxhdGlvbi5kZiRNZWFzdXJlLnksDQogICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gInBlYXJzb24iKQ0KI1RoZSBmb2xsb3dpbmcgY29kZSBjcmVhdGVzIHRoZSBncmFwaCBhbmQgbm90ZXMgd2lsbCBiZSBhbm5vdGF0ZWQgdGhyb3VnaG91dA0KZ2dwbG90KEQxVGVtcCkgKyAjdGhpcyBkYXRhIHdhcyBjaG9zZW4gYXMgaXQgbWF0Y2hlcyB0aGUgbnVtYmVyIG9mIHllYXIgcHJlc2VudCBpbiB0aGUgYERhdGEgI2ANCiAgbGFicyh5ID0gIlJhZGlhbCBSaW5nIEdyb3d0aCAobW0pIiwgI2dlbmVyYXRlcyB0aGUgYXhpcyBhbmQgbGVnZW5kIGxhYmVscw0KICAgICAgIHggPSAiWWVhciIsDQogICAgICAgY29sb3VyID0gIlNlcmllcyIsDQogICAgICAgY2FwdGlvbiA9IENvcnJlbGF0aW9uX1ZhbHVlKSArICNUaGlzIGFkZHMgdGhlIENvcnJlbGF0aW9uX1ZhbHVlIHRvIHRoZSBncmFwaA0KICBnZW9tX2xpbmUoYWVzKHggPSBgRGF0YSAxYCRZZWFyLCAjZ2VuZXJhdGVzIHRoZSBpZDEgY2hyb25vbG9neSBzcGVjaWZpZXMgdGhlIHVzZSBvZiBkYXRhIGZyb20gYERhdGEgMWAgYW5kIGFkZHMgaXRzIGRlZmluaXRpb24gdG8gdGhlIGxlZ2VuZA0KICAgICAgICAgICAgeSA9IGBEYXRhIDFgJE1lYXN1cmUsDQogICAgICAgICAgICBjb2xvdXIgPSBpZDEpKSArDQogIGdlb21fbGluZShhZXMoeCA9IGBEYXRhIDJgJFllYXIsICNnZW5lcmF0ZXMgdGhlIGlkMiBjaHJvbm9sb2d5IHNwZWNpZmllcyB0aGUgdXNlIG9mIGRhdGEgZnJvbSBgRGF0YSAyYCBhbmQgYWRkcyBpdHMgZGVmaW5pdGlvbiB0byB0aGUgbGVnZW5kDQogICAgICAgICAgICAgICAgeSA9IGBEYXRhIDJgJE1lYXN1cmUsDQogICAgICAgICAgICAgICAgY29sb3VyID0gaWQyKSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKFN0YXJ0LCBFbmQsIGJ5ID0gMTApKSArICMgY3VzdG9taXplcyB0aGUgYnJlYWtzIGluIHRoZSB4IGF4aXMNCiAgdGhlbWVfY2xhc3NpYygpICsgI1NldHMgdGhlIHRoZW1lIHRoaXMgY2FuIGJlIGNoYW5nZWQgb3IgbW9kaWZpZWQNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICNkaWN0YXRlcyB0aGUgbGVnZW5kcyBwb3NpdGlvbg0KYGBgDQo=