cps & contification

Matthew Fluet Matthew Fluet <fluet@CS.Cornell.EDU>
Sat, 13 Jan 2001 15:56:09 -0500 (EST)


  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.
  Send mail to mime@docserver.cac.washington.edu for more info.

---559023410-869693583-979419369=:12463
Content-Type: TEXT/PLAIN; charset=US-ASCII


I extended contify.fun to compute my modification of the contifiability
analysis (but not to act on it).  Good news is that it never disagrees
when one of the previous two analyses decides that a function is
contifiable.  Better news is that it is finding a number of additional
functions which are contifiable.  

Here's one example, where neither of the previous analyses determined that
x_664 was contifiable:

fun concat_1(env_39, x_663) = 
   let
      fun L_203() = 
	 x_664(x_663, x_93)
      fun L_202(x_665) = 
	 let
	    val x_666 = #2 x_665
	    val x_667 = #1 x_665
	    fun L_205() = 
	       x_664(x_663, x_94)
	    fun L_204() = 
	       x_667
	 in
	    case x_666 of
	      nil_2 => L_204 | _ => L_205
	 end
   in
      case x_663 of
	::_2 => L_202 | _ => L_203
   end
fun x_664(env_40, x_668) = ...

Call missed it because x_664 appears twice (syntactically).  Cont missed
it because it determined that x_664 has the same continuation as
concat_1, which has multiple continuations.

Here's another one:

fun num_2(env_122, x_1816) = 
   let
      val x_1817 = #3 env_122
      val finishNum_3 = #2 env_122
      val x_1818 = #1 env_122
      fun L_674(x_1819) = 
	 let
	    val x_1820 = (x_1818, finishNum_3)
	    fun L_675(x_1821) = 
	       let
		  val x_1823 = #2 x_1821
		  val x_1822 = #1 x_1821
		  fun L_678() = 
		     let
			val x_1825 = (x_1823, x_1822)
		     in
			x_1824(x_1820, x_1825)
		     end
		  fun L_677() = 
		     let
			val x_1826 = (x_1823, x_1822)
		     in
			x_1824(x_1820, x_1826)
		     end
	       in
		  case x_1822 of
		    0 => L_677 | _ => L_678
	       end
	    fun L_676() = 
	       x_685
	 in
	    case x_1819 of
	      NONE_1 => L_676 | SOME_1 => L_675
	 end
      fun L_673(env_123) = 
	 L_674(x_1178(env_123, x_1816))
   in
      case x_1817 of
	Env_207 => L_673
   end
fun x_1824(env_124, x_1827) = ...

The reason I mention this one, is that my analysis computes that x_1824
will return to num_2; this make sense, because L_677 and L_678 both return
to L_675 which returns to ... num_2.  On the other hand, it seems that we
could reasonably say that x_1824 returns to L_675.  Does this make a
difference, or is it enough to combine top-level cps functions?  I think I
know of a way of "shrinking" the return to narrow it down if that makes a
difference.

Here are the results from the benchmark suite.  First column is the number
of functions in the program.  Successive columns show number of functions
determined contifiable by combinations of the analysis.

So, column 2 is the number of functions contifiable by all analyses.
Column 8 is the number of functions contifiable by the new analysis.
So, the important columns are 3, 6, and 7 -- which are always 0 showing
that the new analysis didn't miss anything that either of the other
analyses got -- and column 8 -- which shows that there are some functions
left to contify.

          funs|call|call|call|    |call|    |
              |cont|cont|    |cont|    |cont|
              | new|    | new| new|    |    | new

testing barnes-hut
functions: 120   61    0    5    2    0    0    3
functions:  50    5    0    0    0    0    0    3
functions:   7    0    0    0    0    0    0    0

testing checksum
functions:  13    9    0    0    0    0    0    0
functions:   4    1    0    0    0    0    0    0
functions:   1    0    0    0    0    0    0    0

testing count-graphs
functions: 107   55    0    5    6    0    0    2
functions:  41    9    0    0    0    0    0    2
functions:   9    0    0    0    0    0    0    0

testing fft
functions:  59   38    0    1    0    0    0    1
functions:  20    3    0    0    0    0    0    1
functions:   2    0    0    0    0    0    0    0

testing fib
functions:  11    7    0    0    0    0    0    0
functions:   4    1    0    0    0    0    0    0
functions:   2    0    0    0    0    0    0    0

testing knuth-bendix
functions: 113   37    0    6    3    0    0    5
functions:  68    2    0    2    0    0    0    4
functions:  34    0    0    0    0    0    0    1

testing lexgen
functions: 245  102    0   18    6    0    0   12
functions: 119    2    0    0    0    0    0   12
functions:  37    0    0    0    0    0    0    3

testing life
functions:  44   23    0    2    0    0    0    1
functions:  19    1    0    0    0    0    0    1
functions:   7    0    0    0    0    0    0    0

testing logic
functions:  73    8    0    7    0    0    0   47
functions:  58    1    0    0    0    0    0   47
functions:  31    0    0    0    0    0    0   22

testing mandelbrot
functions:  14   11    0    0    0    0    0    0
functions:   3    1    0    0    0    0    0    0
functions:   1    0    0    0    0    0    0    0

testing matrix-multiply
functions:  21   14    0    0    0    0    0    0
functions:   7    2    0    0    0    0    0    0
functions:   1    0    0    0    0    0    0    0

testing merge
functions:  16   12    0    0    0    0    0    0
functions:   4    1    0    0    0    0    0    0
functions:   2    0    0    0    0    0    0    0

testing mlyacc
functions: 821  345    0   72   13    0    0   41
functions: 388    8    0    1    0    0    0   40
functions: 108    0    0    0    0    0    0    2

testing mpuz
functions:  36   23    0    2    0    0    0    1
functions:  11    1    0    0    0    0    0    1
functions:   2    0    0    0    0    0    0    0

testing nucleic
functions:  34   16    0    2    0    0    0    0
functions:  16    1    0    0    0    0    0    0
functions:   7    0    0    0    0    0    0    0

testing ratio-regions
functions: 118   64    0    2    0    0    0    2
functions:  52    6    0    0    0    0    0    2
functions:   8    0    0    0    0    0    0    0

testing simple
functions: 265   84    0    7    1    0    0    3
functions: 172    5    0    0    0    0    0    3
functions:  24    0    0    0    0    0    0    0

testing smith-normal-form
functions: 109   47    0    3    3    0    0    3
functions:  55    4    0    1    0    0    0    3
functions:   6    0    0    0    0    0    0    0

testing tak
functions:  12    8    0    0    0    0    0    0
functions:   4    1    0    0    0    0    0    0
functions:   2    0    0    0    0    0    0    0

testing tensor
functions: 158   90    0    7    3    0    0    1
functions:  57    7    0    1    0    0    0    2
functions:   7    0    0    0    0    0    0    0

testing tsp
functions:  59   27    0    1    2    0    0    1
functions:  28    2    0    0    0    0    0    1
functions:   9    0    0    0    0    0    0    0

testing vliw
functions: 507  188    0   39   19    0    0    6
functions: 257   18    0    2    0    0    0    4
functions:  86    0    0    0    0    0    0    2

testing wc
functions:  64   33    0    4    1    0    0    1
functions:  26    0    0    0    0    0    0    1
functions:   6    0    0    0    0    0    0    0

testing zern
functions:  49   33    0    0    2    0    0    1
functions:  14    2    0    0    0    0    0    1
functions:   2    0    0    0    0    0    0    0

raytrace:
functions: 303  110    0   13    6    0    0   42
functions: 174   10    0    0    0    0    0   42
functions:  38    0    0    0    0    0    0    5

In amost everything, something determined to be contifiable by the new
analysis in the first pass is still around for the second pass.  The
couple of exceptions in knuth-bendix and mlyacc were functions that turned
out to be call-contifiable in the second pass, so they are counted under
the call/new column.  In tensor, the second function that is
new-contifiable in the second pass really isn't contifiable in the first
pass -- I don't quite understand what other transformations occured
between the first and second pass to lift that function out of returning
to continuations, but the analysis is correct that it's not contifiable in
the first pass.

The one other inconsistency that I discovered was in the regression suite
with list.sml.  I got two functions determined to be call-contifiable, but
neither cont- nor new- contifiable.  While this is true, what really
happened was that the new analysis determined that those two functions had
no return continuation (i.e., they were never called in execution of the
program); interestingly, the cont-analysis did not determine that the
functions had an empty continuation set.  In any event, in the counts
above, a function is considered cont- or new-contifiable if it is really
contifiable; nothing is reported if the analysis determines that the
function has an empty continuation set.  (This is consistent with the way
the counts were currently being taken in contify.fun; you'll notice that
all of these numbers match up where appropriate with Steve's counts from
his Nov. 21 email on CWS paper.)  I've only discovered a few functions
which have an empty continuation set, most of which were also caught by
the cont-analysis.  Since contify is run after remove-useless,
this seems reasonable.

So, the bad news... I can't quite get the actual contification to occur:
I get a "_var_ has no info property" error, on a variable that isn't even
mentioned in the cps.  Stranger, no property in contify.fun is declared
initRaise("info",...).  I thought it wouldn't be difficult to simply use
the new analysis results in all the places where the cont analyis results
were being used, but I must be missing something.  I'm including the
modified contify.fun if someone wants to take a look.  There are a few
notes on the analysis and where I tried to plug it into the contification.



---559023410-869693583-979419369=:12463
Content-Type: TEXT/PLAIN; charset=US-ASCII; name="contify.new.fun"
Content-Transfer-Encoding: BASE64
Content-ID: <Pine.SOL.3.95.1010113155609.12463H@hoho.cs.cornell.edu>
Content-Description: 

KCogQ29weXJpZ2h0IChDKSAxOTk3LTE5OTkgTkVDIFJlc2VhcmNoIEluc3RpdHV0ZS4NCiAqIFBs
ZWFzZSBzZWUgdGhlIGZpbGUgTElDRU5TRSBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi4NCiAqKQ0K
KCoNCiAqIFRoaXMgcGFzcyBjb21iaW5lcyB0d28gYW5hbHlzZXMgYW5kIHRyYW5zZm9ybWF0aW9u
cy4NCiAqDQogKiBUaGUgZmlyc3QgYW5hbHlzaXMsICJjYWxsIGJhc2VkIiBub3RpY2VzIGlmIGEg
dG9wbGV2ZWwgZnVuY3Rpb24gaXMgY2FsbGVkDQogKiAgICAgICAxLiBmcm9tIG9uZSBwbGFjZSBv
dXRzaWRlIGl0c2VsZg0KICogICBhbmQgMi4gYWxsIGNhbGxzIHRvIGl0c2VsZiB3aXRoaW4gaXRz
ZWxmIGFyZSB0YWlsDQogKiBJZiAoMSkgYW5kICgyKSBhcmUgdHJ1ZSwgdGhlbiB0aGF0IGZ1bmN0
aW9uIGNhbiBiZSBtYWRlIGxvY2FsIGF0IHRoZSBwb2ludA0KICogb2YgaXRzIG91dGVyIGNhbGwu
DQogKg0KICogVGhlIHNlY29uZCBhbmFseXNpcyBpcyBiYXNlZCBvbiB0aGUgZm9sbG93aW5nIHBh
cGVyLg0KICogICBMb2NhbCBDUFMgY29udmVyc2lvbiBpbiBhIGRpcmVjdC1zdHlsZSBjb21waWxl
ci4gIEpvaG4gUmVwcHkuDQogKiBJdCBkZXRlcm1pbmVzIHRoZSBzZXQgb2YgY29udGludWF0aW9u
cyB0aGF0IGEgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGguICBJZg0KICogdGhhdCBzZXQgaXMgYSBz
aW5nbGV0b24sIHRoZW4gdGhlIGZ1bmN0aW9uIGNhbiBiZSBwcmVmaXhlZCBvbnRvIHRoZQ0KICog
Y29udGludWF0aW9uIGl0IGlzIGNhbGxlZCB3aXRoLg0KICopDQoNCmZ1bmN0b3IgQ29udGlmeSAo
UzogQ09OVElGWV9TVFJVQ1RTKTogQ09OVElGWSA9IA0Kc3RydWN0DQoNCm9wZW4gUw0Kb3BlbiBE
ZWMgVHJhbnNmZXINCg0Kc3RydWN0dXJlIFJDb250ID0NCiAgIHN0cnVjdA0KDQogICAgICAoKiBM
YWJlbCA9IHtmIDogZiBpcyB0b3AgbGV2ZWwgQ1BTIGZ1bmN0aW9uIG5hbWV9IFUgIA0KICAgICAg
ICAgICAgICAgICB7ayA6IGsgaXMgbG9jYWwgcmV0dXJuIGNvbnRpbnVhdGlvbn0gDQogICAgICAg
KikNCiAgICAgIGRhdGF0eXBlIGxhYmVsDQoJPSBGdW5jTGFiZWwgb2YgRnVuYy50DQoJfCBKdW1w
TGFiZWwgb2YgSnVtcC50DQoNCiAgICAgIHZhbCBsYWJlbF90b1N0cmluZw0KCT0gZm4gRnVuY0xh
YmVsIGYgPT4gRnVuYy50b1N0cmluZyBmDQoJICAgfCBKdW1wTGFiZWwgaiA9PiBKdW1wLnRvU3Ry
aW5nIGoNCgkNCiAgICAgIHZhbCBsYWJlbF9lcXVhbHMNCgk9IGZuIChGdW5jTGFiZWwgZjEsIEZ1
bmNMYWJlbCBmMikgPT4gRnVuYy5lcXVhbHMgKGYxLCBmMikNCgkgICB8IChKdW1wTGFiZWwgajEs
IEp1bXBMYWJlbCBqMikgPT4gSnVtcC5lcXVhbHMgKGoxLCBqMikNCgkgICB8IF8gPT4gZmFsc2UN
Cg0KICAgICAgKCogUkNvbnQgPSBib3QgVSBMYWJlbA0KICAgICAgICopDQogICAgICBkYXRhdHlw
ZSByY29udA0KCT0gQm90DQoJfCBMYWJlbCBvZiBsYWJlbA0KDQogICAgICB2YWwgcmNvbnRfdG9T
dHJpbmcNCgk9IGZuIEJvdCA9PiAiQm90Ig0KCSAgIHwgTGFiZWwgbCA9PiAiTGFiZWwgIiBeIChs
YWJlbF90b1N0cmluZyBsKQ0KDQogICAgICB2YWwgcmNvbnRfZXF1YWxzDQoJPSBmbiAoQm90LCBC
b3QpID0+IHRydWUNCiAgICAgICAgICAgfCAoTGFiZWwgbDEsIExhYmVsIGwyKSA9PiBsYWJlbF9l
cXVhbHMgKGwxLCBsMikNCgkgICB8IF8gPT4gZmFsc2UNCg0KICAgICAgKCogR2FtbWEgaW4gUkVu
diA9IExhYmVsIC0+IFJDb250DQogICAgICAgKg0KICAgICAgICogR2FtbWExIDw9IEdhbW1hMg0K
ICAgICAgICogaWZmDQogICAgICAgKiBmb3JhbGwgbCBpbiBMYWJlbC4gR2FtbWEobCkgPD1sIEdh
bW1hMihsKQ0KICAgICAgICogICAgICAgICAgICAgICAgICAgIHdoZXJlIGJvdCA8PWwgbCcgPD1s
IGwgZm9yYWxsIGwnIGluIExhYmVsDQogICAgICAgKg0KICAgICAgICogR2FtbWExIFYgR2FtbWEy
DQogICAgICAgKiA9IHtsIC0+IHIgfCBsIGluIExhYmVsDQogICAgICAgKiAgICAgICAgICAgICBy
ID0gY2FzZSAoR2FtbWExKGwpLCBHYW1tYTIobCkpDQogICAgICAgKiAgICAgICAgICAgICAgICAg
ICBvZiAoYm90LCByJykgPT4gcicNCiAgICAgICAqICAgICAgICAgICAgICAgICAgICB8IChyJywg
Ym90KSA9PiByJw0KICAgICAgICogICAgICAgICAgICAgICAgICAgIHwgKHIxLCByMikgPT4gaWYg
cjEgPSByMg0KICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4g
cjENCiAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGx9DQog
ICAgICAgKiANCiAgICAgICAqIEFuYWx5c2lzIHdpbGwgbW9ub3RvbmljYWxseSBpbmNyZWFzZSBH
YW1tYSwNCiAgICAgICAqIHNvIGl0IHN1ZmZpY2VzIHRvIHJlY29yZCwgZm9yIGVhY2ggbGFiZWws
DQogICAgICAgKiB0aGUgY3VycmVudCBSQ29udCBhbmQgYSBsaXN0IG9mIG90aGVyIHZhbHVlcw0K
ICAgICAgICogdG8gY2hhbmdlIGlmIHRoZSBjdXJyZW50IGxhYmVsIGlzIGluY3JlYXNlZC4NCiAg
ICAgICAqKQ0KICAgICAgZGF0YXR5cGUgdCA9IFQgb2Yge2xhYmVsOiBsYWJlbCwNCgkJCSByY29u
dDogcmNvbnQgcmVmLA0KCQkJIHJlc2V0OiBib29sIHJlZiwNCgkJCSBsZXNzVGhhbjogdCBsaXN0
IHJlZiwNCgkJCSBtb3JlVGhhbjogdCBsaXN0IHJlZiwNCgkJCSBtb3JlVGhhbic6IGxhYmVsIGxp
c3QgcmVmfQ0KDQogICAgICBmdW4gdG9TdHJpbmcgKFQge2xhYmVsLCByY29udCwgbGVzc1RoYW4s
IG1vcmVUaGFuLCBtb3JlVGhhbicsIC4uLn0pDQoJPSBjYXNlICFyY29udA0KCSAgICBvZiBCb3Qg
PT4gInt9Ig0KCSAgICAgfCBMYWJlbCBsID0+IGlmIGxhYmVsX2VxdWFscyhsYWJlbCwgbCkNCgkJ
CSAgICB0aGVuICJBbGwiDQoJCQkgICAgZWxzZSBjb25jYXQgWyJ7ICIsDQoJCQkJCSBsYWJlbF90
b1N0cmluZyBsLA0KCQkJCQkgIiB9Il0NCg0KICAgICAgZnVuIGxhYmVsIChUIHtsYWJlbCwgLi4u
fSkgPSBsYWJlbA0KICAgICAgZnVuIHJjb250IChUIHtyY29udCwgLi4ufSkgPSAhcmNvbnQNCg0K
ICAgICAgZnVuIG5ldyBsID0gVCB7bGFiZWwgPSBsLA0KCQkgICAgIHJjb250ID0gcmVmIEJvdCwN
CgkJICAgICByZXNldCA9IHJlZiBmYWxzZSwNCgkJICAgICBsZXNzVGhhbiA9IHJlZiBbXSwNCgkJ
ICAgICBtb3JlVGhhbiA9IHJlZiBbXSwNCgkJICAgICBtb3JlVGhhbicgPSByZWYgW119DQoNCiAg
ICAgIHZhbCBvcCAvXCANCgk9IGZuIChsLCByMSwgcjIpDQoJICAgPT4gIChjYXNlIChyMSwgcjIp
IA0KCQkgIG9mIChCb3QsIHIyKSA9PiByMg0KCQkgICB8IChyMSwgQm90KSA9PiByMQ0KCQkgICB8
IChMYWJlbCBsMSwgTGFiZWwgbDIpDQoJCSAgID0+IGlmIGxhYmVsX2VxdWFscyhsMSwgbDIpDQoJ
CQl0aGVuIExhYmVsIGwxDQoJCQllbHNlIExhYmVsIGwpDQoNCiAgICAgIGZ1biBjYXNjYWRlIChj
IGFzIFQge3Jjb250LCByZXNldCwgbGVzc1RoYW4sIC4uLn0pDQoJPSBpZiAhcmVzZXQNCgkgICAg
dGhlbiAoKQ0KCSAgICBlbHNlIChyY29udCA6PSBCb3Q7DQoJCSAgcmVzZXQgOj0gdHJ1ZTsNCgkJ
ICBMaXN0LmZvcmVhY2goIWxlc3NUaGFuLCBjYXNjYWRlKSkNCg0KICAgICAgZnVuIHJlZG8gKGMg
YXMgVCB7bGFiZWwsIHJjb250LCByZXNldCwgDQoJCQlsZXNzVGhhbiwgbW9yZVRoYW4sIG1vcmVU
aGFuJywgLi4ufSkNCgk9IGxldA0KCQ0KCSAgICB2YWwgb3AgLy9cXCA9IGZuIChyMSwgcjIpID0+
IC9cIChsYWJlbCwgcjEsIHIyKQ0KCSAgICAgIA0KCSAgICB2YWwgcmNvbnRfb2xkID0gIXJjb250
DQoJICAgIHZhbCByY29udF9uZXcNCgkgICAgICA9IExpc3QuZm9sZA0KCSAgICAgICAgKCFtb3Jl
VGhhbiwNCgkJIExpc3QuZm9sZA0KCQkgKCFtb3JlVGhhbicsDQoJCSAgQm90LA0KCQkgIGZuIChs
LCByY29udF9uZXcpID0+IC8vXFwgKHJjb250X25ldywgTGFiZWwgbCkpLA0KCQkgZm4gKFQge3Jj
b250LCAuLi59LCByY29udF9uZXcpID0+IC8vXFwgKHJjb250X25ldywgIXJjb250KSkNCgkgICAg
dmFsIF8gPSByY29udCA6PSByY29udF9uZXcNCgkgIGluDQoJICAgIGlmIHJjb250X2VxdWFscyhy
Y29udF9vbGQsIHJjb250X25ldykgDQoJICAgICAgIGFuZGFsc28NCgkgICAgICAgbm90ICghcmVz
ZXQpDQoJICAgICAgdGhlbiAoKQ0KCSAgICAgIGVsc2UgKHJlc2V0IDo9IGZhbHNlOw0KCQkgICAg
TGlzdC5mb3JlYWNoKCFsZXNzVGhhbiwgcmVkbykpDQoJICBlbmQNCg0KICAgICAgdmFsIGpvaW4N
Cgk9IGZuIChjIGFzIFQge21vcmVUaGFuLCAuLi59LCBjJyBhcyBUIHtsZXNzVGhhbiwgLi4ufSkN
CgkgICA9PiAoTGlzdC5wdXNoIChsZXNzVGhhbiwgYyk7DQoJICAgICAgIExpc3QucHVzaCAobW9y
ZVRoYW4sIGMnKTsNCgkgICAgICAgY2FzY2FkZSBjOw0KCSAgICAgICByZWRvIGMpDQoNCiAgICAg
IHZhbCBqb2luJw0KCT0gZm4gKGMgYXMgVCB7bW9yZVRoYW4nLCAuLi59LCBsKQ0KCSAgID0+IChM
aXN0LnB1c2ggKG1vcmVUaGFuJywgbCk7DQoJICAgICAgIGNhc2NhZGUgYzsNCgkgICAgICAgcmVk
byBjKQ0KDQogICAgICB2YWwgam9pbidfZg0KCT0gZm4gKGMsIGYpID0+IGpvaW4nIChjLCBGdW5j
TGFiZWwgZikNCiAgICAgIHZhbCBqb2luJ19qDQoJPSBmbiAoYywgaikgPT4gam9pbicgKGMsIEp1
bXBMYWJlbCBqKQ0KDQogICAgICBmdW4gbWFrZVRvcCAoYyBhcyBUIHtsYWJlbCwgLi4ufSkgPSBq
b2luJyAoYywgbGFiZWwpDQoNCiAgICAgIGZ1biBpc1RvcCAoYyBhcyBUIHtsYWJlbCwgcmNvbnQs
IC4uLn0pDQoJPSBjYXNlICFyY29udA0KCSAgICBvZiBCb3QgPT4gZmFsc2UNCgkgICAgIHwgTGFi
ZWwgbCA9PiBsYWJlbF9lcXVhbHMgKGwsIGxhYmVsKQ0KICAgICAgZnVuIGlzQm90IChjIGFzIFQg
e2xhYmVsLCByY29udCwgLi4ufSkNCgk9IGNhc2UgIXJjb250DQoJICAgIG9mIEJvdCA9PiB0cnVl
DQoJICAgICB8IExhYmVsIGwgPT4gZmFsc2UNCiAgIGVuZA0KDQpzdHJ1Y3R1cmUgQ29udFNldCA9
DQogICBzdHJ1Y3QNCiAgICAgIGRhdGF0eXBlIHNldCA9DQoJIEVtcHR5DQogICAgICAgfCBNYWlu
Q29udA0KICAgICAgIHwgT25lIG9mIEp1bXAudA0KICAgICAgIHwgUmV0dXJuIG9mIEZ1bmMudA0K
ICAgICAgIHwgQWxsDQoNCiAgICAgIHZhbCB0b1N0cmluZw0KCT0gZm4gRW1wdHkgPT4gInt9Ig0K
ICAgICAgICAgICB8IE1haW5Db250ID0+ICJNYWluQ29udCINCgkgICB8IE9uZSBqID0+IGNvbmNh
dCBbInsgIiwgSnVtcC50b1N0cmluZyBqLCAiIH0iXQ0KCSAgIHwgUmV0dXJuIGYgPT4gY29uY2F0
IFsieyAiLCBGdW5jLnRvU3RyaW5nIGYsICIgfSJdDQoJICAgfCBBbGwgPT4gIkFsbCINCg0KICAg
ICAgZnVuIGxheW91dFNldCBzID0NCgkgbGV0IG9wZW4gTGF5b3V0DQoJIGluIGNhc2UgcyBvZg0K
CSAgICBFbXB0eSA9PiBzdHIgInt9Ig0KCSAgfCBNYWluQ29udCA9PiBzdHIgIk1haW5Db250Ig0K
CSAgfCBPbmUgaiA9PiBzZXEgW3N0ciAieyAiLCBKdW1wLmxheW91dCBqLCBzdHIgIiB9Il0NCgkg
IHwgUmV0dXJuIGYgPT4gc2VxIFtzdHIgInsgIiwgRnVuYy5sYXlvdXQgZiwgc3RyICIgfSJdDQoJ
ICB8IEFsbCA9PiBzdHIgIkFsbCINCgkgZW5kDQoNCiAgICAgIGRhdGF0eXBlIHQgPSBUIG9mIHtz
ZXQ6IHNldCByZWYsDQoJCQkgbGVzc1RoYW46IHQgbGlzdCByZWZ9DQoNCiAgICAgIGZ1biBzZXQg
KFQge3NldCwgLi4ufSkgPSAhc2V0DQoNCiAgICAgIHZhbCBsYXlvdXQgPSBsYXlvdXRTZXQgbyBz
ZXQNCg0KICAgICAgZnVuIGlzRW1wdHkgYyA9IChjYXNlIHNldCBjIG9mDQoJCQkgIEVtcHR5ID0+
IHRydWUNCgkJCXwgXyA9PiBmYWxzZSkNCgkgDQogICAgICBmdW4gbmV3ICgpID0gVCB7c2V0ID0g
cmVmIEVtcHR5LA0KCQkgICAgICBsZXNzVGhhbiA9IHJlZiBbXX0NCg0KICAgICAgZnVuIHVwIChU
IHtzZXQsIGxlc3NUaGFufSwgcykgPQ0KCSBsZXQNCgkgICAgZnVuIGRvaXQgcyA9IChzZXQgOj0g
czsgTGlzdC5mb3JlYWNoICghbGVzc1RoYW4sIGZuIGMgPT4gdXAgKGMsIHMpKSkNCgkgaW4gY2Fz
ZSAoIXNldCwgcykgb2YNCgkgICAgKF8sIEVtcHR5KSA9PiAoKQ0KCSAgfCAoQWxsLCBfKSA9PiAo
KQ0KCSAgfCAoRW1wdHksIGspID0+IGRvaXQgaw0KCSAgfCAoTWFpbkNvbnQsIE1haW5Db250KSA9
PiAoKQ0KCSAgfCAoT25lIGosIE9uZSBqJykgPT4gaWYgSnVtcC5lcXVhbHMgKGosIGonKSB0aGVu
ICgpIGVsc2UgZG9pdCBBbGwNCgkgIHwgKFJldHVybiBmLCBSZXR1cm4gZicpID0+IGlmIEZ1bmMu
ZXF1YWxzIChmLCBmJykgdGhlbiAoKSBlbHNlIGRvaXQgQWxsDQoJICB8IF8gPT4gZG9pdCBBbGwN
CgkgZW5kDQoNCiAgICAgIHZhbCB1cCA9IFRyYWNlLnRyYWNlMiAoInVwIiwgbGF5b3V0LCBsYXlv
dXRTZXQsIFVuaXQubGF5b3V0KSB1cA0KDQogICAgICB2YWwgb3AgPD0gPQ0KCSBmbiAoVCB7c2V0
LCBsZXNzVGhhbn0sIGMpID0+DQoJICAgICAgKExpc3QucHVzaCAobGVzc1RoYW4sIGMpDQoJICAg
ICAgIDsgdXAgKGMsICFzZXQpKQ0KDQogICAgICBmdW4gYWRkUmV0dXJuIChjLCBmKSA9IHVwIChj
LCBSZXR1cm4gZikNCiAgICAgIGZ1biBhZGRKdW1wIChjLCBqKSA9IHVwIChjLCBPbmUgaikNCiAg
ICAgIGZ1biBhZGRNYWluIGMgPSB1cCAoYywgTWFpbkNvbnQpDQogICAgICBmdW4gbWFrZVRvcCBj
ID0gdXAgKGMsIEFsbCkNCiAgIGVuZA0KCSANCnN0cnVjdHVyZSBDYWxsSW5mbyA9DQogICBzdHJ1
Y3QNCiAgICAgIGRhdGF0eXBlIHQgPQ0KCSBOb091dGVyQ2FsbHMNCiAgICAgICB8IE9uZU91dGVy
Q2FsbA0KICAgICAgIHwgTm90Q29udA0KDQogICAgICB2YWwgdG9TdHJpbmcgPQ0KCSBmbiBOb091
dGVyQ2FsbHMgPT4gIk5vT3V0ZXJDYWxscyINCgkgIHwgT25lT3V0ZXJDYWxsID0+ICJPbmVPdXRl
ckNhbGwiDQoJICB8IE5vdENvbnQgPT4gIk5vdENvbnQiDQoNCiAgICAgIHZhbCBsYXlvdXQgPSBM
YXlvdXQuc3RyIG8gdG9TdHJpbmcNCiAgIGVuZA0KICAgDQpzdHJ1Y3R1cmUgR3JhcGggPSBEaXJl
Y3RlZEdyYXBoDQpzdHJ1Y3R1cmUgTm9kZSA9IEdyYXBoLk5vZGUNCiAgDQpmdW4gY29udGlmeSAo
cHJvZ3JhbSBhcyBQcm9ncmFtLlQge2RhdGF0eXBlcywgZ2xvYmFscywgZnVuY3Rpb25zLCBtYWlu
fSkgPQ0KICAgbGV0DQogICAgICB2YWwgc3RyYXRlZ3kgPSAhQ29udHJvbC5jb250aWZ5U3RyYXRl
Z3kNCiAgIGluIGNhc2Ugc3RyYXRlZ3kgb2YNCiAgICAgIENvbnRyb2wuTm9uZSA9PiBwcm9ncmFt
DQogICAgfCBfID0+IA0KCSBsZXQNCgkgICAgZGF0YXR5cGUgJ2EgcmVwbGFjZSA9DQoJICAgICAg
IE5vbmUNCgkgICAgIHwgT25lQ2FsbCBvZiAnYQ0KCSAgICAgfCBPbmVDb250IG9mICdhDQoJICAg
IHZhbCB7Z2V0ID0gZnVuY0luZm86DQoJCSBGdW5jLnQgLT4gew0KCQkJICAgIGNhbGxlcnM6IEZ1
bmMudCBsaXN0IHJlZiwNCgkJCSAgICBjYWxsSW5mbzogQ2FsbEluZm8udCByZWYsDQoJCQkgICAg
Y2FuUHJlZml4OiBib29sIHJlZiwNCgkJCSAgICBjb250U2V0OiBDb250U2V0LnQsDQoJCQkgICAg
aXNMb2NhbDogYm9vbCByZWYsDQoJCQkgICAgbmVzdGVkOiBGdW5jLnQgbGlzdCByZWYsDQoJCQkg
ICAgbm9kZTogR3JhcGguTm9kZS50IG9wdGlvbiByZWYsDQoJCQkgICAgcG9zc2libGVQcmVmaXhl
czogRnVuYy50IGxpc3QgcmVmLA0KCQkJICAgIHByZWZpeGVzOiBGdW5jLnQgbGlzdCBvcHRpb24g
cmVmLA0KCQkJICAgIHJlcGxhY2U6IHthcmdzOiAoVmFyLnQgKiBUeXBlLnQpIGxpc3QsDQoJCQkJ
ICAgICAgYm9keTogRXhwLnQsDQoJCQkJICAgICAganVtcDogSnVtcC50fSBvcHRpb24gcmVmDQoJ
CQkgICAgfX0gPQ0KCSAgICAgICBQcm9wZXJ0eS5nZXQgKEZ1bmMucGxpc3QsDQoJCQkgICAgIFBy
b3BlcnR5LmluaXRGdW4NCgkJCSAgICAgKGZuIF8gPT4ge2NhbGxlcnMgPSByZWYgW10sDQoJCQkJ
ICAgICAgIGNhbGxJbmZvID0gcmVmIENhbGxJbmZvLk5vT3V0ZXJDYWxscywNCgkJCQkgICAgICAg
Y2FuUHJlZml4ID0gcmVmIGZhbHNlLA0KCQkJCSAgICAgICBjb250U2V0ID0gQ29udFNldC5uZXcg
KCksDQoJCQkJICAgICAgIGlzTG9jYWwgPSByZWYgZmFsc2UsDQoJCQkJICAgICAgIG5lc3RlZCA9
IHJlZiBbXSwNCgkJCQkgICAgICAgbm9kZSA9IHJlZiBOT05FLA0KCQkJCSAgICAgICBwb3NzaWJs
ZVByZWZpeGVzID0gcmVmIFtdLA0KCQkJCSAgICAgICBwcmVmaXhlcyA9IHJlZiBOT05FLA0KCQkJ
CSAgICAgICByZXBsYWNlID0gcmVmIE5PTkV9KSkNCgkgICAgKCogQ29tcHV0ZSB0aGUgY29udFNl
dCBhbmQgY2FsbEluZm8gZm9yIGVhY2ggZnVuY3Rpb24uDQoJICAgICAqIFRoZSBjb250U2V0IGlz
IGFuIG92ZXItYXBwcm94aW1hdGlvbiB0byB0aGUgc2V0IG9mIGNvbnRpbnVhdGlvbnMNCgkgICAg
ICogd2l0aCB3aGljaCB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkLg0KCSAgICAgKiBUaGUgY2FsbElu
Zm8gdGVsbHMgYXQgaG93IG1hbnkgcGxhY2VzIG91dHNpZGUgb2YgaXRzZWxmIGVhY2gNCgkgICAg
ICogZnVuY3Rpb24gaXMgY2FsbGVkLg0KCSAgICAgKikNCgkgICAgdmFsIF8gPSBDb250U2V0LmFk
ZE1haW4gKCNjb250U2V0IChmdW5jSW5mbyBtYWluKSkNCgkgICAgdmFsIF8gPQ0KCSAgICAgICBM
aXN0LmZvcmVhY2gNCgkgICAgICAgKGZ1bmN0aW9ucywgZm4ge25hbWUsIGJvZHksIC4uLn0gPT4N
CgkJbGV0IHZhbCB7Y2FsbEluZm8sIGNvbnRTZXQgPSBjLCAuLi59ID0gZnVuY0luZm8gbmFtZQ0K
CQlpbiBFeHAuZm9yZWFjaENhbGwNCgkJICAgKGJvZHksIGZuIHtmdW5jLCBjb250LCAuLi59ID0+
DQoJCSAgICBpZiBGdW5jLmVxdWFscyhuYW1lLCBmdW5jKQ0KCQkgICAgICAgdGhlbg0KCQkJICBj
YXNlIGNvbnQgb2YNCgkJCSAgICAgTk9ORSA9PiAoKQ0KCQkJICAgfCBTT01FIF8gPT4gKGNhbGxJ
bmZvIDo9IENhbGxJbmZvLk5vdENvbnQNCgkJCQkJOyBDb250U2V0Lm1ha2VUb3AgYykNCgkJICAg
IGVsc2UNCgkJICAgICAgIGxldA0KCQkJICB2YWwge2NhbGxlcnMsIGNhbGxJbmZvID0gY2FsbElu
Zm8nLCBjb250U2V0ID0gYycsIC4uLn0gPQ0KCQkJICAgICBmdW5jSW5mbyBmdW5jDQoJCQkgIHZh
bCBfID0NCgkJCSAgICAgbGV0DQoJCQkJZGF0YXR5cGUgeiA9IGRhdGF0eXBlIENhbGxJbmZvLnQN
CgkJCSAgICAgaW4gY2FzZSAhY2FsbEluZm8nIG9mDQoJCQkJTm9PdXRlckNhbGxzID0+IGNhbGxJ
bmZvJyA6PSBPbmVPdXRlckNhbGwNCgkJCSAgICAgIHwgT25lT3V0ZXJDYWxsID0+IGNhbGxJbmZv
JyA6PSBOb3RDb250DQoJCQkgICAgICB8IE5vdENvbnQgPT4gKCkNCgkJCSAgICAgZW5kDQoJCQkg
IHZhbCBfID0gTGlzdC5wdXNoIChjYWxsZXJzLCBuYW1lKQ0KCQkgICAgICAgaW4gY2FzZSBjb250
IG9mDQoJCQkgIE5PTkUgPT4gQ29udFNldC48PSAoYywgYycpDQoJCQkoKiBDb250U2V0LmFkZFJl
dHVybiAoYywgbmFtZSkgKikNCgkJCXwgU09NRSBqID0+IENvbnRTZXQuYWRkSnVtcCAoYycsIGop
DQoJCSAgICAgICBlbmQpDQoJCWVuZCkNCg0KDQogICAgICAoKiBHYW1tYSBpbiBSRW52ID0gTGFi
ZWwgLT4gUkNvbnQNCiAgICAgICAqKQ0KICAgICAgdmFsIHtnZXQgPSBnZXRfcmNvbnQgOg0KCSAg
IFJDb250LmxhYmVsIC0+IFJDb250LnR9DQoJPSBQcm9wZXJ0eS5nZXQNCgkgIChmbiBSQ29udC5G
dW5jTGFiZWwgZiA9PiBGdW5jLnBsaXN0IGYNCgkgICAgfCBSQ29udC5KdW1wTGFiZWwgaiA9PiBK
dW1wLnBsaXN0IGosDQoJICAgUHJvcGVydHkuaW5pdEZ1biAoZm4gbCA9PiBSQ29udC5uZXcgbCkp
DQoNCiAgICAgIHZhbCBnZXRfcmNvbnRfZiA9IGZuIGYgPT4gZ2V0X3Jjb250IChSQ29udC5GdW5j
TGFiZWwgZikNCiAgICAgIHZhbCBnZXRfcmNvbnRfaiA9IGZuIGogPT4gZ2V0X3Jjb250IChSQ29u
dC5KdW1wTGFiZWwgaikNCg0KICAgICAgKCogUHJvZ3JhbSBhbmFseXNpczoNCiAgICAgICAqIEFu
YWxbPGZ1biBmaSAoPHhpaj4rKSA9IGVpPitdID0gZml4IChmbiBHYW1tYSA9PiBWX2kgUltlaV0g
R2FtbWEnKGZpKSkNCiAgICAgICAqICB3aGVyZSBHYW1tYScgPSBHYW1tYSBWIHttYWluIC0+IG1h
aW59DQogICAgICAgKiAoZml4ZWQgcG9pbnQgbmVjZXNzYXJ5IGJlY2F1c2UgdG9wIGxldmVsIENQ
UyBmdW5jdGlvbnMgYXJlIG11dHVhbGx5DQogICAgICAgKiAgcmVjdXJzaXZlOyBidXQgdGhlIGxl
c3NUaGFuIHRyaWNrIGluIFJDb250IGxldHMgdXMgZG8gaXQgaW4gb25lIHBhc3MpDQogICAgICAg
KiAoaW50aWFsaXppbmcgbWFpbiB0byAibWFpbiIgZW5zdXJlcyB0aGF0IGJvdCBjb3JyZXNwb25k
cyB0byBubyBjYWxscykNCiAgICAgICAqDQogICAgICAgKiBEZWMgYW5hbHlzaXM6DQogICAgICAg
KiBSW2xldCBmdW4gayA8eGk+KyA9IGUgaW4gZSddcCA9IFJbZV1wJyBWIEdhbW1hDQogICAgICAg
KiAgd2hlcmUgR2FtbWEgPSBSW2UnXXAgYW5kIHAnID0gR2FtbWEoaykNCiAgICAgICAqIFJbbGV0
IHZhbCB4ID0gcyBpbiBlJ11wID0gUltlJ11wDQogICAgICAgKiBSW2xldCB2YWwgXyA9IEhhbmRs
ZXJQdXNoIGogaW4gZSddcCA9IFJbZSddcCBWIHtqIC0+IHB9DQogICAgICAgKg0KICAgICAgICog
VHJhbnNmZXIgYW5hbHlzaXM6DQogICAgICAgKiBSW2YgKDx4aT4rKV1wID0ge2YgLT4gcH0NCiAg
ICAgICAqIFJbayAoZiAoPHhpPispKV1wID0ge2sgLT4gcH0gViB7ZiAtPiBrfQ0KICAgICAgICog
UltrICg8eGk+KyldcCA9IHtrIC0+IHB9DQogICAgICAgKiBSWzx4aT4rXXAgPSB7fQ0KICAgICAg
ICogUltjYXNlIHggb2YgPENpID0+IGtpPitdcCA9IFZfaSB7a2kgLT4gcH0NCiAgICAgICAqDQog
ICAgICAgKiBUaGUgbm90YXRpb24gPGV4cChpKT4rIGluZGljYXRlcyBhIGxpc3Qgb2YgZXhwcmVz
c2lvbnMsIGluZGV4ZWQgYnkgaS4NCiAgICAgICAqIFRoZSBub3RhdGlvbiBWX2kgaW5kaWNhdGVz
IHRoZSBqb2luIG92ZXIgYWxsIGkuDQogICAgICAgKikNCg0KICAgICAgKCogQ2FuJ3QgdXNlIEV4
cC5mb3JlYWNoKjsgbmVlZCB0byBjaGFuZ2UgcmNvbnQNCiAgICAgICAqIGZvciBkZWNlbnQgaW50
byBib2R5IG9mIERlYy5GdW4uDQogICAgICAgKikNCg0KICAgICAgdmFsIF8gPSBSQ29udC5tYWtl
VG9wIChnZXRfcmNvbnRfZiBtYWluKQ0KDQogICAgICB2YWwgXyANCgk9IExpc3QuZm9yZWFjaA0K
CSAgKGZ1bmN0aW9ucywgDQoJICAgZm4ge25hbWUsIGJvZHksIC4uLn0gDQoJICAgID0+IGxldA0K
CQkgKCogQ2FuJ3QgdXNlIEV4cC5mb3JlYWNoKjsgbmVlZCB0byBjaGFuZ2UgcmNvbnQNCgkJICAq
IGZvciBkZWNlbnQgaW50byBib2R5IG9mIERlYy5GdW4uDQoJCSAgKikNCgkJIGZ1biBkb2l0IChi
b2R5LCByY29udCkNCgkJICAgPSBsZXQNCgkJICAgICAgIHZhbCB7ZGVjcywgdHJhbnNmZXJ9ID0g
RXhwLmRlc3QgYm9keQ0KCQkgICAgIGluDQoJCSAgICAgICBMaXN0LmZvcmVhY2gNCgkJICAgICAg
IChkZWNzLA0KCQkJZm4gRGVjLkZ1biB7bmFtZSwgYm9keSwgLi4ufQ0KCQkJID0+IGRvaXQgKGJv
ZHksIGdldF9yY29udF9qIG5hbWUpDQoJCSAgICAgICAgIHwgRGVjLkhhbmRsZXJQdXNoIGp1bXAN
CgkJCSA9PiBSQ29udC5qb2luIChnZXRfcmNvbnRfaiBqdW1wLCByY29udCkNCgkJICAgICAgICAg
fCBfID0+ICgpKTsNCgkJICAgICAgIGNhc2UgdHJhbnNmZXINCgkJCSBvZiBUcmFuc2Zlci5DYWxs
IHtmdW5jLCBjb250LCAuLi59IA0KCQkJICA9PiBsZXQNCgkJCSAgICAgICB2YWwgZnJjb250ID0g
Z2V0X3Jjb250X2YgZnVuYw0KCQkJICAgICBpbg0KCQkJICAgICAgIGNhc2UgY29udA0KCQkJCSBv
ZiBOT05FID0+IGlmIEZ1bmMuZXF1YWxzKGZ1bmMsIG5hbWUpDQoJCQkJCSAgICAgIHRoZW4gKCkN
CgkJCQkJICAgICAgZWxzZSBSQ29udC5qb2luIChmcmNvbnQsIHJjb250KQ0KCQkJCSAgfCBTT01F
IGp1bXANCgkJCQkgID0+IChSQ29udC5qb2luJ19qIChmcmNvbnQsIGp1bXApOw0KCQkJCSAgICAg
IFJDb250LmpvaW4gKGdldF9yY29udF9qIGp1bXAsIHJjb250KSkNCgkJCSAgICAgZW5kDQoJCQkg
IHwgVHJhbnNmZXIuQ2FzZSB7Y2FzZXMsIGRlZmF1bHQsIC4uLn0NCgkJCSAgPT4gKENhc2VzLmZv
cmVhY2gNCgkJCSAgICAgIChjYXNlcywNCgkJCSAgICAgICBmbiBqdW1wIA0KCQkJICAgICAgICA9
PiBSQ29udC5qb2luIChnZXRfcmNvbnRfaiBqdW1wLCByY29udCkpOw0KCQkJICAgICAgY2FzZSBk
ZWZhdWx0DQoJCQkJb2YgTk9ORSA9PiAoKQ0KCQkJCXwgU09NRSBqdW1wIA0KCQkJCT0+IFJDb250
LmpvaW4gKGdldF9yY29udF9qIGp1bXAsIHJjb250KSkNCgkJCSAgfCBUcmFuc2Zlci5KdW1wIHtk
c3QsIC4uLn0NCgkJCSAgPT4gUkNvbnQuam9pbiAoZ2V0X3Jjb250X2ogZHN0LCByY29udCkNCgkJ
CSAgfCBfID0+ICgpDQoJCSAgICAgZW5kCQkgICANCgkgICAgICAgaW4gDQoJCSBkb2l0IChib2R5
LCBnZXRfcmNvbnRfZiBuYW1lKQ0KCSAgICAgICBlbmQpDQoNCiAgICAgICgqIExldCBHYW1tYSA9
IEFuYWxbcHJvZ10NCiAgICAgICAqIA0KICAgICAgICogY2FzZSBHYW1tYShsKQ0KICAgICAgICog
ICBvZiBib3QgPT4gZnVuY3Rpb24gd2l0aCBsYWJlbCBsIGlzIG5ldmVyIGNhbGxlZA0KICAgICAg
ICogICAgfCByID0+IGlmIHIgPD4gbA0KICAgICAgICogICAgICAgICAgICB0aGVuIHRoZSBmdW5j
dGlvbiB3aXRoIGxhYmVsIGwgaGFzIGV4YWN0bHkgb25lDQogICAgICAgKiAgICAgICAgICAgICAg
ICAgY29udGludWF0aW9uIChyKSBhbmQgaXMgY29udGlmaWFibGUNCiAgICAgICAqICAgICAgICAg
ICAgZWxzZSB0aGUgZnVuY3Rpb24gd2l0aCBsYWJlbCBsIGhhcyBtb3JlIHRoYW4gb25lDQogICAg
ICAgKiAgICAgICAgICAgICAgICAgY29udGludWF0aW9uIGlzIGlzIG5vdCBjb250aWZpYWJsZQ0K
ICAgICAgICopDQoNCgkgICAgKCogUmVjb3JkIGZvciBlYWNoIGp1bXAgdGhlIGZ1bmN0aW9ucyB0
aGF0IG1pZ2h0IGJlIHR1cm5lZCBpbnRvDQoJICAgICAqIGNvbnRpbnVhdGlvbnMgYXMgaXRzIHBy
ZWZpeGVzLg0KCSAgICAgKiBSZWNvcmQgZm9yIGVhY2ggZnVuY3Rpb24gdGhlIGZ1bmN0aW9ucyB0
aGF0IG1pZ2h0IHByZWZpeCBpdHMNCgkgICAgICogcmV0dXJuLg0KCSAgICAgKikNCgkgICAgdmFs
IHtnZXQgPSBqdW1wSW5mbzogSnVtcC50IC0+DQoJCSB7cG9zc2libGVQcmVmaXhlczogRnVuYy50
IGxpc3QgcmVmLA0KCQkgIHByZWZpeGVzOiBGdW5jLnQgbGlzdCBvcHRpb24gcmVmfX0gPQ0KCSAg
ICAgICBQcm9wZXJ0eS5nZXQgKEp1bXAucGxpc3QsDQoJCQkgICAgIFByb3BlcnR5LmluaXRGdW4N
CgkJCSAgICAgKGZuIF8gPT4ge3Bvc3NpYmxlUHJlZml4ZXMgPSByZWYgW10sDQoJCQkJICAgICAg
IHByZWZpeGVzID0gcmVmIE5PTkV9KSkNCgkgICAgdmFsIHRvZG8gPSByZWYgW10NCgkgICAgdmFs
IF8gPQ0KCSAgICAgICBMaXN0LmZvcmVhY2gNCgkgICAgICAgKGZ1bmN0aW9ucywgZm4ge25hbWUs
IC4uLn0gPT4NCgkJbGV0DQoJCSAgIGZ1biBkb2l0IChwb3NzaWJsZVByZWZpeGVzLCBwcmVmaXhl
cykgPQ0KCQkgICAgICBsZXQNCgkJCSB2YWwgXyA9DQoJCQkgICAgY2FzZSAhcG9zc2libGVQcmVm
aXhlcyBvZg0KCQkJICAgICAgIFtdID0+IExpc3QucHVzaCAodG9kbywNCgkJCQkJCShwb3NzaWJs
ZVByZWZpeGVzLCBwcmVmaXhlcykpDQoJCQkgICAgIHwgXyA9PiAoKQ0KCQkgICAgICBpbiBMaXN0
LnB1c2ggKHBvc3NpYmxlUHJlZml4ZXMsIG5hbWUpDQoJCSAgICAgIGVuZA0KDQooKiBIZXJlIHdh
cyBteSBhdHRlbXB0IHRvIHBsdWcgaW4gdGhlIG5ldyBhbmFseXNpczsNCiAqIEkgd2FzIGhvcGlu
ZyB0byBqdXN0IGlnbm9yZSBldmVyeXRoaW5nIGhhdmluZyB0byBkbyB3aXRoIGNvbnRTZXRzDQog
KiBhbmQgdHJ5IHRvIG1pbWljIGl0IHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgY2hlY2tzIG9mIHRo
ZSBuZXcgYW5heXNpcywNCiAqIGJ1dCBpdCBkb2Vzbid0IHdvcmsuDQogKikNCigqDQoJCWluIA0K
CQkgIGNhc2UgUkNvbnQucmNvbnQgKGdldF9yY29udF9mIG5hbWUpDQoJCSAgICBvZiBSQ29udC5C
b3QgPT4gKCkNCgkJICAgICB8IFJDb250LkxhYmVsIChSQ29udC5GdW5jTGFiZWwgZikNCgkJICAg
ICA9PiBpZiBGdW5jLmVxdWFscyhmLCBuYW1lKQ0KCQkJICB0aGVuICgpDQoJCQkgIGVsc2UgbGV0
IHZhbCB7cG9zc2libGVQcmVmaXhlcywgcHJlZml4ZXMsIC4uLn0gDQoJCQkgICAgICAgICAgICAg
PSBmdW5jSW5mbyBmDQoJCQkgICAgICAgaW4gZG9pdCAocG9zc2libGVQcmVmaXhlcywgcHJlZml4
ZXMpDQoJCQkgICAgICAgZW5kDQoJCSAgICAgfCBSQ29udC5MYWJlbCAoUkNvbnQuSnVtcExhYmVs
IGopDQoJCSAgICAgPT4gbGV0IHZhbCB7cG9zc2libGVQcmVmaXhlcywgcHJlZml4ZXMsIC4uLn0g
DQoJCQkgICAgICA9IGp1bXBJbmZvIGoNCgkJCWluIGRvaXQgKHBvc3NpYmxlUHJlZml4ZXMsIHBy
ZWZpeGVzKQ0KCQkJZW5kDQoJCWVuZCkNCiopDQoNCgkJICAgdmFsIHtjb250U2V0LCAuLi59ID0g
ZnVuY0luZm8gbmFtZQ0KCQlpbiBjYXNlIENvbnRTZXQuc2V0IGNvbnRTZXQgb2YNCgkJICAgQ29u
dFNldC5PbmUgaiA9PiANCgkJICAgICAgbGV0IHZhbCB7cG9zc2libGVQcmVmaXhlcywgcHJlZml4
ZXMsIC4uLn0gPSBqdW1wSW5mbyBqDQoJCSAgICAgIGluIGRvaXQgKHBvc3NpYmxlUHJlZml4ZXMs
IHByZWZpeGVzKQ0KCQkgICAgICBlbmQNCgkJIHwgQ29udFNldC5SZXR1cm4gZiA9Pg0KCQkgICAg
ICBsZXQgdmFsIHtwb3NzaWJsZVByZWZpeGVzLCBwcmVmaXhlcywgLi4ufSA9IGZ1bmNJbmZvIGYN
CgkJICAgICAgaW4gZG9pdCAocG9zc2libGVQcmVmaXhlcywgcHJlZml4ZXMpDQoJCSAgICAgIGVu
ZA0KCQkgfCBfID0+ICgpDQoJCWVuZCkNCg0KCSAgICAoKiBTdHJvbmdseSBjb25uZWN0ZWQgY29t
cG9uZW50cyBvZiBhIGdyb3VwIG9mIGZ1bmN0aW9ucy4gKikNCgkgICAgZnVuIHNjY3MgKGZzOiBG
dW5jLnQgbGlzdCkgPQ0KCSAgICAgICBsZXQNCgkJICB2YWwgZyA9IEdyYXBoLm5ldyAoKQ0KCQkg
IHZhbCB7Z2V0ID0gbm9kZUZ1bmMsIHNldCA9IHNldE5vZGVGdW5jfSA9DQoJCSAgICAgUHJvcGVy
dHkuZ2V0U2V0T25jZQ0KCQkgICAgIChOb2RlLnBsaXN0LCBQcm9wZXJ0eS5pbml0UmFpc2UgKCJm
dW5jIiwgTm9kZS5sYXlvdXQpKQ0KCQkgICB2YWwgXyA9DQoJCSAgICAgIExpc3QuZm9yZWFjaCAo
ZnMsIGZuIGYgPT4NCgkJCQkgICAgbGV0IHZhbCB7bm9kZSwgLi4ufSA9IGZ1bmNJbmZvIGYNCgkJ
CQkgICAgICAgdmFsIG4gPSBHcmFwaC5uZXdOb2RlIGcNCgkJCQkgICAgICAgdmFsIF8gPSBzZXRO
b2RlRnVuYyAobiwgZikNCgkJCQkgICAgICAgdmFsIF8gPSBub2RlIDo9IFNPTUUgbg0KCQkJCSAg
ICBpbiAoKQ0KCQkJCSAgICBlbmQpDQoJCSAgICgqIEJ1aWxkIHRoZSBjYWxsIGdyYXBoLg0KCQkg
ICAgKiBFZGdlcyBnbyBmcm9tIG5vZGVzIHRvIHRoZSBjYWxsZXJzLg0KCQkgICAgKikNCgkJICAg
dmFsIF8gPQ0KCQkgICAgICBMaXN0LmZvcmVhY2gNCgkJICAgICAgKGZzLCBmbiBmID0+DQoJCSAg
ICAgICBsZXQgdmFsIHtub2RlLCBjYWxsZXJzLCAuLi59ID0gZnVuY0luZm8gZg0KCQkJICB2YWwg
ZnJvbSA9IHZhbE9mICghbm9kZSkNCgkJICAgICAgIGluIExpc3QuZm9yZWFjaA0KCQkJICAoIWNh
bGxlcnMsIGZuIGYnID0+DQoJCQkgICBsZXQgdmFsIHtub2RlLCAuLi59ID0gZnVuY0luZm8gZicN
CgkJCSAgIGluIGNhc2UgIW5vZGUgb2YNCgkJCSAgICAgIE5PTkUgPT4gKCkNCgkJCSAgICB8IFNP
TUUgdG8gPT4NCgkJCQkgKEdyYXBoLmFkZEVkZ2UgKGcsIHtmcm9tID0gZnJvbSwgdG8gPSB0b30p
DQoJCQkJICA7ICgpKQ0KCQkJICAgZW5kKQ0KCQkgICAgICAgZW5kKQ0KCQkgICB2YWwgXyA9IExp
c3QuZm9yZWFjaCAoZnMsIGZuIGYgPT4gI25vZGUgKGZ1bmNJbmZvIGYpIDo9IE5PTkUpDQoJCSAg
IHZhbCBuc3MgPSBHcmFwaC5zdHJvbmdseUNvbm5lY3RlZENvbXBvbmVudHMgZw0KCSAgICAgICBp
biBMaXN0Lm1hcCAobnNzLCBmbiBucyA9PiBMaXN0LnJldk1hcCAobnMsIG5vZGVGdW5jKSkNCgkg
ICAgICAgZW5kDQoJICAgIA0KCSAgICAoKiBGb3IgZWFjaCBjb2xsZWN0aW9uIG9mIGZ1bmN0aW9u
cyB0aGF0IGFyZSBnb2luZyB0byBwcmVmaXggYSBjb250LA0KCSAgICAgKiBkbyBhIHN0cm9uZ2x5
IGNvbm5lY3RlZCBjb21wb25lbnRzIGNvbXB1dGF0aW9uLiAgSW4gb3JkZXIgZm9yIHRoZQ0KCSAg
ICAgKiBmdW5jdGlvbnMgdG8gYmUgY29udGlmaWVkLCB0aGVyZSBjYW4gYmUgYXQgbW9zdCBvbmUg
ZnVuY3Rpb24gaW4NCgkgICAgICogZWFjaCBjb21wb25lbnQgdGhhdCBpcyBjYWxsZWQgZnJvbSBv
dXRzaWRlLiAgVGhpcyBpcyBkdWUgdG8gdGhlDQoJICAgICAqIGZhY3QgdGhhdCBtdXR1YWxseSBy
ZWN1cnNpdmUgY29udGludWF0aW9ucyBjYW5ub3QgYmUgZGlyZWN0bHkNCgkgICAgICogZGVjbGFy
ZWQgaW4gQ1BTIC0tIHRoZSBvbmx5IHdheSB0byBkbyBzbyBpcyB0byBuZXN0IG9uZSB3aXRoaW4g
dGhlDQoJICAgICAqIG90aGVyLiAgVGh1cyBvbmx5IG9uZSBjYW4gYmUgImV4cG9ydGVkIi4NCgkg
ICAgICopDQoJICAgIGV4Y2VwdGlvbiBOb3BlDQoJICAgICgqIHNjY0hlYWRzIHJldHVybnMgdGhl
IGhlYWQgZnVuY3Rpb24gZm9yIGVhY2ggc2NjIGluIHRoZSBsaXN0IG9mDQoJICAgICAqIGZ1bmN0
aW9ucy4gIEl0IHJhaXNlcyBOb3BlIGlmIHRoZXJlIGlzIGFuIHNjYyB3aXRoIG1vcmUgdGhhbiBv
bmUNCgkgICAgICogZnVuY3Rpb24gY2FsbGVkIGZyb20gb3V0c2lkZSB0aGUgc2NjLg0KCSAgICAg
KikNCgkgICAgZnVuIHNjY0hlYWRzIChmczogRnVuYy50IGxpc3QpOiBGdW5jLnQgbGlzdCA9DQoJ
ICAgICAgIExpc3QubWFwDQoJICAgICAgIChzY2NzIGZzLCBmbiBmcyA9Pg0KCQlsZXQNCgkJICAg
ZnVuIHNldExvY2FsIGIgPQ0KCQkgICAgICBMaXN0LmZvcmVhY2ggKGZzLCBmbiBmID0+ICNpc0xv
Y2FsIChmdW5jSW5mbyBmKSA6PSBiKQ0KCQkgICB2YWwgXyA9IHNldExvY2FsIHRydWUNCgkJICAg
dmFsIG91dHNpZGVDYWxsZXIgPSByZWYgTk9ORQ0KCQkgICB2YWwgXyA9DQoJCSAgICAgIExpc3Qu
Zm9yZWFjaA0KCQkgICAgICAoZnMsIGZuIGYgPT4NCgkJICAgICAgIGxldCB2YWwge2NhbGxlcnMs
IC4uLn0gPSBmdW5jSW5mbyBmDQoJCSAgICAgICBpbiBpZiBMaXN0LmV4aXN0cyAoIWNhbGxlcnMs
IGZuIGYgPT4NCgkJCQkJICBub3QgKCEoI2lzTG9jYWwgKGZ1bmNJbmZvIGYpKSkpDQoJCQkgICAg
IHRoZW4gKGNhc2UgIW91dHNpZGVDYWxsZXIgb2YNCgkJCQkgICAgICBTT01FIF8gPT4gcmFpc2Ug
Tm9wZQ0KCQkJCSAgICB8IE5PTkUgPT4gb3V0c2lkZUNhbGxlciA6PSBTT01FIGYpDQoJCQkgIGVs
c2UgKCkNCgkJICAgICAgIGVuZCkNCgkJICAgdmFsIF8gPSBzZXRMb2NhbCBmYWxzZQ0KCQlpbiBj
YXNlICFvdXRzaWRlQ2FsbGVyIG9mDQoJCSAgIE5PTkUgPT4gRXJyb3IuYnVnICJubyBvdXRzaWRl
IGNhbGxlciINCgkJIHwgU09NRSBmID0+DQoJCSAgICAgIGxldA0KCQkJIHZhbCB7bmVzdGVkLCAu
Li59ID0gZnVuY0luZm8gZg0KCQkJIHZhbCByZXN0ID0gTGlzdC5yZW1vdmVGaXJzdCAoZnMsIGZu
IGYnID0+DQoJCQkJCQkgICAgICBGdW5jLmVxdWFscyAoZiwgZicpKQ0KCQkJIHZhbCBfID0gbmVz
dGVkIDo9IHNjY0hlYWRzIHJlc3QNCgkJICAgICAgaW4gZg0KCQkgICAgICBlbmQNCgkJZW5kKQ0K
CSAgICB2YWwgXyA9DQoJICAgICAgIExpc3QuZm9yZWFjaA0KCSAgICAgICAoIXRvZG8sIGZuIChw
b3NzaWJsZVByZWZpeGVzLCBwcmVmaXhlcykgPT4NCgkJbGV0DQoJCSAgIHZhbCBmcyA9ICFwb3Nz
aWJsZVByZWZpeGVzDQoJCSAgIHZhbCBfID0gcHJlZml4ZXMgOj0gU09NRSAoc2NjSGVhZHMgZnMp
DQoJCSAgIHZhbCBfID0gTGlzdC5mb3JlYWNoIChmcywgZm4gZiA9Pg0KCQkJCQkgI2NhblByZWZp
eCAoZnVuY0luZm8gZikgOj0gdHJ1ZSkNCgkJaW4gKCkNCgkJZW5kIGhhbmRsZSBOb3BlID0+ICgp
KQ0KCSAgICAoKiBEaWFnbm9zdGljcy4gKikNCgkgICAgdmFsIF8gPQ0KCSAgICAgICBpZiBmYWxz
ZQ0KCQkgIHRoZW4gDQoJCSAgICAgbGV0DQooKiBPTEQgRElBR05PU1RJQ1MgKikNCigqDQoJCQl2
YWwgXyA9DQoJCQkgICBQcm9ncmFtLmxheW91dHMNCgkJCSAgIChwcm9ncmFtLCBmbiBsID0+IA0K
CQkJICAgIChMYXlvdXQub3V0cHV0IChsLCBPdXQuZXJyb3IpDQoJCQkgICAgIDsgT3V0Lm5ld2xp
bmUgT3V0LmVycm9yKSkNCgkJCXZhbCBvbGQgPSByZWYgMA0KCQkJdmFsIG5ldyA9IHJlZiAwDQoJ
CQl2YWwgbmV3Tm8gPSByZWYgMA0KCQkJdmFsIHNhbWUgPSByZWYgMA0KCQkJdmFsIHNhbWVObyA9
IHJlZiAwDQoNCgkJCXZhbCBuZXdlciA9IHJlZiAwDQoJCSAgICAgaW4gTGlzdC5mb3JlYWNoDQoJ
CQkoZnVuY3Rpb25zLCBmbiB7bmFtZSwgLi4ufSA9Pg0KCQkJIGxldA0KCQkJICAgIHZhbCB7Y2Fs
bEluZm8sIGNhblByZWZpeCwgY29udFNldCwgLi4ufSA9IGZ1bmNJbmZvIG5hbWUNCgkJCSAgICBm
dW4gZG9pdCAociwgcykgPQ0KCQkJICAgICAgIChJbnQuaW5jIHINCgkJCQk7IGlmIHRydWUNCgkJ
CQkgICAgIHRoZW4gcHJpbnQgKGNvbmNhdCBbcywgIiAiLA0KCQkJCQkJCSBGdW5jLnRvU3RyaW5n
IG5hbWUsICJcbiJdKQ0KCQkJCSAgZWxzZSAoKSkNCgkJCSAgICBkYXRhdHlwZSB6ID0gZGF0YXR5
cGUgQ2FsbEluZm8udA0KCQkJICAgIGRhdGF0eXBlIHogPSBkYXRhdHlwZSBDb250U2V0LnNldA0K
CQkJIGluIGNhc2UgKCFjYWxsSW5mbywgQ29udFNldC5zZXQgY29udFNldCkgb2YNCgkJCSAgICAo
T25lT3V0ZXJDYWxsLCBPbmUgXykgPT4NCgkJCSAgICAgICBpZiAhY2FuUHJlZml4DQoJCQkJICB0
aGVuIGRvaXQgKHNhbWUsICJzYW1lIikNCgkJCSAgICAgICBlbHNlIGRvaXQgKHNhbWVObywgInNh
bWVObyIpDQoJCQkgIHwgKE9uZU91dGVyQ2FsbCwgXykgPT4gZG9pdCAob2xkLCAib2xkIikNCgkJ
CSAgfCAoXywgT25lIF8pID0+DQoJCQkgICAgICAgaWYgIWNhblByZWZpeA0KCQkJCSAgdGhlbiBk
b2l0IChuZXcsICJuZXciKQ0KCQkJICAgICAgIGVsc2UgZG9pdCAobmV3Tm8sICJuZXdObyIpDQoJ
CQkgIHwgXyA9PiAoKQ0KCQkJIGVuZCkNCgkJCTsgcHJpbnQgKGNvbmNhdA0KCQkJCSBbIm51bSBm
dW5jdGlvbnMgIiwNCgkJCQkgIEludC50b1N0cmluZyAoTGlzdC5sZW5ndGggZnVuY3Rpb25zKSwN
CgkJCQkgICIgIHNhbWUgIiwgSW50LnRvU3RyaW5nICghc2FtZSksDQoJCQkJICAiICBzYW1lTm8g
IiwgSW50LnRvU3RyaW5nICghc2FtZU5vKSwNCgkJCQkgICIgIG51bSBuZXcgIiwgSW50LnRvU3Ry
aW5nICghbmV3KSwNCgkJCQkgICIgIG51bSBuZXdObyAiLCBJbnQudG9TdHJpbmcgKCFuZXdObyks
DQoJCQkJICAiICBudW0gb2xkICIsIEludC50b1N0cmluZyAoIW9sZCksDQoJCQkJICAiXG4iXSkN
CiopDQoNCigqIE5FVyBESUFHTk9TVElDUyAqKQ0KDQooKiBwcmludCBvdXQgZW50aXJlIGNwcyBJ
TCAqKQ0KCQkJdmFsIF8NCgkJCSAgPSBpZiB0cnVlDQoJCQkgICAgICB0aGVuIFByb2dyYW0ubGF5
b3V0cw0KCQkJCSAgIChwcm9ncmFtLCANCgkJCQkgICAgZm4gbCA9PiAoTGF5b3V0Lm91dHB1dCAo
bCwgT3V0LmVycm9yKQ0KCQkJCQkgICAgIDsgT3V0Lm5ld2xpbmUgT3V0LmVycm9yKSkNCgkJCSAg
ICAgIGVsc2UgKCkNCg0KCQkJdmFsIGNhbGxfY29udF9uZXcgPSByZWYgMA0KCQkJdmFsIGNhbGxf
Y29udCA9IHJlZiAwDQoJCQl2YWwgY2FsbF9uZXcgPSByZWYgMA0KCQkJdmFsIGNvbnRfbmV3ID0g
cmVmIDANCgkJCXZhbCBjYWxsID0gcmVmIDANCgkJCXZhbCBjb250ID0gcmVmIDANCgkJCXZhbCBu
ZXcgPSByZWYgMA0KCQkgICAgIGluIExpc3QuZm9yZWFjaA0KCQkJKGZ1bmN0aW9ucywgZm4ge25h
bWUsIC4uLn0gPT4NCgkJCSBsZXQNCgkJCSAgICB2YWwge2NhbGxJbmZvLCBjYW5QcmVmaXgsIGNv
bnRTZXQsIC4uLn0gDQoJCQkgICAgICA9IGZ1bmNJbmZvIG5hbWUNCgkJCSAgICB2YWwgcmNvbnQg
PSBnZXRfcmNvbnRfZiBuYW1lDQoNCigqIHByaW50IG91dCB0aGUgcmNvbnQgZm9yIGVhY2ggZnVu
Y3Rpb24gKikNCgkJCSAgICB2YWwgXyANCgkJCSAgICAgID0gaWYgdHJ1ZQ0KCQkJCSAgdGhlbiBw
cmludCAoY29uY2F0IFtGdW5jLnRvU3RyaW5nIG5hbWUsDQoJCQkJCQkgICAgICAiIDogIiwNCgkJ
CQkJCSAgICAgIFJDb250LnRvU3RyaW5nIHJjb250LA0KCQkJCQkJICAgICAgIlxuIl0pDQoJCQkJ
ICBlbHNlICgpDQooKiBwcmludCBvdXQgdGhlIGNvbnQgc2V0IGZvciBlYWNoIGZ1bmN0aW9uICop
DQoJCQkgICAgdmFsIF8gDQoJCQkgICAgICA9IGlmIHRydWUNCgkJCQkgIHRoZW4gcHJpbnQgKGNv
bmNhdCBbRnVuYy50b1N0cmluZyBuYW1lLA0KCQkJCQkJICAgICAgIiA6ICIsDQoJCQkJCQkgICAg
ICBDb250U2V0LnRvU3RyaW5nIA0KCQkJCQkJICAgICAgKENvbnRTZXQuc2V0IGNvbnRTZXQpLA0K
CQkJCQkJICAgICAgIlxuIl0pDQoJCQkJICBlbHNlICgpDQoNCgkJCSAgICBmdW4gZG9pdCAociwg
cykgPQ0KCQkJICAgICAgIChJbnQuaW5jIHINCgkJCQk7IGlmIHRydWUNCgkJCQkgICAgIHRoZW4g
cHJpbnQgKGNvbmNhdCBbcywgDQoJCQkJCQkJICIgIiwNCgkJCQkJCQkgRnVuYy50b1N0cmluZyBu
YW1lLCANCgkJCQkJCQkgIlxuIl0pDQoJCQkJICBlbHNlICgpKQ0KDQoJCQkgICAgZGF0YXR5cGUg
eiA9IGRhdGF0eXBlIENhbGxJbmZvLnQNCgkJCSAgICBkYXRhdHlwZSB6ID0gZGF0YXR5cGUgQ29u
dFNldC5zZXQNCgkJCSAgICBkYXRhdHlwZSB6ID0gZGF0YXR5cGUgUkNvbnQucmNvbnQgDQoNCgkJ
CSAgICB2YWwgY2FuX2NhbGwgPSBjYXNlICFjYWxsSW5mbw0KCQkJCQkgICAgIG9mIE9uZU91dGVy
Q2FsbCA9PiB0cnVlDQoJCQkJCSAgICAgIHwgXyA9PiBmYWxzZQ0KCQkJICAgIHZhbCBjYW5fY29u
dCA9IGNhc2UgQ29udFNldC5zZXQgY29udFNldA0KCQkJCQkgICAgIG9mIE9uZSBfID0+IHRydWUN
CgkJCQkJICAgICAgfCBfID0+IGZhbHNlIA0KCQkJICAgIHZhbCByZW1fY29udCA9IGNhc2UgQ29u
dFNldC5zZXQgY29udFNldA0KCQkJCQkgICAgIG9mIEVtcHR5ID0+IHRydWUNCgkJCQkJICAgICAg
fCBfID0+IGZhbHNlDQoJCQkgICAgdmFsIGNhbl9uZXcgPSBub3QgKFJDb250LmlzVG9wIHJjb250
KQ0KCQkJICAgICAgICAgICAgICAgICAgYW5kYWxzbw0KCQkJCQkgIG5vdCAoUkNvbnQuaXNCb3Qg
cmNvbnQpDQoJCQkgICAgdmFsIHJlbV9uZXcgPSBSQ29udC5pc0JvdCByY29udA0KCQkJIGluIGNh
c2UgKGNhbl9jYWxsLCBjYW5fY29udCwgY2FuX25ldykNCgkJCSAgICAgIG9mICh0cnVlLCB0cnVl
LCB0cnVlKSANCgkJCSAgICAgICA9PiBkb2l0KGNhbGxfY29udF9uZXcsICJjYWxsX2NvbnRfbmV3
IikNCgkJCSAgICAgICB8ICh0cnVlLCB0cnVlLCBmYWxzZSkgDQoJCQkgICAgICAgPT4gZG9pdChj
YWxsX2NvbnQsICJjYWxsX2NvbnQiKQ0KCQkJICAgICAgIHwgKHRydWUsIGZhbHNlLCB0cnVlKSAN
CgkJCSAgICAgICA9PiBkb2l0KGNhbGxfbmV3LCAiY2FsbF9uZXciKQ0KCQkJICAgICAgIHwgKHRy
dWUsIGZhbHNlLCBmYWxzZSkgDQoJCQkgICAgICAgPT4gZG9pdChjYWxsLCAiY2FsbCIpDQoJCQkg
ICAgICAgfCAoZmFsc2UsIHRydWUsIHRydWUpIA0KCQkJICAgICAgID0+IGRvaXQoY29udF9uZXcs
ICJjb250X25ldyIpDQoJCQkgICAgICAgfCAoZmFsc2UsIHRydWUsIGZhbHNlKSANCgkJCSAgICAg
ICA9PiBkb2l0KGNvbnQsICJjb250IikNCgkJCSAgICAgICB8IChmYWxzZSwgZmFsc2UsIHRydWUp
IA0KCQkJICAgICAgID0+IGRvaXQobmV3LCAibmV3IikNCgkJCSAgICAgICB8IChmYWxzZSwgZmFs
c2UsIGZhbHNlKSA9PiAoKQ0KCQkJIGVuZCkNCgkJCTsgcHJpbnQgKGNvbmNhdA0KCQkJCSBbImZ1
bmN0aW9uczogIiwNCgkJCQkgIEludC50b1N0cmluZyAoTGlzdC5sZW5ndGggZnVuY3Rpb25zKSwN
CgkJCQkgICIgIGNhbGxfY29udF9uZXc6ICIsIA0KCQkJCSAgSW50LnRvU3RyaW5nICghY2FsbF9j
b250X25ldyksDQoJCQkJICAiICBjYWxsX2NvbnQ6ICIsIA0KCQkJCSAgSW50LnRvU3RyaW5nICgh
Y2FsbF9jb250KSwNCgkJCQkgICIgIGNhbGxfbmV3OiAiLA0KCQkJCSAgSW50LnRvU3RyaW5nICgh
Y2FsbF9uZXcpLA0KCQkJCSAgIiAgY29udF9uZXc6ICIsIA0KCQkJCSAgSW50LnRvU3RyaW5nICgh
Y29udF9uZXcpLA0KCQkJCSAgIiAgY2FsbDogIiwgDQoJCQkJICBJbnQudG9TdHJpbmcgKCFjYWxs
KSwNCgkJCQkgICIgIGNvbnQ6ICIsIA0KCQkJCSAgSW50LnRvU3RyaW5nICghY29udCksDQoJCQkJ
ICAiICBuZXc6ICIsIA0KCQkJCSAgSW50LnRvU3RyaW5nICghbmV3KSwNCgkJCQkgICJcbiJdKQ0K
CQkgICAgIGVuZA0KCSAgICAgICBlbHNlICgpDQoJICAgICgqIEZvciBmdW5jdGlvbnMgdHVybmVk
IGludG8gY29udGludWF0aW9ucywgcmVjb3JkIHRoZWlyDQoJICAgICAqIGFyZ3MsIGJvZHksIGFu
ZCBuZXcgbmFtZS4NCgkgICAgICopDQoJICAgIHZhbCBfID0NCgkgICAgICAgTGlzdC5mb3JlYWNo
DQoJICAgICAgIChmdW5jdGlvbnMsIGZuIHtuYW1lLCBhcmdzLCBib2R5LCAuLi59ID0+DQoJCWxl
dCB2YWwge2NhbGxJbmZvLCBjYW5QcmVmaXgsIHJlcGxhY2UsIC4uLn0gPSBmdW5jSW5mbyBuYW1l
DQoJCSAgIHZhbCBvbmVDYWxsID0NCgkJICAgICAgY2FzZSAhY2FsbEluZm8gb2YNCgkJCSBDYWxs
SW5mby5PbmVPdXRlckNhbGwgPT4gdHJ1ZQ0KCQkgICAgICAgfCBfID0+IGZhbHNlDQoJCSAgIHZh
bCBvbmVDb250ID0gIWNhblByZWZpeA0KCQlpbiBpZiAoY2FzZSBzdHJhdGVneSBvZg0KCQkJICBD
b250cm9sLkJvdGggPT4gb25lQ2FsbCBvcmVsc2Ugb25lQ29udA0KCQkJfCBDb250cm9sLkNhbGwg
PT4gb25lQ2FsbA0KCQkJfCBDb250cm9sLkNvbnQgPT4gb25lQ29udA0KCQkJfCBDb250cm9sLk5v
bmUgPT4gZmFsc2UpDQoJCSAgICAgIHRoZW4NCgkJCSByZXBsYWNlIDo9DQoJCQkgU09NRSB7YXJn
cyA9IGFyZ3MsDQoJCQkgICAgICAgYm9keSA9IGJvZHksDQoJCQkgICAgICAganVtcCA9IEp1bXAu
bmV3U3RyaW5nIChGdW5jLm9yaWdpbmFsTmFtZSBuYW1lKX0NCgkJICAgZWxzZSAoKQ0KCQllbmQp
DQoJICAgICgqIFdhbGsgb3ZlciBhbGwgZnVuY3Rpb25zLCByZW1vdmluZyB0aG9zZSB0aGF0IGFy
ZW4ndCB0b3BsZXZlbCwgYW5kDQoJICAgICAqIGRlc2NlbmRpbmcgdGhvc2UgdGhhdCBhcmUsIGlu
c2VydGluZyBsb2NhbCBmdW5jdGlvbnMNCgkgICAgICogd2hlcmUgbmVjZXNzYXJ5Lg0KCSAgICAg
KiAgLSB0dXJuIHRhaWwgY2FsbHMgaW50byBub250YWlsIGNhbGxzDQoJICAgICAqICAtIHR1cm4g
cmV0dXJucyBpbnRvIGp1bXBzDQoJICAgICAqKQ0KCSAgICBmdW4gd2Fsa0V4cCAoZjogRnVuYy50
LCBlOiBFeHAudCwgYzogSnVtcC50IG9wdGlvbik6IEV4cC50ID0NCgkgICAgICAgbGV0DQoJCSAg
dmFsIHtkZWNzLCB0cmFuc2Zlcn0gPSBFeHAuZGVzdCBlDQoJCSAgdmFsIGRlY3MgPSANCgkJICAg
ICBMaXN0LmZvbGQNCgkJICAgICAocmV2IGRlY3MsIFtdLCBmbiAoZCwgZHMpID0+DQoJCSAgICAg
IGNhc2UgZCBvZg0KCQkJIEJpbmQgXyA9PiBkIDo6IGRzDQoJCSAgICAgICB8IEZ1biB7bmFtZSwg
YXJncywgYm9keX0gPT4NCgkJCSAgICBGdW4ge25hbWUgPSBuYW1lLA0KCQkJCSBhcmdzID0gYXJn
cywNCgkJCQkgYm9keSA9IHdhbGtFeHAgKGYsIGJvZHksIGMpfQ0KCQkJICAgIDo6IChpZiAoY2Fz
ZSBzdHJhdGVneSBvZg0KCQkJCSAgICAgICBDb250cm9sLkJvdGggPT4gdHJ1ZQ0KCQkJCSAgICAg
fCBDb250cm9sLkNvbnQgPT4gdHJ1ZQ0KCQkJCSAgICAgfCBfID0+IGZhbHNlKQ0KCQkJCSAgIHRo
ZW4NCgkJCQkgICAgICBsZXQgdmFsIHtwcmVmaXhlcywgLi4ufSA9IGp1bXBJbmZvIG5hbWUNCgkJ
CQkgICAgICBpbiBjYXNlICFwcmVmaXhlcyBvZg0KCQkJCQkgTk9ORSA9PiBkcw0KCQkJCSAgICAg
ICB8IFNPTUUgZnMgPT4gbmVzdCAoZnMsIFNPTUUgbmFtZSwgZHMpDQoJCQkJICAgICAgZW5kDQoJ
CQkJZWxzZSBkcykNCgkJICAgICAgIHwgSGFuZGxlclB1c2ggaCA9PiBIYW5kbGVyUHVzaCBoIDo6
IGRzDQoJCSAgICAgICB8IEhhbmRsZXJQb3AgPT4gSGFuZGxlclBvcCA6OiBkcykNCgkJICBmdW4g
bWFrZSB0cmFuc2ZlciA9IEV4cC5tYWtlIHtkZWNzID0gZGVjcywNCgkJCQkJCXRyYW5zZmVyID0g
dHJhbnNmZXJ9DQoJICAgICAgIGluDQoJCSAgY2FzZSB0cmFuc2ZlciBvZg0KCQkgICAgIENhbGwg
e2Z1bmMsIGFyZ3MsIGNvbnR9ID0+DQoJCQlsZXQNCgkJCSAgIHZhbCBuZXdDb250OiBKdW1wLnQg
b3B0aW9uID0NCgkJCSAgICAgIGNhc2UgY29udCBvZg0KCQkJCSBOT05FID0+IGMNCgkJCSAgICAg
ICB8IFNPTUUgXyA9PiBjb250DQoJCQkgICB2YWwge2NhbGxJbmZvLCBjYW5QcmVmaXgsIHJlcGxh
Y2UsIC4uLn0gPQ0KCQkJICAgICAgZnVuY0luZm8gZnVuYw0KCQkJaW4NCgkJCSAgIGNhc2UgIXJl
cGxhY2Ugb2YNCgkJCSAgICAgIE5PTkUgPT4NCgkJCQkgbWFrZSAoQ2FsbCB7ZnVuYyA9IGZ1bmMs
DQoJCQkJCSAgICAgYXJncyA9IGFyZ3MsDQoJCQkJCSAgICAgY29udCA9IG5ld0NvbnR9KQ0KCQkJ
ICAgIHwgU09NRSB7anVtcCwgYXJncyA9IGZvcm1hbHMsIGJvZHl9ID0+DQoJCQkJIGxldA0KCQkJ
CSAgICB2YWwgZGVjcyA9DQoJCQkJICAgICAgIGlmICFjYWxsSW5mbyA9IENhbGxJbmZvLk9uZU91
dGVyQ2FsbA0KCQkJCQkgIGFuZGFsc28gbm90IChGdW5jLmVxdWFscyAoZiwgZnVuYykpDQoJCQkJ
CSAgYW5kYWxzbyAoY2FzZSBzdHJhdGVneSBvZg0KCQkJCQkJICAgICAgQ29udHJvbC5Cb3RoID0+
DQoJCQkJCQkJIG5vdCAoIWNhblByZWZpeCkNCgkJCQkJCSAgICB8IENvbnRyb2wuQ2FsbCA9PiB0
cnVlDQoJCQkJCQkgICAgfCBfID0+IGZhbHNlKQ0KCQkJCQkgIHRoZW4NCgkJCQkJICAgICBkZWNz
DQoJCQkJCSAgICAgQCBbRnVuIHtuYW1lID0ganVtcCwNCgkJCQkJCSAgICAgYXJncyA9IGZvcm1h
bHMsDQoJCQkJCQkgICAgIGJvZHkgPSB3YWxrRXhwIChmdW5jLCBib2R5LA0KCQkJCQkJCQkgICAg
IG5ld0NvbnQpfV0NCgkJCQkJICAgICAgDQoJCQkJICAgICAgIGVsc2UgZGVjcw0KCQkJCSBpbg0K
CQkJCSAgICBFeHAubWFrZQ0KCQkJCSAgICB7ZGVjcyA9IGRlY3MsDQoJCQkJICAgICB0cmFuc2Zl
ciA9IEp1bXAge2RzdCA9IGp1bXAsIGFyZ3MgPSBhcmdzfX0NCgkJCQkgZW5kDQoJCQllbmQNCgkJ
ICAgfCBSZXR1cm4geHMgPT4NCgkJCW1ha2UgKGNhc2UgYyBvZg0KCQkJCSBOT05FID0+IHRyYW5z
ZmVyDQoJCQkgICAgICAgfCBTT01FIGMgPT4gSnVtcCB7ZHN0ID0gYywgYXJncyA9IHhzfSkNCgkJ
ICAgfCBfID0+IG1ha2UgdHJhbnNmZXINCgkgICAgICAgZW5kDQoJICAgIGFuZCBuZXN0IChmczog
RnVuYy50IGxpc3QsDQoJCSAgICAgIGNvbnQ6IEp1bXAudCBvcHRpb24sDQoJCSAgICAgIGRzOiBE
ZWMudCBsaXN0KTogRGVjLnQgbGlzdCA9DQoJICAgICAgIExpc3QuZm9sZA0KCSAgICAgICAocmV2
IGZzLCBkcywgZm4gKGYsIGRzKSA9Pg0KCQlsZXQNCgkJICAgdmFsIHtyZXBsYWNlLCBuZXN0ZWQs
IHByZWZpeGVzLCAuLi59ID0gZnVuY0luZm8gZg0KCQkgICB2YWwgZnMgPQ0KCQkgICAgICBjYXNl
ICFwcmVmaXhlcyBvZg0KCQkJIE5PTkUgPT4gIW5lc3RlZA0KCQkgICAgICAgfCBTT01FIGZzID0+
IExpc3QuYXBwZW5kUmV2IChmcywgIW5lc3RlZCkNCgkJICAgdmFsIHtqdW1wLCBhcmdzLCBib2R5
fSA9IHZhbE9mICghcmVwbGFjZSkNCgkJICAgdmFsIHtkZWNzLCB0cmFuc2Zlcn0gPSBFeHAuZGVz
dCAod2Fsa0V4cCAoZiwgYm9keSwgY29udCkpDQoJCSAgIHZhbCBib2R5ID0gRXhwLm1ha2Uge2Rl
Y3MgPSBuZXN0ICghbmVzdGVkLCBjb250LCBkZWNzKSwNCgkJCQkJdHJhbnNmZXIgPSB0cmFuc2Zl
cn0NCgkJaW4gRnVuIHtuYW1lID0ganVtcCwgYXJncyA9IGFyZ3MsIGJvZHkgPSBib2R5fSA6OiBk
cw0KCQllbmQpDQoJICAgIHZhbCBzaHJpbmtFeHAgPSBzaHJpbmtFeHAgZ2xvYmFscw0KCSAgICB2
YWwgZnVuY3Rpb25zID0NCgkgICAgICAgTGlzdC5mb2xkDQoJICAgICAgIChmdW5jdGlvbnMsIFtd
LCBmbiAoe25hbWUsIGFyZ3MsIGJvZHksIHJldHVybnN9LCBmdW5jdGlvbnMpID0+DQoJCWxldA0K
CQkgICB2YWwge2NvbnRTZXQsIHByZWZpeGVzLCByZXBsYWNlLCAuLi59ID0gZnVuY0luZm8gbmFt
ZQ0KCQkgICAgICANCgkJaW4gY2FzZSAhcmVwbGFjZSBvZg0KCQkgICBOT05FID0+DQoJCSAgICAg
IGlmIENvbnRTZXQuaXNFbXB0eSBjb250U2V0DQoJCQkgdGhlbg0KCQkJICAgICgqIERvbid0IGlu
Y2x1ZGUgZnVuY3Rpb25zIHRoYXQgaGF2ZSBhbiBlbXB0eSBjb250DQoJCQkgICAgICogc2V0LCBi
ZWNhdXNlIHRoZXkgYXJlbid0IGNhbGxlZC4NCgkJCSAgICAgKikNCgkJCSAgICBmdW5jdGlvbnMN
CgkJICAgICAgZWxzZQ0KCQkJIGxldA0KCQkJICAgIHZhbCBib2R5ID0gc2hyaW5rRXhwICh3YWxr
RXhwIChuYW1lLCBib2R5LCBOT05FKSkNCgkJCSAgICB2YWwgYm9keSA9DQoJCQkgICAgICAgY2Fz
ZSAhcHJlZml4ZXMgb2YNCgkJCQkgIE5PTkUgPT4gYm9keQ0KCQkJCXwgU09NRSBmcyA9Pg0KCQkJ
CSAgICAgbGV0IHZhbCB7ZGVjcywgdHJhbnNmZXJ9ID0gRXhwLmRlc3QgYm9keQ0KCQkJCSAgICAg
aW4gRXhwLm1ha2Uge2RlY3MgPSBuZXN0IChmcywgTk9ORSwgZGVjcyksDQoJCQkJCQkgIHRyYW5z
ZmVyID0gdHJhbnNmZXJ9DQoJCQkJICAgICBlbmQNCgkJCSBpbiB7bmFtZSA9IG5hbWUsIGFyZ3Mg
PSBhcmdzLCByZXR1cm5zID0gcmV0dXJucywNCgkJCSAgICAgYm9keSA9IGJvZHl9DQoJCQkgZW5k
IDo6IGZ1bmN0aW9ucw0KCQkgfCBfID0+IGZ1bmN0aW9ucw0KCQllbmQpDQoJICAgIHZhbCBwcm9n
cmFtID0NCgkgICAgICAgUHJvZ3JhbS5UIHtkYXRhdHlwZXMgPSBkYXRhdHlwZXMsDQoJCQkgIGds
b2JhbHMgPSBnbG9iYWxzLA0KCQkJICBmdW5jdGlvbnMgPSBmdW5jdGlvbnMsDQoJCQkgIG1haW4g
PSBtYWlufQ0KCSAgICB2YWwgXyA9IFByb2dyYW0uY2xlYXIgcHJvZ3JhbQ0KCSBpbg0KCSAgICBw
cm9ncmFtDQoJIGVuZA0KICAgZW5kDQoNCmVuZA0K

---559023410-869693583-979419369=:12463--