From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: JD Smith Newsgroups: gmane.emacs.bugs Subject: bug#71572: [PATCH] seconds-to-string-approximate Date: Sat, 22 Jun 2024 22:16:40 -0400 Message-ID: References: <86r0cpicwt.fsf@gnu.org> Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3774.600.62\)) Content-Type: multipart/alternative; boundary="Apple-Mail=_7B0A21E6-71E7-4D62-AA68-5822ED656ACB" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="14992"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Adam Porter , 71572@debbugs.gnu.org, Eli Zaretskii , jonas@bernoul.li To: Paul Eggert Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Jun 23 04:19:21 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sLCp6-0003bw-PA for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 23 Jun 2024 04:19:20 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sLCoq-0002r7-TL; Sat, 22 Jun 2024 22:19:04 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sLCoo-0002qK-Sj for bug-gnu-emacs@gnu.org; Sat, 22 Jun 2024 22:19:02 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sLCoo-0004BD-Kc for bug-gnu-emacs@gnu.org; Sat, 22 Jun 2024 22:19:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1sLCoo-0000Qx-Nn for bug-gnu-emacs@gnu.org; Sat, 22 Jun 2024 22:19:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: JD Smith Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 23 Jun 2024 02:19:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 71572 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 71572-submit@debbugs.gnu.org id=B71572.17191090841573 (code B ref 71572); Sun, 23 Jun 2024 02:19:02 +0000 Original-Received: (at 71572) by debbugs.gnu.org; 23 Jun 2024 02:18:04 +0000 Original-Received: from localhost ([127.0.0.1]:40058 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sLCnr-0000PE-Jm for submit@debbugs.gnu.org; Sat, 22 Jun 2024 22:18:04 -0400 Original-Received: from mail-qk1-f180.google.com ([209.85.222.180]:60629) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sLCnn-0000OT-Hh for 71572@debbugs.gnu.org; Sat, 22 Jun 2024 22:18:01 -0400 Original-Received: by mail-qk1-f180.google.com with SMTP id af79cd13be357-795ca45c54cso176664285a.0 for <71572@debbugs.gnu.org>; Sat, 22 Jun 2024 19:17:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719109013; x=1719713813; darn=debbugs.gnu.org; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:from:to:cc:subject:date:message-id:reply-to; bh=sMpff6FxhODlyq/XQcKye3CKdK66fJf9NuDiuN+5ko8=; b=TZnyuZAAJ4LeutEmK+qgoM6GzgeQS9jqOKUBLecJ/WJ9GxvHymq5DZPfnJpgOyQsI8 WxqPDA5mqW3/fmfDDHpEkZyeqaf3nsuflix1fEzlZJ6F6HIsgEGKlwxxp0/15M4pBtjG H8DUxhQnZl1aBHqiMOpi6B7burCwU3z/spfOVRAa5J8x5sryOH2k1eot9CwkZrOVlWkn 4WqwAZvkdnUSAFKpmk53GxP4E8lOm2OrWZrX3U4/kzGVodmpn8rsCQ6IVqsVm4TvEijd /iyEV2UeUEgG6jZEjTsdrxwWqRbkH3lN8w1yja8uEBXvh/oX9uXWn24hjqNnj2lFG9Hp b8BA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719109013; x=1719713813; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=sMpff6FxhODlyq/XQcKye3CKdK66fJf9NuDiuN+5ko8=; b=JyblCftNMIjCDyzoNQMtGqsfd/gcGB9axpgEkCrQU7IqmC01AF/AoFvPUQEkP7JvIq cMnCszG587oXmgP82R5TVFyfvWrbW38gxFW/lu8vDVTLc0uV9Dkz6zj5OqCLNXgEr0nk GYGQL0knNH3FY7f/jPuRw2WohgwxL7pcIpxFV4dGoBJyJoBTdm5krH7RxwUWvFAKWmCB I5P9bFV352QPvfq26al8tjULM86VTe3e1GN+sGRB3cbHlxV4z6MSAEJM/VOc/PEy5+Om 96+vjSIu0Sgzudkgo8OzEdZYscEP1FVXIBCyqu1jm8BksZXutLz+yXUw7SBimzYqqiJc CTRw== X-Forwarded-Encrypted: i=1; AJvYcCVIqwr90oQKhEz5d42erVuzFh8X/RMOgGIxPJPk7lXIuLmQZqjYVVADKUvAxW9waiyK542HmYfzqRmCswtJilVZkPsPtvg= X-Gm-Message-State: AOJu0YyQFBxao7GuPr7Qv1ZomN9Xd48zukmzKeRQxhkq7Z7wg2nCi6tS ETRqYtvW+OhhrqraqPiWOvSNV0NyM82yrNGjdWHMqT7d1MZ6hqrd X-Google-Smtp-Source: AGHT+IHLZQk0/Ihoa5oW5sTU2a19cBtkl7H6to8tLX/UDNDTcIUUTPxmZ3W6WWmwjXV0hYVpOnRikA== X-Received: by 2002:a05:6214:5581:b0:6b5:44c:24ea with SMTP id 6a1803df08f44-6b5409c2d01mr12698206d6.16.1719109013446; Sat, 22 Jun 2024 19:16:53 -0700 (PDT) Original-Received: from smtpclient.apple (cm-24-53-187-34.buckeyecom.net. [24.53.187.34]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6b51ecfec5csm21659606d6.21.2024.06.22.19.16.51 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 22 Jun 2024 19:16:52 -0700 (PDT) In-Reply-To: X-Mailer: Apple Mail (2.3774.600.62) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:287751 Archived-At: --Apple-Mail=_7B0A21E6-71E7-4D62-AA68-5822ED656ACB Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Jun 22, 2024, at 7:42=E2=80=AFPM, Paul Eggert = wrote: >=20 > On 6/22/24 04:45, Eli Zaretskii wrote: >>>=20 >> Paul, any comments to the patch? >=20 > For starters: Thanks for the comment. > Why define a new function, instead of adding optional arguments to the = existing one? No real reason; new patch doing so attached. > Why not look at what mastodon.el does, as the comment in = seconds-to-string suggests? For example, mastodon-tl--human-duration = lets you specify whatever resolution you want, instead of limiting you = to either 0.5 or 1 as in the proposed patch. I see that mastodon is a package in ELPA, so doesn't satisfy the need in = core. I took a look at this function. The RESOLUTION mentioned is not = equivalent to the HALF argument, it is the minimum resolution in = seconds. So setting it to e.g. 3600 results in truncating to the hour, = but changes nothing below the hour. Setting it to the number of seconds = in a year gives something quite similar to magit--age (though I notice = the mastodon function truncates, instead of rounds; see, e.g., 2.98y in = the table below). Here's a comparison among: - the current seconds-to-string - mastodon-tl--human-duration - mastodon with a 3600s resolution - mastodon with 1yr "resolution" - the new seconds-to-string with option READABLE=3Dt - new seconds-to-string with abbreviated units and half unit resolution Delay (s) s-to-s mastodon mastodon (3600s) mast = (1yr) s-to-s (rdb) s-to-s (rdb=3Dabbrev, half) 0.5 450.00ms 0 sec 0 sec = 0 sec 0 seconds =C2=BDs 1.0 1.03s 1 sec 1 sec = 1 sec 1 second 1s 2.4 2.38s 2 secs 2 secs 2 = secs 2 seconds 2=C2=BDs 5.5 5.48s 5 secs 5 secs 5 = secs 5 seconds 5=C2=BDs 12.6 12.59s 12 secs 12 secs 12 = secs 13 seconds 12=C2=BDs 29.0 28.96s 28 secs 28 secs 28 = secs 29 seconds 29s 66.6 66.62s 1 min 1 min = 1 min 1 minute 1m 153.2 2.55m 2 mins 2 mins 2 = mins 3 minutes 2=C2=BDm 352.4 5.87m 5 mins 5 mins 5 = mins 6 minutes 6m 810.5 13.51m 13 mins 13 mins 13 = mins 14 minutes 13=C2=BDm 1864.2 31.07m 31 mins 31 mins 31 = mins 31 minutes 31m 4287.6 71.46m 1 hour, 11 mins 1 hour 1 = hour 1 hour 1h 9861.6 2.74h 2 hours, 44 mins 2 hours 2 = hours 3 hours 2=C2=BDh 22681.6 6.30h 6 hours, 18 mins 6 hours 6 = hours 6 hours 6=C2=BDh 52167.8 14.49h 14 hours, 29 mins 14 hours 14 = hours 14 hours 14=C2=BDh 119985.9 1.39d 1 day, 9 hours 1 day, 9 hours = 1 day 1 day 1=C2=BDd 275967.5 3.19d 3 days, 4 hours 3 days, 4 hours 3 = days 3 days 3d 634725.2 7.35d 1 week 1 week 1 = week 1 week 1w 1459867.9 16.90d 2 weeks, 2 days 2 weeks, 2 days 2 = weeks 2 weeks 2=C2=BDw 3357696.2 38.86d 1 month, 1 week 1 month, 1 week 1 = month 1 month 1=C2=BDM 7722701.2 89.38d 2 months, 4 weeks 2 months, 4 weeks 2 = months 3 months 3M 17762212.9 205.58d 6 months, 3 weeks 6 months, 3 weeks 6 = months 7 months 7M 40853089.6 1.29y 1 year, 3 months 1 year, 3 months 1 = year 1 year 1=C2=BDY 93962106.0 2.98y 2 years, 11 months 2 years, 11 months 2 = years 3 years 3Y 216112843.8 6.85y 6 years, 10 months 6 years, 10 months 6 = years 7 years 7Y 497059540.7 15.75y 15 years, 9 months 15 years, 9 months 15 = years 16 years 16Y The last column is obviously the most compact while still conveying a = good amount of information, but the 1yr mastodon and normal READABLE = s-to-s are also quite good (effectively equivalent to magit--age) for a = quick glance and maintaining ~constant widths. I do find it awkward to = set the RESOLUTION argument to >30 million seconds to achieve this. It = took me a bit to understand what this argument does.=20 Code use to produce: (concat (format "%11s %10s %18s %18s %12s %12s %s\n" "Delay (s)" "s-to-s" "mastodon" "mastodon (3600s)" "mast (1yr)" "s-to-s (rdb)" = "s-to-s (rdb=3Dabbrev, half)") (cl-loop for s =3D 0.45 then (* s 2.3) while (< s (* 365.25 24 3600 = 22)) concat (format "%11.1f %10s %18s %18s %12s %12s %s\n" s (seconds-to-string s) (car (mastodon-tl--human-duration s)) (car (mastodon-tl--human-duration s 3600)) (car (mastodon-tl--human-duration s (* 365.25 = 24 3600))) (seconds-to-string s t) (seconds-to-string s 'abbrev 'half)))) =EF=BF=BC= --Apple-Mail=_7B0A21E6-71E7-4D62-AA68-5822ED656ACB Content-Type: multipart/mixed; boundary="Apple-Mail=_BAAFEC3A-8FE1-4F22-84C3-4558A83F7E88" --Apple-Mail=_BAAFEC3A-8FE1-4F22-84C3-4558A83F7E88 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8

On Jun 22, 2024, at 7:42=E2=80=AFPM, Paul Eggert = <eggert@cs.ucla.edu> wrote:

On 6/22/24 04:45, Eli = Zaretskii wrote:

Paul, any comments to the = patch?

For = starters:

Thanks for the = comment.

Why define a = new function, instead of adding optional arguments to the existing = one?

No real reason; new = patch doing so attached.

Why = not look at what mastodon.el does, as the comment in seconds-to-string = suggests? For example, mastodon-tl--human-duration lets you specify = whatever resolution you want, instead of limiting you to either 0.5 or 1 =  as in the proposed = patch.

I see that = mastodon is a package in ELPA, so doesn't satisfy the need in core. =  I took a look at this function.  The RESOLUTION mentioned is = not equivalent to the HALF argument, it is the minimum resolution in = seconds.  So setting it to e.g. 3600 results in truncating to the = hour, but changes nothing below the hour.  Setting it to the number = of seconds in a year gives something quite similar to magit--age (though = I notice the mastodon function truncates, instead of rounds; see, e.g., = 2.98y in the table below).

Here's a comparison = among:

- the current = seconds-to-string
- mastodon-tl--human-duration
- = mastodon with a 3600s resolution
- mastodon with 1yr = "resolution"
- the new seconds-to-string with option = READABLE=3Dt
- new seconds-to-string with abbreviated units = and half unit resolution

  Delay (s)      s-to-s   =          mastodon    mastodon (3600s) =    mast (1yr)  s-to-s (rdb)  s-to-s (rdb=3Dabbrev, = half)
      =   0.5    450.00ms           =     0 sec               0 = sec         0 sec     0 seconds =  =C2=BDs
    =     1.0       1.03s         =       1 sec             =   1 sec         1 sec      1 = second  1s
  =       2.4       2.38s       =        2 secs           =    2 secs        2 secs     2 = seconds  2=C2=BDs
        5.5       5.48s   =            5 secs       =        5 secs        5 secs =     5 seconds  5=C2=BDs
       12.6     =  12.59s             12 secs   =           12 secs       12 secs =    13 seconds  12=C2=BDs
       29.0     =  28.96s             28 secs   =           28 secs       28 secs =    29 seconds  29s
       66.6      66.62s   =             1 min       =         1 min         1 min =      1 minute  1m
      153.2       = 2.55m              2 mins   =            2 mins       =  2 mins     3 minutes  2=C2=BDm
      352.4       = 5.87m              5 mins   =            5 mins       =  5 mins     6 minutes  6m
      810.5     =  13.51m             13 mins   =           13 mins       13 mins =    14 minutes  13=C2=BDm
     1864.2     =  31.07m             31 mins   =           31 mins       31 mins =    31 minutes  31m
     4287.6      71.46m   =   1 hour, 11 mins              1 = hour        1 hour        1 hour =  1h
    =  9861.6       2.74h    2 hours, 44 mins =             2 hours       2 = hours       3 hours  2=C2=BDh
    22681.6       6.30h =    6 hours, 18 mins             = 6 hours       6 hours       6 hours =  6=C2=BDh
    = 52167.8      14.49h   14 hours, 29 mins   =          14 hours      14 hours =      14 hours  14=C2=BDh
   119985.9       1.39d =      1 day, 9 hours      1 day, 9 hours =         1 day         1 day =  1=C2=BDd
  =  275967.5       3.19d     3 days, 4 hours =     3 days, 4 hours        3 days   =      3 days  3d
   634725.2       7.35d     =          1 week         =      1 week        1 week   =      1 week  1w
  1459867.9      16.90d     2 weeks, = 2 days     2 weeks, 2 days       2 weeks   =     2 weeks  2=C2=BDw
  3357696.2      38.86d     1 = month, 1 week     1 month, 1 week       1 month =       1 month  1=C2=BDM
  7722701.2      89.38d   = 2 months, 4 weeks   2 months, 4 weeks      2 months =      3 months  3M
 17762212.9     205.58d   6 = months, 3 weeks   6 months, 3 weeks      6 months =      7 months  7M
 40853089.6       1.29y   =  1 year, 3 months    1 year, 3 months     =    1 year        1 year =  1=C2=BDY
 93962106.0       2.98y  2 years, 11 = months  2 years, 11 months       2 years   =     3 years  3Y
216112843.8       6.85y  6 years, 10 months =  6 years, 10 months       6 years     =   7 years  7Y
497059540.7      15.75y  15 years, 9 months =  15 years, 9 months      15 years     =  16 years  16Y

The last = column is obviously the most compact while still conveying a good amount = of information, but the 1yr mastodon and normal READABLE s-to-s are also = quite good (effectively equivalent to magit--age) for a quick glance and = maintaining ~constant widths.  I do find it awkward to set = the RESOLUTION argument to >30 million seconds to achieve = this.  It took me a bit to understand what this argument = does. 

Code use to = produce:

(concat
 (format = "%11s  %10s  %18s  %18s  %12s  %12s  %s\n" = "Delay (s)" "s-to-s"
  =        "mastodon" "mastodon (3600s)" "mast (1yr)" = "s-to-s (rdb)" "s-to-s (rdb=3Dabbrev, half)")
 (cl-loop for s =3D 0.45 then (* s 2.3) while = (< s (* 365.25 24 3600 22))
          concat (format "%11.1f =  %10s  %18s  %18s  %12s  %12s  %s\n" = s
      =                   =  (seconds-to-string s)
                  =        (car (mastodon-tl--human-duration = s))
      =                   =  (car (mastodon-tl--human-duration s 3600))
              =            (car = (mastodon-tl--human-duration s (* 365.25 24 = 3600)))
      =                   =  (seconds-to-string s t)
                  =        (seconds-to-string s 'abbrev = 'half))))

= --Apple-Mail=_BAAFEC3A-8FE1-4F22-84C3-4558A83F7E88 Content-Disposition: attachment; filename=time-data-readable-seconds.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="time-data-readable-seconds.patch" Content-Transfer-Encoding: quoted-printable ---=20time-date.el=092024-06-22=2021:51:21=0A+++=20time-date_new.el=09= 2024-06-22=2021:53:13=0A@@=20-406,10=20+406,41=20@@=0A=20=20=20=20=20=20=20= =20=20(list=20(*=203600=2024=20400)=20"d"=20(*=203600.0=2024.0))=0A=20=20= =20=20=20=20=20=20=20(list=20nil=20"y"=20(*=20365.25=2024=203600)))=0A=20= =20=20"Formatting=20used=20by=20the=20function=20`seconds-to-string'.")=0A= +=0A+(defvar=20seconds-to-string-readable=0A+=20=20`(("Y"=20"year"=20=20=20= "years"=20=20=20,(round=20(*=2060=2060=2024=20365.2425)))=0A+=20=20=20=20= ("M"=20"month"=20=20"months"=20=20,(round=20(*=2060=2060=2024=20= 30.436875)))=0A+=20=20=20=20("w"=20"week"=20=20=20"weeks"=20=20=20,(*=20= 60=2060=2024=207))=0A+=20=20=20=20("d"=20"day"=20=20=20=20"days"=20=20=20= =20,(*=2060=2060=2024))=0A+=20=20=20=20("h"=20"hour"=20=20=20"hours"=20=20= =20,(*=2060=2060))=0A+=20=20=20=20("m"=20"minute"=20"minutes"=2060)=0A+=20= =20=20=20("s"=20"second"=20"seconds"=201))=0A+=20=20"Formatting=20used=20= by=20the=20function=20`seconds-to-string'=20with=20READABLE=20set.")=0A+=0A= =20;;;###autoload=0A-(defun=20seconds-to-string=20(delay)=0A-=20=20= "Convert=20the=20time=20interval=20in=20seconds=20to=20a=20short=20= string."=0A-=20=20(cond=20((>=200=20delay)=20(concat=20"-"=20= (seconds-to-string=20(-=20delay))))=0A+(defun=20seconds-to-string=20= (delay=20&optional=20readable=20half)=0A+=20=20"Convert=20the=20time=20= interval=20in=20seconds=20to=20a=20short=20string.=0A+If=20READABLE=20is=20= non-nil,=20convert=20DELAY=20into=20a=20readable=20string.=20=20If=20it=20= is=0A+the=20value=20`abbrev',=20abbreviate=20the=20units.=20=20If=20HALF=20= is=20set,=20round=20to=20the=0A+nearest=20half=20unit."=0A+=20=20(cond=20= ((>=200=20delay)=20(concat=20"-"=20(seconds-to-string=20(-=20delay)=20= readable=20half)))=0A+=20=20=20=20=20=20=20=20(readable=0A+=20=20=20=20=20= =20=20=20=20(let=20((abbrev=20(eq=20readable=20'abbrev))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(stsa=20seconds-to-string-readable)=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20here=20cnt)=0A+=20=20=20=20=20=20=20= =20=20=20=20(if=20(=3D=20(round=20delay=20(if=20half=200.5=201.))=200)=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(format=20"0%s"=20(if=20= abbrev=20"s"=20"=20seconds"))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= (while=20(and=20(setq=20here=20(pop=20stsa))=20stsa=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(<=20(/=20delay=20= (nth=203=20here))=201)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20= cnt=20(round=20(/=20(float=20delay)=20(nth=203=20here))=20(if=20half=20= 0.5=201.)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(concat=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(let=20((c=20(if=20half=20(/=20cnt=202)=20= cnt)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20(>=20c=20= 0)=20(number-to-string=20c)=20""))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(if=20(and=20half=20(=3D=20(mod=20cnt=202)=201))=20"=C2=BD"=20"")=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20abbrev=20""=20"=20")=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cond=20(abbrev=20(car=20= here))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ((<=3D=20cnt=20(if=20half=202=201))=20(nth=201=20here))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(t=20(nth=202=20here)))))))=0A= =20=20=20=20=20=20=20=20=20((=3D=200=20delay)=20"0s")=0A=20=20=20=20=20=20= =20=20=20(t=20(let=20((sts=20seconds-to-string)=20here)=0A=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(while=20(and=20(car=20(setq=20here=20(pop=20= sts)))=0A= --Apple-Mail=_BAAFEC3A-8FE1-4F22-84C3-4558A83F7E88 Content-Transfer-Encoding: 7bit Content-Type: text/html; charset=us-ascii
--Apple-Mail=_BAAFEC3A-8FE1-4F22-84C3-4558A83F7E88-- --Apple-Mail=_7B0A21E6-71E7-4D62-AA68-5822ED656ACB--