From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp0 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id B1JfFMW3bV9sbQAA0tVLHw (envelope-from ) for ; Fri, 25 Sep 2020 09:26:29 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp0 with LMTPS id CKS8D8W3bV/JAQAA1q6Kng (envelope-from ) for ; Fri, 25 Sep 2020 09:26:29 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 492B39404D5 for ; Fri, 25 Sep 2020 09:26:28 +0000 (UTC) Received: from localhost ([::1]:54394 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kLjzm-00047K-Pj for larch@yhetil.org; Fri, 25 Sep 2020 05:26:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59684) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kLjzA-000471-Nh for emacs-orgmode@gnu.org; Fri, 25 Sep 2020 05:25:48 -0400 Received: from mail-ed1-x52e.google.com ([2a00:1450:4864:20::52e]:36256) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kLjz8-0001An-Dc for emacs-orgmode@gnu.org; Fri, 25 Sep 2020 05:25:48 -0400 Received: by mail-ed1-x52e.google.com with SMTP id w1so1800941edr.3 for ; Fri, 25 Sep 2020 02:25:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=l+voU1Zd6XgMQsf3+FOUCY64D9+ukhlkWbFAOLBLHfQ=; b=qTxsnZtw8Ojtv0bBhbZlYe0+n8JFtsy09t/dEKSQFts+8D01TBISEYEKGudBdIyo/O T20aeaipooODkWj9A2Dj9LMJw2GQdGds+0T8MWHt3DKVPRuIPn2oDRLbHM865dJtGhRW SCxk8NbRDBLaRLXpNfWbBr3Aiv97IY+L2ssqF6R+EjwFdYKv9GpQb/dOlw23mzAx4Fox U/Wn7UGyXeZClHtGcGXCPg/lk9Q2rJ7BW/2cs9RkoN/ebdacbKJ1nqqOaj51P1UerrD9 HblCeyOCZGiOMFB1QcpkxXT+MYb0D9nlcLHuz5AVS27WqNi8eRABGgDc9Tn0joWaFNoq o9eA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=l+voU1Zd6XgMQsf3+FOUCY64D9+ukhlkWbFAOLBLHfQ=; b=MgjMDM+bFMKsWRr7Dqgv12hMUezoKsUqZ6S84Qz8iXBPHOQODpfrU7O57wDI0t8GC0 +k658r0ef80ihvp7zTAFhSBwdg2mv/WXzkVkGkWsC9OpQcU28GhcKd+tadh+TmES9jjP q483FoFBnxpWbsx4oqunhsFUGwRZW/bgE7UhMutf9I0i/sUiXWEfsWGxfyZl72wwtLy6 5aZExG2V8bvLVAMYyJ6MR//rLCUSsxKNvz/4cN3TCZHoCKe3y45xNdGvfaMi25RQyeYH dSBCRa4xYl9GkqzYbu06JkAA4USqi0V3uSBZdGJZV69TX1wPAzu2v3TvVOcme1umn8/+ 7Qqw== X-Gm-Message-State: AOAM5320NaBwB+4LHwstLDSJZwvQ9EwthHu6wohsuAn3i0z5YmYQKjuq UTbfpuCIfuZG5k29COprimlGFFYxzL7xyWbqN3s= X-Google-Smtp-Source: ABdhPJzUINXCxL9vTwvpx0cVClrVgb8iNUm+rEnB2/sdj0JXKC55/DJD42YBEoauVIbNAA6tHHiWIA1A/YEVBS4bOAY= X-Received: by 2002:aa7:dcd9:: with SMTP id w25mr277761edu.280.1601025942998; Fri, 25 Sep 2020 02:25:42 -0700 (PDT) MIME-Version: 1.0 References: <3444a52f-36a7-6e9d-46b9-272dddc7a3ef@grinta.net> In-Reply-To: <3444a52f-36a7-6e9d-46b9-272dddc7a3ef@grinta.net> From: Neil Jerram Date: Fri, 25 Sep 2020 10:25:31 +0100 Message-ID: Subject: Re: org-tables with monetary amounts To: Daniele Nicolodi Content-Type: multipart/mixed; boundary="0000000000009c37dc05b01fe628" Received-SPF: pass client-ip=2a00:1450:4864:20::52e; envelope-from=neiljerram@gmail.com; helo=mail-ed1-x52e.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Org Mode List Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: "Emacs-orgmode" X-Scanner: scn0 Authentication-Results: aspmx1.migadu.com; dkim=fail (body hash did not verify) header.d=gmail.com header.s=20161025 header.b=qTxsnZtw; dmarc=fail reason="SPF not aligned (relaxed)" header.from=gmail.com (policy=none); spf=pass (aspmx1.migadu.com: domain of emacs-orgmode-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=emacs-orgmode-bounces@gnu.org X-Spam-Score: 1.19 X-TUID: TFDyPy0fU849 --0000000000009c37dc05b01fe628 Content-Type: multipart/alternative; boundary="0000000000009c37da05b01fe626" --0000000000009c37da05b01fe626 Content-Type: text/plain; charset="UTF-8" On Tue, 22 Sep 2020 at 17:05, Daniele Nicolodi wrote: > Hello, > Hi Daniele... > > I often use org-tables to work with monetary amounts. Me too. I use Org mode plus Scheme code to try to analyze my bank statements and compare them against a budget. Org is a convenient form for specifying the inputs - e.g. the names of OFX files to read, and string matches for how I want to categorize the transactions - and for displaying the results. Aside: Perhaps I'm misunderstanding them, but none of the open source tools, including (h)ledger, seem to be of much help here. - They focus on data entry and reconciliation, which I don't need as I'm happy to download and use OFX files from my bank. - They don't offer anything intelligent and automated for automatically categorizing transactions. - They don't have a sophisticated representation of a budget, and reporting against that. Do you know of a good forum (other than this!) for discussing such points? > It would be very > nice to have a couple of functionalities common in this domain: > > - fixed precision arithmetic, namely derive the precision of the results > from the precision of the arguments (I think that calc can do this), > In my Scheme code, I convert between strings and pence: ;; In this file, an amount at rest is always represented as a string ;; with 2 decimal places. Convert from that to an integer number of ;; pence: (define (amount->pence amount) (inexact->exact (round (* 100 (string->number amount))))) ;; And the reverse: (define (pence->amount pence) (format-2dp (/ (exact->inexact pence) 100))) > > - support for parsing numbers followed by currencies, > > - correct alignment for monetary values. > > I had a quick look around, but I haven't found anything that implements > those things. Has anyone some secret code that they would like to share? > I've attached mine, in case you read Scheme and there's more detail in there that is of interest. Best wishes, Neil --0000000000009c37da05b01fe626 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Tue, 22 Sep 2020 at 17:05, Daniele Nic= olodi <daniele@grinta.net> = wrote:
Hello,

Hi Daniele...<= /div>
=C2=A0

I often use org-tables to work with monetary amounts.

=
Me too.=C2=A0 I use Org mode plus Scheme code to try to analyze = my bank statements and compare them against a budget.=C2=A0 Org is a conven= ient form for specifying the inputs - e.g. the names of OFX files to read, = and string matches for how I want to categorize the transactions - and for = displaying the results.

Aside: Perhaps I'm mis= understanding them, but none of the open source tools, including (h)ledger,= seem to be of much help here.
- They focus on data entry and rec= onciliation, which I don't need as I'm happy to download and use OF= X files from my bank.
- They don't offer anything intelligent= and automated for automatically categorizing transactions.
- The= y don't have a sophisticated representation of a budget, and reporting = against that.
Do you know of a good forum (other than this!) for = discussing such points?
=C2=A0
It would be very
nice to have a couple of functionalities common in this domain:

- fixed precision arithmetic, namely derive the precision of the results from the precision of the arguments (I think that calc can do this),

In my Scheme code, I convert between strings = and pence:

=C2=A0 =C2=A0 ;; In this file, an amoun= t at rest is always represented as a string
=C2=A0 =C2=A0 ;; with 2 deci= mal places.=C2=A0 Convert from that to an integer number of
=C2=A0 =C2= =A0 ;; pence:

=C2=A0 =C2=A0 (define (amount->pence amount)
=C2= =A0 =C2=A0 =C2=A0 (inexact->exact (round (* 100 (string->number amoun= t)))))

=C2=A0 =C2=A0 ;; And the reverse:

=C2=A0 =C2=A0 (defin= e (pence->amount pence)
=C2=A0 =C2=A0 =C2=A0 (format-2dp (/ (exact-&g= t;inexact pence) 100)))
=C2=A0

- support for parsing numbers followed by currencies,

- correct alignment for monetary values.

I had a quick look around, but I haven't found anything that implements=
those things. Has anyone some secret code that they would like to share?

I've attached mine, in case you read = Scheme and there's more detail in there that is of interest.
=
Best wishes,
=C2=A0 =C2=A0 Neil


--0000000000009c37da05b01fe626-- --0000000000009c37dc05b01fe628 Content-Type: text/x-scheme; charset="US-ASCII"; name="nationwide.scm" Content-Disposition: attachment; filename="nationwide.scm" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_kfi1f00a0 CihhZGQtdG8tbG9hZC1wYXRoIChpbi12aWNpbml0eSAoZ2V0ZW52ICJIT01FIikgIm9zc2F1bGli IikpCgoodXNlLW1vZHVsZXMgKGljZS05IGZvcm1hdCkKCSAgICAgKGljZS05IHJlZ2V4KQoJICAg ICAob3NzYXUgb2Z4KQoJICAgICAoc3JmaSBzcmZpLTEpCgkgICAgIChzeG1sIHNpbXBsZSkKCSAg ICAgKHN4bWwgbWF0Y2gpCgkgICAgIChzcmZpIHNyZmktMTkpKQoKOzsgKG9zc2F1IG9meCkgcHJv dmlkZXMgJ2dldC10cmFuc2FjdGlvbnMnIHRvIHJlYWQgdHJhbnNhY3Rpb25zIGZyb20gYQo7OyBz aW5nbGUgT0ZYIGZpbGUuICBMZXQncyBidWlsZCBvbiB0aGF0IHRvIHJlYWQgdHJhbnNhY3Rpb25z IGZyb20KOzsgbXVsdGlwbGUgT0ZYIGZpbGVzLCBhc3N1bWluZyB0aGF0IHRoZSBmaWxlcyBnaXZl biBhcmUgYWxyZWFkeQo7OyBvcmRlcmVkIGJ5IGRhdGUsIHNvIHRoYXQgdGhlIHRyYW5zYWN0aW9u cyBpbiB0aGVtIGZvbGxvdyBvbiBmcm9tCjs7IGVhY2ggb3RoZXIuCgooZGVmaW5lIChyZWFkLXRy YW5zYWN0aW9ucyAuIGZpbGVzKQogIChhcHBseSBhcHBlbmQgKG1hcCBnZXQtdHJhbnNhY3Rpb25z IGZpbGVzKSkpCgo7OyBSZXR1cm4gYSBkYXRlIHRoYXQgaXMgMDA6MDAgVVRDIG9uIHRoZSBkYXkg b2YgdGhlIGdpdmVuIHRyYW5zYWN0aW9uLgoKKGRlZmluZSAodHgtZGF0ZSB0eCkKICAobGV0ICgo ZCAoc3RyaW5nLT5kYXRlICh0eDpkYXRlIHR4KSAifll+bX5kIikpKQogICAgKG1ha2UtZGF0ZSAw IDAgMCAwCQkJOyBuc2VjIHNlYyBtaW4gaHIKCSAgICAgICAoZGF0ZS1kYXkgZCkKCSAgICAgICAo ZGF0ZS1tb250aCBkKQoJICAgICAgIChkYXRlLXllYXIgZCkKCSAgICAgICAwCQkJOyB6b25lIG9m ZnNldCwgaS5lLiBVVEMKCSAgICAgICApKSkKCjs7IEdpdmVuIGEgZGF0ZSwgcmV0dXJuIGEgZGF0 ZSB0aGF0IGlzIHRoZSBzdGFydCBvZiB0aGUgbmV4dCBtb250aC4KCihkZWZpbmUgKHN0YXJ0LW9m LWZvbGxvd2luZy1tb250aCBkKQogIChpZiAoPSAoZGF0ZS1tb250aCBkKSAxMikKICAgICAgKG1h a2UtZGF0ZSAwIDAgMCAwCQk7IG5zZWMgc2VjIG1pbiBocgoJCSAxCQkJOyBkYXkgb2YgbW9udGgK CQkgMQkJCTsgbW9udGggb2YgeWVhcgoJCSAoKyAoZGF0ZS15ZWFyIGQpIDEpCgkJIDAJCQk7IHpv bmUgb2Zmc2V0LCBpLmUuIFVUQwoJCSApCiAgICAgIChtYWtlLWRhdGUgMCAwIDAgMAkJOyBuc2Vj IHNlYyBtaW4gaHIKCQkgMQkJCTsgZGF5IG9mIG1vbnRoCgkJICgrIChkYXRlLW1vbnRoIGQpIDEp CgkJIChkYXRlLXllYXIgZCkKCQkgMAkJCTsgem9uZSBvZmZzZXQsIGkuZS4gVVRDCgkJICkpKQoK OzsgR2l2ZW4gYSBkYXRlLCByZXR1cm4gYSBkYXRlIHRoYXQgaXMgZXhhY3RseSBOIGRheXMgbGF0 ZXIuCgooZGVmaW5lIChuLWRheXMtbGF0ZXIgZCBuKQogIChqdWxpYW4tZGF5LT5kYXRlICgrIChk YXRlLT5qdWxpYW4tZGF5IGQpIG4pKSkKCjs7IENvbXBhcmUgdHdvIGRhdGVzLgoKKGRlZmluZSAo ZGF0ZS1iZWZvcmU/IGQxIGQyKQogICg8IChkYXRlLT5qdWxpYW4tZGF5IGQxKSAoZGF0ZS0+anVs aWFuLWRheSBkMikpKQoKOzsgR2l2ZW4gYSBzZXJpZXMgb2YgdHJhbnNhY3Rpb25zLCBwYXJ0aXRp b24gdGhlbSBpbnRvIGFuIGFsaXN0IG9mCjs7IHNtYWxsZXIgc2VyaWVzIGFjY29yZGluZyB0byB0 aW1lIHBlcmlvZHMgY2FsY3VsYXRlZCBmcm9tIFNUQVJULURBVEUKOzsgYW5kIE5FWFQtU1RBUlQt REFURS1QUk9DOiB0aGUgc3RhcnQgb2YgdGhlIGZpcnN0IHBlcmlvZCBpcwo7OyBTVEFSVC1EQVRF LCB0aGUgc3RhcnQgb2YgdGhlIHNlY29uZCBwZXJpb2QgaXMgKE5FWFQtU1RBUlQtREFURS1QUk9D Cjs7IFNUQVJULURBVEUpLCB0aGUgc3RhcnQgb2YgdGhlIHRoaXJkIHBlcmlvZCBpcyAoTkVYVC1T VEFSVC1EQVRFLVBST0MKOzsgKE5FWFQtU1RBUlQtREFURS1QUk9DIFNUQVJULURBVEUpKSwgYW5k IHNvIG9uLiAgSW4gdGhlIHJldHVybmVkCjs7IGFsaXN0LCBlYWNoIGVudHJ5IGlzIChEQVRFIC4g VFgtTElTVCksIHdoZXJlIERBVEUgaXMgdGhlIGV4Y2x1c2l2ZQo7OyBwZXJpb2QgZW5kIGRhdGUg KD09IHRoZSBzdGFydCBkYXRlIG9mIHRoZSBmb2xsb3dpbmcgcGVyaW9kKSBmb3IgdGhlCjs7IHRy YW5zYWN0aW9ucyBpbiBUWC1MSVNULgoKKGRlZmluZSAocGFydGl0aW9uLWJ5LXBlcmlvZCB0eHMg c3RhcnQtZGF0ZSBuZXh0LXN0YXJ0LWRhdGUtcHJvYykKICAobGV0IGxvb3AgKCh0eHMgdHhzKQoJ ICAgICAocGFydGl0aW9uLWVuZC1kYXRlLWV4Y2x1c2l2ZSAobmV4dC1zdGFydC1kYXRlLXByb2Mg c3RhcnQtZGF0ZSkpCgkgICAgIChwcmV2aW91cy1wYXJ0aXRpb25zICcoKSkKCSAgICAgKGN1cnJl bnQtcGFydGl0aW9uICcoKSkpCiAgICAoaWYgKG51bGw/IHR4cykKCShyZXZlcnNlIChhY29ucyBw YXJ0aXRpb24tZW5kLWRhdGUtZXhjbHVzaXZlIGN1cnJlbnQtcGFydGl0aW9uIHByZXZpb3VzLXBh cnRpdGlvbnMpKQoJKGxldCogKCh0eCAoY2FyIHR4cykpKQoJICAoaWYgKGRhdGUtYmVmb3JlPyAo dHgtZGF0ZSB0eCkgcGFydGl0aW9uLWVuZC1kYXRlLWV4Y2x1c2l2ZSkKCSAgICAgIDs7IFRoaXMg dHJhbnNhY3Rpb24gaXMgd2l0aGluIHRoZSBjdXJyZW50IHBhcnRpdGlvbi4KCSAgICAgIChsb29w IChjZHIgdHhzKQoJCSAgICBwYXJ0aXRpb24tZW5kLWRhdGUtZXhjbHVzaXZlCgkJICAgIHByZXZp b3VzLXBhcnRpdGlvbnMKCQkgICAgKGNvbnMgdHggY3VycmVudC1wYXJ0aXRpb24pKQoJICAgICAg OzsgVGhpcyB0cmFuc2FjdGlvbiBpcyBhZnRlciB0aGUgY3VycmVudCBwYXJ0aXRpb24uICBCdXQK CSAgICAgIDs7IGJlYXIgaW4gbWluZCB0aGF0IGl0IG1pZ2h0IG5vdCBiZSBpbiB0aGUgaW1tZWRp YXRlCgkgICAgICA7OyBuZXh0IHBhcnRpdGlvbiBlaXRoZXIuICBUaGUgc2FmZXN0IHRoaW5nIHRv IGRvIGlzIHRvCgkgICAgICA7OyBjbG9zZSBvdXQgdGhlIGN1cnJlbnQgcGFydGl0aW9uLCBhZHZh bmNlIHRoZSBsaW1pdAoJICAgICAgOzsgZGF0ZSwgdGhlbiBsb29wIHJvdW5kIHRvIGxvb2sgYXQg dGhlIHRyYW5zYWN0aW9uIGluCgkgICAgICA7OyBoYW5kIGFnYWluLgoJICAgICAgKGxvb3AgdHhz CgkJICAgIChuZXh0LXN0YXJ0LWRhdGUtcHJvYyBwYXJ0aXRpb24tZW5kLWRhdGUtZXhjbHVzaXZl KQoJCSAgICAoYWNvbnMgcGFydGl0aW9uLWVuZC1kYXRlLWV4Y2x1c2l2ZSBjdXJyZW50LXBhcnRp dGlvbiBwcmV2aW91cy1wYXJ0aXRpb25zKQoJCSAgICAnKCkpKSkpKSkKCjs7IEdpdmVuIGEgc2Vy aWVzIG9mIHRyYW5zYWN0aW9ucywgdXNlIFNPUlQtRlVOQ1RJT04gdG8gcGFydGl0aW9uIHRoZW0K OzsgaW50byBhbiBhbGlzdCBvZiBzbWFsbGVyIHNlcmllcy4gIFdlIGNhbGwgU09SVC1GVU5DVElP TiBvbiBlYWNoCjs7IHRyYW5zYWN0aW9uLCBhbmQgaXQgcmV0dXJucyBhIHN0cmluZyBpbmRpY2F0 aW5nIHRoZSBuYW1lIG9mIHRoZQo7OyBwYXJ0aXRpb24gdGhhdCB0aGF0IHRyYW5zYWN0aW9uIHNo b3VsZCBiZWxvbmcgdG8uICBJbiB0aGUgcmVzdWx0Cjs7IGFsaXN0LCBlYWNoIGVudHJ5IGlzIChQ QVJUSVRJT04tTkFNRSAuIFRYLUxJU1QpLgoKKGRlZmluZSAocGFydGl0aW9uLWJ5LXNvcnQtZnVu Y3Rpb24gdHhzIHNvcnQtZnVuY3Rpb24pCiAgKGxldCBsb29wICgodHhzIHR4cykKCSAgICAgKHBh cnRpdGlvbnMgJygpKSkKICAgIChpZiAobnVsbD8gdHhzKQoJKG1hcCAobGFtYmRhIChuYW1lLWxp c3QtcGFpcikKCSAgICAgICAoY29ucyAoY2FyIG5hbWUtbGlzdC1wYWlyKSAocmV2ZXJzZSAoY2Ry IG5hbWUtbGlzdC1wYWlyKSkpKQoJICAgICAoc29ydCBwYXJ0aXRpb25zCgkJICAgKGxhbWJkYSAo eCB5KQoJCSAgICAgKHN0cmluZzw/IChjYXIgeCkgKGNhciB5KSkpKSkKCShsb29wIChjZHIgdHhz KQoJICAgICAgKGxldCogKCh0eCAoY2FyIHR4cykpCgkJICAgICAocGFydGl0aW9uLW5hbWUgKHNv cnQtZnVuY3Rpb24gdHgpKSkKCQkoYXNzb2Mtc2V0ISBwYXJ0aXRpb25zCgkJCSAgICBwYXJ0aXRp b24tbmFtZQoJCQkgICAgKGNvbnMgdHggKG9yIChhc3NvYy1yZWYgcGFydGl0aW9ucyBwYXJ0aXRp b24tbmFtZSkgJygpKSkpKSkpKSkKCjs7IEdpdmVuIGFuIGFsaXN0IG9mIHJlZ2V4cHMgYW5kIHBh cnRpdGlvbiBuYW1lcywgYnVpbGQgYQo7OyBTT1JULUZVTkNUSU9OIHRoYXQgcGFydGl0aW9ucyB0 cmFuc2FjdGlvbnMgYnkgbWF0Y2hpbmcgdGhlCjs7IHRyYW5zYWN0aW9uIGRlc2NyaXB0aW9uIGFn YWluc3QgdGhlIHJlZ2V4cHMuCgooZGVmaW5lIChyZWdleHAtYWxpc3QtPnNvcnQtZnVuY3Rpb24g cmVnZXhwLWFsaXN0KQogIChsYW1iZGEgKHR4KQogICAgKGxldCAoKGRlc2NyaXB0aW9uICh0eDpk ZXNjcmlwdGlvbiB0eCkpKQogICAgICAobGV0IGxvb3AgKChyZWdleHAtYWxpc3QgcmVnZXhwLWFs aXN0KSkKCShjb25kICgobnVsbD8gcmVnZXhwLWFsaXN0KQoJICAgICAgICIiKQoJICAgICAgKChz dHJpbmctbWF0Y2ggKGNhYXIgcmVnZXhwLWFsaXN0KSBkZXNjcmlwdGlvbikKCSAgICAgICAoY2Rh ciByZWdleHAtYWxpc3QpKQoJICAgICAgKGVsc2UKCSAgICAgICAobG9vcCAoY2RyIHJlZ2V4cC1h bGlzdCkpKSkpKSkpCgo7OyBJbiB0aGlzIGZpbGUsIGFuIGFtb3VudCBhdCByZXN0IGlzIGFsd2F5 cyByZXByZXNlbnRlZCBhcyBhIHN0cmluZwo7OyB3aXRoIDIgZGVjaW1hbCBwbGFjZXMuICBDb252 ZXJ0IGZyb20gdGhhdCB0byBhbiBpbnRlZ2VyIG51bWJlciBvZgo7OyBwZW5jZToKCihkZWZpbmUg KGFtb3VudC0+cGVuY2UgYW1vdW50KQogIChpbmV4YWN0LT5leGFjdCAocm91bmQgKCogMTAwIChz dHJpbmctPm51bWJlciBhbW91bnQpKSkpKQoKOzsgQW5kIHRoZSByZXZlcnNlOgoKKGRlZmluZSAo cGVuY2UtPmFtb3VudCBwZW5jZSkKICAoZm9ybWF0LTJkcCAoLyAoZXhhY3QtPmluZXhhY3QgcGVu Y2UpIDEwMCkpKQoKOzsgR2l2ZW4gYSBzZXJpZXMgb2YgdHJhbnNhY3Rpb25zLCByZXR1cm4gdGhl IHN1bSBvZiB0aGVpciBhbW91bnRzLgoKKGRlZmluZSAoc3VtLXRyYW5zYWN0aW9ucyBpbml0aWFs LXBlbmNlIHR4cykKICAocGVuY2UtPmFtb3VudCAoZm9sZCAobGFtYmRhICh0eCBwcmV2aW91cy10 b3RhbC1wZW5jZSkKCQkJICgrIHByZXZpb3VzLXRvdGFsLXBlbmNlCgkJCSAgICAoYW1vdW50LT5w ZW5jZSAodHg6YW1vdW50IHR4KSkpKQoJCSAgICAgICBpbml0aWFsLXBlbmNlCgkJICAgICAgIHR4 cykpKQoKOzsgR2l2ZW4gYSBzZXJpZXMgb2YgdHJhbnNhY3Rpb25zLCByZXR1cm4gYW4gYXJyYXkg c3VpdGFibGUgZm9yIE9yZwo7OyBkaXNwbGF5IHRoYXQgc2hvd3MgdGhlaXIgdG90YWwgZm9sbG93 ZWQgYnkgdGhlIGNvbnN0aXR1ZW50Cjs7IHRyYW5zYWN0aW9ucyBhbmQgYW1vdW50cy4KCihkZWZp bmUgKGRpc3BsYXktdHhzLXdpdGgtaW5pdGlhbC1zdW0gdHhzIHBhcnRpdGlvbi1uYW1lKQogIChj b25zIChsaXN0IChzdHJpbmctYXBwZW5kICJcIiIgcGFydGl0aW9uLW5hbWUgIlwiIikgKHN1bS10 cmFuc2FjdGlvbnMgMCB0eHMpICIiICIiKQoJKG1hcCAobGFtYmRhICh0eCkKCSAgICAgICAobGlz dCAiIiAiIiAodHg6ZGVzY3JpcHRpb24gdHgpICh0eDphbW91bnQgdHgpKSkKCSAgICAgdHhzKSkp Cgo7OyBFeGFtcGxlcyB0byBwdXQgdGhlIHdob2xlIHRoaW5nIHRvZ2V0aGVyLgoKKGRlZmluZSAo Y2F0ZWdvcml6ZS10cmFuc2FjdGlvbnMtYnktcGVyaW9kIHNvdXJjZXMgbmV4dC1zdGFydC1kYXRl LXByb2MgcmVnZXhwLWFsaXN0IHNob3ctYWxsLXR4cykKICAobGV0ICgodHhzIChhcHBseSByZWFk LXRyYW5zYWN0aW9ucyAobWFwIGNhZHIgc291cmNlcykpKQoJKGNhdGVnb3JpemVyIChyZWdleHAt YWxpc3QtPnNvcnQtZnVuY3Rpb24gcmVnZXhwLWFsaXN0KSkpCiAgICAoYXBwbHkgYXBwZW5kCgkg ICAobWFwIChsYW1iZGEgKHBlcmlvZC1wYXJ0aXRpb24pCgkJICAoY29ucyogJ2hsaW5lCgkJCSAo bGlzdCAoc3RyaW5nLWFwcGVuZCAiUGVyaW9kIGVuZGluZyAiCgkJCQkJICAgICAoZGF0ZS0+c3Ry aW5nIChjYXIgcGVyaW9kLXBhcnRpdGlvbikgIn4xIikpCgkJCSAgICAgICIiICIiICIiKQoJCQko YXBwbHkgYXBwZW5kCgkJCSAgICAgICAobWFwIChsYW1iZGEgKG5hbWUtbGlzdC1wYWlyKQoJCQkJ ICAgICAgKGxldCAoKGRldGFpbGVkLWRpc3BsYXkKCQkJCQkgICAgIChkaXNwbGF5LXR4cy13aXRo LWluaXRpYWwtc3VtIChjZHIgbmFtZS1saXN0LXBhaXIpCgkJCQkJCQkJCSAgIChjYXIgbmFtZS1s aXN0LXBhaXIpKSkpCgkJCQkJKGlmIHNob3ctYWxsLXR4cwoJCQkJCSAgICBkZXRhaWxlZC1kaXNw bGF5CgkJCQkJICAgIChsaXN0IChjYXIgZGV0YWlsZWQtZGlzcGxheSkpKSkpCgkJCQkgICAgKHBh cnRpdGlvbi1ieS1zb3J0LWZ1bmN0aW9uIChjZHIgcGVyaW9kLXBhcnRpdGlvbikKCQkJCQkJCQlj YXRlZ29yaXplcikpKSkpCgkJKHBhcnRpdGlvbi1ieS1wZXJpb2QgdHhzCgkJCQkgICAgICh0eC1k YXRlIChjYXIgdHhzKSkKCQkJCSAgICAgbmV4dC1zdGFydC1kYXRlLXByb2MpKSkpKQoKKGRlZmlu ZSAoY2F0ZWdvcml6ZS10cmFuc2FjdGlvbnMtYnktd2VlayBzb3VyY2VzIHJlZ2V4cC1hbGlzdCBz aG93LWFsbC10eHMpCiAgKGNhdGVnb3JpemUtdHJhbnNhY3Rpb25zLWJ5LXBlcmlvZCBzb3VyY2Vz CgkJCQkgICAgIChsYW1iZGEgKHN0YXJ0LWRhdGUpCgkJCQkgICAgICAgKG4tZGF5cy1sYXRlciBz dGFydC1kYXRlIDcpKQoJCQkJICAgICByZWdleHAtYWxpc3QKCQkJCSAgICAgc2hvdy1hbGwtdHhz KSkKCihkZWZpbmUgKGNhdGVnb3JpemUtdHJhbnNhY3Rpb25zLWJ5LW1vbnRoIHNvdXJjZXMgcmVn ZXhwLWFsaXN0IHNob3ctYWxsLXR4cykKICAoY2F0ZWdvcml6ZS10cmFuc2FjdGlvbnMtYnktcGVy aW9kIHNvdXJjZXMKCQkJCSAgICAgc3RhcnQtb2YtZm9sbG93aW5nLW1vbnRoCgkJCQkgICAgIHJl Z2V4cC1hbGlzdAoJCQkJICAgICBzaG93LWFsbC10eHMpKQoKKGRlZmluZSAocGVyaW9kaWMtYmFs YW5jZSBzb3VyY2VzIGluaXRpYWwtZGF0ZSBpbml0aWFsLWJhbGFuY2UgbmV4dC1zdGFydC1kYXRl LXByb2MpCiAgKGxldCogKCh0eHMgKGFwcGx5IHJlYWQtdHJhbnNhY3Rpb25zIChtYXAgY2FkciBz b3VyY2VzKSkpKQogICAgKGxldCBsb29wICgocGFydGl0aW9ucyAocGFydGl0aW9uLWJ5LXBlcmlv ZCB0eHMKCQkJCQkJKHR4LWRhdGUgKGNhciB0eHMpKQoJCQkJCQluZXh0LXN0YXJ0LWRhdGUtcHJv YykpCgkgICAgICAgKGJhbGFuY2UtcGVuY2UgKGFtb3VudC0+cGVuY2UgaW5pdGlhbC1iYWxhbmNl KSkKCSAgICAgICAob3V0cHV0IChsaXN0IChsaXN0IGluaXRpYWwtZGF0ZSBpbml0aWFsLWJhbGFu Y2UpKSkpCiAgICAgIChpZiAobnVsbD8gcGFydGl0aW9ucykKCSAgKHJldmVyc2Ugb3V0cHV0KQoJ ICAobGV0ICgocGFydGl0aW9uLWVuZC1iYWxhbmNlIChzdW0tdHJhbnNhY3Rpb25zIGJhbGFuY2Ut cGVuY2UgKGNkYXIgcGFydGl0aW9ucykpKSkKCSAgICAobG9vcCAoY2RyIHBhcnRpdGlvbnMpCgkJ ICAoYW1vdW50LT5wZW5jZSBwYXJ0aXRpb24tZW5kLWJhbGFuY2UpCgkJICAoY29ucyAobGlzdCAo ZGF0ZS0+c3RyaW5nIChjYWFyIHBhcnRpdGlvbnMpICJ+MSIpCgkJCSAgICAgIHBhcnRpdGlvbi1l bmQtYmFsYW5jZSkKCQkJb3V0cHV0KSkpKSkpKQoKKGRlZmluZSAod2Vla2x5LWJhbGFuY2Ugc291 cmNlcyBpbml0aWFsLWRhdGUgaW5pdGlhbC1iYWxhbmNlKQogIChwZXJpb2RpYy1iYWxhbmNlIHNv dXJjZXMKCQkgICAgaW5pdGlhbC1kYXRlCgkJICAgIGluaXRpYWwtYmFsYW5jZQoJCSAgICAobGFt YmRhIChzdGFydC1kYXRlKQoJCSAgICAgIChuLWRheXMtbGF0ZXIgc3RhcnQtZGF0ZSA3KSkpKQoK KGRlZmluZSAobW9udGhseS1iYWxhbmNlIHNvdXJjZXMgaW5pdGlhbC1kYXRlIGluaXRpYWwtYmFs YW5jZSkKICAocGVyaW9kaWMtYmFsYW5jZSBzb3VyY2VzCgkJICAgIGluaXRpYWwtZGF0ZQoJCSAg ICBpbml0aWFsLWJhbGFuY2UKCQkgICAgc3RhcnQtb2YtZm9sbG93aW5nLW1vbnRoKSkKCihkZWZp bmUgKHR3by1jb2x1bW4tdGFibGUtPmFsaXN0IHRhYmxlKQogIChtYXAgKGxhbWJkYSAocm93KQoJ IChjb25zIChjYXIgcm93KSAoY2FkciByb3cpKSkKICAgICAgIHRhYmxlKSkKCjs7IENvbXBhcmlz b24gYWdhaW5zdCBhIGJ1ZGdldC4KCihkZWZpbmUgKHN1bS10cmFuc2FjdGlvbnMtYnktbW9udGgt YW5kLWNhdGVnb3J5IHNvdXJjZXMgcmVnZXhwLWFsaXN0KQogIChsZXQgKCh0eHMgKGFwcGx5IHJl YWQtdHJhbnNhY3Rpb25zIChtYXAgY2FkciBzb3VyY2VzKSkpCgkoY2F0ZWdvcml6ZXIgKHJlZ2V4 cC1hbGlzdC0+c29ydC1mdW5jdGlvbiByZWdleHAtYWxpc3QpKSkKICAgIChsZXQgKChwZXJpb2Qt Y2F0ZWdvcnktYWxpc3QKCSAgIChtYXAgKGxhbWJkYSAocGVyaW9kLXBhcnRpdGlvbikKCQkgIChj b25zIChkYXRlLT5zdHJpbmcgKGNhciBwZXJpb2QtcGFydGl0aW9uKSAifjEiKQoJCQkobWFwIChs YW1iZGEgKG5hbWUtbGlzdC1wYWlyKQoJCQkgICAgICAgKGNvbnMgKGNhciBuYW1lLWxpc3QtcGFp cikKCQkJCSAgICAgKHN1bS10cmFuc2FjdGlvbnMgMCAoY2RyIG5hbWUtbGlzdC1wYWlyKSkpKQoJ CQkgICAgIChwYXJ0aXRpb24tYnktc29ydC1mdW5jdGlvbiAoY2RyIHBlcmlvZC1wYXJ0aXRpb24p IGNhdGVnb3JpemVyKSkpKQoJCShwYXJ0aXRpb24tYnktcGVyaW9kIHR4cwoJCQkJICAgICAodHgt ZGF0ZSAoY2FyIHR4cykpCgkJCQkgICAgIHN0YXJ0LW9mLWZvbGxvd2luZy1tb250aCkpKSkKICAg ICAgcGVyaW9kLWNhdGVnb3J5LWFsaXN0KSkpCg== --0000000000009c37dc05b01fe628--