Milkias Z. SEMEREAB

GEOL0097-Geostatistics, University of Liège

GitHub Link

October 31, 2022


• Task 1: Structural Analysis

Before we dive into variogram and spatial modelling, we can use the EDA tools that we know already to visualize and interpret the distribution and spatial continuity of the variables (heavy metals concentration) in the X, Y and Z directions.

# distribution of Zn values through x-direction?
plot(data$logZn ~ data$x, xlab="Easting", ylab="Log-Zn concentration")
abline(lm(data$logZn ~ data$x), col="red")

Note:
- abline() = add Straight line to a an existing Plot
- lm() = fits Linear Models (e.g. linear regression)

#  distribution of Zn values through y-direction?
plot(data$logZn ~ data$y, xlab="Northing", ylab="Log-Zn concentration")
abline(lm(data$logZn ~ data$y), col="red")

# distribution of Zn values through z-direction?
plot(data$logZn ~ data$elev, xlab="Elevation", ylab="Log-Zn concentration")
abline(lm(data$logZn ~ data$elev), col="red")

Questions:

• Task 2: Introducing RGeostats

• RGeostats package:

For the variography analysis we will use the RGeostats package.RGeostats is the Geostatistical R Package developed by the Geostatistics Lab of the Geosciences Research Center of MINES ParisTech. RGeostats offers most of the famous geostatistical techniques and it is designed to tackle problems with several variables defined in a space of any dimensions. It is particularly adapted for students or researchers who want to test geostatistical procedures using R scripts. Link to RGeostats website.

To instal RGeostats package: - Install the package Rcpp (an interface between R and C++ langauges that is required when using RGeostats). It is in CRAN archieve (R’s central packages repository) and you can easily install it just by writing its name in the package window in Rstudio (like we did for corrplot and plot3D).

# Load Rgeostats package
library(RGeostats)

• Create standard database

First we need to turn our data (which is in data.frame class) into a database (DB class) using the function db.create(). Once database is created, you can Check its contents using the function print() or db.print().

We will focus on the log-transformed Zn concentrations. The same analysis can be repeated for other heavy metal concentrations (Cd, Cu, and Pb).

# create a standard DB and store it in a variable called db.data
db.data = db.create(x1=data[,1], x2=data[,2], z1=data[,17],flag.grid=FALSE)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'

Where:

Remember: Help window and help function are alaways at your disposal.

# use help() function and ? help operator to access the documentation pages for R functions
help("db.create")
?db.create
#check the content of the database you just created
class(db.data)
[1] "db"
attr(,"package")
[1] "RGeostats"
db.print(db.data)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'

Data Base Characteristics
=========================

Data Base Summary
-----------------
File is organized as a set of isolated points
Space dimension              = 2
Number of Columns            = 4
Maximum Number of UIDs       = 4
Total number of samples      = 155

Variables
---------
Column = 0 - Name = rank - Locator = NA
Column = 1 - Name = x1 - Locator = x1
Column = 2 - Name = x2 - Locator = x2
Column = 3 - Name = z1 - Locator = z1

• Graphic representation of the data (proportional representation) using the function db.plot() or plot() :

# using db.plot() function
db.plot(db.data,xlab="Easting(m)", ylab = "Northing(m)", title="LogZn concentration")


# using the usual plot() function
plot(db.data, xlab="Easting(m)", ylab = "Northing(m)", title="LogZn concentration")

Both functions produced the same plot as we did last time but using a different graphic representation.

• Task 3: Omni-Directional Variography Analysis

• Compute and plot omni-directional experimental variograms of various number of lags using functions of RGeostats package

# Define the Diagonal Geographic Domain
D = sqrt((max(data[,1])-min(data[,1]))^2 + (max(data[,2])-min(data[,2]))^2) 

# Display value of D
print(D)
[1] 4789.868

Note: lag distance should not exceed half of longest dimension in the field.

# Define number of lags. It is good practise to start with 10 lags
nlag = 10
# Compute the omni-directional experimental variogram with 10 lags using  vario.calc() function and store it in a variable called Vario_E1. 
Vario_E1 = vario.calc(db.data,nlag=nlag,lag=D/(2*nlag))
# display the variogram characteristics 
print(Vario_E1)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'

Variogram characteristics
=========================
Number of variable(s)       = 1
Number of direction(s)      = 1
Space dimension             = 2
Variance-Covariance Matrix     0.098

Direction #1
------------
Number of lags              = 10
Direction coefficients      =      1.000     0.000
Direction angles (degrees)  =      0.000     0.000
Tolerance on direction      =     90.000 (degrees)
Calculation lag             =    239.493
Tolerance on distance       =     50.000 (Percent of the lag value)

For variable 1
      Rank    Npairs  Distance     Value
         0    79.000    88.901     0.033
         1   862.000   249.508     0.052
         2  1156.000   480.023     0.091
         3  1293.000   718.387     0.113
         4  1255.000   955.540     0.126
         5  1083.000  1194.132     0.122
         6   993.000  1433.762     0.113
         7   930.000  1673.616     0.104
         8   822.000  1908.365     0.096
         9   711.000  2154.216     0.098
# Display the omni-directional experimental variogram with 10 lags using  vario.plot() function
vario.plot(Vario_E1,npairdw = 2, npairpt=1, varline =TRUE, title="Omni-directional Experimental Variogram - 10 Lags", col="blue", lty=2, xlab="Distance(m)", ylab="Variogram")

• Change the number of lags and observe what happens to the variogram

# change nlag to 20
nlag=20

# Compute the omni-directional experimental variogram with 20 lags. you can call it Vario_E2
Vario_E2=vario.calc(db.data,nlag=nlag,lag=D/(2*nlag))
# display the variogram characteristics
print(Vario_E2)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'

Variogram characteristics
=========================
Number of variable(s)       = 1
Number of direction(s)      = 1
Space dimension             = 2
Variance-Covariance Matrix     0.098

Direction #1
------------
Number of lags              = 20
Direction coefficients      =      1.000     0.000
Direction angles (degrees)  =      0.000     0.000
Tolerance on direction      =     90.000 (degrees)
Calculation lag             =    119.747
Tolerance on distance       =     50.000 (Percent of the lag value)

For variable 1
      Rank    Npairs  Distance     Value
         0     6.000    52.302     0.015
         1   244.000   132.785     0.032
         2   445.000   242.974     0.055
         3   516.000   360.886     0.075
         4   604.000   479.915     0.089
         5   598.000   599.009     0.102
         6   665.000   719.596     0.112
         7   635.000   838.913     0.125
         8   631.000   956.650     0.121
         9   578.000  1075.818     0.131
        10   556.000  1195.374     0.123
        11   505.000  1316.436     0.121
        12   512.000  1437.127     0.107
        13   460.000  1555.978     0.107
        14   471.000  1674.099     0.106
        15   467.000  1796.698     0.099
        16   415.000  1917.253     0.096
        17   356.000  2038.413     0.093
        18   334.000  2154.617     0.102
        19   322.000  2271.511     0.106
# Plot the omni-directional experimental variogram with 20 lags
vario.plot(Vario_E2,npairdw = 2,npairpt=1,varline =TRUE,title="Omni-directional Experimental Variogram - 20 Lags",col="blue",lty=2,xlab="Distance(m)", ylab="Variogram")

Questions: Which variogram should you choose? 10 lags or 20 lags?

There are no set rules for determining what lag size and number of lags should be used. It is the craft of the researcher, their knowledge of the phenomenon they are analyzing, and the reason(s) for modeling a variogram that help to determine the appropriate lag size. Consider what happens when we take lag size to its extremes:

In most cases, the goal is to have as many pairs of points as possible represented in any one variogram point. More pairs per variogram point, however, means a wider bin, and a wider lag distance typically results in less structure for the first points in a variogram.

There are two rules of thumb for selecting a lag size/lag number:

  1. Have at least 30-50 pairs minimum for any one variogram point. Smaller bins or lag size means less pairs and probably better structure, but too small a bin or lag size typically introduces more noise into the variogram.

  2. The lag size times the number of lags should be about half of the largest distance among all points (half diagonal distance). This condition taken care of by RGeostats for us. Remeber why we defined D.

  3. A variogram with as small as possible lag size is preferred so that the spatial variability in the short-range will not be smoothed.

  4. At least 3 variogram plots are needed before reaching sill (i.e. before losing spatial correlation)

• Fit automatically a variogram model on the omni-directional experimental variogram

The experimental (or observed) variograms, which represent your sample data, are then fit to each of the 3 types of variogram models within the course. This is so that the data, which were sampled at discreet units, can be modeled as a continuous function, and the value for any unknown point at any distance can be interpolated/estimated. Once the best fit has been made, you can proceed with the interpolation process by kriging methods (simple or ordinary kriging).

# Fit automatically an isotropic model on Vario_E1 using model.auto() and store the model as Vario_M1   
Vario_M1 = model.auto(Vario_E1, struct = melem.name(c(1,3)),draw=FALSE)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'
# Display model characteristics
print(Vario_M1)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'

Model characteristics
=====================
Space dimension              = 2
Number of variable(s)        = 1
Number of basic structure(s) = 2
Number of drift function(s)  = 1
Number of drift equation(s)  = 1

Covariance Part
---------------
Nugget Effect
- Sill         =      0.011
Spherical
- Sill         =      0.105
- Range        =    873.347
Total Sill     =      0.116

Drift Part
----------
Universality Condition
# plot  experimental variogram Vario_E1 (10 lags) 
vario.plot(Vario_E1, npairdw=1, npairpt=1, varline=FALSE, title="Isotropic Model (nugget effect + spherical)", reset=TRUE, col="blue", lty=2, xlab="Distance(m)",ylab="Variogram")

# display the model on top of the variogram plot
model.plot(Vario_M1 ,vario=Vario_E1,add=T,col="red")
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: Recycling array of length 1 in vector-array arithmetic is deprecated.
  Use c() or as.vector() instead.
# add legend to the plot
legend("bottomright",legend=c("Empirical Variogram","Fitted Variogram (Model)"),lty=c(2,1),cex=1, col=c("blue","red"))

Note:

# Fit an Exponential isotropic model on Vario_E1 and display model characteristics 
Vario_M2 = model.auto(Vario_E1, struct = melem.name(c(1,2)), draw=FALSE)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'
print(Vario_M2)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'

Model characteristics
=====================
Space dimension              = 2
Number of variable(s)        = 1
Number of basic structure(s) = 1
Number of drift function(s)  = 1
Number of drift equation(s)  = 1

Covariance Part
---------------
Exponential
- Sill         =      0.126
- Range        =   1258.019
- Theo. Range  =    419.937
Total Sill     =      0.126

Drift Part
----------
Universality Condition
# Fit Gaussian isotropic model on Vario_E1 and display model characteristics
Vario_M3 = model.auto(Vario_E1,struct = melem.name(c(1,4)),draw=FALSE)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'
print(Vario_M3)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'

Model characteristics
=====================
Space dimension              = 2
Number of variable(s)        = 1
Number of basic structure(s) = 2
Number of drift function(s)  = 1
Number of drift equation(s)  = 1

Covariance Part
---------------
Nugget Effect
- Sill         =      0.028
Gaussian
- Sill         =      0.088
- Range        =    753.473
- Theo. Range  =    435.328
Total Sill     =      0.116

Drift Part
----------
Universality Condition

Note: The argument struct = melem.name() controls which model to fit.

# plot experimental variogram with 10 lags (Vario_E1)
vario.plot(Vario_E1, npairdw=1, npairpt=0, varline=FALSE, title="Isotropic Models", reset=TRUE, col="blue", lty=2, xlab="Distance(m)",ylab="Variogram")

# display all the models on top of the variogram plot
model.plot(Vario_M1 ,vario=Vario_E1,add=T,col="red")
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: Recycling array of length 1 in vector-array arithmetic is deprecated.
  Use c() or as.vector() instead.
model.plot(Vario_M2 ,vario=Vario_E1,add=T,col="green")
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: Recycling array of length 1 in vector-array arithmetic is deprecated.
  Use c() or as.vector() instead.
model.plot(Vario_M3 ,vario=Vario_E1,add=T,col="black")
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: Recycling array of length 1 in vector-array arithmetic is deprecated.
  Use c() or as.vector() instead.
# add legend to the plot
legend("bottomright",legend=c("Experimental variogram", "Spherical model","Exponential model","Gaussian model"), lty=c(2,1,1,1),cex=0.8, col=c("blue", "red","green","black"))

Variogram Models:

• Task 4: Directional Variography Analysis

• Compute the experimental variogram in four directions:
- north-south Direction (90°)
- east-west Direction (0°)
- north-west South-East Direction (45°)
- north-east South-West Direction (135°)

# number of directions 
ndir=4 

# first direction
ang0=0 

# directions vector
dir_vect=((seq(1,ndir)-1) * 180 / ndir+ ang0) # or simply dir_vec = c(0,45,90,135)
print(dir_vect)
[1]   0  45  90 135
# number of lags
nlag=10
# compute directional variogram
Vario_dir=vario.calc(db.data, dirvect=dir_vect, lag=D/(2*nlag), nlag=nlag)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: Recycling array of length 1 in vector-array arithmetic is deprecated.
  Use c() or as.vector() instead.
Warning: Recycling array of length 1 in vector-array arithmetic is deprecated.
  Use c() or as.vector() instead.
Warning: Recycling array of length 1 in vector-array arithmetic is deprecated.
  Use c() or as.vector() instead.
Warning: Recycling array of length 1 in vector-array arithmetic is deprecated.
  Use c() or as.vector() instead.
# display  variogram characteristics
print(Vario_dir)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'

Variogram characteristics
=========================
Number of variable(s)       = 1
Number of direction(s)      = 4
Space dimension             = 2
Variance-Covariance Matrix     0.098

Direction #1
------------
Number of lags              = 10
Direction coefficients      =      1.000     0.000
Direction angles (degrees)  =      0.000     0.000
Tolerance on direction      =     22.500 (degrees)
Calculation lag             =    239.493
Tolerance on distance       =     50.000 (Percent of the lag value)

For variable 1
      Rank    Npairs  Distance     Value
         0    22.000    87.912     0.020
         1   200.000   248.620     0.059
         2   231.000   477.365     0.109
         3   249.000   713.427     0.135
         4   180.000   948.658     0.188
         5   131.000  1188.232     0.189
         6    62.000  1417.947     0.153
         7    27.000  1648.575     0.098
         8     6.000  1899.022     0.036

Direction #2
------------
Number of lags              = 10
Direction coefficients      =      0.707     0.707
Direction angles (degrees)  =     45.000     0.000
Tolerance on direction      =     22.500 (degrees)
Calculation lag             =    239.493
Tolerance on distance       =     50.000 (Percent of the lag value)

For variable 1
      Rank    Npairs  Distance     Value
         0    14.000    89.483     0.022
         1   254.000   246.610     0.036
         2   363.000   482.863     0.053
         3   486.000   722.335     0.076
         4   602.000   958.703     0.086
         5   622.000  1198.084     0.087
         6   660.000  1438.580     0.091
         7   676.000  1674.412     0.090
         8   638.000  1907.329     0.082
         9   561.000  2153.920     0.079

Direction #3
------------
Number of lags              = 10
Direction coefficients      =      0.000     1.000
Direction angles (degrees)  =     90.000     0.000
Tolerance on direction      =     22.500 (degrees)
Calculation lag             =    239.493
Tolerance on distance       =     50.000 (Percent of the lag value)

For variable 1
      Rank    Npairs  Distance     Value
         0    18.000    94.231     0.051
         1   229.000   254.770     0.047
         2   341.000   481.181     0.087
         3   354.000   720.277     0.117
         4   348.000   956.839     0.142
         5   288.000  1188.486     0.157
         6   249.000  1426.902     0.166
         7   210.000  1672.172     0.156
         8   170.000  1912.897     0.153
         9   147.000  2155.917     0.172

Direction #4
------------
Number of lags              = 10
Direction coefficients      =     -0.707     0.707
Direction angles (degrees)  =    135.000     0.000
Tolerance on direction      =     22.500 (degrees)
Calculation lag             =    239.493
Tolerance on distance       =     50.000 (Percent of the lag value)

For variable 1
      Rank    Npairs  Distance     Value
         0    25.000    85.607     0.038
         1   179.000   247.882     0.073
         2   221.000   476.352     0.138
         3   204.000   711.754     0.166
         4   125.000   946.607     0.183
         5    42.000  1192.718     0.203
         6    22.000  1411.434     0.090
         7    17.000  1699.572     0.041
         8     8.000  1901.688     0.051
         9     3.000  2126.160     0.093
# plot the directional variogram
vario.plot(Vario_dir, npairdw = 1, npairpt=0, varline=FALSE, title="Directional Experimental Variograms", lty=2, xlab="Distance(m)", ylab="Variogram")

# add a legend
legend("bottomright",legend=c("Direction 0°","Direction 45°","Direction 90°","Direction 135°"),lty=c(2,2,2,2),col=c(1,2,3,4), cex=0.8)

• Fit automatically anisotropic variogram model on directional experimental variograms

# fit automatically  anisotropic variogram model 
Vario_M4=model.auto(Vario_dir, struct = melem.name(c(1,2)),auth.aniso=TRUE, auth.rotation=TRUE, auth.locksame=TRUE,draw=FALSE)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'
print(Vario_M4)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'

Model characteristics
=====================
Space dimension              = 2
Number of variable(s)        = 1
Number of basic structure(s) = 2
Number of drift function(s)  = 1
Number of drift equation(s)  = 1

Covariance Part
---------------
Nugget Effect
- Sill         =      0.011
Exponential
- Sill         =      0.202
- Ranges       =   1833.689 10357.138
- Theo. Ranges =    612.100  3457.298
- Angles       =    -35.689     0.000
- Rotation Matrix
               [,  0]    [,  1]
     [  0,]     0.812     0.583
     [  1,]    -0.583     0.812
Total Sill     =      0.213

Drift Part
----------
Universality Condition
# plot the directional variogram
vario.plot(Vario_E4,npairdw=1,npairpt=0,varline =FALSE,title="Anisotropic Model",reset=TRUE,lty=2, xlab="Distance(m)",ylab="Variogram")

# plot the anisotropic variogram model
model.plot(Vario_M4 ,vario=Vario_E4,add=T)
Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: is.na() applied to non-(list or vector) of type 'S4'Warning: Recycling array of length 1 in vector-array arithmetic is deprecated.
  Use c() or as.vector() instead.
# add a legend
legend("bottomright", legend=c("Direction 0°","Direction 45°","Direction 90°","Direction 135°"), lty=c(1,1,1,1), col=c(1,2,3,4), cex=0.8)

• Questions:
- What do you observe? - What is the direction of maximum spatial continuity? - can you detect Anisotropy ?

Isotropy and Anisotropy: general speaking, the procedures of distinguishing between isotropy and anisotropy are the same. We can fit a variogram model along all the directions and then obtain different variograms along with different directions. Once we obtain the values of Still, Range, Nugget Effect from all variograms, we can determine if the spatial data is isotropic or anisotropic. If the values of Still, Range, Nugget Effect from the variogram along with all directions are all the same, then it is isotropic; otherwise, it is the anisotropic.

Anisotropy, according to its different structures, could be divided into:

Fig 1: Geometric anisotropy

Fig 2: Zonal anisotropy

Fig 3: Mixed anisotropy

LS0tDQp0aXRsZTogIkdlb3N0YXRpc3RpY3MgLSBTcGF0aWFsIENvcnJlbGF0aW9uIGFuZCBWYXJpb2dyYW1zIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KKk1pbGtpYXMgWi4gU0VNRVJFQUIqDQoNCipHRU9MMDA5Ny1HZW9zdGF0aXN0aWNzLCBVbml2ZXJzaXR5IG9mIExpw6hnZSoNCg0KKipbR2l0SHViIExpbmtdKGh0dHBzOi8vZ2l0aHViLmNvbS9taWxraWFzemVyYWkvZ2VvbC0wMDk3LWdlb3N0YXRpc3RpY3MpKioNCg0KKk9jdG9iZXIgMzEsIDIwMjIqDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQoNCiMjIyMjICoq4oCiIFRhc2sgMTogU3RydWN0dXJhbCBBbmFseXNpcyoqDQoNCkJlZm9yZSB3ZSBkaXZlIGludG8gdmFyaW9ncmFtIGFuZCBzcGF0aWFsIG1vZGVsbGluZywgd2UgY2FuIHVzZSB0aGUgRURBIHRvb2xzIHRoYXQgd2Uga25vdyBhbHJlYWR5IHRvIHZpc3VhbGl6ZSBhbmQgaW50ZXJwcmV0IHRoZSBkaXN0cmlidXRpb24gYW5kIHNwYXRpYWwgY29udGludWl0eSBvZiB0aGUgdmFyaWFibGVzIChoZWF2eSBtZXRhbHMgY29uY2VudHJhdGlvbikgaW4gdGhlIFgsIFkgYW5kIFogZGlyZWN0aW9ucy4gDQoNCmBgYHtyfQ0KIyBkaXN0cmlidXRpb24gb2YgWm4gdmFsdWVzIHRocm91Z2ggeC1kaXJlY3Rpb24/DQpwbG90KGRhdGEkbG9nWm4gfiBkYXRhJHgsIHhsYWI9IkVhc3RpbmciLCB5bGFiPSJMb2ctWm4gY29uY2VudHJhdGlvbiIpDQphYmxpbmUobG0oZGF0YSRsb2dabiB+IGRhdGEkeCksIGNvbD0icmVkIikNCmBgYA0KTm90ZTogICAgDQotIGFibGluZSgpID0gYWRkIFN0cmFpZ2h0IGxpbmUgdG8gYSBhbiBleGlzdGluZyBQbG90ICAgIA0KLSBsbSgpID0gZml0cyBMaW5lYXIgTW9kZWxzIChlLmcuIGxpbmVhciByZWdyZXNzaW9uKQ0KDQogDQpgYGB7cn0NCiMgIGRpc3RyaWJ1dGlvbiBvZiBabiB2YWx1ZXMgdGhyb3VnaCB5LWRpcmVjdGlvbj8NCnBsb3QoZGF0YSRsb2dabiB+IGRhdGEkeSwgeGxhYj0iTm9ydGhpbmciLCB5bGFiPSJMb2ctWm4gY29uY2VudHJhdGlvbiIpDQphYmxpbmUobG0oZGF0YSRsb2dabiB+IGRhdGEkeSksIGNvbD0icmVkIikNCmBgYA0KDQpgYGB7cn0NCiMgZGlzdHJpYnV0aW9uIG9mIFpuIHZhbHVlcyB0aHJvdWdoIHotZGlyZWN0aW9uPw0KcGxvdChkYXRhJGxvZ1puIH4gZGF0YSRlbGV2LCB4bGFiPSJFbGV2YXRpb24iLCB5bGFiPSJMb2ctWm4gY29uY2VudHJhdGlvbiIpDQphYmxpbmUobG0oZGF0YSRsb2dabiB+IGRhdGEkZWxldiksIGNvbD0icmVkIikNCmBgYA0KDQoqKlF1ZXN0aW9uczoqKg0KDQotIERpc2N1c3MgYWJvdXQgdGhlIGRpc3RyaWJ1dGlvbi9zcGF0aWFsIGNvbnRpbnVpdHkgb2YgWm4gdmFsdWVzIHRocm91Z2ggeCwgeSBhbmQgeiBkaXJlY3Rpb25zPw0KDQoNCiMjIyMjICoq4oCiIFRhc2sgMjogSW50cm9kdWNpbmcgUkdlb3N0YXRzKioNCg0KKirigKIgUkdlb3N0YXRzIHBhY2thZ2U6KioNCg0KRm9yIHRoZSB2YXJpb2dyYXBoeSBhbmFseXNpcyB3ZSB3aWxsIHVzZSB0aGUgKipSR2Vvc3RhdHMqKiBwYWNrYWdlLioqUkdlb3N0YXRzKiogaXMgdGhlIEdlb3N0YXRpc3RpY2FsIFIgUGFja2FnZSBkZXZlbG9wZWQgYnkgdGhlIEdlb3N0YXRpc3RpY3MgTGFiIG9mIHRoZSBHZW9zY2llbmNlcyBSZXNlYXJjaCBDZW50ZXIgb2YgTUlORVMgUGFyaXNUZWNoLiBSR2Vvc3RhdHMgb2ZmZXJzIG1vc3Qgb2YgdGhlIGZhbW91cyBnZW9zdGF0aXN0aWNhbCB0ZWNobmlxdWVzIGFuZCBpdCBpcyBkZXNpZ25lZCB0byB0YWNrbGUgcHJvYmxlbXMgd2l0aCBzZXZlcmFsIHZhcmlhYmxlcyBkZWZpbmVkIGluIGEgc3BhY2Ugb2YgYW55IGRpbWVuc2lvbnMuIEl0IGlzIHBhcnRpY3VsYXJseSBhZGFwdGVkIGZvciBzdHVkZW50cyBvciByZXNlYXJjaGVycyB3aG8gd2FudCB0byB0ZXN0IGdlb3N0YXRpc3RpY2FsIHByb2NlZHVyZXMgdXNpbmcgUiBzY3JpcHRzLiBbTGluayB0byBSR2Vvc3RhdHMgd2Vic2l0ZS5dKGh0dHA6Ly9yZ2Vvc3RhdHMuZnJlZS5mci8pDQoNCg0KVG8gaW5zdGFsIFJHZW9zdGF0cyBwYWNrYWdlOg0KLSBJbnN0YWxsIHRoZSBwYWNrYWdlIFJjcHAgKGFuIGludGVyZmFjZSBiZXR3ZWVuIFIgYW5kIEMrKyBsYW5nYXVnZXMgdGhhdCBpcyByZXF1aXJlZCB3aGVuIHVzaW5nIFJHZW9zdGF0cykuIEl0IGlzIGluIENSQU4gYXJjaGlldmUgKFIncyBjZW50cmFsIHBhY2thZ2VzIHJlcG9zaXRvcnkpIGFuZCB5b3UgY2FuIGVhc2lseSBpbnN0YWxsIGl0IGp1c3QgYnkgd3JpdGluZyBpdHMgbmFtZSBpbiB0aGUgcGFja2FnZSB3aW5kb3cgaW4gUnN0dWRpbyAobGlrZSB3ZSBkaWQgZm9yIGNvcnJwbG90IGFuZCBwbG90M0QpLiANCg0KLSBPbiB0aGUgb3RoZXIgaGFuZCwgUkdlb3N0YXRzIGlzIG5vdCB5ZXQgcHVibGlzaGVkIHRvIENSQU4gYW5kIHdlIG5lZWQgdG8gZG93bmxvYWQgYW5kIGluc3RhbGwgaXQgbWFudWFsbHkuIFtEb3dubG9hZCBSR2Vvc3RhdHMgaGVyZS5dKGh0dHA6Ly9yZ2Vvc3RhdHMuZnJlZS5mci9kb3dubG9hZC5waHApDQoNCi0gT25jZSB5b3UgZG93bmxvYWQgdGhlIHppcCBmb2xkZXIsIEluc3RhbGwgUkdlb3N0YXRzIG1hbnVhbGx5OiANCkNsaWNrIFBhY2thZ2VzIFRhYiDihpIgSW5zdGFsbCDihpIgU2VsZWN0IFBhY2thZ2UgQXJjaGl2ZSBGaWxlICguemlwLCAudGFyLmd6KSBpbiB0aGUgSW5zdGFsbCBmcm9tIHNsb3Qg4oaSIEZpbmQgdGhlIGNvcnJlc3BvbmRpbmcgemlwcGVkIGZpbGUgb24geW91ciBsb2NhbCBQQywgYW5kIGNsaWNrIE9wZW4g4oaSIENsaWNrIEluc3RhbGwNCg0KLSBZb3UgY2FuIGNoZWNrIGlmIGl0IGlzIHN1Y2Nlc3NmdWxseSBpbnN0YWxsZWQgYnkgZ29pbmcgdG8gdGhlIHBhY2thZ2VzIHdpbmRvdyBhbmQgc2VlIGlmIFJnZW9zdGF0cyBpcyBpbiB0aGUgbGlzdCBvZiBpbnN0YWxsZWQgcGFja2FnZXMuIA0KDQotIExvYWQvaW1wb3J0IFJnZW9zdGF0cyBwYWNrYWdlIGJ5IGNoZWNraW5nIHRoZSBib3ggb3IgdXNpbmcgdGhlIGxpYnJhcnkoKSBmdW5jdGlvbi4NCg0KYGBge3J9DQojIExvYWQgUmdlb3N0YXRzIHBhY2thZ2UNCmxpYnJhcnkoUkdlb3N0YXRzKQ0KYGBgDQoNCioq4oCiIENyZWF0ZSBzdGFuZGFyZCBkYXRhYmFzZSoqDQoNCkZpcnN0IHdlIG5lZWQgdG8gdHVybiBvdXIgZGF0YSAod2hpY2ggaXMgaW4gZGF0YS5mcmFtZSBjbGFzcykgaW50byBhIGRhdGFiYXNlIChEQiBjbGFzcykgdXNpbmcgdGhlIGZ1bmN0aW9uICoqZGIuY3JlYXRlKCkqKi4gT25jZSBkYXRhYmFzZSBpcyBjcmVhdGVkLCB5b3UgY2FuIENoZWNrIGl0cyBjb250ZW50cyB1c2luZyB0aGUgZnVuY3Rpb24gcHJpbnQoKSBvciBkYi5wcmludCgpLg0KDQpXZSB3aWxsIGZvY3VzIG9uIHRoZSBsb2ctdHJhbnNmb3JtZWQgWm4gY29uY2VudHJhdGlvbnMuIFRoZSBzYW1lIGFuYWx5c2lzIGNhbiBiZSByZXBlYXRlZCBmb3Igb3RoZXIgaGVhdnkgbWV0YWwgY29uY2VudHJhdGlvbnMgKENkLCBDdSwgYW5kIFBiKS4NCg0KYGBge3J9IA0KIyBjcmVhdGUgYSBzdGFuZGFyZCBEQiBhbmQgc3RvcmUgaXQgaW4gYSB2YXJpYWJsZSBjYWxsZWQgZGIuZGF0YQ0KZGIuZGF0YSA9IGRiLmNyZWF0ZSh4MT1kYXRhWywxXSwgeDI9ZGF0YVssMl0sIHoxPWRhdGFbLDE3XSxmbGFnLmdyaWQ9RkFMU0UpDQoNCmBgYA0KV2hlcmU6ICAgDQoNCi0geDE9ZGF0YVssMV0gaXMgRWFzdGluZyAobSkgDQotIHgyPWRhdGFbLDJdIGlzIE5vcnRoaW5nIChtKQ0KLSB6MT1kYXRhWywxN10gaXMgTG9nWm4gY29uY2VudHJhdGlvbiB2YWx1ZXMgKHBwbSkNCg0KUmVtZW1iZXI6IEhlbHAgd2luZG93IGFuZCBoZWxwIGZ1bmN0aW9uIGFyZSBhbGF3YXlzIGF0IHlvdXIgZGlzcG9zYWwuIA0KDQpgYGB7cn0NCiMgdXNlIGhlbHAoKSBmdW5jdGlvbiBhbmQgPyBoZWxwIG9wZXJhdG9yIHRvIGFjY2VzcyB0aGUgZG9jdW1lbnRhdGlvbiBwYWdlcyBmb3IgUiBmdW5jdGlvbnMNCmhlbHAoImRiLmNyZWF0ZSIpDQo/ZGIuY3JlYXRlDQpgYGANCg0KDQpgYGB7cn0NCiNjaGVjayB0aGUgY29udGVudCBvZiB0aGUgZGF0YWJhc2UgeW91IGp1c3QgY3JlYXRlZA0KY2xhc3MoZGIuZGF0YSkNCmRiLnByaW50KGRiLmRhdGEpDQpgYGANCi0gVGhlIGZpcnN0IGNvbHVtbiBpbiB0aGUgZGF0YWJhc2UgaXMgYSByYW5raW5nIGNvbHVtbiB3aGljaCBjb250YWlucyB0aGUgdmFsdWUgdGhhdCBpcyB0aGUgcmFuayBvZiB0aGUgcGFydGljdWxhciBkYXRhIHBvaW50IHdoZXJlIDEgaXMgYXNzaWduZWQgdG8gdGhlIGZpcnN0IGRhdGEgcG9pbnQgYW5kIDE1NSBpcyBhc3NpZ25lZCB0byB0aGUgaGlnaGVzdCBkYXRhIHBvaW50Lg0KDQotIFNlY29uZCBhbmQgdGhpcmQgY29sdW1ucyBhcmUgcmVsYXRlZCB0byB0aGUgc3BhdGlhbCBpbmZvcm1hdGlvbiBvZiB0aGUgc2FtcGxlcyAoZWFzdGluZyBhbmQgbm9ydGhpbmcpIA0KDQotIFRoZSB0aGlyZCBjb3JyZXNwb25kcyB0byB0aGUgYXR0cmlidXRlIGJlaW5nIGFuYWx5emVkIChsb2dabikuIA0KDQoqKuKAoiBHcmFwaGljIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkYXRhIChwcm9wb3J0aW9uYWwgcmVwcmVzZW50YXRpb24pIHVzaW5nIHRoZSBmdW5jdGlvbiBkYi5wbG90KCkgb3IgcGxvdCgpIDoqKg0KDQpgYGB7cn0NCiMgdXNpbmcgZGIucGxvdCgpIGZ1bmN0aW9uDQpkYi5wbG90KGRiLmRhdGEseGxhYj0iRWFzdGluZyhtKSIsIHlsYWIgPSAiTm9ydGhpbmcobSkiLCB0aXRsZT0iTG9nWm4gY29uY2VudHJhdGlvbiIpDQoNCiMgdXNpbmcgdGhlIHVzdWFsIHBsb3QoKSBmdW5jdGlvbg0KcGxvdChkYi5kYXRhLCB4bGFiPSJFYXN0aW5nKG0pIiwgeWxhYiA9ICJOb3J0aGluZyhtKSIsIHRpdGxlPSJMb2dabiBjb25jZW50cmF0aW9uIikNCmBgYA0KDQpCb3RoIGZ1bmN0aW9ucyBwcm9kdWNlZCB0aGUgc2FtZSBwbG90IGFzIHdlIGRpZCBsYXN0IHRpbWUgYnV0IHVzaW5nIGEgZGlmZmVyZW50IA0KZ3JhcGhpYyByZXByZXNlbnRhdGlvbi4gDQoNCg0KIyMjIyMgKirigKIgVGFzayAzOiBPbW5pLURpcmVjdGlvbmFsIFZhcmlvZ3JhcGh5IEFuYWx5c2lzKioNCg0KKirigKIgQ29tcHV0ZSBhbmQgcGxvdCBvbW5pLWRpcmVjdGlvbmFsIGV4cGVyaW1lbnRhbCB2YXJpb2dyYW1zIG9mIHZhcmlvdXMgbnVtYmVyIG9mIGxhZ3MgdXNpbmcgZnVuY3Rpb25zIG9mIFJHZW9zdGF0cyBwYWNrYWdlKioNCg0KYGBge3J9DQojIERlZmluZSB0aGUgRGlhZ29uYWwgR2VvZ3JhcGhpYyBEb21haW4NCkQ9c3FydCgobWF4KGRhdGFbLDFdKS1taW4oZGF0YVssMV0pKV4yICsgKG1heChkYXRhWywyXSktbWluKGRhdGFbLDJdKSleMikgDQoNCiMgRGlzcGxheSB2YWx1ZSBvZiBEDQpwcmludChEKQ0KYGBgDQoqKk5vdGU6KiogbGFnIGRpc3RhbmNlIHNob3VsZCBub3QgZXhjZWVkIGhhbGYgb2YgbG9uZ2VzdCBkaW1lbnNpb24gaW4gdGhlIGZpZWxkLg0KDQpgYGB7cn0NCiMgRGVmaW5lIG51bWJlciBvZiBsYWdzLiBJdCBpcyBnb29kIHByYWN0aXNlIHRvIHN0YXJ0IHdpdGggMTAgbGFncw0KbmxhZz0xMA0KYGBgDQoNCmBgYHtyfQ0KIyBDb21wdXRlIHRoZSBvbW5pLWRpcmVjdGlvbmFsIGV4cGVyaW1lbnRhbCB2YXJpb2dyYW0gd2l0aCAxMCBsYWdzIHVzaW5nICB2YXJpby5jYWxjKCkgZnVuY3Rpb24gYW5kIHN0b3JlIGl0IGluIGEgdmFyaWFibGUgY2FsbGVkIFZhcmlvX0UxLiANClZhcmlvX0UxID0gdmFyaW8uY2FsYyhkYi5kYXRhLG5sYWc9bmxhZyxsYWc9RC8oMipubGFnKSkNCmBgYA0KDQpgYGB7cn0NCiMgZGlzcGxheSB0aGUgdmFyaW9ncmFtIGNoYXJhY3RlcmlzdGljcyANCnByaW50KFZhcmlvX0UxKQ0KYGBgDQoNCmBgYHtyfQ0KIyBQbG90IHRoZSBvbW5pLWRpcmVjdGlvbmFsIGV4cGVyaW1lbnRhbCB2YXJpb2dyYW0gd2l0aCAxMCBsYWdzIHVzaW5nICB2YXJpby5wbG90KCkgZnVuY3Rpb24NCnZhcmlvLnBsb3QoVmFyaW9fRTEsbnBhaXJkdyA9IDIsIG5wYWlycHQ9MSwgdmFybGluZSA9VFJVRSwgdGl0bGU9Ik9tbmktZGlyZWN0aW9uYWwgRXhwZXJpbWVudGFsIFZhcmlvZ3JhbSAtIDEwIExhZ3MiLCBjb2w9ImJsdWUiLCBsdHk9MiwgeGxhYj0iRGlzdGFuY2UobSkiLCB5bGFiPSJWYXJpb2dyYW0iKQ0KYGBgDQoNCioq4oCiIENoYW5nZSB0aGUgbnVtYmVyIG9mIGxhZ3MgYW5kIG9ic2VydmUgd2hhdCBoYXBwZW5zIHRvIHRoZSB2YXJpb2dyYW0qKg0KDQpgYGB7cn0NCiMgY2hhbmdlIG5sYWcgdG8gMjANCm5sYWc9MjANCg0KIyBDb21wdXRlIHRoZSBvbW5pLWRpcmVjdGlvbmFsIGV4cGVyaW1lbnRhbCB2YXJpb2dyYW0gd2l0aCAyMCBsYWdzLiB5b3UgY2FuIGNhbGwgaXQgVmFyaW9fRTINClZhcmlvX0UyPXZhcmlvLmNhbGMoZGIuZGF0YSxubGFnPW5sYWcsbGFnPUQvKDIqbmxhZykpDQpgYGANCg0KYGBge3J9DQojIGRpc3BsYXkgdGhlIHZhcmlvZ3JhbSBjaGFyYWN0ZXJpc3RpY3MNCnByaW50KFZhcmlvX0UyKQ0KYGBgDQoNCmBgYHtyfQ0KIyBQbG90IHRoZSBvbW5pLWRpcmVjdGlvbmFsIGV4cGVyaW1lbnRhbCB2YXJpb2dyYW0gd2l0aCAyMCBsYWdzDQp2YXJpby5wbG90KFZhcmlvX0UyLG5wYWlyZHcgPSAyLG5wYWlycHQ9MSx2YXJsaW5lID1UUlVFLHRpdGxlPSJPbW5pLWRpcmVjdGlvbmFsIEV4cGVyaW1lbnRhbCBWYXJpb2dyYW0gLSAyMCBMYWdzIixjb2w9ImJsdWUiLGx0eT0yLHhsYWI9IkRpc3RhbmNlKG0pIiwgeWxhYj0iVmFyaW9ncmFtIikNCmBgYA0KDQoqKlF1ZXN0aW9uczoqKiBXaGljaCB2YXJpb2dyYW0gc2hvdWxkIHlvdSBjaG9vc2U/IDEwIGxhZ3Mgb3IgMjAgbGFncz8NCg0KDQpUaGVyZSBhcmUgbm8gc2V0IHJ1bGVzIGZvciBkZXRlcm1pbmluZyB3aGF0IGxhZyBzaXplIGFuZCBudW1iZXIgb2YgbGFncyBzaG91bGQgYmUgdXNlZC4gSXQgaXMgdGhlIGNyYWZ0IG9mIHRoZSByZXNlYXJjaGVyLCB0aGVpciBrbm93bGVkZ2Ugb2YgdGhlIHBoZW5vbWVub24gdGhleSBhcmUgYW5hbHl6aW5nLCBhbmQgdGhlIHJlYXNvbihzKSBmb3IgbW9kZWxpbmcgYSB2YXJpb2dyYW0gdGhhdCBoZWxwIHRvIGRldGVybWluZSB0aGUgYXBwcm9wcmlhdGUgbGFnIHNpemUuIENvbnNpZGVyIHdoYXQgaGFwcGVucyB3aGVuIHdlIHRha2UgbGFnIHNpemUgdG8gaXRzIGV4dHJlbWVzOiANCg0KLSBBIGxhZyBzaXplID0gMCB3aWxsIHByb2R1Y2UgYSB2YXJpb2dyYW0gY2xvdWQgdGhhdCBwZXJmZWN0bHkgZGlzcGxheXMgYWxsIHBvc3NpYmxlIHBhaXJpbmdzLCBidXQgbWFrZXMgaW50ZXJwcmV0YXRpb24gb2YgdGhlIHZhcmlvZ3JhbSBzdHJ1Y3R1cmUgZGlmZmljdWx0LiAgICANCg0KLSBBdCBhIGxhZyBzaXplID0gaW5maW5pdHkgKG9yIGEgZGlzdGFuY2UgYXQgbGVhc3QgYXMgbGFyZ2UgYXMgdGhlIG1heGltdW0gZGlzdGFuY2UgYmV0d2VlbiBhbnkgdHdvIHNhbXBsZXMpLCB3ZSBnZXQgb25lIHZhbHVlIHJlcHJlc2VudGVkIGJ5IGEgc2luZ2xlIHBvaW50IHRoYXQgcmVwcmVzZW50cyB0aGUgYXZlcmFnZSBkaXN0YW5jZSBhbmQgYXZlcmFnZSB2YXJpb2dyYW0gdmFsdWUgZm9yIGFsbCBzYW1wbGUgcGFpcmluZ3MuICANCi0gU2VsZWN0aW5nIGFuIGFwcHJvcHJpYXRlIGxhZyBzaXplIGJldHdlZW4gdGhlc2UgZXh0cmVtZXMgYWxsb3dzIGZvciB0aGUgY3JlYXRpb24gb2YgYSBtYW5hZ2VhYmxlIHNlbWl2YXJpb2dyYW0gdG8gYWlkIGluIGludGVycHJldGF0aW9uLg0KDQpJbiBtb3N0IGNhc2VzLCB0aGUgZ29hbCBpcyB0byBoYXZlIGFzIG1hbnkgcGFpcnMgb2YgcG9pbnRzIGFzIHBvc3NpYmxlIHJlcHJlc2VudGVkIGluIGFueSBvbmUgdmFyaW9ncmFtIHBvaW50LiBNb3JlIHBhaXJzIHBlciB2YXJpb2dyYW0gcG9pbnQsIGhvd2V2ZXIsIG1lYW5zIGEgd2lkZXIgYmluLCBhbmQgYSB3aWRlciBsYWcgZGlzdGFuY2UgdHlwaWNhbGx5IHJlc3VsdHMgaW4gbGVzcyBzdHJ1Y3R1cmUgZm9yIHRoZSBmaXJzdCBwb2ludHMgaW4gYSB2YXJpb2dyYW0uDQoNClRoZXJlIGFyZSB0d28gcnVsZXMgb2YgdGh1bWIgZm9yIHNlbGVjdGluZyBhIGxhZyBzaXplL2xhZyBudW1iZXI6ICAgIA0KDQoxLiBIYXZlIGF0IGxlYXN0IDMwLTUwIHBhaXJzIG1pbmltdW0gZm9yIGFueSBvbmUgdmFyaW9ncmFtIHBvaW50LiBTbWFsbGVyIGJpbnMgb3IgbGFnIHNpemUgbWVhbnMgbGVzcyBwYWlycyBhbmQgcHJvYmFibHkgYmV0dGVyIHN0cnVjdHVyZSwgYnV0IHRvbyBzbWFsbCBhIGJpbiBvciBsYWcgc2l6ZSB0eXBpY2FsbHkgaW50cm9kdWNlcyBtb3JlIG5vaXNlIGludG8gdGhlIHZhcmlvZ3JhbS4gICANCg0KMi4gVGhlIGxhZyBzaXplIHRpbWVzIHRoZSBudW1iZXIgb2YgbGFncyBzaG91bGQgYmUgYWJvdXQgaGFsZiBvZiB0aGUgbGFyZ2VzdCBkaXN0YW5jZSBhbW9uZyBhbGwgcG9pbnRzIChoYWxmIGRpYWdvbmFsIGRpc3RhbmNlKS4gVGhpcyBjb25kaXRpb24gdGFrZW4gY2FyZSBvZiBieSBSR2Vvc3RhdHMgZm9yIHVzLiBSZW1lYmVyIHdoeSB3ZSBkZWZpbmVkIEQuICAgICAgDQoNCjMuIEEgdmFyaW9ncmFtIHdpdGggYXMgc21hbGwgYXMgcG9zc2libGUgbGFnIHNpemUgaXMgcHJlZmVycmVkIHNvIHRoYXQgdGhlIHNwYXRpYWwgdmFyaWFiaWxpdHkgaW4gdGhlIHNob3J0LXJhbmdlIHdpbGwgbm90IGJlIHNtb290aGVkLiAgICAgICAgICAgICANCg0KNC4gQXQgbGVhc3QgMyB2YXJpb2dyYW0gcGxvdHMgYXJlIG5lZWRlZCBiZWZvcmUgcmVhY2hpbmcgc2lsbCAoaS5lLiBiZWZvcmUgbG9zaW5nIHNwYXRpYWwgY29ycmVsYXRpb24pIA0KDQoNCioq4oCiIEZpdCBhdXRvbWF0aWNhbGx5IGEgdmFyaW9ncmFtIG1vZGVsIG9uIHRoZSBvbW5pLWRpcmVjdGlvbmFsIGV4cGVyaW1lbnRhbCB2YXJpb2dyYW0qKg0KDQpUaGUgZXhwZXJpbWVudGFsIChvciBvYnNlcnZlZCkgdmFyaW9ncmFtcywgd2hpY2ggcmVwcmVzZW50IHlvdXIgc2FtcGxlIGRhdGEsIGFyZSB0aGVuIGZpdCB0byBlYWNoIG9mIHRoZSAzIHR5cGVzIG9mIHZhcmlvZ3JhbSBtb2RlbHMgd2l0aGluIHRoZSBjb3Vyc2UuIFRoaXMgaXMgc28gdGhhdCB0aGUgZGF0YSwgd2hpY2ggd2VyZSBzYW1wbGVkIGF0IGRpc2NyZWV0IHVuaXRzLCBjYW4gYmUgbW9kZWxlZCBhcyBhIGNvbnRpbnVvdXMgZnVuY3Rpb24sIGFuZCB0aGUgdmFsdWUgZm9yIGFueSB1bmtub3duIHBvaW50IGF0IGFueSBkaXN0YW5jZSBjYW4gYmUgaW50ZXJwb2xhdGVkL2VzdGltYXRlZC4gIE9uY2UgdGhlIGJlc3QgZml0IGhhcyBiZWVuIG1hZGUsIHlvdSBjYW4gcHJvY2VlZCB3aXRoIHRoZSBpbnRlcnBvbGF0aW9uIHByb2Nlc3MgYnkga3JpZ2luZyBtZXRob2RzIChzaW1wbGUgb3Igb3JkaW5hcnkga3JpZ2luZykuIA0KDQpgYGB7cn0NCiMgRml0IGF1dG9tYXRpY2FsbHkgYW4gaXNvdHJvcGljIG1vZGVsIG9uIFZhcmlvX0UxIHVzaW5nIG1vZGVsLmF1dG8oKSBhbmQgc3RvcmUgdGhlIG1vZGVsIGFzIFZhcmlvX00xICAgDQpWYXJpb19NMSA9IG1vZGVsLmF1dG8oVmFyaW9fRTEsIHN0cnVjdCA9IG1lbGVtLm5hbWUoYygxLDMpKSxkcmF3PUZBTFNFKQ0KYGBgDQpgYGB7cn0NCiMgRGlzcGxheSBtb2RlbCBjaGFyYWN0ZXJpc3RpY3MNCnByaW50KFZhcmlvX00xKQ0KYGBgDQoNCmBgYHtyfQ0KIyBwbG90ICBleHBlcmltZW50YWwgdmFyaW9ncmFtIFZhcmlvX0UxICgxMCBsYWdzKSANCnZhcmlvLnBsb3QoVmFyaW9fRTEsIG5wYWlyZHc9MSwgbnBhaXJwdD0xLCB2YXJsaW5lPUZBTFNFLCB0aXRsZT0iSXNvdHJvcGljIE1vZGVsIChudWdnZXQgZWZmZWN0ICsgc3BoZXJpY2FsKSIsIHJlc2V0PVRSVUUsIGNvbD0iYmx1ZSIsIGx0eT0yLCB4bGFiPSJEaXN0YW5jZShtKSIseWxhYj0iVmFyaW9ncmFtIikNCg0KIyBkaXNwbGF5IHRoZSBtb2RlbCBvbiB0b3Agb2YgdGhlIHZhcmlvZ3JhbSBwbG90DQptb2RlbC5wbG90KFZhcmlvX00xICx2YXJpbz1WYXJpb19FMSxhZGQ9VCxjb2w9InJlZCIpDQoNCiMgYWRkIGxlZ2VuZCB0byB0aGUgcGxvdA0KbGVnZW5kKCJib3R0b21yaWdodCIsbGVnZW5kPWMoIkVtcGlyaWNhbCBWYXJpb2dyYW0iLCJGaXR0ZWQgVmFyaW9ncmFtIChNb2RlbCkiKSxsdHk9YygyLDEpLGNleD0xLCBjb2w9YygiYmx1ZSIsInJlZCIpKQ0KDQpgYGANCioqTm90ZToqKg0KDQotIFRoZSBudWdnZXQgaXMgdGhlIHZhcmlhbmNlIGJldHdlZW4gdmVyeSBjbG9zZSBvYnNlcnZhdGlvbnMuIA0KLSBUaGUgcmFuZ2UgaXMgODczIG1ldGVycyBpbiB0aGUgYWJvdmUgdmFyaW9ncmFtLiBJdCBpbmRpY2F0ZXMgdGhlIGRpc3RhbmNlIGFmdGVyIHdoaWNoIG9ic2VydmF0aW9ucyBhcmUgaW5kZXBlbmRlbnQgLiBBdCB0aGlzIGRpc3RhbmNlLCB0aGVyZSBpcyBtYXhpbWFsIHZhcmlhbmNlIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSBzaWxsLiANCi0gSGVyZSwgYSBjb21iaW5lZCBtb2RlbCAodG90YWwgc2lsbD0wLjExNikgd2l0aCBhIG51Z2dldCBlZmZlY3QgbW9kZWwgKHNpbGw9MC4wMTEpIGFuZCBhbiBzcGhlcmljYWwgbW9kZWwgKHNpbGw9MC4xMDUpIGlzIGZpdHRlZCB0byB0aGUgZXhwZXJpbWVudGFsIHZhcmlvZ3JhbS4gVGhlIG1vZGVsIGNhbiBiZSByYWdhcmRlZCBhcyBhIHRoZW9yZXRpY2FsIHZhcmlvZ3JhbSAgd2hpY2ggcHJvdmlkZXMgYSBzbW9vdGggdmFyaWF0aW9uIG9mIHNwYXRpYWwgdmFyaWFuY2UgYXMgYSBmdW5jdGlvbiBvZiBkaXN0YW5jZSBiZXR3ZWVuIHNwYXRpYWwgbG9jYXRpb25zLiANCiAgICANCmBgYHtyfQ0KIyBGaXQgYW4gRXhwb25lbnRpYWwgaXNvdHJvcGljIG1vZGVsIG9uIFZhcmlvX0UxIGFuZCBkaXNwbGF5IG1vZGVsIGNoYXJhY3RlcmlzdGljcyANClZhcmlvX00yID0gbW9kZWwuYXV0byhWYXJpb19FMSwgc3RydWN0ID0gbWVsZW0ubmFtZShjKDEsMikpLCBkcmF3PUZBTFNFKQ0KcHJpbnQoVmFyaW9fTTIpDQpgYGANCg0KYGBge3J9DQojIEZpdCBHYXVzc2lhbiBpc290cm9waWMgbW9kZWwgb24gVmFyaW9fRTEgYW5kIGRpc3BsYXkgbW9kZWwgY2hhcmFjdGVyaXN0aWNzDQpWYXJpb19NMyA9IG1vZGVsLmF1dG8oVmFyaW9fRTEsc3RydWN0ID0gbWVsZW0ubmFtZShjKDEsNCkpLGRyYXc9RkFMU0UpDQpwcmludChWYXJpb19NMykNCmBgYA0KKipOb3RlOioqIFRoZSBhcmd1bWVudCAqc3RydWN0ID0gbWVsZW0ubmFtZSgpKiBjb250cm9scyB3aGljaCBtb2RlbCB0byBmaXQuICAgDQoNCi0gc3RydWN0ID0gbWVsZW0ubmFtZShjKDEsMikgZml0cyBjb21iaW5hdGlvbiBvZiBudWdnZXQgZWZmZWN0IGFuZCBleHBvbmVudGlhbCBtb2RlbHMuDQoNCi0gc3RydWN0ID0gbWVsZW0ubmFtZShjKDEsMykgZml0cyBjb21iaW5hdGlvbiBvZiBudWdnZXQgZWZmZWN0IGFuZCBzcGhlcmljYWwgbW9kZWxzLiAgICANCi0gc3RydWN0ID0gbWVsZW0ubmFtZShjKDEsNCkgZml0cyBjb21iaW5hdGlvbiBvZiBudWdnZXQgZWZmZWN0IGFuZCBnYXVzc2lhbiBtb2RlbHMuDQoNCg0KYGBge3J9DQojIHBsb3QgZXhwZXJpbWVudGFsIHZhcmlvZ3JhbSB3aXRoIDEwIGxhZ3MgKFZhcmlvX0UxKQ0KdmFyaW8ucGxvdChWYXJpb19FMSwgbnBhaXJkdz0xLCBucGFpcnB0PTAsIHZhcmxpbmU9RkFMU0UsIHRpdGxlPSJJc290cm9waWMgTW9kZWxzIiwgcmVzZXQ9VFJVRSwgY29sPSJibHVlIiwgbHR5PTIsIHhsYWI9IkRpc3RhbmNlKG0pIix5bGFiPSJWYXJpb2dyYW0iKQ0KDQojIGRpc3BsYXkgYWxsIHRoZSBtb2RlbHMgb24gdG9wIG9mIHRoZSB2YXJpb2dyYW0gcGxvdA0KbW9kZWwucGxvdChWYXJpb19NMSAsdmFyaW89VmFyaW9fRTEsYWRkPVQsY29sPSJyZWQiKQ0KbW9kZWwucGxvdChWYXJpb19NMiAsdmFyaW89VmFyaW9fRTEsYWRkPVQsY29sPSJncmVlbiIpDQptb2RlbC5wbG90KFZhcmlvX00zICx2YXJpbz1WYXJpb19FMSxhZGQ9VCxjb2w9ImJsYWNrIikNCg0KIyBhZGQgbGVnZW5kIHRvIHRoZSBwbG90DQpsZWdlbmQoImJvdHRvbXJpZ2h0IixsZWdlbmQ9YygiRXhwZXJpbWVudGFsIHZhcmlvZ3JhbSIsICJTcGhlcmljYWwgbW9kZWwiLCJFeHBvbmVudGlhbCBtb2RlbCIsIkdhdXNzaWFuIG1vZGVsIiksIGx0eT1jKDIsMSwxLDEpLGNleD0wLjgsIGNvbD1jKCJibHVlIiwgInJlZCIsImdyZWVuIiwiYmxhY2siKSkNCmBgYA0KICAgIA0KICAgIA0KKipWYXJpb2dyYW0gTW9kZWxzOioqICAgIA0KDQotIFNwaGVyaWNhbCBNb2RlbHM6ICBUaGUgbW9zdCBjb21tb25seSB1c2VkIG1vZGVsLCB3aXRoIGEgc29tZXdoYXQgbGluZWFyIGJlaGF2aW9yIGF0IHNtYWxsIHNlcGFyYXRpb24gZGlzdGFuY2VzIG5lYXIgdGhlIG9yaWdpbiwgYnV0IGZsYXR0ZW5pbmcgb3V0IGF0IGxhcmdlciBkaXN0YW5jZXMgYW5kIHJlYWNoaW5nIGEgc2lsbCBsaW1pdC4gIA0KDQotIEV4cG9uZW50aWFsIE1vZGVsczogIFJlYWNoIHRoZSBzaWxsIGFzeW1wdG90aWNhbGx5LiBMaWtlIHRoZSBzcGhlcmljYWwgbW9kZWwsIHRoZSBleHBvbmVudGlhbCBtb2RlbCBpcyBsaW5lYXIgYXQgc21hbGwgZGlzdGFuY2VzIG5lYXIgdGhlIG9yaWdpbiwgeWV0IHJpc2VzIG1vcmUgc3RlZXBseSBhbmQgZmxhdHRlbnMgb3V0IG1vcmUgZ3JhZHVhbGx5LiAgRXJyYXRpYyBkYXRhIHNldHMgY2FuIHNvbWV0aW1lcyBiZSBmaXQgYmV0dGVyIHdpdGggZXhwb25lbnRpYWwgbW9kZWxzLg0KDQotIEdhdXNzaWFuIE1vZGVsczogIENoYXJhY3Rlcml6ZWQgYnkgcGFyYWJvbGljIGJlaGF2aW9yIGF0IHRoZSBvcmlnaW4sIHRoZW4gcmlzaW5nIHRvIHJlYWNoIGl0cyBzaWxsIGFzeW1wdG90aWNhbGx5LiAgVGhpcyBtb2RlbCBpcyB1c2VkIHRvIG1vZGVsIGV4dHJlbWVseSBjb250aW51b3VzIHBoZW5vbWVuYS4gDQoNCi0gTnVnZ2V0IEVmZmVjdDogIEluIG1vZGVscyB3aXRoIHRoZSBudWdnZXQgZWZmZWN0LCB0aGUgdmFyaWFuY2UgZG9lcyBub3QgZ28gdGhyb3VnaCB0aGUgb3JpZ2luIG9mIHRoZSBwbG90LCBpbmRpY2F0aW5nIHRoYXQgZXZlbiBhdCB2ZXJ5IGNsb3NlIGRpc3RhbmNlcyAoaW5kZWVkLCBldmVuIGF0IGEgZGlzdGFuY2Ugb2YgemVybykgdGhlIGRhdGEgcG9pbnRzIHNob3cgc29tZSBkZWdyZWUgb2YgdmFyaWFiaWxpdHkuIFRoaXMgY2FuIGhhcHBlbiAgd2hlbiBjaGFuZ2Ugb2NjdXJzIG92ZXIgdGhlIHN1cmZhY2UgYXQgZGlzdGFuY2VzIGxlc3MgdGhhbiB0aGUgc2FtcGxpbmcgaW50ZXJ2YWwuIA0KDQoNCiMjIyMjICoq4oCiIFRhc2sgNDogRGlyZWN0aW9uYWwgVmFyaW9ncmFwaHkgQW5hbHlzaXMqKg0KDQoqKuKAoiBDb21wdXRlIHRoZSBleHBlcmltZW50YWwgdmFyaW9ncmFtIGluIGZvdXIgZGlyZWN0aW9uczoqKiAgICANCi0gbm9ydGgtc291dGggRGlyZWN0aW9uICg5MMKwKSAgIA0KLSBlYXN0LXdlc3QgRGlyZWN0aW9uICgwwrApICAgDQotIG5vcnRoLXdlc3QgU291dGgtRWFzdCBEaXJlY3Rpb24gKDQ1wrApICAgIA0KLSBub3J0aC1lYXN0IFNvdXRoLVdlc3QgRGlyZWN0aW9uICgxMzXCsCkNCg0KDQpgYGB7cn0NCiMgbnVtYmVyIG9mIGRpcmVjdGlvbnMgDQpuZGlyPTQgDQoNCiMgZmlyc3QgZGlyZWN0aW9uDQphbmcwPTAgDQoNCiMgZGlyZWN0aW9ucyB2ZWN0b3INCmRpcl92ZWN0PSgoc2VxKDEsbmRpciktMSkgKiAxODAgLyBuZGlyKyBhbmcwKSAjIG9yIHNpbXBseSBkaXJfdmVjID0gYygwLDQ1LDkwLDEzNSkNCnByaW50KGRpcl92ZWN0KQ0KDQojIG51bWJlciBvZiBsYWdzDQpubGFnPTEwDQpgYGANCg0KYGBge3J9DQojIGNvbXB1dGUgZGlyZWN0aW9uYWwgdmFyaW9ncmFtDQpWYXJpb19kaXI9dmFyaW8uY2FsYyhkYi5kYXRhLCBkaXJ2ZWN0PWRpcl92ZWN0LCBsYWc9RC8oMipubGFnKSwgbmxhZz1ubGFnKQ0KYGBgDQoNCmBgYHtyfQ0KIyBkaXNwbGF5ICB2YXJpb2dyYW0gY2hhcmFjdGVyaXN0aWNzDQpwcmludChWYXJpb19kaXIpDQpgYGANCg0KDQpgYGB7cn0NCiMgcGxvdCB0aGUgZGlyZWN0aW9uYWwgdmFyaW9ncmFtDQp2YXJpby5wbG90KFZhcmlvX2RpciwgbnBhaXJkdyA9IDEsIG5wYWlycHQ9MCwgdmFybGluZT1GQUxTRSwgdGl0bGU9IkRpcmVjdGlvbmFsIEV4cGVyaW1lbnRhbCBWYXJpb2dyYW1zIiwgbHR5PTIsIHhsYWI9IkRpc3RhbmNlKG0pIiwgeWxhYj0iVmFyaW9ncmFtIikNCg0KIyBhZGQgYSBsZWdlbmQNCmxlZ2VuZCgiYm90dG9tcmlnaHQiLGxlZ2VuZD1jKCJEaXJlY3Rpb24gMMKwIiwiRGlyZWN0aW9uIDQ1wrAiLCJEaXJlY3Rpb24gOTDCsCIsIkRpcmVjdGlvbiAxMzXCsCIpLGx0eT1jKDIsMiwyLDIpLGNvbD1jKDEsMiwzLDQpLCBjZXg9MC44KQ0KYGBgDQoNCioq4oCiIEZpdCBhdXRvbWF0aWNhbGx5IGFuaXNvdHJvcGljIHZhcmlvZ3JhbSBtb2RlbCBvbiBkaXJlY3Rpb25hbCBleHBlcmltZW50YWwgdmFyaW9ncmFtcyoqDQoNCmBgYHtyfQ0KIyBmaXQgYXV0b21hdGljYWxseSAgYW5pc290cm9waWMgdmFyaW9ncmFtIG1vZGVsIA0KVmFyaW9fTTQ9bW9kZWwuYXV0byhWYXJpb19kaXIsIHN0cnVjdCA9IG1lbGVtLm5hbWUoYygxLDIpKSxhdXRoLmFuaXNvPVRSVUUsIGF1dGgucm90YXRpb249VFJVRSwgYXV0aC5sb2Nrc2FtZT1UUlVFLGRyYXc9RkFMU0UpDQoNCnByaW50KFZhcmlvX000KQ0KDQojIHBsb3QgdGhlIGRpcmVjdGlvbmFsIHZhcmlvZ3JhbQ0KdmFyaW8ucGxvdChWYXJpb19FNCxucGFpcmR3PTEsbnBhaXJwdD0wLHZhcmxpbmUgPUZBTFNFLHRpdGxlPSJBbmlzb3Ryb3BpYyBNb2RlbCIscmVzZXQ9VFJVRSxsdHk9MiwgeGxhYj0iRGlzdGFuY2UobSkiLHlsYWI9IlZhcmlvZ3JhbSIpDQoNCiMgcGxvdCB0aGUgYW5pc290cm9waWMgdmFyaW9ncmFtIG1vZGVsDQptb2RlbC5wbG90KFZhcmlvX000ICx2YXJpbz1WYXJpb19FNCxhZGQ9VCkNCg0KIyBhZGQgYSBsZWdlbmQNCmxlZ2VuZCgiYm90dG9tcmlnaHQiLCBsZWdlbmQ9YygiRGlyZWN0aW9uIDDCsCIsIkRpcmVjdGlvbiA0NcKwIiwiRGlyZWN0aW9uIDkwwrAiLCJEaXJlY3Rpb24gMTM1wrAiKSwgbHR5PWMoMSwxLDEsMSksIGNvbD1jKDEsMiwzLDQpLCBjZXg9MC44KQ0KYGBgDQoNCg0KKirigKIgUXVlc3Rpb25zOioqICAgDQotIFdoYXQgZG8geW91IG9ic2VydmU/IA0KLSBXaGF0IGlzIHRoZSBkaXJlY3Rpb24gb2YgbWF4aW11bSBzcGF0aWFsIGNvbnRpbnVpdHk/DQotIGNhbiB5b3UgZGV0ZWN0IEFuaXNvdHJvcHkgPw0KDQoqKklzb3Ryb3B5IGFuZCBBbmlzb3Ryb3B5OioqIGdlbmVyYWwgc3BlYWtpbmcsIHRoZSBwcm9jZWR1cmVzIG9mIGRpc3Rpbmd1aXNoaW5nIGJldHdlZW4gaXNvdHJvcHkgYW5kIGFuaXNvdHJvcHkgYXJlIHRoZSBzYW1lLiBXZSBjYW4gZml0IGEgdmFyaW9ncmFtIG1vZGVsIGFsb25nIGFsbCB0aGUgZGlyZWN0aW9ucyBhbmQgdGhlbiBvYnRhaW4gZGlmZmVyZW50IHZhcmlvZ3JhbXMgYWxvbmcgd2l0aCBkaWZmZXJlbnQgZGlyZWN0aW9ucy4gT25jZSB3ZSBvYnRhaW4gdGhlIHZhbHVlcyBvZiBTdGlsbCwgUmFuZ2UsIE51Z2dldCBFZmZlY3QgZnJvbSBhbGwgdmFyaW9ncmFtcywgd2UgY2FuIGRldGVybWluZSBpZiB0aGUgc3BhdGlhbCBkYXRhIGlzIGlzb3Ryb3BpYyBvciBhbmlzb3Ryb3BpYy4gSWYgdGhlIHZhbHVlcyBvZiBTdGlsbCwgUmFuZ2UsIE51Z2dldCBFZmZlY3QgZnJvbSB0aGUgdmFyaW9ncmFtIGFsb25nIHdpdGggYWxsIGRpcmVjdGlvbnMgYXJlIGFsbCB0aGUgc2FtZSwgdGhlbiBpdCBpcyBpc290cm9waWM7IG90aGVyd2lzZSwgaXQgaXMgdGhlIGFuaXNvdHJvcGljLg0KDQoNCkFuaXNvdHJvcHksIGFjY29yZGluZyB0byBpdHMgZGlmZmVyZW50IHN0cnVjdHVyZXMsIGNvdWxkIGJlIGRpdmlkZWQgaW50bzogICAgICANCg0KLSBHZW9tZXRyaWMgQW5pc290cm9weTogdGhlIHNpbGwgdmFsdWUgb2YgdGhlIGdlb21ldHJpYyBhbmlzb3Ryb3BpYyB2YXJpb2dyYW0gb25seSB2YXJ5IGFsb25nIHdpdGggZGlzdGFuY2VzLCBidXQgbm90IGFsb25nIHdpdGggZGlyZWN0aW9ucy4gSW4gb3RoZXIgd29yZHMsIHdoZW4gdGhlIGRpc3RhbmNlcyBiZXR3ZWVuIHNhbXBsZXMgaW4gdmFyaW91cyBzcGF0aWFsIGFuZ2xlcyBhcmUgdGhlIHNhbWUsIHRoZWlyIFNpbGwgaXMgdGhlIHNhbWUsIGJ1dCB0aGVpciByYW5nZXMgbWF5IHZhcnkgYWxvbmcgd2l0aCBkaWZmZXJlbnQgYW5nbGVzLiBUaGUgZGlyZWN0aW9uIGhhdmluZyBiaWdnZXN0IHJhbmdlIGlzIHRoZSBkaXJlY3Rpb24gb2YgdmFyaW9ncmFtLiBUaGlzIHJhbmdlIGlzIGNhbGxlZCDigJxNYWpvciBSYW5nZeKAnSwgYW5kIHRoaXMgdmFyaW9ncmFtIGlzIGNhbGxlZCBEaXJlY3Rpb25hbCBWYXJpb2dyYW0uIFRoZSBzbWFsbGVzdCByYW5nZSBpcyBjYWxsZWQg4oCcTWlub3IgUmFuZ2XigJ0uIA0KDQohW0ZpZyAxOiBHZW9tZXRyaWMgYW5pc290cm9weV0oZ2VvbWV0cmljLnBuZykNCg0KLSBab25hbCBBbmlzb3Ryb3B5OiB0aGUgU2lsbCB2YWx1ZSBvZiB0aGUgem9uYWwgYW5pc290cm9waWMgdmFyaW9ncmFtIGRvZXMgbm90IG9ubHkgdmFyeSBhbG9uZyB3aXRoIGFsbCBkaXN0YW5jZXMsIGJ1dCBhbHNvIHZhcmllcyBhbG9uZyB3aXRoIGFsbCBkaXJlY3Rpb25zLiBJbiBvdGhlciB3b3Jkcywgd2hlbiB0aGUgZGlzdGFuY2VzIGJldHdlZW4gc2FtcGxlcyBpbiBhbnkgc3BhdGlhbCBhbmdsZXMgYXJlIHRoZSBzYW1lLCB0aGVpciBTaWxsIHZhbHVlcyBhcmUgbm90IHRoZSBzYW1lLCBhbmQgdGhlaXIgcmFuZ2VzIGFsc28gdmFyeSBhbG9uZyB3aXRoIGRpZmZlcmVudCBhbmdsZXMuIFpvbmFsIEFuaXNvdHJvcGljIHZhcmlvZ3JhbSBtb2RlbCBjb25zaXN0cyBvZiAyIG9yIG1vcmUgYW5pc290cm9waWMgdmFyaW9ncmFtcy4gTmF0dXJhbCBwaGVub21lbmEgdXN1YWxseSBkbyBub3QgaGF2ZSB0aGlzIGtpbmQgb2YgYW5pc290cm9weS4NCg0KIVtGaWcgMjogWm9uYWwgYW5pc290cm9weV0oem9uYWwucG5nKQ0KDQotIE1peGVkIEFuaXNvdHJvcHk6IGlzIGEgbWl4IG9mIHRoZSBHZW9tZXRyaWMgQW5pc290cm9weSBhbmQgWm9uYWwgQW5pc290cm9weSAuIEl0cyBTaWxsIHZhbHVlcyBhbmQgcmFuZ2VzIHZhcnkgYWxvbmcgd2l0aCBhbGwgZGlyZWN0aW9ucy4gTmF0dXJhbCBwaGVub21lbmEgb2Z0ZW4gaGF2ZSB0aGlzIGtpbmQgb2Ygc3BhdGlhbCB2YXJpYWJpbGl0eS4gRm9yIGV4YW1wbGUsIGdlb2xvZ2ljYWwgY2hhbmdlcyB1c3VhbGx5IGhhdmUgYSBiaWdnZXIgZWZmZWN0aXZlIHJhbmdlIGluIHRoZSBob3Jpem9uIGRpcmVjdGlvbiB0aGFuIGluIHRoZSB2ZXJ0aWNhbCBkaXJlY3Rpb24sIGFuZCBjaGFuZ2VzIGluIHRoZSB2ZXJ0aWNhbCBkcmllY3Rpb24gaGF2ZSBhIGJpZ2dlciByYW5nZSB0aGFuIGluIHRoZSBob3Jpem9uIGRpcmVjdGlvbi4NCg0KIVtGaWcgMzogTWl4ZWQgYW5pc290cm9weV0obWl4ZWQucG5nKQ0KDQoNCg0KDQoNCg0KDQoNCg0K