From mboxrd@z Thu Jan 1 00:00:00 1970 From: Matt Price Subject: Re: overlay showing computed value of macro? Date: Thu, 22 Nov 2018 17:37:48 -0500 Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000bd5d77057b4882fd" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:40360) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPxbD-0008Ca-5U for emacs-orgmode@gnu.org; Thu, 22 Nov 2018 17:37:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPxbB-0000B3-Ui for emacs-orgmode@gnu.org; Thu, 22 Nov 2018 17:37:27 -0500 Received: from mail-io1-xd2f.google.com ([2607:f8b0:4864:20::d2f]:41179) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gPxbB-00009X-OQ for emacs-orgmode@gnu.org; Thu, 22 Nov 2018 17:37:25 -0500 Received: by mail-io1-xd2f.google.com with SMTP id s22so7512492ioc.8 for ; Thu, 22 Nov 2018 14:37:25 -0800 (PST) In-Reply-To: List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: Org Mode --000000000000bd5d77057b4882fd Content-Type: text/plain; charset="UTF-8" On Thu, Nov 22, 2018 at 4:06 PM Matt Price wrote: > > > On Thu, Nov 22, 2018 at 1:19 PM Matt Price wrote: > >> It would be nice for me to overlay the macro invocations with the values >> that they will evaluate to on export. I guess I would have to figure out >> when to trigger recalculation of the values (maybe not too often, say only >> when the macro is first created, when it's edited or deleted/deformed, and >> perhaps on structure editing. >> >> I do not understand emacs overlays very well so this feels a little >> daunting to me. Does anyone out there have ideas about how to do it >> effectively? >> >> > This is what I've come up with; it feels somewhat close but not quite > there yet. I can create, remove, and the overlays, which is great. What I > miss is the awesomeness of the way that overlays work with org links. I > love how the link target and the enclosing [[ ][ ]] are invisible until I > delete one of the "[" elements. However, with my code, the whole macro > expression {{{macroname}}} ius invisible until I delete the whole thing, at > which point the overlay helpfully disappears. Is htere a way to get > something like the link behaviour? > Oops! Here is the actual code (a bit long actually! Largely stolen from org source code). #+begin_src emacs-lisp (defun mwp-show-macros () (interactive) (remove-overlays (point-min) (point-max) 'macro-ov-p t) (save-excursion (goto-char (point-min)) ;; keeping this properties/keywordsstuff b/c I don't quite understand it (let* ((keywords nil) (properties-regexp (format "\\`EXPORT_%s\\+?\\'" (regexp-opt keywords))) record) (while (re-search-forward "{{{[-A-Za-z0-9_]" nil t) (unless (save-match-data (org-in-commented-heading-p)) (let* ((datum (save-match-data (org-element-context))) (type (org-element-type datum)) (macro (cond ((eq type 'macro) datum) ;; In parsed keywords and associated node ;; properties, force macro recognition. ((or (and (eq type 'keyword) (member (org-element-property :key datum) keywords)) (and (eq type 'node-property) (string-match-p properties-regexp (org-element-property :key datum)))) (save-excursion (goto-char (match-beginning 0)) (org-element-macro-parser)))))) (when macro (let* ((key (org-element-property :key macro)) (value (org-macro-expand macro org-macro-templates)) (begin (org-element-property :begin macro)) (end (save-excursion (goto-char (org-element-property :end macro)) (skip-chars-backward " \t") (point))) (signature (list begin macro (org-element-property :args macro)))) ;; Avoid circular dependencies by checking if the same ;; macro with the same arguments is expanded at the ;; same position twice. (cond ((member signature record) (error "Circular macro expansion: %s" key)) (value (push signature record) (let ((ov (make-overlay begin end))) (overlay-put ov 'invisible t) (overlay-put ov 'evaporate t) (overlay-put ov 'macro-ov-p t) (overlay-put ov 'before-string value ))) ;; Special "results" macro: if it is not defined, ;; simply leave it as-is. It will be expanded in ;; a second phase. ((equal key "results")) (t ;; (error "Undefined Org macro: %s; aborting" ;; (org-element-property :key macro)) ))))))))) (org-macro--counter-initialize) (setq-local mwp-macro-overlays t) ) (defun mwp-hide-macros () (interactive) (remove-overlays (point-min) (point-max) 'macro-ov-p t) (setq-local mwp-macro-overlays nil) ;; (cl-loop for o in (overlays-in (point-min) (point-max)) ;; if (overlay-get o 'macro-ov-p) ;; ()) ) (defun mwp-toggle-macros () (interactive) (if mwp-macro-overlays (mwp-hide-macros) (mwp-show-macros)) ) (defvar-local mwp-macro-overlays nil) #+end_src --000000000000bd5d77057b4882fd Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+PGRpdiBkaXI9Imx0ciI+PGJyPjxicj48ZGl2IGNsYXNzPSJnbWFpbF9x dW90ZSI+PGRpdiBkaXI9Imx0ciI+T24gVGh1LCBOb3YgMjIsIDIwMTggYXQgNDowNiBQTSBNYXR0 IFByaWNlICZsdDs8YSBocmVmPSJtYWlsdG86bW9wdG9wOTlAZ21haWwuY29tIj5tb3B0b3A5OUBn bWFpbC5jb208L2E+Jmd0OyB3cm90ZTo8YnI+PC9kaXY+PGJsb2NrcXVvdGUgY2xhc3M9ImdtYWls X3F1b3RlIiBzdHlsZT0ibWFyZ2luOjBweCAwcHggMHB4IDAuOGV4O2JvcmRlci1sZWZ0OjFweCBz b2xpZCByZ2IoMjA0LDIwNCwyMDQpO3BhZGRpbmctbGVmdDoxZXgiPjxkaXYgZGlyPSJsdHIiPjxi cj48YnI+PGRpdiBjbGFzcz0iZ21haWxfcXVvdGUiPjxkaXYgZGlyPSJsdHIiPk9uIFRodSwgTm92 IDIyLCAyMDE4IGF0IDE6MTkgUE0gTWF0dCBQcmljZSAmbHQ7PGEgaHJlZj0ibWFpbHRvOm1vcHRv cDk5QGdtYWlsLmNvbSIgdGFyZ2V0PSJfYmxhbmsiPm1vcHRvcDk5QGdtYWlsLmNvbTwvYT4mZ3Q7 IHdyb3RlOjxicj48L2Rpdj48YmxvY2txdW90ZSBjbGFzcz0iZ21haWxfcXVvdGUiIHN0eWxlPSJt YXJnaW46MHB4IDBweCAwcHggMC44ZXg7Ym9yZGVyLWxlZnQ6MXB4IHNvbGlkIHJnYigyMDQsMjA0 LDIwNCk7cGFkZGluZy1sZWZ0OjFleCI+PGRpdiBkaXI9Imx0ciI+PGRpdiBkaXI9Imx0ciI+PGRp diBkaXI9Imx0ciI+PGRpdiBkaXI9Imx0ciI+PGRpdiBkaXI9Imx0ciI+SXQgd291bGQgYmUgbmlj ZSBmb3IgbWUgdG8gb3ZlcmxheSB0aGUgbWFjcm8gaW52b2NhdGlvbnMgd2l0aCB0aGUgdmFsdWVz IHRoYXQgdGhleSB3aWxsIGV2YWx1YXRlIHRvIG9uIGV4cG9ydC4gSSBndWVzcyBJIHdvdWxkIGhh dmUgdG8gZmlndXJlIG91dCB3aGVuIHRvIHRyaWdnZXIgcmVjYWxjdWxhdGlvbiBvZiB0aGUgdmFs dWVzIChtYXliZSBub3QgdG9vIG9mdGVuLCBzYXkgb25seSB3aGVuIHRoZSBtYWNybyBpcyBmaXJz dCBjcmVhdGVkLCB3aGVuIGl0JiMzOTtzIGVkaXRlZCBvciBkZWxldGVkL2RlZm9ybWVkLCBhbmQg cGVyaGFwcyBvbiBzdHJ1Y3R1cmUgZWRpdGluZy7CoMKgIDxicj48ZGl2Pjxicj48L2Rpdj48ZGl2 PkkgZG8gbm90IHVuZGVyc3RhbmQgZW1hY3Mgb3ZlcmxheXMgdmVyeSB3ZWxsIHNvIHRoaXMgZmVl bHMgYSBsaXR0bGUgZGF1bnRpbmcgdG8gbWUuwqAgRG9lcyBhbnlvbmUgb3V0IHRoZXJlIGhhdmUg aWRlYXMgYWJvdXQgaG93IHRvIGRvIGl0IGVmZmVjdGl2ZWx5PzwvZGl2PjxkaXY+PGJyPjwvZGl2 PjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjwvYmxvY2txdW90ZT48ZGl2Pjxicj48L2Rp dj48ZGl2PlRoaXMgaXMgd2hhdCBJJiMzOTt2ZSBjb21lIHVwIHdpdGg7IGl0IGZlZWxzIHNvbWV3 aGF0IGNsb3NlIGJ1dCBub3QgcXVpdGUgdGhlcmUgeWV0LiBJIGNhbiBjcmVhdGUsIHJlbW92ZSwg YW5kIHRoZSBvdmVybGF5cywgd2hpY2ggaXMgZ3JlYXQuwqAgV2hhdCBJIG1pc3MgaXMgdGhlIGF3 ZXNvbWVuZXNzIG9mIHRoZSB3YXkgdGhhdCBvdmVybGF5cyB3b3JrIHdpdGggb3JnIGxpbmtzLiBJ IGxvdmUgaG93IHRoZSBsaW5rIHRhcmdldCBhbmQgdGhlIGVuY2xvc2luZyBbW8KgIF1bwqAgXV0g YXJlIGludmlzaWJsZSB1bnRpbCBJIGRlbGV0ZSBvbmUgb2YgdGhlICZxdW90O1smcXVvdDsgZWxl bWVudHMuwqAgSG93ZXZlciwgd2l0aCBteSBjb2RlLCB0aGUgd2hvbGUgbWFjcm8gZXhwcmVzc2lv biB7e3ttYWNyb25hbWV9fX0gaXVzIGludmlzaWJsZSB1bnRpbCBJIGRlbGV0ZSB0aGUgd2hvbGUg dGhpbmcsIGF0IHdoaWNoIHBvaW50IHRoZSBvdmVybGF5IGhlbHBmdWxseSBkaXNhcHBlYXJzLsKg IElzIGh0ZXJlIGEgd2F5IHRvIGdldCBzb21ldGhpbmcgbGlrZSB0aGUgbGluayBiZWhhdmlvdXI/ IMKgPGJyPjwvZGl2PjxkaXY+PC9kaXY+PC9kaXY+PC9kaXY+PC9ibG9ja3F1b3RlPjxkaXY+PGJy PjwvZGl2PjxkaXY+T29wcyEgSGVyZSBpcyB0aGUgYWN0dWFsIGNvZGUgKGEgYml0IGxvbmcgYWN0 dWFsbHkhwqAgTGFyZ2VseSBzdG9sZW4gZnJvbSBvcmcgc291cmNlIGNvZGUpLiA8YnI+PC9kaXY+ PGRpdj48YnI+PC9kaXY+PGRpdj48YnI+IytiZWdpbl9zcmMgZW1hY3MtbGlzcDxicj48YnI+KGRl ZnVuIG13cC1zaG93LW1hY3JvcyAoKTxicj7CoCAoaW50ZXJhY3RpdmUpPGJyPsKgIChyZW1vdmUt b3ZlcmxheXMgKHBvaW50LW1pbikgKHBvaW50LW1heCkgJiMzOTttYWNyby1vdi1wIHQpPGJyPsKg IChzYXZlLWV4Y3Vyc2lvbjxicj7CoMKgwqAgKGdvdG8tY2hhciAocG9pbnQtbWluKSk8YnI+wqDC oMKgIDs7IGtlZXBpbmcgdGhpcyBwcm9wZXJ0aWVzL2tleXdvcmRzc3R1ZmYgYi9jIEkgZG9uJiMz OTt0IHF1aXRlIHVuZGVyc3RhbmQgaXQ8YnI+wqDCoMKgIChsZXQqICgoa2V5d29yZHMgbmlsKTxi cj7CoMKgwqDCoMKgwqDCoMKgwqDCoCAocHJvcGVydGllcy1yZWdleHAgKGZvcm1hdCAmcXVvdDtc XGBFWFBPUlRfJXNcXCs/XFwmIzM5OyZxdW90Ozxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKg wqAgwqDCoMKgwqDCoCAocmVnZXhwLW9wdCBrZXl3b3JkcykpKTxicj7CoMKgwqAgwqDCoCByZWNv cmQpPGJyPsKgwqDCoMKgwqAgKHdoaWxlIChyZS1zZWFyY2gtZm9yd2FyZCAmcXVvdDt7e3tbLUEt WmEtejAtOV9dJnF1b3Q7IG5pbCB0KTxicj7CoMKgwqDCoMKgwqDCoCAodW5sZXNzIChzYXZlLW1h dGNoLWRhdGEgKG9yZy1pbi1jb21tZW50ZWQtaGVhZGluZy1wKSk8YnI+wqDCoMKgwqDCoMKgwqDC oMKgIChsZXQqICgoZGF0dW0gKHNhdmUtbWF0Y2gtZGF0YSAob3JnLWVsZW1lbnQtY29udGV4dCkp KTxicj7CoMKgwqAgwqDCoMKgwqDCoMKgwqDCoCAodHlwZSAob3JnLWVsZW1lbnQtdHlwZSBkYXR1 bSkpPGJyPsKgwqDCoCDCoMKgwqDCoMKgwqDCoMKgIChtYWNybzxicj7CoMKgwqAgwqDCoMKgwqDC oMKgwqDCoMKgIChjb25kPGJyPsKgwqDCoCDCoMKgwqAgwqDCoCAoKGVxIHR5cGUgJiMzOTttYWNy bykgZGF0dW0pPGJyPsKgwqDCoCDCoMKgwqAgwqDCoCA7OyBJbiBwYXJzZWQga2V5d29yZHMgYW5k IGFzc29jaWF0ZWQgbm9kZTxicj7CoMKgwqAgwqDCoMKgIMKgwqAgOzsgcHJvcGVydGllcywgZm9y Y2UgbWFjcm8gcmVjb2duaXRpb24uPGJyPsKgwqDCoCDCoMKgwqAgwqDCoCAoKG9yIChhbmQgKGVx IHR5cGUgJiMzOTtrZXl3b3JkKTxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqDCoCAobWVt YmVyIChvcmctZWxlbWVudC1wcm9wZXJ0eSA6a2V5IGRhdHVtKSBrZXl3b3JkcykpPGJyPsKgwqDC oCDCoMKgwqAgwqDCoMKgwqDCoMKgwqAgKGFuZCAoZXEgdHlwZSAmIzM5O25vZGUtcHJvcGVydHkp PGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoMKgIChzdHJpbmctbWF0Y2gtcCBwcm9wZXJ0 aWVzLXJlZ2V4cDxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoMKg IChvcmctZWxlbWVudC1wcm9wZXJ0eSA6a2V5IGRhdHVtKSkpKTxicj7CoMKgwqAgwqDCoMKgIMKg wqDCoCAoc2F2ZS1leGN1cnNpb248YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqDCoMKgIChnb3RvLWNo YXIgKG1hdGNoLWJlZ2lubmluZyAwKSk8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqDCoMKgIChvcmct ZWxlbWVudC1tYWNyby1wYXJzZXIpKSkpKSk8YnI+wqDCoMKgIMKgwqDCoCAod2hlbiBtYWNybzxi cj7CoMKgwqAgwqDCoMKgwqDCoCAobGV0KiAoKGtleSAob3JnLWVsZW1lbnQtcHJvcGVydHkgOmtl eSBtYWNybykpPGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgwqAgKHZhbHVlIChvcmctbWFjcm8tZXhw YW5kIG1hY3JvIG9yZy1tYWNyby10ZW1wbGF0ZXMpKTxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoMKg IChiZWdpbiAob3JnLWVsZW1lbnQtcHJvcGVydHkgOmJlZ2luIG1hY3JvKSk8YnI+wqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoZW5kIChzYXZlLWV4Y3Vyc2lvbjxicj7C oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGdv dG8tY2hhciAob3JnLWVsZW1lbnQtcHJvcGVydHkgOmVuZCBtYWNybykpPGJyPsKgwqDCoCDCoMKg wqAgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoc2tpcC1jaGFycy1iYWNrd2FyZCAmcXVvdDsgXHQm cXVvdDspPGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAocG9pbnQpKSk8 YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqDCoCAoc2lnbmF0dXJlIChsaXN0IGJlZ2luPGJyPsKgwqDC oCDCoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqDCoMKgIG1hY3JvPGJyPsKgwqDCoCDCoMKgwqAg wqDCoMKgIMKgwqDCoCDCoMKgwqDCoMKgIChvcmctZWxlbWVudC1wcm9wZXJ0eSA6YXJncyBtYWNy bykpKSk8YnI+wqDCoMKgIMKgwqDCoMKgwqDCoMKgIDs7IEF2b2lkIGNpcmN1bGFyIGRlcGVuZGVu Y2llcyBieSBjaGVja2luZyBpZiB0aGUgc2FtZTxicj7CoMKgwqAgwqDCoMKgwqDCoMKgwqAgOzsg bWFjcm8gd2l0aCB0aGUgc2FtZSBhcmd1bWVudHMgaXMgZXhwYW5kZWQgYXQgdGhlPGJyPsKgwqDC oCDCoMKgwqDCoMKgwqDCoCA7OyBzYW1lIHBvc2l0aW9uIHR3aWNlLjxicj7CoMKgwqAgwqDCoMKg wqDCoMKgwqAgKGNvbmQgKChtZW1iZXIgc2lnbmF0dXJlIHJlY29yZCk8YnI+wqDCoMKgIMKgwqDC oCDCoMKgwqDCoMKgwqAgKGVycm9yICZxdW90O0NpcmN1bGFyIG1hY3JvIGV4cGFuc2lvbjogJXMm cXVvdDsga2V5KSk8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqDCoMKgICh2YWx1ZTxicj7CoMKgwqAg wqDCoMKgIMKgwqDCoMKgwqDCoCAocHVzaCBzaWduYXR1cmUgcmVjb3JkKTxicj7CoMKgwqAgwqDC oMKgIMKgwqDCoMKgwqDCoCAobGV0ICgob3YgKG1ha2Utb3ZlcmxheSBiZWdpbiBlbmQpKSk8YnI+ wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChvdmVybGF5 LXB1dCBvdiAmIzM5O2ludmlzaWJsZSB0KTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgKG92ZXJsYXktcHV0IG92ICYjMzk7ZXZhcG9yYXRlIHQpPGJy PsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAob3Zlcmxh eS1wdXQgb3YgJiMzOTttYWNyby1vdi1wIHQpPGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgwqDCoMKg wqDCoCAob3ZlcmxheS1wdXQgb3YgJiMzOTtiZWZvcmUtc3RyaW5nIHZhbHVlICkpKTxicj7CoMKg wqAgwqDCoMKgIMKgwqDCoMKgwqAgOzsgU3BlY2lhbCAmcXVvdDtyZXN1bHRzJnF1b3Q7IG1hY3Jv OiBpZiBpdCBpcyBub3QgZGVmaW5lZCw8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqDCoMKgIDs7IHNp bXBseSBsZWF2ZSBpdCBhcy1pcy7CoCBJdCB3aWxsIGJlIGV4cGFuZGVkIGluPGJyPsKgwqDCoCDC oMKgwqAgwqDCoMKgwqDCoCA7OyBhIHNlY29uZCBwaGFzZS48YnI+wqDCoMKgIMKgwqDCoCDCoMKg wqDCoMKgICgoZXF1YWwga2V5ICZxdW90O3Jlc3VsdHMmcXVvdDspKTxicj7CoMKgwqAgwqDCoMKg IMKgwqDCoMKgwqAgKHQ8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqDCoMKgwqAgOzsgKGVycm9yICZx dW90O1VuZGVmaW5lZCBPcmcgbWFjcm86ICVzOyBhYm9ydGluZyZxdW90Ozxicj7CoMKgwqAgwqDC oMKgIMKgwqDCoMKgwqDCoCA7O8KgwqDCoMKgwqDCoMKgIChvcmctZWxlbWVudC1wcm9wZXJ0eSA6 a2V5IG1hY3JvKSk8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgKSkpKSkpKSkpPGJyPsKgIChvcmctbWFjcm8tLWNvdW50ZXItaW5pdGlhbGl6ZSk8YnI+wqAg KHNldHEtbG9jYWwgbXdwLW1hY3JvLW92ZXJsYXlzIHQpPGJyPsKgICk8YnI+PGJyPjxicj4oZGVm dW4gbXdwLWhpZGUtbWFjcm9zICgpPGJyPsKgIChpbnRlcmFjdGl2ZSk8YnI+KHJlbW92ZS1vdmVy bGF5cyAocG9pbnQtbWluKSAocG9pbnQtbWF4KSAmIzM5O21hY3JvLW92LXAgdCk8YnI+KHNldHEt bG9jYWwgbXdwLW1hY3JvLW92ZXJsYXlzIG5pbCk8YnI+OzsgKGNsLWxvb3AgZm9yIG8gaW4gKG92 ZXJsYXlzLWluIChwb2ludC1taW4pIChwb2ludC1tYXgpKTxicj47O8KgwqDCoMKgwqDCoMKgwqDC oCBpZiAob3ZlcmxheS1nZXQgbyAmIzM5O21hY3JvLW92LXApPGJyPjs7wqDCoMKgwqDCoMKgwqDC oMKgICgpKTxicj4pPGJyPjxicj4oZGVmdW4gbXdwLXRvZ2dsZS1tYWNyb3MgKCk8YnI+wqAgKGlu dGVyYWN0aXZlKTxicj7CoCAoaWYgbXdwLW1hY3JvLW92ZXJsYXlzPGJyPsKgwqDCoMKgwqAgKG13 cC1oaWRlLW1hY3Jvcyk8YnI+wqDCoMKgIChtd3Atc2hvdy1tYWNyb3MpKSApPGJyPjxicj4oZGVm dmFyLWxvY2FsIG13cC1tYWNyby1vdmVybGF5cyBuaWwpPGJyPiMrZW5kX3NyYzxicj48YnI+PC9k aXY+PC9kaXY+PC9kaXY+PC9kaXY+DQo= --000000000000bd5d77057b4882fd--