@px-petals/roku.motion-web 1.0.0 → 1.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 (77) hide show
  1. package/bands/bands.js +3 -1
  2. package/bundle/bundle.js +56 -0
  3. package/list/list.js +12 -1
  4. package/lottie/lottie.layers.js +64 -11
  5. package/lottie/lottie.paint.js +30 -0
  6. package/lottie/lottie.paths.js +19 -4
  7. package/lottie/lottie.props.js +18 -8
  8. package/lottie/lottie.shapes.js +2 -1
  9. package/mixer/mixer.js +31 -8
  10. package/mixer/mixer.mix.js +17 -0
  11. package/motion/motion.convert.js +32 -1
  12. package/motion/motion.flow.js +20 -2
  13. package/motion/motion.machine.js +28 -13
  14. package/motion/motion.values.js +13 -9
  15. package/motion.js +196 -20
  16. package/package.json +10 -16
  17. package/player/player.js +25 -5
  18. package/readme.md +78 -3
  19. package/script/luau/lib/base/base.js +202 -0
  20. package/script/luau/lib/base/base.table.js +189 -0
  21. package/script/luau/lib/lib.args.js +152 -0
  22. package/script/luau/lib/lib.js +23 -0
  23. package/script/luau/lib/math/math.bit32.js +144 -0
  24. package/script/luau/lib/math/math.js +288 -0
  25. package/script/luau/lib/math/math.vector.js +125 -0
  26. package/script/luau/lib/string/string.format.js +143 -0
  27. package/script/luau/lib/string/string.js +160 -0
  28. package/script/luau/lib/string/string.pattern.js +505 -0
  29. package/script/luau/load/load.js +362 -0
  30. package/script/luau/load/load.ops.js +79 -0
  31. package/script/luau/luau.convert.js +259 -0
  32. package/script/luau/luau.js +132 -0
  33. package/script/luau/luau.md +111 -0
  34. package/script/luau/vm/vm.js +167 -0
  35. package/script/luau/vm/vm.meta.js +401 -0
  36. package/script/luau/vm/vm.num.js +236 -0
  37. package/script/luau/vm/vm.run.js +842 -0
  38. package/script/luau/vm/vm.value.js +406 -0
  39. package/script/play/play.js +199 -0
  40. package/script/play/play.objects.js +295 -0
  41. package/script/play/play.scope.js +91 -0
  42. package/script/rive/api/api.statics.js +31 -0
  43. package/script/rive/api/api.type.js +188 -0
  44. package/script/rive/api/artboard/artboard.js +89 -0
  45. package/script/rive/api/assets/assets.js +72 -0
  46. package/script/rive/api/data/data.value.js +99 -0
  47. package/script/rive/api/draw/draw.contours.js +163 -0
  48. package/script/rive/api/draw/draw.measure.js +196 -0
  49. package/script/rive/api/draw/draw.paint.js +235 -0
  50. package/script/rive/api/draw/draw.path.js +153 -0
  51. package/script/rive/api/draw/draw.renderer.js +117 -0
  52. package/script/rive/api/math/math.color.js +96 -0
  53. package/script/rive/api/math/math.mat2d.js +180 -0
  54. package/script/rive/api/math/math.vector.js +121 -0
  55. package/script/rive/api/media/media.audio.js +113 -0
  56. package/script/rive/api/media/media.draw.js +73 -0
  57. package/script/rive/api/media/media.image.js +61 -0
  58. package/script/rive/api/media/media.mesh.js +50 -0
  59. package/script/rive/api/pointer/pointer.event.js +64 -0
  60. package/script/rive/api/pointer/pointer.route.js +69 -0
  61. package/script/rive/api/text/text.font.js +129 -0
  62. package/script/rive/api/text/text.js +278 -0
  63. package/script/rive/api/text/text.layout.js +259 -0
  64. package/script/rive/context/context.js +76 -0
  65. package/script/rive/context/context.memory.js +196 -0
  66. package/script/rive/context/context.viewmodel.js +302 -0
  67. package/script/rive/context/lists/lists.js +160 -0
  68. package/script/rive/context/lists/lists.values.js +281 -0
  69. package/script/rive/host/host.globals.js +44 -0
  70. package/script/rive/host/host.js +533 -0
  71. package/script/rive/host/host.node.js +45 -0
  72. package/script/rive/rive.js +23 -0
  73. package/script/rive/rive.md +180 -0
  74. package/script/script.js +11 -0
  75. package/skin/skin.deform.js +514 -0
  76. package/skin/skin.ik.js +260 -0
  77. package/skin/skin.js +297 -0
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Argument checks for native library functions, with Luau's messages
3
+ * (`invalid argument #1 to 'insert' (table expected, got nil)`).
4
+ */
5
+
6
+ import { LuaTable, NativeFunction, LuaClosure, fail, typeName } from '../vm/vm.value.js'
7
+ import { toNumber } from '../vm/vm.meta.js'
8
+ import { numberToString } from '../vm/vm.num.js'
9
+
10
+ /**
11
+ * @param {number} n 1-based argument number
12
+ * @param {string} fname
13
+ * @param {string} message
14
+ */
15
+ export function argError(n, fname, message) {
16
+ return fail('invalid argument #' + n + " to '" + fname + "' (" + message + ')')
17
+ }
18
+
19
+ /**
20
+ * @param {any[]} args
21
+ * @param {number} i 0-based
22
+ * @returns {string}
23
+ */
24
+ function got(args, i) {
25
+ return typeName(args[i])
26
+ }
27
+
28
+ /**
29
+ * The error for an argument of the wrong type: Luau says "missing argument"
30
+ * when there is none at all, and "invalid argument" with the type it got otherwise.
31
+ *
32
+ * @param {any[]} args
33
+ * @param {number} i 0-based
34
+ * @param {string} fname
35
+ * @param {string} expected such as 'table'
36
+ */
37
+ export function typeError(args, i, fname, expected) {
38
+ if (i >= args.length) return fail('missing argument #' + (i + 1) + " to '" + fname + "' (" + expected + ' expected)')
39
+ return argError(i + 1, fname, expected + ' expected, got ' + got(args, i))
40
+ }
41
+
42
+ /**
43
+ * @param {any[]} args
44
+ * @param {number} i 0-based
45
+ * @param {string} fname
46
+ * @returns {LuaTable}
47
+ */
48
+ export function checkTable(args, i, fname) {
49
+ const v = args[i]
50
+ if (!(v instanceof LuaTable)) throw typeError(args, i, fname, 'table')
51
+ return v
52
+ }
53
+
54
+ /**
55
+ * @param {any[]} args
56
+ * @param {number} i
57
+ * @param {string} fname
58
+ * @returns {number} a number, or a string that reads as one
59
+ */
60
+ export function checkNumber(args, i, fname) {
61
+ const n = toNumber(args[i])
62
+ if (n === undefined) throw typeError(args, i, fname, 'number')
63
+ return n
64
+ }
65
+
66
+ /**
67
+ * @param {any[]} args
68
+ * @param {number} i
69
+ * @param {string} fname
70
+ * @param {number} def
71
+ * @returns {number}
72
+ */
73
+ export function optNumber(args, i, fname, def) {
74
+ return args[i] === undefined ? def : checkNumber(args, i, fname)
75
+ }
76
+
77
+ /**
78
+ * @param {any[]} args
79
+ * @param {number} i
80
+ * @param {string} fname
81
+ * @returns {number} an integer: the number cut toward zero
82
+ */
83
+ export function checkInt(args, i, fname) {
84
+ const n = checkNumber(args, i, fname)
85
+ return n < 0 ? Math.ceil(n) : Math.floor(n)
86
+ }
87
+
88
+ /**
89
+ * @param {any[]} args
90
+ * @param {number} i
91
+ * @param {string} fname
92
+ * @param {number} def
93
+ * @returns {number}
94
+ */
95
+ export function optInt(args, i, fname, def) {
96
+ return args[i] === undefined ? def : checkInt(args, i, fname)
97
+ }
98
+
99
+ /**
100
+ * @param {any[]} args
101
+ * @param {number} i
102
+ * @param {string} fname
103
+ * @returns {string} a string, or a number written as one
104
+ */
105
+ export function checkString(args, i, fname) {
106
+ const v = args[i]
107
+ if (typeof v === 'string') return v
108
+ if (typeof v === 'number') return numberToString(v)
109
+ throw typeError(args, i, fname, 'string')
110
+ }
111
+
112
+ /**
113
+ * @param {any[]} args
114
+ * @param {number} i
115
+ * @param {string} fname
116
+ * @param {string} def
117
+ * @returns {string}
118
+ */
119
+ export function optString(args, i, fname, def) {
120
+ return args[i] === undefined ? def : checkString(args, i, fname)
121
+ }
122
+
123
+ /**
124
+ * @param {any[]} args
125
+ * @param {number} i
126
+ * @param {string} fname
127
+ * @returns {any} a function
128
+ */
129
+ export function checkFunction(args, i, fname) {
130
+ const v = args[i]
131
+ if (!(v instanceof LuaClosure) && !(v instanceof NativeFunction)) throw typeError(args, i, fname, 'function')
132
+ return v
133
+ }
134
+
135
+ /**
136
+ * @param {any[]} args
137
+ * @param {number} i
138
+ */
139
+ export function checkAny(args, i) {
140
+ if (i >= args.length) throw fail('missing argument #' + (i + 1))
141
+ }
142
+
143
+ /**
144
+ * Puts native functions into a table under their names.
145
+ *
146
+ * @param {LuaTable} table
147
+ * @param {Record<string, import('../vm/vm.value.js').NativeCall>} fns
148
+ * @param {string} [prefix] such as 'string.', so errors and `tostring` name the function
149
+ */
150
+ export function register(table, fns, prefix) {
151
+ for (const name in fns) table.set(name, new NativeFunction((prefix || '') + name, fns[name]))
152
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Installs the standard library subset into a VM's globals: base, `string`,
3
+ * `table`, `math`, `bit32`, `vector` and `os`. The host adds its own globals
4
+ * to `vm.globals` afterwards.
5
+ */
6
+
7
+ import { installBase } from './base/base.js'
8
+ import { installTable } from './base/base.table.js'
9
+ import { installBit32 } from './math/math.bit32.js'
10
+ import { installMath } from './math/math.js'
11
+ import { installVector } from './math/math.vector.js'
12
+ import { installString } from './string/string.js'
13
+
14
+ /** @param {import('../vm/vm.js').VM} vm */
15
+ export function installLibs(vm) {
16
+ const G = vm.globals
17
+ installBase(vm, G)
18
+ installString(vm, G)
19
+ installTable(vm, G)
20
+ installMath(vm, G)
21
+ installBit32(vm, G)
22
+ installVector(vm, G)
23
+ }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * The `bit32` library: 32-bit unsigned integer operations on doubles.
3
+ */
4
+
5
+ import { LuaTable, fail } from '../../vm/vm.value.js'
6
+ import { argError, checkNumber, register } from '../lib.args.js'
7
+
8
+ /**
9
+ * @param {any[]} args
10
+ * @param {number} i
11
+ * @param {string} name
12
+ * @returns {number} the argument as an unsigned 32-bit integer
13
+ */
14
+ function u32(args, i, name) {
15
+ return checkNumber(args, i, name) >>> 0
16
+ }
17
+
18
+ /**
19
+ * @param {number} x
20
+ * @param {number} disp positive shifts left, negative right
21
+ * @returns {number}
22
+ */
23
+ function shift(x, disp) {
24
+ if (disp <= -32 || disp >= 32) return 0
25
+ return (disp >= 0 ? x << disp : x >>> -disp) >>> 0
26
+ }
27
+
28
+ /**
29
+ * @param {import('../../vm/vm.js').VM} vm
30
+ * @param {LuaTable} G
31
+ */
32
+ export function installBit32(vm, G) {
33
+ const bit32 = new LuaTable()
34
+ G.set('bit32', bit32)
35
+
36
+ /**
37
+ * @param {string} name
38
+ * @param {(a: number, b: number) => number} f
39
+ * @param {number} init
40
+ */
41
+ const fold = function (name, f, init) {
42
+ bit32.set(name, vm.native('bit32.' + name, function (vm2, args) {
43
+ let r = init
44
+ for (let i = 0; i < args.length; i++) r = f(r, u32(args, i, name)) >>> 0
45
+ return r
46
+ }))
47
+ }
48
+ fold('band', function (a, b) { return a & b }, 0xffffffff)
49
+ fold('bor', function (a, b) { return a | b }, 0)
50
+ fold('bxor', function (a, b) { return a ^ b }, 0)
51
+
52
+ /**
53
+ * @param {any[]} args
54
+ * @param {string} name
55
+ * @returns {[number, number]} field start and width
56
+ */
57
+ const field = function (args, name) {
58
+ const f = checkNumber(args, 1, name)
59
+ const w = args[2] === undefined ? 1 : checkNumber(args, 2, name)
60
+ if (f < 0) throw argError(2, name, 'field cannot be negative')
61
+ if (w <= 0) throw argError(3, name, 'width must be positive')
62
+ if (f + w > 32) throw fail('trying to access non-existent bits')
63
+ return [ f, w ]
64
+ }
65
+
66
+ register(bit32, {
67
+ bnot(vm, args) {
68
+ return ~u32(args, 0, 'bnot') >>> 0
69
+ },
70
+
71
+ btest(vm, args) {
72
+ let r = 0xffffffff
73
+ for (let i = 0; i < args.length; i++) r = (r & u32(args, i, 'btest')) >>> 0
74
+ return r !== 0
75
+ },
76
+
77
+ lshift(vm, args) {
78
+ return shift(u32(args, 0, 'lshift'), Math.floor(checkNumber(args, 1, 'lshift')))
79
+ },
80
+
81
+ rshift(vm, args) {
82
+ return shift(u32(args, 0, 'rshift'), -Math.floor(checkNumber(args, 1, 'rshift')))
83
+ },
84
+
85
+ arshift(vm, args) {
86
+ const x = u32(args, 0, 'arshift')
87
+ const d = Math.floor(checkNumber(args, 1, 'arshift'))
88
+ if (d >= 32) return (x & 0x80000000) !== 0 ? 0xffffffff : 0
89
+ if (d <= -32) return 0
90
+ return d >= 0 ? (x | 0) >> d >>> 0 : shift(x, -d)
91
+ },
92
+
93
+ lrotate(vm, args) {
94
+ const x = u32(args, 0, 'lrotate')
95
+ const r = Math.floor(checkNumber(args, 1, 'lrotate')) & 31
96
+ return r === 0 ? x : ((x << r) | (x >>> (32 - r))) >>> 0
97
+ },
98
+
99
+ rrotate(vm, args) {
100
+ const x = u32(args, 0, 'rrotate')
101
+ const r = Math.floor(checkNumber(args, 1, 'rrotate')) & 31
102
+ return r === 0 ? x : ((x >>> r) | (x << (32 - r))) >>> 0
103
+ },
104
+
105
+ extract(vm, args) {
106
+ const x = u32(args, 0, 'extract')
107
+ const fw = field(args, 'extract')
108
+ return fw[1] === 32 ? x : (x >>> fw[0]) & (Math.pow(2, fw[1]) - 1)
109
+ },
110
+
111
+ replace(vm, args) {
112
+ const x = u32(args, 0, 'replace')
113
+ const v = u32(args, 1, 'replace')
114
+ const f = checkNumber(args, 2, 'replace')
115
+ const w = args[3] === undefined ? 1 : checkNumber(args, 3, 'replace')
116
+ if (f < 0) throw argError(3, 'replace', 'field cannot be negative')
117
+ if (w <= 0) throw argError(4, 'replace', 'width must be positive')
118
+ if (f + w > 32) throw fail('trying to access non-existent bits')
119
+ const mask = w === 32 ? 0xffffffff : Math.pow(2, w) - 1
120
+ return (((x & ~(mask * Math.pow(2, f))) | ((v & mask) << f)) >>> 0)
121
+ },
122
+
123
+ countlz(vm, args) {
124
+ const x = u32(args, 0, 'countlz')
125
+ if (x === 0) return 32
126
+ let n = 0
127
+ for (let bit = 0x80000000; (x & bit) === 0; bit >>>= 1) n++
128
+ return n
129
+ },
130
+
131
+ countrz(vm, args) {
132
+ const x = u32(args, 0, 'countrz')
133
+ if (x === 0) return 32
134
+ let n = 0
135
+ while (((x >>> n) & 1) === 0) n++
136
+ return n
137
+ },
138
+
139
+ byteswap(vm, args) {
140
+ const x = u32(args, 0, 'byteswap')
141
+ return (((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x >>> 8) & 0xff00) | (x >>> 24)) >>> 0
142
+ },
143
+ }, 'bit32.')
144
+ }
@@ -0,0 +1,288 @@
1
+ /**
2
+ * The `math` library, and `os`. Functions ES5 lacks (`sinh`, `log10`, `sign`,
3
+ * ...) are written out, because the oldest browsers this runs in lack them.
4
+ */
5
+
6
+ import { LuaTable } from '../../vm/vm.value.js'
7
+ import { sign, trunc } from '../../vm/vm.num.js'
8
+ import { argError, checkInt, checkNumber, optNumber, register } from '../lib.args.js'
9
+
10
+ /**
11
+ * @param {number} x
12
+ * @returns {number}
13
+ */
14
+ function sinh(x) {
15
+ return (Math.exp(x) - Math.exp(-x)) / 2
16
+ }
17
+
18
+ /**
19
+ * @param {number} x
20
+ * @returns {number}
21
+ */
22
+ function cosh(x) {
23
+ return (Math.exp(x) + Math.exp(-x)) / 2
24
+ }
25
+
26
+ /**
27
+ * @param {number} x
28
+ * @returns {number}
29
+ */
30
+ function tanh(x) {
31
+ if (x > 20) return 1
32
+ if (x < -20) return -1
33
+ const a = Math.exp(2 * x)
34
+ return (a - 1) / (a + 1)
35
+ }
36
+
37
+ /**
38
+ * The log of x in base `b`, exact where x is a power of b.
39
+ *
40
+ * @param {number} x
41
+ * @param {number} lnb the natural log of the base
42
+ * @param {number} b
43
+ * @returns {number}
44
+ */
45
+ function logBase(x, lnb, b) {
46
+ const r = Math.log(x) / lnb
47
+ const rounded = Math.round(r)
48
+ return Math.abs(r - rounded) < 1e-9 && Math.pow(b, rounded) === x ? rounded : r
49
+ }
50
+
51
+ /**
52
+ * A small deterministic generator (mulberry32), 32 bits of state.
53
+ *
54
+ * @param {number} seed
55
+ */
56
+ function makeRandom(seed) {
57
+ let state = seed >>> 0
58
+ return function () {
59
+ state = (state + 0x6d2b79f5) >>> 0
60
+ let t = state
61
+ t = Math.imul(t ^ (t >>> 15), t | 1)
62
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61)
63
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296
64
+ }
65
+ }
66
+
67
+ /**
68
+ * @param {import('../../vm/vm.js').VM} vm
69
+ * @param {LuaTable} G
70
+ */
71
+ export function installMath(vm, G) {
72
+ const math = new LuaTable()
73
+ G.set('math', math)
74
+ let random = makeRandom(0x2545f491)
75
+
76
+ /**
77
+ * One-argument functions.
78
+ *
79
+ * @param {string} name
80
+ * @param {(x: number) => number} f
81
+ */
82
+ const unary = function (name, f) {
83
+ math.set(name, vm.native('math.' + name, function (vm2, args) {
84
+ return f(checkNumber(args, 0, name))
85
+ }))
86
+ }
87
+
88
+ unary('abs', Math.abs)
89
+ unary('acos', Math.acos)
90
+ unary('asin', Math.asin)
91
+ unary('atan', Math.atan)
92
+ unary('ceil', Math.ceil)
93
+ unary('cos', Math.cos)
94
+ unary('cosh', cosh)
95
+ unary('deg', function (x) { return x * (180 / Math.PI) })
96
+ unary('exp', Math.exp)
97
+ unary('floor', Math.floor)
98
+ unary('log10', function (x) { return logBase(x, Math.LN10, 10) })
99
+ unary('rad', function (x) { return x * (Math.PI / 180) })
100
+ unary('sin', Math.sin)
101
+ unary('sinh', sinh)
102
+ unary('sqrt', Math.sqrt)
103
+ unary('tan', Math.tan)
104
+ unary('tanh', tanh)
105
+ unary('sign', sign)
106
+ unary('round', function (x) { return x < 0 ? -Math.floor(-x + 0.5) : Math.floor(x + 0.5) })
107
+ unary('isnan', function (x) { return /** @type {any} */ (x !== x) })
108
+ unary('isinf', function (x) { return /** @type {any} */ (x === Infinity || x === -Infinity) })
109
+ unary('isfinite', function (x) { return /** @type {any} */ (x === x && x !== Infinity && x !== -Infinity) })
110
+
111
+ register(math, {
112
+ atan2(vm, args) {
113
+ return Math.atan2(checkNumber(args, 0, 'atan2'), checkNumber(args, 1, 'atan2'))
114
+ },
115
+
116
+ fmod(vm, args) {
117
+ return checkNumber(args, 0, 'fmod') % checkNumber(args, 1, 'fmod')
118
+ },
119
+
120
+ frexp(vm, args) {
121
+ const x = checkNumber(args, 0, 'frexp')
122
+ if (x === 0 || x !== x || x === Infinity || x === -Infinity) return [ x, 0 ]
123
+ let e = Math.max(-1023, Math.floor(logBase(Math.abs(x), Math.LN2, 2)) + 1)
124
+ let m = x * Math.pow(2, -e)
125
+ while (Math.abs(m) < 0.5) {
126
+ m *= 2
127
+ e--
128
+ }
129
+ while (Math.abs(m) >= 1) {
130
+ m /= 2
131
+ e++
132
+ }
133
+ return [ m, e ]
134
+ },
135
+
136
+ ldexp(vm, args) {
137
+ return checkNumber(args, 0, 'ldexp') * Math.pow(2, checkInt(args, 1, 'ldexp'))
138
+ },
139
+
140
+ log(vm, args) {
141
+ const x = checkNumber(args, 0, 'log')
142
+ if (args[1] === undefined) return Math.log(x)
143
+ const b = checkNumber(args, 1, 'log')
144
+ if (b === 2) return logBase(x, Math.LN2, 2)
145
+ if (b === 10) return logBase(x, Math.LN10, 10)
146
+ return Math.log(x) / Math.log(b)
147
+ },
148
+
149
+ max(vm, args) {
150
+ let m = checkNumber(args, 0, 'max')
151
+ for (let i = 1; i < args.length; i++) {
152
+ const v = checkNumber(args, i, 'max')
153
+ if (v > m) m = v
154
+ }
155
+ return m
156
+ },
157
+
158
+ min(vm, args) {
159
+ let m = checkNumber(args, 0, 'min')
160
+ for (let i = 1; i < args.length; i++) {
161
+ const v = checkNumber(args, i, 'min')
162
+ if (v < m) m = v
163
+ }
164
+ return m
165
+ },
166
+
167
+ modf(vm, args) {
168
+ const x = checkNumber(args, 0, 'modf')
169
+ const whole = trunc(x)
170
+ return [ whole, x - whole ]
171
+ },
172
+
173
+ pow(vm, args) {
174
+ return Math.pow(checkNumber(args, 0, 'pow'), checkNumber(args, 1, 'pow'))
175
+ },
176
+
177
+ clamp(vm, args) {
178
+ const v = checkNumber(args, 0, 'clamp')
179
+ const lo = checkNumber(args, 1, 'clamp')
180
+ const hi = checkNumber(args, 2, 'clamp')
181
+ if (lo > hi) throw argError(3, 'clamp', 'max must be greater than min')
182
+ return v < lo ? lo : v > hi ? hi : v
183
+ },
184
+
185
+ lerp(vm, args) {
186
+ const a = checkNumber(args, 0, 'lerp')
187
+ const b = checkNumber(args, 1, 'lerp')
188
+ const t = checkNumber(args, 2, 'lerp')
189
+ return t === 1 ? b : a + (b - a) * t
190
+ },
191
+
192
+ random(vm, args) {
193
+ const r = random()
194
+ if (args.length === 0) return r
195
+ const lo = args.length === 1 ? 1 : checkInt(args, 0, 'random')
196
+ const hi = checkInt(args, args.length === 1 ? 0 : 1, 'random')
197
+ if (lo > hi) throw argError(args.length === 1 ? 1 : 2, 'random', 'interval is empty')
198
+ return lo + Math.floor(r * (hi - lo + 1))
199
+ },
200
+
201
+ randomseed(vm, args) {
202
+ random = makeRandom(checkInt(args, 0, 'randomseed'))
203
+ return []
204
+ },
205
+
206
+ noise(vm, args) {
207
+ return noise(checkNumber(args, 0, 'noise'), optNumber(args, 1, 'noise', 0), optNumber(args, 2, 'noise', 0))
208
+ },
209
+ }, 'math.')
210
+
211
+ math.set('pi', Math.PI)
212
+ math.set('huge', Infinity)
213
+
214
+ // os
215
+ const os = new LuaTable()
216
+ G.set('os', os)
217
+ register(os, {
218
+ clock() {
219
+ return now() / 1000
220
+ },
221
+ time() {
222
+ return Math.floor(Date.now() / 1000)
223
+ },
224
+ }, 'os.')
225
+ }
226
+
227
+ /** @returns {number} milliseconds, from a clock that only moves forward where the host has one */
228
+ function now() {
229
+ const perf = typeof performance !== 'undefined' ? performance : null
230
+ return perf !== null && typeof perf.now === 'function' ? perf.now() : Date.now()
231
+ }
232
+
233
+ /**
234
+ * Perlin gradient noise in 1 to 3 dimensions, in about -1..1.
235
+ *
236
+ * @param {number} x
237
+ * @param {number} y
238
+ * @param {number} z
239
+ * @returns {number}
240
+ */
241
+ function noise(x, y, z) {
242
+ const xi = Math.floor(x)
243
+ const yi = Math.floor(y)
244
+ const zi = Math.floor(z)
245
+ const xf = x - xi
246
+ const yf = y - yi
247
+ const zf = z - zi
248
+ /** @param {number} t */
249
+ const fade = function (t) { return t * t * t * (t * (t * 6 - 15) + 10) }
250
+ /**
251
+ * @param {number} a
252
+ * @param {number} b
253
+ * @param {number} c
254
+ */
255
+ const hash = function (a, b, c) {
256
+ let h = Math.imul(a, 374761393) + Math.imul(b, 668265263) + Math.imul(c, 1274126177)
257
+ h = Math.imul(h ^ (h >>> 13), 1274126177)
258
+ return (h ^ (h >>> 16)) & 15
259
+ }
260
+ /**
261
+ * @param {number} h
262
+ * @param {number} dx
263
+ * @param {number} dy
264
+ * @param {number} dz
265
+ */
266
+ const grad = function (h, dx, dy, dz) {
267
+ const u = h < 8 ? dx : dy
268
+ const v = h < 4 ? dy : h === 12 || h === 14 ? dx : dz
269
+ return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v)
270
+ }
271
+ const u = fade(xf)
272
+ const v = fade(yf)
273
+ const w = fade(zf)
274
+ /**
275
+ * @param {number} a
276
+ * @param {number} b
277
+ * @param {number} t
278
+ */
279
+ const lerp = function (a, b, t) { return a + (b - a) * t }
280
+ const c = function (/** @type {number} */ dx, /** @type {number} */ dy, /** @type {number} */ dz) {
281
+ return grad(hash(xi + dx, yi + dy, zi + dz), xf - dx, yf - dy, zf - dz)
282
+ }
283
+ return lerp(
284
+ lerp(lerp(c(0, 0, 0), c(1, 0, 0), u), lerp(c(0, 1, 0), c(1, 1, 0), u), v),
285
+ lerp(lerp(c(0, 0, 1), c(1, 0, 1), u), lerp(c(0, 1, 1), c(1, 1, 1), u), v),
286
+ w,
287
+ )
288
+ }