Some General Comments:

Betatron Motion

          [,1]       [,2]
[1,] 1.0237788 -28.970214
[2,] 0.1007168  -1.873243

Suppose a beam of particles entering a synchrotron has a phase space distribution (consider \(x\) only, for now) that is parameterized by the Courant-Snyder variables \(\beta\) = 25 m, \(\alpha\) = -1 and rms emittance \(\epsilon\) = 3.75 \(\pi\) mm-mrad when the particles first pass by a particular observation point in the ring. If a matrix calculation were performed, corresponding to the magnetic elements about the circumference of this ring, we find that the one-turn matrix at this same observation point is given by \[ M_0 = \begin{pmatrix} 1.0238 & -28.970~{\rm m} \\ 0.10072{\rm /m}& -1.8732 \end{pmatrix} \] which transports the vector \(\vec{X} = (x,x')^T\) according to \(\vec{X}_{n+1} = M_0\vec{X}_n = M_0^n\vec{X}_0\) where \(n\) is the revolution number, or turn number.

  1. Create a distribution of several thousand particles that has the initial Courant-Snyder parameterization given above. Plot the phase space distribution after \(n\) = 0, 1, 2, 3, 4 and 5 revolutions, as well as histograms of the distribution in \(x\) (corresponding to possible beam width measurements at our observation point) for the same values of \(n\).
beta = 25     # m
alfa = -1  
gamm = (1+alfa^2)/beta
eps  = 3.75   # pi mm-mrad
M0 = matrix(c(1.0238, -28.970, 0.10072, -1.8732),ncol=2,byrow=TRUE)

Npar = 5000
x0  =  rnorm(Npar,0,sqrt(eps*beta))  # mm
xp0 = (rnorm(Npar,0,sqrt(eps*beta)) - alfa*x0)/beta  # mrad
# save; will use these values later...

x  = x0
xp = xp0
par(mfrow=c(2,2))
i = 0
while(i<6){
   i=i+1
   plot(x,xp,xlim=c(-1,1)*40,ylim=c(-1,1)*5,pch=".")
   hist(x, xlim=c(-1,1)*40)
   j = 0
   while(j<Npar){
      j = j+1
      U = M0 %*% c(x[j],xp[j])
      x[j]  = U[1]
      xp[j] = U[2]
   }
}

  1. Create a plot of how the beam distribution rms width varies with revolution number, for \(0<n<200\).
beta = 25     # m
alfa = -1  
gamm = (1+alfa^2)/beta
eps  = 3.75   # pi mm-mrad
M0 = matrix(c(1.0238, -28.970, 0.10072, -1.8732),ncol=2,byrow=TRUE)

Npar = 5000
x  =  x0  # mm
xp = (x0 - alfa*x0)/beta  # mrad

xrms = sd(x)
i = 0
while(i<200){
   i=i+1
   j = 0
   while(j<Npar){
      j = j+1
      U = M0 %*% c(x[j],xp[j])
      x[j]  = U[1]
      xp[j] = U[2]
   }
   xrms[i] = sd(x)
}
plot(xrms, ylim=c(0,15), typ="l")

  1. Next, using the matrix \(M_0\), find the periodic Courant-Snyder parameters \(\beta_0\) and \(\alpha_0\) at the observation point, as well as the betatron tune \(\nu_x\) of the synchrotron.
mu0 = acos(sum(diag(M0))/2)
#  NOTE:  if M[1,2]<0, then sin(mu)<0 -- beta>0 always!
if( M0[1,2]<0 ) mu0 = 2*pi - mu0

beta0  =  M0[1,2]/sin(mu0)
alpha0 = (M0[1,1]-M0[2,2])/2/sin(mu0)
mu0; beta0; alpha0
[1] 4.273758
[1] 31.99924
[1] -1.599962
nu = mu0/2/pi   # modulo 2pi
nu
[1] 0.6801898
  1. Can you relate the period of the rms width variation to the betatron tune?
# Let's do a trial and error exercise...
plot(xrms, typ="l", xlim=c(0,50) )
xplt = c(1:200)
y = mean(xrms)*(1+.5*sin(2*pi*(2*nu)*(xplt)))
points(y,col="blue")

[ Looks like xrms oscillates at 2x the tune.]

  1. Create phase space plots of (\(\beta_0\;x'+\alpha_0\;x\)) vs. \(x\) of the distribution for \(n\) = 0, 1, 2, 3, 4, 5.
x = x0
p = alpha0*x0 + beta0*xp0


R0 = matrix(c(cos(mu0),sin(mu0),-sin(mu0),cos(mu0)),ncol=2,byrow=TRUE)
i = 0
par(mfrow=c(2,3))
while(i<6){
   i=i+1
   plot(x,p,xlim=c(-1,1)*80,asp=1,pch=".")
   j = 0
   while(j<Npar){
      j = j+1
      U = R0 %*% c(x[j],p[j])
      x[j] = U[1]
      p[j] = U[2]
   }
}

  1. Change \(\alpha\) and \(\beta\) of the initial distribution to be equal to \(\alpha_0\) and \(\beta_0\), thus creating a new corresponding initial particle distribution; repeat the plots of part (e) above.
x0  =  rnorm(Npar,0,sqrt(eps*beta0))  # mm
xp0 = (rnorm(Npar,0,sqrt(eps*beta0)) - alfa0*x0)/beta0  # mrad

x = x0
p = alpha0*x0 + beta0*xp0


R0 = matrix(c(cos(mu0),sin(mu0),-sin(mu0),cos(mu0)),ncol=2,byrow=TRUE)
i = 0
par(mfrow=c(2,3))
while(i<6){
   i=i+1
   plot(x,p,xlim=c(-1,1)*80,asp=1,pch=".")
   j = 0
   while(j<Npar){
      j = j+1
      U = R0 %*% c(x[j],p[j])
      x[j] = U[1]
      p[j] = U[2]
   }
}

As a check:

x = x0  # mm
p = alpha0*x0 + beta0*xp0  # mm

xrms = sd(x)
i = 0
while(i<200){
   i=i+1
   j = 0
   while(j<Npar){
      j = j+1
      U = R0 %*% c(x[j],p[j])
      x[j] = U[1]
      p[j] = U[2]
   }
   xrms[i] = sd(x)
}
plot(xrms, ylim=c(0,15), typ="l")

[So, in this case the beam is well matched to the periodic CS parameters of the ring, and hence – while each particle oscillates in phase space – the overall width of the distribution does not change significantly turn-by-turn.]

The Standard FODO Cell

Note: a MAD-X file associated with this Homework Problem can be found here.

  1. Provide a formula for the Courant-Snyder parameters \(\beta_{max,min}\) for a thin lens FODO cell in terms of the cell phase advance, \(\mu\), and the half-cell length \(L\).

\[ \beta_{\pm} = \frac{L}{\sin\mu/2}\sqrt{\frac{1\pm\sin\mu/2}{1\mp\sin\mu/2}} \]

  1. Make a single plot of \(\beta_{max}/L\) and \(\beta_{min}/L\) vs. \(\mu\) for \(0 < \mu < 150^\circ\).
bmaxonL = function(x){sqrt((1+sin(x*pi/180/2)) / (1-sin(x*pi/180/2)))/sin(x*pi/180/2)}
bminonL = function(x){sqrt((1-sin(x*pi/180/2)) / (1+sin(x*pi/180/2)))/sin(x*pi/180/2)}
curve(bmaxonL,0,150,ylim=c(0,20),xlab="Cell Phase Advance [deg.]", ylab="betaMax,Min / L")
curve(bminonL,add=TRUE,lty=2,col="blue")

  1. Compute \(\beta_{max}\) and \(\beta_{min}\) for the Tevatron FODO cell, where the lenses were separated by 30 m, using a cell phase advance of 75 degrees. What focal length does this correspond to?
betaMax = bmaxonL(75)*30
betaMin = bminonL(75)*30
F = 30/2/sin(75*pi/180/2)
betaMax;betaMin # meters
[1] 99.93074
[1] 24.3024
F  # meters
[1] 24.64019
  1. Use MADX to perform the same calculation at the downstream end of each quadrupole in a thick lens system. Use Tevatron-like quadrupole magnets with effective lengths of 2 m. Note that the total cell length should be equivalent to that of the “thin lens” version and that the total cell phase advance should again be 75 degrees. What values for \(\alpha_x\) and \(\alpha_y\) do you find at these locations? What value of \(|K| = |B'|/B\rho\) is required in this calculation? What focal length does this value of \(K\) correspond to?

We generate a model as follows:

LQ = 2    ;  ! quad length
F  = 25   ;  ! quad focal length

L0 : drift, L=28 ;
QF : quadrupole, L=LQ, K1= 1/F/LQ ;
QD : quadrupole, L=LQ, K1=-1/F/LQ ;

Tcell : line=(L0, QD, L0, QF) ;

Using a MATCH command in MAD-X we can generate the appropriate 75 degree phase advance, and perform a TWISS calculation.

match, sequence=Tcell ;
    constraint, sequence=Tcell, range=#e, mux=75/360, muy=75/360 ;
     vary, name=QF->k1,  lower = -1/25, upper=1/25, step=5.0e-3 ;
     vary, name=QD->k1,  lower = -1/25, upper=1/25, step=5.0e-3 ;
    simplex, calls=5000, tolerance=1.0e-6;
endmatch ;

From the output of calculation, \((\alpha_x,\alpha_y)\) = (2.022264919, -0.5561859735) at the output of the focusing quad, and = (-0.556511509, 2.022216597) at the output of the defocusing quad. The output of the match operation yields for \(K_1\) of the quadrupoles:

qf->k1             =      0.02075938165 ;
qd->k1             =     -0.02076360524 ;
1/(qf->k1*qf->l)   =        24.08549582 ;

The last line is the effective focal length of the magnet.

  1. Re-compute the values of \(\beta_{max}\) and \(\beta_{min}\) at the mid-point of each thick quad, using MADX. Also, what are the values of \(\alpha\) at these points?

Here, we create “half-length” quadrupoles and generate a new beam line:

K1fit = QF->K1 ;

QF2 : quadrupole, L=LQ/2, K1= K1fit ;
QD2 : quadrupole, L=LQ/2, K1=-K1fit ;

Tcell2 : line=(QF2, L0, 2*QD2, L0, QF2) ;

The output will now show the values of the CS parameters at the midpoints of the magnets; we see that \((\alpha_x,\alpha_y)\) = (0,0) (at least to the \(10^{-16}\)-level) at both midpoint locations for this symmetric system, as these points are where the values of \(\beta\) reach their maxima. Note also that these maximum betas have values:

thin lens MAD-X 2-m quads
\(\beta_{max}\) 99.93074 99.25046839
\(\beta_{min}\) 24.3024 24.46556152

illustrating that for this calculation, the thin lens approximation is good to better than 1%.

  1. In the thin lens calculations, how would you determine CS parameters at the quad mid-points?

[ Change the matrix computation from… \[ \begin{pmatrix} 1 & L \\ 0 & 1 \end{pmatrix} \begin{pmatrix} 1 & 0 \\ q & 1 \end{pmatrix} \begin{pmatrix} 1 & L \\ 0 & 1 \end{pmatrix} \begin{pmatrix} 1 & 0 \\ -q & 1 \end{pmatrix} \] to \[ \begin{pmatrix} 1 & 0 \\ -q/2 & 1 \end{pmatrix} \begin{pmatrix} 1 & L \\ 0 & 1 \end{pmatrix} \begin{pmatrix} 1 & 0 \\ q & 1 \end{pmatrix} \begin{pmatrix} 1 & L \\ 0 & 1 \end{pmatrix} \begin{pmatrix} 1 & 0 \\ -q/2 & 1 \end{pmatrix} \] etc. ]

THE Booster Ring

Note: a MAD-X file associated with this Homework Problem can be found here.

The original Fermilab Booster synchrotron – still in operation today – was designed in the late 1960’s and has the following configuration:

  1. Verify that the above configuration should bend the beam through 360 degrees. What is the total circumference of the ring, and what fraction of the circumference contains bending?
# Total bending length x field = (BL)_total should equal 2pi*Brho
Lmag = 2.889612
Bf = 0.72588
Bd = 0.61727
BLtot = 24*(Bf + Bd)*2*Lmag  # T-m
mc2 = 0.938  # GeV
W0  = 8      # GeV/c
bg  = sqrt(((8+mc2)/mc2)^2-1)
Brho = mc2*bg*10/2.9979  # T-m

BLtot/Brho - 2*pi
[1] 0.0001016444
C = 24*(4*2.889612 + 2*0.5 + 2*0.6 + 6)
C
[1] 474.2028
pkf = (24*4*2.889612)/C
pkf
[1] 0.5849876
  1. Create an appropriate MADX input file with a beam line that describes the Fermilab Booster. Compute and print out the values of the Courant-Snyder (Twiss) parameters at the end of each element according to the geometry described above.

Some relevant lines from the input file:

! The magnets:
BD: rbend, L= 2.889612, angle= 0.61727*2.889612/brho,  k1= -1.71101/brho ;
BF: rbend, L= 2.889612, angle= 0.72588*2.889612/brho,  k1=  1.60761/brho ;

! Drift spaces:
O  :   drift,  L= 0.6 ;
OO :   drift,  L= 0.5 ;
OOO:   drift,  L= 6.0 ;

! The layout:
BCEL:  line=(     O, BF, OO, BD, OOO, BD, OO, BF, O )   ;

and a table from the output:

* NAME                   S           BETX           BETY             DX               MUX              MUY
"BCEL$START"             0    33.67385206    5.271002857    3.204695719                 0                0
 "O"                   0.6    33.68454285    5.339301055    3.204695719    0.002835519438    0.01803901468
 "BF"          3.490214615     20.8840135    10.82233146    2.604892322     0.01891236161    0.08519977287
 "OO"          3.990214615    17.30501983    12.99977669     2.40508385     0.02309882393    0.09191082297
 "BD"           6.88026237    7.587521356    20.46123159    1.850080196     0.06707513392      0.118018933
 "OOO"         12.88026237    7.587521356    20.46123159    1.850080196      0.2122354719     0.1653852637
 "BD"          15.77031013    17.30501983    12.99977669     2.40508385      0.2562117819     0.1914933737
 "OO"          16.27031013     20.8840135    10.82233146    2.604892322      0.2603982442     0.1982044238
 "BF"          19.16052474    33.68454285    5.339301055    3.204695719      0.2764750864      0.265365182
 "O"           19.76052474    33.67385206    5.271002857    3.204695719      0.2793106058     0.2834041966
 "BCEL$END"    19.76052474    33.67385206    5.271002857    3.204695719      0.2793106058     0.2834041966
  1. What are the betatron oscillation tunes \((\nu_x, \nu_y)\) of the synchrotron?

The output of the TWISS command will generate values for “Q1” and “Q2” which are the horizontal and vertical tunes (here, through one period); so:

value, 24*TABLE(SUMM,Q1);    ! note:  here used one period, hence x24
24*table( summ q1 ) =        6.703454539 ;
value, 24*TABLE(SUMM,Q2);
24*table( summ q2 ) =        6.801700719 ;
nux0 = 24*Table(summ,Q1) ;
nuy0 = 24*Table(summ,Q2) ;

Also, we can see that MUX and MUY for one period is given in the above table. These numbers are \(\Delta\psi/2\pi\) and so the tunes will be 24 times those values.

  1. Plot the periodic amplitude functions \(\beta_x\), \(\beta_y\) and the dispersion function \(D_x\) throughout a single period.
Booster Period

Booster Period

  1. Protons are injected into the Booster ring from a linear accelerator, when the proton kinetic energy is 400 MeV. Make a plot of the revolution time (in microseconds) for an ideal proton as a function of magnetic field corresponding to the ring’s range of operation.

bet  = function(x){ sqrt(1-(mc2/(mc2+x))^2) }
tprd = function(x){ C/2.9979e8/bet(x) }
curve(tprd(x)*1e6,0.4,8,
   xlab="Kinetic Energy [GeV]", ylab="Rev. Time [microsec.]")

ke = function(bg){mc2*(sqrt(1+bg^2) - 1)}
bgMin = sqrt(((mc2+0.4)/mc2)^2-1)
bgMax = sqrt(((mc2+8.0)/mc2)^2-1)
curve(tprd(ke(x*bgMax))*1e6,bgMin/bgMax,
   xlab="Fraction of maximum field", ylab="Rev. Time [microsec.]")

  1. Suppose that a single BF magnet in the ring has its gradient altered by +5%. Compute the resulting change in the horizontal and vertical tunes of the Booster using appropriate modifications to the matrices found above. Estimate the change by using the simple tune shift formula and compare.

Here, we take a single BF magnet (BFerr) and increase its gradient by 5%, then build a new ring description that has one period with this magnet in it, and 23 periods with “normal” magnets :

BFerr: rbend, L= 2.889612, angle= 0.72588*2.889612/brho,  k1=  1.60761/brho*1.05 ;
BCELerr:  line=(     O, BF, OO, BD, OOO, BD, OO, BFerr, O )   ;
BRing:   line=( 11*(BCEL), BCELerr, 12*(BCEL) ) ;

We then re-compute the Twiss paramters and extract the new tunes (Q1 and Q2):

value, TABLE(SUMM,Q1);
table( summ q1 )   =         6.72132284  ;
value, TABLE(SUMM,Q2);
table( summ q2 )   =         6.797235611 ;
nux1 = Table(summ,Q1) ;   ! note:  here used complete ring
nuy1 = Table(summ,Q2) ;

We see that the new tunes differ from the original tunes, due to the error field, by:

nux1-nux0          =      0.01786830108  ;
nuy1-nuy0          =     -0.004465107912 ;

We now use our “tune shift formula” to do a quick check:

\[ \Delta\nu_{x,y} = \pm \frac{1}{4\pi}\beta_{x,y}\Delta K\ell \]


Bpf = 1.60761   # T/m for the BF magnet
betaxBF = 26    # from the MAD output; use average values within the BFerr magnet...
betayBF = 8.0 
dnux =  1/4/pi*betaxBF*(Bpf/Brho*0.05)*Lmag # "+" since   focuses in x
dnuy = -1/4/pi*betayBF*(Bpf/Brho*0.05)*Lmag # "-" since defocuses in y
dnux; dnuy
[1] 0.01620822
[1] -0.004987145

  1. Northern Illinois University and Fermi National Accelerator Laboratory

LS0tCnRpdGxlOiAiSG9tZXdvcmsgMyBEaXNjdXNzaW9uIgphdXRob3I6IE1pa2UgU3lwaGVyc15bTm9ydGhlcm4gSWxsaW5vaXMgVW5pdmVyc2l0eSBhbmQgRmVybWkgTmF0aW9uYWwgQWNjZWxlcmF0b3IKICBMYWJvcmF0b3J5XQpkYXRlOiAnbGFzdCB1cGRhdGU6IGByIGZvcm1hdCgoU3lzLkRhdGUoKSksICIlZCAlYiAlWSIpYCcKb3V0cHV0OiAgaHRtbF9ub3RlYm9vawotLS0KCioqU29tZSBHZW5lcmFsIENvbW1lbnRzOioqCgotIGdyYWRlOiAgMzAgcG9zc2libGUgIAogICAgICArIDEwIHB0cyBlYWNoIHByb2JsZW0gIAogICAgICArIGF2ZSBzY29yZTogIDIwLzMwICAKCi0gc3RpbGw6ICBsYXN0IG5hbWVzIGluIHlvdXIgZmlsZSBuYW1lcyAtLSBhbG1vc3QgdGhlcmUhICAKLSBjb21wdXRlcnMgYW5kIGRldGVybWluaW5nIGFuZ2xlczogIGJldGEgPiAwIGFsd2F5cyEgIAotIHR1bmUgc2hpZnQgIAotIHNvbWUgc3RpbGwgbmVlZCBwcmFjdGljZTogIFcgdnMgRSB2cyBwYyB2cyBtY14yIHZzIGJldGEgdnMgZ2FtbWEKIC4uLiAgCi0gTUFELVg6ICBtdXggPSBwc2lfeC8ycGk7IFExIChzdW1tYXJ5IHRhYmxlKSA9IHBlcmlvZGljIG11eAotIHBlcmlvZGljIENTIHBhcmFtZXRlcnMgdnMuIG5vbi1wZXJpb2RpYyB2YWx1ZXMKLSBjcmVhdGluZyBtYXRyaWNlcywgYXJyYXlzLCBkYXRhIGZyYW1lcywgZXRjLiAtLSBhbHdheXMgY2hlY2sgd2hhdCdzIGdvaW5nIG9uOyBtYWtlIHN1cmUgaXQncyB3aGF0IHlvdSB3YW50CgojIyAqKkJldGF0cm9uIE1vdGlvbioqCgpgYGB7ciwgZXZhbD1UUlVFLCBlY2hvPUZBTFNFIH0Kcm0obGlzdD1scygpKQpzZXQuc2VlZCg4MzcpCmJldGEwID0gMzIKYWxmYTAgPSAtMS42CmdhbW0wID0gKDErYWxmYTBeMikvYmV0YTAKZXBzMCAgPSAzLjc1Cm11eCAgID0gMipwaSowLjY4MDE4NDE4NzQKTTAgICAgPSBtYXRyaXgoIGMoIGNvcyhtdXgpK2FsZmEwKnNpbihtdXgpLCBiZXRhMCpzaW4obXV4KSwgLWdhbW0wKnNpbihtdXgpLCBjb3MobXV4KS1hbGZhMCpzaW4obXV4KSApLCBieXJvdyA9IFRSVUUsIG5jb2w9MikKTTAKYGBgCgpTdXBwb3NlIGEgYmVhbSBvZiBwYXJ0aWNsZXMgZW50ZXJpbmcgYSBzeW5jaHJvdHJvbiBoYXMgYSBwaGFzZSBzcGFjZSBkaXN0cmlidXRpb24gKGNvbnNpZGVyICR4JCBvbmx5LCBmb3Igbm93KSB0aGF0IGlzIHBhcmFtZXRlcml6ZWQgYnkgdGhlIENvdXJhbnQtU255ZGVyIHZhcmlhYmxlcyAkXGJldGEkID0gMjUgbSwgJFxhbHBoYSQgPSAtMSBhbmQgcm1zIGVtaXR0YW5jZSAkXGVwc2lsb24kID0gMy43NSAkXHBpJCBtbS1tcmFkIHdoZW4gdGhlIHBhcnRpY2xlcyBmaXJzdCBwYXNzIGJ5IGEgcGFydGljdWxhciBvYnNlcnZhdGlvbiBwb2ludCBpbiB0aGUgcmluZy4gIElmIGEgbWF0cml4IGNhbGN1bGF0aW9uIHdlcmUgcGVyZm9ybWVkLCBjb3JyZXNwb25kaW5nIHRvIHRoZSBtYWduZXRpYyBlbGVtZW50cyBhYm91dCB0aGUgY2lyY3VtZmVyZW5jZSBvZiB0aGlzIHJpbmcsIHdlIGZpbmQgdGhhdCB0aGUgb25lLXR1cm4gbWF0cml4IGF0IHRoaXMgc2FtZSBvYnNlcnZhdGlvbiBwb2ludCBpcyBnaXZlbiBieQokJApNXzAgPSBcYmVnaW57cG1hdHJpeH0gMS4wMjM4ICYgLTI4Ljk3MH57XHJtIG19IFxcIDAuMTAwNzJ7XHJtIC9tfSYgLTEuODczMiBcZW5ke3BtYXRyaXh9CiQkCndoaWNoIHRyYW5zcG9ydHMgdGhlIHZlY3RvciAkXHZlY3tYfSA9ICh4LHgnKV5UJCBhY2NvcmRpbmcgdG8gJFx2ZWN7WH1fe24rMX0gPSBNXzBcdmVje1h9X24gPSBNXzBeblx2ZWN7WH1fMCQgd2hlcmUgJG4kIGlzIHRoZSByZXZvbHV0aW9uIG51bWJlciwgb3IgKnR1cm4gbnVtYmVyKi4KCmEuIENyZWF0ZSBhIGRpc3RyaWJ1dGlvbiBvZiBzZXZlcmFsIHRob3VzYW5kIHBhcnRpY2xlcyB0aGF0IGhhcyB0aGUgaW5pdGlhbCBDb3VyYW50LVNueWRlciBwYXJhbWV0ZXJpemF0aW9uIGdpdmVuIGFib3ZlLiAgUGxvdCB0aGUgcGhhc2Ugc3BhY2UgZGlzdHJpYnV0aW9uIGFmdGVyICRuJCA9IDAsIDEsIDIsIDMsIDQgYW5kIDUgcmV2b2x1dGlvbnMsIGFzIHdlbGwgYXMgaGlzdG9ncmFtcyBvZiB0aGUgZGlzdHJpYnV0aW9uIGluICR4JCAoY29ycmVzcG9uZGluZyB0byBwb3NzaWJsZSBiZWFtIHdpZHRoIG1lYXN1cmVtZW50cyBhdCBvdXIgb2JzZXJ2YXRpb24gcG9pbnQpIGZvciB0aGUgc2FtZSB2YWx1ZXMgb2YgJG4kLgoKYGBge3J9CmJldGEgPSAyNSAgICAgIyBtCmFsZmEgPSAtMSAgCmdhbW0gPSAoMSthbGZhXjIpL2JldGEKZXBzICA9IDMuNzUgICAjIHBpIG1tLW1yYWQKTTAgPSBtYXRyaXgoYygxLjAyMzgsIC0yOC45NzAsIDAuMTAwNzIsIC0xLjg3MzIpLG5jb2w9MixieXJvdz1UUlVFKQoKTnBhciA9IDUwMDAKeDAgID0gIHJub3JtKE5wYXIsMCxzcXJ0KGVwcypiZXRhKSkgICMgbW0KeHAwID0gKHJub3JtKE5wYXIsMCxzcXJ0KGVwcypiZXRhKSkgLSBhbGZhKngwKS9iZXRhICAjIG1yYWQKIyBzYXZlOyB3aWxsIHVzZSB0aGVzZSB2YWx1ZXMgbGF0ZXIuLi4KCnggID0geDAKeHAgPSB4cDAKcGFyKG1mcm93PWMoMiwyKSkKaSA9IDAKd2hpbGUoaTw2KXsKICAgaT1pKzEKICAgcGxvdCh4LHhwLHhsaW09YygtMSwxKSo0MCx5bGltPWMoLTEsMSkqNSxwY2g9Ii4iKQogICBoaXN0KHgsIHhsaW09YygtMSwxKSo0MCkKICAgaiA9IDAKICAgd2hpbGUoajxOcGFyKXsKICAgICAgaiA9IGorMQogICAgICBVID0gTTAgJSolIGMoeFtqXSx4cFtqXSkKICAgICAgeFtqXSAgPSBVWzFdCiAgICAgIHhwW2pdID0gVVsyXQogICB9Cn0KYGBgCgpiLiBDcmVhdGUgYSBwbG90IG9mIGhvdyB0aGUgYmVhbSBkaXN0cmlidXRpb24gcm1zIHdpZHRoIHZhcmllcyB3aXRoIHJldm9sdXRpb24gbnVtYmVyLCBmb3IgJDA8bjwyMDAkLiAgCgpgYGB7cn0KYmV0YSA9IDI1ICAgICAjIG0KYWxmYSA9IC0xICAKZ2FtbSA9ICgxK2FsZmFeMikvYmV0YQplcHMgID0gMy43NSAgICMgcGkgbW0tbXJhZApNMCA9IG1hdHJpeChjKDEuMDIzOCwgLTI4Ljk3MCwgMC4xMDA3MiwgLTEuODczMiksbmNvbD0yLGJ5cm93PVRSVUUpCgpOcGFyID0gNTAwMAp4ICA9ICB4MCAgIyBtbQp4cCA9ICh4MCAtIGFsZmEqeDApL2JldGEgICMgbXJhZAoKeHJtcyA9IHNkKHgpCmkgPSAwCndoaWxlKGk8MjAwKXsKICAgaT1pKzEKICAgaiA9IDAKICAgd2hpbGUoajxOcGFyKXsKICAgICAgaiA9IGorMQogICAgICBVID0gTTAgJSolIGMoeFtqXSx4cFtqXSkKICAgICAgeFtqXSAgPSBVWzFdCiAgICAgIHhwW2pdID0gVVsyXQogICB9CiAgIHhybXNbaV0gPSBzZCh4KQp9CnBsb3QoeHJtcywgeWxpbT1jKDAsMTUpLCB0eXA9ImwiKQpgYGAKCmMuICBOZXh0LCB1c2luZyB0aGUgbWF0cml4ICRNXzAkLCBmaW5kIHRoZSAqcGVyaW9kaWMqIENvdXJhbnQtU255ZGVyIHBhcmFtZXRlcnMgJFxiZXRhXzAkIGFuZCAkXGFscGhhXzAkIGF0IHRoZSBvYnNlcnZhdGlvbiBwb2ludCwgYXMgd2VsbCBhcyB0aGUgYmV0YXRyb24gdHVuZSAkXG51X3gkIG9mIHRoZSBzeW5jaHJvdHJvbi4KCmBgYHtyfQptdTAgPSBhY29zKHN1bShkaWFnKE0wKSkvMikKIyAgTk9URTogIGlmIE1bMSwyXTwwLCB0aGVuIHNpbihtdSk8MCAtLSBiZXRhPjAgYWx3YXlzIQppZiggTTBbMSwyXTwwICkgbXUwID0gMipwaSAtIG11MAoKYmV0YTAgID0gIE0wWzEsMl0vc2luKG11MCkKYWxwaGEwID0gKE0wWzEsMV0tTTBbMiwyXSkvMi9zaW4obXUwKQptdTA7IGJldGEwOyBhbHBoYTAKbnUgPSBtdTAvMi9waSAgICMgbW9kdWxvIDJwaQpudQpgYGAKCmQuIENhbiB5b3UgcmVsYXRlIHRoZSBwZXJpb2Qgb2YgdGhlIHJtcyB3aWR0aCB2YXJpYXRpb24gdG8gdGhlIGJldGF0cm9uIHR1bmU/CgpgYGB7cn0KIyBMZXQncyBkbyBhIHRyaWFsIGFuZCBlcnJvciBleGVyY2lzZS4uLgpwbG90KHhybXMsIHR5cD0ibCIsIHhsaW09YygwLDUwKSApCnhwbHQgPSBjKDE6MjAwKQp5ID0gbWVhbih4cm1zKSooMSsuNSpzaW4oMipwaSooMipudSkqKHhwbHQpKSkKcG9pbnRzKHksY29sPSJibHVlIikKYGBgClsgTG9va3MgbGlrZSB4cm1zIG9zY2lsbGF0ZXMgYXQgMnggdGhlIHR1bmUuXQoKZS4gIENyZWF0ZSBwaGFzZSBzcGFjZSBwbG90cyBvZiAoJFxiZXRhXzBcO3gnK1xhbHBoYV8wXDt4JCkgKnZzLiogJHgkIG9mIHRoZSBkaXN0cmlidXRpb24gZm9yICRuJCA9IDAsIDEsIDIsIDMsIDQsIDUuCgpgYGB7cn0KeCA9IHgwCnAgPSBhbHBoYTAqeDAgKyBiZXRhMCp4cDAKCgpSMCA9IG1hdHJpeChjKGNvcyhtdTApLHNpbihtdTApLC1zaW4obXUwKSxjb3MobXUwKSksbmNvbD0yLGJ5cm93PVRSVUUpCmkgPSAwCnBhcihtZnJvdz1jKDIsMykpCndoaWxlKGk8Nil7CiAgIGk9aSsxCiAgIHBsb3QoeCxwLHhsaW09YygtMSwxKSo4MCxhc3A9MSxwY2g9Ii4iKQogICBqID0gMAogICB3aGlsZShqPE5wYXIpewogICAgICBqID0gaisxCiAgICAgIFUgPSBSMCAlKiUgYyh4W2pdLHBbal0pCiAgICAgIHhbal0gPSBVWzFdCiAgICAgIHBbal0gPSBVWzJdCiAgIH0KfQpgYGAKCmYuICBDaGFuZ2UgJFxhbHBoYSQgYW5kICRcYmV0YSQgb2YgdGhlIGluaXRpYWwgZGlzdHJpYnV0aW9uIHRvIGJlIGVxdWFsIHRvICRcYWxwaGFfMCQgYW5kICRcYmV0YV8wJCwgdGh1cyBjcmVhdGluZyBhIG5ldyBjb3JyZXNwb25kaW5nIGluaXRpYWwgcGFydGljbGUgZGlzdHJpYnV0aW9uOyByZXBlYXQgdGhlICBwbG90cyBvZiBwYXJ0IChlKSBhYm92ZS4KCmBgYHtyfQp4MCAgPSAgcm5vcm0oTnBhciwwLHNxcnQoZXBzKmJldGEwKSkgICMgbW0KeHAwID0gKHJub3JtKE5wYXIsMCxzcXJ0KGVwcypiZXRhMCkpIC0gYWxmYTAqeDApL2JldGEwICAjIG1yYWQKCnggPSB4MApwID0gYWxwaGEwKngwICsgYmV0YTAqeHAwCgoKUjAgPSBtYXRyaXgoYyhjb3MobXUwKSxzaW4obXUwKSwtc2luKG11MCksY29zKG11MCkpLG5jb2w9MixieXJvdz1UUlVFKQppID0gMApwYXIobWZyb3c9YygyLDMpKQp3aGlsZShpPDYpewogICBpPWkrMQogICBwbG90KHgscCx4bGltPWMoLTEsMSkqODAsYXNwPTEscGNoPSIuIikKICAgaiA9IDAKICAgd2hpbGUoajxOcGFyKXsKICAgICAgaiA9IGorMQogICAgICBVID0gUjAgJSolIGMoeFtqXSxwW2pdKQogICAgICB4W2pdID0gVVsxXQogICAgICBwW2pdID0gVVsyXQogICB9Cn0KYGBgCgpBcyBhIGNoZWNrOgoKYGBge3J9CnggPSB4MCAgIyBtbQpwID0gYWxwaGEwKngwICsgYmV0YTAqeHAwICAjIG1tCgp4cm1zID0gc2QoeCkKaSA9IDAKd2hpbGUoaTwyMDApewogICBpPWkrMQogICBqID0gMAogICB3aGlsZShqPE5wYXIpewogICAgICBqID0gaisxCiAgICAgIFUgPSBSMCAlKiUgYyh4W2pdLHBbal0pCiAgICAgIHhbal0gPSBVWzFdCiAgICAgIHBbal0gPSBVWzJdCiAgIH0KICAgeHJtc1tpXSA9IHNkKHgpCn0KcGxvdCh4cm1zLCB5bGltPWMoMCwxNSksIHR5cD0ibCIpCmBgYAoKW1NvLCBpbiB0aGlzIGNhc2UgdGhlIGJlYW0gaXMgd2VsbCBtYXRjaGVkIHRvIHRoZSBwZXJpb2RpYyBDUyBwYXJhbWV0ZXJzIG9mIHRoZSByaW5nLCBhbmQgaGVuY2UgLS0gd2hpbGUgZWFjaCBwYXJ0aWNsZSBvc2NpbGxhdGVzIGluIHBoYXNlIHNwYWNlIC0tIHRoZSBvdmVyYWxsIHdpZHRoIG9mIHRoZSBkaXN0cmlidXRpb24gZG9lcyBub3QgY2hhbmdlIHNpZ25pZmljYW50bHkgdHVybi1ieS10dXJuLl0KCgojIyAqKlRoZSBTdGFuZGFyZCBGT0RPIENlbGwqKiAgCgoqKk5vdGU6KiogYSBgTUFELVhgIGZpbGUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgSG9tZXdvcmsgUHJvYmxlbSBjYW4gYmUgZm91bmQgW2hlcmVdKFRldkNlbGwubWFkeCkuCgphLiBQcm92aWRlIGEgZm9ybXVsYSBmb3IgdGhlIENvdXJhbnQtU255ZGVyIHBhcmFtZXRlcnMgJFxiZXRhX3ttYXgsbWlufSQgZm9yIGEgdGhpbiBsZW5zIEZPRE8gY2VsbCBpbiB0ZXJtcyBvZiB0aGUgY2VsbCBwaGFzZSBhZHZhbmNlLCAkXG11JCwgYW5kIHRoZSBoYWxmLWNlbGwgbGVuZ3RoICRMJC4gIAoKJCQKXGJldGFfe1xwbX0gPSBcZnJhY3tMfXtcc2luXG11LzJ9XHNxcnR7XGZyYWN7MVxwbVxzaW5cbXUvMn17MVxtcFxzaW5cbXUvMn19CiQkCgpiLiBNYWtlIGEgc2luZ2xlIHBsb3Qgb2YgJFxiZXRhX3ttYXh9L0wkIGFuZCAkXGJldGFfe21pbn0vTCQgKnZzLiogJFxtdSQgZm9yICQwIDwgXG11IDwgMTUwXlxjaXJjJC4gIApgYGB7ciwgZXZhbD1UUlVFLCBlY2hvPVRSVUV9CmJtYXhvbkwgPSBmdW5jdGlvbih4KXtzcXJ0KCgxK3Npbih4KnBpLzE4MC8yKSkgLyAoMS1zaW4oeCpwaS8xODAvMikpKS9zaW4oeCpwaS8xODAvMil9CmJtaW5vbkwgPSBmdW5jdGlvbih4KXtzcXJ0KCgxLXNpbih4KnBpLzE4MC8yKSkgLyAoMStzaW4oeCpwaS8xODAvMikpKS9zaW4oeCpwaS8xODAvMil9CmN1cnZlKGJtYXhvbkwsMCwxNTAseWxpbT1jKDAsMjApLHhsYWI9IkNlbGwgUGhhc2UgQWR2YW5jZSBbZGVnLl0iLCB5bGFiPSJiZXRhTWF4LE1pbiAvIEwiKQpjdXJ2ZShibWlub25MLGFkZD1UUlVFLGx0eT0yLGNvbD0iYmx1ZSIpCmBgYAoKYy4gQ29tcHV0ZSAkXGJldGFfe21heH0kIGFuZCAkXGJldGFfe21pbn0kIGZvciB0aGUgVGV2YXRyb24gRk9ETyBjZWxsLCB3aGVyZSB0aGUgbGVuc2VzIHdlcmUgc2VwYXJhdGVkIGJ5IDMwIG0sIHVzaW5nIGEgY2VsbCBwaGFzZSBhZHZhbmNlIG9mIDc1IGRlZ3JlZXMuIFdoYXQgZm9jYWwgbGVuZ3RoIGRvZXMgdGhpcyBjb3JyZXNwb25kIHRvPwpgYGB7ciwgZXZhbD1UUlVFLGVjaG89VFJVRX0KYmV0YU1heCA9IGJtYXhvbkwoNzUpKjMwCmJldGFNaW4gPSBibWlub25MKDc1KSozMApGID0gMzAvMi9zaW4oNzUqcGkvMTgwLzIpCmJldGFNYXg7YmV0YU1pbiAjIG1ldGVycwpGICAjIG1ldGVycwpgYGAKCmQuIFVzZSBgTUFEWGAgdG8gcGVyZm9ybSB0aGUgc2FtZSBjYWxjdWxhdGlvbiBhdCB0aGUgZG93bnN0cmVhbSBlbmQgb2YgZWFjaCBxdWFkcnVwb2xlIGluIGEgKnRoaWNrIGxlbnMqIHN5c3RlbS4gIFVzZSBUZXZhdHJvbi1saWtlIHF1YWRydXBvbGUgbWFnbmV0cyB3aXRoIGVmZmVjdGl2ZSBsZW5ndGhzIG9mIDIgbS4gIE5vdGUgdGhhdCB0aGUgKnRvdGFsKiBjZWxsIGxlbmd0aCBzaG91bGQgYmUgZXF1aXZhbGVudCB0byB0aGF0IG9mIHRoZSAidGhpbiBsZW5zIiB2ZXJzaW9uIGFuZCB0aGF0IHRoZSB0b3RhbCBjZWxsIHBoYXNlIGFkdmFuY2Ugc2hvdWxkIGFnYWluIGJlIDc1IGRlZ3JlZXMuICBXaGF0IHZhbHVlcyBmb3IgJFxhbHBoYV94JCBhbmQgJFxhbHBoYV95JCBkbyB5b3UgZmluZCBhdCB0aGVzZSBsb2NhdGlvbnM/ICBXaGF0IHZhbHVlIG9mICR8S3wgPSB8Qid8L0JccmhvJCBpcyByZXF1aXJlZCBpbiB0aGlzIGNhbGN1bGF0aW9uPyAgV2hhdCAqZm9jYWwgbGVuZ3RoKiBkb2VzIHRoaXMgdmFsdWUgb2YgJEskIGNvcnJlc3BvbmQgdG8/ICAgCgpXZSBnZW5lcmF0ZSBhIG1vZGVsIGFzIGZvbGxvd3M6CmBgYApMUSA9IDIgICAgOyAgISBxdWFkIGxlbmd0aApGICA9IDI1ICAgOyAgISBxdWFkIGZvY2FsIGxlbmd0aAoKTDAgOiBkcmlmdCwgTD0yOCA7ClFGIDogcXVhZHJ1cG9sZSwgTD1MUSwgSzE9IDEvRi9MUSA7ClFEIDogcXVhZHJ1cG9sZSwgTD1MUSwgSzE9LTEvRi9MUSA7CgpUY2VsbCA6IGxpbmU9KEwwLCBRRCwgTDAsIFFGKSA7CmBgYApVc2luZyBhIGBNQVRDSGAgY29tbWFuZCBpbiBgTUFELVhgIHdlIGNhbiBnZW5lcmF0ZSB0aGUgYXBwcm9wcmlhdGUgNzUgZGVncmVlIHBoYXNlIGFkdmFuY2UsIGFuZCBwZXJmb3JtIGEgYFRXSVNTYCBjYWxjdWxhdGlvbi4gIAoKYGBgCm1hdGNoLCBzZXF1ZW5jZT1UY2VsbCA7Cgljb25zdHJhaW50LCBzZXF1ZW5jZT1UY2VsbCwgcmFuZ2U9I2UsIG11eD03NS8zNjAsIG11eT03NS8zNjAgOwogICAgIHZhcnksIG5hbWU9UUYtPmsxLCAgbG93ZXIgPSAtMS8yNSwgdXBwZXI9MS8yNSwgc3RlcD01LjBlLTMgOwogICAgIHZhcnksIG5hbWU9UUQtPmsxLCAgbG93ZXIgPSAtMS8yNSwgdXBwZXI9MS8yNSwgc3RlcD01LjBlLTMgOwoJc2ltcGxleCwgY2FsbHM9NTAwMCwgdG9sZXJhbmNlPTEuMGUtNjsKZW5kbWF0Y2ggOwpgYGAKCkZyb20gdGhlIG91dHB1dCBvZiBjYWxjdWxhdGlvbiwgJChcYWxwaGFfeCxcYWxwaGFfeSkkID0gKDIuMDIyMjY0OTE5LCAtMC41NTYxODU5NzM1KSBhdCB0aGUgb3V0cHV0IG9mIHRoZSBmb2N1c2luZyBxdWFkLCBhbmQgPSAoLTAuNTU2NTExNTA5LCAyLjAyMjIxNjU5NykgYXQgdGhlIG91dHB1dCBvZiB0aGUgZGVmb2N1c2luZyBxdWFkLiAgVGhlIG91dHB1dCBvZiB0aGUgbWF0Y2ggb3BlcmF0aW9uIHlpZWxkcyBmb3IgJEtfMSQgb2YgdGhlIHF1YWRydXBvbGVzOgpgYGAKcWYtPmsxICAgICAgICAgICAgID0gICAgICAwLjAyMDc1OTM4MTY1IDsKcWQtPmsxICAgICAgICAgICAgID0gICAgIC0wLjAyMDc2MzYwNTI0IDsKMS8ocWYtPmsxKnFmLT5sKSAgID0gICAgICAgIDI0LjA4NTQ5NTgyIDsKYGBgClRoZSBsYXN0IGxpbmUgaXMgdGhlIGVmZmVjdGl2ZSBmb2NhbCBsZW5ndGggb2YgdGhlIG1hZ25ldC4KCmUuIFJlLWNvbXB1dGUgdGhlIHZhbHVlcyBvZiAkXGJldGFfe21heH0kIGFuZCAkXGJldGFfe21pbn0kIGF0IHRoZSBtaWQtcG9pbnQgb2YgZWFjaCB0aGljayBxdWFkLCB1c2luZyBgTUFEWGAuICBBbHNvLCB3aGF0IGFyZSB0aGUgdmFsdWVzIG9mICRcYWxwaGEkIGF0IHRoZXNlIHBvaW50cz8gIAoKSGVyZSwgd2UgY3JlYXRlICJoYWxmLWxlbmd0aCIgcXVhZHJ1cG9sZXMgYW5kIGdlbmVyYXRlIGEgbmV3IGJlYW0gbGluZToKYGBgCksxZml0ID0gUUYtPksxIDsKClFGMiA6IHF1YWRydXBvbGUsIEw9TFEvMiwgSzE9IEsxZml0IDsKUUQyIDogcXVhZHJ1cG9sZSwgTD1MUS8yLCBLMT0tSzFmaXQgOwoKVGNlbGwyIDogbGluZT0oUUYyLCBMMCwgMipRRDIsIEwwLCBRRjIpIDsKYGBgClRoZSBvdXRwdXQgd2lsbCBub3cgc2hvdyB0aGUgdmFsdWVzIG9mIHRoZSBDUyBwYXJhbWV0ZXJzIGF0IHRoZSBtaWRwb2ludHMgb2YgdGhlIG1hZ25ldHM7IHdlIHNlZSB0aGF0ICQoXGFscGhhX3gsXGFscGhhX3kpJCA9ICgwLDApIChhdCBsZWFzdCB0byB0aGUgJDEwXnstMTZ9JC1sZXZlbCkgYXQgYm90aCBtaWRwb2ludCBsb2NhdGlvbnMgZm9yIHRoaXMgc3ltbWV0cmljIHN5c3RlbSwgYXMgdGhlc2UgcG9pbnRzIGFyZSB3aGVyZSB0aGUgdmFsdWVzIG9mICRcYmV0YSQgcmVhY2ggdGhlaXIgbWF4aW1hLiAgTm90ZSBhbHNvIHRoYXQgdGhlc2UgbWF4aW11bSBiZXRhcyBoYXZlIHZhbHVlczoKCnwgICB8ICAgdGhpbiBsZW5zIHwgTUFELVggMi1tIHF1YWRzIHwKfC0tLXwtLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tfAp8JFxiZXRhX3ttYXh9JCB8IDk5LjkzMDc0ICB8IDk5LjI1MDQ2ODM5IHwKfCRcYmV0YV97bWlufSQgfCAyNC4zMDI0ICB8IDI0LjQ2NTU2MTUyIHwKCmlsbHVzdHJhdGluZyB0aGF0IGZvciB0aGlzIGNhbGN1bGF0aW9uLCB0aGUgdGhpbiBsZW5zIGFwcHJveGltYXRpb24gaXMgZ29vZCB0byBiZXR0ZXIgdGhhbiAxJS4KCmYuIEluIHRoZSB0aGluIGxlbnMgY2FsY3VsYXRpb25zLCBob3cgd291bGQgeW91IGRldGVybWluZSBDUyBwYXJhbWV0ZXJzIGF0IHRoZSBxdWFkIG1pZC1wb2ludHM/CgpbIENoYW5nZSB0aGUgbWF0cml4IGNvbXB1dGF0aW9uIGZyb20uLi4KJCQKXGJlZ2lue3BtYXRyaXh9IDEgJiBMIFxcIDAgJiAxIFxlbmR7cG1hdHJpeH0KXGJlZ2lue3BtYXRyaXh9IDEgJiAwIFxcIHEgJiAxIFxlbmR7cG1hdHJpeH0KXGJlZ2lue3BtYXRyaXh9IDEgJiBMIFxcIDAgJiAxIFxlbmR7cG1hdHJpeH0KXGJlZ2lue3BtYXRyaXh9IDEgJiAwIFxcIC1xICYgMSBcZW5ke3BtYXRyaXh9CiQkCnRvCiQkClxiZWdpbntwbWF0cml4fSAxICYgMCBcXCAtcS8yICYgMSBcZW5ke3BtYXRyaXh9ClxiZWdpbntwbWF0cml4fSAxICYgTCBcXCAwICYgMSBcZW5ke3BtYXRyaXh9ClxiZWdpbntwbWF0cml4fSAxICYgMCBcXCBxICYgMSBcZW5ke3BtYXRyaXh9ClxiZWdpbntwbWF0cml4fSAxICYgTCBcXCAwICYgMSBcZW5ke3BtYXRyaXh9ClxiZWdpbntwbWF0cml4fSAxICYgMCBcXCAtcS8yICYgMSBcZW5ke3BtYXRyaXh9CiQkCiBldGMuICAgXQoKCiMjICoqKlRIRSogQm9vc3RlciBSaW5nKioKCioqTm90ZToqKiBhIGBNQUQtWGAgZmlsZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBIb21ld29yayBQcm9ibGVtIGNhbiBiZSBmb3VuZCBbaGVyZV0oQm9vc3Rlci5tYWR4KS4KClRoZSBvcmlnaW5hbCBGZXJtaWxhYiBCb29zdGVyIHN5bmNocm90cm9uIC0tIHN0aWxsIGluIG9wZXJhdGlvbiB0b2RheSAtLSB3YXMgZGVzaWduZWQgaW4gdGhlIGxhdGUgMTk2MCdzIGFuZCBoYXMgdGhlIGZvbGxvd2luZyBjb25maWd1cmF0aW9uOgoKLSAyNCBpZGVudGljYWwgcGVyaW9kcyAgCi0gZWFjaCBwZXJpb2QgY29udGFpbnMgdHdvICoqQkYqKiBtYWduZXRzIGFuZCB0d28gKipCRCoqIG1hZ25ldHMsIGVhY2ggb2Ygd2hpY2ggYm90aCBiZW5kcyBhbmQgZm9jdXNlcyAob3IgZGVmb2N1c2VzKSB0aGUgYmVhbQotIGVhY2ggKipCRioqIG1hZ25ldCBhbmQgZWFjaCAqKkJEKiogbWFnbmV0IGlzIDIuODg5NjEyIG0gbG9uZyAoZGVzaWduIHZhbHVlKSwgYW5kIGFyZSByZWN0YW5ndWxhciwgcmF0aGVyIHRoYW4gc2VjdG9yLCBlbGVtZW50cyAgICAKLSBlYWNoICoqQkYqKiBtYWduZXQgb3BlcmF0ZXMgd2l0aCBhIGNlbnRyYWwgZmllbGQgdmFsdWUgb2YgMC43MjU4OCBULCBhbmQgaGFzIGEgZmllbGQgZ3JhZGllbnQgb2YgIDEuNjA3NjEgVC9tICAKLSBlYWNoICoqQkQqKiBtYWduZXQgb3BlcmF0ZXMgd2l0aCBhIGNlbnRyYWwgZmllbGQgdmFsdWUgb2YgMC42MTcyNyBULCBhbmQgaGFzIGEgZmllbGQgZ3JhZGllbnQgb2YgLTEuNzExMDEgVC9tICAKLSB0aGUgZmllbGRzIGFib3ZlIGNvcnJlc3BvbmQgdG8gYSBmaW5hbCBwcm90b24gKmtpbmV0aWMgZW5lcmd5KiBvZiA4IEdlVgotIGVhY2ggb2YgdGhlIDI0IHBlcmlvZHMgaGFzIHRoZSBmb2xsb3dpbmcgZ2VvbWV0cmljIGNvbmZpZ3VyYXRpb246ICAKICAgKyAoMC42IG0pIC0tICoqQkYqKiAtLSAoMC41IG0pIC0tICoqQkQqKiAtLSAoNi4wIG0pIC0tICoqQkQqKiAtLSAoMC41IG0pIC0tICoqQkYqKiAtLSAoMC42IG0pCgphLiAgVmVyaWZ5IHRoYXQgdGhlIGFib3ZlIGNvbmZpZ3VyYXRpb24gc2hvdWxkIGJlbmQgdGhlIGJlYW0gdGhyb3VnaCAzNjAgZGVncmVlcy4gIFdoYXQgaXMgdGhlIHRvdGFsIGNpcmN1bWZlcmVuY2Ugb2YgdGhlIHJpbmcsIGFuZCB3aGF0IGZyYWN0aW9uIG9mIHRoZSBjaXJjdW1mZXJlbmNlIGNvbnRhaW5zIGJlbmRpbmc/CgpgYGB7ciwgZXZhbD1UUlVFLGVjaG89VFJVRX0KIyBUb3RhbCBiZW5kaW5nIGxlbmd0aCB4IGZpZWxkID0gKEJMKV90b3RhbCBzaG91bGQgZXF1YWwgMnBpKkJyaG8KTG1hZyA9IDIuODg5NjEyCkJmID0gMC43MjU4OApCZCA9IDAuNjE3MjcKQkx0b3QgPSAyNCooQmYgKyBCZCkqMipMbWFnICAjIFQtbQptYzIgPSAwLjkzOCAgIyBHZVYKVzAgID0gOCAgICAgICMgR2VWL2MKYmcgID0gc3FydCgoKDgrbWMyKS9tYzIpXjItMSkKQnJobyA9IG1jMipiZyoxMC8yLjk5NzkgICMgVC1tCgpCTHRvdC9CcmhvIC0gMipwaQpgYGAKYGBge3IsIGV2YWw9VFJVRSxlY2hvPVRSVUV9CkMgPSAyNCooNCoyLjg4OTYxMiArIDIqMC41ICsgMiowLjYgKyA2KQpDCnBrZiA9ICgyNCo0KjIuODg5NjEyKS9DCnBrZgpgYGAKCmIuICBDcmVhdGUgYW4gYXBwcm9wcmlhdGUgYE1BRFhgIGlucHV0IGZpbGUgd2l0aCBhIGJlYW0gbGluZSB0aGF0IGRlc2NyaWJlcyB0aGUgRmVybWlsYWIgQm9vc3Rlci4gIENvbXB1dGUgYW5kIHByaW50IG91dCB0aGUgdmFsdWVzIG9mIHRoZSBDb3VyYW50LVNueWRlciAoVHdpc3MpIHBhcmFtZXRlcnMgYXQgdGhlIGVuZCBvZiBlYWNoIGVsZW1lbnQgYWNjb3JkaW5nIHRvIHRoZSBnZW9tZXRyeSBkZXNjcmliZWQgYWJvdmUuICAKClNvbWUgcmVsZXZhbnQgbGluZXMgZnJvbSB0aGUgaW5wdXQgZmlsZToKYGBgCiEgVGhlIG1hZ25ldHM6CkJEOiByYmVuZCwgTD0gMi44ODk2MTIsIGFuZ2xlPSAwLjYxNzI3KjIuODg5NjEyL2JyaG8sICBrMT0gLTEuNzExMDEvYnJobyA7CkJGOiByYmVuZCwgTD0gMi44ODk2MTIsIGFuZ2xlPSAwLjcyNTg4KjIuODg5NjEyL2JyaG8sICBrMT0gIDEuNjA3NjEvYnJobyA7CgohIERyaWZ0IHNwYWNlczoKTyAgOiAgIGRyaWZ0LCAgTD0gMC42IDsKT08gOiAgIGRyaWZ0LCAgTD0gMC41IDsKT09POiAgIGRyaWZ0LCAgTD0gNi4wIDsKCiEgVGhlIGxheW91dDoKQkNFTDogIGxpbmU9KCAgICAgTywgQkYsIE9PLCBCRCwgT09PLCBCRCwgT08sIEJGLCBPICkgICA7CmBgYAphbmQgYSB0YWJsZSBmcm9tIHRoZSBvdXRwdXQ6CmBgYAoqIE5BTUUgICAgICAgICAgICAgICAgICAgUyAgICAgICAgICAgQkVUWCAgICAgICAgICAgQkVUWSAgICAgICAgICAgICBEWCAgICAgICAgICAgICAgIE1VWCAgICAgICAgICAgICAgTVVZCiJCQ0VMJFNUQVJUIiAgICAgICAgICAgICAwICAgIDMzLjY3Mzg1MjA2ICAgIDUuMjcxMDAyODU3ICAgIDMuMjA0Njk1NzE5ICAgICAgICAgICAgICAgICAwICAgICAgICAgICAgICAgIDAKICJPIiAgICAgICAgICAgICAgICAgICAwLjYgICAgMzMuNjg0NTQyODUgICAgNS4zMzkzMDEwNTUgICAgMy4yMDQ2OTU3MTkgICAgMC4wMDI4MzU1MTk0MzggICAgMC4wMTgwMzkwMTQ2OAogIkJGIiAgICAgICAgICAzLjQ5MDIxNDYxNSAgICAgMjAuODg0MDEzNSAgICAxMC44MjIzMzE0NiAgICAyLjYwNDg5MjMyMiAgICAgMC4wMTg5MTIzNjE2MSAgICAwLjA4NTE5OTc3Mjg3CiAiT08iICAgICAgICAgIDMuOTkwMjE0NjE1ICAgIDE3LjMwNTAxOTgzICAgIDEyLjk5OTc3NjY5ICAgICAyLjQwNTA4Mzg1ICAgICAwLjAyMzA5ODgyMzkzICAgIDAuMDkxOTEwODIyOTcKICJCRCIgICAgICAgICAgIDYuODgwMjYyMzcgICAgNy41ODc1MjEzNTYgICAgMjAuNDYxMjMxNTkgICAgMS44NTAwODAxOTYgICAgIDAuMDY3MDc1MTMzOTIgICAgICAwLjExODAxODkzMwogIk9PTyIgICAgICAgICAxMi44ODAyNjIzNyAgICA3LjU4NzUyMTM1NiAgICAyMC40NjEyMzE1OSAgICAxLjg1MDA4MDE5NiAgICAgIDAuMjEyMjM1NDcxOSAgICAgMC4xNjUzODUyNjM3CiAiQkQiICAgICAgICAgIDE1Ljc3MDMxMDEzICAgIDE3LjMwNTAxOTgzICAgIDEyLjk5OTc3NjY5ICAgICAyLjQwNTA4Mzg1ICAgICAgMC4yNTYyMTE3ODE5ICAgICAwLjE5MTQ5MzM3MzcKICJPTyIgICAgICAgICAgMTYuMjcwMzEwMTMgICAgIDIwLjg4NDAxMzUgICAgMTAuODIyMzMxNDYgICAgMi42MDQ4OTIzMjIgICAgICAwLjI2MDM5ODI0NDIgICAgIDAuMTk4MjA0NDIzOAogIkJGIiAgICAgICAgICAxOS4xNjA1MjQ3NCAgICAzMy42ODQ1NDI4NSAgICA1LjMzOTMwMTA1NSAgICAzLjIwNDY5NTcxOSAgICAgIDAuMjc2NDc1MDg2NCAgICAgIDAuMjY1MzY1MTgyCiAiTyIgICAgICAgICAgIDE5Ljc2MDUyNDc0ICAgIDMzLjY3Mzg1MjA2ICAgIDUuMjcxMDAyODU3ICAgIDMuMjA0Njk1NzE5ICAgICAgMC4yNzkzMTA2MDU4ICAgICAwLjI4MzQwNDE5NjYKICJCQ0VMJEVORCIgICAgMTkuNzYwNTI0NzQgICAgMzMuNjczODUyMDYgICAgNS4yNzEwMDI4NTcgICAgMy4yMDQ2OTU3MTkgICAgICAwLjI3OTMxMDYwNTggICAgIDAuMjgzNDA0MTk2NgpgYGAKCmMuIFdoYXQgYXJlIHRoZSBiZXRhdHJvbiBvc2NpbGxhdGlvbiB0dW5lcyAkKFxudV94LCBcbnVfeSkkIG9mIHRoZSBzeW5jaHJvdHJvbj8gIAoKVGhlIG91dHB1dCBvZiB0aGUgYFRXSVNTYCBjb21tYW5kIHdpbGwgZ2VuZXJhdGUgdmFsdWVzIGZvciAiYFExYCIgYW5kICJgUTJgIiB3aGljaCBhcmUgdGhlIGhvcml6b250YWwgYW5kIHZlcnRpY2FsIHR1bmVzIChoZXJlLCB0aHJvdWdoIG9uZSBwZXJpb2QpOyBzbzoKYGBgCnZhbHVlLCAyNCpUQUJMRShTVU1NLFExKTsgICAgISBub3RlOiAgaGVyZSB1c2VkIG9uZSBwZXJpb2QsIGhlbmNlIHgyNAoyNCp0YWJsZSggc3VtbSBxMSApID0gICAgICAgIDYuNzAzNDU0NTM5IDsKdmFsdWUsIDI0KlRBQkxFKFNVTU0sUTIpOwoyNCp0YWJsZSggc3VtbSBxMiApID0gICAgICAgIDYuODAxNzAwNzE5IDsKbnV4MCA9IDI0KlRhYmxlKHN1bW0sUTEpIDsKbnV5MCA9IDI0KlRhYmxlKHN1bW0sUTIpIDsKYGBgCkFsc28sIHdlIGNhbiBzZWUgdGhhdCBgTVVYYCBhbmQgYE1VWWAgZm9yIG9uZSBwZXJpb2QgaXMgZ2l2ZW4gaW4gdGhlIGFib3ZlIHRhYmxlLiAgVGhlc2UgbnVtYmVycyBhcmUgJFxEZWx0YVxwc2kvMlxwaSQgYW5kIHNvIHRoZSB0dW5lcyB3aWxsIGJlIDI0IHRpbWVzIHRob3NlIHZhbHVlcy4KCmQuIFBsb3QgdGhlIHBlcmlvZGljIGFtcGxpdHVkZSBmdW5jdGlvbnMgJFxiZXRhX3gkLCAkXGJldGFfeSQgYW5kIHRoZSBkaXNwZXJzaW9uIGZ1bmN0aW9uICREX3gkIHRocm91Z2hvdXQgYSBzaW5nbGUgcGVyaW9kLiAgCgohW0Jvb3N0ZXIgUGVyaW9kXShCb29zdGVyLmpwZykKCmUuIFByb3RvbnMgYXJlIGluamVjdGVkIGludG8gdGhlIEJvb3N0ZXIgcmluZyBmcm9tIGEgbGluZWFyIGFjY2VsZXJhdG9yLCB3aGVuIHRoZSBwcm90b24ga2luZXRpYyBlbmVyZ3kgaXMgNDAwIE1lVi4gIE1ha2UgYSBwbG90IG9mIHRoZSByZXZvbHV0aW9uIHRpbWUgKGluIG1pY3Jvc2Vjb25kcykgZm9yIGFuIGlkZWFsIHByb3RvbiBhcyBhIGZ1bmN0aW9uIG9mIG1hZ25ldGljIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHJpbmcncyByYW5nZSBvZiBvcGVyYXRpb24uICAKCmBgYHtyLCBldmFsPVRSVUUsZWNobz1UUlVFfQoKYmV0ICA9IGZ1bmN0aW9uKHgpeyBzcXJ0KDEtKG1jMi8obWMyK3gpKV4yKSB9CnRwcmQgPSBmdW5jdGlvbih4KXsgQy8yLjk5NzllOC9iZXQoeCkgfQpjdXJ2ZSh0cHJkKHgpKjFlNiwwLjQsOCwKICAgeGxhYj0iS2luZXRpYyBFbmVyZ3kgW0dlVl0iLCB5bGFiPSJSZXYuIFRpbWUgW21pY3Jvc2VjLl0iKQprZSA9IGZ1bmN0aW9uKGJnKXttYzIqKHNxcnQoMStiZ14yKSAtIDEpfQpiZ01pbiA9IHNxcnQoKChtYzIrMC40KS9tYzIpXjItMSkKYmdNYXggPSBzcXJ0KCgobWMyKzguMCkvbWMyKV4yLTEpCmN1cnZlKHRwcmQoa2UoeCpiZ01heCkpKjFlNixiZ01pbi9iZ01heCwKICAgeGxhYj0iRnJhY3Rpb24gb2YgbWF4aW11bSBmaWVsZCIsIHlsYWI9IlJldi4gVGltZSBbbWljcm9zZWMuXSIpCmBgYAoKZi4gIFN1cHBvc2UgdGhhdCBhICpzaW5nbGUgKipCRioqIG1hZ25ldCogaW4gdGhlIHJpbmcgaGFzIGl0cyBncmFkaWVudCBhbHRlcmVkIGJ5ICs1JS4gIENvbXB1dGUgdGhlIHJlc3VsdGluZyBjaGFuZ2UgaW4gdGhlIGhvcml6b250YWwgYW5kIHZlcnRpY2FsIHR1bmVzIG9mIHRoZSBCb29zdGVyIHVzaW5nIGFwcHJvcHJpYXRlIG1vZGlmaWNhdGlvbnMgdG8gdGhlIG1hdHJpY2VzIGZvdW5kIGFib3ZlLiAgRXN0aW1hdGUgdGhlIGNoYW5nZSBieSB1c2luZyB0aGUgc2ltcGxlICp0dW5lIHNoaWZ0KiBmb3JtdWxhIGFuZCBjb21wYXJlLiAgCgpIZXJlLCB3ZSB0YWtlIGEgc2luZ2xlICoqQkYqKiBtYWduZXQgKCoqQkZlcnIqKikgYW5kIGluY3JlYXNlIGl0cyBncmFkaWVudCBieSA1JSwgdGhlbiBidWlsZCBhIG5ldyByaW5nIGRlc2NyaXB0aW9uIHRoYXQgaGFzIG9uZSBwZXJpb2Qgd2l0aCB0aGlzIG1hZ25ldCBpbiBpdCwgYW5kIDIzIHBlcmlvZHMgd2l0aCAibm9ybWFsIiBtYWduZXRzIDoKYGBgCkJGZXJyOiByYmVuZCwgTD0gMi44ODk2MTIsIGFuZ2xlPSAwLjcyNTg4KjIuODg5NjEyL2JyaG8sICBrMT0gIDEuNjA3NjEvYnJobyoxLjA1IDsKQkNFTGVycjogIGxpbmU9KCAgICAgTywgQkYsIE9PLCBCRCwgT09PLCBCRCwgT08sIEJGZXJyLCBPICkgICA7CkJSaW5nOiAgIGxpbmU9KCAxMSooQkNFTCksIEJDRUxlcnIsIDEyKihCQ0VMKSApIDsKYGBgCldlIHRoZW4gcmUtY29tcHV0ZSB0aGUgVHdpc3MgcGFyYW10ZXJzIGFuZCBleHRyYWN0IHRoZSBuZXcgdHVuZXMgKGBRMWAgYW5kIGBRMmApOgpgYGAKdmFsdWUsIFRBQkxFKFNVTU0sUTEpOwp0YWJsZSggc3VtbSBxMSApICAgPSAgICAgICAgIDYuNzIxMzIyODQgIDsKdmFsdWUsIFRBQkxFKFNVTU0sUTIpOwp0YWJsZSggc3VtbSBxMiApICAgPSAgICAgICAgIDYuNzk3MjM1NjExIDsKbnV4MSA9IFRhYmxlKHN1bW0sUTEpIDsgICAhIG5vdGU6ICBoZXJlIHVzZWQgY29tcGxldGUgcmluZwpudXkxID0gVGFibGUoc3VtbSxRMikgOwpgYGAKV2Ugc2VlIHRoYXQgdGhlIG5ldyB0dW5lcyBkaWZmZXIgZnJvbSB0aGUgb3JpZ2luYWwgdHVuZXMsIGR1ZSB0byB0aGUgZXJyb3IgZmllbGQsIGJ5OgpgYGAKbnV4MS1udXgwICAgICAgICAgID0gICAgICAwLjAxNzg2ODMwMTA4ICA7Cm51eTEtbnV5MCAgICAgICAgICA9ICAgICAtMC4wMDQ0NjUxMDc5MTIgOwpgYGAKCldlIG5vdyB1c2Ugb3VyICJ0dW5lIHNoaWZ0IGZvcm11bGEiIHRvIGRvIGEgcXVpY2sgY2hlY2s6CgokJApcRGVsdGFcbnVfe3gseX0gPSBccG0gXGZyYWN7MX17NFxwaX1cYmV0YV97eCx5fVxEZWx0YSBLXGVsbAokJApgYGB7ciwgZXZhbD1UUlVFLGVjaG89VFJVRX0KCkJwZiA9IDEuNjA3NjEgICAjIFQvbSBmb3IgdGhlIEJGIG1hZ25ldApiZXRheEJGID0gMjYgICAgIyBmcm9tIHRoZSBNQUQgb3V0cHV0OyB1c2UgYXZlcmFnZSB2YWx1ZXMgd2l0aGluIHRoZSBCRmVyciBtYWduZXQuLi4KYmV0YXlCRiA9IDguMCAKZG51eCA9ICAxLzQvcGkqYmV0YXhCRiooQnBmL0JyaG8qMC4wNSkqTG1hZyAjICIrIiBzaW5jZSAgIGZvY3VzZXMgaW4geApkbnV5ID0gLTEvNC9waSpiZXRheUJGKihCcGYvQnJobyowLjA1KSpMbWFnICMgIi0iIHNpbmNlIGRlZm9jdXNlcyBpbiB5CmRudXg7IGRudXkKYGBgCgoK