Path: csiph.com!usenet.pasdenom.info!aioe.org!news.stack.nl!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'python.': 0.02; 'modified': 0.05; 'source.': 0.05; '64-bit': 0.07; 'exec': 0.07; 'filename:fname piece:py': 0.07; 'globals': 0.09; 'imported': 0.09; 'imports': 0.09; 'loop.': 0.09; 'plug': 0.09; 'received :mail-vc0-f174.google.com': 0.09; 'thread,': 0.09; 'gui': 0.11; 'source,': 0.15; '"good': 0.16; 'polling': 0.16; 'subject:import': 0.16; 'thread.': 0.16; 'threading': 0.16; 'vpython': 0.16; 'wxpython': 0.16; 'implementing': 0.17; 'module,': 0.17; 'creates': 0.18; 'solution.': 0.18; 'developer': 0.19; 'module': 0.19; 'math': 0.20; 'import': 0.21; 'minor': 0.22; 'subject:problem': 0.22; 'bruce': 0.23; 'nearly': 0.23; 'statement': 0.23; 'properties': 0.24; 'second': 0.24; 'header:In- Reply-To:1': 0.25; 'handling': 0.27; 'module.': 0.27; 'message- id:@mail.gmail.com': 0.27; 'run': 0.28; 'environment': 0.29; 'cocoa': 0.29; 'finds': 0.29; 'loop,': 0.29; 'received:209.85.220.174': 0.29; 'source': 0.29; "i'm": 0.29; 'attach': 0.30; 'function': 0.30; 'primary': 0.30; 'problem.': 0.32; 'structure': 0.32; 'comments': 0.33; 'animation': 0.33; 'avoiding': 0.33; 'to:addr:python-list': 0.33; 'received:google.com': 0.34; 'done': 0.34; 'thanks': 0.34; 'adds': 0.35; 'massive': 0.35; 'problem,': 0.35; 'received:209.85.220': 0.35; 'received:209.85': 0.35; 'there': 0.35; 'but': 0.36; "i'll": 0.36; 'test': 0.36; 'problems': 0.36; 'does': 0.37; 'level': 0.37; 'rather': 0.37; 'received:209': 0.37; 'subject:: ': 0.38; 'fact': 0.38; 'some': 0.38; 'to:addr:python.org': 0.39; 'header:Received:5': 0.40; 'containing': 0.61; 'solve': 0.62; 'more': 0.63; 'great': 0.64; 'forward': 0.66; 'content- type:application/octet-stream': 0.67; 'believe': 0.69; '100': 0.78; 'calculations': 0.84; 'clamps': 0.84; 'mac.': 0.84; 'tricky': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=xzDDu7cb/M67nSnozbDBN7XSwXQ5eNsWqVX/Mq0jEuY=; b=Xni78x28q8ltFj8kPGqrIUIAkiqO9M2CYtHTPAeT9JOfg6KwKoVH9fYp30QJBil/jj 4YLYSXoPEFQeEjd5yCAQ1EQ5GqjjjkcfYlL/ma8DOQVVQayU9dMz8qmD4NAXS47COPy+ ujQvhiUNK7S644NeIeuapPcc/+tuTdI7Hd34e52C7ptaEqCmWeffDGAZ/rE9xdmH59ay abl7Ndc66ZWB/1aq4ZjEgM1zYQLWHdKwbpFyER40OCzSMMRpe9KlAKX2/z6FKD2Dmgr6 ycaTTWlPfVn1R04BUBiHEvJRorSdlbgEeBYntYoQtSVeytEEOV38gjOMEjtazLaHssbg +evA== MIME-Version: 1.0 In-Reply-To: References: <87a9yt7bw6.fsf@handshake.de> <2u8m085co3j3n97jorkl04o5hr1orqb7la@invalid.netcom.com> <5gfm08htgbrum782hfv5fqkb4084qra7vq@invalid.netcom.com> Date: Mon, 23 Jul 2012 21:33:09 -0600 Subject: Re: A thread import problem From: Bruce Sherwood To: python-list@python.org Content-Type: multipart/mixed; boundary=bcaec53ae9ee720ea704c58b05cb X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 204 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1343100792 news.xs4all.nl 6899 [2001:888:2000:d::a6]:49877 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:25946 --bcaec53ae9ee720ea704c58b05cb Content-Type: text/plain; charset=ISO-8859-1 I'm happy to report that Robin Dunn, the developer of wxPython, showed me how to solve my VPython architectural problem, using wxPython. I attach a test program based on wxPython that has all of the properties I was looking for (though it needs some minor cleanups, including quitting gracefully, and handling timing better). The attached program userpoll.py imports the wxpython-based module wxpoll.py which does the following: Creates a wxpython environment but does not start the interact loop. Reads the source of the user program. Finds the import of the module and adds imported entities to globals used with exec. Comments out this import statement in the source. Does an exec of the modified source, in the primary thread. Because the exec is not done in a secondary thread, there are no problems associated with other imports such as math that may be in the user program. The exec-ed program has a loop in it, containing a rate statement which clamps to no more than 100 iterations per second (to make the animation run at a reasonable speed) and which calls a one-shot interact function in the import module. In other words, polling is used rather than using an interact loop, thereby avoiding the nearly intractable threading problems. Happily, Robin found a way to make this polling work with Cocoa on the Mac. I can now move forward with implementing this machinery for VPython, to be able to run VPython programs on 64-bit Pythons on the Mac. Hurray! You will find massive violations of "good practice" in the attached module, because in order to pull this off I have to do lots of calculations at the top level of the module. However, I believe the structure is in fact entirely reasonable and a good solution to a very tricky problem. Thanks to those of you who have made suggestions in this forum that fed into finding a solution. I'll put in a big plug for wxPython (wxpython.org), which is a great way to do cross-platform GUI development with Python. Bruce Sherwood --bcaec53ae9ee720ea704c58b05cb Content-Type: application/octet-stream; name="userpoll.py" Content-Disposition: attachment; filename="userpoll.py" Content-Transfer-Encoding: base64 X-Attachment-Id: f_h50ezzqj0 IyBBbiBleGFtcGxlIG9mIGEgc2ltcGxlIHVzZXIgcHJvZ3JhbQ0KZnJvbSB3eHBvbGwgaW1wb3J0 ICoNCmZyb20gbWF0aCBpbXBvcnQgY29zDQpwcmludCgnYWZ0ZXIgZ2V0dGluZyBtYXRoJykNCnBy aW50KGNvcygzLjE0MTU5LzQpKQ0Kcm9kID0gbGluZSgpDQp3aGlsZSByb2QuYW5nbGUgPCAyOg0K ICAgIHJhdGUoMTAwKQ0KICAgIHJvZC5hbmdsZSArPSAuMDENCg== --bcaec53ae9ee720ea704c58b05cb Content-Type: application/octet-stream; name="wxpoll.py" Content-Disposition: attachment; filename="wxpoll.py" Content-Transfer-Encoding: base64 X-Attachment-Id: f_h50f046c1 ZnJvbSBfX2Z1dHVyZV9fIGltcG9ydCBkaXZpc2lvbiwgcHJpbnRfZnVuY3Rpb24NCmltcG9ydCB3 eA0KZnJvbSB0aHJlYWRpbmcgaW1wb3J0IFRocmVhZA0KaW1wb3J0IHN5cw0KZnJvbSBtYXRoIGlt cG9ydCBzaW4sIGNvcw0KaW1wb3J0IHRpbWUNCg0KIyBUaGUgdXNlciBwcm9ncmFtIGltcG9ydHMg dGhpcyBtb2R1bGUsIHdoaWNoIGRvZXMgdGhpczoNCiMgICAoMSkgVXNlIHd4cHl0aG9uIHRvIHNl dCB1cCB0aGUgR1VJLCBidXQgbm90IHN0YXJ0IE1haW5Mb29wLg0KIyAgICgyKSBSZWFkIHRoZSBz b3VyY2Ugb2YgdGhlIHVzZXIgKGltcG9ydGluZykgcHJvZ3JhbS4NCiMgICAoMykgSW4gdGhlIHVz ZXIgc291cmNlLCBwcm9jZXNzIHRoZSBpbXBvcnQgb2YgdGhpcyBmaWxlLCB0aGVuDQojICAgICAg IGNvbW1lbnQgb3V0IHRoZSBpbXBvcnQgc3RhdGVtZW50Lg0KIyAgICg0KSBleGVjIHRoZSBzb3Vy Y2UsIHdpdGggc3VpdGFibGUgZ2xvYmFscyBzZXQgdXAgZm9yIHRoZSBleGVjLg0KIyBUaGUgdXNl ciBwcm9ncmFtIG11c3QgcGVyaW9kaWNhbGx5IGNhbGwgcmF0ZSgpLCB3aGljaCBkcml2ZXMgdGhl DQojIHNpbmdsZS1zaG90IGZ1bmN0aW9uIG9uZU1haW5Mb29wSXRlcmF0aW9uKCkgdG8gcHJvY2Vz cyBldmVudHMuDQoNCiMgQWxsIG9mIHRoaXMgY29tcGxleGl0eSBpcyBjYXVzZWQgYnkgdGhlIGZh Y3QgdGhhdCB0aGUgQ29jb2EgZnJhbWV3b3JrDQojIG9uIHRoZSBNYWMgd2lsbCBub3QgcnVuIGlm IE1haW5Mb29wIGlzIG5vdCBpbiB0aGUgcHJpbWFyeSB0aHJlYWQuDQojIEJhc2ljYWxseSwgd2Un dmUgdHVybmVkIHRoaW5ncyBpbnNpZGUgb3V0OiBJbnN0ZWFkIG9mIGRpcmVjdGx5IGV4ZWN1dGlu Zw0KIyB0aGUgdXNlcidzIHByb2dyYW0sIHRoZSB1c2VyJ3MgcHJvZ3JhbSBpbXBvcnRzIHRoaXMg bW9kdWxlIHdoaWNoIGluIHR1cm4NCiMgZXhlY3V0ZXMgYSBtb2RpZmllZCB2ZXJzaW9uIG9mIHRo ZSB1c2VyJ3MgcHJvZ3JhbS4NCg0KIyBBZGRpdGlvbmFsIGNvbXBsZXhpdHkgaXMgY2F1c2VkIGJ5 IHRoZSBmYWN0IHRoYXQgUHl0aG9uIGRvZXMgbm90IHBlcm1pdA0KIyBpbXBvcnRzIGZyb20gYSBz ZWNvbmRhcnkgdGhyZWFkIChvciBpbnNpZGUgYSBmdW5jdGlvbiBpbiBhbiBpbXBvcnQgbW9kdWxl KS4NCg0Kd2lkdGggPSA0MDAgIyBkZWZhdWx0IHdpbmRvdyB3aWR0aCBhbmQgaGVpZ2h0DQpoZWln aHQgPSA0MDANCg0KcmVuZGVyYWJsZV9vYmplY3RzID0gW10gIyBhY3RpdmUgb2JqZWN0cyB0byBi ZSByZW5kZXJlZCBwZXJpb2RpY2FsbHkNCg0KY2xhc3MgbGluZSgpOiAjIGEgc2ltcGxlIDJEIG9i amVjdCAoYSBsaW5lKQ0KICAgIGRlZiBfX2luaXRfXyhzZWxmKToNCiAgICAgICAgc2VsZi5jeCA9 IHdpZHRoLzINCiAgICAgICAgc2VsZi5jeSA9IChoZWlnaHQtNTApLzINCiAgICAgICAgc2VsZi5M ID0gMTQwDQogICAgICAgIHNlbGYuYW5nbGUgPSAwDQogICAgICAgIHJlbmRlcmFibGVfb2JqZWN0 cy5hcHBlbmQoc2VsZikNCg0KICAgIGRlZiB1cGRhdGUoc2VsZik6DQogICAgICAgIGR4ID0gKHNl bGYuTC8yKSpjb3Moc2VsZi5hbmdsZSkNCiAgICAgICAgZHkgPSAoc2VsZi5MLzIpKnNpbihzZWxm LmFuZ2xlKQ0KICAgICAgICByZXR1cm4gKHNlbGYuY3gtZHgsIHNlbGYuY3krZHksIHNlbGYuY3gr ZHgsIHNlbGYuY3ktZHkpICMgaW52ZXJ0IHkgY29vcmRpbmF0ZXMNCg0KbGFzdHJhdGUgPSAwICMg dGltZSBvZiBsYXN0IGNhbGwgdG8gcmF0ZSgpDQpkZWYgcmF0ZShmKTogIyBsaW1pdCBhIGxvb3Ag cmF0ZSB0byBmIGl0ZXJhdGlvbnMgcGVyIHNlY29uZA0KICAgIGdsb2JhbCBsYXN0cmF0ZQ0KICAg IGR0ID0gMS4wL2YNCiAgICBsYXN0cmF0ZSArPSBkdA0KICAgIHQgPSB0aW1lLnRpbWUoKQ0KICAg IGlmIGxhc3RyYXRlID4gdDoNCiAgICAgICAgb25lTWFpbkxvb3BJdGVyYXRpb24oKQ0KICAgICAg ICB0aW1lLnNsZWVwKGxhc3RyYXRlLXQpDQogICAgZWxzZToNCiAgICAgICAgaWYgbGFzdHJhdGUg PCB0LTAuMTogbGFzdHJhdGUgPSB0DQoNCmNsYXNzIEZyYW1lKHd4LkZyYW1lKTogIyBzZXQgdXAg dGhlIEdVSSBlbnZpcm9ubWVudA0KICAgIGRlZiBfX2luaXRfXyhzZWxmLCBwYXJlbnQsIHcsIGgs IHRpdGxlKToNCiAgICAgICAgc3VwZXIoRnJhbWUsIHNlbGYpLl9faW5pdF9fKHBhcmVudCwgdGl0 bGU9dGl0bGUsIA0KICAgICAgICAgICAgc2l6ZT0odywgaCksIHBvcz0oMCwzMCkpDQogICAgICAg IGdsb2JhbCB3aWR0aCwgaGVpZ2h0DQogICAgICAgIHdpZHRoID0gdw0KICAgICAgICBoZWlnaHQg PSBoDQoNCiAgICAgICAgTWVudUJhciA9IHd4Lk1lbnVCYXIoKQ0KICAgICAgICBGaWxlTWVudSA9 IHd4Lk1lbnUoKQ0KICAgICAgICBpdGVtID0gRmlsZU1lbnUuQXBwZW5kKHd4LklEX0VYSVQsICIm RXhpdCIpDQogICAgICAgIHNlbGYuQmluZCh3eC5FVlRfTUVOVSwgc2VsZi5PblF1aXQsIGl0ZW0p DQogICAgICAgIE1lbnVCYXIuQXBwZW5kKEZpbGVNZW51LCAiJkZpbGUiKQ0KICAgICAgICBzZWxm LlNldE1lbnVCYXIoTWVudUJhcikNCg0KICAgICAgICBzZWxmLkJpbmQod3guRVZUX1BBSU5ULCBz ZWxmLk9uUGFpbnQpDQogICAgICAgIA0KICAgICAgICBzZWxmLnRpbWVyID0gd3guVGltZXIoc2Vs ZikNCiAgICAgICAgc2VsZi5CaW5kKHd4LkVWVF9USU1FUiwgc2VsZi5PblRpbWVyLCBzZWxmLnRp bWVyKQ0KICAgICAgICBzZWxmLnRpbWVyLlN0YXJ0KDMwKSAjIHJlbmRlciBldmVyeSAzMCBtaWxs aXNlY29uZHMNCg0KICAgICAgICBzZWxmLlNob3coKQ0KDQogICAgZGVmIHJlbmRlcihzZWxmKTog IyBwZXJpb2RpY2FsbHkgcmVuZGVyIGV4aXN0aW5nIG9iamVjdHMsIGJhc2VkIG9uIHRoZSBjdXJy ZW50IGF0dHJpYnV0ZXMNCiAgICAgICAgaWYgbGVuKHJlbmRlcmFibGVfb2JqZWN0cykgPiAwOg0K ICAgICAgICAgICAgZGMgPSB3eC5DbGllbnREQyhzZWxmKQ0KICAgICAgICAgICAgZGMuQ2xlYXIo KQ0KICAgICAgICAgICAgeDEsIHkxLCB4MiwgeTIgPSByZW5kZXJhYmxlX29iamVjdHNbMF0udXBk YXRlKCkgIyBvbmx5IG9uZSBvYmplY3QgZm9yIG5vdywgYSBsaW5lDQogICAgICAgICAgICBkYy5E cmF3TGluZSh4MSwgeTEsIHgyLCB5MikNCg0KICAgIGRlZiBPblF1aXQoc2VsZiwgZXZ0KToNCiAg ICAgICAgc2VsZi5EZXN0cm95KCkNCg0KICAgIGRlZiBPblRpbWVyKHNlbGYsIGV2dCk6DQogICAg ICAgIHNlbGYucmVuZGVyKCkNCg0KICAgIGRlZiBPblBhaW50KHNlbGYsIGV2dCk6DQogICAgICAg IHNlbGYucmVuZGVyKCkNCg0KYXBwID0gd3guQXBwKCkgICMgY3JlYXRlIGEgd3hweXRob24gYXBw bGljYXRpb24NCkZyYW1lKE5vbmUsIDMwMCwgMzAwLCAnUm90YXRpbmcgTGluZScpICMgc2V0IHVw IHd4cHl0aG9uIEdVSSBlbnZpcm9ubWVudA0KICAgICAgICAgDQpldnRsb29wID0gd3guR1VJRXZl bnRMb29wKCkNCnd4LkV2ZW50TG9vcC5TZXRBY3RpdmUoZXZ0bG9vcCkNCg0KZGVmIG9uZU1haW5M b29wSXRlcmF0aW9uKCk6DQogICAgd2hpbGUgbm90IGV2dGxvb3AuUGVuZGluZygpIGFuZCBldnRs b29wLlByb2Nlc3NJZGxlKCk6IHBhc3MNCiAgICBpZiB3eC5HZXRBcHAoKTogd3guR2V0QXBwKCku UHJvY2Vzc1BlbmRpbmdFdmVudHMoKQ0KICAgIGlmIG5vdCBldnRsb29wLkRpc3BhdGNoKCk6IHJl dHVybg0KICAgICMgQ3VycmVudGx5IG9uIHd4T1NYIFBlbmRpbmcgYWx3YXlzIHJldHVybnMgdHJ1 ZSwgc28gdGhlDQogICAgIyBQcm9jZXNzSWRsZSBhYm92ZSBpcyBub3QgZXZlciBjYWxsZWQuIENh bGwgaXQgaGVyZSBpbnN0ZWFkLg0KICAgIGlmICd3eE9TWCcgaW4gd3guUGxhdGZvcm1JbmZvOiBl dnRsb29wLlByb2Nlc3NJZGxlKCkNCiAgICB3aGlsZSBUcnVlOg0KICAgICAgICBjaGVja0FnYWlu ID0gRmFsc2UNCiAgICAgICAgaWYgd3guR2V0QXBwKCkgYW5kIHd4LkdldEFwcCgpLkhhc1BlbmRp bmdFdmVudHMoKToNCiAgICAgICAgICAgIHd4LkdldEFwcCgpLlByb2Nlc3NQZW5kaW5nRXZlbnRz KCkNCiAgICAgICAgICAgIGNoZWNrQWdhaW4gPSBUcnVlDQogICAgICAgIGlmICd3eE9TWCcgbm90 IGluIHd4LlBsYXRmb3JtSW5mbyBhbmQgZXZ0bG9vcC5QZW5kaW5nKCk6DQogICAgICAgICAgICBl dnRsb29wLkRpc3BhdGNoKCkNCiAgICAgICAgICAgIGNoZWNrQWdhaW4gPSBUcnVlDQogICAgICAg IGlmIG5vdCBjaGVja0FnYWluOg0KICAgICAgICAgICAgYnJlYWsNCg0KIyBJbXBvcnRzIG11c3Qg YmUgaGFuZGxlZCBoZXJlLCBhdCBiYXNlIGxldmVsIGluIHRoZSBtb2R1bGUgKG5vdCBpbiBhIGRl ZikuDQojIEZvciB0aGUgaW1wb3J0IHN0YXRlbWVudCBpbiB0aGUgdXNlciBmaWxlIHRoYXQgaW1w b3J0cyB0aGlzIG1vZHVsZSwgd2UgcGVyZm9ybQ0KIyB0aGUgaW1wb3J0IGFuZCBleHRyYWN0IHRo ZSBpbXBvcnRlZCBpbmZvcm1hdGlvbiwgYWRkaW5nIGl0IHRvIHRoZSBnbG9iYWxzDQojIHVzZWQg dG8gZXhlYyB0aGUgZmlsZS4NCg0KIyBJbml0aWFsaXplIGV4ZWMncyBnbG9iYWxzIHNvIHRoYXQg dXNlciBwcm9ncmFtIHVzZXMgZnV0dXJlIGRpdmlzaW9uIGFuZCBwcmludF9mdW5jdGlvbjoNCmdp bmZvID0geydkaXZpc2lvbic6Z2xvYmFscygpWydkaXZpc2lvbiddLCAncHJpbnRfZnVuY3Rpb24n Omdsb2JhbHMoKVsncHJpbnRfZnVuY3Rpb24nXX0NCmZpbGVuYW1lID0gc3lzLmFyZ3ZbMF0NCnBy b2cgPSBvcGVuKGZpbGVuYW1lKS5yZWFkKCkgIyByZWFkIHN0YXJ0aW5nIC5weSBmaWxlDQoNCmRl ZiB1bmRlcnNjb3JlKHByZWZpeCk6ICMgY29udmVydCB3eHBvbGwucmF0ZSB0byB3eHBvbGxfcmF0 ZQ0KICAgIGdsb2JhbCBwcm9nDQogICAgcHJlZml4ICs9ICcuJw0KICAgIHN0YXJ0ID0gMA0KICAg IHdoaWxlIFRydWU6DQogICAgICAgIGYgPSBwcm9nLmZpbmQocHJlZml4KQ0KICAgICAgICBpZiBm IDwgMDogYnJlYWsNCiAgICAgICAgZiArPSBsZW4ocHJlZml4KS0xDQogICAgICAgIHByb2cgPSBw cm9nWzpmXSsnXycrcHJvZ1tmKzE6XQ0KDQppbXBvcnRhYmxlcyA9IFsncmF0ZScsICdsaW5lJ10N CnN0YXJ0ID0gMA0Kd2hpbGUgVHJ1ZToNCiAgICAjIEZpbmQgYSBzdGF0ZW1lbnQgImZyb20geCBp bXBvcnQgeSIgb3IgYSBzdGF0ZW1lbnQgImltcG9ydCB4IiBvciAiaW1wb3J0IHggYXMgeSINCiAg ICAjIEFzc3VtZXMgZm9yIHRoZSBtb21lbnQgdGhhdCB0aGUgaW1wb3J0IHN0YXRlbWVudCBpcyBu b3QgaW5kZW50ZWQsIG5vciBwcmVjZWRlZCBieSAiOyAiDQogICAgIyBTZWUgdGVzdCBwcm9ncmFt IHBhcnNlX3Rlc3QucHkNCiAgICBpbXAgPSBwcm9nLmZpbmQoJ2ltcG9ydCcsIHN0YXJ0KQ0KICAg IGlmIGltcCA9PSAtMTogYnJlYWsNCiAgICBiZWdpbiA9IHByb2cucmZpbmQoJ1xuJywgMCwgaW1w KSsxDQogICAgaWYgYmVnaW4gPT0gLTE6IGJlZ2luID0gMA0KICAgIGVuZCA9IHByb2cuZmluZCgn XG4nLCBiZWdpbikNCiAgICBpZiBlbmQgPT0gLTE6IGVuZCA9IGxlbihwcm9nKS0xDQogICAgc3Rh cnQgPSBlbmQrMQ0KICAgIGlmICggaW1wID09IGJlZ2luIGFuZCBub3QgcHJvZ1tpbXArNl0uaXNh bG51bSgpICkgb3IgXA0KICAgICAgICAgICAoIHByb2dbYmVnaW46YmVnaW4rNV0gPT0gJ2Zyb20g JyBhbmQgXA0KICAgICAgICAgICAgIG5vdCBwcm9nW2ltcC0xXS5pc2FsbnVtKCkgYW5kIG5vdCBw cm9nW2ltcCs2XS5pc2FsbnVtKCkgKToNCiAgICAgICAgIyBGb3VuZCBhIGxlZ2l0aW1hdGUgaW1w b3J0IHN0YXRlbWVudA0KICAgICAgICBzdG10ID0gcHJvZ1tiZWdpbjplbmRdICMgdGhlIGltcG9y dCBzdGF0ZW1lbnQNCiAgICAgICAgcHJvZyA9IHByb2dbOmJlZ2luXSsnIycrcHJvZ1tiZWdpbjpd ICMgY29tbWVudCBvdXQgdGhlIGltcG9ydCBzdGF0ZW1lbnQgaW4gc291cmNlDQogICAgICAgIHQg PSBzdG10LnNwbGl0KCkNCiAgICAgICAgaWYgdFswXSA9PSAnaW1wb3J0JzoNCiAgICAgICAgICAg IGlmIGxlbih0KSA8IDI6DQogICAgICAgICAgICAgICAgcmFpc2UgSW1wb3J0RXJyb3IocykNCiAg ICAgICAgICAgIFggPSB0WzFdDQogICAgICAgICAgICBpZiBsZW4odCkgPT0gMjoNCiAgICAgICAg ICAgICAgICBpbXBvcnRfdHlwZSA9IDANCiAgICAgICAgICAgICAgICBpbXBvcnRfaW5mbyA9IFsn aW1wb3J0JywgWF0NCiAgICAgICAgICAgIGVsaWYgdFsyXSA9PSAnYXMnOg0KICAgICAgICAgICAg ICAgIGlmIGxlbih0KSAhPSA0Og0KICAgICAgICAgICAgICAgICAgICByYWlzZSBJbXBvcnRFcnJv cihzKQ0KICAgICAgICAgICAgICAgIGltcG9ydF90eXBlID0gMQ0KICAgICAgICAgICAgICAgIGlt cG9ydF9pbmZvID0gWydpbXBvcnQnLCBYLCAnYXMnLCB0WzNdXQ0KICAgICAgICAgICAgZWxzZToN CiAgICAgICAgICAgICAgICByYWlzZSBJbXBvcnRFcnJvcihzKQ0KICAgICAgICBlbGlmIHRbMF0g PT0gJ2Zyb20nOg0KICAgICAgICAgICAgaWYgbGVuKHQpIDwgNCBvciB0WzJdICE9ICdpbXBvcnQn Og0KICAgICAgICAgICAgICAgIHJhaXNlIEltcG9ydEVycm9yKHMpDQogICAgICAgICAgICBYID0g dFsxXQ0KICAgICAgICAgICAgaWYgdFstMV0gPT0gJyonIGFuZCBsZW4odCkgPT0gNDoNCiAgICAg ICAgICAgICAgICBpbXBvcnRfdHlwZSA9IDMNCiAgICAgICAgICAgICAgICBpbXBvcnRfaW5mbyA9 IFsnZnJvbScsIFgsICdpbXBvcnQnLCAnKiddDQogICAgICAgICAgICBlbHNlOg0KICAgICAgICAg ICAgICAgIG5hbWVzID0gW10NCiAgICAgICAgICAgICAgICBmb3IgbiBpbiB0WzM6XToNCiAgICAg ICAgICAgICAgICAgICAgZm9yIHNwIGluIG4uc3BsaXQoJywnKToNCiAgICAgICAgICAgICAgICAg ICAgICAgIGlmIHNwID09ICcnOiBjb250aW51ZQ0KICAgICAgICAgICAgICAgICAgICAgICAgbmFt ZXMuYXBwZW5kKHNwKQ0KICAgICAgICAgICAgICAgIGltcG9ydF9pbmZvID0gWydmcm9tJywgWCwg J2ltcG9ydCddDQogICAgICAgICAgICAgICAgZm9yIG4gaW4gbmFtZXM6DQogICAgICAgICAgICAg ICAgICAgIGltcG9ydF9pbmZvLmFwcGVuZChuKQ0KICAgICAgICAgICAgICAgIGltcG9ydF90eXBl ID0gMg0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgcmFpc2UgSW1wb3J0RXJyb3Ioc3RtdCkN CiAgICAgICAgaWYgaW1wb3J0X2luZm9bMV0gPT0gX19uYW1lX186ICMgaGFuZGxlIGltcG9ydHMg ZnJvbSB0aGlzIG1vZHVsZQ0KICAgICAgICAgICAgaWYgaW1wb3J0X3R5cGUgPT0gMDogIyBpbXBv cnQgdGhpc19tb2R1bGUNCiAgICAgICAgICAgICAgICBmb3IgbmFtZSBpbiBpbXBvcnRhYmxlczoN CiAgICAgICAgICAgICAgICAgICAgZ2luZm9baW1wb3J0X2luZm9bMV0rJ18nK25hbWVdID0gZ2xv YmFscygpW25hbWVdDQogICAgICAgICAgICAgICAgdW5kZXJzY29yZShpbXBvcnRfaW5mb1sxXSkN CiAgICAgICAgICAgIGVsaWYgaW1wb3J0X3R5cGUgPT0gMTogIyBpbXBvcnQgdGhpc19tb2R1bGUg YXMgc29tZXRoaW5nDQogICAgICAgICAgICAgICAgZm9yIG5hbWUgaW4gaW1wb3J0YWJsZXM6DQog ICAgICAgICAgICAgICAgICAgIGdpbmZvW2ltcG9ydF9pbmZvWzNdKydfJytuYW1lXSA9IGdsb2Jh bHMoKVtuYW1lXQ0KICAgICAgICAgICAgICAgIHVuZGVyc2NvcmUoaW1wb3J0X2luZm9bM10pICAg DQogICAgICAgICAgICBlbGlmIGltcG9ydF90eXBlID09IDI6ICMgZnJvbSB0aGlzX21vZHVsZSBp bXBvcnQgeCwgeSwgeg0KICAgICAgICAgICAgICAgIGZvciBuYW1lIGluIGltcG9ydF9pbmZvWzM6 XToNCiAgICAgICAgICAgICAgICAgICAgaWYgbmFtZSBpbiBpbXBvcnRhYmxlczoNCiAgICAgICAg ICAgICAgICAgICAgICAgIGdpbmZvW25hbWVdID0gZ2xvYmFscygpW25hbWVdDQogICAgICAgICAg ICAgICAgICAgIGVsc2U6DQogICAgICAgICAgICAgICAgICAgICAgICByYWlzZSBJbXBvcnRFcnJv cihzdG10KQ0KICAgICAgICAgICAgZWxpZiBpbXBvcnRfdHlwZSA9PSAzOiAjIGZyb20gdGhpc19t b2R1bGUgaW1wb3J0ICoNCiAgICAgICAgICAgICAgICBmb3IgaW0gaW4gaW1wb3J0YWJsZXM6DQog ICAgICAgICAgICAgICAgICAgIGdpbmZvW2ltXSA9IGdsb2JhbHMoKVtpbV0NCiAgICAgICAgICAg IGJyZWFrDQogICAgc3RhcnQgPSBlbmQNCg0KZXhlYyhwcm9nLCBnaW5mbykNCndoaWxlIFRydWU6 ICMgYXQgZW5kIG9mIHVzZXIgcHJvZ3JhbSwgd2FpdCBmb3IgdXNlciB0byBjbG9zZSB0aGUgcHJv Z3JhbQ0KICAgIHJhdGUoMzApDQo= --bcaec53ae9ee720ea704c58b05cb--