[Python-Dev] new imputil.py

Greg Stein gstein@lyra.org
Sun, 2 Jan 2000 18:53:24 -0800 (PST)


  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.

--1658348780-1657214722-946868004=:412
Content-Type: TEXT/PLAIN; charset=US-ASCII

Happy New Year!

I've attached a new imputil.py to this message. It isn't posted on my page
yet, as I'd like some feedback before declaring this new version viable.

In this imputil, there is an ImportManager class. It gets installed as the
import hook, with the presumption that it is the only import hook
(technically, it could chain, but I've disabled that for now). I think
Python 1.6 should drop the __import__ builtin and move to something like
sys.import_hook (to allow examination and change). Another alternative
would be sys.get_import_hook() and sys.set_import_hook().
[ I don't think we would want a "set" that returned the old version as the
  only way to get the current hook function; we want to be able to easily 
  find the ImportManager instance. ]

The ImportManager knows how to scan sys.path when it needs to find a
top-level module/package (e.g. given a.b.c, the "a" is the top-level; b.c
falls "below" that). sys.path can contain strings which specify a
filesystem directory, or it can contain Importer instances.

The manager also records an ordered list of suffix/importer pairs. The
add_suffix() method is used to append new suffixes, but clients can also
access the .suffixes attribute for fine-grained manipulation/ordering.

There is a new importer called _FilesystemImporter which understands how
to look into a directory for Python modules. It borrows/refers to the
ImportManager's .suffixes attribute, using that to find modules in a
directory. This is also the Importer that gets associated with each
filesystem-based module.

The importers used for suffix-based importing are derived from
SuffixImporter. While a function could be used here, future changes will
be easier if we presume class instances.

The new imputil works fine (use _test_revamp() to switch to the new import
mechanism). Importer subclasses using the old imputil should continue to
work, although I am deprecating the 2-tuple return value for get_code().
get_code() should return None or the 3-tuple form now.

I think I still have a bit more work to do, to enable something like
"import a.b.c" where a.zip is an archive on the path and "b.c" resides in
the archive. Note: it *is* possible to do
sys.path.append(ZipImporter(filename)) and have "a.b.c" in the Zip file.
It would simply be nicer to be able to drop arbitrary .zip files onto the
path and use their basename as the top-level name of a package. Anyhow: I
haven't looked at this scenario yet to find what the new system is missing
(if anything).

As always: feedback is more than appreciated! Especially from people using
imputil today. Did I break anything? Does the new scheme still feel right
to you? etc.

Cheers,
-g

p.s. I'd also like to remove PackageArchiveImporter and PackageArchive.
     They don't seem to add any real value. I might move DirectoryImporter
     and PathImporter to an "examples" file, too.

-- 
Greg Stein, http://www.lyra.org/


--1658348780-1657214722-946868004=:412
Content-Type: TEXT/PLAIN; charset=US-ASCII; name="imputil.py"
Content-Transfer-Encoding: BASE64
Content-ID: <Pine.LNX.4.10.10001021853240.412@nebula.lyra.org>
Content-Description: 
Content-Disposition: attachment; filename="imputil.py"

Iw0KIyBpbXB1dGlsLnB5DQojDQojIFdyaXR0ZW4gYnkgR3JlZyBTdGVpbi4g
UHVibGljIERvbWFpbi4NCiMgTm8gQ29weXJpZ2h0LCBubyBSaWdodHMgUmVz
ZXJ2ZWQsIGFuZCBubyBXYXJyYW50aWVzLg0KIw0KIyBVdGlsaXRpZXMgdG8g
aGVscCBvdXQgd2l0aCBjdXN0b20gaW1wb3J0IG1lY2hhbmlzbXMuDQojDQoj
IEFkZGl0aW9uYWwgbW9kaWZpY2F0aW9ucyB3ZXJlIGNvbnRyaWJlZCBieSBN
YXJjLUFuZHJlIExlbWJ1cmcgYW5kDQojIEdvcmRvbiBNY01pbGxhbi4NCiMN
CiMgVGhpcyBtb2R1bGUgaXMgbWFpbnRhaW5lZCBieSBHcmVnIGFuZCBpcyBh
dmFpbGFibGUgYXQ6DQojICAgIGh0dHA6Ly93d3cubHlyYS5vcmcvZ3JlZy9w
eXRob24vaW1wdXRpbC5weQ0KIw0KIyBTaW5jZSB0aGlzIGlzbid0IGluIHRo
ZSBQeXRob24gZGlzdHJpYnV0aW9uIHlldCwgd2UnbGwgdXNlIHRoZSBDVlMg
SUQNCiMgZm9yIHRyYWNraW5nOg0KIyAgICRJZDogaW1wdXRpbC5weSx2IDEu
OSAyMDAwLzAxLzAzIDAyOjM4OjI5IGdzdGVpbiBFeHAgJA0KIw0KDQojIG5v
dGU6IGF2b2lkIGltcG9ydGluZyBub24tYnVpbHRpbiBtb2R1bGVzDQppbXBv
cnQgaW1wDQppbXBvcnQgc3lzDQppbXBvcnQgc3Ryb3ANCmltcG9ydCBfX2J1
aWx0aW5fXw0KDQojIGZvciB0aGUgRGlyZWN0b3J5SW1wb3J0ZXINCmltcG9y
dCBzdHJ1Y3QNCmltcG9ydCBtYXJzaGFsDQoNCl9TdHJpbmdUeXBlID0gdHlw
ZSgnJykNCl9Nb2R1bGVUeXBlID0gdHlwZShzeXMpDQoNCmNsYXNzIEltcG9y
dE1hbmFnZXI6DQogICJNYW5hZ2UgdGhlIGltcG9ydCBwcm9jZXNzLiINCg0K
ICBkZWYgaW5zdGFsbChzZWxmKToNCiAgICAjIyMgd2FybmluZzogUHl0aG9u
IDEuNiB3aWxsIGhhdmUgYSBkaWZmZXJlbnQgaG9vayBtZWNoYW5pc207IHRo
aXMNCiAgICAjIyMgY29kZSB3aWxsIG5lZWQgdG8gY2hhbmdlLg0KICAgIHNl
bGYuX19jaGFpbl9pbXBvcnQgPSBfX2J1aWx0aW5fXy5fX2ltcG9ydF9fDQog
ICAgc2VsZi5fX2NoYWluX3JlbG9hZCA9IF9fYnVpbHRpbl9fLnJlbG9hZA0K
ICAgIF9fYnVpbHRpbl9fLl9faW1wb3J0X18gPSBzZWxmLl9pbXBvcnRfaG9v
aw0KICAgICMjIyBmaXggdGhpcw0KICAgICNfX2J1aWx0aW5fXy5yZWxvYWQg
PSBOb25lDQogICAgI19fYnVpbHRpbl9fLnJlbG9hZCA9IHNlbGYuX3JlbG9h
ZF9ob29rDQoNCiAgZGVmIGFkZF9zdWZmaXgoc2VsZiwgc3VmZml4LCBpbXBv
cnRlcik6DQogICAgYXNzZXJ0IGlzaW5zdGFuY2UoaW1wb3J0ZXIsIFN1ZmZp
eEltcG9ydGVyKQ0KICAgIHNlbGYuc3VmZml4ZXMuYXBwZW5kKChzdWZmaXgs
IGltcG9ydGVyKSkNCg0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQog
ICMNCiAgIyBQUklWQVRFIE1FVEhPRFMNCiAgIw0KICBkZWYgX19pbml0X18o
c2VsZik6DQogICAgIyB3ZSdyZSBkZWZpbml0ZWx5IGdvaW5nIHRvIGJlIGlt
cG9ydGluZyBzb21ldGhpbmcgaW4gdGhlIGZ1dHVyZSwNCiAgICAjIHNvIGxl
dCdzIGp1c3QgbG9hZCB0aGUgT1MtcmVsYXRlZCBmYWNpbGl0aWVzLg0KICAg
IGlmIG5vdCBfb3Nfc3RhdDoNCiAgICAgIF9vc19ib290c3RyYXAoKQ0KDQog
ICAgIyBJbml0aWFsaXplIHRoZSBzZXQgb2Ygc3VmZml4ZXMgdGhhdCB3ZSBy
ZWNvZ25pemUgYW5kIGltcG9ydC4NCiAgICAjIFRoZSBkZWZhdWx0IHdpbGwg
aW1wb3J0IGR5bmFtaWMtbG9hZCBtb2R1bGVzIGZpcnN0LCBmb2xsb3dlZCBi
eQ0KICAgICMgLnB5IGZpbGVzIChvciBhIC5weSBmaWxlJ3MgY2FjaGVkIGJ5
dGVjb2RlKQ0KICAgIHNlbGYuc3VmZml4ZXMgPSBbIF0NCiAgICBmb3IgZGVz
YyBpbiBpbXAuZ2V0X3N1ZmZpeGVzKCk6DQogICAgICBpZiBkZXNjWzJdID09
IGltcC5DX0VYVEVOU0lPTjoNCiAgICAgICAgc2VsZi5zdWZmaXhlcy5hcHBl
bmQoKGRlc2NbMF0sIER5bkxvYWRTdWZmaXhJbXBvcnRlcihkZXNjKSkpDQog
ICAgc2VsZi5zdWZmaXhlcy5hcHBlbmQoKCcucHknLCBQeVN1ZmZpeEltcG9y
dGVyKCkpKQ0KDQogICAgIyBUaGlzIGlzIHRoZSBpbXBvcnRlciB0aGF0IHdl
IHVzZSBmb3IgZ3JhYmJpbmcgc3R1ZmYgZnJvbSB0aGUNCiAgICAjIGZpbGVz
eXN0ZW0uIEl0IGRlZmluZXMgb25lIG1vcmUgbWV0aG9kIChpbXBvcnRfZnJv
bV9kaXIpIGZvciBvdXIgdXNlLg0KICAgIHNlbGYuZnNfaW1wID0gX0ZpbGVz
eXN0ZW1JbXBvcnRlcihzZWxmLnN1ZmZpeGVzKQ0KDQogIGRlZiBfaW1wb3J0
X2hvb2soc2VsZiwgZnFuYW1lLCBnbG9iYWxzPU5vbmUsIGxvY2Fscz1Ob25l
LCBmcm9tbGlzdD1Ob25lKToNCiAgICAiIiJQeXRob24gY2FsbHMgdGhpcyBo
b29rIHRvIGxvY2F0ZSBhbmQgaW1wb3J0IGEgbW9kdWxlLiIiIg0KDQogICAg
cGFydHMgPSBzdHJvcC5zcGxpdChmcW5hbWUsICcuJykNCg0KICAgICMgZGV0
ZXJtaW5lIHRoZSBjb250ZXh0IG9mIHRoaXMgaW1wb3J0DQogICAgcGFyZW50
ID0gc2VsZi5fZGV0ZXJtaW5lX2ltcG9ydF9jb250ZXh0KGdsb2JhbHMpDQoN
CiAgICAjIGlmIHRoZXJlIGlzIGEgcGFyZW50LCB0aGVuIGl0cyBpbXBvcnRl
ciBzaG91bGQgbWFuYWdlIHRoaXMgaW1wb3J0DQogICAgaWYgcGFyZW50Og0K
ICAgICAgbW9kdWxlID0gcGFyZW50Ll9faW1wb3J0ZXJfXy5fZG9faW1wb3J0
KHBhcmVudCwgcGFydHMsIGZyb21saXN0KQ0KICAgICAgaWYgbW9kdWxlOg0K
ICAgICAgICByZXR1cm4gbW9kdWxlDQoNCiAgICAjIGhhcyB0aGUgdG9wIG1v
ZHVsZSBhbHJlYWR5IGJlZW4gaW1wb3J0ZWQ/DQogICAgdHJ5Og0KICAgICAg
dG9wX21vZHVsZSA9IHN5cy5tb2R1bGVzW3BhcnRzWzBdXQ0KICAgIGV4Y2Vw
dCBLZXlFcnJvcjoNCg0KICAgICAgIyBsb29rIGZvciB0aGUgdG9wbW9zdCBt
b2R1bGUNCiAgICAgIHRvcF9tb2R1bGUgPSBzZWxmLl9pbXBvcnRfdG9wX21v
ZHVsZShwYXJ0c1swXSkNCiAgICAgIGlmIG5vdCB0b3BfbW9kdWxlOg0KICAg
ICAgICAjIHRoZSB0b3Btb3N0IG1vZHVsZSB3YXNuJ3QgZm91bmQgYXQgYWxs
Lg0KICAgICAgICByYWlzZSBJbXBvcnRFcnJvciwgJ05vIG1vZHVsZSBuYW1l
ZCAnICsgZnFuYW1lDQogICAgICAgIHJldHVybiBzZWxmLl9fY2hhaW5faW1w
b3J0KG5hbWUsIGdsb2JhbHMsIGxvY2FscywgZnJvbWxpc3QpDQoNCiAgICAj
IGZhc3QtcGF0aCBzaW1wbGUgaW1wb3J0cw0KICAgIGlmIGxlbihwYXJ0cykg
PT0gMToNCiAgICAgIGlmIG5vdCBmcm9tbGlzdDoNCiAgICAgICAgcmV0dXJu
IHRvcF9tb2R1bGUNCg0KICAgICAgaWYgbm90IHRvcF9tb2R1bGUuX19kaWN0
X18uZ2V0KCdfX2lzcGtnX18nKToNCiAgICAgICAgIyBfX2lzcGtnX18gaXNu
J3QgZGVmaW5lZCAodGhlIG1vZHVsZSB3YXMgbm90IGltcG9ydGVkIGJ5IHVz
KSwgb3INCiAgICAgICAgIyBpdCBpcyB6ZXJvLg0KICAgICAgICAjDQogICAg
ICAgICMgSW4gdGhlIGZvcm1lciBjYXNlLCB0aGVyZSBpcyBubyB3YXkgdGhh
dCB3ZSBjb3VsZCBpbXBvcnQNCiAgICAgICAgIyBzdWItbW9kdWxlcyB0aGF0
IG9jY3VyIGluIHRoZSBmcm9tbGlzdCAoYnV0IHdlIGNhbid0IHJhaXNlIGFu
DQogICAgICAgICMgZXJyb3IgYmVjYXVzZSBpdCBtYXkganVzdCBiZSBuYW1l
cykgYmVjYXVzZSB3ZSBkb24ndCBrbm93IGhvdw0KICAgICAgICAjIHRvIGRl
YWwgd2l0aCBwYWNrYWdlcyB0aGF0IHdlcmUgaW1wb3J0ZWQgYnkgb3RoZXIg
c3lzdGVtcy4NCiAgICAgICAgIw0KICAgICAgICAjIEluIHRoZSBsYXR0ZXIg
Y2FzZSAoX19pc3BrZ19fID09IDApLCB0aGVyZSBjYW4ndCBiZSBhbnkgc3Vi
LQ0KICAgICAgICAjIG1vZHVsZXMgcHJlc2VudCwgc28gd2UgY2FuIGp1c3Qg
cmV0dXJuLg0KICAgICAgICAjDQogICAgICAgICMgSW4gYm90aCBjYXNlcywg
c2luY2UgbGVuKHBhcnRzKSA9PSAxLCB0aGUgdG9wX21vZHVsZSBpcyBhbHNv
DQogICAgICAgICMgdGhlICJib3R0b20iIHdoaWNoIGlzIHRoZSBkZWZpbmVk
IHJldHVybiB3aGVuIGEgZnJvbWxpc3QgZXhpc3RzLg0KICAgICAgICByZXR1
cm4gdG9wX21vZHVsZQ0KDQogICAgaW1wb3J0ZXIgPSB0b3BfbW9kdWxlLl9f
ZGljdF9fLmdldCgnX19pbXBvcnRlcl9fJykNCiAgICBpZiBpbXBvcnRlcjoN
CiAgICAgIHJldHVybiBpbXBvcnRlci5fZmluaXNoX2ltcG9ydCh0b3BfbW9k
dWxlLCBwYXJ0c1sxOl0sIGZyb21saXN0KQ0KDQogICAgIyBJZiB0aGUgaW1w
b3J0ZXIgZG9lcyBub3QgZXhpc3QsIHRoZW4gd2UgaGF2ZSB0byBiYWlsLiBB
IG1pc3NpbmcgaW1wb3J0ZXINCiAgICAjIG1lYW5zIHRoYXQgc29tZXRoaW5n
IGVsc2UgaW1wb3J0ZWQgdGhlIG1vZHVsZSwgYW5kIHdlIGhhdmUgbm8ga25v
d2xlZGdlDQogICAgIyBvZiBob3cgdG8gZ2V0IHN1Yi1tb2R1bGVzIG91dCBv
ZiB0aGUgdGhpbmcuDQogICAgcmFpc2UgSW1wb3J0RXJyb3IsICdObyBtb2R1
bGUgbmFtZWQgJyArIGZxbmFtZQ0KICAgIHJldHVybiBzZWxmLl9fY2hhaW5f
aW1wb3J0KG5hbWUsIGdsb2JhbHMsIGxvY2FscywgZnJvbWxpc3QpDQoNCiAg
ZGVmIF9kZXRlcm1pbmVfaW1wb3J0X2NvbnRleHQoc2VsZiwgZ2xvYmFscyk6
DQogICAgIiIiUmV0dXJucyB0aGUgY29udGV4dCBpbiB3aGljaCBhIG1vZHVs
ZSBzaG91bGQgYmUgaW1wb3J0ZWQuDQoNCiAgICBUaGUgY29udGV4dCBjb3Vs
ZCBiZSBhIGxvYWRlZCAocGFja2FnZSkgbW9kdWxlIGFuZCB0aGUgaW1wb3J0
ZWQgbW9kdWxlDQogICAgd2lsbCBiZSBsb29rZWQgZm9yIHdpdGhpbiB0aGF0
IHBhY2thZ2UuIFRoZSBjb250ZXh0IGNvdWxkIGFsc28gYmUgTm9uZSwNCiAg
ICBtZWFuaW5nIHRoZXJlIGlzIG5vIGNvbnRleHQgLS0gdGhlIG1vZHVsZSBz
aG91bGQgYmUgbG9va2VkIGZvciBhcyBhDQogICAgInRvcC1sZXZlbCIgbW9k
dWxlLg0KICAgICIiIg0KDQogICAgaWYgbm90IGdsb2JhbHMgb3Igbm90IGds
b2JhbHMuZ2V0KCdfX2ltcG9ydGVyX18nKToNCiAgICAgICMgZ2xvYmFscyBk
b2VzIG5vdCByZWZlciB0byBvbmUgb2Ygb3VyIG1vZHVsZXMgb3IgcGFja2Fn
ZXMuIFRoYXQNCiAgICAgICMgaW1wbGllcyB0aGVyZSBpcyBubyByZWxhdGl2
ZSBpbXBvcnQgY29udGV4dCAoYXMgZmFyIGFzIHdlIGFyZQ0KICAgICAgIyBj
b25jZXJuZWQpLCBhbmQgaXQgc2hvdWxkIGp1c3QgcGljayBpdCBvZmYgdGhl
IHN0YW5kYXJkIHBhdGguDQogICAgICByZXR1cm4gTm9uZQ0KDQogICAgIyBU
aGUgZ2xvYmFscyByZWZlciB0byBhIG1vZHVsZSBvciBwYWNrYWdlIG9mIG91
cnMuIEl0IHdpbGwgZGVmaW5lDQogICAgIyB0aGUgY29udGV4dCBvZiB0aGUg
bmV3IGltcG9ydC4gR2V0IHRoZSBtb2R1bGUvcGFja2FnZSBmcW5hbWUuDQog
ICAgcGFyZW50X2ZxbmFtZSA9IGdsb2JhbHNbJ19fbmFtZV9fJ10NCg0KICAg
ICMgaWYgYSBwYWNrYWdlIGlzIHBlcmZvcm1pbmcgdGhlIGltcG9ydCwgdGhl
biByZXR1cm4gaXRzZWxmIChpbXBvcnRzDQogICAgIyByZWZlciB0byBwa2cg
Y29udGVudHMpDQogICAgaWYgZ2xvYmFsc1snX19pc3BrZ19fJ106DQogICAg
ICBwYXJlbnQgPSBzeXMubW9kdWxlc1twYXJlbnRfZnFuYW1lXQ0KICAgICAg
YXNzZXJ0IGdsb2JhbHMgaXMgcGFyZW50Ll9fZGljdF9fDQogICAgICByZXR1
cm4gcGFyZW50DQoNCiAgICBpID0gc3Ryb3AucmZpbmQocGFyZW50X2ZxbmFt
ZSwgJy4nKQ0KDQogICAgIyBhIG1vZHVsZSBvdXRzaWRlIG9mIGEgcGFja2Fn
ZSBoYXMgbm8gcGFydGljdWxhciBpbXBvcnQgY29udGV4dA0KICAgIGlmIGkg
PT0gLTE6DQogICAgICByZXR1cm4gTm9uZQ0KDQogICAgIyBpZiBhIG1vZHVs
ZSBpbiBhIHBhY2thZ2UgaXMgcGVyZm9ybWluZyB0aGUgaW1wb3J0LCB0aGVu
IHJldHVybiB0aGUNCiAgICAjIHBhY2thZ2UgKGltcG9ydHMgcmVmZXIgdG8g
c2libGluZ3MpDQogICAgcGFyZW50X2ZxbmFtZSA9IHBhcmVudF9mcW5hbWVb
OmldDQogICAgcGFyZW50ID0gc3lzLm1vZHVsZXNbcGFyZW50X2ZxbmFtZV0N
CiAgICBhc3NlcnQgcGFyZW50Ll9fbmFtZV9fID09IHBhcmVudF9mcW5hbWUN
CiAgICByZXR1cm4gcGFyZW50DQoNCiAgZGVmIF9pbXBvcnRfdG9wX21vZHVs
ZShzZWxmLCBuYW1lKToNCiAgICAjIHNjYW4gc3lzLnBhdGggbG9va2luZyBm
b3IgYSBsb2NhdGlvbiBpbiB0aGUgZmlsZXN5c3RlbSB0aGF0IGNvbnRhaW5z
DQogICAgIyB0aGUgbW9kdWxlLCBvciBhbiBJbXBvcnRlciBvYmplY3QgdGhh
dCBjYW4gaW1wb3J0IHRoZSBtb2R1bGUuDQogICAgZm9yIGl0ZW0gaW4gc3lz
LnBhdGg6DQogICAgICBpZiB0eXBlKGl0ZW0pID09IF9TdHJpbmdUeXBlOg0K
ICAgICAgICBtb2R1bGUgPSBzZWxmLmZzX2ltcC5pbXBvcnRfZnJvbV9kaXIo
aXRlbSwgbmFtZSkNCiAgICAgIGVsc2U6DQogICAgICAgIG1vZHVsZSA9IGl0
ZW0uaW1wb3J0X3RvcChuYW1lKQ0KICAgICAgaWYgbW9kdWxlOg0KICAgICAg
ICByZXR1cm4gbW9kdWxlDQogICAgcmV0dXJuIE5vbmUNCg0KICBkZWYgX3Jl
bG9hZF9ob29rKHNlbGYsIG1vZHVsZSk6DQogICAgIlB5dGhvbiBjYWxscyB0
aGlzIGhvb2sgdG8gcmVsb2FkIGEgbW9kdWxlLiINCg0KICAgICMgcmVsb2Fk
aW5nIG9mIGEgbW9kdWxlIG1heSBvciBtYXkgbm90IGJlIHBvc3NpYmxlIChk
ZXBlbmRpbmcgb24gdGhlDQogICAgIyBpbXBvcnRlciksIGJ1dCBhdCBsZWFz
dCB3ZSBjYW4gdmFsaWRhdGUgdGhhdCBpdCdzIG91cnMgdG8gcmVsb2FkDQog
ICAgaW1wb3J0ZXIgPSBtb2R1bGUuX19kaWN0X18uZ2V0KCdfX2ltcG9ydGVy
X18nKQ0KICAgIGlmIG5vdCBpbXBvcnRlcjoNCiAgICAgIHJldHVybiBzZWxm
Ll9fY2hhaW5fcmVsb2FkKG1vZHVsZSkNCg0KICAgICMgb2theS4gaXQgaXMg
dXNpbmcgdGhlIGltcHV0aWwgc3lzdGVtLCBhbmQgd2UgbXVzdCBkZWxlZ2F0
ZSBpdCwgYnV0DQogICAgIyB3ZSBkb24ndCBrbm93IHdoYXQgdG8gZG8gKHll
dCkNCiAgICAjIyMgd2Ugc2hvdWxkIGJsYXN0IHRoZSBtb2R1bGUgZGljdCBh
bmQgZG8gYW5vdGhlciBnZXRfY29kZSgpLiBuZWVkIHRvDQogICAgIyMjIGZs
ZXNoIHRoaXMgb3V0IGFuZCBhZGQgcHJvcGVyIGRvY2NvLi4uDQogICAgcmFp
c2UgU3lzdGVtRXJyb3IsICJyZWxvYWQgbm90IHlldCBpbXBsZW1lbnRlZCIN
Cg0KDQpjbGFzcyBJbXBvcnRlcjoNCiAgIkJhc2UgY2xhc3MgZm9yIHJlcGxh
Y2luZyBzdGFuZGFyZCBpbXBvcnQgZnVuY3Rpb25zLiINCg0KICBkZWYgaW5z
dGFsbChzZWxmKToNCiAgICBzeXMucGF0aC5pbnNlcnQoMCwgc2VsZikNCg0K
ICBkZWYgaW1wb3J0X3RvcChzZWxmLCBuYW1lKToNCiAgICAiSW1wb3J0IGEg
dG9wLWxldmVsIG1vZHVsZS4iDQogICAgcmV0dXJuIHNlbGYuX2ltcG9ydF9v
bmUoTm9uZSwgbmFtZSwgbmFtZSkNCg0KICAjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjDQogICMNCiAgIyBQUklWQVRFIE1FVEhPRFMNCiAgIw0KICBkZWYg
X2ZpbmlzaF9pbXBvcnQoc2VsZiwgdG9wLCBwYXJ0cywgZnJvbWxpc3QpOg0K
ICAgICMgaWYgImEuYi5jIiB3YXMgcHJvdmlkZWQsIHRoZW4gbG9hZCB0aGUg
Ii5iLmMiIHBvcnRpb24gZG93biBmcm9tDQogICAgIyBiZWxvdyB0aGUgdG9w
LWxldmVsIG1vZHVsZS4NCiAgICBib3R0b20gPSBzZWxmLl9sb2FkX3RhaWwo
dG9wLCBwYXJ0cykNCg0KICAgICMgaWYgdGhlIGZvcm0gaXMgImltcG9ydCBh
LmIuYyIsIHRoZW4gcmV0dXJuICJhIg0KICAgIGlmIG5vdCBmcm9tbGlzdDoN
CiAgICAgICMgbm8gZnJvbWxpc3Q6IHJldHVybiB0aGUgdG9wIG9mIHRoZSBp
bXBvcnQgdHJlZQ0KICAgICAgcmV0dXJuIHRvcA0KDQogICAgIyB0aGUgdG9w
IG1vZHVsZSB3YXMgaW1wb3J0ZWQgYnkgc2VsZi4NCiAgICAjDQogICAgIyB0
aGlzIG1lYW5zIHRoYXQgdGhlIGJvdHRvbSBtb2R1bGUgd2FzIGFsc28gaW1w
b3J0ZWQgYnkgc2VsZiAoanVzdA0KICAgICMgbm93LCBvciBpbiB0aGUgcGFz
dCBhbmQgd2UgZmV0Y2hlZCBpdCBmcm9tIHN5cy5tb2R1bGVzKS4NCiAgICAj
DQogICAgIyBzaW5jZSB3ZSBpbXBvcnRlZC9oYW5kbGVkIHRoZSBib3R0b20g
bW9kdWxlLCB0aGlzIG1lYW5zIHRoYXQgd2UgY2FuDQogICAgIyBhbHNvIGhh
bmRsZSBpdHMgZnJvbWxpc3QgKGFuZCByZWxpYWJseSB1c2UgX19pc3BrZ19f
KS4NCg0KICAgICMgaWYgdGhlIGJvdHRvbSBub2RlIGlzIGEgcGFja2FnZSwg
dGhlbiAocG90ZW50aWFsbHkpIGltcG9ydCBzb21lIG1vZHVsZXMuDQogICAg
Iw0KICAgICMgbm90ZTogaWYgaXQgaXMgbm90IGEgcGFja2FnZSwgdGhlbiAi
ZnJvbWxpc3QiIHJlZmVycyB0byBuYW1lcyBpbg0KICAgICMgICAgICAgdGhl
IGJvdHRvbSBtb2R1bGUgcmF0aGVyIHRoYW4gbW9kdWxlcy4NCiAgICAjIG5v
dGU6IGZvciBhIG1peCBvZiBuYW1lcyBhbmQgbW9kdWxlcyBpbiB0aGUgZnJv
bWxpc3QsIHdlIHdpbGwNCiAgICAjICAgICAgIGltcG9ydCBhbGwgbW9kdWxl
cyBhbmQgaW5zZXJ0IHRob3NlIGludG8gdGhlIG5hbWVzcGFjZSBvZg0KICAg
ICMgICAgICAgdGhlIHBhY2thZ2UgbW9kdWxlLiBQeXRob24gd2lsbCBwaWNr
IHVwIGFsbCBmcm9tbGlzdCBuYW1lcw0KICAgICMgICAgICAgZnJvbSB0aGUg
Ym90dG9tIChwYWNrYWdlKSBtb2R1bGU7IHNvbWUgd2lsbCBiZSBtb2R1bGVz
IHRoYXQNCiAgICAjICAgICAgIHdlIGltcG9ydGVkIGFuZCBzdG9yZWQgaW4g
dGhlIG5hbWVzcGFjZSwgb3RoZXJzIGFyZSBleHBlY3RlZA0KICAgICMgICAg
ICAgdG8gYmUgcHJlc2VudCBhbHJlYWR5Lg0KICAgIGlmIGJvdHRvbS5fX2lz
cGtnX186DQogICAgICBzZWxmLl9pbXBvcnRfZnJvbWxpc3QoYm90dG9tLCBm
cm9tbGlzdCkNCg0KICAgICMgaWYgdGhlIGZvcm0gaXMgImZyb20gYS5iIGlt
cG9ydCBjLCBkIiB0aGVuIHJldHVybiAiYiINCiAgICByZXR1cm4gYm90dG9t
DQoNCiAgZGVmIF9pbXBvcnRfb25lKHNlbGYsIHBhcmVudCwgbW9kbmFtZSwg
ZnFuYW1lKToNCiAgICAiSW1wb3J0IGEgc2luZ2xlIG1vZHVsZS4iDQoNCiAg
ICAjIGhhcyB0aGUgbW9kdWxlIGFscmVhZHkgYmVlbiBpbXBvcnRlZD8NCiAg
ICB0cnk6DQogICAgICByZXR1cm4gc3lzLm1vZHVsZXNbZnFuYW1lXQ0KICAg
IGV4Y2VwdCBLZXlFcnJvcjoNCiAgICAgIHBhc3MNCg0KICAgICMgbG9hZCB0
aGUgbW9kdWxlJ3MgY29kZSwgb3IgZmV0Y2ggdGhlIG1vZHVsZSBpdHNlbGYN
CiAgICByZXN1bHQgPSBzZWxmLmdldF9jb2RlKHBhcmVudCwgbW9kbmFtZSwg
ZnFuYW1lKQ0KICAgIGlmIHJlc3VsdCBpcyBOb25lOg0KICAgICAgcmV0dXJu
IE5vbmUNCg0KICAgICMjIyBiYWNrd2FyZHMtY29tcGF0DQogICAgaWYgbGVu
KHJlc3VsdCkgPT0gMjoNCiAgICAgIHJlc3VsdCA9IHJlc3VsdCArICh7fSwp
DQoNCiAgICBtb2R1bGUgPSBzZWxmLl9wcm9jZXNzX3Jlc3VsdChyZXN1bHQs
IGZxbmFtZSkNCg0KICAgICMgaW5zZXJ0IHRoZSBtb2R1bGUgaW50byBpdHMg
cGFyZW50DQogICAgaWYgcGFyZW50Og0KICAgICAgc2V0YXR0cihwYXJlbnQs
IG1vZG5hbWUsIG1vZHVsZSkNCiAgICByZXR1cm4gbW9kdWxlDQoNCiAgZGVm
IF9wcm9jZXNzX3Jlc3VsdChzZWxmLCAoaXNwa2csIGNvZGUsIHZhbHVlcyks
IGZxbmFtZSk6DQogICAgIyBkaWQgZ2V0X2NvZGUoKSByZXR1cm4gYW4gYWN0
dWFsIG1vZHVsZT8gKHJhdGhlciB0aGFuIGEgY29kZSBvYmplY3QpDQogICAg
aXNfbW9kdWxlID0gdHlwZShjb2RlKSBpcyBfTW9kdWxlVHlwZQ0KDQogICAg
IyB1c2UgdGhlIHJldHVybmVkIG1vZHVsZSwgb3IgY3JlYXRlIGEgbmV3IG9u
ZSB0byBleGVjIGNvZGUgaW50bw0KICAgIGlmIGlzX21vZHVsZToNCiAgICAg
IG1vZHVsZSA9IGNvZGUNCiAgICBlbHNlOg0KICAgICAgbW9kdWxlID0gaW1w
Lm5ld19tb2R1bGUoZnFuYW1lKQ0KDQogICAgIyMjIHJlY29yZCBwYWNrYWdl
cyBhIGJpdCBkaWZmZXJlbnRseT8/DQogICAgbW9kdWxlLl9faW1wb3J0ZXJf
XyA9IHNlbGYNCiAgICBtb2R1bGUuX19pc3BrZ19fID0gaXNwa2cNCg0KICAg
ICMgaW5zZXJ0IGFkZGl0aW9uYWwgdmFsdWVzIGludG8gdGhlIG1vZHVsZSAo
YmVmb3JlIGV4ZWN1dGluZyB0aGUgY29kZSkNCiAgICBtb2R1bGUuX19kaWN0
X18udXBkYXRlKHZhbHVlcykNCg0KICAgICMgdGhlIG1vZHVsZSBpcyBhbG1v
c3QgcmVhZHkuLi4gbWFrZSBpdCB2aXNpYmxlDQogICAgc3lzLm1vZHVsZXNb
ZnFuYW1lXSA9IG1vZHVsZQ0KDQogICAgIyBleGVjdXRlIHRoZSBjb2RlIHdp
dGhpbiB0aGUgbW9kdWxlJ3MgbmFtZXNwYWNlDQogICAgaWYgbm90IGlzX21v
ZHVsZToNCiAgICAgIGV4ZWMgY29kZSBpbiBtb2R1bGUuX19kaWN0X18NCg0K
ICAgIHJldHVybiBtb2R1bGUNCg0KICBkZWYgX2xvYWRfdGFpbChzZWxmLCBt
LCBwYXJ0cyk6DQogICAgIiIiSW1wb3J0IHRoZSByZXN0IG9mIHRoZSBtb2R1
bGVzLCBkb3duIGZyb20gdGhlIHRvcC1sZXZlbCBtb2R1bGUuDQoNCiAgICBS
ZXR1cm5zIHRoZSBsYXN0IG1vZHVsZSBpbiB0aGUgZG90dGVkIGxpc3Qgb2Yg
bW9kdWxlcy4NCiAgICAiIiINCiAgICBmb3IgcGFydCBpbiBwYXJ0czoNCiAg
ICAgIGZxbmFtZSA9ICIlcy4lcyIgJSAobS5fX25hbWVfXywgcGFydCkNCiAg
ICAgIG0gPSBzZWxmLl9pbXBvcnRfb25lKG0sIHBhcnQsIGZxbmFtZSkNCiAg
ICAgIGlmIG5vdCBtOg0KICAgICAgICByYWlzZSBJbXBvcnRFcnJvciwgIk5v
IG1vZHVsZSBuYW1lZCAiICsgZnFuYW1lDQogICAgcmV0dXJuIG0NCg0KICBk
ZWYgX2ltcG9ydF9mcm9tbGlzdChzZWxmLCBwYWNrYWdlLCBmcm9tbGlzdCk6
DQogICAgJ0ltcG9ydCBhbnkgc3ViLW1vZHVsZXMgaW4gdGhlICJmcm9tIiBs
aXN0LicNCg0KICAgICMgaWYgJyonIGlzIHByZXNlbnQgaW4gdGhlIGZyb21s
aXN0LCB0aGVuIGxvb2sgZm9yIHRoZSAnX19hbGxfXycgdmFyaWFibGUNCiAg
ICAjIHRvIGZpbmQgYWRkaXRpb25hbCBpdGVtcyAobW9kdWxlcykgdG8gaW1w
b3J0Lg0KICAgIGlmICcqJyBpbiBmcm9tbGlzdDoNCiAgICAgIGZyb21saXN0
ID0gbGlzdChmcm9tbGlzdCkgKyBsaXN0KHBhY2thZ2UuX19kaWN0X18uZ2V0
KCdfX2FsbF9fJywgW10pKQ0KDQogICAgZm9yIHN1YiBpbiBmcm9tbGlzdDoN
CiAgICAgICMgaWYgdGhlIG5hbWUgaXMgYWxyZWFkeSBwcmVzZW50LCB0aGVu
IGRvbid0IHRyeSB0byBpbXBvcnQgaXQgKGl0DQogICAgICAjIG1pZ2h0IG5v
dCBiZSBhIG1vZHVsZSEpLg0KICAgICAgaWYgc3ViICE9ICcqJyBhbmQgbm90
IGhhc2F0dHIocGFja2FnZSwgc3ViKToNCiAgICAgICAgc3VibmFtZSA9ICIl
cy4lcyIgJSAocGFja2FnZS5fX25hbWVfXywgc3ViKQ0KICAgICAgICBzdWJt
b2QgPSBzZWxmLl9pbXBvcnRfb25lKHBhY2thZ2UsIHN1Yiwgc3VibmFtZSkN
CiAgICAgICAgaWYgbm90IHN1Ym1vZDoNCiAgICAgICAgICByYWlzZSBJbXBv
cnRFcnJvciwgImNhbm5vdCBpbXBvcnQgbmFtZSAiICsgc3VibmFtZQ0KDQog
IGRlZiBfZG9faW1wb3J0KHNlbGYsIHBhcmVudCwgcGFydHMsIGZyb21saXN0
KToNCiAgICAiIiJBdHRlbXB0IHRvIGltcG9ydCB0aGUgbW9kdWxlIHJlbGF0
aXZlIHRvIHBhcmVudC4NCg0KICAgIFRoaXMgbWV0aG9kIGlzIHVzZWQgd2hl
biB0aGUgaW1wb3J0IGNvbnRleHQgc3BlY2lmaWVzIHRoYXQgPHNlbGY+DQog
ICAgaW1wb3J0ZWQgdGhlIHBhcmVudCBtb2R1bGUuDQogICAgIiIiDQogICAg
dG9wX25hbWUgPSBwYXJ0c1swXQ0KICAgIHRvcF9mcW5hbWUgPSBwYXJlbnQu
X19uYW1lX18gKyAnLicgKyB0b3BfbmFtZQ0KICAgIHRvcF9tb2R1bGUgPSBz
ZWxmLl9pbXBvcnRfb25lKHBhcmVudCwgdG9wX25hbWUsIHRvcF9mcW5hbWUp
DQogICAgaWYgbm90IHRvcF9tb2R1bGU6DQogICAgICAjIHRoaXMgaW1wb3J0
ZXIgYW5kIHBhcmVudCBjb3VsZCBub3QgZmluZCB0aGUgbW9kdWxlIChyZWxh
dGl2ZWx5KQ0KICAgICAgcmV0dXJuIE5vbmUNCg0KICAgIHJldHVybiBzZWxm
Ll9maW5pc2hfaW1wb3J0KHRvcF9tb2R1bGUsIHBhcnRzWzE6XSwgZnJvbWxp
c3QpDQoNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjDQogICMg
TUVUSE9EUyBUTyBPVkVSUklERQ0KICAjDQogIGRlZiBnZXRfY29kZShzZWxm
LCBwYXJlbnQsIG1vZG5hbWUsIGZxbmFtZSk6DQogICAgIiIiRmluZCBhbmQg
cmV0cmlldmUgdGhlIGNvZGUgZm9yIHRoZSBnaXZlbiBtb2R1bGUuDQoNCiAg
ICBwYXJlbnQgc3BlY2lmaWVzIGEgcGFyZW50IG1vZHVsZSB0byBkZWZpbmUg
YSBjb250ZXh0IGZvciBpbXBvcnRpbmcuIEl0DQogICAgbWF5IGJlIE5vbmUs
IGluZGljYXRpbmcgbm8gcGFydGljdWxhciBjb250ZXh0IGZvciB0aGUgc2Vh
cmNoLg0KDQogICAgbW9kbmFtZSBzcGVjaWZpZXMgYSBzaW5nbGUgbW9kdWxl
IChub3QgZG90dGVkKSB3aXRoaW4gdGhlIHBhcmVudC4NCg0KICAgIGZxbmFt
ZSBzcGVjaWZpZXMgdGhlIGZ1bGx5LXF1YWxpZmllZCBtb2R1bGUgbmFtZS4g
VGhpcyBpcyBhIChwb3RlbnRpYWxseSkNCiAgICBkb3R0ZWQgbmFtZSBmcm9t
IHRoZSAicm9vdCIgb2YgdGhlIG1vZHVsZSBuYW1lc3BhY2UgZG93biB0byB0
aGUgbW9kbmFtZS4NCiAgICBJZiB0aGVyZSBpcyBubyBwYXJlbnQsIHRoZW4g
bW9kbmFtZT09ZnFuYW1lLg0KDQogICAgVGhpcyBtZXRob2Qgc2hvdWxkIHJl
dHVybiBOb25lLCBvciBhIDMtdHVwbGUuDQoNCiAgICAqIElmIHRoZSBtb2R1
bGUgd2FzIG5vdCBmb3VuZCwgdGhlbiBOb25lIHNob3VsZCBiZSByZXR1cm5l
ZC4NCg0KICAgICogVGhlIGZpcnN0IGl0ZW0gb2YgdGhlIDItIG9yIDMtdHVw
bGUgc2hvdWxkIGJlIHRoZSBpbnRlZ2VyIDAgb3IgMSwNCiAgICAgIHNwZWNp
Znlpbmcgd2hldGhlciB0aGUgbW9kdWxlIHRoYXQgd2FzIGZvdW5kIGlzIGEg
cGFja2FnZSBvciBub3QuDQoNCiAgICAqIFRoZSBzZWNvbmQgaXRlbSBpcyB0
aGUgY29kZSBvYmplY3QgZm9yIHRoZSBtb2R1bGUgKGl0IHdpbGwgYmUNCiAg
ICAgIGV4ZWN1dGVkIHdpdGhpbiB0aGUgbmV3IG1vZHVsZSdzIG5hbWVzcGFj
ZSkuIFRoaXMgaXRlbSBjYW4gYWxzbw0KICAgICAgYmUgYSBmdWxseS1sb2Fk
ZWQgbW9kdWxlIG9iamVjdCAoZS5nLiBsb2FkZWQgZnJvbSBhIHNoYXJlZCBs
aWIpLg0KDQogICAgKiBUaGUgdGhpcmQgaXRlbSBpcyBhIGRpY3Rpb25hcnkg
b2YgbmFtZS92YWx1ZSBwYWlycyB0aGF0IHdpbGwgYmUNCiAgICAgIGluc2Vy
dGVkIGludG8gbmV3IG1vZHVsZSBiZWZvcmUgdGhlIGNvZGUgb2JqZWN0IGlz
IGV4ZWN1dGVkLiBUaGlzDQogICAgICBpcyBwcm92aWRlZCBpbiBjYXNlIHRo
ZSBtb2R1bGUncyBjb2RlIGV4cGVjdHMgY2VydGFpbiB2YWx1ZXMgKHN1Y2gN
CiAgICAgIGFzIHdoZXJlIHRoZSBtb2R1bGUgd2FzIGZvdW5kKS4gV2hlbiB0
aGUgc2Vjb25kIGl0ZW0gaXMgYSBtb2R1bGUNCiAgICAgIG9iamVjdCwgdGhl
biB0aGVzZSBuYW1lcy92YWx1ZXMgd2lsbCBiZSBpbnNlcnRlZCAqYWZ0ZXIq
IHRoZSBtb2R1bGUNCiAgICAgIGhhcyBiZWVuIGxvYWRlZC9pbml0aWFsaXpl
ZC4NCiAgICAiIiINCiAgICByYWlzZSBSdW50aW1lRXJyb3IsICJnZXRfY29k
ZSBub3QgaW1wbGVtZW50ZWQiDQoNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIw0KIw0KIyBTb21lIGhhbmR5IHN0dWZmIGZvciB0aGUgSW1wb3J0ZXJz
DQojDQoNCiMgYnl0ZS1jb21waWxlZCBmaWxlIHN1ZmZpYyBjaGFyYWN0ZXIN
Cl9zdWZmaXhfY2hhciA9IF9fZGVidWdfXyBhbmQgJ2MnIG9yICdvJw0KDQoj
IGJ5dGUtY29tcGlsZWQgZmlsZSBzdWZmaXgNCl9zdWZmaXggPSAnLnB5JyAr
IF9zdWZmaXhfY2hhcg0KDQojIHRoZSBDX0VYVEVOU0lPTiBzdWZmaXhlcw0K
X2Nfc3VmZml4ZXMgPSBmaWx0ZXIobGFtYmRhIHg6IHhbMl0gPT0gaW1wLkNf
RVhURU5TSU9OLCBpbXAuZ2V0X3N1ZmZpeGVzKCkpDQoNCmRlZiBfY29tcGls
ZShwYXRobmFtZSwgdGltZXN0YW1wKToNCiAgIiIiQ29tcGlsZSAoYW5kIGNh
Y2hlKSBhIFB5dGhvbiBzb3VyY2UgZmlsZS4NCg0KICBUaGUgZmlsZSBzcGVj
aWZpZWQgYnkgPHBhdGhuYW1lPiBpcyBjb21waWxlZCB0byBhIGNvZGUgb2Jq
ZWN0IGFuZA0KICByZXR1cm5lZC4NCg0KICBQcmVzdW1pbmcgdGhlIGFwcHJv
cHJpYXRlIHByaXZpbGVnZXMgZXhpc3QsIHRoZSBieXRlY29kZXMgd2lsbCBi
ZQ0KICBzYXZlZCBiYWNrIHRvIHRoZSBmaWxlc3lzdGVtIGZvciBmdXR1cmUg
aW1wb3J0cy4gVGhlIHNvdXJjZSBmaWxlJ3MNCiAgbW9kaWZpY2F0aW9uIHRp
bWVzdGFtcCBtdXN0IGJlIHByb3ZpZGVkIGFzIGEgTG9uZyB2YWx1ZS4NCiAg
IiIiDQogIGNvZGVzdHJpbmcgPSBvcGVuKHBhdGhuYW1lLCAncicpLnJlYWQo
KQ0KICBpZiBjb2Rlc3RyaW5nIGFuZCBjb2Rlc3RyaW5nWy0xXSAhPSAnXG4n
Og0KICAgIGNvZGVzdHJpbmcgPSBjb2Rlc3RyaW5nICsgJ1xuJw0KICBjb2Rl
ID0gX19idWlsdGluX18uY29tcGlsZShjb2Rlc3RyaW5nLCBwYXRobmFtZSwg
J2V4ZWMnKQ0KDQogICMgdHJ5IHRvIGNhY2hlIHRoZSBjb21waWxlZCBjb2Rl
DQogIHRyeToNCiAgICBmID0gb3BlbihwYXRobmFtZSArIF9zdWZmaXhfY2hh
ciwgJ3diJykNCiAgZXhjZXB0IElPRXJyb3I6DQogICAgcGFzcw0KICBlbHNl
Og0KICAgIGYud3JpdGUoJ1wwXDBcMFwwJykNCiAgICBmLndyaXRlKHN0cnVj
dC5wYWNrKCc8SScsIHRpbWVzdGFtcCkpDQogICAgbWFyc2hhbC5kdW1wKGNv
ZGUsIGYpDQogICAgZi5mbHVzaCgpDQogICAgZi5zZWVrKDAsIDApDQogICAg
Zi53cml0ZShpbXAuZ2V0X21hZ2ljKCkpDQogICAgZi5jbG9zZSgpDQoNCiAg
cmV0dXJuIGNvZGUNCg0KX29zX3N0YXQgPSBfb3NfcGF0aF9qb2luID0gTm9u
ZQ0KZGVmIF9vc19ib290c3RyYXAoKToNCiAgIlNldCB1cCAnb3MnIG1vZHVs
ZSByZXBsYWNlbWVudCBmdW5jdGlvbnMgZm9yIHVzZSBkdXJpbmcgaW1wb3J0
IGJvb3RzdHJhcC4iDQoNCiAgbmFtZXMgPSBzeXMuYnVpbHRpbl9tb2R1bGVf
bmFtZXMNCg0KICBqb2luID0gTm9uZQ0KICBpZiAncG9zaXgnIGluIG5hbWVz
Og0KICAgIHNlcCA9ICcvJw0KICAgIGZyb20gcG9zaXggaW1wb3J0IHN0YXQN
CiAgZWxpZiAnbnQnIGluIG5hbWVzOg0KICAgIHNlcCA9ICdcXCcNCiAgICBm
cm9tIG50IGltcG9ydCBzdGF0DQogIGVsaWYgJ2RvcycgaW4gbmFtZXM6DQog
ICAgc2VwID0gJ1xcJw0KICAgIGZyb20gZG9zIGltcG9ydCBzdGF0DQogIGVs
aWYgJ29zMicgaW4gbmFtZXM6DQogICAgc2VwID0gJ1xcJw0KICAgIGZyb20g
b3MyIGltcG9ydCBzdGF0DQogIGVsaWYgJ21hYycgaW4gbmFtZXM6DQogICAg
ZnJvbSBtYWMgaW1wb3J0IHN0YXQNCiAgICBkZWYgam9pbihhLCBiKToNCiAg
ICAgIGlmIGEgPT0gJyc6DQogICAgICAgIHJldHVybiBiDQogICAgICBwYXRo
ID0gcw0KICAgICAgaWYgJzonIG5vdCBpbiBhOg0KICAgICAgICBhID0gJzon
ICsgYQ0KICAgICAgaWYgYVstMTpdIDw+ICc6JzoNCiAgICAgICAgYSA9IGEg
KyAnOicNCiAgICAgIHJldHVybiBhICsgYg0KICBlbHNlOg0KICAgIHJhaXNl
IEltcG9ydEVycm9yLCAnbm8gb3Mgc3BlY2lmaWMgbW9kdWxlIGZvdW5kJw0K
ICANCiAgaWYgam9pbiBpcyBOb25lOg0KICAgIGRlZiBqb2luKGEsIGIsIHNl
cD1zZXApOg0KICAgICAgaWYgYSA9PSAnJzoNCiAgICAgICAgcmV0dXJuIGIN
CiAgICAgIGxhc3RjaGFyID0gYVstMTpdDQogICAgICBpZiBsYXN0Y2hhciA9
PSAnLycgb3IgbGFzdGNoYXIgPT0gc2VwOg0KICAgICAgICByZXR1cm4gYSAr
IGINCiAgICAgIHJldHVybiBhICsgc2VwICsgYg0KDQogIGdsb2JhbCBfb3Nf
c3RhdA0KICBfb3Nfc3RhdCA9IHN0YXQNCg0KICBnbG9iYWwgX29zX3BhdGhf
am9pbg0KICBfb3NfcGF0aF9qb2luID0gam9pbg0KDQpkZWYgX29zX3BhdGhf
aXNkaXIocGF0aG5hbWUpOg0KICAiTG9jYWwgcmVwbGFjZW1lbnQgZm9yIG9z
LnBhdGguaXNkaXIoKS4iDQogIHRyeToNCiAgICBzID0gX29zX3N0YXQocGF0
aG5hbWUpDQogIGV4Y2VwdCBPU0Vycm9yOg0KICAgIHJldHVybiBOb25lDQog
IHJldHVybiAoc1swXSAmIDAxNzAwMDApID09IDAwNDAwMDANCg0KZGVmIF90
aW1lc3RhbXAocGF0aG5hbWUpOg0KICAiUmV0dXJuIHRoZSBmaWxlIG1vZGlm
aWNhdGlvbiB0aW1lIGFzIGEgTG9uZy4iDQogIHRyeToNCiAgICBzID0gX29z
X3N0YXQocGF0aG5hbWUpDQogIGV4Y2VwdCBPU0Vycm9yOg0KICAgIHJldHVy
biBOb25lDQogIHJldHVybiBsb25nKHNbOF0pDQoNCmRlZiBfZnNfaW1wb3J0
KGRpciwgbW9kbmFtZSwgZnFuYW1lKToNCiAgIkZldGNoIGEgbW9kdWxlIGZy
b20gdGhlIGZpbGVzeXN0ZW0uIg0KDQogIHBhdGhuYW1lID0gX29zX3BhdGhf
am9pbihkaXIsIG1vZG5hbWUpDQogIGlmIF9vc19wYXRoX2lzZGlyKHBhdGhu
YW1lKToNCiAgICB2YWx1ZXMgPSB7ICdfX3BrZ2Rpcl9fJyA6IHBhdGhuYW1l
LCAnX19wYXRoX18nIDogWyBwYXRobmFtZSBdIH0NCiAgICBpc3BrZyA9IDEN
CiAgICBwYXRobmFtZSA9IF9vc19wYXRoX2pvaW4ocGF0aG5hbWUsICdfX2lu
aXRfXycpDQogIGVsc2U6DQogICAgdmFsdWVzID0geyB9DQogICAgaXNwa2cg
PSAwDQoNCiAgICAjIGxvb2sgZm9yIGR5bmxvYWQgbW9kdWxlcw0KICAgIGZv
ciBkZXNjIGluIF9jX3N1ZmZpeGVzOg0KICAgICAgZmlsZSA9IHBhdGhuYW1l
ICsgZGVzY1swXQ0KICAgICAgdHJ5Og0KICAgICAgICBmcCA9IG9wZW4oZmls
ZSwgZGVzY1sxXSkNCiAgICAgIGV4Y2VwdCBJT0Vycm9yOg0KICAgICAgICBw
YXNzDQogICAgICBlbHNlOg0KICAgICAgICBtb2R1bGUgPSBpbXAubG9hZF9t
b2R1bGUoZnFuYW1lLCBmcCwgZmlsZSwgZGVzYykNCiAgICAgICAgdmFsdWVz
WydfX2ZpbGVfXyddID0gZmlsZQ0KICAgICAgICByZXR1cm4gMCwgbW9kdWxl
LCB2YWx1ZXMNCg0KICB0X3B5ID0gX3RpbWVzdGFtcChwYXRobmFtZSArICcu
cHknKQ0KICB0X3B5YyA9IF90aW1lc3RhbXAocGF0aG5hbWUgKyBfc3VmZml4
KQ0KICBpZiB0X3B5IGlzIE5vbmUgYW5kIHRfcHljIGlzIE5vbmU6DQogICAg
cmV0dXJuIE5vbmUNCiAgY29kZSA9IE5vbmUNCiAgaWYgdF9weSBpcyBOb25l
IG9yICh0X3B5YyBpcyBub3QgTm9uZSBhbmQgdF9weWMgPj0gdF9weSk6DQog
ICAgZmlsZSA9IHBhdGhuYW1lICsgX3N1ZmZpeA0KICAgIGYgPSBvcGVuKGZp
bGUsICdyYicpDQogICAgaWYgZi5yZWFkKDQpID09IGltcC5nZXRfbWFnaWMo
KToNCiAgICAgIHQgPSBzdHJ1Y3QudW5wYWNrKCc8SScsIGYucmVhZCg0KSlb
MF0NCiAgICAgIGlmIHQgPT0gdF9weToNCiAgICAgICAgY29kZSA9IG1hcnNo
YWwubG9hZChmKQ0KICAgIGYuY2xvc2UoKQ0KICBpZiBjb2RlIGlzIE5vbmU6
DQogICAgZmlsZSA9IHBhdGhuYW1lICsgJy5weScNCiAgICBjb2RlID0gX2Nv
bXBpbGUoZmlsZSwgdF9weSkNCg0KICB2YWx1ZXNbJ19fZmlsZV9fJ10gPSBm
aWxlDQogIHJldHVybiBpc3BrZywgY29kZSwgdmFsdWVzDQoNCg0KIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIw0KIw0KIyBTaW1wbGUgZnVuY3Rpb24tYmFz
ZWQgaW1wb3J0ZXINCiMNCmNsYXNzIEZ1bmNJbXBvcnRlcihJbXBvcnRlcik6
DQogICJJbXBvcnRlciBzdWJjbGFzcyB0byB1c2UgYSBzdXBwbGllZCBmdW5j
dGlvbiByYXRoZXIgdGhhbiBtZXRob2Qgb3ZlcnJpZGVzLiINCiAgZGVmIF9f
aW5pdF9fKHNlbGYsIGZ1bmMpOg0KICAgIHNlbGYuZnVuYyA9IGZ1bmMNCiAg
ZGVmIGdldF9jb2RlKHNlbGYsIHBhcmVudCwgbW9kbmFtZSwgZnFuYW1lKToN
CiAgICByZXR1cm4gc2VsZi5mdW5jKHBhcmVudCwgbW9kbmFtZSwgZnFuYW1l
KQ0KDQpkZWYgaW5zdGFsbF93aXRoKGZ1bmMpOg0KICBGdW5jSW1wb3J0ZXIo
ZnVuYykuaW5zdGFsbCgpDQoNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
Iw0KIw0KIyBCYXNlIGNsYXNzIGZvciBhcmNoaXZlLWJhc2VkIGltcG9ydGlu
Zw0KIw0KY2xhc3MgUGFja2FnZUFyY2hpdmVJbXBvcnRlcihJbXBvcnRlcik6
DQogICIiIkltcG9ydGVyIHN1YmNsYXNzIHRvIGltcG9ydCBmcm9tIChmaWxl
KSBhcmNoaXZlcy4NCg0KICBUaGlzIEltcG9ydGVyIGhhbmRsZXMgaW1wb3J0
cyBvZiB0aGUgc3R5bGUgPGFyY2hpdmU+LjxzdWJmaWxlPiwgd2hlcmUNCiAg
PGFyY2hpdmU+IGNhbiBiZSBsb2NhdGVkIHVzaW5nIGEgc3ViY2xhc3Mtc3Bl
Y2lmaWMgbWVjaGFuaXNtIGFuZCB0aGUNCiAgPHN1YmZpbGU+IGlzIGZvdW5k
IGluIHRoZSBhcmNoaXZlIHVzaW5nIGEgc3ViY2xhc3Mtc3BlY2lmaWMgbWVj
aGFuaXNtLg0KDQogIFRoaXMgY2xhc3MgZGVmaW5lcyB0d28gaG9va3MgZm9y
IHN1YmNsYXNzZXM6IG9uZSB0byBsb2NhdGUgYW4gYXJjaGl2ZQ0KICAoYW5k
IHBvc3NpYmx5IHJldHVybiBzb21lIGNvbnRleHQgZm9yIGZ1dHVyZSBzdWJm
aWxlIGxvb2t1cHMpLCBhbmQgb25lDQogIHRvIGxvY2F0ZSBzdWJmaWxlcy4N
CiAgIiIiDQoNCiAgZGVmIGdldF9jb2RlKHNlbGYsIHBhcmVudCwgbW9kbmFt
ZSwgZnFuYW1lKToNCiAgICBpZiBwYXJlbnQ6DQogICAgICAjIHRoZSBJbXBv
cnRlci5fZmluaXNoX2ltcG9ydCBsb2dpYyBlbnN1cmVzIHRoYXQgd2UgaGFu
ZGxlIGltcG9ydHMNCiAgICAgICMgdW5kZXIgdGhlIHRvcCBsZXZlbCBtb2R1
bGUgKHBhY2thZ2UgLyBhcmNoaXZlKS4NCiAgICAgIGFzc2VydCBwYXJlbnQu
X19pbXBvcnRlcl9fID09IHNlbGYNCg0KICAgICAgIyBpZiBhIHBhcmVudCAi
cGFja2FnZSIgaXMgcHJvdmlkZWQsIHRoZW4gd2UgYXJlIGltcG9ydGluZyBh
IHN1Yi1maWxlDQogICAgICAjIGZyb20gdGhlIGFyY2hpdmUuDQogICAgICBy
ZXN1bHQgPSBzZWxmLmdldF9zdWJmaWxlKHBhcmVudC5fX2FyY2hpdmVfXywg
bW9kbmFtZSkNCiAgICAgIGlmIHJlc3VsdCBpcyBOb25lOg0KICAgICAgICBy
ZXR1cm4gTm9uZQ0KICAgICAgaWYgdHlwZShyZXN1bHQpID09IHR5cGUoKCkp
Og0KICAgICAgICByZXR1cm4gKDAsKSArIHJlc3VsdA0KICAgICAgcmV0dXJu
IDAsIHJlc3VsdA0KDQogICAgIyBubyBwYXJlbnQgd2FzIHByb3ZpZGVkLCBz
byB0aGUgYXJjaGl2ZSBzaG91bGQgZXhpc3Qgc29tZXdoZXJlIG9uIHRoZQ0K
ICAgICMgZGVmYXVsdCAicGF0aCIuDQogICAgYXJjaGl2ZSA9IHNlbGYuZ2V0
X2FyY2hpdmUobW9kbmFtZSkNCiAgICBpZiBhcmNoaXZlIGlzIE5vbmU6DQog
ICAgICByZXR1cm4gTm9uZQ0KICAgIHJldHVybiAxLCAiIiwgeydfX2FyY2hp
dmVfXyc6YXJjaGl2ZX0NCg0KICBkZWYgZ2V0X2FyY2hpdmUoc2VsZiwgbW9k
bmFtZSk6DQogICAgIiIiR2V0IGFuIGFyY2hpdmUgb2YgbW9kdWxlcy4NCg0K
ICAgIFRoaXMgbWV0aG9kIHNob3VsZCBsb2NhdGUgYW4gYXJjaGl2ZSBhbmQg
cmV0dXJuIGEgdmFsdWUgd2hpY2ggY2FuIGJlDQogICAgdXNlZCBieSBnZXRf
c3ViZmlsZSB0byBsb2FkIG1vZHVsZXMgZnJvbSBpdC4gVGhlIHZhbHVlIG1h
eSBiZSBhIHNpbXBsZQ0KICAgIHBhdGhuYW1lLCBhbiBvcGVuIGZpbGUsIG9y
IGEgY29tcGxleCBvYmplY3QgdGhhdCBjYWNoZXMgaW5mb3JtYXRpb24NCiAg
ICBmb3IgZnV0dXJlIGltcG9ydHMuDQoNCiAgICBSZXR1cm4gTm9uZSBpZiB0
aGUgYXJjaGl2ZSB3YXMgbm90IGZvdW5kLg0KICAgICIiIg0KICAgIHJhaXNl
IFJ1bnRpbWVFcnJvciwgImdldF9hcmNoaXZlIG5vdCBpbXBsZW1lbnRlZCIN
Cg0KICBkZWYgZ2V0X3N1YmZpbGUoc2VsZiwgYXJjaGl2ZSwgbW9kbmFtZSk6
DQogICAgIiIiR2V0IGNvZGUgZnJvbSBhIHN1YmZpbGUgaW4gdGhlIHNwZWNp
ZmllZCBhcmNoaXZlLg0KDQogICAgR2l2ZW4gdGhlIHNwZWNpZmllZCBhcmNo
aXZlIChhcyByZXR1cm5lZCBieSBnZXRfYXJjaGl2ZSgpKSwgbG9jYXRlDQog
ICAgYW5kIHJldHVybiBhIGNvZGUgb2JqZWN0IGZvciB0aGUgc3BlY2lmaWVk
IG1vZHVsZSBuYW1lLg0KDQogICAgQSAyLXR1cGxlIG1heSBiZSByZXR1cm5l
ZCwgY29uc2lzdGluZyBvZiBhIGNvZGUgb2JqZWN0IGFuZCBhIGRpY3QNCiAg
ICBvZiBuYW1lL3ZhbHVlcyB0byBwbGFjZSBpbnRvIHRoZSB0YXJnZXQgbW9k
dWxlLg0KDQogICAgUmV0dXJuIE5vbmUgaWYgdGhlIHN1YmZpbGUgd2FzIG5v
dCBmb3VuZC4NCiAgICAiIiINCiAgICByYWlzZSBSdW50aW1lRXJyb3IsICJn
ZXRfc3ViZmlsZSBub3QgaW1wbGVtZW50ZWQiDQoNCg0KY2xhc3MgUGFja2Fn
ZUFyY2hpdmUoUGFja2FnZUFyY2hpdmVJbXBvcnRlcik6DQogICJQYWNrYWdl
QXJjaGl2ZUltcG9ydGVyIHN1YmNsYXNzIHRoYXQgcmVmZXJzIHRvIGEgc3Bl
Y2lmaWMgYXJjaGl2ZS4iDQoNCiAgZGVmIF9faW5pdF9fKHNlbGYsIG1vZG5h
bWUsIGFyY2hpdmVfcGF0aG5hbWUpOg0KICAgIHNlbGYuX19tb2RuYW1lID0g
bW9kbmFtZQ0KICAgIHNlbGYuX19wYXRoID0gYXJjaGl2ZV9wYXRobmFtZQ0K
DQogIGRlZiBnZXRfYXJjaGl2ZShzZWxmLCBtb2RuYW1lKToNCiAgICBpZiBt
b2RuYW1lID09IHNlbGYuX19tb2RuYW1lOg0KICAgICAgcmV0dXJuIHNlbGYu
X19wYXRoDQogICAgcmV0dXJuIE5vbmUNCg0KICAjIGdldF9zdWJmaWxlIGlz
IHBhc3NlZCB0aGUgZnVsbCBwYXRobmFtZSBvZiB0aGUgYXJjaGl2ZQ0KDQoN
CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMNCiMgRW11bGF0ZSB0aGUg
c3RhbmRhcmQgZGlyZWN0b3J5LWJhc2VkIGltcG9ydCBtZWNoYW5pc20NCiMN
CmNsYXNzIERpcmVjdG9yeUltcG9ydGVyKEltcG9ydGVyKToNCiAgIkltcG9y
dGVyIHN1YmNsYXNzIHRvIGVtdWxhdGUgdGhlIHN0YW5kYXJkIGltcG9ydGVy
LiINCg0KICBkZWYgX19pbml0X18oc2VsZiwgZGlyKToNCiAgICBzZWxmLmRp
ciA9IGRpcg0KDQogIGRlZiBnZXRfY29kZShzZWxmLCBwYXJlbnQsIG1vZG5h
bWUsIGZxbmFtZSk6DQogICAgaWYgcGFyZW50Og0KICAgICAgZGlyID0gcGFy
ZW50Ll9fcGtnZGlyX18NCiAgICBlbHNlOg0KICAgICAgZGlyID0gc2VsZi5k
aXINCg0KICAgICMgZGVmZXIgdGhlIGxvYWRpbmcgb2YgT1MtcmVsYXRlZCBm
YWNpbGl0aWVzDQogICAgaWYgbm90IF9vc19zdGF0Og0KICAgICAgX29zX2Jv
b3RzdHJhcCgpDQoNCiAgICAjIFJldHVybiB0aGUgbW9kdWxlIChhbmQgb3Ro
ZXIgaW5mbykgaWYgZm91bmQgaW4gdGhlIHNwZWNpZmllZA0KICAgICMgZGly
ZWN0b3J5LiBPdGhlcndpc2UsIHJldHVybiBOb25lLg0KICAgIHJldHVybiBf
ZnNfaW1wb3J0KGRpciwgbW9kbmFtZSwgZnFuYW1lKQ0KDQogIGRlZiBfX3Jl
cHJfXyhzZWxmKToNCiAgICByZXR1cm4gJzwlcy4lcyBmb3IgIiVzIiBhdCAw
eCV4PicgJSAoc2VsZi5fX2NsYXNzX18uX19tb2R1bGVfXywNCiAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2NsYXNz
X18uX19uYW1lX18sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgIHNlbGYuZGlyLA0KICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICBpZChzZWxmKSkNCg0KIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIw0KIw0KIyBFbXVsYXRlIHRoZSBzdGFuZGFyZCBwYXRoLXN0
eWxlIGltcG9ydCBtZWNoYW5pc20NCiMNCmNsYXNzIFBhdGhJbXBvcnRlcihJ
bXBvcnRlcik6DQogIGRlZiBfX2luaXRfXyhzZWxmLCBwYXRoPXN5cy5wYXRo
KToNCiAgICBzZWxmLnBhdGggPSBwYXRoDQoNCiAgICAjIHdlJ3JlIGRlZmlu
aXRlbHkgZ29pbmcgdG8gYmUgaW1wb3J0aW5nIHNvbWV0aGluZyBpbiB0aGUg
ZnV0dXJlLA0KICAgICMgc28gbGV0J3MganVzdCBsb2FkIHRoZSBPUy1yZWxh
dGVkIGZhY2lsaXRpZXMuDQogICAgaWYgbm90IF9vc19zdGF0Og0KICAgICAg
X29zX2Jvb3RzdHJhcCgpDQoNCiAgZGVmIGdldF9jb2RlKHNlbGYsIHBhcmVu
dCwgbW9kbmFtZSwgZnFuYW1lKToNCiAgICBpZiBwYXJlbnQ6DQogICAgICAj
IHdlIGFyZSBsb29raW5nIGZvciBhIG1vZHVsZSBpbnNpZGUgb2YgYSBzcGVj
aWZpYyBwYWNrYWdlDQogICAgICByZXR1cm4gX2ZzX2ltcG9ydChwYXJlbnQu
X19wa2dkaXJfXywgbW9kbmFtZSwgZnFuYW1lKQ0KDQogICAgIyBzY2FuIHN5
cy5wYXRoLCBsb29raW5nIGZvciB0aGUgcmVxdWVzdGVkIG1vZHVsZQ0KICAg
IGZvciBkaXIgaW4gc2VsZi5wYXRoOg0KICAgICAgcmVzdWx0ID0gX2ZzX2lt
cG9ydChkaXIsIG1vZG5hbWUsIGZxbmFtZSkNCiAgICAgIGlmIHJlc3VsdDoN
CiAgICAgICAgcmV0dXJuIHJlc3VsdA0KDQogICAgIyBub3QgZm91bmQNCiAg
ICByZXR1cm4gTm9uZQ0KDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMN
CiMNCiMgRW11bGF0ZSB0aGUgaW1wb3J0IG1lY2hhbmlzbSBmb3IgYnVpbHRp
biBhbmQgZnJvemVuIG1vZHVsZXMNCiMNCmNsYXNzIEJ1aWx0aW5JbXBvcnRl
cihJbXBvcnRlcik6DQogIGRlZiBnZXRfY29kZShzZWxmLCBwYXJlbnQsIG1v
ZG5hbWUsIGZxbmFtZSk6DQogICAgaWYgcGFyZW50Og0KICAgICAgIyB0aGVz
ZSBtb2R1bGVzIGRlZmluaXRlbHkgZG8gbm90IG9jY3VyIHdpdGhpbiBhIHBh
Y2thZ2UgY29udGV4dA0KICAgICAgcmV0dXJuIE5vbmUNCg0KICAgICMgbG9v
ayBmb3IgdGhlIG1vZHVsZQ0KICAgIGlmIGltcC5pc19idWlsdGluKG1vZG5h
bWUpOg0KICAgICAgdHlwZSA9IGltcC5DX0JVSUxUSU4NCiAgICBlbGlmIGlt
cC5pc19mcm96ZW4obW9kbmFtZSk6DQogICAgICB0eXBlID0gaW1wLlBZX0ZS
T1pFTg0KICAgIGVsc2U6DQogICAgICAjIG5vdCBmb3VuZA0KICAgICAgcmV0
dXJuIE5vbmUNCg0KICAgICMgZ290IGl0LiBub3cgbG9hZCBhbmQgcmV0dXJu
IGl0Lg0KICAgIG1vZHVsZSA9IGltcC5sb2FkX21vZHVsZShtb2RuYW1lLCBO
b25lLCBtb2RuYW1lLCAoJycsICcnLCB0eXBlKSkNCiAgICByZXR1cm4gMCwg
bW9kdWxlLCB7IH0NCg0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoj
DQojIEludGVybmFsIGltcG9ydGVyIHVzZWQgZm9yIGltcG9ydGluZyBmcm9t
IHRoZSBmaWxlc3lzdGVtDQojDQpjbGFzcyBfRmlsZXN5c3RlbUltcG9ydGVy
KEltcG9ydGVyKToNCiAgZGVmIF9faW5pdF9fKHNlbGYsIHN1ZmZpeGVzKToN
CiAgICAjIHRoaXMgbGlzdCBpcyBzaGFyZWQgd2l0aCB0aGUgSW1wb3J0TWFu
YWdlci4NCiAgICBzZWxmLnN1ZmZpeGVzID0gc3VmZml4ZXMNCg0KICBkZWYg
aW1wb3J0X2Zyb21fZGlyKHNlbGYsIGRpciwgZnFuYW1lKToNCiAgICByZXN1
bHQgPSBzZWxmLl9pbXBvcnRfcGF0aG5hbWUoX29zX3BhdGhfam9pbihkaXIs
IGZxbmFtZSksIGZxbmFtZSkNCiAgICBpZiByZXN1bHQ6DQogICAgICByZXR1
cm4gc2VsZi5fcHJvY2Vzc19yZXN1bHQocmVzdWx0LCBmcW5hbWUpDQogICAg
cmV0dXJuIE5vbmUNCg0KICBkZWYgZ2V0X2NvZGUoc2VsZiwgcGFyZW50LCBt
b2RuYW1lLCBmcW5hbWUpOg0KICAgICMgVGhpcyBpbXBvcnRlciBpcyBuZXZl
ciB1c2VkIHdpdGggYW4gZW1wdHkgcGFyZW50LiBJdHMgZXhpc3RlbmNlIGlz
DQogICAgIyBwcml2YXRlIHRvIHRoZSBJbXBvcnRNYW5hZ2VyLiBUaGUgSW1w
b3J0TWFuYWdlciB1c2VzIHRoZQ0KICAgICMgaW1wb3J0X2Zyb21fZGlyKCkg
bWV0aG9kIHRvIGltcG9ydCB0b3AtbGV2ZWwgbW9kdWxlcy9wYWNrYWdlcy4N
CiAgICAjIFRoaXMgbWV0aG9kIGlzIG9ubHkgdXNlZCB3aGVuIHdlIGxvb2sg
Zm9yIGEgbW9kdWxlIHdpdGhpbiBhIHBhY2thZ2UuDQogICAgYXNzZXJ0IHBh
cmVudA0KDQogICAgcmV0dXJuIHNlbGYuX2ltcG9ydF9wYXRobmFtZShfb3Nf
cGF0aF9qb2luKHBhcmVudC5fX3BrZ2Rpcl9fLCBtb2RuYW1lKSwNCiAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZxbmFtZSkNCg0KICBkZWYg
X2ltcG9ydF9wYXRobmFtZShzZWxmLCBwYXRobmFtZSwgZnFuYW1lKToNCiAg
ICBpZiBfb3NfcGF0aF9pc2RpcihwYXRobmFtZSk6DQogICAgICByZXN1bHQg
PSBzZWxmLl9pbXBvcnRfcGF0aG5hbWUoX29zX3BhdGhfam9pbihwYXRobmFt
ZSwgJ19faW5pdF9fJyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgZnFuYW1lKQ0KICAgICAgaWYgcmVzdWx0Og0KICAgICAgICB2
YWx1ZXMgPSByZXN1bHRbMl0NCiAgICAgICAgdmFsdWVzWydfX3BrZ2Rpcl9f
J10gPSBwYXRobmFtZQ0KICAgICAgICB2YWx1ZXNbJ19fcGF0aF9fJ10gPSBb
IHBhdGhuYW1lIF0NCiAgICAgICAgcmV0dXJuIDEsIHJlc3VsdFsxXSwgdmFs
dWVzDQogICAgICByZXR1cm4gTm9uZQ0KDQogICAgZm9yIHN1ZmZpeCwgaW1w
b3J0ZXIgaW4gc2VsZi5zdWZmaXhlczoNCiAgICAgIGZpbGVuYW1lID0gcGF0
aG5hbWUgKyBzdWZmaXgNCiAgICAgIHRyeToNCiAgICAgICAgZmluZm8gPSBf
b3Nfc3RhdChmaWxlbmFtZSkNCiAgICAgIGV4Y2VwdCBPU0Vycm9yOg0KICAg
ICAgICBwYXNzDQogICAgICBlbHNlOg0KICAgICAgICByZXR1cm4gaW1wb3J0
ZXIuaW1wb3J0X2ZpbGUoZmlsZW5hbWUsIGZpbmZvLCBmcW5hbWUpDQogICAg
cmV0dXJuIE5vbmUNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIw0K
IyBTVUZGSVgtQkFTRUQgSU1QT1JURVJTDQojDQoNCmNsYXNzIFN1ZmZpeElt
cG9ydGVyOg0KICBkZWYgaW1wb3J0X2ZpbGUoc2VsZiwgZmlsZW5hbWUsIGZp
bmZvLCBmcW5hbWUpOg0KICAgIHJhaXNlIFJ1bnRpbWVFcnJvcg0KDQpjbGFz
cyBQeVN1ZmZpeEltcG9ydGVyKFN1ZmZpeEltcG9ydGVyKToNCiAgZGVmIGlt
cG9ydF9maWxlKHNlbGYsIGZpbGVuYW1lLCBmaW5mbywgZnFuYW1lKToNCiAg
ICBmaWxlID0gZmlsZW5hbWVbOi0zXSArIF9zdWZmaXgNCiAgICB0X3B5ID0g
bG9uZyhmaW5mb1s4XSkNCiAgICB0X3B5YyA9IF90aW1lc3RhbXAoZmlsZSkN
Cg0KICAgIGNvZGUgPSBOb25lDQogICAgaWYgdF9weWMgaXMgbm90IE5vbmUg
YW5kIHRfcHljID49IHRfcHk6DQogICAgICBmID0gb3BlbihmaWxlLCAncmIn
KQ0KICAgICAgaWYgZi5yZWFkKDQpID09IGltcC5nZXRfbWFnaWMoKToNCiAg
ICAgICAgdCA9IHN0cnVjdC51bnBhY2soJzxJJywgZi5yZWFkKDQpKVswXQ0K
ICAgICAgICBpZiB0ID09IHRfcHk6DQogICAgICAgICAgY29kZSA9IG1hcnNo
YWwubG9hZChmKQ0KICAgICAgZi5jbG9zZSgpDQogICAgaWYgY29kZSBpcyBO
b25lOg0KICAgICAgZmlsZSA9IGZpbGVuYW1lDQogICAgICBjb2RlID0gX2Nv
bXBpbGUoZmlsZSwgdF9weSkNCg0KICAgIHJldHVybiAwLCBjb2RlLCB7ICdf
X2ZpbGVfXycgOiBmaWxlIH0NCg0KY2xhc3MgRHluTG9hZFN1ZmZpeEltcG9y
dGVyKFN1ZmZpeEltcG9ydGVyKToNCiAgZGVmIF9faW5pdF9fKHNlbGYsIGRl
c2MpOg0KICAgIHNlbGYuZGVzYyA9IGRlc2MNCg0KICBkZWYgaW1wb3J0X2Zp
bGUoc2VsZiwgZmlsZW5hbWUsIGZpbmZvLCBmcW5hbWUpOg0KICAgIGZwID0g
b3BlbihmaWxlbmFtZSwgc2VsZi5kZXNjWzFdKQ0KICAgIG1vZHVsZSA9IGlt
cC5sb2FkX21vZHVsZShmcW5hbWUsIGZwLCBmaWxlbmFtZSwgc2VsZi5kZXNj
KQ0KICAgIG1vZHVsZS5fX2ZpbGVfXyA9IGZpbGVuYW1lDQogICAgcmV0dXJu
IDAsIG1vZHVsZSwgeyB9DQoNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
Iw0KDQpkZWYgX3Rlc3RfZGlyKCk6DQogICJEZWJ1Zy90ZXN0IGZ1bmN0aW9u
IHRvIGNyZWF0ZSBEaXJlY3RvcnlJbXBvcnRlcnMgZnJvbSBzeXMucGF0aC4i
DQogIHBhdGggPSBzeXMucGF0aFs6XQ0KICBwYXRoLnJldmVyc2UoKQ0KICBm
b3IgZCBpbiBwYXRoOg0KICAgIERpcmVjdG9yeUltcG9ydGVyKGQpLmluc3Rh
bGwoKQ0KDQpkZWYgX3Rlc3RfcmV2YW1wKCk6DQogICJEZWJ1Zy90ZXN0IGZ1
bmN0aW9uIGZvciB0aGUgcmV2YW1wZWQgaW1wb3J0IHN5c3RlbS4iDQogIFBh
dGhJbXBvcnRlcigpLmluc3RhbGwoKQ0KICBCdWlsdGluSW1wb3J0ZXIoKS5p
bnN0YWxsKCkNCg0KZGVmIF9wcmludF9pbXBvcnRlcnMoKToNCiAgaXRlbXMg
PSBzeXMubW9kdWxlcy5pdGVtcygpDQogIGl0ZW1zLnNvcnQoKQ0KICBmb3Ig
bmFtZSwgbW9kdWxlIGluIGl0ZW1zOg0KICAgIGlmIG1vZHVsZToNCiAgICAg
IHByaW50IG5hbWUsIG1vZHVsZS5fX2RpY3RfXy5nZXQoJ19faW1wb3J0ZXJf
XycsICctLSBubyBpbXBvcnRlcicpDQogICAgZWxzZToNCiAgICAgIHByaW50
IG5hbWUsICctLSBub24tZXhpc3RlbnQgbW9kdWxlJw0KDQpkZWYgX3Rlc3Rf
cmV2YW1wKCk6DQogIEltcG9ydE1hbmFnZXIoKS5pbnN0YWxsKCkNCiAgc3lz
LnBhdGguaW5zZXJ0KDAsIEJ1aWx0aW5JbXBvcnRlcigpKQ0KDQojIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjDQo=
--1658348780-1657214722-946868004=:412--