zuzu-js 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/LICENSE +5 -0
  2. package/README.md +113 -0
  3. package/bin/zuzu +17 -0
  4. package/bin/zuzu-build-browser-bundle +57 -0
  5. package/bin/zuzu-generate-browser-stdlib +584 -0
  6. package/bin/zuzu-js +23 -0
  7. package/bin/zuzu-js-compile +152 -0
  8. package/bin/zuzu-js-electron +19 -0
  9. package/dist/zuzu-browser-worker.js +45574 -0
  10. package/dist/zuzu-browser.js +45362 -0
  11. package/lib/browser-bundle-entry.js +160 -0
  12. package/lib/browser-gui-renderer.js +387 -0
  13. package/lib/browser-runtime.js +167 -0
  14. package/lib/browser-worker-entry.js +413 -0
  15. package/lib/browser-ztests/runner.html +103 -0
  16. package/lib/browser-ztests/runner.js +369 -0
  17. package/lib/cli.js +350 -0
  18. package/lib/collections.js +367 -0
  19. package/lib/compiler.js +303 -0
  20. package/lib/electron/launcher.js +70 -0
  21. package/lib/electron/main.js +956 -0
  22. package/lib/electron/preload.js +80 -0
  23. package/lib/electron/renderer.html +122 -0
  24. package/lib/electron/renderer.js +24 -0
  25. package/lib/execution-metadata.js +18 -0
  26. package/lib/gui/dom-renderer.js +778 -0
  27. package/lib/host/browser-host.js +278 -0
  28. package/lib/host/capabilities.js +47 -0
  29. package/lib/host/electron-host.js +15 -0
  30. package/lib/host/node-host.js +74 -0
  31. package/lib/paths.js +150 -0
  32. package/lib/runtime-entrypoints.js +60 -0
  33. package/lib/runtime-helpers.js +886 -0
  34. package/lib/runtime.js +3529 -0
  35. package/lib/tap.js +37 -0
  36. package/lib/transpiler-new/ast.js +23 -0
  37. package/lib/transpiler-new/codegen.js +2455 -0
  38. package/lib/transpiler-new/errors.js +28 -0
  39. package/lib/transpiler-new/index.js +26 -0
  40. package/lib/transpiler-new/lexer.js +834 -0
  41. package/lib/transpiler-new/parser.js +2332 -0
  42. package/lib/transpiler-new/validate-bindings.js +326 -0
  43. package/lib/transpiler-utils.js +95 -0
  44. package/lib/transpiler.js +33 -0
  45. package/lib/zuzu.js +53 -0
  46. package/modules/javascript.js +193 -0
  47. package/modules/std/archive.js +603 -0
  48. package/modules/std/clib.js +338 -0
  49. package/modules/std/data/csv.js +1331 -0
  50. package/modules/std/data/json.js +531 -0
  51. package/modules/std/data/xml.js +441 -0
  52. package/modules/std/data/yaml.js +256 -0
  53. package/modules/std/db-worker.js +250 -0
  54. package/modules/std/db.js +664 -0
  55. package/modules/std/digest/_hash.js +443 -0
  56. package/modules/std/digest/md5.js +26 -0
  57. package/modules/std/digest/sha.js +72 -0
  58. package/modules/std/eval.js +10 -0
  59. package/modules/std/gui/objects.js +1519 -0
  60. package/modules/std/internals.js +571 -0
  61. package/modules/std/io/socks-worker.js +318 -0
  62. package/modules/std/io/socks.js +186 -0
  63. package/modules/std/io.js +475 -0
  64. package/modules/std/marshal/cbor.js +463 -0
  65. package/modules/std/marshal/graph.js +1624 -0
  66. package/modules/std/marshal.js +87 -0
  67. package/modules/std/math/bignum.js +91 -0
  68. package/modules/std/math.js +79 -0
  69. package/modules/std/net/dns.js +306 -0
  70. package/modules/std/net/http.js +820 -0
  71. package/modules/std/net/smtp.js +943 -0
  72. package/modules/std/net/url.js +109 -0
  73. package/modules/std/proc.js +602 -0
  74. package/modules/std/secure.js +3724 -0
  75. package/modules/std/string/base64.js +138 -0
  76. package/modules/std/string.js +299 -0
  77. package/modules/std/task.js +914 -0
  78. package/modules/std/time.js +579 -0
  79. package/modules/std/tui.js +188 -0
  80. package/modules/std/worker-thread.js +246 -0
  81. package/modules/std/worker.js +790 -0
  82. package/package.json +67 -0
  83. package/stdlib/modules/javascript.zzm +99 -0
  84. package/stdlib/modules/perl.zzm +105 -0
  85. package/stdlib/modules/std/archive.zzm +132 -0
  86. package/stdlib/modules/std/cache/lru.zzm +174 -0
  87. package/stdlib/modules/std/clib.zzm +112 -0
  88. package/stdlib/modules/std/colour.zzm +220 -0
  89. package/stdlib/modules/std/config.zzm +818 -0
  90. package/stdlib/modules/std/data/cbor.zzm +497 -0
  91. package/stdlib/modules/std/data/csv.zzm +285 -0
  92. package/stdlib/modules/std/data/ini.zzm +472 -0
  93. package/stdlib/modules/std/data/json/schema/core.zzm +573 -0
  94. package/stdlib/modules/std/data/json/schema/format.zzm +581 -0
  95. package/stdlib/modules/std/data/json/schema/model.zzm +255 -0
  96. package/stdlib/modules/std/data/json/schema/output.zzm +272 -0
  97. package/stdlib/modules/std/data/json/schema/relative_pointer.zzm +299 -0
  98. package/stdlib/modules/std/data/json/schema/validation.zzm +1503 -0
  99. package/stdlib/modules/std/data/json/schema.zzm +306 -0
  100. package/stdlib/modules/std/data/json.zzm +102 -0
  101. package/stdlib/modules/std/data/kdl/json.zzm +460 -0
  102. package/stdlib/modules/std/data/kdl/xml.zzm +387 -0
  103. package/stdlib/modules/std/data/kdl.zzm +1631 -0
  104. package/stdlib/modules/std/data/toml.zzm +756 -0
  105. package/stdlib/modules/std/data/toon.zzm +1017 -0
  106. package/stdlib/modules/std/data/xml/escape.zzm +156 -0
  107. package/stdlib/modules/std/data/xml.zzm +276 -0
  108. package/stdlib/modules/std/data/yaml.zzm +94 -0
  109. package/stdlib/modules/std/db.zzm +173 -0
  110. package/stdlib/modules/std/defer.zzm +75 -0
  111. package/stdlib/modules/std/digest/crc32.zzm +196 -0
  112. package/stdlib/modules/std/digest/md5.zzm +54 -0
  113. package/stdlib/modules/std/digest/sha.zzm +83 -0
  114. package/stdlib/modules/std/dump.zzm +317 -0
  115. package/stdlib/modules/std/eval.zzm +63 -0
  116. package/stdlib/modules/std/getopt.zzm +432 -0
  117. package/stdlib/modules/std/gui/dialogue.zzm +592 -0
  118. package/stdlib/modules/std/gui/objects.zzm +123 -0
  119. package/stdlib/modules/std/gui.zzm +1914 -0
  120. package/stdlib/modules/std/internals.zzm +139 -0
  121. package/stdlib/modules/std/io/socks.zzm +139 -0
  122. package/stdlib/modules/std/io.zzm +157 -0
  123. package/stdlib/modules/std/lingua/en.zzm +347 -0
  124. package/stdlib/modules/std/log.zzm +169 -0
  125. package/stdlib/modules/std/mail.zzm +2726 -0
  126. package/stdlib/modules/std/marshal.zzm +138 -0
  127. package/stdlib/modules/std/math/bignum.zzm +98 -0
  128. package/stdlib/modules/std/math/range.zzm +116 -0
  129. package/stdlib/modules/std/math/roman.zzm +156 -0
  130. package/stdlib/modules/std/math.zzm +141 -0
  131. package/stdlib/modules/std/net/dns.zzm +93 -0
  132. package/stdlib/modules/std/net/http.zzm +278 -0
  133. package/stdlib/modules/std/net/smtp.zzm +257 -0
  134. package/stdlib/modules/std/net/url.zzm +69 -0
  135. package/stdlib/modules/std/path/jsonpointer.zzm +526 -0
  136. package/stdlib/modules/std/path/kdl.zzm +1003 -0
  137. package/stdlib/modules/std/path/simple.zzm +520 -0
  138. package/stdlib/modules/std/path/z/context.zzm +147 -0
  139. package/stdlib/modules/std/path/z/evaluate.zzm +549 -0
  140. package/stdlib/modules/std/path/z/functions.zzm +874 -0
  141. package/stdlib/modules/std/path/z/lexer.zzm +490 -0
  142. package/stdlib/modules/std/path/z/node.zzm +1455 -0
  143. package/stdlib/modules/std/path/z/operators.zzm +445 -0
  144. package/stdlib/modules/std/path/z/parser.zzm +359 -0
  145. package/stdlib/modules/std/path/z.zzm +403 -0
  146. package/stdlib/modules/std/path/zz/functions.zzm +828 -0
  147. package/stdlib/modules/std/path/zz/operators.zzm +1036 -0
  148. package/stdlib/modules/std/path/zz.zzm +100 -0
  149. package/stdlib/modules/std/proc.zzm +155 -0
  150. package/stdlib/modules/std/result.zzm +149 -0
  151. package/stdlib/modules/std/secure.zzm +606 -0
  152. package/stdlib/modules/std/string/base64.zzm +66 -0
  153. package/stdlib/modules/std/string/quoted_printable.zzm +485 -0
  154. package/stdlib/modules/std/string.zzm +179 -0
  155. package/stdlib/modules/std/task.zzm +221 -0
  156. package/stdlib/modules/std/template/z.zzm +531 -0
  157. package/stdlib/modules/std/template/zz.zzm +62 -0
  158. package/stdlib/modules/std/time.zzm +188 -0
  159. package/stdlib/modules/std/tui.zzm +89 -0
  160. package/stdlib/modules/std/uuid.zzm +223 -0
  161. package/stdlib/modules/std/web/session.zzm +388 -0
  162. package/stdlib/modules/std/web/static.zzm +329 -0
  163. package/stdlib/modules/std/web.zzm +1942 -0
  164. package/stdlib/modules/std/worker.zzm +202 -0
  165. package/stdlib/modules/std/zuzuzoo.zzm +3960 -0
  166. package/stdlib/modules/test/more.zzm +528 -0
  167. package/stdlib/modules/test/parser.zzm +209 -0
@@ -0,0 +1,188 @@
1
+ =encoding utf8
2
+
3
+ =head1 NAME
4
+
5
+ std/time - Time objects, formatting, and parsing.
6
+
7
+ =head1 SYNOPSIS
8
+
9
+ from std/time import Time, TimeZone, Duration, TimeFormat, TimeParser;
10
+
11
+ let london := TimeZone.named("Europe/London");
12
+ let now := new Time(timezone: london);
13
+ let tomorrow := now.add_days(1);
14
+ let next_hour := now.add(Duration.hours(1));
15
+
16
+ let parsed := Time.parse("2026-03-20T12:00:00", timezone: london);
17
+ say TimeFormat.rfc3339().format(parsed);
18
+
19
+ =head1 IMPLEMENTATION SUPPORT
20
+
21
+ This module is supported by all implementations of ZuzuScript.
22
+
23
+ =head1 DESCRIPTION
24
+
25
+ This module provides immutable C<Time> objects for working with instants,
26
+ timezones, calendar arithmetic, parsing, and serialization. C<TimeParser>
27
+ remains available for compatibility with older strptime-style parsing.
28
+
29
+ =head1 EXPORTS
30
+
31
+ =head2 Classes
32
+
33
+ =over
34
+
35
+ =item C<< Time(Number epoch?, timezone: TimeZone|String?) >>
36
+
37
+ Construct a time from an epoch value in seconds, or use the current
38
+ time when omitted. C<timezone> controls the calendar view used by component
39
+ accessors and calendar arithmetic. Returns: C<Time>.
40
+
41
+ Common instance methods include:
42
+
43
+ =over
44
+
45
+ =item C<< time.sec() >>, C<< time.min() >>, C<< time.hour() >>
46
+
47
+ Parameters: none. Returns: C<Number>. Returns the seconds, minutes, or
48
+ hours component.
49
+
50
+ =item C<< time.day_of_month() >>, C<< time.mon() >>, C<< time.month() >>, C<< time.year() >>, C<< time.yy() >>
51
+
52
+ Parameters: none. Returns: C<Number>. Returns the local calendar date
53
+ component.
54
+
55
+ =item C<< time.day_of_week() >>, C<< time.day() >>, C<< time.day_of_year() >>, C<< time.month_last_day() >>
56
+
57
+ Parameters: none. Returns: C<Number>. Returns derived local calendar
58
+ component values.
59
+
60
+ =item C<< time.epoch() >>
61
+
62
+ Parameters: none. Returns: C<Number>. Returns epoch seconds.
63
+
64
+ =item C<< time.timezone() >>
65
+
66
+ Parameters: none. Returns: C<TimeZone>. Returns the timezone metadata for
67
+ the time object.
68
+
69
+ =item C<< time.with_timezone(TimeZone|String zone) >>
70
+
71
+ Parameters: C<zone> is an IANA name, fixed offset, or C<TimeZone>. Returns:
72
+ C<Time>. Keeps the same instant and changes the displayed timezone.
73
+
74
+ =item C<< time.reinterpret_timezone(TimeZone|String zone) >>
75
+
76
+ Parameters: C<zone> is an IANA name, fixed offset, or C<TimeZone>. Returns:
77
+ C<Time>. Keeps the same displayed date/time fields and changes the instant.
78
+
79
+ =item C<< time.hms(separator?) >>, C<< time.ymd(separator?) >>, C<< time.mdy(separator?) >>, C<< time.dmy(separator?) >>
80
+
81
+ Parameters: C<separator> is an optional separator string. Returns:
82
+ C<String>. Formats a time or date component string.
83
+
84
+ =item C<< time.date() >>, C<< time.time() >>, C<< time.datetime() >>, C<< time.cdate() >>, C<< time.to_String() >>
85
+
86
+ Parameters: none. Returns: C<String>. Formats the time using common date
87
+ and time layouts.
88
+
89
+ =item C<< time.strftime(String format) >>
90
+
91
+ Parameters: C<format> is a strftime format string. Returns: C<String>.
92
+ Formats the time with C<format>.
93
+
94
+ =item C<< time.to_iso8601() >>, C<< time.to_rfc3339() >>, C<< time.to_rfc5322(include_weekday: Boolean?) >>
95
+
96
+ Parameters: C<include_weekday> is an optional Boolean for C<to_rfc5322>.
97
+ Returns: C<String>. Serializes the time using common machine and mail date
98
+ formats. C<to_rfc5322> includes a weekday by default; pass
99
+ C<include_weekday: false> to omit it.
100
+
101
+ =item C<< time.tzoffset() >>
102
+
103
+ Parameters: none. Returns: C<Number>. Returns the local timezone offset.
104
+
105
+ =item C<< time.is_leap_year() >>
106
+
107
+ Parameters: none. Returns: C<Boolean>. Returns true when the local year
108
+ is a leap year.
109
+
110
+ =item C<< time.week() >>, C<< time.week_year() >>, C<< time.julian_day() >>
111
+
112
+ Parameters: none. Returns: C<Number>. Returns week-numbering and Julian
113
+ day values.
114
+
115
+ =item C<< time.add_seconds(Number n) >>, C<< time.add_minutes(Number n) >>, C<< time.add_hours(Number n) >>, C<< time.add_days(Number n) >>, C<< time.add_weeks(Number n) >>
116
+
117
+ Parameters: C<n> is the amount to add. Returns: C<Time>. Seconds, minutes,
118
+ and hours are elapsed-time operations. Days and weeks are calendar
119
+ operations in the object's timezone.
120
+
121
+ =item C<< time.add_months(Number n) >>, C<< time.add_years(Number n) >>
122
+
123
+ Parameters: C<n> is the amount to add. Returns: C<Time>. Returns a new
124
+ time offset by calendar months or years on supported builds.
125
+
126
+ =item C<< time.subtract_seconds(Number n) >>, C<< time.subtract_minutes(Number n) >>, C<< time.subtract_hours(Number n) >>, C<< time.subtract_days(Number n) >>, C<< time.subtract_weeks(Number n) >>, C<< time.subtract_months(Number n) >>, C<< time.subtract_years(Number n) >>
127
+
128
+ Parameters: C<n> is the amount to subtract. Returns: C<Time>.
129
+
130
+ =item C<< time.add(Duration d) >>, C<< time.subtract(Duration d) >>
131
+
132
+ Parameters: C<d> is a C<Duration>. Returns: C<Time>.
133
+
134
+ =item C<< time.elapsed_seconds_until(Time other) >>, C<< time.compare(Time other) >>, C<< time.is_before(Time other) >>, C<< time.is_after(Time other) >>
135
+
136
+ Parameters: C<other> is another C<Time>. Returns elapsed seconds, ordering,
137
+ or boolean comparison results.
138
+
139
+ =item C<< Time.parse(String text, timezone: TimeZone|String?) >>
140
+
141
+ Parameters: C<text> is ISO 8601/RFC 3339 or RFC 5322 text. RFC 5322 input
142
+ accepts common obsolete mail-date spellings including two-digit years,
143
+ legacy US zones, and military zones other than C<J>. Zone-less ISO input
144
+ requires an explicit C<timezone>. Returns: C<Time>.
145
+
146
+ =item C<< TimeZone.utc() >>, C<< TimeZone.local() >>, C<< TimeZone.named(String name) >>, C<< TimeZone.offset(Number seconds) >>
147
+
148
+ Returns timezone helper objects. Named zones use IANA timezone names.
149
+
150
+ =item C<< Duration.seconds(Number n) >>, C<< Duration.minutes(Number n) >>, C<< Duration.hours(Number n) >>, C<< Duration.days(Number n) >>, C<< Duration.weeks(Number n) >>, C<< Duration.months(Number n) >>, C<< Duration.years(Number n) >>
151
+
152
+ Returns immutable duration helper objects.
153
+
154
+ =item C<< TimeFormat.iso8601() >>, C<< TimeFormat.rfc3339() >>, C<< TimeFormat.rfc5322() >>, C<< TimeFormat.strftime(String pattern) >>
155
+
156
+ Returns formatter/parser helper objects.
157
+
158
+ =item C<< TimeFormat.format(Time time) >>
159
+
160
+ Parameters: C<time> is a C<Time>. Returns: C<String>. Formats C<time>
161
+ using the helper object's format.
162
+
163
+ =item C<< TimeFormat.parse(String text, timezone: TimeZone|String?) >>
164
+
165
+ Parameters: C<text> is date-time text matching the helper object's format.
166
+ RFC 5322 input may carry its own timezone. Zone-less input requires an
167
+ explicit C<timezone>. Returns: C<Time>.
168
+
169
+ =back
170
+
171
+ =item C<< TimeParser(String format = "%Y-%m-%d") >>
172
+
173
+ Creates a parser for the given format string. Returns: C<TimeParser>.
174
+
175
+ =item C<< TimeParser->parse(String text) >>
176
+
177
+ Parameters: C<text> is text matching the parser format. Returns:
178
+ C<Time>. Parses text into a time object.
179
+
180
+ =back
181
+
182
+ =head1 COPYRIGHT AND LICENCE
183
+
184
+ B<< std/time >> is copyright Toby Inkster.
185
+
186
+ It is free software; you may redistribute it and/or modify it under
187
+ the terms of either the Artistic License 1.0 or the GNU General Public
188
+ License version 2.
@@ -0,0 +1,89 @@
1
+ =encoding utf8
2
+
3
+ =head1 NAME
4
+
5
+ std/tui - Terminal UI helpers.
6
+
7
+ =head1 SYNOPSIS
8
+
9
+ from std/tui import supports_ansi, colour_text, readline, write_line;
10
+
11
+ write_line( "Warning", "yellow" );
12
+ let path := readline( "File: ", "", filename_completions );
13
+
14
+ =head1 IMPLEMENTATION SUPPORT
15
+
16
+ This module is supported by all implementations of ZuzuScript.
17
+
18
+ =head1 DESCRIPTION
19
+
20
+ This runtime-supported module provides small terminal UI primitives for
21
+ standard-library modules that need command-line fallbacks.
22
+
23
+ =head1 EXPORTS
24
+
25
+ =head2 Functions
26
+
27
+ =over
28
+
29
+ =item * C<ansi_esc()>
30
+
31
+ Parameters: none. Returns: C<String>. Returns a one-character ANSI
32
+ escape string.
33
+
34
+ =item * C<supports_ansi()>
35
+
36
+ Parameters: none. Returns: C<Boolean>. Returns true when stdout appears
37
+ to be an ANSI-capable terminal.
38
+
39
+ =item * C<colour_text(text, colour)>
40
+
41
+ Parameters: C<text> is the value to display and C<colour> is a colour
42
+ name or C<null>. Returns: C<String>. Returns C<text> wrapped in ANSI
43
+ colour escapes when C<supports_ansi()> is true, otherwise returns
44
+ C<text> unchanged.
45
+
46
+ =item * C<write(text, colour)>
47
+
48
+ Parameters: C<text> is the value to write and C<colour> is a colour name
49
+ or C<null>. Returns: C<null>. Writes C<text> to stdout, optionally
50
+ coloured.
51
+
52
+ =item * C<write_line(text, colour)>
53
+
54
+ Parameters: C<text> is the value to write and C<colour> is a colour name
55
+ or C<null>. Returns: C<null>. Writes C<text> followed by a newline to
56
+ stdout, optionally coloured.
57
+
58
+ =item * C<readline(prompt, default, completion_callback)>
59
+
60
+ Parameters: C<prompt> is prompt text, C<default> is the initial value,
61
+ and C<completion_callback> is C<null> or a completion function. Returns:
62
+ C<String> or C<null>. Reads a line from stdin.
63
+
64
+ =item * C<readline_supports_completion()>
65
+
66
+ Parameters: none. Returns: C<Boolean>. Returns true when the runtime can
67
+ provide native readline completion.
68
+
69
+ =item * C<filename_completions(text)>
70
+
71
+ Parameters: C<text> is the partial path. Returns: C<Array>. Returns file
72
+ and directory path completions for C<text>.
73
+
74
+ =item * C<directory_completions(text)>
75
+
76
+ Parameters: C<text> is the partial path. Returns: C<Array>. Returns
77
+ directory path completions for C<text>.
78
+
79
+ =back
80
+
81
+ =head1 COPYRIGHT AND LICENCE
82
+
83
+ B<< std/tui >> is copyright Toby Inkster.
84
+
85
+ It is free software; you may redistribute it and/or modify it under
86
+ the terms of either the Artistic License 1.0 or the GNU General Public
87
+ License version 2.
88
+
89
+ =cut
@@ -0,0 +1,223 @@
1
+ =encoding utf8
2
+
3
+ =head1 NAME
4
+
5
+ std/uuid - Pure ZuzuScript UUID v1 generator.
6
+
7
+ =head1 SYNOPSIS
8
+
9
+ from std/uuid import create_uuid, create_uuid_binary;
10
+
11
+ let text := create_uuid();
12
+ let raw := create_uuid_binary();
13
+
14
+ =head1 IMPLEMENTATION SUPPORT
15
+
16
+ This module is supported by all implementations of ZuzuScript.
17
+
18
+ =head1 DESCRIPTION
19
+
20
+ This module implements UUID version 1 generation using only
21
+ ZuzuScript code.
22
+
23
+ =head1 EXPORTS
24
+
25
+ =head2 Functions
26
+
27
+ =over
28
+
29
+ =item * C<create_uuid_binary()>
30
+
31
+ Parameters: none. Returns: C<BinaryString>. Returns a single UUID as 16
32
+ raw bytes.
33
+
34
+ =item * C<create_uuid()>
35
+
36
+ Parameters: none. Returns: C<String>. Returns a single UUID as
37
+ lowercase hexadecimal text with hyphens in the usual C<8-4-4-4-12>
38
+ layout.
39
+
40
+ =back
41
+
42
+ =head1 COPYRIGHT AND LICENCE
43
+
44
+ B<< std/uuid >> is copyright Toby Inkster.
45
+
46
+ It is free software; you may redistribute it and/or modify it under
47
+ the terms of either the Artistic License 1.0 or the GNU General Public
48
+ License version 2.
49
+
50
+ =cut
51
+
52
+ from std/math import Math;
53
+ from std/string import substr;
54
+ from std/string/base64 import decode;
55
+ from std/time import Time;
56
+
57
+ let _B64_ALPHABET := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
58
+ let _HEX_ALPHABET := "0123456789abcdef";
59
+
60
+ function _div_floor ( Number n, Number d ) {
61
+ return floor( n / d );
62
+ }
63
+
64
+ function _mod ( Number n, Number d ) {
65
+ return n - _div_floor( n, d ) * d;
66
+ }
67
+
68
+ function _rand_int ( Number max ) {
69
+ return floor( Math.rand(max) );
70
+ }
71
+
72
+ function _bytes_to_binary ( Array bytes ) {
73
+ let out := "";
74
+ let i := 0;
75
+ let n := bytes.length();
76
+
77
+ while ( i < n ) {
78
+ let b0 := bytes[i];
79
+ let b1 := null;
80
+ let b2 := null;
81
+ if ( i + 1 < n ) {
82
+ b1 := bytes[i + 1];
83
+ }
84
+ if ( i + 2 < n ) {
85
+ b2 := bytes[i + 2];
86
+ }
87
+
88
+ let c0 := _div_floor( b0, 4 );
89
+ let c1 := _mod( b0, 4 ) * 16;
90
+ let c2 := 64;
91
+ let c3 := 64;
92
+
93
+ if ( b1 ≢ null ) {
94
+ c1 += _div_floor( b1, 16 );
95
+ c2 := _mod( b1, 16 ) * 4;
96
+ if ( b2 ≢ null ) {
97
+ c2 += _div_floor( b2, 64 );
98
+ c3 := _mod( b2, 64 );
99
+ }
100
+ }
101
+
102
+ out _= substr( _B64_ALPHABET, c0, 1 );
103
+ out _= substr( _B64_ALPHABET, c1, 1 );
104
+ if ( c2 ≡ 64 ) {
105
+ out _= "=";
106
+ }
107
+ else {
108
+ out _= substr( _B64_ALPHABET, c2, 1 );
109
+ }
110
+ if ( c3 ≡ 64 ) {
111
+ out _= "=";
112
+ }
113
+ else {
114
+ out _= substr( _B64_ALPHABET, c3, 1 );
115
+ }
116
+
117
+ i += 3;
118
+ }
119
+
120
+ return decode(out);
121
+ }
122
+
123
+ function _timestamp_words () {
124
+ // Seconds between 1582-10-15 and 1970-01-01.
125
+ let epoch_offset := 12219292800;
126
+ let seconds := new Time().epoch() + epoch_offset;
127
+ let ticks := _rand_int(10000000);
128
+
129
+ let words := [
130
+ _mod( seconds, 65536 ),
131
+ _mod( _div_floor( seconds, 65536 ), 65536 ),
132
+ _mod( _div_floor( seconds, 4294967296 ), 65536 ),
133
+ 0,
134
+ 0,
135
+ ];
136
+
137
+ let scale := 10000000;
138
+ let i := 0;
139
+ let carry := 0;
140
+ while ( i < words.length() ) {
141
+ let product := words[i] * scale + carry;
142
+ words[i] := _mod( product, 65536 );
143
+ carry := _div_floor( product, 65536 );
144
+ i++;
145
+ }
146
+
147
+ let add_i := 0;
148
+ let add_carry := ticks;
149
+ while ( add_carry > 0 and add_i < words.length() ) {
150
+ let sum := words[add_i] + _mod( add_carry, 65536 );
151
+ words[add_i] := _mod( sum, 65536 );
152
+ add_carry := _div_floor( add_carry, 65536 ) + _div_floor( sum, 65536 );
153
+ add_i++;
154
+ }
155
+
156
+ return words;
157
+ }
158
+
159
+ function _create_uuid_bytes () {
160
+ let words := _timestamp_words();
161
+ let time_low := words[0] + words[1] * 65536;
162
+ let time_mid := words[2];
163
+ let time_hi_and_version := _mod( words[3], 4096 ) + 4096;
164
+
165
+ let clock_seq := _rand_int(16384);
166
+ let clock_seq_hi_and_reserved := _mod( _div_floor( clock_seq, 256 ), 64 ) + 128;
167
+ let clock_seq_low := _mod( clock_seq, 256 );
168
+
169
+ let node := [];
170
+ let j := 0;
171
+ while ( j < 6 ) {
172
+ node.push( _rand_int(256) );
173
+ j++;
174
+ }
175
+ // Multicast bit set means this is not an IEEE MAC address.
176
+ node[0] := node[0] | 1;
177
+
178
+ return [
179
+ _mod( _div_floor( time_low, 16777216 ), 256 ),
180
+ _mod( _div_floor( time_low, 65536 ), 256 ),
181
+ _mod( _div_floor( time_low, 256 ), 256 ),
182
+ _mod( time_low, 256 ),
183
+ _mod( _div_floor( time_mid, 256 ), 256 ),
184
+ _mod( time_mid, 256 ),
185
+ _mod( _div_floor( time_hi_and_version, 256 ), 256 ),
186
+ _mod( time_hi_and_version, 256 ),
187
+ clock_seq_hi_and_reserved,
188
+ clock_seq_low,
189
+ node[0],
190
+ node[1],
191
+ node[2],
192
+ node[3],
193
+ node[4],
194
+ node[5],
195
+ ];
196
+ }
197
+
198
+ function _byte_to_hex ( Number b ) {
199
+ let hi := _div_floor( b, 16 );
200
+ let lo := _mod( b, 16 );
201
+ return substr( _HEX_ALPHABET, hi, 1 ) _ substr( _HEX_ALPHABET, lo, 1 );
202
+ }
203
+
204
+ function _bytes_to_uuid_text ( Array bytes ) {
205
+ let out := "";
206
+ let i := 0;
207
+ while ( i < 16 ) {
208
+ out _= _byte_to_hex( bytes[i] );
209
+ if ( i ≡ 3 or i ≡ 5 or i ≡ 7 or i ≡ 9 ) {
210
+ out _= "-";
211
+ }
212
+ i++;
213
+ }
214
+ return out;
215
+ }
216
+
217
+ function create_uuid_binary () {
218
+ return _bytes_to_binary( _create_uuid_bytes() );
219
+ }
220
+
221
+ function create_uuid () {
222
+ return _bytes_to_uuid_text( _create_uuid_bytes() );
223
+ }