In this report, I have used all OUR MODIFIED functions which are based on robCompositions package

1. Import climate data

## ===== Packages =================================

library(readstata13)        ## Importing Stata data
library(ggplot2)            ## Figures

## ==== Other packages ============================
## Source = https://swilke-geoscience.net/post/spatial_interpolation/


# Some packages for (spatial) data processing
library(tidyverse) # wrangling tabular data and plotting
library(sf) # processing spatial vector data
library(sp) # another vector data package necessary for continuity
library(raster) # processing spatial raster data. !!!overwrites dplyr::select!!!

# Different packages to test their interpolation functions
library(gstat)  # inverse distance weighted, Kriging
library(fields) # Thin Plate Spline
library(interp) # Triangulation
library(mgcv)   # Spatial GAM
library(automap)# Automatic approach to Kriging

# Finally, some packages to make pretty plots
library(patchwork)
library(viridis)
require(readxl)
require(stringr)
##--------------------Transform hist using clr
require(robCompositions)
require(splines)
## ===== Load data ================================

setwd("D:/Compositional regression/Climate")
tmax_2015 <-read.dta13("tmax_2015.dta")

tentinh <- read_excel("Tentinh.xlsx")

source("FunctionCRF.R") # function fcenLRF
## ===== Data manipulations =======================
# Change name to capita


tmax_2015 <- tmax_2015 %>% mutate(province = str_to_upper(province))
setdiff(tmax_2015$province, tentinh$PROVINCE_NAME2)
##  [1] "YUNNAN"             "GUANGXI ZHUANG"     "GUANGXI"           
##  [4] "PHONGSALY"          "HANOI"              "STATE NOT FOUND"   
##  [7] "OUDOMXAY"           "LUANG PRABANG"      "HUAPHANH"          
## [10] "HAIPHONG"           "XIENGKHUANG"        "HAINAN"            
## [13] "VIENTIANE"          "XAYSOMBOON"         "BORIKHAMXAY"       
## [16] "VIENTIANE CAPITAL"  "NONG KHAI"          "BUENG KAN PROVINCE"
## [19] "UDON THANI"         "SAKON NAKHON"       "NAKHON PHANOM"     
## [22] "KHAMMUANE"          "NONG BUA LAMPHU"    "KHON KAEN"         
## [25] "KALASIN"            "MUKDAHAN"           "SAVANNAKHET"       
## [28] "CHAIYAPHUM"         "MAHA SARAKHAM"      "ROI ET"            
## [31] "SARAVANE"           "NAKHON RATCHASIMA"  "YASOTHON"          
## [34] "AMNAT CHAROEN"      "UBON RATCHATHANI"   "SEKONG"            
## [37] "BURIRAM"            "SURIN"              "SISAKET"           
## [40] "CHAMPASACK"         "ATTAPEU"            "ODDAR MEANCHEY"    
## [43] "PREAH VIHEAR"       "STUNG TRENG"        "RATANAKIRI"        
## [46] "SA KAEO"            "BANTEAY MEANCHEY"   "SIEM REAP"         
## [49] "CHANTHABURI"        "BATTAMBANG"         "KAMPONG THOM"      
## [52] "KRATIE"             "MONDULKIRI"         "PAILIN"            
## [55] "POUTHISAT"          "TRAT PROVINCE"      "KAMPONG CHHNANG"   
## [58] "KAMPONG CHAM"       "TBOUNG KHMUM"       "KOH KONG"          
## [61] "KAMPONG SPEU"       "KANDAL"             "PREY VENG"         
## [64] "SVAY RIENG"         "PREAH SIHANOUK"     "KAMPOT"            
## [67] "TAKEO"              "HO CHI MINH CITY"   "BA RIA-VUNG TAU"
setdiff(tentinh$PROVINCE_NAME2, tmax_2015$province)
##  [1] "HA NOI"            "VINH PHUC"         "BAC NINH"         
##  [4] "HAI PHONG"         "HUNG YEN"          "THAI BINH"        
##  [7] "HA NAM"            "DA NANG"           "BA RIA - VUNG TAU"
## [10] "HO CHI MINH"       "VINH LONG"         "CAN THO"          
## [13] "SOC TRANG"
tmax_2015 <- tmax_2015 %>% mutate(province =  case_when(province== "HANOI"  ~ "HA NOI" ,
                                                        province== "HANOI"  ~ "HA NOI",
                                                        province== "HAIPHONG"  ~ "HAI PHONG",
                                                        province== "BA RIA-VUNG TAU" ~  "BA RIA - VUNG TAU",
                                                        province== "HO CHI MINH CITY" ~ "HO CHI MINH" ,
                                                        province== "HO CHI MINH CITY" ~ "HO CHI MINH" ,
                                                        TRUE ~  province))
                                  
# No VINH PHUC, BAC NINH,   "HUNG YEN" ,  "THAI BINH", "HA NAM", "DA NANG",  "VINH LONG", "CAN THO" ,  "SOC TRANG"   

  
  
#filter only Vietnamese provinces

tmax_2015 <- tmax_2015 %>% filter(province %in% tentinh$PROVINCE_NAME2)
unique(tmax_2015$province)
##  [1] "HA GIANG"          "LAO CAI"           "CAO BANG"         
##  [4] "DIEN BIEN"         "LAI CHAU"          "TUYEN QUANG"      
##  [7] "BAC KAN"           "LANG SON"          "SON LA"           
## [10] "YEN BAI"           "THAI NGUYEN"       "PHU THO"          
## [13] "HA NOI"            "BAC GIANG"         "QUANG NINH"       
## [16] "HOA BINH"          "HAI DUONG"         "HAI PHONG"        
## [19] "THANH HOA"         "NINH BINH"         "NAM DINH"         
## [22] "NGHE AN"           "HA TINH"           "QUANG BINH"       
## [25] "QUANG TRI"         "THUA THIEN HUE"    "QUANG NAM"        
## [28] "QUANG NGAI"        "KON TUM"           "GIA LAI"          
## [31] "BINH DINH"         "DAK LAK"           "PHU YEN"          
## [34] "DAK NONG"          "KHANH HOA"         "TAY NINH"         
## [37] "BINH PHUOC"        "LAM DONG"          "NINH THUAN"       
## [40] "BINH DUONG"        "DONG NAI"          "BINH THUAN"       
## [43] "AN GIANG"          "LONG AN"           "HO CHI MINH"      
## [46] "BA RIA - VUNG TAU" "KIEN GIANG"        "DONG THAP"        
## [49] "BEN TRE"           "TIEN GIANG"        "HAU GIANG"        
## [52] "TRA VINH"          "CA MAU"            "BAC LIEU"
dim(tmax_2015)
## [1] 119 369
names(tmax_2015)[1] <- "longitude" 

2. Store all tmax for each province in list Ltmax2015

#---------Work with 1 provicine
require(reshape2)

unique(tmax_2015$province)
##  [1] "HA GIANG"          "LAO CAI"           "CAO BANG"         
##  [4] "DIEN BIEN"         "LAI CHAU"          "TUYEN QUANG"      
##  [7] "BAC KAN"           "LANG SON"          "SON LA"           
## [10] "YEN BAI"           "THAI NGUYEN"       "PHU THO"          
## [13] "HA NOI"            "BAC GIANG"         "QUANG NINH"       
## [16] "HOA BINH"          "HAI DUONG"         "HAI PHONG"        
## [19] "THANH HOA"         "NINH BINH"         "NAM DINH"         
## [22] "NGHE AN"           "HA TINH"           "QUANG BINH"       
## [25] "QUANG TRI"         "THUA THIEN HUE"    "QUANG NAM"        
## [28] "QUANG NGAI"        "KON TUM"           "GIA LAI"          
## [31] "BINH DINH"         "DAK LAK"           "PHU YEN"          
## [34] "DAK NONG"          "KHANH HOA"         "TAY NINH"         
## [37] "BINH PHUOC"        "LAM DONG"          "NINH THUAN"       
## [40] "BINH DUONG"        "DONG NAI"          "BINH THUAN"       
## [43] "AN GIANG"          "LONG AN"           "HO CHI MINH"      
## [46] "BA RIA - VUNG TAU" "KIEN GIANG"        "DONG THAP"        
## [49] "BEN TRE"           "TIEN GIANG"        "HAU GIANG"        
## [52] "TRA VINH"          "CA MAU"            "BAC LIEU"
#Now, store tmax in each province in a list, List tmax: Ltmax

funtmax <- function(PRO)
{
  TempPRO <- tmax_2015 %>% filter(province == PRO)
  
  TempPRO  <- reshape2::melt( TempPRO , 
                    id.vars = c("longitude",  "latitude" ,
                                "district",   "province"))
  TempPRO  <-  TempPRO  %>% rename(tmax = value)
  TempPRO  <-  TempPRO  %>% group_by(variable) %>%
    summarise(tmax = max(tmax))
  return( TempPRO )
}

#test funtmax for Hanoi

HN1 <- funtmax ("HA NOI")

#------APPLY funtmax()

Ltmax2015 <- list()
for (P in unique(tmax_2015$province))
{
  Ltmax2015[[P]] <- funtmax (P)
}

3. Store all compositional spline output in list Ltmax2015CS

#---------------Now, applying compositionalSpline() function

order = 4
der = 2
alpha = 0.3


funCS <- function(PRO)
{
  histempt <- hist( Ltmax2015[[PRO]]$tmax,
                 #xlab = "Tmax",
                # main = "Estimated histogram of tmax - Hanoi", 
                 #col = "blue", lwd = 2, 
                 breaks = 30,
                 plot = FALSE) # It does not work with 50 bins
  #t: histHN$breaks
  #density: histHN$density
  
  t_step = diff(histempt$breaks[1:2])
  
  
  #-----Using fcenLRF() by Huong
  
  knots <-  histempt$breaks[-length( histempt$breaks)]+0.5
  clrhisttempt <- fcenLRF(knots,   histempt$density ) #knots and  estimate
  
  #----using function in robCompositions
  t <- NULL
  clrf <- NULL
  knots<- NULL
  
  clrf <-  clrhisttempt$estimate
  t  <- clrhisttempt$knots
  knots <-  seq(min(Ltmax2015[[PRO]]$tmax), 
                max(Ltmax2015[[PRO]]$tmax), length = 10)
  w <- rep( 1/length(t), length(t))
  
  return(list(clrf=clrf, t = t, knots = knots, w = w))
  #compositionalSpline(t, clrf, knots, w, order,
   #                   der, alpha, 
    #                  spline.plot = TRUE, 
     #                 basis.plot = FALSE) #DONE
}

#---Now, apply for all provinces

Ltmax2015CS <- list()
for (P in unique(tmax_2015$province))
{
  Ltmax2015CS[[P]] <- funCS (P)
}

4. Now, plot all the spline of provinces, using compositionalSplineF

Plot for one province

P <- "DONG NAI"
order = 4
der = 2
alpha = 0.5
compositionalSplineF(Ltmax2015CS[[P]]$t, 
                    Ltmax2015CS[[P]]$clrf,
                    Ltmax2015CS[[P]]$knots,
                    Ltmax2015CS[[P]]$w, order,
                    der, alpha, 
                    spline.plot = TRUE, 
                    basis.plot = FALSE,
                    namemain = P) #DONE

## $J
##           [,1]
## [1,] 0.4575099
## 
## $ZB_coef
##              [,1]
##  [1,] -0.70757681
##  [2,] -1.97903576
##  [3,] -3.45542347
##  [4,] -4.53624184
##  [5,] -4.68004850
##  [6,] -4.00624818
##  [7,] -2.79506093
##  [8,] -1.42424492
##  [9,] -0.31368592
## [10,]  0.06411245
## [11,]  0.06292768
## 
## $CV
## [1] 0.8240508
## 
## $GCV
## [1] 0.7766156

Now, plot for all provinces, using the same smoothing parameters.

order = 4
der = 2
alpha = 0.5

for (P in unique(tmax_2015$province))
{
  compositionalSplineF(Ltmax2015CS[[P]]$t, 
                    Ltmax2015CS[[P]]$clrf,
                    Ltmax2015CS[[P]]$knots,
                    Ltmax2015CS[[P]]$w, order,
                    der, alpha, 
                    spline.plot = TRUE, 
                    basis.plot = FALSE,
                    namemain = P)
}

LS0tDQp0aXRsZTogIkNvbXBvc2l0aW9uYWwgc3BsaW5lIG9mIHRtYXgtIGFsbCBwcm92aW5jZSBpbiAyMDE1Ig0KYXV0aG9yOiAiSHVvbmciDQpkYXRlOiAiMTMvMTEvMjAyMSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzDQogICAgdGhlbWU6IGZsYXRseQ0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgd29yZF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KLS0tDQoNCmBgYHtyIHNldHVwLGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFKQ0KYGBgDQoNCkluIHRoaXMgcmVwb3J0LCBJIGhhdmUgdXNlZCBhbGwgT1VSIE1PRElGSUVEIGZ1bmN0aW9ucyB3aGljaCBhcmUgYmFzZWQgb24gcm9iQ29tcG9zaXRpb25zIHBhY2thZ2UNCg0KIyMgMS4gSW1wb3J0IGNsaW1hdGUgZGF0YQ0KDQpgYGB7cn0NCiMjID09PT09IFBhY2thZ2VzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KDQpsaWJyYXJ5KHJlYWRzdGF0YTEzKSAgICAgICAgIyMgSW1wb3J0aW5nIFN0YXRhIGRhdGENCmxpYnJhcnkoZ2dwbG90MikgICAgICAgICAgICAjIyBGaWd1cmVzDQoNCiMjID09PT0gT3RoZXIgcGFja2FnZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KIyMgU291cmNlID0gaHR0cHM6Ly9zd2lsa2UtZ2Vvc2NpZW5jZS5uZXQvcG9zdC9zcGF0aWFsX2ludGVycG9sYXRpb24vDQoNCg0KIyBTb21lIHBhY2thZ2VzIGZvciAoc3BhdGlhbCkgZGF0YSBwcm9jZXNzaW5nDQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIyB3cmFuZ2xpbmcgdGFidWxhciBkYXRhIGFuZCBwbG90dGluZw0KbGlicmFyeShzZikgIyBwcm9jZXNzaW5nIHNwYXRpYWwgdmVjdG9yIGRhdGENCmxpYnJhcnkoc3ApICMgYW5vdGhlciB2ZWN0b3IgZGF0YSBwYWNrYWdlIG5lY2Vzc2FyeSBmb3IgY29udGludWl0eQ0KbGlicmFyeShyYXN0ZXIpICMgcHJvY2Vzc2luZyBzcGF0aWFsIHJhc3RlciBkYXRhLiAhISFvdmVyd3JpdGVzIGRwbHlyOjpzZWxlY3QhISENCg0KIyBEaWZmZXJlbnQgcGFja2FnZXMgdG8gdGVzdCB0aGVpciBpbnRlcnBvbGF0aW9uIGZ1bmN0aW9ucw0KbGlicmFyeShnc3RhdCkgICMgaW52ZXJzZSBkaXN0YW5jZSB3ZWlnaHRlZCwgS3JpZ2luZw0KbGlicmFyeShmaWVsZHMpICMgVGhpbiBQbGF0ZSBTcGxpbmUNCmxpYnJhcnkoaW50ZXJwKSAjIFRyaWFuZ3VsYXRpb24NCmxpYnJhcnkobWdjdikgICAjIFNwYXRpYWwgR0FNDQpsaWJyYXJ5KGF1dG9tYXApIyBBdXRvbWF0aWMgYXBwcm9hY2ggdG8gS3JpZ2luZw0KDQojIEZpbmFsbHksIHNvbWUgcGFja2FnZXMgdG8gbWFrZSBwcmV0dHkgcGxvdHMNCmxpYnJhcnkocGF0Y2h3b3JrKQ0KbGlicmFyeSh2aXJpZGlzKQ0KcmVxdWlyZShyZWFkeGwpDQpyZXF1aXJlKHN0cmluZ3IpDQojIy0tLS0tLS0tLS0tLS0tLS0tLS0tVHJhbnNmb3JtIGhpc3QgdXNpbmcgY2xyDQpyZXF1aXJlKHJvYkNvbXBvc2l0aW9ucykNCnJlcXVpcmUoc3BsaW5lcykNCiMjID09PT09IExvYWQgZGF0YSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KDQpzZXR3ZCgiRDovQ29tcG9zaXRpb25hbCByZWdyZXNzaW9uL0NsaW1hdGUiKQ0KdG1heF8yMDE1IDwtcmVhZC5kdGExMygidG1heF8yMDE1LmR0YSIpDQoNCnRlbnRpbmggPC0gcmVhZF9leGNlbCgiVGVudGluaC54bHN4IikNCg0Kc291cmNlKCJGdW5jdGlvbkNSRi5SIikgIyBmdW5jdGlvbiBmY2VuTFJGDQojIyA9PT09PSBEYXRhIG1hbmlwdWxhdGlvbnMgPT09PT09PT09PT09PT09PT09PT09PT0NCiMgQ2hhbmdlIG5hbWUgdG8gY2FwaXRhDQoNCg0KdG1heF8yMDE1IDwtIHRtYXhfMjAxNSAlPiUgbXV0YXRlKHByb3ZpbmNlID0gc3RyX3RvX3VwcGVyKHByb3ZpbmNlKSkNCnNldGRpZmYodG1heF8yMDE1JHByb3ZpbmNlLCB0ZW50aW5oJFBST1ZJTkNFX05BTUUyKQ0KDQoNCnNldGRpZmYodGVudGluaCRQUk9WSU5DRV9OQU1FMiwgdG1heF8yMDE1JHByb3ZpbmNlKQ0KDQp0bWF4XzIwMTUgPC0gdG1heF8yMDE1ICU+JSBtdXRhdGUocHJvdmluY2UgPSAgY2FzZV93aGVuKHByb3ZpbmNlPT0gIkhBTk9JIiAgfiAiSEEgTk9JIiAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpbmNlPT0gIkhBTk9JIiAgfiAiSEEgTk9JIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmluY2U9PSAiSEFJUEhPTkciICB+ICJIQUkgUEhPTkciLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm92aW5jZT09ICJCQSBSSUEtVlVORyBUQVUiIH4gICJCQSBSSUEgLSBWVU5HIFRBVSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpbmNlPT0gIkhPIENISSBNSU5IIENJVFkiIH4gIkhPIENISSBNSU5IIiAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpbmNlPT0gIkhPIENISSBNSU5IIENJVFkiIH4gIkhPIENISSBNSU5IIiAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAgcHJvdmluY2UpKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KIyBObyBWSU5IIFBIVUMsIEJBQyBOSU5ILCAgICJIVU5HIFlFTiIgLCAgIlRIQUkgQklOSCIsICJIQSBOQU0iLCAiREEgTkFORyIsICAiVklOSCBMT05HIiwgIkNBTiBUSE8iICwgICJTT0MgVFJBTkciICAgDQoNCiAgDQogIA0KI2ZpbHRlciBvbmx5IFZpZXRuYW1lc2UgcHJvdmluY2VzDQoNCnRtYXhfMjAxNSA8LSB0bWF4XzIwMTUgJT4lIGZpbHRlcihwcm92aW5jZSAlaW4lIHRlbnRpbmgkUFJPVklOQ0VfTkFNRTIpDQp1bmlxdWUodG1heF8yMDE1JHByb3ZpbmNlKQ0KZGltKHRtYXhfMjAxNSkNCm5hbWVzKHRtYXhfMjAxNSlbMV0gPC0gImxvbmdpdHVkZSIgDQoNCmBgYA0KDQoNCiMjIDIuIFN0b3JlIGFsbCB0bWF4IGZvciBlYWNoIHByb3ZpbmNlIGluIGxpc3QgTHRtYXgyMDE1DQoNCmBgYHtyfQ0KIy0tLS0tLS0tLVdvcmsgd2l0aCAxIHByb3ZpY2luZQ0KcmVxdWlyZShyZXNoYXBlMikNCg0KdW5pcXVlKHRtYXhfMjAxNSRwcm92aW5jZSkNCg0KI05vdywgc3RvcmUgdG1heCBpbiBlYWNoIHByb3ZpbmNlIGluIGEgbGlzdCwgTGlzdCB0bWF4OiBMdG1heA0KDQpmdW50bWF4IDwtIGZ1bmN0aW9uKFBSTykNCnsNCiAgVGVtcFBSTyA8LSB0bWF4XzIwMTUgJT4lIGZpbHRlcihwcm92aW5jZSA9PSBQUk8pDQogIA0KICBUZW1wUFJPICA8LSByZXNoYXBlMjo6bWVsdCggVGVtcFBSTyAsIA0KICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gYygibG9uZ2l0dWRlIiwgICJsYXRpdHVkZSIgLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGlzdHJpY3QiLCAgICJwcm92aW5jZSIpKQ0KICBUZW1wUFJPICA8LSAgVGVtcFBSTyAgJT4lIHJlbmFtZSh0bWF4ID0gdmFsdWUpDQogIFRlbXBQUk8gIDwtICBUZW1wUFJPICAlPiUgZ3JvdXBfYnkodmFyaWFibGUpICU+JQ0KICAgIHN1bW1hcmlzZSh0bWF4ID0gbWF4KHRtYXgpKQ0KICByZXR1cm4oIFRlbXBQUk8gKQ0KfQ0KDQojdGVzdCBmdW50bWF4IGZvciBIYW5vaQ0KDQpITjEgPC0gZnVudG1heCAoIkhBIE5PSSIpDQoNCiMtLS0tLS1BUFBMWSBmdW50bWF4KCkNCg0KTHRtYXgyMDE1IDwtIGxpc3QoKQ0KZm9yIChQIGluIHVuaXF1ZSh0bWF4XzIwMTUkcHJvdmluY2UpKQ0Kew0KICBMdG1heDIwMTVbW1BdXSA8LSBmdW50bWF4IChQKQ0KfQ0KICANCmBgYA0KDQoNCiMjIDMuIFN0b3JlIGFsbCBjb21wb3NpdGlvbmFsIHNwbGluZSBvdXRwdXQgaW4gbGlzdCBMdG1heDIwMTVDUw0KDQpgYGB7cn0NCiMtLS0tLS0tLS0tLS0tLS1Ob3csIGFwcGx5aW5nIGNvbXBvc2l0aW9uYWxTcGxpbmUoKSBmdW5jdGlvbg0KDQpvcmRlciA9IDQNCmRlciA9IDINCmFscGhhID0gMC4zDQoNCg0KZnVuQ1MgPC0gZnVuY3Rpb24oUFJPKQ0Kew0KICBoaXN0ZW1wdCA8LSBoaXN0KCBMdG1heDIwMTVbW1BST11dJHRtYXgsDQogICAgICAgICAgICAgICAgICN4bGFiID0gIlRtYXgiLA0KICAgICAgICAgICAgICAgICMgbWFpbiA9ICJFc3RpbWF0ZWQgaGlzdG9ncmFtIG9mIHRtYXggLSBIYW5vaSIsIA0KICAgICAgICAgICAgICAgICAjY29sID0gImJsdWUiLCBsd2QgPSAyLCANCiAgICAgICAgICAgICAgICAgYnJlYWtzID0gMzAsDQogICAgICAgICAgICAgICAgIHBsb3QgPSBGQUxTRSkgIyBJdCBkb2VzIG5vdCB3b3JrIHdpdGggNTAgYmlucw0KICAjdDogaGlzdEhOJGJyZWFrcw0KICAjZGVuc2l0eTogaGlzdEhOJGRlbnNpdHkNCiAgDQogIHRfc3RlcCA9IGRpZmYoaGlzdGVtcHQkYnJlYWtzWzE6Ml0pDQogIA0KICANCiAgIy0tLS0tVXNpbmcgZmNlbkxSRigpIGJ5IEh1b25nDQogIA0KICBrbm90cyA8LSAgaGlzdGVtcHQkYnJlYWtzWy1sZW5ndGgoIGhpc3RlbXB0JGJyZWFrcyldKzAuNQ0KICBjbHJoaXN0dGVtcHQgPC0gZmNlbkxSRihrbm90cywgICBoaXN0ZW1wdCRkZW5zaXR5ICkgI2tub3RzIGFuZCAgZXN0aW1hdGUNCiAgDQogICMtLS0tdXNpbmcgZnVuY3Rpb24gaW4gcm9iQ29tcG9zaXRpb25zDQogIHQgPC0gTlVMTA0KICBjbHJmIDwtIE5VTEwNCiAga25vdHM8LSBOVUxMDQogIA0KICBjbHJmIDwtICBjbHJoaXN0dGVtcHQkZXN0aW1hdGUNCiAgdCAgPC0gY2xyaGlzdHRlbXB0JGtub3RzDQogIGtub3RzIDwtICBzZXEobWluKEx0bWF4MjAxNVtbUFJPXV0kdG1heCksIA0KICAgICAgICAgICAgICAgIG1heChMdG1heDIwMTVbW1BST11dJHRtYXgpLCBsZW5ndGggPSAxMCkNCiAgdyA8LSByZXAoIDEvbGVuZ3RoKHQpLCBsZW5ndGgodCkpDQogIA0KICByZXR1cm4obGlzdChjbHJmPWNscmYsIHQgPSB0LCBrbm90cyA9IGtub3RzLCB3ID0gdykpDQogICNjb21wb3NpdGlvbmFsU3BsaW5lKHQsIGNscmYsIGtub3RzLCB3LCBvcmRlciwNCiAgICMgICAgICAgICAgICAgICAgICAgZGVyLCBhbHBoYSwgDQogICAgIyAgICAgICAgICAgICAgICAgIHNwbGluZS5wbG90ID0gVFJVRSwgDQogICAgICMgICAgICAgICAgICAgICAgIGJhc2lzLnBsb3QgPSBGQUxTRSkgI0RPTkUNCn0NCg0KIy0tLU5vdywgYXBwbHkgZm9yIGFsbCBwcm92aW5jZXMNCg0KTHRtYXgyMDE1Q1MgPC0gbGlzdCgpDQpmb3IgKFAgaW4gdW5pcXVlKHRtYXhfMjAxNSRwcm92aW5jZSkpDQp7DQogIEx0bWF4MjAxNUNTW1tQXV0gPC0gZnVuQ1MgKFApDQp9DQpgYGANCg0KIyMgNC4gTm93LCBwbG90IGFsbCB0aGUgc3BsaW5lIG9mIHByb3ZpbmNlcywgdXNpbmcgY29tcG9zaXRpb25hbFNwbGluZUYNCg0KUGxvdCBmb3Igb25lIHByb3ZpbmNlDQoNCmBgYHtyfQ0KUCA8LSAiRE9ORyBOQUkiDQpvcmRlciA9IDQNCmRlciA9IDINCmFscGhhID0gMC41DQpjb21wb3NpdGlvbmFsU3BsaW5lRihMdG1heDIwMTVDU1tbUF1dJHQsIA0KICAgICAgICAgICAgICAgICAgICBMdG1heDIwMTVDU1tbUF1dJGNscmYsDQogICAgICAgICAgICAgICAgICAgIEx0bWF4MjAxNUNTW1tQXV0ka25vdHMsDQogICAgICAgICAgICAgICAgICAgIEx0bWF4MjAxNUNTW1tQXV0kdywgb3JkZXIsDQogICAgICAgICAgICAgICAgICAgIGRlciwgYWxwaGEsIA0KICAgICAgICAgICAgICAgICAgICBzcGxpbmUucGxvdCA9IFRSVUUsIA0KICAgICAgICAgICAgICAgICAgICBiYXNpcy5wbG90ID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgIG5hbWVtYWluID0gUCkgI0RPTkUNCmBgYA0KDQpOb3csIHBsb3QgZm9yIGFsbCBwcm92aW5jZXMsIHVzaW5nIHRoZSBzYW1lIHNtb290aGluZyBwYXJhbWV0ZXJzLg0KDQpgYGB7cn0NCm9yZGVyID0gNA0KZGVyID0gMg0KYWxwaGEgPSAwLjUNCg0KZm9yIChQIGluIHVuaXF1ZSh0bWF4XzIwMTUkcHJvdmluY2UpKQ0Kew0KICBjb21wb3NpdGlvbmFsU3BsaW5lRihMdG1heDIwMTVDU1tbUF1dJHQsIA0KICAgICAgICAgICAgICAgICAgICBMdG1heDIwMTVDU1tbUF1dJGNscmYsDQogICAgICAgICAgICAgICAgICAgIEx0bWF4MjAxNUNTW1tQXV0ka25vdHMsDQogICAgICAgICAgICAgICAgICAgIEx0bWF4MjAxNUNTW1tQXV0kdywgb3JkZXIsDQogICAgICAgICAgICAgICAgICAgIGRlciwgYWxwaGEsIA0KICAgICAgICAgICAgICAgICAgICBzcGxpbmUucGxvdCA9IFRSVUUsIA0KICAgICAgICAgICAgICAgICAgICBiYXNpcy5wbG90ID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgIG5hbWVtYWluID0gUCkNCn0NCmBgYA0KDQo=