From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Julian Graham Newsgroups: gmane.lisp.guile.devel Subject: r6rs libraries, round three Date: Sat, 26 Sep 2009 16:10:19 -0400 Message-ID: <2bc5f8210909261310q7a32ff83x8ebceb44a78d55c5@mail.gmail.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary=0016e6d7837e5bdabc047480a744 X-Trace: ger.gmane.org 1253995840 31696 80.91.229.12 (26 Sep 2009 20:10:40 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 26 Sep 2009 20:10:40 +0000 (UTC) To: guile-devel Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sat Sep 26 22:10:33 2009 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1MrdbE-0002H2-Ga for guile-devel@m.gmane.org; Sat, 26 Sep 2009 22:10:33 +0200 Original-Received: from localhost ([127.0.0.1]:43165 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MrdbD-0000AR-D9 for guile-devel@m.gmane.org; Sat, 26 Sep 2009 16:10:31 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Mrdb8-0000AI-4q for guile-devel@gnu.org; Sat, 26 Sep 2009 16:10:26 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Mrdb3-0000A1-IU for guile-devel@gnu.org; Sat, 26 Sep 2009 16:10:25 -0400 Original-Received: from [199.232.76.173] (port=57010 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Mrdb3-00009y-Cr for guile-devel@gnu.org; Sat, 26 Sep 2009 16:10:21 -0400 Original-Received: from mail-ew0-f208.google.com ([209.85.219.208]:62084) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Mrdb2-0005zV-On for guile-devel@gnu.org; Sat, 26 Sep 2009 16:10:21 -0400 Original-Received: by ewy4 with SMTP id 4so1602125ewy.31 for ; Sat, 26 Sep 2009 13:10:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:date:message-id:subject :from:to:content-type; bh=D0R5wrC7ErzOjyBojOVm1tfXjtOTmjuDuM4bVj51Tv8=; b=l+wxKC/cT+j3gmCWrh62gZD6oDDWPSSu8MGMwht8OJq5FLzvIJkhtpDM1J9sYredAj AnwAaGF2NMZpvB387Bg7pHxVF0LUxk3sl6qzFwh36IRuRuq7Bg4Wlfhz7D40J+7ATffn 0yRDYmL9mc3pizLXFD+BDLoMOKQIlUVRsbZE0= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=tIrBKTWSyc+3kCg4qbnCG3/9/pyNqOf5YbZFx95N4GIGY3Irj4fTkyxsFTBuyv1jJw g5kcPKznpWvdGlL2R+NWmhpGSIEK7nxaZhouUXSPPbKzUdE6f2pXEHIcQdi8zaK5wlwU 0hIcppu2QoGv2a4GLVtWI27VKg9kbMy+HkE3Q= Original-Received: by 10.216.88.209 with SMTP id a59mr362845wef.50.1253995819288; Sat, 26 Sep 2009 13:10:19 -0700 (PDT) X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:9403 Archived-At: --0016e6d7837e5bdabc047480a744 Content-Type: text/plain; charset=ISO-8859-1 Hi Guilers, Having been motivated by an extended discussion with Andy over pints in Brooklyn last weekend, I've resolved to return to the issue of R6RS library support once more. As discussed the last time we took this on, I think the first step is getting support for version information into the modules system. Find attached a patch that adds trivial support for versions to boot-9.scm. Applying this patch gives you the ability to specify an R6RS-compatible (i.e., `(x y z...)' where x, y, and z are whole numbers) version, via a #:version keyword argument, for both the `define-module' and `use-modules' forms. Specifying a version in your `use-modules' that doesn't match the version of an already-loaded module with that name will raise an error. This patch is "trivial" because version matching at the moment is done via `equal?' and thus doesn't support the full range of matching behavior outlined by R6RS. More importantly, though, it's missing support for matching versions on disk. I got most of the way through an initial implementation of that when I found myself in some trickiness. To recap, what I think we decided about storing versioned modules was: Module version numbers can be represented in a directory hierarchy: [dir-hint] / x / y / z / module.scm, e.g. ice-9/0/1/2/readline.scm. This is approach has the benefit that it can co-exist with the traditional directory structure for Guile modules, since numbers can't be confused with module name components [1]. But this also means that the path searching performed by `primitive-load-path' won't work for locating these modules, and Andy's symlink solution [2] doesn't really help that much, since R6RS version matching sometimes requires that we select a number based on a set of constraints, not just a straight-up wildcard. The solution I'm working on does the following: 1. Combine every entry in `%load-path' with the "dir hint" to produce a list of root paths to search. 2. For every component of the version reference, for every root path, find all subdirectories with names that match the reference. 3. Sort the results in numerically descending order; these are the new root paths. 4. Loop back to step 2 until all components of the version reference have been matched and a module file has been found. The problem I ran into is that once I've finished this procedure, I've got an absolute path to the module, and I want to load it by performing the same autocompilation heuristics that `primitive-load-path' provides -- but that function only works on relative paths. How come this magic hasn't been added to `primitive-load' (or some other function that operates on absolute paths)? Regards, Julian [1] - http://www.mail-archive.com/guile-devel@gnu.org/msg03259.html [2] - http://article.gmane.org/gmane.lisp.guile.devel/8585 --0016e6d7837e5bdabc047480a744 Content-Type: text/x-diff; charset=US-ASCII; name="0001-Initial-support-for-version-information-in-Guile-s.patch" Content-Disposition: attachment; filename="0001-Initial-support-for-version-information-in-Guile-s.patch" Content-Transfer-Encoding: base64 X-Attachment-Id: f_g02qqh840 RnJvbSBhMWQ0OWMwMGNkNmNjMTQ0YmY1MjY0ODFlNWJhN2RhNmFlZmEwODIyIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBKdWxpYW4gR3JhaGFtIDxqdWxpYW4uZ3JhaGFtQGF5YS55YWxl LmVkdT4KRGF0ZTogU2F0LCAyNiBTZXAgMjAwOSAxNDo1Mjo1NiAtMDQwMApTdWJqZWN0OiBbUEFU Q0hdIEluaXRpYWwgc3VwcG9ydCBmb3IgdmVyc2lvbiBpbmZvcm1hdGlvbiBpbiBHdWlsZSdzIGBt b2R1bGUnIGZvcm0uCgoqIG1vZHVsZS9pY2UtOS9ib290LTkuc2NtIChtb2R1bGUtdmVyc2lvbiwg c2V0LW1vZHVsZS12ZXJzaW9uISwgdmVyc2lvbi1tYXRjaGVzPyk6Ck5ldyBmdW5jdGlvbnMuCiog bW9kdWxlL2ljZS05L2Jvb3QtOS5zY20gKG1vZHVsZS10eXBlLCBtYWtlLW1vZHVsZSwgcmVzb2x2 ZS1tb2R1bGUsIHRyeS1sb2FkLW1vZHVsZSwgcHJvY2Vzcy1kZWZpbmUtbW9kdWxlLCBtYWtlLWF1 dG9sb2FkLWludGVyZmFjZSwgY29tcGlsZS1pbnRlcmZhY2Utc3BlYyk6CkFkZCBhd2FyZW5lc3Mg YW5kIGNoZWNraW5nIG9mIHZlcnNpb24gaW5mb3JtYXRpb24uCi0tLQogbW9kdWxlL2ljZS05L2Jv b3QtOS5zY20gfCAgIDQyICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0tLS0tLS0tLS0t LQogMSBmaWxlcyBjaGFuZ2VkLCAzMCBpbnNlcnRpb25zKCspLCAxMiBkZWxldGlvbnMoLSkKCmRp ZmYgLS1naXQgYS9tb2R1bGUvaWNlLTkvYm9vdC05LnNjbSBiL21vZHVsZS9pY2UtOS9ib290LTku c2NtCmluZGV4IGExNTM3ZDEuLmI0OWY3OTkgMTAwNjQ0Ci0tLSBhL21vZHVsZS9pY2UtOS9ib290 LTkuc2NtCisrKyBiL21vZHVsZS9pY2UtOS9ib290LTkuc2NtCkBAIC0xMzMyLDggKzEzMzIsOCBA QAogKGRlZmluZSBtb2R1bGUtdHlwZQogICAobWFrZS1yZWNvcmQtdHlwZSAnbW9kdWxlCiAJCSAg ICAnKG9iYXJyYXkgdXNlcyBiaW5kZXIgZXZhbC1jbG9zdXJlIHRyYW5zZm9ybWVyIG5hbWUga2lu ZAotCQkgICAgICBkdXBsaWNhdGVzLWhhbmRsZXJzIGltcG9ydC1vYmFycmF5Ci0JCSAgICAgIG9i c2VydmVycyB3ZWFrLW9ic2VydmVycykKKwkJICAgICAgZHVwbGljYXRlcy1oYW5kbGVycyBpbXBv cnQtb2JhcnJheSBvYnNlcnZlcnMgCisJCSAgICAgIHdlYWstb2JzZXJ2ZXJzIHZlcnNpb24pCiAJ CSAgICAlcHJpbnQtbW9kdWxlKSkKIAogOzsgbWFrZS1tb2R1bGUgJm9wdCBzaXplIHVzZXMgYmlu ZGVyCkBAIC0xMzc0LDEzICsxMzc0LDEyIEBACiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAjZiAjZiAjZgogCQkJCQkgIChtYWtlLWhhc2gtdGFibGUgJWRlZmF1bHQt aW1wb3J0LXNpemUpCiAJCQkJCSAgJygpCi0JCQkJCSAgKG1ha2Utd2Vhay1rZXktaGFzaC10YWJs ZSAzMSkpKSkKKwkJCQkJICAobWFrZS13ZWFrLWtleS1oYXNoLXRhYmxlIDMxKSAjZikpKQogCiAJ ICA7OyBXZSBjYW4ndCBwYXNzIHRoaXMgYXMgYW4gYXJndW1lbnQgdG8gbW9kdWxlLWNvbnN0cnVj dG9yLAogCSAgOzsgYmVjYXVzZSB3ZSBuZWVkIGl0IHRvIGNsb3NlIG92ZXIgYSBwb2ludGVyIHRv IHRoZSBtb2R1bGUKIAkgIDs7IGl0c2VsZi4KIAkgIChzZXQtbW9kdWxlLWV2YWwtY2xvc3VyZSEg bW9kdWxlIChzdGFuZGFyZC1ldmFsLWNsb3N1cmUgbW9kdWxlKSkKLQogCSAgbW9kdWxlKSkpKQog CiAoZGVmaW5lIG1vZHVsZS1jb25zdHJ1Y3RvciAocmVjb3JkLWNvbnN0cnVjdG9yIG1vZHVsZS10 eXBlKSkKQEAgLTEzOTYsNiArMTM5NSw4IEBACiAKIChkZWZpbmUgbW9kdWxlLXRyYW5zZm9ybWVy IChyZWNvcmQtYWNjZXNzb3IgbW9kdWxlLXR5cGUgJ3RyYW5zZm9ybWVyKSkKIChkZWZpbmUgc2V0 LW1vZHVsZS10cmFuc2Zvcm1lciEgKHJlY29yZC1tb2RpZmllciBtb2R1bGUtdHlwZSAndHJhbnNm b3JtZXIpKQorKGRlZmluZSBtb2R1bGUtdmVyc2lvbiAocmVjb3JkLWFjY2Vzc29yIG1vZHVsZS10 eXBlICd2ZXJzaW9uKSkKKyhkZWZpbmUgc2V0LW1vZHVsZS12ZXJzaW9uISAocmVjb3JkLW1vZGlm aWVyIG1vZHVsZS10eXBlICd2ZXJzaW9uKSkKIDs7IChkZWZpbmUgbW9kdWxlLW5hbWUgKHJlY29y ZC1hY2Nlc3NvciBtb2R1bGUtdHlwZSAnbmFtZSkpIHdhaXQgdW50aWwgbW9kcyBhcmUgYm9vdGVk CiAoZGVmaW5lIHNldC1tb2R1bGUtbmFtZSEgKHJlY29yZC1tb2RpZmllciBtb2R1bGUtdHlwZSAn bmFtZSkpCiAoZGVmaW5lIG1vZHVsZS1raW5kIChyZWNvcmQtYWNjZXNzb3IgbW9kdWxlLXR5cGUg J2tpbmQpKQpAQCAtMjAwOCwyNCArMjAwOSwzMiBAQAogICAgICAgOzsgSW1wb3J0IHRoZSBkZWZh dWx0IHNldCBvZiBiaW5kaW5ncyAoZnJvbSB0aGUgU0NNIG1vZHVsZSkgaW4gTU9EVUxFLgogICAg ICAgKG1vZHVsZS11c2UhIG1vZHVsZSB0aGUtc2NtLW1vZHVsZSkpKQogCis7OyBUZW1wb3Jhcnkg a2x1ZGdlIGJlZm9yZSBpbXBsZW1lbnRpbmcgZnVsbCB2ZXJzaW9uIG1hdGNoaW5nLgorKGRlZmlu ZSB2ZXJzaW9uLW1hdGNoZXM/IGVxdWFsPykKKwogOzsgTk9URTogVGhpcyBiaW5kaW5nIGlzIHVz ZWQgaW4gbGliZ3VpbGUvbW9kdWxlcy5jLgogOzsKIChkZWZpbmUgcmVzb2x2ZS1tb2R1bGUKICAg KGxldCAoKHRoZS1yb290LW1vZHVsZSB0aGUtcm9vdC1tb2R1bGUpKQotICAgIChsYW1iZGEgKG5h bWUgLiBtYXliZS1hdXRvbG9hZCkKKyAgICAobGFtYmRhIChuYW1lIC4gYXJncykgICAgICAKICAg ICAgIChpZiAoZXF1YWw/IG5hbWUgJyhndWlsZSkpCiAgICAgICAgICAgdGhlLXJvb3QtbW9kdWxl CiAgICAgICAgICAgKGxldCAoKGZ1bGwtbmFtZSAoYXBwZW5kICcoJWFwcCBtb2R1bGVzKSBuYW1l KSkpCi0gICAgICAgICAgICAobGV0ICgoYWxyZWFkeSAobmVzdGVkLXJlZiB0aGUtcm9vdC1tb2R1 bGUgZnVsbC1uYW1lKSkKLSAgICAgICAgICAgICAgICAgIChhdXRvbG9hZCAob3IgKG51bGw/IG1h eWJlLWF1dG9sb2FkKSAoY2FyIG1heWJlLWF1dG9sb2FkKSkpKQorICAgICAgICAgICAgKGxldCog KChhbHJlYWR5IChuZXN0ZWQtcmVmIHRoZS1yb290LW1vZHVsZSBmdWxsLW5hbWUpKQorCQkgICAo bnVtYXJncyAobGVuZ3RoIGFyZ3MpKQorCQkgICAoYXV0b2xvYWQgKG9yICg9IG51bWFyZ3MgMCkg KGNhciBhcmdzKSkpCisJCSAgICh2ZXJzaW9uIChhbmQgKD4gbnVtYXJncyAxKSAoY2FkciBhcmdz KSkpKQogICAgICAgICAgICAgICAoY29uZAogICAgICAgICAgICAgICAgKChhbmQgYWxyZWFkeSAo bW9kdWxlPyBhbHJlYWR5KQogICAgICAgICAgICAgICAgICAgICAgKG9yIChub3QgYXV0b2xvYWQp IChtb2R1bGUtcHVibGljLWludGVyZmFjZSBhbHJlYWR5KSkpCiAgICAgICAgICAgICAgICAgOzsg QSBoaXQsIGEgcGFscGFibGUgaGl0LgorCQkoYW5kIHZlcnNpb24gCisJCSAgICAgKG5vdCAodmVy c2lvbi1tYXRjaGVzPyB2ZXJzaW9uIChtb2R1bGUtdmVyc2lvbiBhbHJlYWR5KSkpCisJCSAgICAg KGVycm9yICJpbmNvbXBhdGlibGUgbW9kdWxlIHZlcnNpb24gYWxyZWFkeSBsb2FkZWQiIG5hbWUp KQogICAgICAgICAgICAgICAgIGFscmVhZHkpCiAgICAgICAgICAgICAgICAoYXV0b2xvYWQKICAg ICAgICAgICAgICAgICA7OyBUcnkgdG8gYXV0b2xvYWQgdGhlIG1vZHVsZSwgYW5kIHJlY3Vyc2Uu Ci0gICAgICAgICAgICAgICAgKHRyeS1sb2FkLW1vZHVsZSBuYW1lKQorICAgICAgICAgICAgICAg ICh0cnktbG9hZC1tb2R1bGUgbmFtZSB2ZXJzaW9uKQogICAgICAgICAgICAgICAgIChyZXNvbHZl LW1vZHVsZSBuYW1lICNmKSkKICAgICAgICAgICAgICAgIChlbHNlCiAgICAgICAgICAgICAgICAg OzsgQSBtb2R1bGUgaXMgbm90IGJvdW5kIChidXQgbWF5YmUgc29tZXRoaW5nIGVsc2UgaXMpLApA QCAtMjA3MSw3ICsyMDgwLDcgQEAKIAogOzsgKGRlZmluZS1zcGVjaWFsLXZhbHVlICcoJWFwcCBt b2R1bGVzIG5ldy13cykgKGxhbWJkYSAoKSAobWFrZS1zY20tbW9kdWxlKSkpCiAKLShkZWZpbmUg KHRyeS1sb2FkLW1vZHVsZSBuYW1lKQorKGRlZmluZSAodHJ5LWxvYWQtbW9kdWxlIG5hbWUgdmVy c2lvbikKICAgKHRyeS1tb2R1bGUtYXV0b2xvYWQgbmFtZSkpCiAKIChkZWZpbmUgKHB1cmlmeS1t b2R1bGUhIG1vZHVsZSkKQEAgLTIxMzIsNyArMjE0MSw4IEBACiAJCSAgICAgIChsZXQgKChwcmVm aXggKGdldC1rZXl3b3JkLWFyZyBhcmdzICM6cHJlZml4ICNmKSkpCiAJCQkoYW5kIHByZWZpeCAo c3ltYm9sLXByZWZpeC1wcm9jIHByZWZpeCkpKQogCQkgICAgICBpZGVudGl0eSkpCi0gICAgICAg ICAobW9kdWxlIChyZXNvbHZlLW1vZHVsZSBuYW1lKSkKKwkgKHZlcnNpb24gKGdldC1rZXl3b3Jk LWFyZyBhcmdzICM6dmVyc2lvbiAjZikpCisgICAgICAgICAobW9kdWxlIChyZXNvbHZlLW1vZHVs ZSBuYW1lICN0IHZlcnNpb24pKQogICAgICAgICAgKHB1YmxpYy1pIChhbmQgbW9kdWxlIChtb2R1 bGUtcHVibGljLWludGVyZmFjZSBtb2R1bGUpKSkpCiAgICAgKGFuZCAob3IgKG5vdCBtb2R1bGUp IChub3QgcHVibGljLWkpKQogICAgICAgICAgKGVycm9yICJubyBjb2RlIGZvciBtb2R1bGUiIG5h bWUpKQpAQCAtMjI1Myw2ICsyMjYzLDEyIEBACiAgICAgICAgICAgICAgKHB1cmlmeS1tb2R1bGUh IG1vZHVsZSkKICAgICAgICAgICAgICAobG9vcCAoY2RyIGt3cykgcmV2ZXJzZWQtaW50ZXJmYWNl cyBleHBvcnRzIHJlLWV4cG9ydHMKICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudHMgYXV0 b2xvYWRzKSkKKwkgICAgKCgjOnZlcnNpb24pCisgICAgICAgICAgICAgKG9yIChwYWlyPyAoY2Ry IGt3cykpCisgICAgICAgICAgICAgICAgICh1bnJlY29nbml6ZWQga3dzKSkKKwkgICAgIChzZXQt bW9kdWxlLXZlcnNpb24hIG1vZHVsZSAoY2FkciBrd3MpKQorCSAgICAgKGxvb3AgKGNkZHIga3dz KSByZXZlcnNlZC1pbnRlcmZhY2VzIGV4cG9ydHMgcmUtZXhwb3J0cworCQkgICByZXBsYWNlbWVu dHMgYXV0b2xvYWRzKSkKICAgICAgICAgICAgICgoIzpkdXBsaWNhdGVzKQogICAgICAgICAgICAg IChpZiAobm90IChwYWlyPyAoY2RyIGt3cykpKQogICAgICAgICAgICAgICAgICAodW5yZWNvZ25p emVkIGt3cykpCkBAIC0yMzE2LDcgKzIzMzIsOCBAQAogCQkJICAoc2V0LWNhciEgYXV0b2xvYWQg aSkpKQogCQkgICAgKG1vZHVsZS1sb2NhbC12YXJpYWJsZSBpIHN5bSkpKSkpKQogICAgIChtb2R1 bGUtY29uc3RydWN0b3IgKG1ha2UtaGFzaC10YWJsZSAwKSAnKCkgYiAjZiAjZiBuYW1lICdhdXRv bG9hZCAjZgotICAgICAgICAgICAgICAgICAgICAgICAgKG1ha2UtaGFzaC10YWJsZSAwKSAnKCkg KG1ha2Utd2Vhay12YWx1ZS1oYXNoLXRhYmxlIDMxKSkpKQorICAgICAgICAgICAgICAgICAgICAg ICAgKG1ha2UtaGFzaC10YWJsZSAwKSAnKCkgKG1ha2Utd2Vhay12YWx1ZS1oYXNoLXRhYmxlIDMx KQorCQkJI2YpKSkKIAogKGRlZmluZSAobW9kdWxlLWF1dG9sb2FkISBtb2R1bGUgLiBhcmdzKQog ICAiSGF2ZSBAdmFye21vZHVsZX0gYXV0b21hdGljYWxseSBsb2FkIHRoZSBtb2R1bGUgbmFtZWQg QHZhcntuYW1lfSB3aGVuIG9uZQpAQCAtMjkyMSw3ICsyOTM4LDggQEAgbW9kdWxlICcoaWNlLTkg cSkgJyhtYWtlLXEgcS1sZW5ndGgpKX0uIgogICAgICcoKDpzZWxlY3QgIzpzZWxlY3QgI3QpCiAg ICAgICAoOmhpZGUgICAjOmhpZGUJI3QpCiAgICAgICAoOnByZWZpeCAjOnByZWZpeCAjdCkKLSAg ICAgICg6cmVuYW1lciAjOnJlbmFtZXIgI2YpKSkKKyAgICAgICg6cmVuYW1lciAjOnJlbmFtZXIg I2YpCisgICAgICAoOnZlcnNpb24gIzp2ZXJzaW9uICNmKSkpCiAgIChpZiAobm90IChwYWlyPyAo Y2FyIHNwZWMpKSkKICAgICAgIGAoJyxzcGVjKQogICAgICAgYCgnLChjYXIgc3BlYykKLS0gCjEu Ni4wLjQKCg== --0016e6d7837e5bdabc047480a744--